/* Expand Comments version 1.1
 *  Copyright 2006 Andrew Rader
 *
 * This file is part of Expand Comments
 *
 * Expand Comments is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.

 * Expand Comments is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Expand Comments; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

/*
 * Called when the link is clicked, handles show/hide stuff
 */
function expandCollapseComments( src ) {
	srcId = src.id;
	appendDiv = document.getElementById( srcId.replace( "expComLink-", "expComDiv-" ) );
	postID = srcId.replace( "expComLink-", "" );

	/* If we need to download the comments */
	if( src.getAttribute( "rel" ) == "get" ) {
		src.innerHTML = "Loading...";
		url = expcom_proxy_loc+"?id="+srcId.replace("expComLink-", "");
		makeAjaxRequest( 'handleExpandReturn', true, url, postID );
		src.setAttribute( "rel", "hide" );
	} else {
		/* otherwise, just show/hide the div */
		if( src.getAttribute( "rel" ) == "hide" ) {
			/* Hide the div */
			appendDiv.style.display = "none";
			src.setAttribute( "rel", "show" );
			if( expcom_exp.indexOf( '$count' ) != -1 ) {
				var divs = appendDiv.getElementsByTagName('div');
				var count = 0;
				for( i = 0; i < divs.length; i++ ) {
					if( divs[i].id.indexOf( 'expComComment-' ) == 0 ) {
						count++;
					}
				}
				src.innerHTML = expcom_exp.replace( '$count', count );
			}
			else {
				src.innerHTML = expcom_exp;
			}
		} else {
			/* Show the div */
			appendDiv.style.display = "";
			src.setAttribute( "rel", "hide" );
			src.innerHTML = expcom_col;
		}
	}
	return false;
}

/*
 * Called from the bottom collapse link
 */
function collapse( src ) {
	srcID = src.id;
	appendDiv = document.getElementById( srcID.replace( "expCollLink-", "expComDiv-" ) );
	expColLink = document.getElementById( srcID.replace( "expCollLink-", "expComLink-" ) );

	appendDiv.style.display = "none";
	expColLink.setAttribute( "rel", "show" );
	if( expcom_exp.indexOf( '$count' ) != -1 ) {
		var divs = appendDiv.getElementsByTagName('div');
		var count = 0;
		for( i = 0; i < divs.length; i++ ) {
			if( divs[i].id.indexOf( 'expComComment-' ) == 0 ) {
				count++;
			}
		}
		expColLink.innerHTML = expcom_exp.replace( '$count', count );
	}
	else {
		expColLink.innerHTML = expcom_exp;
	}
	return false;
}

/*
 * Called from the form to submit a comment using AJAX
 */
function submitCommentForm( submitUrl, form, postID ) {
	getUrl = expcom_proxy_loc+ "?id=" + postID

	/* Clear the error */
	var err = document.getElementById( "expcom_ajax_error" );
	if(err) err.parentNode.removeChild(err);

	params = "";
	for( var i = 0; i < form.elements.length; i++ ) {
		switch( form.elements[i].name ) {
			case "author":
				if( form.elements[i].value == "" ) {
					alertBadForm( form.elements[i], "You must enter a Name" );
					return;
				}
				params += ( "author=" + form.elements[i].value + "&" );
				break;
			case "email":
				if( form.elements[i].value == "" ) {
					alertBadForm( form.elements[i], "You must enter an Email" );
					return;
				}
				var filter  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
				if( !filter.test( form.elements[i].value ) ) {
					alertBadForm( form.elements[i], "You must enter a Valid Email" );
					return;
				}
				params += ( "email=" + form.elements[i].value + "&" );
				break;
			case "url":
				params += ( "url=" + form.elements[i].value + "&" );
				break;
			case "comment":
				if( form.elements[i].value == "" ) {
					alertBadForm( form.elements[i], "You must enter a Comment" );
					return;
				}
				params += ( "comment=" + form.elements[i].value + "&" );
				break;
			case "comment_post_ID":
				params += ( "comment_post_ID=" + form.elements[i].value + "&" );
				break;
		}
	}
	
	submit = null;
	inputs = form.getElementsByTagName("input");
	for( var i = 0; i < inputs.length; i++ ) {
		if( inputs[i].type == "submit" ) {
			submit = inputs[i];
			break;
		}
	}

	textarea = form.getElementsByTagName("textarea")[0];

	params = params.substr(0,(params.length - 1));
	makeAjaxPost('handlePostReturn', true, submitUrl, params, getUrl, submit, textarea, postID);
	
	if( textarea != null ) {
		textarea.disabled = true;
	}

	if( submit != null ) {
		submit.disabled = true;
	}

}

/*
 * insertComment will insert a comment to the list of comments
 * before the beforeElement
 */
function insertComment( entry, appendDiv, beforeElement, showEffect ) {
	/* Create the container for this single comment */
	comment = document.createElement( "div" );

	commentIDNode = entry.getElementsByTagName("comment_ID");
	if( commentIDNode.length >0 && commentIDNode[0].firstChild ) {
		comment.id = "expComComment-" + commentIDNode[0].firstChild.data;
	}

	if( i % 2 == 0 ) {
		comment.className = expcom_comtext_even_class;
	}
	else {
		comment.className = expcom_comtext_odd_class;
	}

	/* Create the Author & Link */
	authLinkNode = entry.getElementsByTagName("comment_author_url");
	if( authLinkNode.length > 0 && authLinkNode[0].firstChild ) {
		authLink = authLinkNode[0].firstChild.data;
		authCite = document.createElement( "cite" );
		authCite.innerHTML = authLink;
		authCite.className = expcom_authclass;

		comment.appendChild( authCite );
	}

	says = document.createTextNode( " says: " );
	comment.appendChild( says );

	approvedNode = entry.getElementsByTagName("comment_approved");
	if( approvedNode.length > 0 && approvedNode[0].firstChild ) {
		approved = approvedNode[0].firstChild.data;
		/* Is this approved? */
		if( approved == "0" ) {
			appr = document.createElement( "em" );
			appr.innerHTML = "Your comment is awaiting moderation.";
			comment.appendChild( appr );
		}
	}

	br = document.createElement( "br" );
	comment.appendChild(br);

	/* Now the Date */
	small = document.createElement( "small" );
	small.className = expcom_dateclass;

	linkNode = entry.getElementsByTagName("comment_link");
	if( linkNode.length > 0 && linkNode[0].firstChild ) {
		link = document.createElement( "a" );
		link.href = linkNode[0].firstChild.data;
		dateNode = entries[i].getElementsByTagName("comment_date");
		if( dateNode.length > 0 && dateNode[0].firstChild ) {
			theDate = dateNode[0].firstChild.data;
		}
		else {
			dateNode = entries[i].getElementsByTagName("comment_date_gmt");
			if( dateNode.length > 0 && dateNode[0].firstChild ) {
				theDate = dateNode[0].firstChild.data;
			}
			else {
				theDate = "";
			}
		}
		timeNode = entry.getElementsByTagName( "comment_time" );
		if( timeNode.length > 0 && timeNode[0].firstChild ) {
			theTime = " at "+timeNode[0].firstChild.data;
		}
		else {
			theTime = "";
		}

		link.innerHTML = theDate + theTime;

		link.title = "";
		small.appendChild( link );
	}
	
	/* Can we edit this comment? */
	canEdit = entry.getElementsByTagName("comment_edit");
	if( canEdit.length > 0 && canEdit[0].firstChild ) {
		space = document.createTextNode( " " );
		small.appendChild( space );

		edit = document.createElement("a");
		edit.href = canEdit[0].firstChild.data;
		edit.innerHTML = "edit";
		small.appendChild( edit );
	}

	comment.appendChild( small );

	/* Now the Comment Body */
	entryNode = entry.getElementsByTagName( "comment_content" );
	if( entryNode.length > 0 && entryNode[0].firstChild ) {
		text = document.createElement( "div" );
		text.className = expcom_comcontentclass;

		text.innerHTML = entryNode[0].firstChild.data;
		comment.appendChild( text );
	}
			
	/* Insert the comment block */
	if( showEffect ) {
		fadeEffect = new fx.Opacity( comment, {duration: 1000} );
		fadeEffect.setOpacity( 0 );

		appendDiv.insertBefore( comment, beforeElement );

		fadeEffect.custom(0,1);
	}
	else {
		appendDiv.insertBefore( comment, beforeElement );
	}
}

/*
 * removeComment - given the id number of the comment and post,
 * this will remove the comment from the DOM
 */
function removeComment( commentID, postID ) {
	commentsDiv = document.getElementById( "expComDiv-" + postID );
	comment = document.getElementById( "expComComment-" + commentID );
	commentsDiv.removeChild( comment );
}

/*
 * handleExpandReturn - called after the expand link is pressed and the
 * AJAX function has finished
 * This will insert all of the comments into the div
 */
function handleExpandReturn( retVal, postID ) {
	/* The XML Doc */
	xmlDoc = retVal.documentElement;

	if( postID >= 0 ) {
		appendDiv = document.getElementById( "expComDiv-" + postID );

		collapseLinkDiv = document.getElementById( "expCollLinkDiv-" + postID );

		/* Loop through the entries from the XML */
		entries = xmlDoc.getElementsByTagName( "comment" );
		for( i = 0; i < entries.length; i++ ) {
			insertComment( entries[i], appendDiv, collapseLinkDiv, false );
		}

		appendDiv.style.display = "";
	}

	newcommentform = document.getElementById(appendDiv.id.replace("expComDiv-","expcom-newform-"));
	if( newcommentform ) {
		newcommentform.style.display = "";
	}

	appendLink = document.getElementById(appendDiv.id.replace("expComDiv-","expComLink-"));
	appendLink.innerHTML = expcom_col;
}

/*
 * handePostReturn - this is called when the post request has completed.
 * Once the comment has been submitted, it will update the comments
 */
function handlePostReturn( retVal, getUrl, submit, textarea, postID ) {
	makeAjaxRequest( 'handleCommentSubmitted', true, getUrl, submit, textarea, postID );
}

/*
 * handleCommentSubmitted - Now that the comment is submitted,
 * update the comment list, and disable the form items
 * This will insert / remove comments based on what currently exists
 * versus what is returned from the server
 */
function handleCommentSubmitted( retVal, submit, textarea, postID ) {
	xmlDoc = retVal.documentElement;

	commentsDiv = document.getElementById( "expComDiv-" + postID );

	/* Create an array of the comment elements */
	commentIDs = new Array();

	/* And fill the array */
	subDivs = commentsDiv.getElementsByTagName( "div" );
	for( i = 0; i < subDivs.length; i++ ) {
		if( subDivs[i].id.indexOf( "expComComment-" ) == 0 ) {
			commentIDs.push( subDivs[i].id.replace("expComComment-", "") );
		}
	}

	/* Loop through the entries from the XML */
	entries = xmlDoc.getElementsByTagName( "comment" );
	for( i = 0; i < entries.length; i++ ) {
		entry = entries[i];
		entryIDNode = entry.getElementsByTagName( "comment_ID" );
		if( entryIDNode.length > 0 && entryIDNode[0].firstChild ) {
			entryID = entryIDNode[0].firstChild.data;
			matched = false;
			for( k = 0; k < commentIDs.length; k++ ) {
				if( commentIDs[k] == entryID ) {
					commentIDs.splice(k ,1);
					matched = true;
					break;
				}
			}
			if( !matched ) {
				/* This is a new comment, so we must add it. First find the element
			 	* That will go after this comment, then insert the new comment
			 	*/
				insertBeforeID = null;
				for( probe = commentIDs.length - 1; probe >= 0; probe++ ) {
					if( commentIDs[probe] < entryID ) {
						break;
					}

					insertBeforeID = commentIDs[probe];
				}

				if( insertBeforeID != null ) {
					insertBeforeElement = document.getElementById( "expComComment-" + insertBeforeID );
				}
				else {
					insertBeforeElement = document.getElementById( "expCollLinkDiv-" + postID );
				}

				insertComment( entry, commentsDiv, insertBeforeElement, expcom_moo_fx );
			}
		}
	}

	/* Now if there are any comments left, it means they were removed
	 * by the server, so lets remove them from the list
	 */

	for( r = 0; r < commentIDs.length; r++ ) {
		removeComment( commentIDs[r], postID );
	}

	refreshEvenOdd( postID );

	disableForm( textarea, submit, 15 );
}

/*
 * disableForm - disable the textarea and submit items for the number
 * of seconds
 */
function disableForm( textarea, submit, seconds ) {
	if( textarea != null ) {
		if( seconds > 0 ) {
			textarea.value = "You must wait " + seconds + " seconds";
		}
		else {
			textarea.value = "";
			textarea.disabled = false;
		}
	}

	if( seconds == 0 && submit != null ) {
		submit.disabled = false;
	}

	seconds--;
	secs = seconds + "";
	if( seconds >= 0 ) {
		setTimeout( 'disableForm( textarea, submit, secs )', 1000 );
	}
}

/*
 * refreshEvenOdd - this goes through all of the comments in a post
 * and re-calculates the even/odd class name
 */
function refreshEvenOdd( postID ) {
	commentsDiv = document.getElementById( "expComDiv-" + postID );

	divs = commentsDiv.getElementsByTagName( "div" );

	counter = 0;
	for( i = 0; i < divs.length; i++ ) {
		if( divs[i].id.indexOf( "expComComment-" ) == 0 ) {
			counter++;
			if( counter % 2 == 0 ) {
				divs[i].className = expcom_comtext_odd_class;
			}
			else {
				divs[i].className = expcom_comtext_even_class;
			}
		}
	}
}

/*
 * alertBadForm - modify the form to show that it is malformed
 */
function alertBadForm( el, msg ) {
	var error = document.createElement( "div" );
	error.id = "expcom_ajax_error";
	error.style.color = "#f08080";
	var errMsg = document.createTextNode( msg );
	error.appendChild( errMsg );
	el.parentNode.insertBefore( error,el );
}
