var DEFAULT_COMMENTS_PER_PAGE = 30;
var MAX_COMMENT_CHARS = 1000;

var currentCommentPage = 1;
var commentsLoaded = 0;
var commentsPerPage = DEFAULT_COMMENTS_PER_PAGE;
var editing = false;

function initComments() {
	getCommentsForPage();
	jQuery(document).one('ajax_loginsuccess', onLoginSuccess);
}

function reloadComments() {
	commentsWereLoaded = commentsLoaded;
	getCommentsForPage(true, commentsWereLoaded);
}

function getCommentsForPage(refresh,limit) {
	if (typeof refresh != "undefined") {
		commentsLoaded = 0;
	}
	if (typeof limit != "undefined") {
		loadComments = limit;
	} else {
		loadComments = DEFAULT_COMMENTS_PER_PAGE;
	}
	
	var getCommentsCallback = {success: onGetCommentsSuccess, failure: onGetCommentsFailure, argument: {'commentsLoaded': loadComments+commentsLoaded}, scope: this};
	var sortOrder = document.getElementById('sort-comments').value;
	YAHOO.util.Connect.asyncRequest('GET',urlPrefix+'/comments/viewRPC/modulename/'+moduleName+'/topicID/'+topicID+'/commentsLoaded/'+commentsLoaded+'/limit/'+loadComments+'/sortby/'+sortOrder,getCommentsCallback,null);
	showLoader();
}

function onGetCommentsSuccess(o){
	comments = o.responseText;
	var output = document.getElementById('commentContainer');

	output.removeChild(document.getElementById('comment-loader'));
	if (commentsLoaded == 0) {
		output.innerHTML = comments;
	} else {
		output.innerHTML += comments;
	}
	commentsLoaded = o.argument.commentsLoaded;
	
	commentList = document.getElementById('commentList-'+commentsLoaded);
	
	connectActions(commentList);

	jQuery(document).trigger('comments_loaded');
}

function onGetCommentsFailure(oRequest,oResponse,oPayload) {
}

function addComment(event,eventData) {
	if ( (eventData.commentElement.value.length > 0) && (! checkMaxLength(eventData.commentElement,eventData.commentCountElement)) ) {
		var addCommentCallback = {success: onAddCommentSuccess, failure: onAddCommentFailure, scope: this, argument: eventData};
		YAHOO.util.Connect.asyncRequest('POST',urlPrefix+'/comments/add/modulename/'+moduleName,addCommentCallback,"parent="+eventData.parentID+"&id="+topicID+"&comment="+encodeURIComponent(eventData.commentElement.value));
	}
}

function onAddCommentSuccess(o){
	var eventData = o.argument;
	var comment = o.responseText;
	var temp = document.createElement('div');
	temp.innerHTML = comment;
	comment = temp.childNodes[0];
	var parentID = eventData.parentID;
	if (parentID) {
		(eventData.parentNode).replaceChild(comment, eventData.listItem);
		cancelReply(false, eventData);
	} else {
		var commentList = YAHOO.util.Dom.getChildren('commentContainer')[0];
		var children = YAHOO.util.Dom.getChildren(commentList);
		if (children.length > 0) {
			YAHOO.util.Dom.insertBefore(comment, children[0]);
		} else {
			commentList.appendChild(comment);
		}
	}
	
	
	if (!YAHOO.util.Dom.getClientRegion().contains(YAHOO.util.Dom.getRegion(comment))) { // Check to see if we should scroll to see the new comment in place
		//(new YAHOO.util.Scroll(document.body, { scroll: { to: YAHOO.util.Dom.getXY(comment) } }, .25, YAHOO.util.Easing.easeOut)).animate(); only works in Safari
		window.scrollTo(0,YAHOO.util.Dom.getY(comment)-100);
	}

	// reset the styles and character counters
	if (parentID == 0) {
		eventData.commentElement.value = '';
		checkMaxLength(eventData.commentElement,eventData.commentCountElement);
	}
	connectActions(comment);
}

// callback function when call to service fails
function onAddCommentFailure(oRequest,oResponse,oPayload) {
	alert('Sorry - we could not add your comment');
}

function reply(event,eventData) { //TODO: undisable if disabled.
	if (!jQuery(document).ajax_login('logged_in')) {
		askLogin(eventData, reply);
		return;
	}
	if (eventData == undefined) eventData = event.data;
	commentID = eventData.id;
	if (YAHOO.util.Dom.hasClass('d-'+commentID, 'disabled')) {
		toggle(false, eventData);
	}
	if (YAHOO.util.Dom.hasClass('d-'+commentID, 're-enabled')) {
		YAHOO.util.Dom.replaceClass('d-'+commentID, 're-enabled', 'not-re-enabled'); // Hide link gets hidden... when cancelling reply, should come back
		document.getElementById('togdiv-'+commentID).innerHTML = '';
	}

	var replyLink = document.getElementById('reply-'+eventData.id);
	if (!replyLink) return; //Don't allow someone to reply to themself

	replyLink.innerHTML = 'Replying...';
	replyLink.className = 'disabled';
	YAHOO.util.Event.removeListener(replyLink, "click");
	var replies = document.getElementById('r-' + commentID);
	if (replies) {
		ul = replies;
	} else {
		level = parseInt(document.getElementById('c_' + commentID).parentNode.className.split('-')[1]);
		ul = document.createElement('ul');
		ul.className = 'l-'+(level+1);
		YAHOO.util.Dom.insertAfter(ul,document.getElementById('d-'+commentID))
	}
	li = document.createElement('li');
	li.id = 'reply-item-'+commentID;
	li.className = 'comment reply';
	li.style.display = 'none';
	li.innerHTML = '<textarea id="commentEditor-'+commentID+'" class="short wide" name="reply" onkeyup="checkMaxLength(this,document.getElementById(\'editCharacterCounter-'+commentID+'\'))"></textarea><div class="clearfix"><p class="info"><strong>Characters used: <span id="editCharacterCounter-'+commentID+'" class="commentOK">0</span> ('+MAX_COMMENT_CHARS+' max.)</strong><br />'+(document.getElementById('attributed').innerHTML)+'</p><input id="reply-button-'+commentID+'" onclick="return false" class="submit hover" type="image" src="/images/blank.gif" value="submit" name="submit" /><input id="cancel-button-'+commentID+'" onclick="return false" class="cancel hover" type="image" src="/images/blank.gif" value="cancel" name="cancel" /></div>';
	
	ul.appendChild(li);

	(dojo.lfx.wipeIn(li,250,dojo.lfx.easeDefault,dojo_fix)).play();
	var replyButton = new YAHOO.util.Element('reply-button-'+commentID);
	var cancelButton = new YAHOO.util.Element('cancel-button-'+commentID);
	
	var eventData = new Object();
	eventData.parentID = commentID;
	eventData.commentElement = document.getElementById('commentEditor-'+commentID);
	eventData.commentCountElement = document.getElementById('editCharacterCounter-'+commentID);
	eventData.listItem = li;
	eventData.parentNode = ul;
	replyButton.on("click", addComment, eventData, this);
	cancelButton.on("click", cancelReply, eventData, this);
	
	if (!YAHOO.util.Dom.getClientRegion().contains(YAHOO.util.Dom.getRegion(eventData.commentElement))) { // Check to see if we should scroll to see the new comment in place
		//(new YAHOO.util.Scroll(document.body, { scroll: { to: YAHOO.util.Dom.getXY(comment) } }, .25, YAHOO.util.Easing.easeOut)).animate(); only works in Safari
		window.scrollTo(0,YAHOO.util.Dom.getY(eventData.commentElement) - YAHOO.util.Dom.getClientHeight() + 160); // Scroll to top of box - height of viewport + 160 = reply box top should be 160px off bottom of screen
	}
	
	eventData.commentElement.focus();
}

function cancelReply(event,eventData) {
	var replyLink = document.getElementById('reply-'+eventData.parentID);
	replyLink.innerHTML = 'Reply';
	replyLink.className = 'reply';
	addMethod(replyLink);
	if (event!=false) (dojo.lfx.wipeOut(eventData.listItem,250,dojo.lfx.easeDefault, removeElement)).play();
	if (YAHOO.util.Dom.hasClass('d-'+commentID, 'not-re-enabled')) { // Hide link gets shown if it was hidden
		YAHOO.util.Dom.replaceClass('d-'+commentID, 'not-re-enabled', 're-enabled')
		document.getElementById('togdiv-'+commentID).innerHTML = ' &#124; ';
	}
}

function editComment(event,eventData) {
	var commentID = eventData.id;
	if (!editing) {
		editing = true;
		var editedComment = document.getElementById('p-' + commentID);
		var commentHTML = editedComment.innerHTML;
		var editedCommentText = document.getElementById('t_' + commentID).innerHTML;

		editedComment.innerHTML = '<textarea id="commentEditor" class="short wide" name="editedComment" onkeyup="checkMaxLength(this,document.getElementById(\'editCharacterCounter\'))"></textarea><div class="clearfix"><p class="info"><strong>Characters used: <span id="editCharacterCounter" class="commentOK"></span> ('+MAX_COMMENT_CHARS+' max.)</strong></p><input id="edit-button" onclick="return false" class="submit hover" type="image" src="/images/blank.gif" value="submit" name="submit" /><input id="cancel-button" onclick="return false" class="cancel hover" type="image" src="/images/blank.gif" value="cancel" name="cancel" /></div>';

		// fill in the textarea with the text to edit - replacing any <br> tags with \r
		document.getElementById('commentEditor').value = editedCommentText.replace(/<br>/ig,"\r");

		var editButton = new YAHOO.util.Element('edit-button');
		var cancelButton = new YAHOO.util.Element('cancel-button');

		checkMaxLength(document.getElementById('commentEditor'),document.getElementById('editCharacterCounter'));
		var eventData = new Object();
		eventData.commentID = commentID;
		eventData.commentElement = document.getElementById('commentEditor');
		eventData.commentCountElement = document.getElementById('editCharacterCounter');
		eventData.original = commentHTML;
		editButton.on("click", saveEdit, eventData, this);
		cancelButton.on("click", cancelEdit, eventData, this);
	}
}

function saveEdit(event,eventData) {
	if ( (eventData.commentElement.value.length > 0) && (! checkMaxLength(eventData.commentElement,eventData.commentCountElement)) ) {
		var editCommentCallback = {success: onEditCommentSuccess, failure: onEditCommentFailure, scope: this, argument: eventData};
		YAHOO.util.Connect.asyncRequest('POST',urlPrefix+'/comments/edit',editCommentCallback,"id="+eventData.commentID+"&comment="+encodeURIComponent(eventData.commentElement.value));
	}
}

function cancelEdit(event,eventData) {
	editing = false; //re-enable editing of other comments
	//getCommentsForPage(currentCommentPage);
	document.getElementById('p-' + eventData.commentID).innerHTML = eventData.original;
}

function onEditCommentSuccess(o){
	editing = false; //re-enable editing of other comments
	eventData = o.argument;
	comment = o.responseText;
	document.getElementById('p-'+eventData.commentID).innerHTML = comment;	
}

// callback function when call to service fails
function onEditCommentFailure(oRequest,oResponse,oPayload) {
	alert('Sorry - we could not edit your comment');
}

function deleteComment(event,eventData) {
	if (confirm('Are you sure you want to delete this comment?')) {
		var delCommentCallback = {success: onDeleteCommentSuccess, failure: onDeleteCommentFailure, scope: this, argument: eventData.id};
		YAHOO.util.Connect.asyncRequest('POST',urlPrefix+'/comments/delete',delCommentCallback,"id="+eventData.id);
	}
}

function flagComment(commentID) {
	var flagCommentCallback = {success: onFlagCommentSuccess, failure: onFlagCommentFailure, scope: this, argument: commentID};
	dsFlagComment.sendRequest(YAHOO.Tools.printf('id/{0}',commentID), flagCommentCallback);	
}

function setTooltipPosition(event, argument) {
	region = YAHOO.util.Dom.getRegion(argument[0]);
	this.moveTo(region.left-20,region.top-95); // figure out difference for two graphics
}

function onDeleteCommentSuccess(o){
	id = o.argument;
	header = document.getElementById('h-'+id);
	header.innerHTML = 'This post has been removed by the author.';
	YAHOO.util.Dom.addClass(header.parentNode, 'deleted');

	YAHOO.util.Dom.addClass('c_'+id, 'disabled');
	YAHOO.util.Dom.addClass('d-'+id, 'disabled');
	
	(dojo.lfx.wipeOut(document.getElementById('p-'+id),250,dojo.lfx.easeDefault)).play();
}

// callback function when call to service fails
function onDeleteCommentFailure(oRequest,oResponse,oPayload) {
	alert('Sorry - we could not delete your comment');
}

function toggle(event, eventData) {
	var id=eventData.id;
	var div = document.getElementById('d-'+id);
	var li = document.getElementById('c_'+id);
	var toggle = document.getElementById('tog-'+id);
	if (YAHOO.util.Dom.hasClass(div, 'disabled')) {
		YAHOO.util.Dom.removeClass([div, li],'disabled');
		YAHOO.util.Dom.addClass(div,'re-enabled');
		toggle.innerHTML = 'Hide';
		if (document.getElementById('reply-'+id)) {
			document.getElementById('togdiv-'+id).innerHTML = " &#124; ";
		}
		(dojo.lfx.wipeIn(document.getElementById('p-'+id),250,dojo.lfx.easeDefault, dojo_fix)).play();
	} else {
		setTimeout("YAHOO.util.Dom.addClass(['d-"+id+"', 'c_"+id+"'],'disabled')", 250);
		(dojo.lfx.wipeOut(document.getElementById('p-'+id),250,dojo.lfx.easeDefault)).play();
		toggle.innerHTML = 'Show';
		document.getElementById('togdiv-'+id).innerHTML = "";
	}
}

function up(event, eventData) {
	if (!jQuery(document).ajax_login('logged_in')) {
		askLogin(eventData, up);
		return;
	}
	if (eventData == undefined) eventData = event.data;
	var id = eventData.id;

	var control = document.getElementById('z-'+id);
	if (!control) return; //Don't allow someone to vote on their own comment

	var voteCommentCallback = {success: onSetScoreSuccess, failure: onSetScoreFailure, argument: id, scope: this};
	if (YAHOO.util.Dom.hasClass(control, 'up')) {
		YAHOO.util.Connect.asyncRequest('POST',urlPrefix+'/comments/vote/comment/'+id,voteCommentCallback,"direction=remove");
		YAHOO.util.Dom.removeClass(control,'up');
	} else {
		if (YAHOO.util.Dom.hasClass('c_'+id,'disabled')) toggle(false, eventData);
		YAHOO.util.Connect.asyncRequest('POST',urlPrefix+'/comments/vote/comment/'+id,voteCommentCallback,"direction=up");
		YAHOO.util.Dom.replaceClass(control,'down','up');
	}
}

function down(event, eventData) {
	if (!jQuery(document).ajax_login('logged_in')) {
		askLogin(eventData, down);
		return;
	}
	if (eventData == undefined) eventData = event.data;
	var id = eventData.id;
	replyLink = document.getElementById('reply-'+id);
	if (replyLink != null && replyLink.innerHTML == 'Replying...') {
		eventData.parentID = id;
		eventData.listItem = document.getElementById('reply-item-'+id);
		cancelReply(event, eventData);
	}
	var control = document.getElementById('z-'+id);
	if (!control) return; //Don't allow someone to vote on their own comment

	var voteCommentCallback = {success: onSetScoreSuccess, failure: onSetScoreFailure, argument: id, scope: this};
	if (YAHOO.util.Dom.hasClass(control, 'down')) {
		if (YAHOO.util.Dom.hasClass('d-'+id, 'disabled')) toggle(false, eventData);
		YAHOO.util.Connect.asyncRequest('POST',urlPrefix+'/comments/vote/comment/'+id,voteCommentCallback,"direction=remove");
		YAHOO.util.Dom.removeClass(control,'down');
	} else {
		if (!YAHOO.util.Dom.hasClass('d-'+id, 'disabled')) toggle(false, eventData);
		YAHOO.util.Connect.asyncRequest('POST',urlPrefix+'/comments/vote/comment/'+id,voteCommentCallback,"direction=down");
		YAHOO.util.Dom.replaceClass(control,'up','down');
	}
}

function onSetScoreSuccess(o) {
	id = o.argument;
	response = YAHOO.lang.JSON.parse(o.responseText);
	if (response.status == 'success') {
		scoreElement = document.getElementById('s-'+id);
		userScoreElement = document.getElementById('us-'+id);
		score = parseInt(scoreElement.innerHTML) + parseInt(response.score);
		userScore = parseInt(userScoreElement.innerHTML) + parseInt(response.score);
		scoreElement.innerHTML = score > 0 ? '+'+score : score;
		userScoreElement.innerHTML = userScore > 0 ? '+'+userScore : userScore;
		if (score > 0) {
			YAHOO.util.Dom.replaceClass(scoreElement, 'neg', 'pos');
		} else if (score < 0) {
			YAHOO.util.Dom.replaceClass(scoreElement, 'pos', 'neg');
		} else {
			YAHOO.util.Dom.removeClass(scoreElement, 'neg');
			YAHOO.util.Dom.removeClass(scoreElement, 'pos');
		}
	}
}

// callback function when call to service fails
function onSetScoreFailure(oRequest,oResponse,oPayload) {
	alert('Sorry - we could not rate this comment');
}

function connectActions(commentList) {
	YAHOO.util.Dom.getElementsByClassName('reply', 'a', commentList, addMethod);
	YAHOO.util.Dom.getElementsByClassName('toggle', 'a', commentList, addMethod);
	YAHOO.util.Dom.getElementsByClassName('vote-up', 'a', commentList, addMethod);
	YAHOO.util.Dom.getElementsByClassName('vote-down', 'a', commentList, addMethod);
	YAHOO.util.Dom.getElementsByClassName('delete', 'a', commentList, addMethod);
	YAHOO.util.Dom.getElementsByClassName('edit', 'a', commentList, addMethod);
	
	TEDCred2_tooltip = new YAHOO.widget.Tooltip("TEDCred2_tooltip", { context:YAHOO.util.Dom.getElementsByClassName('TEDCred2', 'span', commentList), text:'<div class="TEDCred-tooltip"><h4>TEDCred:</h4><p>This medal goes to members whose comments earned 1000+ points.</p></div>', container:'utility', preventoverlap:false, autodismissdelay: 15000, effect:{effect:YAHOO.widget.ContainerEffect.FADE,duration:0.25}, monitorresize: false, showDelay:250 } );
	TEDCred1_tooltip = new YAHOO.widget.Tooltip("TEDCred1_tooltip", { context:YAHOO.util.Dom.getElementsByClassName('TEDCred1', 'span', commentList), text:'<div class="TEDCred-tooltip"><h4>TEDCred:</h4><p>This medal goes to members whose comments earned 100+ points.</p></div>', container:'utility', preventoverlap:false, autodismissdelay: 15000, effect:{effect:YAHOO.widget.ContainerEffect.FADE,duration:0.25}, monitorresize: false, showDelay:250 } );
	
	TEDCred2_tooltip.contextTriggerEvent.subscribe(setTooltipPosition);
	TEDCred1_tooltip.contextTriggerEvent.subscribe(setTooltipPosition);
}

function addMethod(object) {
	eventData = new Object();
	eventData.object = object;
	eventData.id = object.id.split('-')[1];
	if (YAHOO.util.Dom.hasClass(object, 'reply')) {
		YAHOO.util.Event.addListener(object, 'click', reply, eventData, this);
	} else if (YAHOO.util.Dom.hasClass(object, 'toggle')) {
		YAHOO.util.Event.addListener(object, 'click', toggle, eventData, this);
	} else if (YAHOO.util.Dom.hasClass(object, 'vote-up')) {
		YAHOO.util.Event.addListener(object, 'click', up, eventData, this);
	} else if (YAHOO.util.Dom.hasClass(object, 'vote-down')) {
		YAHOO.util.Event.addListener(object, 'click', down, eventData, this);
	} else if (YAHOO.util.Dom.hasClass(object, 'delete')) {
		YAHOO.util.Event.addListener(object, 'click', deleteComment, eventData, this);
	} else if (YAHOO.util.Dom.hasClass(object, 'edit')) {
		YAHOO.util.Event.addListener(object, 'click', editComment, eventData, this);
	}
}

function checkMaxLength(commentElement,counterElement) {
	var CRITICAL_LEVEL = MAX_COMMENT_CHARS - 10;
	var WARNING_LEVEL = MAX_COMMENT_CHARS - 100;
	var exceeded = false;
	if (commentElement.value.length > MAX_COMMENT_CHARS) {
		commentElement.value = commentElement.value.substring(0, MAX_COMMENT_CHARS);
		counterElement.className = 'commentCritical';
		exceeded = true;
	}
	else if (commentElement.value.length > CRITICAL_LEVEL) {
		counterElement.className = 'commentCritical';
	}
	else if (commentElement.value.length > WARNING_LEVEL) {
		counterElement.className = 'commentWarning';
	}
	else {
		counterElement.className = 'commentOK';
	}
	counterElement.innerHTML = '' + commentElement.value.length;
		
	return exceeded;
}

function showLoader() {
	var e = document.getElementById('comment-loader');
	// if the element isn't defined the bypass the showing the loader icon
	if (e != null) {
		e.innerHTML = '<img src="http://www.ted.com/images/ajax-loader.gif" />';
	}
}

function removeElement(object) {
	(object.parentNode).removeChild(object);
}

function dojo_fix(object) {
	object.style.height='';//dojo isn't unsetting the height when finishing animations
}
	
function askLogin(eventData, fn) {
	jQuery(document).ajax_login('set_title', 'Sign in to comment on this talk!').ajax_login('show_login');

	if (fn != undefined) {
		//after the comments have reloaded, continue whatever function we started unless we cancelled the login attempt
		jQuery(document).one('comments_loaded', eventData, fn);
		jQuery(document).one('ajax_logincancelled', fn, function(event) {
			jQuery(document).unbind('comments_loaded', event.data);
		});
	}
}

function onCommentsReloaded() {
	if (jQuery(document).ajax_login('logged_in')) {
		jQuery('#discussion').removeClass('signed-out');
		jQuery('#discussion a.username-profile-link').html(jQuery(document).ajax_login('option', 'fullname')).attr('href', "http://www.ted.com/profiles/view/id/"+jQuery(document).ajax_login('option', 'profileID'));
	}
}

function onLoginSuccess() {
	jQuery(document).one('comments_loaded', onCommentsReloaded);
	reloadComments();
}