<?xml version="1.0" encoding="UTF-8"?>
<Module>
 <ModulePrefs title="Reply Using Twitter"
              author="Cisco"
              author_email="help@cisco.com"
              scrolling="true"
              height="700">
   <Require feature="dynamic-height"/>
   <Require feature="settitle"/>
   <Require feature="minimessage"/>
   <Require feature="setprefs"/>
 </ModulePrefs>
 <Content type="html">
   <![CDATA[
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<style type="text/css">

body {
	font-family:Arial;color:#000000;
	font-size:12px;
	position:absolute;z-index:0;top:0px;left:0px;
	background-color:transparent; 
	width:100%;
	margin:0;padding:0;border:0;
}
	  
a:link             {color:#333399;text-decoration:underline;} 
a:visited          {color:#993366;text-decoration:underline;} 
br                 {line-height:8px;clear:both;}


th {
background-color:#eef3f8;
border-bottom:1px solid #eef3f8;
border-top:1px solid #eef3f8;
border-left:1px solid #eef3f8;
border-right:1px solid #FFFFFF;
font-family:Arial;
font-size:12px;
font-weight:normal;
line-height:16px;
padding-left:2px;
padding-right: 2px;
text-align:left;
vertical-align:middle;
}

td {
font-family:Arial;
font-size:12px;
line-height:16px;
padding: 1px;

vertical-align: text-top;
}

.transferBox {
	margin-top: 15px;
	width: 480px;
}

.transferBox select {
	height: 200px;
	width: 200px;
}

.transferBox div {
	float: left;
	margin-left: 2px;
	margin-right: 2px;
}

.transferBox .controls {
	width: 40px;
	padding-top: 30px;
}

.transferBox .controls .spacer {
	display: block;
	height: 25px;
}

.transferBox div button {
	width: 100%;
	margin-left: 0 auto ;
	margin-right: 0 auto ;
}

.layer {
	clear: both;
}

button {
         cursor:pointer;
}

legend {
    font-size:14px;
    font-weight:bold;
    position:relative;
    top:-.4em;
}

select:disabled{
	background-color:#DCDCDC;
}

div.floatLeft {
	float: left;
	margin: 5px 0 0 10px;
	width: 500px;
}

.layerHeadingFloat {
	float: left;
	margin: 5px 0 0 5px;
}

.toolbar {
	float: right;
	margin-right: 5px;
}

.toolbar IMG {
	border:0;
	width: 20px;
	height: 20px;
	padding-left: 3px;
	padding-top: 1px;
	cursor: pointer;
}

.hidden {
	display: none;
}

div.floatRight {
	float: right;
	margin: 7px 50px 0 0;
}

span.floatLeft {
	float: left;
	margin: 10px 0 0 10px;
}

span.floatRight {
	float: right;
	margin: 7px 50px 0 0;
}

.title {
	border-top: thin outset #407bb3;
	font-family:Arial;
	font-size:12px;
	font-weight:normal;
	line-height:16px;
	text-align:left;
	vertical-align:middle;
	display: inline-block;
	width: 100%;
	height: 22px;
	padding-top: 1px;
}

.layerHeading {
	font-size:16px;
	font-weight:normal;
}

.info, .success, .warning, .error, .systemError, .systemWarning{
	width: 100%;
	font: 9px arial,sans-serif;
    border: 1px solid;
	margin: 5px 0px;
	padding:5px;
    background-repeat: no-repeat;
    background-position: 10px center;
}
.info {
	border-color: #00529B;
    background-color: #BDE5F8;
}
.success {
    border-color: #4F8A10;
    background-color: #DFF2BF;
}
.warning {
    border-color: #9F6000;
    background-color: #FEEFB3;
}
.systemWarning {
    border-color: #9F6000;
    background-color: #FEEFB3;
}
.error {
    border-color: #D8000C;
    background-color: #FFBABA;
}

.systemError {
    border-color: #D8000C;
    background-color: #FFBABA;
}

.settingsLabel {
	font-family:Arial;
	font-size:12px;
	font-weight:bold;
}


textarea.errorHighlight{background-color:red}

#summaryData {
        height: 540px;
		overflow-x:hidden;
		overflow-y:auto;
		padding: 2px;
}

#detailsForm {
        height: 520px;
		overflow-x:hidden;
		overflow-y:auto;
		padding: 2px;
}

#postList {
        height: 540px;
		overflow-x:hidden;
		overflow-y:auto;
		padding:2px;	
}

#scrollDiv {
        height: 560px;		
		overflow-y:auto;
		padding:2px;
}


input.error {
	border: 1px solid red;
}

.postEntry:hover .statecontrols {
	/* opacity: 1.0; */
}

.statecontrols {
	display: inline-block;
	float: right;
    border:0;
    margin-right:0px;
    margin-left: auto;
	margin-top: 2px;
	margin-bottom: 2px;
	/* opacity: 0.01; */
}

IMG.statecontrol {
    border:0;
    width:18px;
    height:18px;
    margin-right:0px;
    padding: 0px 5px 0px 5px;
    cursor: pointer;
}

IMG.feedStatusIcon {
	border:0;
	width:16px;
	height:16px;
	margin-right:0px;
	padding: 0px 2px 0px 1px;
}

.contactstate {
    float:right;
	vertical-align: middle;
	height: 22px;
	display: inline;
	margin: 2px 2px 2px 2px;
}

.updated, .author {
	float: left;
	vertical-align: middle;
	display: inline;
	font-size:10px;
	color: #222222;
}

.trainingResponse, .tagResponse {
	text-align: center ;
	padding: 1px 5px;
	border: 1px solid;
	border-color: #4F8A10;
	background-color: #DFF2BF;
	margin: 2px 2px 2px 2px;
	float: left;
}

.tagResponse {
	margin-left: 5px;
}

.verticalSeparator {
	display: inline-block;
	border-left: 2px solid;
	border-color: #8499A2;
	height:18px;
}

.trainingHeading {
	
	padding-right: 40px;
}

.tags {
	margin-top: 5px;
	width: 100%;
}

.proxy {
	margin-top: 5px;
	width: 380px;
}

.tags input[type="text"] 
{
  width: 100px;
}

.proxy label 
{
  display: inline-block;
  float: left;
  min-width: 10em;
  text-align: left;
  margin: 4px;
}

.proxyExcludeList
{ 
  height:250px;
  overflow:auto;
 }

/*
   Set proxy settings link style so it looks the same
   even after it is clicked
*/
.proxySettingsLink
{ 
  float: right;
  margin-bottom: 5px;
  margin-right: 10px;
 }

a.proxySettingsLink:link, a.proxySettingsLink:visited
{ 
  color:#333399;
  text-decoration:underline;
 }

.proxy input[type="text"]
{ 
  margin: 3px;
  width: 200px;
 } 

.proxy input[type="checkbox"]
{ 
  margin: 3px;
 }

.proxySettings:disabled
{ 
  background-color:#DCDCDC;
 }

.postEntry:hover input[type="text"]
{
	border: 1px solid;
	border-color: #407BB3;
	
}

.postEntry input[type="text"] {
	border: 1px solid;
	border-color: #407BB3;
}

.postEntry button {

}

.postEntry:hover {
	background-color: #EEF3F8;
	width: 100%;
}

.postEntry a, .postEntry a:link, .postEntry a:visited {
	color:#333399;
	text-decoration: none;
	font-size: 13px;
}

.postEntry a:hover {
	text-decoration: underline;
}

.postEntry {
	width: 100%;
	padding-bottom: 5px;
}

.suggestedTagsWrapper {
	
	height: 20px;
}

.suggestedTags
{	
}

.tagSuggestion {
	color:#555599;
	text-decoration: none;
}


.tagSuggestion:hover {
	text-decoration: underline;
	cursor: pointer;
}

.postEntry:hover .suggestedTags {
}

.currentTags {
}

.postEntry:hover .addTags {
	opacity: 1.0;
}

.addTags {
	opacity: 0.01;
}

.summary {
	width: 100%;
	margin-bottom: 2px;
}
.tag,.proxyExcludeTag {
	display: inline-block;
	border-color: #AEB8BC;
	background:none repeat scroll 0 0 #DFF4FF;
	border:1px solid #A7CEDF;
	
	margin-bottom: 3px;
	margin-right: 3px;
	padding:2px 3px 2px 3px;
	
	-moz-border-radius: 5px;
	-webkit-border-radius: 5px;
	-khtml-border-radius: 5px;
}

#pendingResults {
	display: inline-block;
	border-color: #AEB8BC;
	background:none repeat scroll 0 0 #DFF4FF;
	width: 100%;
	text-align: center;
	margin-bottom: 3px;
	line-height: 20px;
	cursor: pointer;
	-moz-border-radius: 5px;
	-webkit-border-radius: 5px;
	-khtml-border-radius: 5px;
}

#pendingResults:hover {
	text-decoration: underline;		
}

.proxyExcludeTag
{
  display: block;
  min-width: 15em;
  }
img.deleteTag,img.deleteProxyExcludeTag {
	width: 8px;
	height: 8px;
	margin-left: 3px;
	cursor: pointer;
}

img.deleteProxyExcludeTag 
{
  float:right;
  vertical-align: center;
  margin: 3px;
}

td.rb {
	text-align: right;
    vertical-align: bottom;
}

.signinOverlay{
    background:transparent url(../img/overlay.png) repeat top left;
    position:fixed;
    top:0px;
    bottom:0px;
    left:0px;
    right:0px;
    z-index:100;
}

.signinBox{
    position:fixed;
    top:-325px;
    left:30%;
    right:30%;
    background-color:#fff;
    color:#7F7F7F;
    padding:20px;
    border:2px solid #ccc;
    -moz-border-radius: 20px;
    -webkit-border-radius:20px;
    -khtml-border-radius:20px;
    -moz-box-shadow: 0 1px 5px #333;
    -webkit-box-shadow: 0 1px 5px #333;
    z-index:101;
}

.signinBox h1
{
    border-bottom: 1px dashed #7F7F7F;
    margin:-20px -20px 0px -20px;
    padding:10px;
    background-color:#eef3f8;
    color:#407BB3;
    -moz-border-radius:20px 20px 0px 0px;
    -webkit-border-top-left-radius: 20px;
    -webkit-border-top-right-radius: 20px;
    -khtml-border-top-left-radius: 20px;
    -khtml-border-top-right-radius: 20px;
}

.signinBox input[type="text"], .signinBox input[type="password"] {
	width: 155px;
}
  
/*
active dir
*/  
  .activeDir input[type="text"]
{ 
  margin: 1px;
  width: 300px;
 }
 
  .activeDir input[type="password"]
{ 
  margin: 1px;
  width: 300px;
 }
 
   .activeDir input[type="checkbox"]
{ 
  margin: 1px; 
 }
 
 .activeDir label 
{
  display: inline-block;
  float: left;
  min-width: 16em;
  height: 28px;
  text-align: left-center;
  margin: 1px;
}

.activeDirSpan 
{	
	float: left;
	width: 350px;
	word-wrap: break-word; 
}

.campaignResultsSettingsLayer
{
	float: left;
	margin-left: 5px;
	width: 99%;
}

.campaignResultsBoxes
{
	width:400px;
	height:110px;
}

.campaignResultsSettingsHeader {
	font-family:Arial;
	font-size:14px;
	font-weight:bold;
	display: block;
	margin-top:15px;
    margin-bottom:5px;	
}
.campaignResultsCheckBox {
	margin: 0px;
	margin-bottom:4px;
	
}



textarea
{
	font-family:Arial;
	font-size:12px;
	line-height:16px;
	padding-left:8px;
	padding-top:2px;
	vertical-align:middle;
	margin-left:5px;
	width:95%;
}

</style>

<script type="text/javascript">


/**
 * Parameter name of the social contact's reference URL.  The value of
 * this parameter is used to derive the other REST paths used in the
 * reply template.
 */
var SC_REF_URL_PARAM      = "scRefUrl" ;

/**
 * CCP Feed API path
 */
var CCP_FEED_REST_PATH    = "/ccp-webapp/ccp/feed" ;

/**
 * CCP Twitter status update API path 
 */
var STATUS_MESSAGE_PATH   = "/ccp-webapp/ccp/reply/twitter/statuses/update" ;

/**
 * CCP Twitter direct message API path
 */
var DIRECT_MESSAGE_PATH   = "/ccp-webapp/ccp/reply/twitter/direct_messages/new" ;

/**
 * Social contact handled state
 */
var SC_STATUS_HANDLED = "handled" ;
	
/**
 * Social contact reserved state
 */
var SC_STATUS_RESERVED = "reserved" ;


//
// Utility Functions
//

/**
 * Found the parameter with the given name in the URL used to retrieve this
 * page.
 */
function getRequestParameterValue(paramName, url)
{
	paramName = paramName.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]") ;
	var regexS = "[\\?&]" + paramName + "=([^&#]*)" ;
	var regex = new RegExp(regexS) ;
	var results = regex.exec(url) ;
	if( results == null )
	{
	 	return "" ;
	}

	return results[1] ;
}

/**
 * Retrieve the node with the given name from the xml contained in the xml
 * parameter
 */
function getElementValue(xml, nodeName)
{
	var element = xml.getElementsByTagName(nodeName) ;
	if ( (element == null) ||
	     (element[0] == null) ||
	     (element[0].childNodes[0] == null) )
	{
		return "" ;
	}
	
	return element[0].childNodes[0].nodeValue ;
}

/**
 * Make a REST request to CCP.
 */
function makeRequest(url, method, callback, postdata)
{
	window.parent.window.parent.makeRequest(url, method, callback, postdata) ;
}

/**
* Hide the reply and set the social contact's state to nextState.
*/
function closeTemplate(nextState)
{
	window.parent.window.parent.clearError() ;
	window.parent.window.parent.closeReplyTemplate(nextState) ;
}

/**
 * Set the heading for the reply template
 */
function setHeading(heading)
{
	window.parent.window.parent.setHeading(heading) ;
}

/**
* Show an error using the CCP infrastructure
*/
function showError(message)
{
	window.parent.window.parent.showError(message) ;
}

/**
* Clear errors using the CCP infrastructure
*/
function clearError()
{
	window.parent.window.parent.clearError() ;
}


//
// CcpSession class definition
//

/**
 * The CcpSession class allows applications to interact with CCP as follows:
 *   - get the details of the social contact
 *   - change the state of the social contact
 *   - get the list of Twitter accounts available on CCP.  These accounts can
 *     be used to send Twitter messages
 *   - send Twitter status updates and direct messages
 * 
 * The href parameter is the URL of the reply template.  It is expected to
 * have an scRefUrl parameter in it.  This parameter is used to find the
 * protocol, port, and server to use to communicate with CCP.  
 */
function CcpSession(href)
{
	this.restSocialContact = unescape(getRequestParameterValue(SC_REF_URL_PARAM, unescape(href))) ;
	
	var ccpProtocol = "" ;
	var ccpHost = "" ;
	var ccpPort = "" ;
	
	// The following regex parses the protocol, host, and port from the social
	// contact's refUrl.  This gives the page a path back to CCP's REST APIs.
	//
	e = /([^:]+):\/\/([^:/]+):*([0-9]*)/ ;
	var array = this.restSocialContact.match(e) ;
	if ( array != null )
	{
		ccpProtocol = array[1] ;
		ccpHost = array[2] ;
		ccpPort = array[3] ;
	}
	
	// array[1] - protocol
	// array[2] - host
	// array[3] - port
	//
	var ccpBasePath = array[1] + "://" + array[2] + (ccpPort == "" ? "" : ":" + ccpPort) ;
	
	this.restGetFeedList = ccpBasePath + CCP_FEED_REST_PATH ;
	
	this.restSendStatusMessage = ccpBasePath + STATUS_MESSAGE_PATH ;
		
	this.restSendDirectMessage = ccpBasePath + DIRECT_MESSAGE_PATH ;
}

/**
 * Get the social contact's details.
 */
CcpSession.prototype.getSocialContact = function(callback)
{
	makeRequest(this.restSocialContact, gadgets.io.MethodType.GET, callback) ;
}

/**
 * Get the list of feeds configured on CCP.
 */
CcpSession.prototype.getAllCcpFeeds = function(callback)
{
	makeRequest(this.restGetFeedList, gadgets.io.MethodType.GET, callback) ;
}

/**
 * Send a status message using the Twitter account with the given username.
 */
CcpSession.prototype.twitterStatusUpdate = function(username, message, callback)
{
	var postData =
			"<Status>\n" +
			"  <username>" + username + "</username>\n" +
			"  <message>" + message + "</message>\n" +
			"</Status>" ;

	makeRequest(this.restSendStatusMessage, gadgets.io.MethodType.POST, callback, postData) ;
}

/**
 * Send a status message using the Twitter account with the given username.
 */
CcpSession.prototype.twitterReply = function(username, message, statusId, callback)
{
	var postData =
			"<Status>\n" +
			"  <username>" + username + "</username>\n" +
			"  <message>" + message + "</message>\n" +
			"  <inReplyToStatusId>" + statusId + "</inReplyToStatusId>\n" +
			"</Status>" ;

	makeRequest(this.restSendStatusMessage, gadgets.io.MethodType.POST, callback, postData) ;
}

/**
 * Send a direct message using the account specified by fromUsername to the user
 * specified in toUsername.
 */
CcpSession.prototype.twitterDirectMessage = function(fromUsername, toUsername, message, callback)
{
	var postData =
			"<DirectMessage>\n" +
			"  <fromUsername>" + fromUsername + "</fromUsername>\n" +
			"  <toUsername>" + toUsername + "</toUsername>\n" +
			"  <message>" + message + "</message>\n" +
			"</DirectMessage>" ;

	makeRequest(this.restSendDirectMessage, gadgets.io.MethodType.POST, callback, postData) ;
}

/**
 * Change the state of the social contact.
 */
CcpSession.prototype.changeState = function(newState, timestamp, callback)
{
	var postData =
			"<SocialContact>" +
			"  <statusTimestamp>" + timestamp + "</statusTimestamp>" +
			"  <status>" + newState + "</status>" +
			"</SocialContact>" ;
	
	makeRequest(this.restSocialContact, gadgets.io.MethodType.POST, callback, postData) ;
}
	

/**
 * Type value of a CCP Twitter Account feed
 */ 
var TWITTER_ACOUNT_TYPE = 6 ;

/**
 * Maximum number of characters in a tweet
 */
var MAX_TWEET_LEN       = 140 ;

/**
 * ID of the reply radio button
 */
REPLY_TYPE_REPLY = "replyTypeReply" ;

/**
 * ID of the direct message radio button
 */
REPLY_TYPE_DIRECT_MESSAGE = "replyTypeDirectMessage" ;


var saveReplies = [] ;
var lastReplyTypeId = "" ;

var ccpSession = null ;

var author = null ;
var timestamp = null ;
var twitterId = null ;

var DIRECT_MESSAGE_PREFIX = "Direct message:" ;

var ACCOUNT_NAME_KEY      = "accountName" ;

//
// References to UI elements
//

var replyArea = null ;

var charactersLeft = null ;

var sendButton = null ;

var accounts = null ;


/**
 * Return the value for the given key stored in the cookie
 */
function getFromCookie(key)
{
	var keyEquals = key + "=" ;
	var cookies = document.cookie.split(';') ;
	for ( var i = 0 ; i < cookies.length ; i++ )
	{
		var cookie = cookies[i] ;
		while ( cookie.charAt(0) == ' ')
		{
			cookie = cookie.substring(1, cookie.length) ;
		}
		
		if ( cookie.indexOf(keyEquals) == 0 )
		{
			return cookie.substring(keyEquals.length, cookie.length) ;
		}
	}
	
	return null ;
}

/**
 * Set the given key/value pair in the cookie
 */
function setInCookie(key, value)
{
	var curDate = new Date() ;
	
	// Expire in 30 days
	//
	var expiresDate = new Date(curDate.getTime() + (1000 * 60 * 60 * 24 * 30)) ;
	document.cookie = key + "=" + value + "; expires=" + expiresDate.toGMTString() + "; path=/" ;
}

/**
 * Send a reply using the selectedAccount.  The text in the reply area is used
 * as the text of the message.
 */
function reply(selectedAccount)
{
	setInCookie(ACCOUNT_NAME_KEY, selectedAccount) ;

	var replyCallback = function(obj)
	{
		if ( obj.rc != 200 )
		{
			showError(
				"Failed to send reply.\n" +
				"\nError code: " + obj.rc + "\nError text: " + obj.text) ;
		
			return ;
		}

		closeTemplate(SC_STATUS_HANDLED) ;
	}
	ccpSession.twitterReply(selectedAccount, replyArea.value, twitterId, replyCallback) ;
}

/**
 * Send a direct message using the selectedAccount.  The author of the social
 * contact is the target of the direct message.  The text in the reply area is
 * used as the text of the message.
 */
function directMessage(selectedAccount)
{
	setInCookie(ACCOUNT_NAME_KEY, selectedAccount) ;

	var directMessageCallback = function(obj)
	{
		if ( obj.rc != 200 )
		{
			showError(
				"Failed to send direct message.\n" +
				"\nError code: " + obj.rc + "\nError text: " + obj.text) ;
		
			return ;
		}

		closeTemplate(SC_STATUS_HANDLED) ;
	}
	ccpSession.twitterDirectMessage(selectedAccount, author, replyArea.value, directMessageCallback) ;
}

/**
 * Make sure the text in the reply area is within Twitter's limits.
 */
function updateCharactersLeft()
{
	var left = MAX_TWEET_LEN - replyArea.value.length ;
	charactersLeft.innerHTML = left ;
}

/**
 * Enable/disable the send button based on the selected account and the size
 * of the tweet.
 */
function updateSendButton()
{
	var replyLen = replyArea.value.length ;
	sendButton.disabled =
		((replyLen <= 0) || (replyLen > MAX_TWEET_LEN) || (accounts.selectedIndex == 0)) ;
}

function updateUI()
{
	updateCharactersLeft() ;
	updateSendButton() ;
}

/**
 * HTML UI callbacks
 */
 
/**
 * Process changes to the reply type radio buttons
 */
function replyTypeChanged(replyTypeId)
{
	var replyType = document.getElementById(replyTypeId) ;
	if ( replyType == null )
	{
		return ;
	}
	
	if ( lastReplyTypeId != null )
	{
		saveReplies[lastReplyTypeId] = replyArea.value ;
	}
	
	var replyText = saveReplies[replyType.id] ;
	replyArea.value = replyText == null ? "" : replyText ;

	lastReplyTypeId = replyType.id ;
	
	updateUI() ;
}

/**
 * Process changes to the account pulldown
 */
function accountChanged()
{
	updateUI() ;
}

/**
 * Handle send button clicks.
 */
function sendReply()
{
	var selectedAccount = accounts.options[accounts.selectedIndex].value ;
	
	if ( lastReplyTypeId == REPLY_TYPE_REPLY )
	{
		reply(selectedAccount) ;
	}
	else if ( lastReplyTypeId == REPLY_TYPE_DIRECT_MESSAGE )
	{
		directMessage(selectedAccount) ;
	}
	else
	{
		closeTemplate("SC_STATUS_RESERVED") ;
	}
}

/**
 * Restore the reply area to the content it had after initialization
 */
function resetReply()
{
	if ( document.getElementById(REPLY_TYPE_DIRECT_MESSAGE).checked )
	{
		replyArea.value = "" ;
	}
	
	if ( document.getElementById(REPLY_TYPE_REPLY).checked )
	{
		replyArea.value = "@" + author + " " ;
	}

	updateUI() ;	
}

/**
 * Inital entry point
 */
function main()
{
	setHeading("Twitter Reply") ;
	
	replyArea      = document.getElementById("replyText") ;
	charactersLeft = document.getElementById("charactersLeft") ;
	sendButton     = document.getElementById("sendButton") ;
	accounts       = document.getElementById("accounts") ;
	
	ccpSession = new CcpSession(window.location.href) ;
	
	// Use the social contact's details to populate the reply
	// form's fields.
	//
	var socialContactCallback = function(obj, success)
	{
		if ( obj.rc != 200 )
		{
			showError(
				"Failed to get social contact details.\n" +
				"\nError code: " + obj.rc + "\nError text: " + obj.text) ;
		
			return ;
		}
		
		var contact = obj.data ;
		author    = getElementValue(contact, "author") ;
		timestamp = getElementValue(contact, "statusTimestamp") ;
		
		var title = getElementValue(contact, "title") ;
		document.getElementById("title").innerHTML = title ;
		
		document.getElementById("description").innerHTML = getElementValue(contact, "description") ;
		
		charactersLeft = document.getElementById("charactersLeft") ;
		
		var checkReplyId = title.indexOf(DIRECT_MESSAGE_PREFIX) == 0 ? REPLY_TYPE_DIRECT_MESSAGE : REPLY_TYPE_REPLY ;
		var replyType = document.getElementById(checkReplyId) ;
		
		var replyPrefix = "@" + author + " " ;
		
		// Initialize the saved reply map to defaults
		//
		saveReplies[REPLY_TYPE_REPLY] = replyPrefix ;
		saveReplies[REPLY_TYPE_DIRECT_MESSAGE] = "" ;
		
		replyType.checked = true ;
		lastReplyTypeId = replyType.id ;
		
		replyArea = document.getElementById("replyText") ;
		replyArea.value = saveReplies[replyType.id] ;
		
		// Get the ID of the tweet or direct message
		//
		var link = getElementValue(contact, "link") ;
		if ( link.indexOf("http://twitter.com/#inbox?id=") == 0 )
		{
			twitterId = link.substring(link.lastIndexOf("=") + 1) ;
		}
		else
		{
			twitterId = link.substring(link.lastIndexOf("/") + 1) ;
		}
		
		// Parse the list of feeds configured on CCP for Twitter Account feeds.
		// The user's configured for those feeds have been configured with oAuth.
		// These users will make up the set of accounts to use to reply since they
		// have the ability to post tweets via CCP.
		//
		var accountsCallback = function(obj, success)
		{
			if ( obj.rc != 200 )
			{
				showError(
					"Failed to get Twitter accounts.\n" +
					"\nError code: " + obj.rc + "\nError text: " + obj.text) ;
			
				return ;
			}
			
			var feeds = obj.data.getElementsByTagName("Feed") ;
			if ( feeds == null )
			{
				return ;
			}
			
			var ccpAccounts = [] ;
			for ( var i = 0 ; i < feeds.length ; i++ )
			{
				var feedType =
					feeds[i].getElementsByTagName("type")[0].firstChild.nodeValue ;
				if ( feedType == TWITTER_ACOUNT_TYPE )
				{
					ccpAccounts[ccpAccounts.length] =
						feeds[i].getElementsByTagName("authenticationUsername")[0].firstChild.nodeValue ;
				}
			}
			
			var selectedAccount = getFromCookie(ACCOUNT_NAME_KEY) ;
			accounts[accounts.length] = new Option("", "") ;
			
			for ( var i = 0 ; i < ccpAccounts.length ; i++ )
			{
				accounts[accounts.length] = new Option(ccpAccounts[i], ccpAccounts[i]) ;
				if ( ccpAccounts[i] == selectedAccount )
				{
					accounts.selectedIndex = accounts.length - 1 ;
				}
			}
			
			accountChanged() ;
		}
		ccpSession.getAllCcpFeeds(accountsCallback) ;
	}
	ccpSession.getSocialContact(socialContactCallback) ;	
}

</script>

</head>

<body onLoad="main()">
<div id="reply">
	<form>
		<table style="width:100%">
		    <!-- Social contact details -->
			<tr><td>
			<table style="width:100%">
				<tr><th><div id="title"></div></th></tr>
				<tr><td><div id="description" class="description"></div></td></tr>
			</table>
			</td></tr>
		    <!--  Reply table -->
			<tr><td>
			<table style="width:100%">
				<tr><td></td></tr>
				<tr>
					<td>
						<label>Account:&nbsp</label>
						<select id="accounts" tabindex=1 onchange="javascript:accountChanged()">
						</select>
					</td>
				</tr>
				<tr>
					<td>
						<label for="replyTypeReply"><input type="radio" id="replyTypeReply" name="replyType" value="reply" onclick="javascript:replyTypeChanged('replyTypeReply')"/>Reply</label>
						<label for="replyTypeDirectMessage"><input type="radio" id="replyTypeDirectMessage" name="replyType" value="directMessage" onclick="javascript:replyTypeChanged('replyTypeDirectMessage')">Direct message</label>
					</td>
					<td>
						<label id="charactersLeft"></label>
					</td>
				</tr>
			</table>
			</td></tr>
			<!-- Send and cancel buttons -->
			<tr><td>
			<table style="width:100%">
				<tr>
					<td>
						<textarea id="replyText" rows="5" tabindex="2" onchange="javascript:updateUI()" onkeypress="javascript:updateUI()">
						</textarea>
					</td>
				</tr>
				<tr>
					<td>
						<input id="sendButton" type="button" value="Send" onclick="javascript:sendReply()">
						<input id="resetButton" type="button" value="Reset" onclick="javascript:resetReply()">
						<input id="cancelButton" type="button" value="Cancel" onclick="javascript:closeTemplate('reserved')">
					</td>
				</tr>
			</table>
			</td></tr>
		</table>
	</form>
  
                  
                  
                  ****** This is Tod's custom gadget!!!   *******
</div>

</body>
</html>    
  ]]>
  </Content>
</Module>

