var comments = new Array();
var currentEditCommentId = -1;

function Comment(id, text, displayText, date, name, email, editable, deletable) {
	this.id = id;
	this.text = text;
	this.displayText = displayText;
	this.date = date;
	this.name = name;
	this.email = email;
	this.editableByThisUser = editable;
	this.deletableByThisUser = deletable;
	this.deleting = false;
}

function handleAddComment() {
	if (currentlyBusy()) {
		return;
	}
	
	document.getElementById("nextcommentaction").value = ACTION_ADD_COMMENT;

	var textObj = document.getElementById("comment");
	imposeMaxLength(textObj);

	var text = textObj.value;
	if (text == "" || text.length == 0)
		return true;
	document.getElementById(COMMENT_VALUE_PARAM).value = text;

	if (document.getElementById("postpublic").checked == true)
		document.getElementById(COMMENT_VISIBILITY_PARAM).value = VISIBILITY_PUBLIC;
	else
		document.getElementById(COMMENT_VISIBILITY_PARAM).value = VISIBILITY_PRIVATE;

	if (xmlhttp) 
		doXmlHttpSubmit(callbackResponse_AddComment);
	else
		doSubmit();	

	return false;	
}

var callbackResponse_AddComment_locked = false;
function callbackResponse_AddComment() {
	if (xmlhttp.readyState != 4)
		return;
	try {
		if (callbackResponse_AddComment_locked == true)
			return;
		callbackResponse_AddComment_locked = true;

		var xml = xmlhttp.responseXML;
		if (xml) {
			var photoid = getElText(xml, 'photoid');
			var curphoto = getCurrentPhoto();
			if (photoid == curphoto.id) {
				var newComment = new Comment();
				newComment.id = getElText(xml, 'id');

				for (var idx=0; idx < curphoto.comments.length; idx++) {
					if (newComment.id == curphoto.comments[idx].id) {
						dbg("callbackResponse_AddComment: found a dup (" + newComment.id + ", skipping");
						return;
					}
				}

				newComment.text = unescapeXml(getElText(xml, 'commentbody'));
				
				newComment.displayText = unescapeXml(getElText(xml, 'displaybody'));
				
				newComment.date = getElText(xml, 'date');
				newComment.name = getElText(xml, 'name');
				newComment.email = getElText(xml, 'email');
				newComment.editableByThisUser = new Boolean(getElText(xml, 'editable'));
				newComment.deletableByThisUser = new Boolean(getElText(xml, 'deletable'));

				// make the name a link if the author has a galleryurl
				var galleryUrl = getElText(xml, 'galleryurl');
				if (galleryUrl.length > 0) {
					newComment.name = '<a href="'+ galleryUrl + '">' + newComment.name + "</a>";
				}

				var tmp = new Array();
				tmp[0] = newComment;
				for (var idx=0; idx < curphoto.comments.length; idx++)
					tmp[idx+1] = curphoto.comments[idx];
				curphoto.comments = tmp;

				renderComments();
				clearAddCommentArea();
                displayCharsAvailable("comment",COMMENT_MAX_LENGTH,"charsAvailable");
			}
		}
	}
	catch (e) {
		alert(e.message);
	}

	callbackResponse_AddComment_locked = false;

	// clear hidden form field in case user does a regular browser post
	document.getElementById("comment_id").value = "";
	document.getElementById("comment_value").value = "";
	document.getElementById("nextcommentaction").value = "";
}

function handleCancelAddComment() {
	clearAddCommentArea();
}

function handleBeginEditComment() {
	if (currentlyBusy())
		return;

	handlePause();

	var commentId = this.commentId;
	var commentToEdit = comments[commentId];
	renderCommentEditMode(commentToEdit);
	return false;
}

function handleCommitEditComment() {
	var commentId = this.commentId;
	var text = document.getElementById(commentId + "_text").value;
	document.getElementById(COMMENT_ID_PARAM).value = commentId;
	document.getElementById(COMMENT_VALUE_PARAM).value = text;
	document.getElementById("nextcommentaction").value = ACTION_UPDATE_COMMENT;


	if (xmlhttp) {
		// delete the comment from the page if there is no longer any text in the field
		if (isBlank(text))
			doXmlHttpSubmit(callbackResponse_DeleteComment);
		else
			doXmlHttpSubmit(callbackResponse_SaveEditComment);
	}
	else
		doSubmit();	
	
	return false;
}

function callbackResponse_SaveEditComment() {
	if (xmlhttp.readyState != 4)
		return;
	
	try {
		var xml = xmlhttp.responseXML;
		if (xml) {
			var photoid = getElText(xml, 'photoid');
			var curphoto = getCurrentPhoto();
			if (photoid == new String(curphoto.id)) {
				var id = getElText(xml, 'id');
				var comment;
				comment = comments[id];
				if (comment == null)
					return;
				comment.text = unescapeXml(getElText(xml, 'commentbody'));
				comment.displayText = unescapeXml(getElText(xml, 'displaybody'));
				comment.date = getElText(xml, 'date');
				replaceComment(comment);
				clearAddCommentArea();
			}
		}
	}
	catch (e) {
		alert(e.message);
	}
	// clear hidden form field in case user does a regular browser post
	document.getElementById("comment_id").value = "";
	document.getElementById("comment_value").value = "";
	document.getElementById("nextcommentaction").value = "";
}

function handleBeginDeleteComment() {
	if (currentlyBusy())
		return;

	if (!this.commentId)
		return;
	var commentId = this.commentId;
	var commentToEdit = comments[commentId];
	renderCommentEditMode(commentToEdit, true)
	return false;
}

function handleCommitDeleteComment() {
	if (!this.commentId)
		return;
	var commentId = this.commentId;
	
	var photo = getCurrentPhoto();
	var comment;
	for (idx=0; idx < photo.comments.length; idx++) {
		if (commentId == photo.comments[idx].id) {
			if (photo.comments[idx].deleting == true) {
				return;
			}
			else {
				comment = photo.comments[idx];
			}
		}
	}

	// note: hardcoding constants here bcs delete can be a rapid-fire action
	// running into race cond where page has not inited the constant var yet
	document.getElementById("comment_id").value = commentId;
	document.getElementById("comment_value").value = "";
	document.getElementById("nextcommentaction").value = ACTION_UPDATE_COMMENT;

	comment.deleting = true;
	
	if (xmlhttp)
		doXmlHttpSubmit(callbackResponse_DeleteComment);
	else
		doSubmit();
	return false;
}

function callbackResponse_DeleteComment() {
	if (xmlhttp.readyState != 4)
		return;
	
	try {
		var xml = xmlhttp.responseXML;
		if (xml) {
			var curphoto = getCurrentPhoto();
			var photoid = getElText(xml, 'photoid');
			if (photoid == new String(curphoto.id)) {
				var id = getElText(xml, 'id');
				var comment;
				var idx;
				for (idx=0; idx < curphoto.comments.length; idx++) {
					if (id == curphoto.comments[idx].id) {
						comment = curphoto.comments[idx];
						curphoto.comments.splice(idx, 1);
					}
				}
				if (comment)
					removeComment(comment);

				clearAddCommentArea();
			}
		}
	}
	catch (e) {
		;
	}
	// clear hidden form field in case user does a regular browser post
	document.getElementById("comment_id").value = "";
	document.getElementById("comment_value").value = "";
	document.getElementById("nextcommentaction").value = "";
}

function renderComments() {
	var photo = getCurrentPhoto();
	if (photo == null)
		return;
	
	var commentsDiv = document.getElementById("comments");
	removeChildren(commentsDiv);
	
	var numCommentsSpan = document.getElementById("numcomments");
	numCommentsSpan.innerHTML = new String(photo.comments.length);
		
	var numCommentsLinkSpan = document.getElementById("numcommentslink");
	if (numCommentsLinkSpan) {
		numCommentsLinkSpan.innerHTML = new String(photo.comments.length);
	}

	for (var cIdx=0; cIdx < photo.comments.length; cIdx++) {
		var comment = photo.comments[cIdx];
		comments[comment.id] = comment;
		var commentDiv = renderComment(comment);
		commentsDiv.appendChild(commentDiv);
	}
}

function renderComment(comment) {
	var commentDiv = document.createElement("div");
	commentDiv.className = "comment clear-l clearfix";
	commentDiv.id = comment.id;

	var p = document.createElement("p");
	p.className = "clear-l";
	p.innerHTML = htmlify(comment.displayText);
	commentDiv.appendChild(p);

	comment.height = findHeight(p);
	if ((! comment.height) || (! comment.height < 20))
		comment.height = 20;

	var div = document.createElement("div");
	div.className = "commentinfo";
	div.innerHTML = comment.name + ", " + comment.date;
	commentDiv.appendChild(div);

	div = document.createElement("div");

	if (comment.editableByThisUser) {
		a = document.createElement("a");
		a.className = "commentaction arrow-link";
		a.href = "javascript:void(0);";
		a.commentId = comment.id;
		a.onclick = handleBeginEditComment;
		a.innerHTML = commentlabels["Edit"];
		
		div.appendChild(a);
	}

	if (comment.deletableByThisUser) {
		a = document.createElement("a");
		a.className = "commentaction arrow-link";
		a.href = "javascript:void(0);";
		a.commentId = comment.id;
		a.onclick = handleBeginDeleteComment;
		a.innerHTML = commentlabels["Delete"];

		div.appendChild(a);
	}
	
	commentDiv.appendChild(div);

	return commentDiv;
}

function removeComment(comment) {
	var commentsDiv = document.getElementById("comments");
	commentsDiv.removeChild(document.getElementById(comment.id));
	currentEditCommentId = -1;

	var numCommentsSpan = document.getElementById("numcomments");
	numCommentsSpan.innerHTML = new String(getCurrentPhoto().comments.length);

	var numCommentsLinkSpan = document.getElementById("numcommentslink");
	if (numCommentsLinkSpan) {
		numCommentsLinkSpan.innerHTML = new String(getCurrentPhoto().comments.length);
	}
}

function replaceComment(comment) {
	var replaceCommentDiv = renderComment(comment);
	var currCommentDiv = document.getElementById(comment.id);
	var commentsDiv = document.getElementById("comments");
	commentsDiv.replaceChild(replaceCommentDiv, currCommentDiv);
	currentEditCommentId = -1;
}

function revertComment() {
	var id = this.commentId;
	var comment = comments[id];
	replaceComment(comment);
}

function renderCommentEditMode(comment, deleteFlag) {
	if (currentEditCommentId != -1) {
		var oldComment = comments[currentEditCommentId];
		if (oldComment) 
			replaceComment(oldComment);
	}
	currentEditCommentId = comment.id;

	var origCommentDiv = document.getElementById(comment.id);

	var commentDiv = document.createElement("div");
	commentDiv.id = comment.id;
	commentDiv.className = "comment";
	var p = document.createElement("p");
	commentDiv.appendChild(p);
	
	if (deleteFlag) {
		var p = document.createElement("p");
		p.className = "deletetext clear-l";
		p.innerHTML = htmlify(comment.displayText);
		commentDiv.appendChild(p);				
	}
	else {
		var textarea = document.createElement("textarea");
		textarea.id = comment.id + "_text";
		textarea.cols = 40;	
		textarea.rows = calcTextAreaRows(comment.text, textarea.cols);
		textarea.value = unescapeXml(comment.text);		
		textarea.className = "commentarea";
        textarea.onkeyup=function () {displayCharsAvailable(textarea.id,COMMENT_MAX_LENGTH,'charsAvailableEdit');}
        textarea.onmouseup=function () {displayCharsAvailable(textarea.id,COMMENT_MAX_LENGTH,'charsAvailableEdit');}
        textarea.onchange=function () {displayCharsAvailable(textarea.id,COMMENT_MAX_LENGTH,'charsAvailableEdit');}
        textarea.onblur=function () {displayCharsAvailable(textarea.id,COMMENT_MAX_LENGTH,'charsAvailableEdit');}
		var origHeight = findHeight(origCommentDiv);
		if (! origHeight) {
			origHeight = 30;
		}
		else if (origHeight > 200) {
			origHeight = 200;
		}
		textarea.style.height = origHeight + "px";
		textarea.style.width = EDIT_COMMENT_FIELD_WIDTH + "px";
		commentDiv.appendChild(textarea);
        var ccp = document.createElement("p");
        ccp.className = "commentCharsAvailable";
		ccp.id = "charsAvailableEdit";
        ccp.innerHTML = MAX_CHAR_COUNTER;
        ccp.style.margin="0";
        ccp.style.padding="0";
        commentDiv.appendChild(ccp);
	}
	var btndiv = document.createElement("div");
	btndiv.className = "pri-small-l";
	var a = document.createElement("a");
	a.href = "javascript:void(0)";
	a.commentId = comment.id;
	if (deleteFlag) {
		a.onclick = handleCommitDeleteComment;
		a.innerHTML = commentlabels["Delete"];
	} 
	else {
		a.onclick = handleCommitEditComment;
		a.innerHTML = commentlabels["Save"];				
	}
	btndiv.appendChild(a);
	commentDiv.appendChild(btndiv);

	btndiv = document.createElement("div");
	btndiv.className = "ter-l";
	a = document.createElement("a");
	a.href = "javascript:void(0)";
	a.commentId = comment.id;
	a.onclick = revertComment;
	a.innerHTML = commentlabels["Cancel"];
	btndiv.appendChild(a);
	commentDiv.appendChild(btndiv);

	var commentsDiv = document.getElementById("comments");
	commentsDiv.replaceChild(commentDiv, origCommentDiv);

	var commentListDiv = document.getElementById("commentlist");
	window.scrollTo(0, findPosY(btndiv) + findPosY(commentListDiv));

	if (textarea) {
		textarea.focus();
		if (!(is_mac && is_ie5))
			setCaretToEnd(textarea);
	}
}

function clearAddCommentArea() {
	var comment = document.getElementById("comment");
	if (comment) {
		comment.value = "";
	}
	var postpublic = document.getElementById("postpublic");
	if (postpublic) {
		postpublic.checked = true;
	}
	displayCharsAvailable("comment",COMMENT_MAX_LENGTH,"charsAvailable");
}

function scrollToCommentArea() {
	var commentsArea = document.getElementById("commentlist");
	window.scrollTo(0, findPosY(commentsArea));
}

function scrollToHandledComment() {
	var handledComment = document.getElementById(handledCommentId);
	if (handledComment == null) {
		setTimeout(scrollToHandledComment, 50);
	}
	else {
		window.scrollTo(0, findPosY(handledComment));
	}
}

function handleSignin() {
	document.getElementById("nextcommentaction").value = ACTION_SIGN_IN_AND_RESUME;
	doSubmit();
	return false;
}

function handleSignup() {
	document.getElementById("nextcommentaction").value = ACTION_REGISTER_AND_RESUME;
	doSubmit();	
	return false;
}

function calcTextAreaRows(txt, maxCols) {
	var rows = 0;
	var col = 0;
	for (var idx=0; idx < txt.length; idx++) {
		var c = txt.charAt(idx);
		++col;
		if (c == '\n') {
			++rows;
			col = 0;
			continue;
		}
		if (col >= maxCols) {
			++rows;
			col = 0;
			continue;			
		}
	}

	// tweak to size the box
	if (rows == 0 && !is_ie)
		rows = 1;
	else if (is_ie)
		rows += 2;
			
	return rows;
}

function imposeMaxLength(obj){
	if (obj && (obj.value.length > COMMENT_MAX_LENGTH)) {
       obj.value = obj.value.substring(0, COMMENT_MAX_LENGTH);
    }		
}

function htmlify(s) {
	var retVal = "";
	if (!s)
		return retVal;

	for (var idx=0; idx < s.length; idx++) {
		if (s.charAt(idx) == '\n') 
			retVal += "<br/>";
		else
			retVal += s.charAt(idx);	
	}
	return retVal;
}

function unescapeXml(s) {
	
	var tokens = [["&amp;","&"],["&quot;","\""],["&apos;","'"],["&lt;","<_"],["&gt;",">"],["&#040;","("],["&#041;",")"],["&#037;","%"],["&#059;",";"],["&#043;","+"],["&#045;","-"]];
	for (var idx=0; idx < tokens.length; idx++) {
		var re = new RegExp(tokens[idx][0], "gi");
		s = s.replace(re, tokens[idx][1]);
	}
	
	return s;
}

