var msie = navigator.appName.indexOf("Microsoft") > -1;

function Throw(msg) {
	alert(msg);
	throw msg;
}

function theForm(name) {
	if (document.forms.length < 1)
		Throw("<FORM> element not found.");
	return name ? document.forms[name] : document.forms[0];
}

function exists(name) {
	var comps = document.getElementsByName(name);
	return comps != null && comps.length > 0;
}

function elms(name) {
	var comps = document.getElementsByName(name);
	if (comps.length == 0)
		Throw("Element not found: " + name);
	return comps;
}

function elm(name) {
	var comps = document.getElementsByName(name);
	if (comps.length == 0) {
		var comp = document.getElementById(name);
		if (!comp) Throw("Element not found: " + name);
		return comp;
	}
	if (comps.length > 1)
		Throw("Duplicate elements: " + name);
	return comps[0];
}

function trim(str) {
	if (typeof(str) != "string")
		return str;
		
	while (str.length > 0 && str.charAt(0) == ' ')
		str = str.substr(1);
	while (str.length > 0 && str.charAt(str.length - 1) == ' ')
		str = str.substr(0, str.length - 1);
	return str;
}

function isEmpty(value) {
	if (value == null || value == undefined || 
		value == "undefined" || value == "null") return true;
	switch (typeof(value)) {
	case "boolean": if (false == value) return false;
	case "number": if (0 == value) return false;
	default: return "" == trim(value);
	}
}

function ifEmpty(value, nval) {
	return isEmpty(value) ? nval : value;
}

function elementEmpty(input, msg) {
	if (!isEmpty(input.value)) return false;
	
	alert(msg);
	input.focus();
	return true;
}

function isNumber(value) {
	return !isNaN(value);
}

function parseNumber(value) {
	if (isNumber(value)) return value;
	var length = value.length,
		string = value.charAt(0),
		number = string == "-" ? string : isNumber(string) ? string : "";
	for (var i = 1; i < length; ++i) {
		string = value.charAt(i);
		number += isNumber(string) ? string : "";
	}
	return number;
}

function uncomma(value) {
	return isEmpty(value) ? value : value.replace(/,/g, '');
}

function comma(value) {
	var minus = parseFloat(value) < 0,
		text = minus ? "" + -value : "" + value,
		length = text.length;
	if (length <= 3) return value;

	var mod = length % 3,
		count = Math.floor(length / 3),
		formatted = mod > 0 ? (text.substring(0, mod)) : "";
	for (var i = 0; i < count; ++i) {
		var txt = text.substring(mod + 3 * i, mod + 3 * i + 3);
		formatted += (mod == 0) && (i == 0) ? txt : "," + txt;
	}
	return minus ? "-" + formatted : formatted;
}

function NumberFormat() {}

NumberFormat.isValid = function(v) {
	var value = uncomma(v),
		valid = isNumber(value);
	if (!valid) alert(valueMsg(invalidNumber, v));
	return valid;
}

NumberFormat.format = function(value) {
	if (isEmpty(value)) return value;
	var number = parseNumber(value).toString(),
		floatIndex = number.indexOf('.'),
		head = floatIndex < 0 ? number : number.substring(0, floatIndex),
		tail = floatIndex < 0 ? '' : number.substring(floatIndex, number.length);
	return comma(head) + tail;
}

function SimpleDateFormat() {}

SimpleDateFormat.isValid = function(value) {
	if (isEmpty(value)) return true;
	var number = parseNumber(value),
		valid = number >= 0 && number.length == 8;
	if (valid) valid = valid && Year.isValid(number) && Month.isValid(number) && Day.isValid(number);
	if (!valid) alert(valueMsg(invalidDate, value));
	return valid;
}

SimpleDateFormat.format = function(value) {
	if (isEmpty(value)) return value;
	var number = parseNumber(value).toString();
	return Year.value(number) + "-" + Month.value(number) + "-" + Day.value(number);
}

function Year() {}

Year.value = function(v) {
	return v.substring(0, 4);
}

Year.isValid = function(v) {
	return Year.value(v) >= 0;
}

Year.isLeaping = function(value) {
	var year = Year.value(value);
	return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}

function Month() {}
Month["01"] = 31;
Month["02"] = 28;
Month["03"] = 31;
Month["04"] = 30;
Month["05"] = 31;
Month["06"] = 30;
Month["07"] = 31;
Month["08"] = 31;
Month["09"] = 30;
Month["10"] = 31;
Month["11"] = 30;
Month["12"] = 31;

Month.value = function(v) {
	return v.substring(4, 6);
}

Month.isValid = function(value) {
	var month = Month.value(value);
	return month > 0 && month < 13;
}

Month.lastDay = function(year, month) {
	var lastDay = Month[month];
	if (month == "02" && Year.isLeaping(year)) ++lastDay;
	return lastDay;
}

function Day() {}

Day.value = function(v) {
	return value.substring(6, 8);
}

Day.isValid = function(value) {
	var year = Year.value(value),
		month = Month.value(value),
		day = Day.value(value),
		lastDay = Month.lastDay(year, month);
	return day > 0 && day <= lastDay;
}

function NameValue(name, value) {
	this.name = name;
	this.value = value;
}

function isNull(nameValue) {
	var name = nameValue.name,
		inputs = nameValue.value,
		count = inputs == null ? 0 : inputs.length;
	for (var i = 0; i < count; ++i) {
		var input = inputs[i],
			value = input.value;
		if (isEmpty(value)) {
			alert(fieldMsg(notNull, name));
			if ("hidden" != input.type)
				input.focus();
			return true;
		}
	}
	return false;
}

function hasNull(nameValues) {
	var count = nameValues == null ? 0 : nameValues.length;
	if (count == 0) return false;

	for (var i = 0; i < count; ++i)
		if (isNull(nameValues[i])) return true;

	return false;
}

function checkAll(checkboxes, checked) {
	if (!checkboxes) return;
	if (!checkboxes.length) {
		checkboxes.checked = checked;
		return;
	}

	var count = checkboxes.length;
	for (var i = 0; i < count; ++i)
		checkboxes[i].checked = checked;
}

function checkedValues(checkboxes) {
	if (!checkboxes) return null;
	if (!checkboxes.length)
		return checkboxes.checked ? checkboxes.value : "";

	var count = checkboxes.length,
		s = "";
	for (var i = 0; i < count; ++i) {
		var checkbox = checkboxes[i];
		if (checkbox.checked) {
			s += checkbox.value + ",";
		}
	}
	return s.substring(0, s.length - 1);
}

function selectedValues(select) {
	var index = select.selectedIndex;
	if (index < 0) return "";
	
	if (!select.multiple) {
		return select.options[index].value;
	}
	var count = select.options.length,
		result = "";
	for (var i = index; i < count; ++i) {
		var op = select.options[i];
		if (op.selected) {
			result += (result != "" ? "," : "") + op.value;
		}
	}
	return result;
}

function fileSize(path) {
	return 1024;
/*
	var img = new Image();
	img.dynsrc = path;
	return img.fileSize;
*/
}

function toQuery(map) {
	if (!map || map.length < 1) return null;

	var query = [];
	for (var key in map) {
		var value = map[key],
			type = typeof(value);
		if ("object" == type || "function" == type) continue;
		if (isEmpty(value))
			value = "";
		query[query.length] = key + "=" + encodeURIComponent(value);
	}
	return query.join("&");
}


/* Messages for invalid value */
var invalidNumber = "field_value is not a valid number.",
	invalidDate = "field_value is not a valid date.",
	notNull = "field_name cannot be empty.";

function valueMsg(msg, s) {
	return msg.replace(/field_value/g, s);
}

function fieldMsg(msg, s) {
	return msg.replace(/field_name/g, s);
}

var ajax = {};
ajax.create = function() {
	var req = null;
	try {
		req = new XMLHttpRequest();
	} catch (e) {
		try {
			req = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
			try {
				req = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (e) {
			}
		}
	}
	if (!req)
		Throw("Failed to create an AJAX request.");
	return req;
};
ajax.setPost = function(req, charset) {
	if (isEmpty(charset)) charset = "utf-8";
	req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=" + charset + ";");
	return req;
};
ajax.response = function(req, callback) {
	if (!callback)
		callback = function() {
			if (req.readystate != 4) return;
			try {
				if (req.status != 200) return;
				eval(req.responseText);
			} catch (e) {
				Throw(e.description + "\n" + req.responseText);
			}
		};
	req.onreadystatechange = callback;
	return req;
};
ajax.request = function(info) {//info properties: method, url, data, charset, async, callback
	if ("string" == typeof(info)) {
		var tmp = {};
		tmp.url = info;
		info = tmp;
	}
	var method = ifEmpty(info.method, "GET"),
		post = "POST" == method,
		url = info.url,
		async = true == info.async,
		req = ajax.create();
	req.open(method, url, async);
	if (post)
		ajax.setPost(req, info.charset);
	if (async)
		ajax.response(req, info.callback);
	req.send(!post ? null : info.data);
	return req;
}

function DataSet(name, _records) {
	var dataSet = {};
	dataSet.name = name;
	dataSet.recordCount = 0;
	dataSet.allCount = 0;
	dataSet.records = null;
	dataSet.start = -1;
	dataSet.end = -1;
	if (_records) {
		dataSet.records = _records.records;
		dataSet.recordCount = dataSet.records ? _records.recordCount : 0;
		dataSet.allCount = dataSet.records ? _records.allCount : 0;
		dataSet.start = dataSet.records ? _records.start : -1;
		dataSet.end = dataSet.records ? _records.end : -1;
/*		dataSet.recordCount = _records.recordCount ? _records.recordCount : _records.length;
		dataSet.allCount = _records.allCount ? _records.allCount : _records.length;
		dataSet.records = _records.records ? _records.records : _records;
		dataSet.start = _records.start ? _records.start : 0;
		dataSet.end = _records.end ? _records.end : _records.length - 1;
*/
	}
	dataSet.recordAt = function(index) {
		return dataSet.records[index];
	};
	dataSet.getValueAt = function(recordIndex, fieldName) {
		return dataSet.records[recordIndex][fieldName];
	};
	dataSet.getValue = function(fieldName) {
		return dataSet.getValueAt(0, fieldName);
	};
	dataSet.setValueAt = function(recordIndex, fieldName, value) {
		dataSet.records[recordIndex][fieldName] = value;
	};
	dataSet.setValue = function(fieldName, value) {
		dataSet.setValueAt(0, fieldName, value);
	};
	dataSet.toParams = function() {
		var params = "";
		for (var i = 0; i < this.recordCount; ++i)
			for (var j in dataSet.records[i]) {
				if (j == "__ID__") continue;
				params += (params == "" ? dataSet.name + j : "&" + dataSet.name + j)
					   + "=" + encodeURIComponent(dataSet.records[i][j]);
			}
		return params;
	}
	return dataSet;
};

var SWF = {};
if (msie)
SWF.tag = "<OBJECT id=\"<ID>\" classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" style=\"display:block;<STYLE>\" \n"
	+ "codebase=\"http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0\" width=\"<WIDTH>\" height=\"<HEIGHT>\" align=\"<ALIGN>\">\n"
	+ "<PARAM name=\"allowScriptAccess\" value=\"always\"/>\n"
	+ "<PARAM name=\"allowNetworking\" value=\"all\"/>\n"
	+ "<PARAM name=\"salign\" value=\"l\"/>\n"
	+ "<PARAM name=\"movie\" value=\"<MOVIE>\"/>\n"
	+ "<PARAM name=\"flashVars\" value=\"<PARAMS>\"/>\n"
	+ "<PARAM name=\"quality\" value=\"high\"/>\n"
	+ "<PARAM name=\"scale\" value=\"showAll\"/>\n"
	+ "<PARAM name=\"wmode\" value=\"<WMODE>\"/>\n"
	+ "<PARAM name=\"bgcolor\" value=\"<BGCOLOR>\"/>\n"
	+ "<EMBED id=\"<ID>\" src=\"<MOVIE>\" quality=\"high\" salign=\"l\" bgcolor=\"<BGCOLOR>\" wmode=\"<WMODE>\" width=\"<WIDTH>\" height=\"<HEIGHT>\" name=\"<ID>\" \n"
	+ "flashVars=\"<PARAMS>\" align=\"<ALIGN>\" allowScriptAccess=\"always\" allowNetworking=\"all\" type=\"application/x-shockwave-flash\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" style=\"<STYLE>\"/>\n"
	+ "</OBJECT>";
else
SWF.tag = "<EMBED id=\"<ID>\" src=\"<MOVIE>\" quality=\"high\" salign=\"l\" bgcolor=\"<BGCOLOR>\" wmode=\"<WMODE>\" width=\"<WIDTH>\" height=\"<HEIGHT>\" name=\"<ID>\" \n"
  + "flashVars=\"<PARAMS>\" align=\"<ALIGN>\" allowScriptAccess=\"always\" allowNetworking=\"all\" type=\"application/x-shockwave-flash\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" style=\"<STYLE>\"/>\n";

SWF.create = function(cfg) {//cfg properties: id, movie, width, height, wmode, align, bgcolor, style, visible, params
	var id = cfg.id;
	if (isEmpty(id)) Throw("id is empty.");
	
	var movie = cfg.movie,
		width = ifEmpty(cfg.width, "100"),
		height = ifEmpty(cfg.height, "100"),
		wmode = cfg.wmode;
	var	str = SWF.tag.replace(/<ID>/g, id).replace(/<MOVIE>/g, movie).replace(/<WIDTH>/g, width ? width : "").replace(/<HEIGHT>/g, height ? height : "").replace(/<WMODE>/g, wmode ? wmode : "window"),
		style = cfg.style;
	if (!style) style = "";
	
	var visible = cfg.visible;
	if (visible == false) style += ";display:none";
	
	var align = cfg.align,
		bgcolor = cfg.bgcolor,
		params = ifEmpty(cfg.params, "");
		
	var	tag = str.replace(/<ALIGN>/g, align ? align : "").replace(/<BGCOLOR>/g, bgcolor ? bgcolor : "").replace(/<STYLE>/g, style ? style : "").replace(/<PARAMS>/g, params);
	document.write(tag);
}

SWF.get = function(id) {
	var swf = window[id] || document[id];
	if (!swf)
		Throw("SWF not found: " + id);
	return swf;
};

var dataName = null;

function delm(name) {
	var e = theForm()[name];
	if (!e) {
		try {
			e = document.createElement("<INPUT type=\"hidden\" name=\"" + name + "\">");
		} catch (ex) {
			e = document.createElement("INPUT");
			e.type = "hidden";
			e.name = name;
		}
		theForm().appendChild(e);
	}
	return e;
}

function assertNotNull(obj, name) {
	if (isEmpty(obj))
		throwException(name + ": null or empty");
	return obj;
}

function contains(s, p) {
	return s.indexOf(p) > -1;
}

function hasValue(s, p) {
	if (isEmpty(s)) return false;

	var sa = s.split(","),
		length = sa.length;
	for (var i = 0; i < length; ++i)
		if (p == sa[i]) return true;

	return false;
}

function fieldName(name) {
	return dataName + name;
}

function field(name) {
	return delm(fieldName(name));
}

function fields(name) {
	return elms(fieldName(name));
}

function setHandler(handler) {
//	delm("ah").value = handler;
	theForm().action = handler;
}

function setActionType(actionType) {
	delm("at").value = actionType;
}

function contentType() {
	return delm("ct").value;
}

function setContentType(contentType) {
	delm("ct").value = contentType;
}

function contentID() {
	return delm("ci").value;
}

function setContentID(contentID) {
	delm("ci").value = contentID;
}

function setPost(request) {
	request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8');
	return request;
}

function ActionInfo() {
	this.count = 0;
	this.activeX = null;

	this.put = function(name, value) {
		this[name] = value;
		this[this.count++] = name;
		return this;
	}
	
	this.get = function(name) {
		return this[name];
	}
	
	this.clear = function() {
		for (var i = 0; i < this.count; ++i) {
			var name = this[i];
			this[i] = this[name] = null;
		}
		this.count = 0;
	}
	
	this.toParams = function() {
		if (this.count < 1) return null;
		var params = [];
		for (var i = 0; i < this.count; ++i) {
			var name = this[i],
				value = this[name];
			if (isEmpty(value))
				value = "";
			params[params.length] = name + "=" + encodeURIComponent(value);
		}
		return params.join("&");
	}
	
	this.client = function() {
		if (!this.activeX)
			this.activeX = new ActiveXObject("Hiverion.ActionInfo");
		return this.activeX;
	}
	
	this.clientValue = function(name) {
		return this.client().ClientValue(name);
	}
	
	this.newRequest = function() {
		return this.client().Request();
	}
	
	this.callClient = function() {
		for (var i = 0; i < this.count; ++i) {
			var name = this[i],
				value = this[name];
			if (isEmpty(value))
				value = "";
			this.client().put(name, value);
		}
		this.client().callClient();
	}
}

function request(actionType) {
	if (actionType)
		setActionType(actionType);
	if (theForm().method.match(/GET/i)) {
		var els = theForm().getElementsByTagName("TEXTAREA");
		for(var i = 0; i < els.length; i++)
			els[i].disabled = true;
		els = theForm().getElementsByTagName("INPUT");
		for(var i = 0; i < els.length; i++)
			if (els[i].type == "file")
				els[i].disabled = true;
	}
	theForm().submit();
}

function postRequest(actionType) {
	theForm().method = "POST";
	request(actionType);
}

function multipartRequest(actionType) {
	theForm().encoding = "multipart/form-data";
	postRequest(actionType);
}

var mtag = "<EMBED src=\"<PATH>\" width=\"<WIDTH>\" height=\"<HEIGHT>\" autostart=\"<START>\" autosize=\"0\" autoresize=\"0\" enablecontextmenu=\"0\" volume=\"-500\" animationatstart=\"0\" transparentatstart=\"1\"<ETC>></EMBED>";
function media(url, width, height, start, etc) {
	if (!width) width = 500;
	if (!height) height = 400;
	if (!start) start = 0;
	if (!etc) etc = "";
	var tag = mtag.replace(/<PATH>/g, url).replace(/<WIDTH>/g, width).replace(/<HEIGHT>/g, height).replace(/<START>/g, start).replace(/<ETC>/g, etc);
	document.write(tag);
}

var ftag = '<EMBED src=\"<PATH>\" width=\"<WIDTH>\" height=\"<HEIGHT>\" type=application/x-shockwave-flash<ETC>></EMBED>';
function flash(url, width, height, etc) {
	if (!width) width = 500;
	if (!height) height = 400;
	if (!etc) etc = "";
	var tag = ftag.replace(/<PATH>/g, url).replace(/<WIDTH>/g, width).replace(/<HEIGHT>/g, height).replace(/<ETC>/g, etc);
	document.write(tag);
}

function include(url) {
	delm("include").value = url;
}

function Kookie(path, expires) {
	this.path = path;
	this.expires = expires;
	
	this.set = function(name, value) {
		var s = name + "=" + escape(value);
		if (this.expires) s += "; expires=" + this.expires;
		if (this.path) s += "; path=" + this.path;
		document.cookie = s;
		return this;
	}
	
	this.get = function(name) {
		var cookieName = name + "=",
			x = 0; 
	
		while (x <= document.cookie.length) {
			var y = (x + cookieName.length);
	
			if (document.cookie.substring(x, y) == cookieName) {
				if ((endOfCookie=document.cookie.indexOf(";", y)) == -1)
				endOfCookie = document.cookie.length;
				return unescape( document.cookie.substring( y, endOfCookie ) );
			}
			x = document.cookie.indexOf( " ", x ) + 1;
			if (x == 0)
			break;
		}
		return ""; 
	}
}

function hasAttachments() {
	if (!exists("fpath")) return false;
	var files = elms("fpath");
	for (var i = 0; i < files.length; ++i) {
		if (!isEmpty(files[i].value)) return true;
	}
	return false;
}

function HiveHandler() {
	this.ah;
	this.full;
	this.siteID;
	this.range;
	this.uri;
	this.actionInfo = null;
	
	this.getName = function() {
		return this.ah;
	}
	
	this.params = function(full, wsID) {
		this.full = full;
		this.siteID = wsID;
		this.actionInfo = new ActionInfo();
		this.set("ct", delm("ct").value);
		this.set("ci", delm("ci").value);
		return this;
	}
	
	this.set = function(name, value) {
		if (isEmpty(value)) return this;
		
		if (this.get(name) != value) {
			if (this.actionInfo) this.actionInfo.put(name, value);
			else delm(name).value = value;
		}
		return this;
	}
	
	this.bounds = function(name, start, end) {
		if (!this.actionInfo) {
			delm(name + "Start").value = start;
			delm(name + "End").value = end;
		} else {
			if (!this.range) this.range = {};
			this.range[name] = [start, end];
		}
		return this;
	}
	
	this.dest = function(dest) {
		if (this.actionInfo) this.uri = dest;
		else delm("dest").value = dest;
		return this;
	}
	
	this.get = function(name) {
		return this.actionInfo ? this.actionInfo.get(name) : delm(name).value;
	}
	
	this.toURL = function(wsID) {
		if (isEmpty(wsID))
			wsID = siteID();
		return thisCtx + "/" + wsID + "/" + this.ah;
	}
	
	this.getParams = function() {
		var params = this.actionInfo.toParams();
		if (this.full)
			params = this.toURL(this.siteID) + "?" + params;
		if (this.range) {
			for (var name in this.range) {
				var range = this.range[name],
					start = range[0],
					end = range[1];
				params += "&" + name + "Start=" + start + "&" + name + "End=" + end;
			}
		}
		if (this.uri)
			params += "&dest=" + encodeURIComponent(this.uri);
		this.actionInfo.clear();
		this.range = this.actionInfo = null;
		this.full = this.siteID = this.uri = null;
		return params;
	}
	
	this.request = function(actionType) {
		if (this.actionInfo)
			return this.getParams();
		setHandler(this.toURL());//setHandler(this.ah);
		request(actionType);
	}
	
	this.postRequest = function(actionType) {
		if (this.actionInfo)
			return this.getParams();
		setHandler(this.toURL());
		postRequest(actionType);
	}
	
	this.multipartRequest = function(actionType) {
		if (this.actionInfo)
			return this.getParams();
		setHandler(this.toURL());
		multipartRequest(actionType);
	}
	
	this.setSourceSite = function(srcSite) {
		if (srcSite == siteID()) return;
		this.set("srcSite", srcSite);
	}
}

function UserHandler() {
	this.ah = "user";

	this.search = function(fieldName, fieldValue, status, order) {
		this.set("at", "srch");
		this.set("fname", fieldName);
		this.set("fvalue", fieldValue);
		this.set("status", status);
		this.set("order", order);
		return this.request();
	}

	this.getInfo = function(userID) {
		this.set("at", "get");
		this.set("ids", userID);
		assertNotNull(this.get("ids"), "userID");
		return this.request();
	}
	
	this.newInfo = function() {
		this.set("at", "new");
		return this.request();
	}

	this.view = function(userID) {
		this.set("at", "view");
		this.set("ids", userID);
		assertNotNull(this.get("ids"), "userID");
		return this.request();
	}

	this.isIDUsable = function(newID) {
		this.set("at", "usable");
		this.set("newID", newID);
		assertNotNull(this.get("newID"), "newID");
			
		return this.request();
	}
	
	this.isUsable = function(userID, fieldName, fieldValue) {
		this.set("at", "usable");
		this.set("userID", userID);
		this.set("fname", fieldName);
		this.set("fvalue", fieldValue);
			
		return this.request();
	}
	
	this.isRegistered = function(userID, regNum) {
		this.set("at", "registered");
		this.set("userID", userID);
		this.set("regNum", regNum);
		assertNotNull(this.get("regNum"), "regNum");

		return this.request();
	}
	
	this.getAge = function(date) {
		this.set("at", "getAge");
		this.set("date", date);
		assertNotNull(this.get("date"), "date");

		return this.request();
	}

	this.save = function(op) {
		if (op != "crt" && op != "upd")
			throwException("Invalid op: " + save);
		if (op == "crt") {
			var userID = document.getElementById("userRecUSER_ID").value
			if (!UserID.isValid(userID)) return;
		}
		this.set("at", op);
		if (hasAttachments()) return this.multipartRequest();
		else return this.postRequest();
	}

	this.join = function() {
		this.set("at", "join");
		return this.postRequest();
	}
	
	this.setPassword = function(userID, password) {
		this.set("at", "chgPwd");
		this.set("ids", userID);
		this.set("pwd", password);
		return this.postRequest();
	}
	
	this.findIDPw = function(find, fieldValue, email) {
		this.set("at", "findIDPW");
		this.set("fname", find);
		assertNotNull(this.get("fname"), "find");
		this.set("fvalue", fieldValue);
		assertNotNull(this.get("fvalue"), "fieldValue");
		this.set("email", email);
		assertNotNull(this.get("email"), "email");
		return this.request();
	}
	
	this.setStatus = function(userIDs, status) {
		this.set("at", "chgStatus");
		this.set("ids", userIDs);
		this.set("status", status);
		return this.postRequest();
	}
	
	this.quit = function(userIDs) {
		this.set("at", "quit");
		this.set("ids", userIDs);
		return this.postRequest();
	}
}
UserHandler.prototype = new HiveHandler;

var userHandler = new UserHandler();

function UserID() {}

UserID.isValid = function(v) {
	return v && !v.match("[^0-9a-zA-Z\\-_]");
/*	var valid = v && !v.match("[^0-9a-zA-Z\\-_]");
	if (!valid)
		alert(VALID_USER_ID);
	return valid;*/
}

UserID.format = function(value) {
	if (isEmpty(value)) return value;
	value = trim(value);
	if (!UserID.isValid(value))
		return "__false";
	return value;
}

function isUserIDUsable(v, path) {
	var valid = UserID.isValid(v);
	if (valid) {
		var req = ajaxRequest("GET", userHandler.params(true).dest(path).isIDUsable(v));
		req.send(null);
		eval(req.responseText);
	}
	return valid;
}

function isEmailRegistered(v, path) {
	var valid = validateEmail(v);
	if (valid) {
		var req = ajaxRequest("GET", userHandler.params(true).dest(path).isRegistered(v));
		req.send(null);
		eval(req.responseText);
	}
	return valid;
}

function JuminNumber() {}

JuminNumber.isValid = function(v) {
	var a = v.charAt(0),
		b = v.charAt(1),
		c = v.charAt(2),
		d = v.charAt(3),
		e = v.charAt(4),
		f = v.charAt(5),
		g = v.charAt(6),
		h = v.charAt(7),
		i = v.charAt(8),
		j = v.charAt(9),
		k = v.charAt(10),
		l = v.charAt(11),
		sub = v.charAt(12),
		sum = a*2 + b*3 + c*4 + d*5+ e*6 + f*7 + g*8 + h*9 + i*2 + j*3 + k*4 + l*5,
		n = sum % 11,
		mod = 11 - n,
		val = mod % 10;
	var valid = sub == val;
	if (!valid) alert("Àß¸øµÈ ÁÖ¹Îµî·Ï¹øÈ£ ÀÔ´Ï´Ù.");
	return valid;
}

JuminNumber.format = function(value) {
	if (isEmpty(value)) return value;
	value = trim(value);
	value = value.replace(/-/g, '');
	if (!JuminNumber_isValid(value))
		return "__false";
	return value.substring(0, 6) + "-" + value.substring(6, 13);
}

function validateEmail(address) {
   var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
   return reg.test(address);
}

function WebsiteHandler() {
	this.ah = "website";

	this.search = function(siteID, fieldName, fieldValue, status, order) {
		this.set("at", "srch");
		this.set("si", siteID);
		this.set("fname", fieldName);
		this.set("fvalue", fieldValue);
		this.set("status", status);
		this.set("order", order);
		return this.request();
	}
	
	this.getInfo = function(siteID) {
		this.set("at", "get");
		this.set("ids", siteID);
		assertNotNull(this.get("ids"), "siteID");
		return this.request();
	}
	
	this.newInfo = function(siteID) {
		this.set("at", "new");
		this.set("siteID", siteID);
		return this.request();
	}
	
	this.isDomainUsable = function(domain) {
		this.set("at", "usable");
		this.set("dom", newID);
		return this.postRequest();
	}
	
	this.save = function(op) {
		if (op != "crt" && op != "upd")
			throwException("Invalid save: " + save);
		this.set("at", op);
		return this.postRequest();
	}
	
	this.init = function(siteID) {
		this.set("at", "init");
		this.set("si", siteID);
		return this.postRequest();
	}
	
	this.setFields = function(fieldNames, fieldValues) {
		this.set("at", "setField");
		this.set("fname", fieldNames);
		assertNotNull(this.get("fname"), "fieldNames");
		this.set("fvalue", fieldValues);
		return this.postRequest();
	}
	
	this.setStatus = function(siteIDs, status) {
		this.set("at", "status");
		this.set("ids", siteIDs);
		this.set("status", status);
		return this.postRequest();
	}
	
	this.setPageGroup = function(siteID, groupID) {
		this.set("at", "setPgGrp");
		this.set("si", siteID);
		this.set("grpID", groupID);
		this.set("dest", redir);
		return this.postRequest();
	}
	
	this.goTo = function(fieldName, fieldValue) {
		this.set("at", "goTo");
		this.set("fname", fieldName);
		this.set("fvalue", fieldValue);
		return this.request();
	}
	
	this.initConstants = function() {
		this.set("at", "constCtx");
		return this.request();
	}
}
WebsiteHandler.prototype = new HiveHandler;

var websiteHandler = new WebsiteHandler();

function Domain() {}

Domain.isValid = function(v) {
	var valid = !v.match("[^0-9a-zA-Z\\-_]");
	if (!valid) alert("Invalid value for a domain name");
	return valid;
}

Domain.format = function(value) {
	if (isEmpty(value)) return value;
	value = trim(value);
	if (!Domain.isValid(value))
		return "__false";
	return value;
}

function AccessHandler() {
	this.ah = "access";

	this.searchUsers = function(groupID, fieldName, fieldValue) {
		this.set("at", "srchUsers");
		this.set("grpID", groupID);
		this.set("fname", fieldName);
		this.set("fvalue", fieldValue);
		return this.request();
	}

	this.getSiteUser = function(groupID, userID) {
		this.set("at", "getUser");
		this.set("grpID", groupID);
		assertNotNull(this.get("grpID"), "groupID");
		this.set("userID", userID);
		assertNotNull(this.get("userID"), "userID");
		return this.request();
	}

	this.addUser = function(groupID, userID, status) {
		this.set("at", "addUser");
		this.set("grpID", groupID);
		assertNotNull(this.get("grpID"), "groupID");
		this.set("userID", userID);
		assertNotNull(this.get("userID"), "userID");
		this.set("status", status);
		return this.postRequest();
	}

	this.saveSiteUser = function(groupID, userID) {
		this.set("at", "updUser");
		this.set("grpID", groupID);
		assertNotNull(this.get("grpID"), "groupID");
		this.set("userID", userID);
		assertNotNull(this.get("userID"), "userID");
		return this.postRequest();
	}
	this.setUserGroup = function(userIDs, groupID) {
		this.set("at", "setGrp");
		this.set("ids", userIDs);
		assertNotNull(this.get("ids"), "userIDs");
		this.set("grpID", groupID);
		if (isEmpty(this.get("grpID")))
			return alert(NO_USER_GRPS), null;
		return this.postRequest();
	}

	this.setUserStatus = function(groupID, userIDs, status) {
		this.set("at", "setStatus");
		this.set("grpID", groupID);
		this.set("ids", userIDs);
		assertNotNull(this.get("ids"), "userIDs");
		
		this.set("status", status);
		assertNotNull(this.get("status"), "status");
		return this.postRequest();
	}

	this.deleteSiteUsers = function(userIDs) {
		if (!confirm(CNFM_DEL_SITE_USERS)) return null;
		this.set("at", "delUsers");
		this.set("ids", userIDs);
		assertNotNull(this.get("ids"), "userIDs");
		return this.postRequest();
	}

	this.searchGroups = function(fieldName, fieldValue, order) {
		this.set("at", "srchGrps");
		this.set("fname", fieldName);
		this.set("fvalue", fieldValue);
		this.set("order", order);
		return this.request();
	}

	this.getGroupInfo = function(groupID) {
		this.set("at", "getGrp");
		this.set("grpID", groupID);
		assertNotNull(this.get("grpID"), "groupID");
		return this.request();
	}

	this.newGroupInfo = function() {
		this.set("at", "newGrp");
		return this.request();
	}

	this.saveGroupInfo = function(op, groupID) {
		this.set("at", op);
		this.set("grpID", groupID);
		return this.postRequest();
	}
	
	this.deleteGroups = function(groupIDs) {
		if (!confirm(CNFM_DEL_USER_GRPS))
			return null;
		this.set("at", "delGrps");
		this.set("ids", groupIDs);
		assertNotNull(this.get("ids"), "groupIDs");
		return this.postRequest();
	}

	this.login = function(userID, password) {
		this.set("at", "logIn");
		this.set("userID", userID);
		if (isEmpty(this.get("userID")))
			return alert(NO_USER_ID), null;
		this.set("pwd", password);
		if (isEmpty(this.get("pwd")))
			return alert(NO_PASSWORD), null;
		return this.postRequest();
	}

	this.logout = function() {
		this.set("at", "logOut");
		return this.postRequest();
	}
}
AccessHandler.prototype = new HiveHandler;

var accessHandler = new AccessHandler();

function MemberHandler() {
	this.ah = "member";
	
	this.searchRequests = function(userID, reqType) {
		this.set("at", "srchReq");
		this.set("userID", userID);
		this.set("reqType", reqType);
		assertNotNull(this.get("userID"), "userID");
		return this.request();
	}
	
	this.isMember = function(serder, receivers) {
		this.set("at", "isMember");
		this.set("userID", sender);
		this.set("ids", receivers);
		return this.request();
	}
	
	this.requestMember = function(sender, receivers, comment) {
		this.set("at", "req");
		this.set("userID", sender);
		this.set("ids", receivers);
		this.set("cmt", comment);
		return this.postRequest();
	}
	
	this.updateRequest = function(sender, receiver, sndCmt, rcvCmt) {
		this.set("at", "upd");
		this.set("sender", sender);
		this.set("receiver", receiver);
		this.set("sndCmt", sndCmt);
		this.set("rcvCmt", rcvCmt);
		return this.postRequest();
	}
	
	this.accept = function(receiver, senders) {
		this.set("at", "accept");
		this.set("userID", receiver);
		this.set("ids", senders);
		return this.postRequest();
	}
	
	this.reject = function(receiver, senders) {
		this.set("at", "reject");
		this.set("userID", receiver);
		this.set("ids", senders);
		return this.postRequest();
	}
	
	this.save = function(userID, accept, decline) {
		this.set("at", "save");
		this.set("userID", userID);
		this.set("accept", accept);
		this.set("decline", decline);
		return this.postRequest();
	}
	
	this.remove = function(receiver, senders) {
		this.set("at", "del");
		this.set("userID", receiver);
		this.set("ids", senders);
		return this.postRequest();
	}
}
MemberHandler.prototype = new HiveHandler;

var memberHandler = new MemberHandler();

var MB = 1024 * 1024,
	inMB = 4,
	maxSize = MB * inMB,
	ext = "com,exe,dll,jar,bmp";

function getExt(fileName) {
	var index = fileName.lastIndexOf(".");
	return index < 0 ? "__false" : fileName.substring(index + 1, fileName.length).toLowerCase();
}

function fileSelected(fileIDs) {
	if (isEmpty(IDs())) {
		alert(NO_FILES);
		return false;
	}
	return true;	
}

function fileToShortcut(contentType) {
	if ("999" == contentType) {
		alert(NO_FILES_TO_SHORTCUT);
		return true;
	}
	return false;
}

function uploadable(fileName) {
	if (isEmpty(fileName)) {
		alert(NO_FILES);
		return false;
	}
	if (contains(ext, getExt(fileName))) {
		alert(BAD_UPLOADS);
		return false;
	}
	if (fileSize(fileName) > maxSize) {
		alert(inMB + FILES_TOO_BIG);
		return false;
	}
	return true;
}

function newUpload(upload, tmpl) {
	var value;
	if (tmpl) {
		var div = document.getElementById(tmpl);
		value = div.outerHTML.replace("none","inline");
	}
	if (!value) value = "<INPUT type=\"file\" name=\"fpath\">";
	if (!upload) upload = "uploads";
	
	document.getElementById(upload).innerHTML = document.getElementById(upload).outerHTML + value;
}

function FileHandler() {
	this.ah = "file";

	this.search = function(contentType, contentID, fieldName, fieldValue, order) {
		this.set("at", "srch");
		this.set("ct", contentType);
		this.set("ci", contentID);
		this.set("fname", fieldName);
		this.set("fvalue", fieldValue);
		this.set("order", order);
		return this.request();
	}

	this.getInfo = function(fileID) {
		this.set("at", "get");
		this.set("ids", fileID);
		assertNotNull(this.get("ids"), "fileID");
		return this.request();
	}

	this.newInfo = function(contentType, contentID) {
		this.set("at", "new");
		this.set("ct", contentType);
		assertNotNull(this.get("ct"), "contentType");
		this.set("ci", contentID);
		assertNotNull(this.get("ci"), "contentID");
		return this.request();
	}

	this.remove = function(fileIDs) {
		this.set("at", "rmv");
		this.set("ids", fileIDs);
		return this.postRequest();
	}

	this.removeAll = function(contentType, contentIDs) {
		this.set("at", "rmvAll");
		this.set("ct", contentType);
		assertNotNull(this.get("ct"), "contentType");
		this.set("ids", contentIDs);
		assertNotNull(this.get("ids"), "contentIDs");
		return this.postRequest();
	}

	this.move = function(fileIDs, contentType, contentID) {
		if ("999" == contentType)
			return alert(NO_FILES_TO_SHORTCUT), null;
		this.set("at", "mv");
		this.set("ids", fileIDs);
		this.set("ct", contentType);
		assertNotNull(this.get("ct"), "contentType");
		this.set("ci", contentID);
		assertNotNull(this.get("ci"), "contentID");
		return this.postRequest();
	}

	this.upload = function(contentType, contentID) {
		this.set("at", "crt");
		this.set("ct", contentType);
		assertNotNull(this.get("ct"), "contentType");
		this.set("ci", contentID);
		assertNotNull(this.get("ci"), "contentID");
		return this.multipartRequest();
	}
}
FileHandler.prototype = new HiveHandler;

var fileHandler = new FileHandler();

function PageHandler() {
	this.ah = "page";

	this.searchGroups = function(fieldName, fieldValue, order) {
		this.set("at", "srchGrps");
		this.set("fname", fieldName);
		this.set("fvalue", fieldValue);
		this.set("order", order);
		return this.request();
	}

	this.getGroupInfo = function(groupID) {
		this.set("at", "getGrp");
		this.set("grpID", groupID);
		return this.request();
	}

	this.newGroupInfo = function() {
		this.set("at", "newGrp");
		return this.request();
	}

	this.saveGroup = function(op) {
		this.set("at", op);
		return this.postRequest();
	}
	this.removeGroups = function(groupIDs) {
		if (!confirm(CNFM_RMV_PAGE_GRPS)) return null;
	
		this.set("at", "rmvGrps");
		this.set("ids", groupIDs);
		if (isEmpty(this.get("ids")))
			return alert(NO_PAGE_GRPS), null;
		return this.postRequest();
	}

	this.getPages = function(groupID, fieldName, fieldValue) {
		this.set("at", "grpPages");
		this.set("grpID", groupID);
		assertNotNull(this.get("grpID"), "groupID");
		this.set("fname", fieldName);
		this.set("fvalue", fieldValue);
		return this.request();
	}

	this.getInfo = function(pageID) {
		this.set("at", "getPage");
		if (pageID) this.set("pgID", pageID);
		assertNotNull(this.get("pgID"), "pageID");
		return this.request();
	}

	this.newInfo = function(groupID) {
		this.set("at", "newPage");
		this.set("grpID", groupID);
		assertNotNull(this.get("grpID"), "groupID");
		return this.request();
	}

	this.savePage = function(op) {
		this.set("at", op);
		return this.postRequest();
	}
	
	this.removePages = function(pageIDs) {
		if (!confirm(CNFM_RMV_PAGE_TMPLS)) return null;
		this.set("at", "rmvPages");
		this.set("ids", pageIDs);
		if (isEmpty(this.get("ids")))
			return alert(NO_PAGE_TMPLS), null;
		return this.postRequest();
	}

	this.setPageContentProperty = function(name, contentType, contentID, uri, value) {
		this.set("at", "setProp");
		this.set("fname", name);
		assertNotNull(this.get("fname"), "name");
		
		this.set("ct", contentType);
		this.set("ci", contentID);
		this.set("uri", uri);
		this.set("fvalue", value);
		return this.postRequest();
	}

	this.setPageProperty = function(name, uri, value) {
		assertNotNull(uri, "uri");
		return this.setPageContentProperty(name, null, null, uri, value);
	}

	this.setContentProperty = function(name, contentType, contentID, value) {
		if (!contentType) contentType = this.get("ct");
		if (!contentID) contentID = this.get("ci");
		assertNotNull(contentID, "ci");
		return this.setPageContentProperty(name, contentType, contentID, null, value);
	}

	this.setProperty = function(name, value) {
		return this.setPageContentProperty(name, null, null, null, value);
	}
}
PageHandler.prototype = new HiveHandler;

var pageHandler = new PageHandler();

function SkinHandler() {
	this.ah = "skin";

	this.searchByTypes = function(skinTypes, asTree) {
		this.set("at", "skinsByTypes");
		this.set("ids", skinTypes);
		assertNotNull(this.get("ids"), "skinTypes");
		return this.request();
	}

	this.getInfo = function(skinIDs) {
		this.set("at", "get");
		this.set("ids", skinIDs);
		assertNotNull(this.get("ids"), "skinIDs");
		return this.request();
	}

	this.newInfo = function(groupID) {
		this.set("at", "new");
		this.set("grpID", groupID);
		assertNotNull(this.get("grpID"), "groupID");
		return this.request();
	}

	this.save = function(op) {
		this.set("at", op);
		if (hasAttachments()) return this.multipartRequest();
		else return this.postRequest();
	}

	this.remove = function(skinIDs) {
		this.set("at", "rmv");
		this.set("ids", skinIDs);
		assertNotNull(this.get("ids"), "skinIDs");
		return this.postRequest();
	}
}
SkinHandler.prototype = new HiveHandler;

var skinHandler = new SkinHandler();

var extSvc = {};
extSvc['Facebook'] = 'http://www.facebook.com/sharer.php?u=<URL>&t=<TITLE>';
extSvc['LinkedIn'] = 'http://www.linkedin.com/shareArticle?mini=true&ro=true&url=<URL>&title=<TITLE>';
extSvc['Digg'] = 'http://digg.com/submit?phase=2&url=<URL>&title=<TITLE>';
extSvc['Delicious'] = 'http://delicious.com/save?url=<URL>&title=<TITLE>';
extSvc['StumbleUpon'] = 'http://www.stumbleupon.com/submit?url=<URL>&title=<TITLE>';
extSvc['Bebo'] = 'http://www.bebo.com/share?Url=<URL>&Title=<TITLE>';
extSvc['Reddit'] = 'http://reddit.com/submit?url=<URL>&title=<TITLE>';
extSvc['Twitter'] = 'http://twitter.com/home?status=<TITLE>';
extSvc['Yahoo Buzz'] = 'http://buzz.yahoo.com/submit/?submitUrl=<URL>&submitHeadline=<TITLE>';

function share(svc, url, text) {
	var u = encodeURIComponent(url),
		t = encodeURIComponent(text),
		s = extSvc[svc],
		str = s.replace(/<URL>/, u).replace(/<TITLE>/, t);
	window.open(str, "shareOut");
}

function disableBody() {
	if (!exists(fieldName("BODY"))) return;
	field("BODY").disable = true;
}

function selectFile(property) {
	var url = "explorer?ah="+fileHandler.getName()+"&si=" + siteID() + "&prop=" + property + "&at=srch&dest=/jsp/file/fileDialog.jsp",
	    dim = "width=620,height=400,scrollbars=yes";
	window.open(url, 'selectFile', dim);
}

function selectTemplate(usageType, property, group) {
	var url = "explorer?si="+siteID()+"&ah="+pageHandler.getName()+"&prop=" + property + "&at=grpPages&grpID=" + group + "&fname=USG&fvalue="+usageType+"&dest=/jsp/page/tmplDialog.jsp",
	    dim = "width=630,height=400,scrollbars=yes";
	window.open(url, 'selectTemplate', dim);
}

HiveAlert = function(msg) {
	alert( msg );
}

HiveConfirm = function(msg, tfn, ffn) {
	try {
		if( confirm( msg ) )
			return tfn();
		else
			return ffn();
	} catch(e) { }
}

function ContentHandler() {
	this.search = function(srcSite, srcParent, incSubs, parentID, fieldName, fieldValue, status, order) {
		this.set("at", "srch");
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("srcParent", srcParent);
		this.set("incSubs", incSubs);
		this.set("ci", parentID);
		this.set("fname", fieldName);
		this.set("fvalue", fieldValue);
		this.set("status", status);
		this.set("order", order);
		return this.request();
	}

	this.getInfo = function(srcSite, srcID) {
		this.set("at", "get");
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("srcID", srcID);
		return this.request();
	}

	this.newInfo = function(srcSite, parentID) {
		this.set("at", "new");
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("pi", parentID);
		return this.request();
	}

	this.save = function(srcID, op) {
		this.set("at", op);
		this.set("srcID", srcID);
		if (hasAttachments()) return this.multipartRequest();
		else return this.postRequest();
	}
	
	this.removeTrue = function(srcSite, contentIDs, parentID) {
		this.set("at", "rmv");
		this.setSourceSite( srcSite );//if (srcSite) this.set("srcSite", srcSite);
		this.set("ids", contentIDs );
		if (isEmpty(this.get("ids")))
			return alert(NO_CNTS), null;
		this.set("ci", parentID );
		assertNotNull(this.get("ci"), "parentID");
		return this.postRequest();
	}
	
	this.remove = function(srcSite, contentIDs, parentID) {
		if (hasValue(contentIDs, "00000"))
			return HiveAlert(NO_RMV_ROOT_CNT), null;
		this.pass = [srcSite, contentIDs, parentID];
		RemoveInstance = this;
		HiveConfirm(CNFM_RMV_CNT,
			  function() { RemoveInstance.removeTrue.apply(RemoveInstance,RemoveInstance.pass); }
			, function() { try { RemoveInstance.dest("").actionInfo=null; } catch(e) { } }
		);
	}
	
/*
	this.remove = function(srcSite, contentIDs, parentID) {
		if (hasValue(contentIDs, "00000"))
			return alert(NO_RMV_ROOT_CNT), null;
		if (!confirm(CNFM_RMV_CNT)) return null;
		this.set("at", "rmv");
		
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("ids", contentIDs);
		if (isEmpty(this.get("ids")))
			return alert(NO_CNTS), null;
		this.set("ci", parentID);
		assertNotNull(this.get("ci"), "parentID");
		return this.postRequest();
	}
*/

	this.reorder = function(srcSite, contentID, parentID, offset) {
		this.set("at", "reorder");
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("ci", contentID);
		if (isEmpty(this.get("ci")))
			return alert(NO_CNTS), null;
		if ("00000" == this.get("ci"))
			return alert(NO_REORDER_ROOT_CNT), null;
		this.set("pi", parentID);
		assertNotNull(this.get("pi"), "parentID");
		
		this.set("offset", offset);
		if (isEmpty(this.get("offset")))
			return alert(NO_OFFSET), null;
		return this.postRequest();
	}

	this.moveDest = function(contentIDs, currentContent) {
		this.set("at", "getDest");
		this.set("ids", contentIDs);
		if (isEmpty(this.get("ids")))
			return alert(NO_CNTS), null;
		if ("00000" == this.get("ids"))
			return alert(NO_MOVE_ROOT_CNT), null;
	
		this.set("ci", currentContent);
		assertNotNull(this.get("ci"), "currentContent");
		
		this.set("next", "move");
		if (this.handlesContainer()) this.set("chkSub", "true");
		return this.request();
	}

	this.move = function(srcSite, contentIDs, parentID) {
		this.set("at", "move");
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("ids", contentIDs);
		if (isEmpty(this.get("ids")))
			return alert(NO_CNTS), null;
		if (hasValue(this.get("ids"), "00000"))
			return alert(NO_MOVE_ROOT_CNT), null;
		this.set("pi", parentID);
		assertNotNull(this.get("pi"), "parentID");
		return this.postRequest();
	}

	this.setField = function(srcSite, contentID, fieldName, fieldValue) {
		this.set("at", "setField");
		
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("srcID", contentID);
		assertNotNull(this.get("srcID"), "contentID");
		this.set("fname", fieldName);
		assertNotNull(this.get("fname"), "fieldName");
		this.set("fvalue", fieldValue);
		assertNotNull(this.get("fvalue"), "fieldValue");
		return this.postRequest();
	}
	
	this.setReadAccess = function(srcSite, contentID, groupID) {
		this.set("at", "setRead");
		
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("srcID", contentID);
		assertNotNull(this.get("srcID"), "contentID");
		this.set("grpID", groupID);
		return this.postRequest();
	}
	
	this.getReadAccess = function(srcSite, contentID) {
		this.set("at", "getRead");
		
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("srcID", contentID);
		assertNotNull(this.get("srcID"), "contentID");
		return this.request();
	}

	this.shortcutDest = function(srcSite, srcIDs, destSite, currentContent) {
		this.set("at", "getDest");
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		
		this.set("ids", srcIDs);
		if (isEmpty(this.get("ids")))
			return alert(NO_CNTS), null;
		if (hasValue(this.get("ids"), "00000"))
			return alert(NO_SHCT_ROOT_CNT), null;
		this.set("ci", currentContent);
		assertNotNull(this.get("ci"), "currentContent");
		
		if (destSite) this.set("destSite", destSite);
		this.set("next", "shortcut");
		return this.request();
	}

	this.createShortcuts = function(srcSite, srcIDs, destSite, destIDs) {
		this.set("at", "shortcut");
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("ids", srcIDs);
		assertNotNull(this.get("ids"), "ids");
		if (hasValue(this.get("ids"), "00000"))
			return alert(NO_SHCT_ROOT_CNT), null;
		this.set("destSite", destSite);
		this.set("pi", destIDs);
		assertNotNull(this.get("pi"), "destIDs");
		return this.postRequest();
	}

	this.setStatus = function(srcSite, contentIDs, parentID, status) {
		this.set("at", "status");
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("ids", contentIDs);
		if (isEmpty(this.get("ids")))
			return alert(NO_CNTS), null;
		this.set("ci", parentID);
		assertNotNull(this.get("ci"), "parentID");
		
		this.set("status", status);
		assertNotNull(this.get("status"), "status");
		return this.postRequest();
	}
}
ContentHandler.prototype = new HiveHandler;

function ContentContainerHandler() {
	this.handlesContainer = function() {
		return true;
	}

	this.view = function(parentID, srcSite, srcID) {
		this.set("at", "view");
		this.set("srcID", srcID);
		assertNotNull(this.get("srcID"), "srcID");
		
		this.set("ci", parentID);
		assertNotNull(this.get("ci"), "ci");
		
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		
		return this.request();
	}
	
	this.refresh = function(contentID) {
		this.set("at", "refresh");
		this.set("ci", contentID);
		return this.postRequest();
	}
}
ContentContainerHandler.prototype = new ContentHandler;

function SectionHandler() {
	this.ah = "section";
}
SectionHandler.prototype = new ContentContainerHandler;

var sectionHandler = new SectionHandler();

function ContentBoxHandler() {
	this.ah = "box";
}
ContentBoxHandler.prototype = new ContentContainerHandler;

var boxHandler = new ContentBoxHandler();

function commentVoted(srcSite, commentID) {
	assertNotNull(commentID, "commentID");
	var kookie = new Kookie(),
		voted = "true" == kookie.get("ynCmt-" + kookie.get("HIVE_ID") + "-" + srcSite + "-" + commentID);
	if (voted)
		alert(ALREADY_VOTED_CMT);
	return voted;
}

function ContainedContentHandler() {
	this.contentType = null;
	
	this.handlesContainer = function() {
		return false;
	}

	this.searchActives = function(srcSite, srcParent, incSubs, parentID, fieldName, fieldValue, order) {
		this.set("at", "srchActives");
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("srcParent", srcParent);
		this.set("incSubs", incSubs);
		this.set("ci", parentID);
		this.set("fname", fieldName);
		this.set("fvalue", fieldValue);
		this.set("order", order);
		return this.request();
	}

	this.searchByTagIDs = function(tagIDs, all) {
		this.set("at", "srchByTagIDs");
		if (tagIDs) this.set("ids", tagIDs);
		if (all != null) this.set("any", all);
		return this.request();
	}

	this.searchByTagNames = function(tagNames, all) {
		this.set("at", "srchByTagNames");
		if (tagNames) this.set("ids", tagNames);
		if (all != null) this.set("any", all);
		return this.request();
	}
	
	this.getIndex = function() {
		var indexHandler = new ContentIndexHandler();
		indexHandler.contentType = this.contentType;
		return indexHandler;
	}

	this.view = function(parentID, srcSite, srcID, view) {
		this.set("at", "view");
		this.set("srcID", srcID);
		assertNotNull(this.get("srcID"), "srcID");
		
		this.set("ci", parentID);
		assertNotNull(this.get("ci"), "ci");
		
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		
		this.set("view", view);
		return this.request();
	}

	this.copyDest = function(srcSite, srcIDs, destSite, currentContent) {
		this.set("at", "getDest");
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("ids", srcIDs);
		if (isEmpty(this.get("ids")))
			return alert(NO_CNTS), null;
		this.set("destSite", destSite);
		this.set("ci", currentContent);
		assertNotNull(this.get("ci"), "currentContent");
		
		this.set("next", "copy");
		return this.request();
	}

	this.copy = function(srcSite, srcIDs, destSite, parentIDs) {
		this.set("at", "copy");
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("ids", srcIDs);
		this.set("destSite", destSite);
		this.set("pi", parentIDs);
		
		return this.postRequest();
	}

	this.getPublishings = function(srcSite, parentID) {
		this.set("at", "getPubs");
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("ci", parentID);
		return this.request();
	}

	this.preparePublish = function(srcSite, contentIDs, parentID) {
		return this.setStatus(srcSite, contentIDs, parentID, "004");
	}

	this.publish = function(srcSite, contentIDs, parentID) {
		return this.setStatus(srcSite, contentIDs, parentID, "005");
	}
	
	this.getVoters = function(srcSite, srcID, vote) {
		this.set("at", "get-cnt-voters");
		this.setSourceSite(srcSite);
		this.set("srcType", this.contentType);
		this.set("srcID", srcID);
		this.set("vote", vote);
		return this.request();
	}

	this.voteContent = function(srcSite, srcID, vote) {
		if (contentVoted(srcSite, this.contentType, srcID)) return null;
		this.set("at", "voteCnt");
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("srcType", this.contentType);
		this.set("srcID", srcID);
		this.set("vote", vote);
		return this.postRequest();
	}

	this.yesToContent = function(srcSite, srcID) {
		return this.voteContent(srcSite, srcID, true);
	}

	this.noToContent = function(srcSite, srcID) {
		return this.voteContent(srcSite, srcID, false);
	}

	this.getComments = function(srcSite, srcID) {
		this.set("at", "getCmts");
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("srcType", this.contentType);
		this.set("srcID", srcID)
		return this.request();
	}

	this.addComment = function(srcSite, srcID, contentID) {
		this.set("at", "addCmt");
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("srcType", this.contentType);
		this.set("srcID", srcID);
		assertNotNull(this.get("srcID"), "srcID");
		
		this.set("ci", contentID);
		return this.postRequest();
	}

	this.removeComments = function(srcSite, srcID, commentIDs) {
		this.set("at", "rmvCmt");
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("srcType", this.contentType);
		this.set("srcID", srcID);
		assertNotNull(this.get("srcID"), "srcID");
		this.set("ids", commentIDs);
		assertNotNull(this.get("ids"), "commentIDs");
		
		return this.postRequest();
	}

	this.voteComment = function(srcSite, srcID, commentID, vote) {
		if (commentVoted(srcSite, commentID)) return null;
		this.set("at", "voteCmt");
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("srcType", this.contentType);
		this.set("srcID", srcID);
		assertNotNull(this.get("srcID"), "srcID");
		this.set("cmtID", commentID);
		assertNotNull(this.get("cmtID"), "cmtID");
		this.set("vote", vote);
		return this.postRequest();
	}

	this.yesToComment = function(srcSite, srcID, commentID) {
		return this.voteComment(srcSite, srcID, commentID, true);
	}

	this.noToComment = function(srcSite, srcID, commentID) {
		return this.voteComment(srcSite, srcID, commentID, false);
	}
	
	this.getReferences = function(srcSite, srcID) {
		this.set("at", "getRefs");
		this.set("srcType", this.contentType);
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		assertNotNull(this.get("srcSite"), "srcSite");
		this.set("srcID", srcID);
		assertNotNull(this.get("srcID"), "srcID");
		
		return this.request();
	}
	
	this.getRefTargets = function(srcSite, srcID, accessGroup, fieldName, fieldValue) {
		this.set("at", "refTgts");
		this.set("srcType", this.contentType);
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		assertNotNull(this.get("srcSite"), "srcSite");
		this.set("srcID", srcID);
		assertNotNull(this.get("srcID"), "srcID");
		this.set("accGrp", accessGroup);
		this.set("fname", fieldName);
		this.set("fvalue", fieldValue);
		
		return this.request();
	}

	this.addReferences = function(srcSite, srcID, tgtSite, tgtType, tgtIDs) {
		this.set("at", "addRefs");
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("srcType", this.contentType);
		this.set("srcID", srcID);
		assertNotNull(this.get("srcID"), "srcID");
		this.set("tgtSite", tgtSite);
		this.set("tgt", tgtType);
		assertNotNull(this.get("tgt"), "tgt");
		this.set("ids", tgtIDs);
		assertNotNull(this.get("ids"), "ids");
		
		return this.postRequest();
	}
	
	this.removeReferences = function(srcSite, srcID, refIDs) {
		this.set("at", "delRefs");
		this.setSourceSite(srcSite);//if (srcSite) this.set("srcSite", srcSite);
		this.set("srcType", this.contentType);
		this.set("srcID", srcID);
		assertNotNull(this.get("srcID"), "srcID");
		this.set("ids", refIDs);
		assertNotNull(this.get("ids"), "ids");
		
		return this.postRequest();
	}
}
ContainedContentHandler.prototype = new ContentHandler;

function DocumentHandler() {
	this.ah = "document";
	this.contentType = "010";
}
DocumentHandler.prototype = new ContainedContentHandler;

var documentHandler = new DocumentHandler();

function MemoHandler() {
	this.ah = "memo";
	this.contentType = "015";
	
	this.searchMemos = function(cfg) {
		this.set("at", "srchMemos");
		for (var key in cfg)
			this.set(key, cfg[key]);
		assertNotNull(this.get("urlHash"), "urlHash");
		return this.request();
	}
	
	this.searchExt = function(cfg) {
		this.set("at", "srchExt");
		for (var key in cfg)
			this.set(key, cfg[key]);
		return this.request();
	}
}
MemoHandler.prototype = new ContainedContentHandler;

var memoHandler = new MemoHandler();

function contentVoted(srcSite, srcType, srcID) {
	assertNotNull(srcType, "srcType");
	assertNotNull(srcID, "srcID");
	var kookie = new Kookie(),
		voted = "true" == kookie.get("ynCnt-" + kookie.get("HIVE_ID") + "-" + srcSite + "-" + srcType + "-" + srcID);
	if (voted)
		alert(ALREADY_VOTED_CNT);
	return voted;
}

function pollVoted(pollID) {
	assertNotNull(pollID, "pollID");
	var kookie = new Kookie(),
		voted = "true" == kookie.get("voted-" + kookie.get("HIVE_ID") + "-" + siteID() + "-" + pollID);
	if (voted)
		alert(ALREADY_VOTED_POOL);
	return voted;
}

function PollHandler() {
	this.ah = "poll";
	this.contentType = "020";

	this.getAnswer = function(pollID, answerID) {
		this.set("at", "getAns");
		this.set("ci", pollID);
		assertNotNull(this.get("ci"), "ci");
		
		this.set("ansID", answerID);
		assertNotNull(this.get("ansID"), "ansID");
		
		return this.request();
	}

	this.newAnswer = function(pollID) {
		this.set("at", "newAns");
		this.set("ci", pollID);
		assertNotNull(this.get("ci"), "ci");
		return this.request();
	}

	this.saveAnswer = function(op, pollID) {
		this.set("at", op);
		this.set("ci", pollID);
		assertNotNull(this.get("ci"), "ci");
		return this.postRequest();
	}

	this.deleteAnswers = function(pollID, answerIDs) {
		this.set("at", "delAns");
		this.set("ci", pollID);
		assertNotNull(this.get("ci"), "ci");
		
		this.set("ids", answerIDs);
		assertNotNull(this.get("ids"), "ids");
		return this.postRequest();
	}

	this.vote = function(pollID, answerID) {
		if (pollVoted(pollID)) return;
		this.set("at", "vote");
		
		this.set("srcID", pollID);
		this.set("ansID", answerID);
		assertNotNull(this.get("ansID"), "ansID");
		return this.postRequest();
	}
}
PollHandler.prototype = new ContainedContentHandler;

var pollHandler = new PollHandler();

function URLHandler() {
	this.ah = "url";
	this.contentType = "025";
}
URLHandler.prototype = new ContainedContentHandler;

var urlHandler = new URLHandler();

function PopupHandler() {
	this.ah = "popup";
	this.contentType = "030";
}
PopupHandler.prototype = new ContainedContentHandler;

var popupHandler = new PopupHandler();

function ContentIndexHandler() {
	this.ah = "index";
	this.contentType = null;
	
	this.search = function(srcSite, terms, orderBy) {
		this.set("at", "srch");
		this.set("srcSite", srcSite);
		this.set("srcType", this.contentType);
		this.set("terms", terms);
		this.set("order", orderBy);
		return this.request();
	}
	
	this.build = function(siteIDs) {
		this.set("at", "build");
		this.set("ids", siteIDs);
		this.set("srcType", this.contentType);
		return this.request();
	}
	
	this.aggregate = function(destSite) {
		this.set("at", "aggregate");
		this.set("destSite", destSite);
		this.set("srcType", this.contentType);
		return this.request();
	}
}
ContentIndexHandler.prototype = new HiveHandler;