function comments_init() {
	if (!document.getElementById('comments')) {
		return;
	}

	// apply the submit comment functionality
	var oLeaveReplyDiv = document.getElementById('leave_reply');
	if (oLeaveReplyDiv && oLeaveReplyDiv.getElementsByTagName('form').length > 0) {
		oLeaveReplyDiv.getElementsByTagName('form')[0].onsubmit = comments_addComment;
	}

	// apply the AJAX pagination functionality
	comments_addPaginationItemClick(document.getElementById('comments').getElementsByClassName('pagination'));

	// apply the search comments functionality
	if (document.getElementById('search_comments')) {
		document.getElementById('search_comments').onsubmit = comments_searchComments;
	}

	if (document.getElementById('see_all_comments_link')) {
		document.getElementById('see_all_comments_link').onclick = function () {
			document.getElementById('all-comments').style.display = 'block';
			document.getElementById('filtered-comments').style.display = 'none';

			return false;
		};
	}

	// apply the select comment for reply functionality
	oaSelectForReplyLinks = document.getElementById('comments').getElementsByClassName('select-for-reply');
	for (var i = 0; i < oaSelectForReplyLinks.length; i++) {
		oaSelectForReplyLinks[i].onclick = comments_selectForReplyClick;
	}

	// apply the deselect comment for reply functionality
	var oDeselectForReply = document.getElementById('deselect-for-reply');
	if (oDeselectForReply) {
		oDeselectForReply.style.display = 'none';
		oDeselectForReply.onclick = comments_deselectForReplyClick;
	}

	// fix opera bug
	var oCommentTextTextarea = document.getElementById('text');
	if (window.opera && oCommentTextTextarea) {
		oCommentTextTextarea.onkeydown = function() {
			this.style.display = 'block';
		}
	}

	// characters count
	if (document.getElementById('comment_characters_count')) {
		document.getElementById('text').onkeyup = comments_updateCharactersCount;
	}
}

function comments_addComment() {
	var form = this;
	var itemId = this.parentNode.className.match(/(^|\s+)c-(\d+)(\s+|$)/)[2];

	// validate
	if (!comments_isValid(form)) {
		return false;
	}

	// disable the submit button, change the text to 'submitting comment...' and hide reCAPTCHA error message
	var oSubmitButton = document.getElementById('submit_comment');
	oSubmitButton.disabled = true;
	oSubmitButton.innerHTML = window.serverConfigs.commentsLeaveReply.submittingComment;

	var oRecaptchaField = document.getElementById('recaptcha_input');
	if (oRecaptchaField) {
		oRecaptchaField.getElementsByClassName('error')[0].className.replace(' visible', '');
	}

	// build the POST data
	var data = 'item_id=' + itemId + '&text=' + encodeURIComponent(this.text.value);

	// add name if exists
	if (this.name) {
		data +='&name=' + encodeURIComponent(this.name.value);
	}

	// and email if exists
	if (this.email) {
		data += '&email=' + encodeURIComponent(this.email.value);
	}

	// and link if exists
	if (this.link) {
		data += '&link=' + encodeURIComponent(this.link.value);
	}

	if (typeof(Recaptcha) != 'undefined') {
		data += '&recaptcha_challenge_field=' + encodeURIComponent(this.recaptcha_challenge_field.value) +
			'&recaptcha_response_field=' + encodeURIComponent(this.recaptcha_response_field.value);
	}

	if(window.parentCommentId) {
		data += '&parent_comment_id='+window.parentCommentId;
	}

	// open the XHR
	var xhr = new XMLHttpRequest('MSXML2.XMLHTTP.3.0');
	xhr.open('POST', '/comment_add/', true);

	// set the POST headers
	xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
	xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
	xhr.setRequestHeader('Content-length', data.length);
	xhr.setRequestHeader('Connection', 'close');

	// reload comments on success
	xhr.onreadystatechange = function () {
		if (xhr.readyState == 4) {
			var sIdOfElementToFocus = 'leave_comm';
			if (xhr.status == 200) {
				switch (true) {
					case xhr.responseText.indexOf('SUCCESS') == 0:
						window.commentPages = { };
						if (xhr.responseText == 'SUCCESS') {
							window.location.href = ((sUrlMatches = window.location.href.match(/(.*)(-page\/\d+\/)/)) ? sUrlMatches[1]+'.html' : window.location.href.replace(/#.*$/, '')) + '#comments';
							comments_showCommentsPage(1);
							comments_deselectForReplyClick();
						} else {
							var oaPagination = document.getElementById('all-comments').getElementsByClassName('pages_left');
							var iCurrentPage = oaPagination.length == 0 ? 1 : parseInt(oaPagination[0].getElementsByClassName('current')[0].getElementsByTagName('a')[0].innerHTML);
							comments_showCommentsPage(iCurrentPage);
							window.location.href = window.location.href.indexOf('#') == -1 ? window.location.href + '#pc-' + window.parentCommentId : window.location.href = window.location.href.replace(/#.+$/, '#pc-' + window.parentCommentId);
						}

						var saInputNames = { name: window.serverConfigs.commentsLeaveReply.nameLabel, email: window.serverConfigs.commentsLeaveReply.emailLabel, text: '', link: 'http://www.', recaptcha_response_field: '' };
						for (inputName in saInputNames) {
							if (document.getElementById(inputName)) {
								document.getElementById(inputName).value = saInputNames[inputName];
								document.getElementById(inputName).blur();
							}
						}
					break;
					case xhr.responseText.indexOf('INVALID_CAPTCHA') == 0:
						if (oRecaptchaField) {
							oRecaptchaField.getElementsByClassName('error')[0].className += ' visible';
							document.getElementById('recaptcha_response_field').focus();
						}
						sIdOfElementToFocus = 'recaptcha_response_field';
					break;
					case xhr.responseText.indexOf('INVALID_EMAIL') == 0:
						var oEmailError = document.getElementsByClassName('error email')[0].className += ' visible';
						sIdOfElementToFocus = 'email';
					break;
					case xhr.responseText.indexOf('INVALID_NAME') == 0:
						var oEmailError = document.getElementsByClassName('error name')[0].className += ' visible';
						sIdOfElementToFocus = 'name';
					break;
					case xhr.responseText.indexOf('INVALID_TEXT') == 0:
						var oEmailError = document.getElementsByClassName('error text')[0].className += ' visible';
						sIdOfElementToFocus = 'text';
					break;
					case xhr.responseText.indexOf('TEXT_TOO_LONG') == 0:
						var oEmailError = document.getElementsByClassName('error texttoolong')[0].className += ' visible';
						sIdOfElementToFocus = 'text';
					break;
				}
			} else{
				alert(window.serverConfigs.xhrError);
			}

			// after the request has finished (with success, invalid captcha or other error) refresh the captcha image
			if (typeof(Recaptcha) != 'undefined') {
				Recaptcha.destroy();
				Recaptcha.create(window.serverConfigs.recaptchaPublicKey, document.getElementById('recaptcha_widget'), RecaptchaOptions);
			}

			// enable the submit button, change the text to 'SUBMIT COMMENT', focus the desired element
			var oSubmitButton = document.getElementById('submit_comment');
			oSubmitButton.disabled = false;
			oSubmitButton.innerHTML = window.serverConfigs.commentsLeaveReply.submitComment;
			if (document.getElementById(sIdOfElementToFocus)) {
				document.getElementById(sIdOfElementToFocus).focus();
			}
		}
	}
	xhr.send(data);

	return false;
}

function comments_isValid(form) {
	// reset errors
	var oaErrors = form.getElementsByClassName('error');
	for (var i = 0; i < oaErrors.length; i++) {
		oaErrors[i].className = oaErrors[i].className.replace(' visible', '');
	}

	// validate name
	if (form.name && (form.name.value == window.serverConfigs.commentsLeaveReply.nameLabel || !form.name.value.match(/^[\w_-][\s\w_-]*$/))) {
		document.getElementsByClassName('error name')[0].className += ' visible';
		form.name.focus();
		return false;
	}

	// validate email
	if (form.email) {
		var iOccurencesCount = 0;
		for (var i = 0; i < form.email.value.length; i++) {
			if (form.email.value.charAt(i) == '@') {
				iOccurencesCount++;
			}
		}
		if (iOccurencesCount != 1) {
			document.getElementsByClassName('error email')[0].className += ' visible';
			form.email.focus();
			return false;
		}
	}

	// validate text
	if (form.text && form.text.value.replace(/(^\s+|\s+$)/, '') == '') {
		document.getElementsByClassName('error text')[0].className += ' visible';
		form.text.focus();
		return false;
	}

	if (document.getElementById('comment_characters_count') && form.text.value.length > window.serverConfigs.commentsLeaveReply.maxCharsInComment) {
		document.getElementsByClassName('error texttoolong')[0].className += ' visible';
		form.text.focus();
		return false;
	}

	return true;
}

function comments_selectForReplyClick() {
	// get selected comment id
	var commentId = window.parentCommentId = this.className.match(/(^|\s+)c-(\d+)(\s+|$)/)[2];

	// deselect all comments, except for the one that needs to be selected
	var oaComments = document.getElementById('all-comments').getElementsByClassName('one_comment');
	for (var i = 0; i < oaComments.length; i++) {
		if (oaComments[i].getElementsByClassName('select-for-reply')[0].hasClassName('c-' + commentId)) {
			if (!oaComments[i].hasClassName('selected-for-reply')) {
				oaComments[i].className += ' selected-for-reply';
			}
		} else {
			oaComments[i].className = oaComments[i].className.replace(' selected-for-reply', '') ;
		}
	}

	// change the submit button text to 'submit as reply'
	document.getElementById('submit_comment').innerHTML = 'submit as reply';

	// show the 'deselect ...' link
	var oDeselectForReply = document.getElementById('deselect-for-reply');
	if (oDeselectForReply) {
		oDeselectForReply.style.display = 'inline';
	}

	return false;
}

function comments_deselectForReplyClick() {
	window.parentCommentId = 0;
	var oaComments = document.getElementById('all-comments').getElementsByClassName('one_comment');
	for (var i = 0; i < oaComments.length; i++) {
		oaComments[i].className = oaComments[i].className.replace(' selected-for-reply', '') ;
	}

	// change the submit button text back to 'submit comment'
	document.getElementById('submit_comment').innerHTML = window.serverConfigs.commentsLeaveReply.submitComment;

	// hide the 'deselect ...' link
	if (document.getElementById('deselect-for-reply')) {
		document.getElementById('deselect-for-reply').style.display = 'none';
	}

	return false;
}


function comments_searchComments() {
	// build the search terms array
	var sSearchTerms = document.getElementById('search_comments_text').value;
	var saSearchTerms = [ '' ];
	var saSearchTermsCount = 0;
	for (var i = 0; i  < sSearchTerms.length; i++) {
		if (sSearchTerms.charAt(i) == ' ' || sSearchTerms.charAt(i) == '.' || sSearchTerms.charAt(i) == ',' || sSearchTerms.charAt(i) == '?' || sSearchTerms.charAt(i) == '!' || sSearchTerms.charAt(i) == ':') {
			switch (true) {
				case saSearchTerms[saSearchTermsCount].length >= 3:
					saSearchTerms[++saSearchTermsCount] = '';
				break;
				case saSearchTerms[saSearchTermsCount].length > 0:
					saSearchTerms[saSearchTermsCount] = '';
				break;
			}
		} else {
			saSearchTerms[saSearchTermsCount] += sSearchTerms.charAt(i).toLowerCase();
		}
	}

	// remove the last search term if it exists and is invalid
	if (saSearchTerms[saSearchTerms.length - 1].length <= 2) {
		saSearchTerms.pop();
	}

	if (saSearchTerms.length > 0) {
		var iItemId = document.getElementById('comments').className.match(/(^|\s+)c-(\d+)(\s+|$)/)[2];

		var xhr = new XMLHttpRequest('MSXML2.XMLHTTP.3.0');
		xhr.open('GET', '/comments_search/' + iItemId + '/' + saSearchTerms.join(' '));

		// set the xhr request headers
		xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

		// display new text on success
		xhr.onreadystatechange = function () {
			if (xhr.readyState == 4) {
				if (xhr.status == 200) {
					window.oaItemComments = JSON.parse(xhr.responseText);

					var oFilteredCommentsContainer = document.getElementById('filtered-comments').getElementsByTagName('div')[0];
					oFilteredCommentsContainer.innerHTML = '';
					for (var commentId in window.oaItemComments) {
						oFilteredCommentsContainer.innerHTML = comment_buildOneCommentHtml(window.oaItemComments[commentId]) + oFilteredCommentsContainer.innerHTML;
					}

					// if the search did not return any results, display a message
					var oError = document.getElementById('search_comments_error');
					if (window.oaItemComments.length == 0) {
						oError.innerHTML = window.serverConfigs.commentsLeaveReply.searchNoResults;
						oError.style.display = 'inline';
						// if no error has occurred, show the filtered comments
					} else {
						oError.innerHTML = '';
						oError.style.display = 'none';
						Cufon.replace('#filtered-comments div .author p',{ fontFamily: 'Myriad Pro'});

						// hide all comments and display the filtered comments
						document.getElementById('all-comments').style.display = 'none'
						document.getElementById('filtered-comments').style.display = 'block';
					}
				} else{
					alert(window.serverConfigs.xhrError);
				}
			}
		}
		xhr.send(null);
	} else {
		document.getElementById('filtered-comments').innerHTML = '';
		var oError = document.getElementById('comments-search-error');
		oError.innerHTML = window.serverConfigs.commentsLeaveReply.searchError;
		oError.className += ' visible';
	}

	return false;
}

function comments_filterComments(saSearchTerms) {
	// filter comments based on the search terms
	var oaFilteredComments = new Object();
	var iFilteredCommentsCount = 0;

	for (commentId in window.oaItemComments) {
		if (iFilteredCommentsCount == 20) {
			break;
		}

		for (var j = 0; j < saSearchTerms.length; j++) {
			if (window.oaItemComments[commentId].text.toLowerCase().indexOf(saSearchTerms[j]) > -1) {
				oaFilteredComments[commentId] = window.oaItemComments[commentId];
			} else {
				if (window.oaItemComments[commentId].children) {
					for (var childCommentId in window.oaItemComments[commentId].children) {
						if (window.oaItemComments[commentId].children[childCommentId].text.toLowerCase().indexOf(saSearchTerms[j]) > -1) {
							oaFilteredComments[commentId] = window.oaItemComments[commentId];
						}
					}
				}
			}
		}

		iFilteredCommentsCount++;
	}

	// if the search did not return any results, display a message
	var oError = document.getElementById('search_comments_error');
	if (oaFilteredComments.length == 0) {
		oError.innerHTML = window.serverConfigs.commentsLeaveReply.searchNoResults;
		oError.style.display = 'inline';
		// if no error has occurred, show the filtered comments
	} else {
		oError.innerHTML = '';
		oError.style.display = 'none';

		// append the filtered comments to the filtered comments div
		var oFilteredCommentsContainer = document.getElementById('filtered-comments').getElementsByTagName('div')[0];
		oFilteredCommentsContainer.innerHTML = '';
		for (commentId in oaFilteredComments) {
			oFilteredCommentsContainer.innerHTML += comment_buildOneCommentHtml(oaFilteredComments[commentId]);
		}
		Cufon.replace('#filtered-comments div .author p',{ fontFamily: 'Myriad Pro'});

		// hide all comments and display the filtered comments
		document.getElementById('all-comments').style.display = 'none'
		document.getElementById('filtered-comments').style.display = 'block';
	}
}

function comment_buildOneCommentHtml(oCommentData) {
	var sHtml = '<div class="one_comment">';
	sHtml += '<div class="author"><p>' + oCommentData.name + '</p><span>' + oCommentData.created + '</span></div><div class="question"><div class="quest_text">' + oCommentData.text + '</div></div>';
	if (oCommentData.children) {
		for (childCommentId in oCommentData.children) {
			sHtml += '<div class="answer"><div class="logo_comm"><img alt="FlashXML Support" src="/static/images/logo_comm.gif"></div><div class="ans_text">' + oCommentData.children[childCommentId].text + '</div></div>';
		}
	}
	sHtml += '</div>';

	return sHtml;
}

function comments_addPaginationItemClick(oCommentsPaginations) {
	for (var i = 0; i < oCommentsPaginations.length; i++) {
		var oaCommentsPaginationItems = oCommentsPaginations[i].getElementsByTagName('a');
		// set total number of pages
		oCommentsPaginations[i].className += ' cpt-'+(oaCommentsPaginationItems.length - 2);
		for (var j = 0; j < oaCommentsPaginationItems.length; j++) {
			oaCommentsPaginationItems[j].onclick = comments_paginationItemClick;
		}
	}
}

function comments_paginationItemClick() {
	var iClickedPage = parseInt(this.innerHTML.replace(/^(\s+|\s+)$/g, ''));

	var oaCommentsPaginationItems = this.parentNode.parentNode.getElementsByTagName('li');
	for (var i = 1; i < oaCommentsPaginationItems.length; i++) {
		if (oaCommentsPaginationItems[i].hasClassName('current')) {
			iCurrentPage = parseInt(oaCommentsPaginationItems[i].getElementsByTagName('a')[0].innerHTML);
			break;
		}
	}

	switch(true) {
		case iCurrentPage == iClickedPage:
			return false;
		break;
		case this.innerHTML.replace(/^(\s+|\s+)$/g, '') == window.serverConfigs.pagination.prev:
			comments_showCommentsPage(iCurrentPage - 1);
		break;
		case this.innerHTML.replace(/^(\s+|\s+)$/g, '') == window.serverConfigs.pagination.next:
			comments_showCommentsPage(iCurrentPage + 1);
		break;
		default:
			comments_showCommentsPage(iClickedPage);
		break;
	}

	return false;
}

function comments_showCommentsPage(iCommentsPage) {
	if (!window.commentPages) {
		window.commentPages = { };
	}

	if (!window.commentPages[iCommentsPage]) {
			var iItemId = document.getElementById('comments').className.match(/(^|\s+)c-(\d+)(\s+|$)/)[2];

			var oAjaxThrobbers = document.getElementById('comments').getElementsByClassName('ajax-throbber');
			for (var i = 0; i < oAjaxThrobbers.length; i++) {
				oAjaxThrobbers[i].style.display = 'block';
			}

			var xhr = new XMLHttpRequest('MSXML2.XMLHTTP.3.0');
			xhr.open('GET', '/comments_page/' + iItemId + '/' + iCommentsPage + '/');

			// set the xhr request headers
			xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

			// display new text on success
			xhr.onreadystatechange = function () {
				if (xhr.readyState == 4) {
					if (xhr.status == 200) {
						window.commentPages[iCommentsPage] = document.createElement('div');
						window.commentPages[iCommentsPage].className = 'comments-content';
						window.commentPages[iCommentsPage].innerHTML = xhr.responseText;

						// apply non w3c fixes to the newly created elements
						if (typeof(nonW3CFixes_init) != 'undefined') {
							window.nonW3CFixesInitialized = false;
							window.commentPages[iCommentsPage].nonW3CFixes_init = nonW3CFixes_init;
							window.commentPages[iCommentsPage].nonW3CFixes_init();
						}

						// apply the onclick functionality to reply links
						oaSelectForReplyLinks = window.commentPages[iCommentsPage].getElementsByClassName('select-for-reply');
						for (var i = 0; i < oaSelectForReplyLinks.length; i++) {
							oaSelectForReplyLinks[i].onclick = comments_selectForReplyClick;
						}

						// apply the onclick functionality to pagination links
						comments_addPaginationItemClick(window.commentPages[iCommentsPage].getElementsByClassName('pagination'));

						for (var i = 0; i < oAjaxThrobbers.length; i++) {
							oAjaxThrobbers[i].style.display = 'none';
						}

						comments_updateCommentsPage(iCommentsPage);
					} else{
						alert(window.serverConfigs.xhrError);
					}
				}
			}
			xhr.send(null);
	} else {
		comments_updateCommentsPage(iCommentsPage);
	}
}

function comments_updateCommentsPage(iCommentsPage) {
	var oCommentsContent = document.getElementById('comments').getElementsByClassName('comments-content')[0];
	oCommentsContent.parentNode.replaceChild(window.commentPages[iCommentsPage], oCommentsContent);

	// highlight code bocks
	if (window.codeHighlighter) {
		window.codeHighlighter.highlight();
	}

	// cufon-ize author names
	Cufon.replace('.author p',{ fontFamily: 'Myriad Pro'});
}

function comments_updateCharactersCount() {
	var oCommentCharsCountSpan = document.getElementById('comment_characters_count');
	if (oCommentCharsCountSpan) {
		var iCurrentCharsCount = document.getElementById('text').value.length;
		if (iCurrentCharsCount <= window.serverConfigs.commentsLeaveReply.maxCharsInComment) {
			oCommentCharsCountSpan.innerHTML = 'You may type <strong>' + (window.serverConfigs.commentsLeaveReply.maxCharsInComment - iCurrentCharsCount) + '</strong> more characters in your comment.' ;
		} else {
			oCommentCharsCountSpan.innerHTML = 'Your comment is <strong>' + (iCurrentCharsCount - window.serverConfigs.commentsLeaveReply.maxCharsInComment) + '</strong> characters too long. Either keep within <strong>' + window.serverConfigs.commentsLeaveReply.maxCharsInComment + '</strong> characters, or send your problem via email to ' + window.serverConfigs.commentsLeaveReply.obfuscatedSupportEmailAddress + '.';
		}
	}
}
