
// - ///////////////////////////////////////////////////////////////////////
// - PHONEDOG COMMENTS MODULE
// - ///////////////////////////////////////////////////////////////////////
// - Looks for a submit button with the comment id and then attaches
// - event click observer to sumbit the comment via ajax
//fields
pdCommentsModule.prototype._transport;
pdCommentsModule.prototype._user;
pdCommentsModule.prototype._channelId = 'site.comments';
pdCommentsModule.prototype._sortField ;
pdCommentsModule.prototype._sortReverse;
pdCommentsModule.prototype._currentPage;
pdCommentsModule.prototype._pageLength;
pdCommentsModule.prototype._totalItems;
pdCommentsModule.prototype._contentId;
pdCommentsModule.prototype._itemId;
pdCommentsModule.prototype._BACK_PAGE_NUMBER = -2;
pdCommentsModule.prototype._NEXT_PAGE_NUMBER = -1;
pdCommentsModule.prototype._PAGE_NUMBER_LIMIT = 6;

function pdCommentsModule() {}

pdCommentsModule.prototype.initialize = function(transport, user){
  	//this function is called back during module registration
	this._transport = transport;
	this._user = user;
	
	// Ensure that we have a comment submit button since the class
	// gets initialized on all pages but not all pages have comment forms
	if($('cmt_submit')){
		//hold reference to "this" to pass along
		var me = this;	
	
		//default parameters for retrieving comments
		this._sortField = 'PublishDate';
		this._sortReverse = 'False';
		this._currentPage = 1;
		this._pageLength = 20;	
		this._contentId = $('cmt_threadid').value;
		this._itemId = $('cmt_itemid').value;
		this._totalItems = $('cmt_total').value;
		
		//reset paging if we have more comments that we're displaying now
		if(this._totalItems > this._pageLength){
			this.resetPaging(this._totalItems);
		}

		// build the user login / registration information 
		// if we have a user that is currently not logged in	
		if(!this._user.isLoggedIn()){		
			var userWrapper = $('commentform-user');
			userWrapper.update();
			
			var userNewWrapper = new Element('div', {'class':'commentform-userinfo clearfix', id:'commentform-userinfo-new'});			
			var userNewInfoTxt = new Element('div', {'class':'commentform-userinfotxt'}).update('First time posting? A confirmation e-mail will be sent to you after submitting.');

			var userNewInfo1 = new Element('div', {'class':'commentform-userinfo1'});
			userNewInfo1.appendChild(new Element('b').update('Display name:'));
			userNewInfo1.appendChild(new Element('input', {type:'text', id:'user_new_name', maxlength:20}));
			
			var userNewInfo2 = new Element('div', {'class':'commentform-userinfo2'});
			userNewInfo2.appendChild(new Element('b').update('Email:'));
			userNewInfo2.appendChild(new Element('input', {type:'text', id:'user_new_email', maxlength:80}));
			
			var userNewInfoToggle = new Element('div', {'class':'commentform-userinfo-toggle'});
			userNewInfoToggle.appendChild(new Element('span').update('Posted before or have a PhoneDog account? '));
			userNewInfoToggle.appendChild(new Element('a', {id:'commentform-userinfo-linknew', style:'font-weight:bold;'}).update('Sign in here')).observe('click',this.onSigninClick.bindAsEventListener(this));			
			userNewWrapper.appendChild(userNewInfoTxt);
			userNewWrapper.appendChild(userNewInfo1);
			userNewWrapper.appendChild(userNewInfo2);
			
			var userNewInfoReceiveEmail = new Element('div', {'class':'commentform-userinfo-subscribe'});
			userNewInfoReceiveEmail.appendChild(new Element('input', {type:'checkbox', id:'user_new_receiveemail'}));
			userNewInfoReceiveEmail.appendChild(new Element('span').update('Subscribe to the daily digest (email summary of the day\'s news)'));
			userNewWrapper.appendChild(userNewInfoReceiveEmail);
			
			userNewWrapper.appendChild(userNewInfoToggle);			

			var userExistingWrapper = new Element('div', {'class':'commentform-userinfo clearfix', id:'commentform-userinfo-existing', style:'display:none;' });
			var userExistingInfoTxt = new Element('div', {'class':'commentform-userinfotxt'}).update('Returning members, please enter your username and password.');

			var userExistingInfo1 = new Element('div', {'class':'commentform-userinfo1'});
			userExistingInfo1.appendChild(new Element('b').update('Username:'));
			userExistingInfo1.appendChild(new Element('input', {type:'text', id:'user_existing_username', maxlength:20}));
			
			var userExistingInfo2 = new Element('div', {'class':'commentform-userinfo2'});
			userExistingInfo2.appendChild(new Element('b').update('Password:'));
			userExistingInfo2.appendChild(new Element('input', {type:'password', id:'user_existing_password', maxlength:20}));			
			
			var userExistingInfoToggle = new Element('div', {'class':'commentform-userinfo-toggle'});
			userExistingInfoToggle.appendChild(new Element('span').update('Posted before or have a PhoneDog account? '));
			userExistingInfoToggle.appendChild(new Element('a', {id:'commentform-userinfo-linkexisting', style:'font-weight:bold;'}).update('First-time poster')).observe('click',this.onSigninClick.bindAsEventListener(this));
			userExistingInfoToggle.appendChild(new Element('span').update(', &nbsp; or '));
			userExistingInfoToggle.appendChild(new Element('a', {id:'commentform-userinf-forgot', href:'/community/login.aspx'}).update('forgot your login?'));												
			userExistingWrapper.appendChild(userExistingInfoTxt);
			userExistingWrapper.appendChild(userExistingInfo1);
			userExistingWrapper.appendChild(userExistingInfo2);
			userExistingWrapper.appendChild(userExistingInfoToggle);
			
			userWrapper.appendChild(userNewWrapper);
			userWrapper.appendChild(userExistingWrapper);
			
			// add extra footer information
			var footerInfo = $('commentform-footer-user');
			var footerInfoWrapper = new Element('div', {'class':'commentform-footer'}).update('<b>Email addresses are never displayed, but are required to confirm your comments.</b> Please keep your comments relevant to this post. <span>When you enter your name and email address, we\'ll send you a link to confirm your comment, and a password. To leave subsequent comments, simply use that password.</span>');
			footerInfo.appendChild(footerInfoWrapper);
		}else{
			//for logged in users, check if they already receive the daily digest
			//and if not then add the checkbox - unchecked at the bottom of the form
			if(this._user.getHasDigest() < 1){
				$('commentform-receiveemail').show();
			}
		}
	
		// attach input field beautifications
		$('commentform').select('input, textarea').each(function(input){
			input.observe('focus',me.onInputFocus.bindAsEventListener(me));
			input.observe('blur',me.onInputBlur.bindAsEventListener(me));
		});
		
		// reset the submit button
		$('cmt_submit').value='Submit comment';
		$('cmt_submit').disabled=false;
		$('cmt_submit').observe('click',this.onSubmitClick.bindAsEventListener(this));				
		
		// reset possibly cached values
		$('cmt_parentid').value = '0';
		$('cmt_txt').value = '';
		
		//attach events
		this.attachEvents();
		
		// if we have a comment_ hash in the location then scroll 
		// the window down to that element
		if(window.location.hash && window.location.hash.indexOf('comment_')!=-1){
			if($(window.location.hash.replace('#',''))){
				$(window.location.hash.replace('#','')).scrollTo();
			}
		}
	}
}

pdCommentsModule.prototype.attachEvents = function(){
	var me = this;

	// find all comments-vote divs and build the voting icons
	$$('.comments-vote').each(function(div){
		var voteResponse = new Element('span');
		var votePlus = new Element('a', {href:'#', 'class':'comments_vote_plus', title:'I like... I like!'});
		var voteMinus = new Element('a', {href:'#', 'class':'comments_vote_minus', title:'This one... ah, not so much!'});
		var voteReport = new Element('a', {href:'#', 'class':'comments_vote_report', title:'Ouch... I\'m gonna tell the PhoneDog!'});

		votePlus.observe('click',me.onVoteClick.bindAsEventListener(me,2));
		voteMinus.observe('click',me.onVoteClick.bindAsEventListener(me,1));
		voteReport.observe('click',me.onVoteClick.bindAsEventListener(me,-1));
		
		div.appendChild(voteResponse);
		div.appendChild(votePlus);
		div.appendChild(voteMinus);
		div.appendChild(voteReport);
	});
	
		
	// Attach event listeners to reply links
	$$('.comments-reply').each(function(reply){reply.observe('click',me.onReplyClick.bindAsEventListener(me));});		
}

pdCommentsModule.prototype.isEmail = function(s){
	var good="@_-.:/ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
	var upper=s.toUpperCase()
	var valid=true;	
	for(x=0; x>s.length; x++){c=upper.charAt(x);for(y=0; y<good.length; y++){if(c==good.charAt(y)){break;}}if(y==good.length){valid=false;break;}}	
	if (!valid || s.length < 7 || s.indexOf("@") == "-1" || s.indexOf(".") == "-1" || s.indexOf("@") != s.lastIndexOf("@")) {return (false);}else{return (true);}
}

pdCommentsModule.prototype.isValidUsername = function(s){
	var goodCharacters = ['@','_','-','.','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','0','1','2','3','4','5','6','7','8','9'];
	var usernameUpper = s.toUpperCase();
	var isValid = true;
	for(var x=0; x<usernameUpper.length; x++){if(goodCharacters.indexOf(usernameUpper.charAt(x)) == -1){isValid = false;}}
	return isValid;
}

pdCommentsModule.prototype.getCommentId = function(clickElement){
	var divItem = clickElement.up('.comments-item');
	return divItem.identify().split('_')[1];
}

pdCommentsModule.prototype.showError = function(msg){
	$('commentform-errors').update(msg);
	$('commentform-errors').show();
	pd_globalSiteFramework.trackEvent('Comments', 'Error', msg);
}

pdCommentsModule.prototype.onSigninClick = function(event){
	var element = Event.element(event);
	var id = element.identify();	

	//reset all fields
	$('user_new_name').value = '';
	$('user_new_email').value = '';
	$('user_existing_username').value = '';
	$('user_existing_password').value = '';	

	if(id == 'commentform-userinfo-linknew'){
		$('commentform-userinfo-new').hide();
		$('commentform-userinfo-existing').show();
		pd_globalSiteFramework.trackEvent('Comments', 'Toggle signin - existing');
	}else{
		$('commentform-userinfo-existing').hide();	
		$('commentform-userinfo-new').show();
		pd_globalSiteFramework.trackEvent('Comments', 'Toggle signin - new');
	}
}

pdCommentsModule.prototype.onInputFocus = function(event){
	var element = Event.element(event);
	element.addClassName('on');
}

pdCommentsModule.prototype.onInputBlur = function(event){
	var element = Event.element(event);
	element.removeClassName('on');
}

pdCommentsModule.prototype.onVoteClick = function(event, vote){
	event.stop();
	var element = Event.element(event);
	var indicator = element.up().down('span');
	var commentId = this.getCommentId(element);	
	var saveVote = true;
	var request = {
		contentId : commentId,
		rating : vote,
		referrerUrl : $('cmt_referrerurl').value
	};
	
	// make the user confirm reporting a comment
	if(vote == -1 && !confirm('Are you sure you want to report this comment?')){
		saveVote = false;
	}
	
	if(saveVote){	
		this._transport.transmitRequest('site.shared', 'setrating', request, this.onVoteSaveCompleted.bindAsEventListener(this, element, vote, indicator));			
	}
}

pdCommentsModule.prototype.onVoteSaveCompleted = function(objResponse, element, vote, indicator){
	// -1 = indicates comment was reported
	// 0 = indicates previously voted
	// otherwise returns new rating of comment
	if(objResponse.rating == -1){
		indicator.update('Comment reported!');
	}else if(objResponse.rating == 0){
		indicator.update('You already voted');
	}else{
		if(vote == 1){
			indicator.update('You voted down');
		}else{
			indicator.update('You voted up');
		}		
		pd_globalSiteFramework.trackEvent('Comments', 'Voted', vote);
		window.setTimeout(function() {indicator.update('Thanks for voting') }, 2000);
	}
	
	//hide the voting links
	element.up().select('a').each(function(link){link.hide();});
}

pdCommentsModule.prototype.onReplyClick = function(event){
	event.stop();
	var element = Event.element(event);
	var commentId = this.getCommentId(element);
	var replyinfo = $('commentform-replyinfo');
	var author = element.up('.comments-item').down('.comments-header').childElements()[0].innerHTML;
	var replyTxt = new Element('span').update('You\'re replying to ');
	var replySpace = new Element('span').update(' - ');
	var authorLink = new Element('a',{href:'#comment_'+commentId}).update(author);
	var removeLink = new Element('a',{href:'#'}).update('undo reply');
	removeLink.observe('click',this.onReplyRemoveClick.bindAsEventListener(this));

	// set reply information	
	replyinfo.update();
	replyinfo.appendChild(replyTxt);
	replyinfo.appendChild(authorLink);
	replyinfo.appendChild(replySpace);
	replyinfo.appendChild(removeLink);	
	
	// store the reply comment id
	$('cmt_parentid').value = commentId;
	
	// scroll to the comment form
	$('commentform').scrollTo();
	
	pd_globalSiteFramework.trackEvent('Comments', 'Reply  - click');
}

pdCommentsModule.prototype.onReplyRemoveClick = function(event){
	event.stop();
	$('cmt_parentid').value = '0';
	$('commentform-replyinfo').update();
	pd_globalSiteFramework.trackEvent('Comments', 'Reply - unclick');
}

pdCommentsModule.prototype.onSubmitClick = function(event){	
	// these are always available
	var submit = Event.element(event);
	var comment = $('cmt_txt');
	var isnewuser = ($('commentform-userinfo-new') && $('commentform-userinfo-new').style.display == 'none') ? false : true;
	var postData;
	var name = '';
	var email = '';
	var username = '';
	var password = '';
	var isLive = false;
	var subscribe = $('cmt_subscribe').checked;
	var receiveEmail = false;
	
	// these are only available if we are not logged in
	if(!this._user.isLoggedIn()){
		var new_name = $('user_new_name');
		var new_email = $('user_new_email');
		var existing_username = $('user_existing_username');
		var existing_password = $('user_existing_password');
	
		if(isnewuser){
			if(new_name.value==''){this.showError('Please enter your desired display name');new_name.focus();return false;}
			if(new_email.value==''){this.showError('Please enter your email address');new_email.focus();return false;}
			if(new_name.value.length<6){this.showError('Your display name must be a minimum of 6 characters');new_name.focus();return false;}
			if(!this.isValidUsername(new_name.value)){this.showError('Display name contains invalid characters - please use only a combination of letters, numbers, and the characters @._ but no spaces');new_name.focus();return false;}
			if(!this.isEmail(new_email.value)){this.showError('Your email address appears to be invalid - Please double-check it and try again.');new_email.focus();return false;}
			
			username = '';
			password = '';
			name = new_name.value;
			email = new_email.value;
			receiveEmail = $('user_new_receiveemail').checked;
		}else{
			if(existing_username.value==''){this.showError('Please enter your username');existing_username.focus();return false;}
			if(existing_password.value==''){this.showError('Please enter your password');existing_password.focus();return false;}		
			
			name = '';
			email = '';
			isLive = true;
			username = existing_username.value;
			password = existing_password.value;
		}
	}else{
		isLive = true;
		
		if(this._user.getHasDigest() < 1 && $('cmt_receiveEmail').checked){
			receiveEmail = true;
		}		
	}
	
	//validate entering a proper comment	
	if(comment.value==''){this.showError('Please enter your comments');comment.focus();return false;}	
	
	submit.value='Submitting';
	submit.disabled=true;
	
	var request = {
		threadId:$('cmt_threadid').value,
		parentId:$('cmt_parentid').value,
		itemId:$('cmt_itemid').value,
		sectionId:$('cmt_sectionid').value,
		subSectionId:$('cmt_subsectionid').value,
		referrerUrl:$('cmt_referrerurl').value,
		subscribe:subscribe,
		text:$('cmt_txt').value.stripScripts().stripTags().gsub('\n','<br/>'),
		userNewName:name,
		userNewEmail:email,
		userExistingUsername:username,
		userExistingPassword:password,
		receiveEmail:receiveEmail
	};	
	
	this._transport.transmitRequest('site.shared', 'setcomment', request, this.onCommentSaveCompleted.bindAsEventListener(this, submit, isLive, username, password));
}

pdCommentsModule.prototype.onCommentSaveCompleted = function(objResponse, submit, isLive, username, password){
	// Present user error here based on whether we have a result that's "Ok"
	// or a possible error wich would indicate a user registration or signin problem
	if(objResponse.result == 'Ok'){
		$('commentform-errors').update();
		$('commentform').hide();
		$('commentsubmitted').show();		
		
		if(isLive == true){
			$('commentsubmitted').update('<b>Thanks for submitting your comment.</b><p/>Refresh this page to view your comment!');
			pd_globalSiteFramework.trackEvent('Comments', 'Saved - existing user');
			
			//if we have a username/password then also log in the user - no callback needed
			if(username.length > 0 && password.length > 0){
				pd_globalSiteFramework.login(username, password, null);
			}
		}else{		
			$('commentsubmitted').update('<b>Thanks for submitting your comment.</b> Please check your email inbox for instructions on how to activate your account and comment.');
			pd_globalSiteFramework.trackEvent('Comments', 'Saved - new user');
		}
	}else{
		//show the error message and enable the submit button again
		$('commentform-errors').update(objResponse.errorMessage);	
		$('commentform-errors').show();
		submit.value='Submit Comment';
		submit.disabled = false;	
		
		pd_globalSiteFramework.trackEvent('Comments', 'Error', objResponse.errorMessage);			
	}
}


// - /////////////////////////////////////////////////////////////////
// - COMMENT LIST LOADING
// - /////////////////////////////////////////////////////////////////
pdCommentsModule.prototype.loadComments = function(){
	var request = {
		'contentId': this._contentId,
		'itemId': this._itemId,
		'sortField': this._sortField,
		'sortDesc': this._sortReverse,
		'pageIndex': this._currentPage, 
		'pageSize': this._pageLength
	};
	
	this._transport.transmitRequest('site.shared', 'getcontentcomments', request, this.onCommentsRetrieved.bindAsEventListener(this));	
}

pdCommentsModule.prototype.onCommentsRetrieved = function(objResponse){
	if(objResponse.comments){
		this.resetPaging(objResponse.total);
		
		if (objResponse.comments.length > 0){
			$('divCommentsList').update();
					
			for (var i = 0; i < objResponse.comments.length; i++){
				var comment = objResponse.comments[i];

				if(comment.parentid != 0){
					var commentItem = new Element('div', {'class' : 'comments-item comments-item-child clearfix', 'id': 'comment_' + comment.id});
					commentItem.appendChild(new Element('div', {'class' : 'comments-vote'}));

					var author = new Element('div', {'class' : 'comments-author-child'});
					var authorLink = new Element('a', {'href' : comment.authorurl});
					var authorImg = new Element('img', {'src' : comment.authorimage, 'border' : '0'});
					authorLink.appendChild(authorImg);
					author.appendChild(authorLink);					
					commentItem.appendChild(author);
					
					var header = new Element('div', {'class' : 'comments-header'});
					var headerLink = new Element('a', {'href' : comment.authorurl}).update(comment.authorname);
					var headerDate = new Element('span').update(' @ ' + comment.publishdate);
					header.appendChild(headerLink);
					header.appendChild(headerDate);
					commentItem.appendChild(header);
					
					var content = new Element('div', {'class' : 'comments-content-child'}).update(comment.text);
					commentItem.appendChild(content);
				}else{
					var commentItem = new Element('div', {'class' : 'comments-item clearfix', 'id': 'comment_' + comment.id});
					commentItem.appendChild(new Element('div', {'class' : 'comments-vote'}));

					var author = new Element('div', {'class' : 'comments-author'});
					var authorLink = new Element('a', {'href' : comment.authorurl});
					var authorImg = new Element('img', {'src' : comment.authorimage, 'border' : '0'});	
					authorLink.appendChild(authorImg);
					author.appendChild(authorLink);					
					commentItem.appendChild(author);
							
					var header = new Element('div', {'class' : 'comments-header'});
					var headerLink = new Element('a', {'href' : comment.authorurl}).update(comment.authorname);
					var headerDate = new Element('span').update(' @ ' + comment.publishdate);
					header.appendChild(headerLink);
					header.appendChild(headerDate);
					commentItem.appendChild(header);
				
					var content = new Element('div', {'class' : 'comments-content'}).update(comment.text);
					var reply = new Element('div', {'class' : 'comments-reply'});
					var replyLink = new Element('a', {'href' : '#'}).update('Reply to this comment');
					reply.appendChild(replyLink);
					content.appendChild(reply);
					commentItem.appendChild(content);
				}				
				
				$('divCommentsList').appendChild(commentItem);
			}						
			
			//attach events
			this.attachEvents();
			
			//scroll back up
			$('divComments').scrollTo();	
		}else{
			//no comments
		}	
		
		pd_globalSiteFramework.trackEvent('Comments', 'Page - ' + this._currentPage);
	}
}

pdCommentsModule.prototype.resetPaging = function (itemsCount){	
	var paging = $('divCommentsPaging');
	var ulList = new Element('ul');
	
	paging.update('');	
	
	if (itemsCount > 0){
		//round up to get a whole number of pages
		var pageCount = Math.ceil(itemsCount / this._pageLength); 
		
		if (pageCount > 1){
			//add a link to view all comments on one page unless we're already showing all
			if(this._pageLength != this._totalItems){
				var divAll = new Element('div', {'class' : 'viewall'});
				var linkAll = new Element('a', {'href' : '#'}).update('View all ' + this._totalItems + ' comments');
				linkAll.observe('click', this.onAllCommentsClicked.bind(this));
				divAll.appendChild(linkAll);				
				paging.appendChild(divAll);
			}		
		
			//figure out the upper and lower page numbers, based on the current page
			var minPageNumber = Math.max(1, this._currentPage - parseInt(this._PAGE_NUMBER_LIMIT/2) );
			var maxPageNumber = Math.min(pageCount, this._currentPage + parseInt(this._PAGE_NUMBER_LIMIT/2) );
			if (maxPageNumber - minPageNumber < this._PAGE_NUMBER_LIMIT - 1){
				//insufficient pages displayed - attempt to increase the max number
				 maxPageNumber = Math.min(pageCount, minPageNumber + this._PAGE_NUMBER_LIMIT - 1 );
			}
			if (maxPageNumber - minPageNumber < this._PAGE_NUMBER_LIMIT - 1){
				//insufficient pages displayed - attempt to decrease the min number
				 minPageNumber = Math.max(1, maxPageNumber - this._PAGE_NUMBER_LIMIT + 1 );
			}		
		
			//if not the first page, add the 'first'
			if (this._currentPage > 1){
				ulList.appendChild(this.addPagingLink ('pageFirst', '&laquo; First', 1, 'prevnext'));
			}
			
			//add the page numbers
			for (var p = minPageNumber; p <= maxPageNumber; p++){
				if (p==this._currentPage){
					ulList.appendChild(this.addPagingLink ('pageTo' + p, p, p, 'active'));
				}else{
					ulList.appendChild(this.addPagingLink ('pageTo' + p, p , p, ''));
				}														
			}
			
			//if not the last page, add the 'last' links
			if (this._currentPage < pageCount){
				ulList.appendChild(this.addPagingLink ('pageLast', 'Last &raquo;', pageCount, 'prevnext'));
			}
			
			paging.appendChild(ulList);
		}
	}
}

pdCommentsModule.prototype.addPagingLink = function (refId, description, pageNumber, className){
	var listItem = new Element('li', {'class' : className});
	var listLink = new Element('A', {href: '#', id: refId}).update(description);	
	listItem.appendChild(listLink);
	Event.observe(listLink, 'click', this.onPageClicked.bindAsEventListener(this, pageNumber));	
	return listItem;
}

pdCommentsModule.prototype.onPageClicked = function (event, pageNumber){
	//navigate to chosen page
	Event.stop(event);
	if (pageNumber == this._BACK_PAGE_NUMBER){
		this._currentPage-- ;
	}else if (pageNumber == this._NEXT_PAGE_NUMBER){
		this._currentPage++ ;		
	}else{
		this._currentPage = pageNumber;
	}
	this.loadComments();
}

pdCommentsModule.prototype.onAllCommentsClicked = function(event){
	Event.stop(event);
	this._currentPage = 1;
	this._pageLength = this._totalItems;
	this.loadComments();
	
	pd_globalSiteFramework.trackEvent('Comments', 'All comments');
}