function Comments(elems, opts, cbs) {
	var self = this;
	
	this._cbs = jQuery.extend({}, {}, cbs);
	this._idents = {};
	this._comments = {};
	this._chandler = new Comment_ajax_handler();

	var ids = [];
	for (var i=0; i < elems.length; ++i) {
		ids.push(elems[i].id);
	}
			
	var postcbs = {	
		add_comment : function (eid, name, str, priv) {
			var f = priv ? 8 : 0;
			var rv = self._chandler.add_comment(eid, name, str, f);
			if (rv[0] == 0) {
				self.update([eid]);   
			}
			else {
				window.alert("error: " + rv[1] + " (" + rv[0] + ")");
			}
		},
		del_comment : function (eid, id) {
			var rv = self._chandler.del_comment(id);
			if (rv[0] == 0) {
				self.update([eid]);   
			}
			else {
				window.alert("error: " + rv[1] + " (" + rv[0] + ")");
			}
		},
		change_comment_flags : function (eid, id, sflags, cflags) {
			var rv = self._chandler.change_comment_flags(id, sflags, cflags);
			if (rv[0] == 0) {
				self.update([eid]);   
			}
			else {
				window.alert("error: " + rv[1] + " (" + rv[0] + ")");
			}
		}
	};

	var commentcbs = {
		get_comments : function (rv) {
			if (rv[0] != 0)
				return; // skip error
			
			var cdatas = rv[1];
			$.extend(self._idents, rv[2]);
			for (var i=0; i < ids.length; ++i) {
				var id = ids[i];
				var posts = cdatas[id] ? cdatas[id] : [];
				self._comments[id] = new Comment(id, self, posts, opts, postcbs); 
				self._comments[id].refresh();
			}

			if (self._cbs.comments_ready_action) {
				self._cbs.comments_ready_action();
			}
		}
	};

	var h = new Comment_ajax_handler(commentcbs);
	h.get_comments(ids, 15);
}

Comments.prototype.get_comments = function () {
	return this._comments;
}

Comments.prototype.get_idents = function () {
	return this._idents;
}

Comments.prototype.update = function (ids) {
	var rv = this._chandler.get_comments(ids, 15);
	if (rv[0] == 0) {
		var cdatas = rv[1];
		$.extend(this._idents, rv[2]);
		var fids = {}; // ids:t joilla posteja
		for (var id in cdatas) {
			fids[id] = 1;
			var c = this._comments[id];
			var posts = cdatas[id];
			c.update(posts);
			c.refresh();
		}
		// silta varalta etta olla poistettu kaikki postit
		for (var i=0; i < ids.length; ++i) {
			var id = ids[i];
			if (!fids[id])  {
				var c = this._comments[id];
				c.update([]);
				c.refresh();
			}
		}
	}
}


function Comment(id, comments, posts, opts, cbs) {
	var self = this;
	this._id = id;
	this._comments = comments;
	this._sposts = 0;
	this._cbs = cbs;
	var def_opts = { visible: 3, rows : 4, cols : 40, status_mask : 15 };
	this._opts = jQuery.extend({}, def_opts, opts);
	
	this.update(posts);
	
	var div = $("#" + this._id);
	
	var pdiv;	
	div.append(pdiv = $(document.createElement("div")));
	pdiv.addClass("commentarea");
	pdiv.attr("id", this._id + "_p");

	var d;
	var t1;
	div.append(d = $(document.createElement("div")));
	d.addClass("commentcontrolarea");
	d.attr("id", this._id + "_ca");
	d.css("display", "none");
	d.append(t = $(document.createElement("div")));
	t.append(t = $(document.createElement("textarea")));
	t.attr("cols", this._opts.cols);
	t.attr("rows", this._opts.rows);
	d.append(d = $(document.createElement("div")));
	d.append("<label>name*:</label>&nbsp;");
	d.append(t = $(document.createElement("input")));
	t.attr("size", "16");
	d.append("<span>&nbsp;*empty=anonymous</span>");
	d.append(d = $(document.createElement("div")));
	d.append(t = $(document.createElement("button")));
	t.text("save");
	t.click(function () {
		$("#" + self._id + "_ca").hide("slow");
		var priv = $(":checkbox", "#" + self._id)[0].checked;
		var str = $("textarea", "#" + self._id).val();
		var name = $("input", "#" + self._id).val();
		self._cbs.add_comment(self._id, name, str, priv);
	});
	d.append("&nbsp;");
	d.append(t = $(document.createElement("button")));
	t.text("cancel");
	t.click(function () {
		$("#" + self._id + "_ca").hide("slow");
	});
	d.append("&nbsp;");
	t = document.createElement("input");
	t.type = "checkbox";
	t = $(t);
	d.append(t);
	d.append("&nbsp;");
	d.append(t = $(document.createElement("label")));
	t.html("private");
}

Comment.post_statuses = {
	1 : 'accepted',
	2 : 'rejected',
	4 : 'pending',
	8 : 'private'
};

Comment.admin_ids = {
	1 : 1, 734 : 1, 7978 : 1, 10111 : 1
};

Comment.is_admin = function (id) {
	return Comment.admin_ids[id] ? 1 : 0;
}

Comment.prototype.set_opts = function (opts) {
	this._opts = jQuery.extend(this._opts, opts);
}

Comment.prototype.get_id = function () {
	return this._id;
}

Comment.prototype.get_spost_count = function () {
	return this._nsposts;
}

Comment.prototype.get_post_status_str = function (pstat) {
	var s = "";
	var ps = Comment.post_statuses;
	for (var f in ps) {
		if (pstat & f) {
			if (s != "") s += " / ";
			s += ps[f];
		}
	}
	return s;
}

Comment.prototype.refresh = function () {
	var self = this;
	var div = $("#" + this._id + "_p");
	var visible = this._opts.visible;
	var smask = this._opts.status_mask;
	var lid = Tipex.check_login();
	var nsposts = 0;
	var idents = this._comments.get_idents();
		
	div.children().remove();

	for (var i=this._posts.length-1; i >= 0; --i) {
		var p = this._posts[i];
		var pstat = p[4];
		if (!(pstat & smask)) 
			continue;
		++nsposts;
		var pstatstr = this.get_post_status_str(pstat);	
		var ep = $(document.createElement("div"));
		ep.addClass("post").addClass(pstatstr);
		ep.attr("id", "cp_" + p[0]);
		var e = $(document.createElement("div"));
		ep.append(e);
		e.addClass("posthead");
		e.html("<span class=\"posttime\">" + Util.date_str2(new Date(p[1]*1000)) + "</span>");
		
		var ident = p[5].length > 0 ? p[5] : "anonymous";
		if (p[3] != 0) ident += " (" + idents[p[3]] + ")";
		e.append("&nbsp;<span class=\"postident\">" +  ident + "</span>");
		if (!(pstat & 1) || (pstat & 8)) {
			e.append("&nbsp;<span class=\"poststatus\">(" + pstatstr + ")</span>");
		}
		if (lid && lid == p[3] || Comment.is_admin(lid)) {
			var lnk = $(document.createElement("a"));
			lnk.attr("href", "#");
			lnk.html("del");
			lnk.click(function () {
				var id = $(this).parent().parent().attr("id").substr(3);
				self._cbs.del_comment(self._id, id);
			});
			e.append("&nbsp;");
			e.append(lnk);
		}
		if (!(pstat & 8) && Comment.is_admin(lid)) {
			if ((pstat & 4)) { 
				var lnk = $(document.createElement("a"));
				lnk.attr("href", "#");
				lnk.html("accept");
				e.append("&nbsp;");
				e.append(lnk);
				lnk.click(function () {
					var id = $(this).parent().parent().attr("id").substr(3);
					self._cbs.change_comment_flags(self._id, id, 1, (2|4));
				});
				
				var lnk = $(document.createElement("a"));
				lnk.click(function () {
					var id = $(this).parent().parent().attr("id").substr(3);
					self._cbs.change_comment_flags(self._id, id, 2, (1|4));
				});
				lnk.attr("href", "#");
				lnk.html("reject");
				e.append("&nbsp;");
				e.append(lnk);
			}
		}

		var e = $(document.createElement("div"));
		ep.append(e);
		e.addClass("postcontent");
		e.html(p[2]);
		if (nsposts > visible)
			ep.css("display", "none");
		div.append(ep);
	}
	
	var e = $(document.createElement("div"));
	div.append(e);
	if (nsposts > visible) {
		var lnk = $(document.createElement("a"));
		var moretxt = (nsposts-visible) + " more";
		lnk.html(moretxt).attr("href", "#");
		e.append(lnk);
		lnk.click(function() {
			var lnk = $(this);
			var pdivs = $(".post", div).slice(visible);
			var t = lnk.html();	
			if (t == moretxt) {
				$(pdivs).show();
				lnk.html("hide");
			}
			else {
				$(pdivs).hide();
				lnk.html(moretxt);
			}
			return false;
		});
	}
	if (lid) {
		if (e.html().length > 0) 
			e.append("<span>&nbsp;/&nbsp;</span>");
		e.append(t = $(document.createElement("a")));
		t.attr("href", "#");
		t.html("new comment");
		t.click(function () {
			var t = $("#" + self._id + "_ca");
			if (t.css("display") == "none") {
				t.show("slow");
			}
			else { 
				t.hide("slow");
			}
			return false;
		});
	}
	this._nsposts = nsposts;
}
	
Comment.prototype.update = function (posts) {
	this._posts = posts;
}
