/**
 * Class to handle comments display and functionality  
 */
 
var AMEXComments = new Class(
{
	options: {
		urlAdd : null ,
		formAdd : null ,
		updateAdd : null ,
		urlFlag : null ,
		updateFlag : null ,
		xmlPath : null ,
		submitButton : null ,
		onComplete : null ,
		btnSubmit : null
	},
	
	tmp: {
		
	},
	
	xhrFlag : null ,
	xhrAdd : null ,
	
	// Object containing parsed XML comment data 
	commentData: {},
	
	commentCount: 0,
	
	initialize: function ( pOptions )
	{
		// Store passed options to this instance's options object
		this.options.formAdd  = pOptions.formAdd;
		this.options.urlFlag  = pOptions.urlFlag;
		this.options.urlAdd   = pOptions.urlAdd;
		this.options.updateAdd   = pOptions.updateAdd;
		this.options.updateFlag   = pOptions.updateFlag;
		this.options.xmlPath  = pOptions.xmlPath;
		this.options.xmlPath  = pOptions.xmlPath;
		this.options.onFlagComplete = pOptions.onFlagComplete;
		this.options.onAddComplete = pOptions.onAddComplete;
		this.options.submitButton = pOptions.submitButton;
	},
	
	formatQuantity: function ( pQuantity , pSingular , pPlural )
	{
		if ( pQuantity == 1 )
		{
			return pQuantity + " " + pSingular;
		}
		return pQuantity + " " + pPlural;
	},
	
	clearComments: function ( )
	{
		$( 'comments' ).setHTML( "" );
		$( 'comments_new' ).setHTML( "" );
		if ( $( 'comment_preview' ) )
		{
			$( 'comment_preview' ).remove();
		}
		//this.updateCommentCount( -1 );
		$( this.options.formAdd ).reset();
	},
	
	/**
	 * Writes the comments HTML.
	 */
	writeComments: function ( pCommentData , pParams )
	{
		var target = pParams.target;
		var questionID = pParams.questionID;
		
		target.commentData = pCommentData;
		
		target.clearComments();
		
		target.commentCount = 0;
		var flaggedComments = Cookie.get( 'amex.comments_flag_' + questionID );
		if ( !flaggedComments ) flaggedComments = "";
		var curComment;
		if ( target.commentData.comments[0].comment )
		{
			for ( iComment = 0 ; iComment < target.commentData.comments[0].comment.length ; iComment++ )
			{
				curComment = target.commentData.comments[0].comment[ iComment ];
				if ( flaggedComments.indexOf( "c" + curComment[ 'id' ] + "," ) < 0 )
				{
					target.writeComment( 
						'comments' , 
						curComment.id , 
						curComment.display_name ,
						curComment.display_date ,
						curComment._text ,
						questionID
					);
					++target.commentCount;
				}
			}
		}
		target.updateCommentCount( target.commentCount );
		
		// Update styles, showing everything
		$( 'panel_comments' ).set( { 'styles':{ 'display':'block' } } );
		$( 'pane_main' ).set( { 'styles':{ 'width':'480px' , 'margin-right':'20px' } } );
		$( 'pane_side' ).set( { 'styles':{ 'display':'block' } } );
		$( 'comments' ).set( { 'styles':{ 'display':'block' } } );
	},
	
	updateCommentCount: function ( pCommentCount ) 
	{
		if ( pCommentCount >= 0 )
		{
			this.commentCount = pCommentCount;
			$( 'comments_count' ).setHTML( "(" + this.formatQuantity( this.commentCount , "comment" , "comments" ) + ")" );
			return;
		}
		if ( $( 'comments_count' ) ) $( 'comments_count' ).setHTML( "" );
	},
	
	/**
	 * Loads and parses comment data.
	 */
	loadComments: function ( pQuestionID )
	{
		// Clear old comments
		this.clearComments();
		
		// Show loading message
		$( 'comments_loading' ).set( { 'styles':{ 'display':'block' } } );
		
		//var urlXML = this.options.xmlPath + pQuestionID + ".xml?rnd=" + ( Math.floor( Math.random() * 99999 ) );
		var urlXML = this.options.xmlPath + "view.php?vid="+pQuestionID+"&rnd=" + ( Math.floor( Math.random() * 99999 ) );
		
		var ajaxXML = new Ajax( urlXML , { method:'get' } ).request();
		ajaxXML.eventObj = { 
			target:this , 
			questionID:pQuestionID
		};
		
		ajaxXML.addEvent( 
			'onComplete' , 
			function ( pStrXML ) { 
				this.eventObj.xml = pStrXML;
				this.eventObj.target.onCommentsLoaded( this.eventObj )
			}
		);
	},
	
	onCommentsLoaded: function ( pEvtObj ) 
	{
		if (document.implementation.createDocument) { // mozilla
			var parser = new DOMParser();
			doc = parser.parseFromString( pEvtObj.xml , 'text/xml' );
		} else if ( window.ActiveXObject ) { // ie
			doc = new ActiveXObject('Microsoft.XMLDOM');
			doc.async = 'false';
			doc.loadXML( pEvtObj.xml );
		}
		
		// Hide loading message
		$( 'comments_loading' ).set( { 'styles':{ 'display':'none' } } );
		
		var object = parseXML( doc );
		pEvtObj.target.writeComments( object , pEvtObj );
	},
	
	writeComment: function ( pTarget , pID , pDisplayName , pDisplayDate , pText , pQuestionID )
	{	
		var commentHTML = '';
		
		// Wrap with preview tag/message if writing preview
		if ( pID == 'NA' )
		{
			commentHTML += '<div id="comment_preview">';
			commentHTML += '	<div class="description">Below is a preview of your comment.</div>';
			commentHTML += '	<div class="instructions">Click Submit to send.</div>';
			commentHTML += '</div>';
		}
		
		commentHTML += '<div class="comment" id="comment' + pID + '">';
		commentHTML += '	<img src="images/ico_comment.png" class="icon" alt="Comment" width="15" height="12" />';
		commentHTML += '	<div class="author">' + pDisplayName + '</div>';
		commentHTML += '	<div class="date">- ' + pDisplayDate + '</div>';
		commentHTML += '	<div class="flag"><a href="javascript:void(' + pID + ');" onClick="amexComments.flagComment( \'' + pQuestionID + '\',' + pID + ')">Flag as Inappropriate</a></div>';
		commentHTML += '	<div id="copy_preview_c' + pID + '" class="copy_preview">';
		commentHTML += '		<p>' + pText + '</p>';
		commentHTML += '	</div>';
		commentHTML += '	<div id="copy_full_c' + pID + '" class="copy_full">';
		commentHTML += '		<p>' + pText + '</p>';
		commentHTML += '	</div>';
		commentHTML += '	<div id="collapse_c' + pID + '" class="collapse"><a href="javascript:collapseComment(' + pID + ');">Collapse</a></div>';
		commentHTML += '</div>';
		
		$( pTarget ).setHTML( $( pTarget ).innerHTML + commentHTML );
	},
	
	/*
	truncateComment: function ( pCommentID )
	{
		var len = 100;
		var p = document.getElementById('truncateMe');
		if (p) {
		
		  var trunc = p.innerHTML;
		  if (trunc.length > len) {
		
		    // Truncate the content of the P, then go back to the end of the
		    // previous word to ensure that we don't truncate in the middle of
		    // a word
		    trunc = trunc.substring(0, len);
		    trunc = trunc.replace(/\w+$/, '');
		
		    // Add an ellipses to the end and make it a link that expands
		    // the paragraph back to its original size /
		    trunc += '<a href="#" ' +
		      'onclick="this.parentNode.innerHTML=' +
		      'unescape(\''+escape(p.innerHTML)+'\');return false;">' +
		      '...<\/a>';
		    p.innerHTML = trunc;
		  }
		}
	}
	*/
	
	/**
	 * Flags the specified comment as inappropriate and temporarily hides it.
	 */
	flagComment: function ( pQuestionID , pCommentID )
	{
		if ( pCommentID == undefined || pCommentID == 'NA' ) return;
		
		this.updateCommentCount( this.commentCount - 1 );
		
		// Hide comment
		$( 'comment' + pCommentID ).set( { 'styles':{ 'display':'none' } } );
		
		// Set cookie
		var flaggedIDs = Cookie.get( "amex.comments_flag_" + pQuestionID );
		
		if ( !flaggedIDs ) flaggedIDs = '';
		flaggedIDs += "c" + pCommentID + ",";
		Cookie.set( "amex.comments_flag_" + pQuestionID , flaggedIDs , { duration:0.05 } ); // Expires in ~1 hour
		
		// Create new mootools Ajax instance
		this.xhrFlag = new XHR({ method:'get' }).send( this.options.urlFlag , "id=" + pCommentID );
		this.xhrFlag.addEvent( 'onSuccess' , this.onFlagComplete );
		//onComplete:this.options.onFlagComplete });
		return false;
	},
	
	onFlagComplete: function ( )
	{
	},
	
	/**
	 * Adds a submitted comment view the defined form.
	 */
	addComment: function ( pQuestionID )
	{
		// Create new mootools Ajax instance
		this.xhrAdd = new XHR({ method:'post' }).send( this.options.urlAdd , $( this.options.formAdd ).toQueryString() );
		this.xhrAdd[ 'referrer' ] = this;
		this.xhrAdd.addEvent( 'onSuccess' , this.onAddComplete );
		this.tmp.questionID = pQuestionID;
		return false;
	},
	
	onAddComplete: function ( )
	{
		this[ 'referrer' ].updateCommentCount( this[ 'referrer' ].commentCount + 1 );
		
		// Check if user prefers full name or initials
		var displayName = Cookie.get( 'amex.user_name' );
		if ( $( 'radInitials' ).checked ) displayName = Cookie.get( 'amex.user_initials' );
		
		// Create JSON object for cookie and set it
		var jsonData = 
		{
			commentID:    this.response.text ,
			commentData:
			{
				displayName:  displayName , 
				displayDate:  this[ 'referrer' ].getDateAsString() ,  
				text:         $( 'comments_form_commenttxt' ).getValue() , 
				questionID:   this[ 'referrer' ].tmp.questionID
			}
		}
		// Clear input
		this[ 'referrer' ].addClear();
		
		// Write added comment
		this[ 'referrer' ].writeComment( 
			"comments" , 
			jsonData.commentID ,
			jsonData.commentData.displayName , 
			jsonData.commentData.displayDate , 
			jsonData.commentData.text , 
			jsonData.commentData.questionID
		);
	},
	
	/**
	 * Called when the add comment textarea changes.
	 */
	onAddTextChange: function ( )
	{
		var textValue = $( 'comments_form_commenttxt' ).getValue();
		
		// Check if user prefers full name or initials
		var displayName = Cookie.get( 'amex.user_name' );
		if ( $( 'radInitials' ).checked ) displayName = Cookie.get( 'amex.user_initials' );
		
		// If there is text and no new comment element, create it
		if ( textValue.length > 0 && $( 'comment_preview' ) == undefined )
		{
			this.writeComment( 'comments_new' , 'NA' , displayName , this.getDateAsString() , textValue , 'NA' );
		}
		// If there is text and a new comment element, update comment
		else if ( textValue.length > 0 )
		{
			$( 'copy_preview_cNA' ).setText( textValue );
		}
		// Otherwise, remove the new comment area
		else
		{
			this.addClear();
		}
	},
	
	focusAdd: function ( )
	{
		$( 'comments_form_commenttxt' ).focus();
	},
	
	getDateAsString: function ( )
	{
		var dteCurrent = new Date();
		var arrMonths = [ "January" , "February" , "March" , "April" , "May" , "June" , "July", "August" , "September" , "November" , "December" ];
		return arrMonths[ dteCurrent.getMonth() ] + " " + dteCurrent.getDate() + ", " + dteCurrent.getFullYear();
	},
	
	getTimestamp: function ( )
	{
		var dteCurrent = new Date();
		return "" + ( dteCurrent.getMonth() + 1 ) + dteCurrent.getDate() + dteCurrent.getHours() + dteCurrent.getMinutes() + dteCurrent.getSeconds() + dteCurrent.getMilliseconds();
	},
	
	addClear: function ( ) 
	{
		$( this.options.formAdd ).reset();
		
		// Clear new comments area
		$( 'comments_new' ).setHTML( "" );
	}
	
});