/*
 * Copyright (c) 2006, 2007 Lev Walkin <vlm@lionet.info>. All rights reserved.
 * You may copy and modify this script as long as the above copyright notice,
 * this condition and the following disclaimer is left intact.
 * This software is provided by the author "AS IS" and no warranties are
 * implied, including fitness for a particular purpose. In no event shall
 * the author be liable for any damages arising in any way out of the use
 * of this software, even if advised of the possibility of such damage.
 * $Version: 1.24$
 */

if(!window.$JCA) {
  var $JCA = [];
  var $JCLT = {
	leaveComment: 'Leave a comment',
	nameLabel: 'Your name:',
	emailLabel: 'Send replies to email:',
	emailNote: '(if provided, email will not be displayed or shared)',
	commentLabel: 'Comment:',
	submit: 'Submit comment',
	cancel: 'Cancel',
	tooShort: 'Your message is too short',
	tooLong: 'Message size should not exceed 1000 bytes',
	junkCtl: 'Junk control'
  };
  var $JCL = window.JSCC_Translate || function(t) { return $JCLT[t] || t; }
}

new JSCC();	/* JavaScript Comment Class */

function JSCC() {
	/* Find the target DIV for all the blog comments */
	this.jcaIndex = $JCA.length;
	$JCA.push(this);
	this.get = function(id) { return document.getElementById(id); }
	this.cr = function(tag) { return document.createElement(tag); }
	this.uri = 'http://js-kit.com/comment';
	this.fieldDfl = {};
	this.TC = {};
	this.tmpID = 0;
	this.pathOverride = "";
	this.cmtById = [];
	this.utmpl={};

	var idName = "js-kit-comments";

	var target = arguments.length ? arguments[0] : this.get(idName);

	if(target) {
		this.labelHTML = target.getAttribute("label");
		var path = target.getAttribute("path");
		if(path) {
			this.pathOverride = String(path).replace(/^([^\/]+)/,
				window.location.pathname + "/$1");
		}
		var rel = target.getAttribute("rel");
		this.backwards = (!!target.getAttribute("backwards"))
				|| (rel && rel == "backwards");
		var cn = target.childNodes;
		for(var n=0;n < cn.length;n++)
			this.utmpl[cn[n].className] = cn[n].outerHTML;
		target.innerHTML = "";
		target.style.visibility = "visible";
	} else {
		var els = document.body.getElementsByTagName(idName);
		var oWay = false;
		if(els && els.length) oWay = true;
		else els = document.body.getElementsByTagName("div");
		if(els && els.length) {
			$JCA.shift();
			for(var i=0; i < els.length;i++)
			  if(oWay || els[i].className.match(/js-kit-comments/))
				new JSCC(els[i]);
			if($JCA.length) return;
			$JCA.push(this);
		}
		document.write('<div id="'+idName+'"></div>');
		target = this.get(idName);
	}
	target.className = idName;
	target.id = "";

	var self = this;
	self.target = target;
	self.setDefaultField = function(name,value){self.fieldDfl[name]=value;}

	this.server = function(ext, data) {
		var wl = window.location;
		var sc = self.cr("script");
		sc.setAttribute("charset", "utf-8");
		sc.src = self.uri + ext + self.pathOverride
			+ "?ref="
			+ encodeURIComponent(
	wl.protocol + "//" + wl.host
	+ (self.pathOverride.length ? "/" : wl.pathname))
			+ "&" + data;
		self.target.appendChild(sc);
		return false;
	}
	self.server("s-data.js","jx="+self.jcaIndex);
}

document.write('<style type="text/css">'
+ ".js-OldComments { margin-bottom: 1px; }"
+ ".js-LeaveComment { margin: 3pt; }"
+ ".js-CreateComment { display: none; }"
+ ".js-CreateCommentBg { margin: 1em; padding: 0.5em; border: solid 1px #c0c0c0; text-align: left; float: left; -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.4) }"
+ ".js-commentFieldSubject { font-weight: bold; margin-bottom: 5px; }"
+ ".js-commentFieldLabel { margin-top: 5px; }"
+ ".js-commentFieldNote { font-family: Verdana; font-size: 7pt; color: #808080; }"
+ ".js-singleComment { font-size: 8pt; font-family: Verdana, Helvetica; border: solid 1px #c0c0c0; text-align: left; margin-bottom: -1px; }"
+ ".js-singleCommentBg { padding: 0.3em; }"
+ ".js-singleCommentINFO { text-shadow: #c0c0c0 0px 2px 4px; color: #808080; float: right; padding: 3px; margin-left: 2em; text-align: right; }"
+ ".js-singleCommentName { }"
+ ".js-singleCommentDate { font-size: 7pt; }"
+ ".js-commentControl { float: left; margin-right: 2em; }"
+ ".js-poweredBy { margin-right: 2pt; color: #808080; font-size: 7pt; font-family: Verdana, Helvetica; }"
+ ".js-poweredBy A { text-decoration: none; color: #8080a0 }"
+ "</style>");
(function(v){v=parseFloat(v.split("MSIE")[1]);
if(v>=5.5)document.write('<style>.js-singleCommentBg{zoom:1.0;}</style>');})
(navigator.appVersion);
if(navigator.userAgent.indexOf("Opera")>=0)
document.write("<style>wbr:after{content:\"\\00200B\"}</style>");
else
document.write("<style>.js-singleCommentTEXT{word-wrap:break-word}</style>");

JSCC.prototype.addChild = function(to, what) {
	if(arguments.length == 3 && arguments[2])
		to.insertBefore(what, to.firstChild);
	else
		to.appendChild(what);
}
JSCC.prototype.html = function() {
	var div = this.cr("div");
	for(var text = '', i = 0; i < arguments.length; i++)
		text += arguments[i];
	div.innerHTML = text;
	var ch = div.firstChild;
	div = null;
	return ch;
}
JSCC.prototype.a = function() {
	var a = this.cr("a");
	a.href = "";
	for(var text = '', i = 0; i < arguments.length; i++)
		text += arguments[i];
	a.innerHTML += text;
	return a;
}

JSCC.prototype.div = function(id) {
	var div = this.cr("div");
	for(var i = 1; i < arguments.length; i++) {
		var arg = arguments[i];
		switch(typeof(arg)) {
		case "string":
			this.addChild(div, document.createTextNode(arg));
			break;
		case "undefined":
			break;
		default:
		case "object":
			if(!arg) break;
			this.addChild(div, arg);
			break;
		}
	}
	if(id) {
		div.className = id;
		var idText = String(id);
		if(idText.charCodeAt(3) < 91)
			this.TC[idText] = div;
	}
	return div;
}

JSCC.prototype.dtJunk
 = '<div class="js-singleCommentJunkCtl">'
   + '<div class="js-singleCommentIsJunk">'
     + '[<a class="js-singleCommentSetNonJunk">{Label:not junk}</a>]</div>'
   + '<div class="js-singleCommentIsNonJunk">'
     + '[<a class="js-singleCommentSetJunk">{Label:junk}</a>]</div>'
 + '</div>'
;

JSCC.prototype.dtComment
 = '<div class="js-singleComment">'
 + '<div class="js-singleCommentBg">'
 + '<div class="js-singleCommentINFO">'
   + '<div class="js-singleCommentName">{Name}</div>'
   + '<div class="js-singleCommentDate">{Date}</div>'
   + '<div class="js-singleCommentControls">'
     + '[<a class="js-singleCommentReply">{Label:reply}</a>]'
     + '<span class="js-singleCommentDeletable"> [<a class="js-singleCommentDelete">{Label:delete}</a>]</span>'
   + '</div>'
 + '</div>'
 + '<div class="js-singleCommentText">{Text}</div>'
 + '<br clear="all" />'
 + '</div>'
 + '</div>'
;

JSCC.prototype.dtCreate
 = '<div class="js-CreateComment">'
 + '<div class="js-CreateCommentBg">'
 + '<div class="js-commentFieldSubject">{Label:leaveComment}</div>'
 + '<div class="js-commentFieldLabel">{Label:nameLabel}</div>'
 + '<div><input name="js-CmtName" SIZE=32 /></div>'
 + '<div class="js-commentFieldLabel">{Label:emailLabel}'
   + '<div class="js-commentFieldNote">{Label:emailNote}</div>'
 + '</div>'
 + '<div><input name="js-CmtEmail" type="email" SIZE=32 /></div>'
 + '<div class="js-commentFieldLabel">{Label:commentLabel}</div>'
 + '<div><textarea name="js-CmtText" ROWS=4 COLS=32></textarea></div>'
 + '<div><input type=submit name="js-Cmtsubmit" VALUE="{Label:submit}">'
 + '<input type=reset name="js-Cmtcancel" VALUE="{Label:cancel}"></div>'
 + '</div><br clear="all" /></div>'
;

JSCC.prototype.mapClass2Object = function(ctl, e) {
	if(e.className) ctl[e.className] = e;
	if(e.name) ctl[e.name] = e;
	try { var cn = e.childNodes; var clen = cn.length;
		for(var i = 0; i < clen; i++)
			this.mapClass2Object(ctl, cn[i]);
	} catch(e){}
	return ctl;
}
JSCC.prototype.localDate = function(t) {
	if(!t) return "";
	var d = new Date(t * 1000);
	return d.toLocaleDateString();
}
JSCC.prototype.localTime = function(t) {
	if(!t) return "";
	var d = new Date(t * 1000);
	return d.toLocaleTimeString();
}
JSCC.prototype.gtmpl = function(t) {
	var lowercase = function(a, m) { return String(m).toLowerCase(); }
	t = t.replace(/^[^<]*(<.*>)[^>]*$/m, "$1");
	t = t.replace(/(<[\/]?[A-Z]+)/g, lowercase);
	t = t.replace(/{Label:([^}]*)}/g,function(a,m){return $JCL(m);});
	return t;
}
JSCC.prototype.tmpl = function(t, obj) {
	var self = this;
	t = self.gtmpl(t);
	t = t.replace(/{Date}/g, self.localDate(obj.TS));
	t = t.replace(/{Time}/g, self.localTime(obj.TS));
	var text = String(obj.Text).replace(/^[ \s]+|[ \s]+$/, '');
	text = text.replace(/\n/g, '&nbsp;<br />');
	text = text.replace(/([^&<>\s]{12})([^&<>\s]{12})/g, '$1<wbr></wbr>$2');
	text = text.replace(/{/g, '&#123;');
	t = t.replace(/{Text}/g, text);
	t = t.replace(/{([A-Za-z0-9]+)}/g,function(a,m){return obj[m]||'';});
	return t;
}

JSCC.prototype.createSingleComment = function(obj) {
	if(!obj.ID || !obj.Text) return undefined;

	var self = this;

	if(obj.status == 'D') {
		var cmt = this.cr("div");
		cmt.style.display = "none";
	} else {
		var cmt = this.html(this.tmpl(this.utmpl['js-singleComment']
			|| this.dtComment, obj));
	}

	cmt.id = obj.ID;
	this.cmtById[cmt.id] = cmt;

	var ctls = this.mapClass2Object({}, cmt);
	cmt.ctls = ctls;
	cmt.cobj = obj;
	var jsc = function(t){return ctls['js-singleComment'+t]}

	if(obj.isEmbryonic) {
		/* Waiting for permanent ID */
		var cmtCtls = jsc('Controls');
		if(cmtCtls) {
			cmtCtls.style.visibility = "hidden";
			cmt.assignPermanentID = function(msgId) {
				cmt.assignPermanentID = null;
				delete self.cmtById[cmt.id];
				cmt.id = msgId;
				self.cmtById[cmt.id] = cmt;
				cmtCtls.style.visibility = "";
			}
		}
	}

	var rC = jsc("Reply");
	if(rC) {
		rC.href = "";
		rC.onclick = function() {
			return self.ShowCommentDialog(cmt.id); }
	}
	var dC = jsc("Delete");
	if(dC) {
		dC.href = "";
		dC.onclick = function() {
			cmt.style.display = "none";
			return self.server('.del', 'id=' + cmt.id,
				+ (cmt.cobj.status == 'S' ? '&junk=yes' : ''));
		}
	}
	var hideCtl = jsc("Deletable");
	if(hideCtl && !obj.yours)
		hideCtl.style.display = "none";

	cmt.bg = jsc('Bg');
	var cinfo = jsc('INFO');

	var junkCtl = jsc("JunkCtl");
	if(!junkCtl) {
		junkCtl = this.html(this.tmpl(this.dtJunk, obj));
		try { this.addChild(cinfo, junkCtl); } catch(e) {}
		this.mapClass2Object(ctls, junkCtl);
	}
	junkCtl.style.display = "none";

	var isJ = jsc("IsJunk");
	var noJ = jsc("IsNonJunk");
	var enJ = jsc("SetJunk");
	var unJ = jsc("SetNonJunk");

	var spsf = function(s) {
		isJ.style.display = s ? "" : "none";
		noJ.style.display = s ? "none" : "";
		cmt.cobj.status = s ? 'S' : 'A';
		if(s) cmt.style.background = '#ffffe0 url(http://js-kit.com/images/bio-hazard.gif) bottom right repeat-x';
		else {
			cmt.style.backgroundColor = "";
			cmt.style.backgroundImage = "";
		}
		if(cinfo) cinfo.style.backgroundColor = s ? '#ffffe0' : "";
	}

	spsf(obj.status == 'S');

	var af = function(o,L,S){o.href="";o.onclick=function(){if(obj.status!=L){spsf(L=='S');self.server('.jnk','id='+cmt.id+"&junk="+S)};return false;}}
	af(enJ, 'S', 'yes');
	af(unJ, 'A', 'no');

	return this.div("js-commentThread", cmt);
}

JSCC.prototype.level2margin = function(level) {
	if(level < 20) return "10px";
	if(level < 40) return "4px";
	return "0px";
}
JSCC.prototype.cmtInDiv = function(div, obj) {
	var cmt = this.createSingleComment(obj);
	if(cmt) {
		if(obj.ParentID) {
			var prn = this.cmtById[obj.ParentID];
			if(prn && (prn = prn.parentNode)) {
				cmt.jsLeftOffset = prn.jsLeftOffset + 1;
				cmt.style.marginLeft = this.level2margin(cmt.jsLeftOffset);
				this.addChild(prn, cmt);
				return cmt;
			}
		}
		cmt.jsLeftOffset = 0;
		this.addChild(div, cmt, this.backwards);
	}
	return cmt;
}

JSCC.prototype.setOpacity = function(div, val) {
	div.style.opacity = val;
	div.style.filter = 'alpha(opacity: ' + Math.round(val * 100) + ')';
}

JSCC.prototype.flash = function(cmt) {
	var self = this;
	var bg = cmt.bg;

	try {
		bg.style.backgroundColor = "#ffff00";
		self.setOpacity(bg, 0);
	} catch(e) { return; }

	cmt.cntDown = 3.14 / 2;
	cmt.cntMode = 0;

	cmt.intvl = setInterval(function() {
		cmt.cntDown -= cmt.cntMode ? 0.5 : 0.3;
		if(cmt.cntDown > 0) {
			if(cmt.cntMode)
				var c = Math.sin(cmt.cntDown);
			else
				var c = Math.cos(cmt.cntDown);
			self.setOpacity(bg, c);
		} else if(cmt.cntMode) {
			clearInterval(cmt.intvl);
			cmt.intvl = null;
			bg.style.backgroundColor = "";
			self.setOpacity(bg, 1);
		} else {
			cmt.cntMode = 1;
			cmt.cntDown = 3.14 / 2;
		}
	}, 100);
}

JSCC.prototype.fields = function (node, cmtObj, tagName) {
	var flds = node.getElementsByTagName(tagName);
	var message = '';
	for(var i = 0; i < flds.length; i++) {
		var field = flds[i];
		var name = String(field.getAttribute("NAME"));
		if(!name.match(/^js-Cmt[A-Za-z0-9]+$/)) continue;
		message += "&" + name + "=" + encodeURIComponent(field.value);
		var shortName = name.replace(/^js-Cmt/, '');
		var text = String(field.value);
		text = text.replace(/&/g, "&amp;");
		text = text.replace(/</g, "&lt;");
		text = text.replace(/>/g, "&gt;");
		text = text.replace(/\n/g, "<br />");
		cmtObj[shortName] = text;
	}
	return message;
}

JSCC.prototype.cmtInPlace = function(cobj) {
	var div = this.TC["js-OldComments"];
	this.tmpID++;
	cobj.ID = "jst-" + this.tmpID;
	cobj.isEmbryonic = true;
	var d = new Date();
	cobj.TS = Math.round(d.valueOf() / 1000);
	var cmt = this.cmtInDiv(div, cobj);
	this.flash(cmt.firstChild);
	return cmt;
}

JSCC.prototype.ShowCommentDialog = function(msgId) {

	this.forMsgID = msgId;

	var cct = this.TC["js-LeaveComment"];
	var ccd = this.TC["js-CreateComment"];

	/* Remove dialog from sight */
	this.CommentCancelled();
	if(msgId) {
		var nthr = this.get(msgId);
		if(nthr && (nthr = nthr.parentNode)) {
			/* Reposition dialog */
			ccd.parentNode.removeChild(ccd);
			this.addChild(nthr, ccd);
		}
	}

	cct.style.display = "none";
	ccd.style.display = "block";
	try {
		var sub = this.TC["js-Cmtsubmit"];
		var email = this.TC["js-CmtEmail"];
		var name = this.TC["js-CmtName"];
		var text = this.TC["js-CmtText"];

		if(sub) sub.focus();
		if(email && !email.eFilled && this.fieldDfl["Email"]) {
			email.focus();
			email.value = this.fieldDfl["Email"];
		}
		if(name && !name.value.length)
			name.value = this.fieldDfl["Name"];
		if(name && name.value.length) {
			text.focus();
		} else if(name) {
			name.focus();
		}
	} catch(e) { }
	return false;
}

JSCC.prototype.CommentCancelled = function() {
	var lct = this.TC["js-LeaveComment"];
	var ccd = this.TC["js-CreateComment"];
	var car = this.TC["js-CommentsArea"];
	lct.style.display = "";
	ccd.style.display = "";
	if(car && ccd.parentNode != car) {
		ccd.parentNode.removeChild(ccd);
		this.addChild(car, ccd, this.backwards);
	}
	return false;
}

JSCC.prototype.CommentSubmitted = function() {
	var form = this.TC["js-CreateComment"];
	var cmtObj = {};
	cmtObj.yours = true;
	var message = this.fields(form, cmtObj, "input")
		+ this.fields(form, cmtObj, "textarea");
	message = message.replace(/^&/, '');
	if(!cmtObj.Text || !cmtObj.Text.length) {
		alert($JCL("tooShort"));
		return false;
	}
	if(cmtObj.Text.length > 1000) {
		alert($JCL("tooLong"));
		return false;
	}
	cmtObj.ParentID = this.forMsgID;
	this.CommentCancelled();
	/* Attach message */
	this.cmtInPlace(cmtObj);
	/* Kick in message submission */
	var puturl = message + '&tid=' + cmtObj.ID
	  + (cmtObj.ParentID ? ('&js-CmtParentID=' + cmtObj.ParentID) : '');
	return this.server('.put', puturl);
}

function JSReplyMSGId(tmpid, msgid) {
	try {
		var tcmt = document.getElementById(tmpid);
		tcmt.assignPermanentID(msgid);
	} catch(e) { ; }
}

JSCC.prototype.newData = function(arr) {

	var s = this;
	var tc = s.TC;
	var d=function(){return s.div.apply(s,arguments);}
	s.adminMode = (arguments.length>1) && arguments[1];
	s.noJunk = (arguments.length>2) && arguments[2];

	var labelHTML = s.labelHTML || $JCL('leaveComment');

	var oc = d("js-OldComments");
	for(var i = 0; i < arr.length; i++)
		s.cmtInDiv(oc, arr[i]);

	var cc = s.html(s.gtmpl(s.utmpl['js-CreateComment'] || s.dtCreate));
	s.mapClass2Object(tc, cc);

	var o;
	o = tc['js-Cmtsubmit'];
	if(o) o.onclick = function() { return s.CommentSubmitted(); }
	o = tc['js-Cmtcancel'];
	if(o) o.onclick = function() { return s.CommentCancelled(); }
	o = tc['js-CmtEmail'];
	if(o) {
		o.style.color = '#808080';
		o.value = 'email is ' + (s.adminMode ? 'mandatory for you (admin)' : 'optional');
		o.onfocus = function() { if(o.eFilled) return true; o.value = ''; o.style.color = ''; o.eFilled = true; return true; }
	}

	var lca = d('js-commentControl', s.a($JCL(labelHTML)));
	lca.onclick = function() { return s.ShowCommentDialog(null); };

	var jmg = d('js-commentControl', s.a($JCL("junkCtl")));
	jmg.onclick = function() {
		s.jmgmt = !s.jmgmt;
		for(var i in s.cmtById) try {
			var cmt = s.cmtById[i];
			var ctls = cmt.ctls;
			ctls["js-singleCommentControls"].style.display=s.jmgmt?"none":"";
			ctls["js-singleCommentJunkCtl"].style.display=s.jmgmt?"":"none";
		} catch(e){;}
		return false;
	}
	if((!s.adminMode)||s.noJunk) jmg = "";

	var pb = d("js-commentControl js-poweredBy", "(",
	s.html('<a href="http://js-kit.com/?wow">JS-Kit</a>'), " anti-spam by ",
	s.html('<a href="http://akismet.com/">Akismet</a>'), ")");
	if(s.noJunk) pb = "";

	var ca = d("js-CommentsArea",
		d("js-LeaveComment", lca, jmg, pb,
			s.html('<br clear="all"/>')),
		tc["js-CreateComment"]);
	s.addChild(ca, tc["js-OldComments"], !s.backwards);
	s.addChild(s.target, ca);
}
