//var htmpl_comments = function(article_id,display){
var htmpl_comments = function(hcom_args){
	this.debug = null;
	this.article_url = document.location.href;
	this.article_id = null;
	this.varpage = 1;// default will always start off at 1
	this.vardisp = 10;
	this.paginationStyle = "partial"; // I will default this to partial. Partial is slick!
	this.commentcount = 0;
	this.transition = null;
	this.loginState = 0; // 0 - offline, 1 - online, 2 - other (I haven't quite thought about it yet)
	// args for ajax calls
	this.state_haspostedcomment = false;
	this.apiPath = "/api_static/js/";
	this.cacheBust = Math.floor(Math.random()*100001);
	this.ha = false;// obsolete
	this.parameterString = "";
	this.sort_by = "post_timestamp";
	this.sort_direction = "desc";
	//commentjsonobj used to fake 'add' a post
	this.commentjsonobj = null;
	//commentloopdata - container used to hold the current set of comments in json format
	this.commentloopdata = null;
	this.commentTextResize = true;
	
	//callback function when a page of comments is finished rendering
	this.callback = null; 
	// callback function when comment count is finished rendering
	this.rendercountcallback = null;


	// first thing's first, we check the args being passed
	if (!!hcom_args.debug){this.debug = true;} else {this.debug = false;}
	if (!!hcom_args.comments_per_page){this.vardisp = hcom_args.comments_per_page;} else {this.vardisp = 10;}
	if (!!hcom_args.transition){this.transition = hcom_args.transition;}
	if (!!hcom_args.article_id){this.article_id = hcom_args.article_id;} else {return false;}
	if (!!hcom_args.login_form){this.commentLoginForm = hcom_args.login_form;}
	if (!!hcom_args.post_form){this.commentPostingForm = hcom_args.post_form;}
	if (!!hcom_args.callback){this.callback = hcom_args.callback;}
	if (!!hcom_args.rendercountcallback){this.rendercountcallback = hcom_args.rendercountcallback;}
	if (!!hcom_args.paginationStyle){this.paginationStyle = hcom_args.paginationStyle;}
	if (hcom_args.commentTextResize !== undefined){this.commentTextResize = hcom_args.commentTextResize;}
	if (!!hcom_args.sort_by){this.sort_by = hcom_args.sort_by;}
	if (!!hcom_args.sort_direction){this.sort_direction = hcom_args.sort_direction;}

	// overriding this.debug for some fancypants firebug action, otherwise ignore
	if (this.debug && !!console){this.debug = true;} else {this.debug = false;}
	
	if (this.debug){
		console.debug("Initializing htmpl_comments!");
		console.debug("this.vardisp: %d", this.vardisp);
		console.debug("this.transition: %d", this.transition);
		console.debug("this.article_id: %d", this.article_id);
		console.debug("this.loginState: %d", this.loginState);
//		console.debug("this.vardisp: %d", this.vardisp);
		console.debug();
	}

	
	
	// initialize the templating system..
	this.hjstmpl = new HJSTemplateRegistry();

	// register the standard templates
	this.hjstmpl.register("comment_count");
	this.hjstmpl.register("comment_previous_link");
	this.hjstmpl.register("comment_next_link");
	

	// register the loop templates
	this.hjstmpl.loopregister("loop_comment_pagination","selected_page");
	this.hjstmpl.loopregister("loop_comment_pagination","iteration");
	this.hjstmpl.loopregister("loop_comment_wrap","blog_comment");
	
	
	this.getParameter = function(name,optstring){
		var thestring = (!optstring) ? window.location.href : "?"+optstring;
		name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
		var regexS = "[\\?&]"+name+"=([^&#]*)";
		var regex = new RegExp( regexS );
		var results = regex.exec( thestring );
		if( results === null )
			return "";
		else
			return results[1];
	}

	// function calls that are hopefully hooked to event handlers at a later time, let's work on that..
	// nah we won't. causes too much stuff to break down
	this.topage = function(obj){
		this.displayDialog();//$("[template='loop_comment_wrap_waiting']").show();
		$("[templateloop='loop_comment_wrap']").hide();
		this.renderpagination(obj);
		this.getcommentsjson();
	}


	this.getcommentsjson = function(){
		var myself = this;
		$.getJSON(this.apiPath+"CommentsByArticle/"+this.article_id+"_"+this.varpage+"_"+this.vardisp+""+this.parameterString, function(json){myself.rendercomments(json);});
	}

	this.rendercomments = function(json){
		this.commentloopdata = json;
		if (json.length == 0){
			this.hideDialog();//$("[template='loop_comment_wrap_waiting']").hide();
			return false;
		}
		var jsoncommentloop = {
			"templateloop" : "loop_comment_wrap",
			"loop" : []
		};
		for (rc = 0; rc < (json.length); rc++){
			var serverDate = json[rc].post_date+" "+json[rc].post_time;			
			var clientDate = convertToClientDate(serverDate,- new Date().getTimezoneOffset()/60);			
			var post_time = ConvertTo12HourFormat(clientDate.toLocaleTimeString());
			var post_date = clientDate.toLocaleDateString();			
			
			var datagram = {
				"template_name" : "blog_comment",
				"variable_names" : [
					"%TEMPLATE_VARIABLE_COMMENTTITLE%",
					"%TEMPLATE_VARIABLE_TIMESTAMP%",
					"%TEMPLATE_VARIABLE_DATESTAMP%",
					"%TEMPLATE_VARIABLE_USERNAME%",
					"%TEMPLATE_VARIABLE_COMMENTTEXT%",
					"%TEMPLATE_VARIABLE_COMMENTNUMBER%",
					"%TEMPLATE_VARIABLE_UR_ID%",
					"%TEMPLATE_VARIABLE_COMMENT_ID%",
					"%TEMPLATE_VARIABLE_POSITIVE_VOTES%",
					"%TEMPLATE_VARIABLE_TOTAL_VOTES%",
					"%TEMPLATE_VARIABLE_USER_RATED%"
				],
				"data" : [
					json[rc].comment_title.replace(/&amp;/g,"\&"),
					post_time,
					post_date,					
					json[rc].user_name,
					json[rc].comment_text.replace(/(\r\n|\r|\n)/g, "<br />").replace(/&amp;/g,"\&"),
					(this.commentcount-(this.vardisp*(this.varpage-1))-rc),
					json[rc].ur_id,
					json[rc].comment_id,
					0,// ******** NEW STUFF GOES HERE
					0,
					!!json[rc].user_rating
				]
			}
			jsoncommentloop.loop.push(datagram);
		}
		this.hjstmpl.drawloop(jsoncommentloop);
		this.hideDialog();//$("[template='loop_comment_wrap_waiting']").hide();
		
		switch(this.transition){
			case "slide":
				$("[templateloop='loop_comment_wrap']").slideDown();
				break;
			case "fade":
				$("[templateloop='loop_comment_wrap']").fadeIn();
				break;
			default:
				$("[templateloop='loop_comment_wrap']").show();
		}
		this.disableSubmitFields(false);
		if (!!this.callback){
			this.callback();
		}
	}

	/* Faking a comment post
	 * 
	 */
	this.visualizeCommentPost = function(data){
		var myself = this;
		d = new Date();
		var uniquestring = "fake_blog_comment"+d.getUTCHours()+d.getUTCMinutes()+d.getUTCSeconds()+d.getUTCMilliseconds();
		var tempusername = mag_user.user_name;
		tempusername = (this.loginState == 1) ?  mag_user.user_name : this.commentjsonobj.comment_email.substr(0,this.commentjsonobj.comment_email.indexOf("@"));
		// var a = data.split("/");
		// var commentId = a[a.length-1].replace(/^[\s]+/,'').replace(/[\s]+$/,'').replace(/[\s]{2,}/,'');
		var datagram = {
			"template_name" : "loop_comment_wrapblog_comment",
			"variable_names" : [
				"%TEMPLATE_VARIABLE_COMMENTTITLE%",
				"%TEMPLATE_VARIABLE_TIMESTAMP%",
				"%TEMPLATE_VARIABLE_DATESTAMP%",
				"%TEMPLATE_VARIABLE_USERNAME%",
				"%TEMPLATE_VARIABLE_COMMENTTEXT%",
				"%TEMPLATE_VARIABLE_COMMENTNUMBER%",
				"%TEMPLATE_VARIABLE_UR_ID%",
				"%TEMPLATE_VARIABLE_COMMENT_ID%",
				"%TEMPLATE_VARIABLE_POSITIVE_VOTES%",
				"%TEMPLATE_VARIABLE_TOTAL_VOTES%"
			],
			"data" : [
				this.commentjsonobj.comment_title,
				ConvertTo12HourFormat(d.toLocaleTimeString()),
				d.toLocaleDateString(),
				tempusername,
				this.commentjsonobj.comment_text.replace(/(\r\n|\r|\n)/g, "<br />"),
				++this.commentcount,
				"",
				"TEMPID_",
				// commentId,
				0,
				0
			]
		}
		var mysampleoutput = this.hjstmpl.render(datagram);
		$("[templateloop='loop_comment_wrap']").prepend("<div class=\""+uniquestring+" comment_fakepost\" style=\"display:none\">"+mysampleoutput+"</div>");
		$("."+uniquestring+"").slideDown("slow",function(){myself.rendercount({"count":myself.commentcount});});
		// here we add another comment count
		$("[hearstcomment='commentcount']").html(this.commentcount);
		this.state_haspostedcomment = true;
		this.disableSubmitFields(false);
		
	}

	this.postP401 = function(){
		this.firebugConsole("Calling postP401..");
		this.firebugConsole(getCookie("hearstCommentP401"));
		var hearstCommentP401 = getCookie("hearstCommentP401");
		if (this.article_id == this.getParameter("article_id",hearstCommentP401)){
			this.state_haspostedcomment = false;
			this.firebugConsole("comment_text: %d", this.getParameter("comment_text",hearstCommentP401));
			this.firebugConsole("comment_title: %d", this.getParameter("comment_title",hearstCommentP401));
	/*		$("textarea[@name=commentText]").val(this.getParameter("comment_text",hearstCommentP401));
			$("input[@name=commentTitle]").val(this.getParameter("comment_title",hearstCommentP401));
*/
			document.commentPost.commentText.value = this.getParameter("comment_text",hearstCommentP401);
			document.commentPost.commentTitle.value = this.getParameter("comment_title",hearstCommentP401);
		}
		setCookie("hearstCommentP401",null,-1);
	}

	this.initialize = function(){
		this.ha = (!!this.getParameter("ha"));
		this.state_haspostedcomment = (!!getCookie("hcomment"+this.article_id));
		var myself = this;
		this.cacheBust = Math.floor(Math.random()*100001);
		/* da plan: if this.loginState is 0 (offline), getJSON using api_static
		 * else, reset the cacheBust and use /api/js
		 * NEW PLAN: will only use /api/js after USER HAS POSTED, which means
		 * even if user is logged in, we will be reading /api_static
		 */
		if (this.state_haspostedcomment == false){
			this.parameterString = "?sort_by="+this.sort_by+"&sort_direction="+this.sort_direction;
			this.apiPath = "/api_static/js/";
		} else {
			this.apiPath = "/api/js/";
			this.parameterString = "?cacheBust="+this.cacheBust+"&sort_by="+this.sort_by+"&sort_direction="+this.sort_direction;
		}
		$.getJSON(this.apiPath+"CommentsByArticle/"+this.article_id+"_count"+this.parameterString, function(json){myself.rendercount(json);myself.getcommentsjson(); myself.postP401()});
		if (this.commentTextResize) {
			//this.prep_commentText();
			$('#commentText').TextAreaExpander(100, 500);
		}
		this.displayDialog();
	}

	this.rendercount = function(json){
		/* this function has two uses:
		 * 1) Render the appropriate jq template counts, and
		 * 2) Render any counts where we have hearstcomment attribute - commentcount - I don't like the naming convention here
		 */
		var suffix = "";
		if (parseInt(json.count) != 1){suffix = "s";}
		var jsoncommentcount = {
			"template" : "comment_count",
			"variable_names" : [
				"%TEMPLATE_VARIABLE_COMMENTCOUNT%",
				"%TEMPLATE_VARIABLE_ARTICLE_URL%",
				"%TEMPLATE_VARIABLE_COMMENTCOUNT_STRING%"
			],
			"data" : [
				json.count,
				this.article_url,
				suffix
			]
		};
		this.hjstmpl.drawwide(jsoncommentcount);
		this.commentcount = json.count;
		$("[hearstcomment='commentcount']").html(this.commentcount);
		this.renderpagination();
		if (!!this.rendercountcallback){
			this.rendercountcallback(json);
		}
	}

	this.renderpagination = function(pagenum){
		if (pagenum){this.varpage = pagenum} else {
			this.varpage = 1;
		}
		var totalpages = Math.ceil(this.commentcount/this.vardisp);
		var jsonpages = {
			"templateloop" : "loop_comment_pagination",
			"loop" : []
		};


		switch (this.paginationStyle){
			case "partial":
				if (totalpages > 7){
					if (this.varpage > 4){
						var datagram = {
							"template_name" : "selected_page",
							"variable_names" : ["%TEMPLATE_VARIABLE_ITERATION%","%TEMPLATE_VARIABLE_TOTALPAGES%"],
							"data" : ["&hellip;",totalpages]
						}
						jsonpages.loop.push(datagram);
					}
					var startingpage = 1;
					if (this.varpage <= 4){startingpage = 1}
					else if(this.varpage > (totalpages-4)){startingpage = (totalpages-6)}
					else {startingpage = this.varpage-3}
					for (rp = (startingpage+0); rp <= (startingpage+6); rp++){
						var templatesel = "";
						if (rp == this.varpage){
							templatesel = "selected_page";
						} else {
							templatesel = "iteration";
						}
						var datagram = {
							"template_name" : templatesel,
							"variable_names" : ["%TEMPLATE_VARIABLE_ITERATION%","%TEMPLATE_VARIABLE_TOTALPAGES%"],
							"data" : [rp,totalpages]
						}
						jsonpages.loop.push(datagram);
					}					
					if (this.varpage <= (totalpages-4)){
						var datagram = {
							"template_name" : "selected_page",
							"variable_names" : ["%TEMPLATE_VARIABLE_ITERATION%","%TEMPLATE_VARIABLE_TOTALPAGES%"],
							"data" : ["&hellip;",totalpages]
						}
						jsonpages.loop.push(datagram);
					}
				} else {
					for (rp = 1; rp <= (totalpages); rp++){
						var templatesel = "";
						if (rp == this.varpage){
							templatesel = "selected_page";
						} else {
							templatesel = "iteration";
						}
						var datagram = {
							"template_name" : templatesel,
							"variable_names" : ["%TEMPLATE_VARIABLE_ITERATION%","%TEMPLATE_VARIABLE_TOTALPAGES%"],
							"data" : [rp,totalpages]
						}
						jsonpages.loop.push(datagram);
					}					
				}
				break;
			default:
				for (rp = 1; rp <= (totalpages); rp++){
					var templatesel = "";
					if (rp == this.varpage){
						templatesel = "selected_page";
					} else {
						templatesel = "iteration";
					}
					var datagram = {
						"template_name" : templatesel,
						"variable_names" : ["%TEMPLATE_VARIABLE_ITERATION%","%TEMPLATE_VARIABLE_TOTALPAGES%"],
						"data" : [rp,totalpages]
					}
					jsonpages.loop.push(datagram);
				}
		}

		var jsonprevious = {
			"template" : "comment_previous_link",
			"variable_names" : [
				"%TEMPLATE_VARIABLE_PREVIOUSITERATION%",
				"%TEMPLATE_VARIABLE_TOTALPAGES%"
			],
			"data" : [
				this.varpage-1,
				totalpages
			]
		};
		var jsonnext = {
			"template" : "comment_next_link",
			"variable_names" : [
				"%TEMPLATE_VARIABLE_NEXTITERATION%",
				"%TEMPLATE_VARIABLE_TOTALPAGES%"
			],
			"data" : [
				parseInt(this.varpage)+1,
				totalpages
			]
		};


		// render when appropriate
		if (jsonprevious.data[0] < 1){
			this.hjstmpl.clear(jsonprevious.template);
		} else {
			this.hjstmpl.draw(jsonprevious);
		}
		
		if (jsonnext.data[0] > totalpages){
			this.hjstmpl.clear(jsonnext.template);
		} else {
			this.hjstmpl.draw(jsonnext);
		}
		if (totalpages != 0) {this.hjstmpl.drawloop(jsonpages);}
	}




















	/*
	 * ok this is login verification function, the first arg is displayed if offline, the second if online
	 * I got big problems with this as it uses an external global variable called "loggedInNow" - messy
	 * I'll have to adjust that at a later point
	 */
/*	this.logincheck = function(offline,online){
		this.firebugConsole("CALLING: this.logincheck");
		if (mag_user.logged_in){
			this.postingState("post");
			if ($(".hearstcommentEmail").length != 0){$(".hearstcommentEmail").hide()}
			this.firebugConsole("logincheck: ONLINE");
			return 1;
		} else {
			this.postingState("login");
			if ($(".hearstcommentEmail").length != 0){$(".hearstcommentEmail").show()}
			this.firebugConsole("logincheck: OFFLINE");
			return 0;
		}
	}*/
	this.postingState = function(state){
		switch(state){
			case "post":
				$("[template='addComment']").show();
				$("[template='previewComment']").hide();
				$("[template='loginComment']").hide();
				break;
			case "preview":
				$("[template='addComment']").hide();
				$("[template='previewComment']").show();
				$("[template='loginComment']").hide();
				break;
			case "login":
				$("[template='addComment']").hide();
				$("[template='previewComment']").hide();
				$("[template='loginComment']").show();
				break;
			case "newpost":
				$("#commentText").val("");
				$("[template='addComment']").show();
				$("[template='previewComment']").hide();
				$("[template='loginComment']").hide();
				break;
			default:
				break;
		}
	}
	
	this.publishPost = function(){
		var comment_text = ChangeScriptToText($("[name='commentText']").val()); 
		var comment_title = ChangeScriptToText($("[name='commentTitle']").val());	
		
		if (IsNotNull(comment_title,comment_text)) 
		{
			this.commentjsonobj  = {
				"comment_text" : comment_text,
				"comment_tags" : "",
				"comment_email" : "",
				"comment_title" : comment_title
			}
			this.postingState("newpost");
			this.displayDialog("Thanks! Your tip has been added to this topic");
			this.postComment(this.commentjsonobj);
			return;
		}
		//$('#border-below-blog-comment-text').css("display", "none");
	}
	
	this.previewComment = function(){
		this.commentjsonobj  = {
			"comment_text" : (!!$("[name='commentText']").val()) ? $("[name='commentText']").val() : "",
			"comment_tags" : "",
			"comment_email" : "",
			"comment_title" : (!!$("[name='commentTitle']").val()) ? $("[name='commentTitle']").val() : ""
		}
		var preview_comment_text = this.commentjsonobj.comment_text.replace(/(\r\n|\r|\n)/g, "<br />");
		var preview_comment_title = this.commentjsonobj.comment_title.replace(/(\r\n|\r|\n)/g, "<br />");
		if (!!!this.commentjsonobj.comment_text){
			alert("Text field is empty!");
			return false;
		}
		var date = new Date();
		/* NOTE: we need to get the user_name from a common place, there are a number of ways to get it
		 * $h.session.hearst_user.user_name
		 * hearst_user.user_name
		 * I'm going to use hearst_user.user_name for now..
		 * NOTE: We're having load issues with the avatar images for now, esp with IE. I need to find out what's causing this..
		 */
		$("[template='previewCommentAvatar']").attr({"src": "/community/profilepic/" + hearst_user.user_name});
		$("[template='previewCommentUsername']").html(hearst_user.user_name);
		$("[template='previewCommentTimestamp']").html(date.toLocaleString());
		$("[template='previewCommentTimestampOnly']").html(date.toLocaleTimeString());
		$("[template='previewCommentDatestampOnly']").html(date.toLocaleDateString());
		$("[template='previewCommentTitle']").html(preview_comment_title);
		$("[template='previewCommentText']").html(preview_comment_text);
		this.postingState("preview");
	}
	
	
	
	
	
	
	
	
	
	this.postComment = function(commentjsonobj){
		if (this.submissionInProgress) {
			alert("submission in progress! Please wait..");
			return false;
		}
		var myself = this;
		this.disableSubmitFields(true);
		
		this.commentjsonobj = commentjsonobj;
		if (this.debug){
			this.firebugConsole("SIMULATING this.postComment (post call disabled during debug mode)");
			this.firebugConsole("calling post..:/api/js/Comment?article_id=" + this.article_id + "&comment_title=" + commentjsonobj.comment_title + "&comment_text=" + commentjsonobj.comment_text + "&email="+commentjsonobj.comment_email+"&origin=comments&per_page=" + this.vardisp);
			//myself.ajaxError({"status":"401"},"error",null);
			myself.visualizeCommentPost();
		} else {
			var commentData = {"article_id":this.article_id, "comment_title": commentjsonobj.comment_title, "comment_text":commentjsonobj.comment_text, "email":commentjsonobj.comment_email, "origin":"comments", "per_page": this.vardisp};
			$.ajax({
				type: "POST",
				url: "/api/js/Comment",
				data: commentData,
				//"article_id=" + this.article_id + "&comment_title=" + commentjsonobj.comment_title + "&comment_text" + commentjsonobj.comment_text + "&email="+commentjsonobj.comment_email+"&origin=comments&per_page=" + this.vardisp, 
				//"article_id=" + this.article_id + "&comment_title=" + commentjsonobj.comment_title + "&comment_text=" + commentjsonobj.comment_text + "&per_page=" + this.vardisp,
				error: function(data,status,errorThrown){myself.ajaxError(data,status,errorThrown)},
				success: function(data){setCookie("hcomment"+myself.article_id,true,1);setCookie("hearstCommentP401",null,-1);myself.visualizeCommentPost(data); /*myself.initialize();*/}
			});
		}
	}
	
	this.ajaxError = function(data,status,error){
//		alert("an error was made :-( [Data:"+data+"] [status:"+status+"] [errorThrown"+errorThrown+"]");
//		this.visualizeCommentPost(data);
		
		this.firebugConsole("ajaxERROR");
		this.firebugConsole("data: %d",data.status);
		this.firebugConsole("status: %d",status);
		this.firebugConsole("error: %d",error);
		switch (parseInt(data.status)){
			case 401:
				this.firebugConsole("401 - USER IS ATTEMPTING TO USE EXISTING EMAIL ACCOUNT TO POST ANONYMOUSLY");
				this.firebugConsole("DataString:article_id=" + this.article_id + "&comment_title=" + this.commentjsonobj.comment_title + "&comment_text=" + this.commentjsonobj.comment_text + "&email="+this.commentjsonobj.comment_email+"&origin=comments&per_page=" + this.vardisp);
				alert("You are attempting to post anonymously using an existing account. Please log in to continue");
				setCookie("hearstCommentP401","article_id=" + this.article_id + "&comment_title=" + this.commentjsonobj.comment_title + "&comment_text=" + this.commentjsonobj.comment_text + "&email="+this.commentjsonobj.comment_email+"&origin=comments&per_page=" + this.vardisp,1);
				setCookie("hcomment"+this.article_id,true,-1);
				break;
			default:
				alert("SERVICE ERROR["+data.status+"] Service may be unavailable. Please try again later.");
		}
	}
	
	this.submissionInProgress = false;
	this.disableSubmitFields = function(bool){
		if (bool){
			this.submissionInProgress = true;
			$("#commentText").attr("disabled", true);
			$("#submit_button").attr("disabled", true);
			$("#submit_button").attr("value", "submitting..");
			$("#commentTitle").attr("disabled", true);
			$("input.hearstcommentEmail").attr("disabled", true);
			
			// do this if true
		} else {
			this.submissionInProgress = false;
			$("#commentText").attr("disabled", false);
			$("#submit_button").attr("disabled", false);
			$("#submit_button").attr("value", "Post Comment");
			$("#commentTitle").attr("disabled", false);
			$("input.hearstcommentEmail").attr("disabled", false);
			if (this.state_haspostedcomment){
				$("#commentText").attr("value", "");
				$("#commentTitle").attr("value", "");
				charLimit();
			}
		}
	}

	this.dump = function(arg){
		
		// invoking debug dump will force debug to be true from this point forward..
		this.debug = !!arg;
		console.log("** BEGIN DEBUG DUMP : htmpl_comments**");
		console.log("this.debug: %d", this.debug);
		console.log("this.article_url: %d", this.article_url);
		console.log("this.article_id: %d", this.article_id);
		console.log("this.varpage: %d", this.varpage);
		console.log("this.vardisp: %d", this.vardisp);
		console.log("this.paginationStyle: %d", this.paginationStyle);
		console.log("this.commentcount: %d", this.commentcount);
		console.log("this.transition: %d", this.transition);
		console.log("this.commentLoginForm: %d", this.commentLoginForm);
		console.log("this.commentPostingForm: %d", this.commentPostingForm);
		console.log("this.loginState: %d", this.loginState);
		console.log("this.state_haspostedcomment: %d", this.state_haspostedcomment);
		console.log("this.apiPath: %d", this.apiPath);
		console.log("this.cacheBust: %d", this.cacheBust);
		console.log("this.ha: %d", this.ha);
		console.log("this.parameterString: %d", this.parameterString);
		console.log("this.callback: %d", this.callback);
		console.log("this.commentjsonobj: %d", this.commentjsonobj);
		console.log("COOKIE.hearstCommentP401: %d", getCookie("hearstCommentP401"));
		console.log("COOKIE.hcomment"+this.article_id+": %d", getCookie("hcomment"+this.article_id));
		console.log("** END DEBUG DUMP : htmpl_comments**");
	}
	this.firebugConsole = function(){
		if (this.debug){
			if (arguments.length == 2){
				console.log(arguments[0],arguments[1]);
			}else if(arguments.length == 1){
				console.info(arguments[0]);
			}else {
				console.log(arguments);
			}
		}
	}
	
	this.setsort_by = function(value){
		this.sort_by = value;
		this.initialize();
	}
	this.setsort_direction = function(value){
		this.sort_direction = value;
		this.initialize();
	}
	this.setcomment_rating = function(rating,comment_id,user_rated){
		alert("comment rating being set:"+rating+" comment_id:"+comment_id +" user_rated:"+user_rated);
		var positivecount = $("#comment_rating_dialog_"+comment_id+" > [hearstcomment='comment_positive_count']").html();
		var totalcount = $("#comment_rating_dialog_"+comment_id+" > [hearstcomment='comment_total_count']").html();
		
		positivecount = parseInt(positivecount)+parseInt(rating);
		if (!user_rated){
			totalcount++;
		}
		$("[hearstcomment='comment_rating_dialog_"+comment_id+"']  > [hearstcomment='comment_positive_count']").html(positivecount);
		$("[hearstcomment='comment_rating_dialog_"+comment_id+"'] > [hearstcomment='comment_total_count']").html(totalcount);
	}


	this.displayDialog = function(txt){
		if (txt){
			$("[template='loop_comment_wrap_txt']").show().html(txt);
			$("[template='loop_comment_wrap_waiting']").hide();
		} else {
			$("[template='loop_comment_wrap_txt']").hide();
			$("[template='loop_comment_wrap_waiting']").show();
		}
		$("[template='comment_dialog_box']").show();
	}
	this.hideDialog = function(){
		$("[template='comment_dialog_box']").hide();
	}
	this.prep_commentText = function(){
		/*******************************************************
		 * Auto resize for the comments textarea
		 * inspired by James Padolsey http://james.padolsey.com
		 * thanks James!!
		 */
		var ct_obj = $("#commentText");
		var textarea = ct_obj.css({resize:'none','overflow-y':'hidden'});
		origHeight = (textarea.height() == 0) ? ct_obj.css("height").replace("px","") : textarea.height();
        clone = (function(){
            // Properties which may effect space taken up by chracters:
            var props = ['height','width','lineHeight','textDecoration','letterSpacing'],
                propOb = {};
            // Create object of styles to apply:
            $.each(props, function(i, prop){propOb[prop] = textarea.css(prop);});
            // Clone the actual textarea removing unique properties
            // and insert before original textarea:
            return textarea.clone().removeAttr('id').removeAttr('name').css({
                position: 'absolute',
                top: 0,
                left: -9999
            }).css(propOb).attr('tabIndex','-1').insertBefore(textarea);
			
        })();
		lastScrollTop = null;
		var ct_objupdate = function(){
            // Prepare the clone:
            clone.height(0).val($(this).val()).scrollTop(10000);
            // Find the height of text:
            var scrollTop = Math.max(clone.scrollTop(), origHeight),
                toChange = $(this).add(clone);
            // Don't do anything if scrollTip hasen't changed:
            if (lastScrollTop === scrollTop) { return; }
            lastScrollTop = scrollTop;
            // Check for limit:
            if ( scrollTop >= 1000 ) {
                $(this).css('overflow-y','');
                return;
            }
			toChange.height(scrollTop);
		}
		ct_obj.change(ct_objupdate).keyup(ct_objupdate).keydown(ct_objupdate);
	}

	this.reportAbuse = function(comment_id){
		var url = document.URL;
		//alert(comment_id);
		var popWin = window.open('/comments_report_abuse_login?comment_id='+comment_id+'&pUrl='+url,'popForm','width=450,height=330,resizable=1');
		popWin.focus();
	}





	this.loginCheck = function(status){
		this.loginState = status;
		this.firebugConsole("CALLING: this.logincheck");
		if (this.loginState == 1){
			// user is logged in
			hearstcomments.postingState("post");
			$(".hearstcommentEmail").hide();
			this.firebugConsole("logincheck: ONLINE");
		} else {
			// user is logged out
			hearstcomments.postingState("login");
			$(".hearstcommentEmail").show();
			this.firebugConsole("logincheck: OFFLINE");
		}
	}

	// initial call
	this.initialize();

}








/*
 * Legacy functions that I've yet to incorporate into the comments object
 */

	function reportAbuse(id){
		var id = id;
		var popWin = window.open('','popForm','width=450,height=330');
		popWin.location="/comments/report-this?comment_id="+id;
		popWin.focus(); 
	}


var charCount = "1700"; // max 
function charLimit(){
	var userPost = document.getElementById("commentText").value;
	if ( $.browser.msie ) 
		userPost = userPost.replace(/\s\n/g,'\n');
	
	var len = userPost.length;
	if(len > charCount){
		userPost = userPost.substring(0,charCount);
		document.getElementById("commentText").value = userPost;
		return false;
	}
	document.getElementById("watchCharCount").value = charCount-len;
	if(charCount-len <= 0){
		alert("You've reached the maximum length. This post may be truncated.");
		return false;
	}
}

function emailValid(str) {
	var r1 = new RegExp("(@.*@)|(\\.\\.)|(@\\.)|(^\\.)");
	var r2 = new RegExp("^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$");
	return (!r1.test(str) && r2.test(str));
}

function checkChars(hearstcommentobject){
//	alert(!hearstcommentobject.loginState);
	var commentjsonobject = {
		"comment_text" : document.commentPost.commentText.value,
		"comment_tags" : document.commentPost.commentTags.value,
		"comment_email" : document.commentPost.commentEmail.value,
		"comment_title" : document.commentPost.commentTitle.value
	}
	if(document.commentPost.watchCharCount.value >= 1700){
		document.commentPost.commentText.value = document.commentPost.commentText.value.substring(0,1700);
		alert("You've reached the maximum length. This post may be truncated.");
		return false;
	}else if ((!emailValid(document.commentPost.commentEmail.value)) && (!hearstcommentobject.loginState)){
		alert("Email is invalid.");
		return false;
	}else{
	hearstcommentobject.postComment(commentjsonobject);
	}
}

// cookie utilities 
function setCookie(c_name,value,expiredays){
	var exdate=new Date();
	exdate.setDate(exdate.getDate()+expiredays);
	document.cookie=c_name+ "=" +escape(value)+
	((expiredays==null) ? "" : ";expires="+exdate.toGMTString());
}

function getCookie(c_name){
	if (document.cookie.length>0)
	  {
	  c_start=document.cookie.indexOf(c_name + "=");
	  if (c_start!=-1)
	    { 
	    c_start=c_start + c_name.length+1; 
	    c_end=document.cookie.indexOf(";",c_start);
	    if (c_end==-1) c_end=document.cookie.length;
	    return unescape(document.cookie.substring(c_start,c_end));
	    } 
	  }
	return "";
}





/**
 * TextAreaExpander plugin for jQuery
 * v1.0
 * Expands or contracts a textarea height depending on the
 * quatity of content entered by the user in the box.
 *
 * By Craig Buckler, Optimalworks.net
 *
 * As featured on SitePoint.com:
 * http://www.sitepoint.com/blogs/2009/07/29/build-auto-expanding-textarea-1/
 *
 * Please use as you wish at your own risk.
 */

/**
 * Usage:
 *
 * From JavaScript, use:
 *     $(<node>).TextAreaExpander(<minHeight>, <maxHeight>);
 *     where:
 *       <node> is the DOM node selector, e.g. "textarea"
 *       <minHeight> is the minimum textarea height in pixels (optional)
 *       <maxHeight> is the maximum textarea height in pixels (optional)
 *
 * Alternatively, in you HTML:
 *     Assign a class of "expand" to any <textarea> tag.
 *     e.g. <textarea name="textarea1" rows="3" cols="40" class="expand"></textarea>
 *
 *     Or assign a class of "expandMIN-MAX" to set the <textarea> minimum and maximum height.
 *     e.g. <textarea name="textarea1" rows="3" cols="40" class="expand50-200"></textarea>
 *     The textarea will use an appropriate height between 50 and 200 pixels.
 */

(function($) {

	// jQuery plugin definition
	$.fn.TextAreaExpander = function(minHeight, maxHeight) {

		var hCheck = !($.browser.msie || $.browser.opera);

		// resize a textarea
		function ResizeTextarea(e) {

			// event or initialize element?
			e = e.target || e;

			// find content length and box width
			var vlen = e.value.length, ewidth = e.offsetWidth;
			if (vlen != e.valLength || ewidth != e.boxWidth) {

				if (hCheck && (vlen < e.valLength || ewidth != e.boxWidth)) e.style.height = "0px";
				var h = Math.max(e.expandMin, Math.min(e.scrollHeight, e.expandMax));

				e.style.overflow = (e.scrollHeight > h ? "auto" : "hidden");
				e.style.height = h + "px";

				e.valLength = vlen;
				e.boxWidth = ewidth;
			}

			return true;
		};

		// initialize
		this.each(function() {

			// is a textarea?
			if (this.nodeName.toLowerCase() != "textarea") return;

			// set height restrictions
			var p = this.className.match(/expand(\d+)\-*(\d+)*/i);
			this.expandMin = minHeight || (p ? parseInt('0'+p[1], 10) : 0);
			this.expandMax = maxHeight || (p ? parseInt('0'+p[2], 10) : 99999);

			// initial resize
			ResizeTextarea(this);

			// zero vertical padding and add events
			if (!this.Initialized) {
				this.Initialized = true;
				$(this).css("padding-top", 0).css("padding-bottom", 0);
				$(this).bind("keyup", ResizeTextarea).bind("focus", ResizeTextarea);
			}
		});

		return this;
	};

})(jQuery);


// initialize all expanding textareas
jQuery(document).ready(function() {
	jQuery("textarea[class*=expand]").TextAreaExpander();
});

function ChangeScriptToText(script)
{	
	return script.replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\$/g,"&#36;");	
}

function Trim(InputString) { 
  return InputString.replace(/^\s+|\s+$/g, '') ;
}

function IsNotNull(commentTitle, commentText)
{
	commentTitle = Trim(commentTitle);
	commentText = Trim(commentText);
	if (commentTitle == "" || commentTitle == null) 
	{
		alert("Please enter text for subject.");
		return false;
	}
	
	if (commentText == "" || commentText == null) 
	{
		alert("Please enter text for this comment.");
		return false;
	}
	return true;
}

  //////////////////////////////////////////////////////////////////
 // Function to convert from server datetime to client datetime  //
//////////////////////////////////////////////////////////////////
function convertToClientDate(serverDateTime,clientTimezoneOffset) {

    // Create Date object for server    
	serverDate = new Date(serverDateTime);
	
    // Get UTC time in msec, 4 is our server timezone offset
    utc = serverDate.getTime() + (4 * 3600000) - 108000;
   
    // Create new Date object for client 
    clientDate = new Date(utc + (3600000*clientTimezoneOffset));
	
    // Return client date
    return clientDate;
}

//Limit characters of subject string. If > 200 characters => truncate it.
$("#commentTitle").keyup(function(){
	var subject = $("#commentTitle").val();
	if(subject.length > 200)
	{
		var truncatedSubject = subject.substring(0,200);
		alert("You've reached the maximum length. This comment subject may be truncated.");
		$("#commentTitle").val(truncatedSubject);
	}
});

  /////////////////////////////////////////
 // Function: convert to 12 hour format //
/////////////////////////////////////////
function ConvertTo12HourFormat(time)
{	
	var time = time.substring(0,11);
	if(time.substring(9,11) != "")
	{
		return time;
	}
	else
	{
		var result = "";
		var arrayTime = time.substring(0,8).split(":");
		var hour = arrayTime[0];
		
		//Convert hour
		if(hour > 0 && hour < 13)
			result += hour;				
		else
		{
			if(hour == 0)
				result += 12;
			else
				result += hour - 12;
		}				
		result += ":" + arrayTime[1] + ":" + arrayTime[2];
		
		//Get AM or PM
		if(hour > 12)
			result += " PM";
		else
			result += " AM";
		
		return result;
	}
}

