var arrLinkTabObjs;
var DICT = new VarTable();
var initVars = new VarTable();
var strPrevAnchor = "";
var strSortBy = "";

addEvent(window, "load", loadPage);
function loadPage() {
	addDefaultListeners();
	if (typeof loadPage2 == "function") loadPage2();
}

function setOpacity(obj, value) {
	obj.style.opacity = value/10;
	obj.style.filter = 'alpha(opacity=' + value*10 + ')';
}

String.prototype.endsWith = function(strEnd) {
	return (this.substr(this.length - strEnd.length) == strEnd);
};
String.prototype.beginsWith = function(strBegin) {
	return (this.substr(0, strBegin.length) == strBegin);
};
String.prototype.trim = function() {
	return this.replace(/^\s+|\s+$/, ''); 
};
String.prototype.removeDashes = function() {
	return this.replaceAll("-", "");
};
String.prototype.replaceAll = function(strFind, strReplace) {
	var subject = this;
	while (subject.indexOf(strFind) != -1) {
		subject = subject.replace(strFind, strReplace);
	}
	return subject;
};

function exWriteToDoc(str) {
	document.write(str);
}

function getCleanHref() {
	var cleanhref = window.document.URL.toString();
	if (cleanhref.indexOf("#") != -1) {
		cleanhref = cleanhref.substr(0, cleanhref.lastIndexOf("#"));
	}
	if (cleanhref.indexOf("?") != -1) {
		cleanhref = cleanhref.substr(0, cleanhref.lastIndexOf("?"));
	}		
	//while (cleanhref.endsWith("/")) cleanhref = cleanhref.substr(0, cleanhref.length-1);
	if (initVars.get("haspagenumber") == "1") {
		cleanhref = cleanhref.substr(0, cleanhref.lastIndexOf("/"));
	}
	return cleanhref;
}

function getDForm(myVarTable, formaction, formmethod) {
	var frm = document.createElement("form");
	frm.setAttribute("action", formaction);
	frm.setAttribute("method", formmethod);
	for (var i=0;i<myVarTable.getLength();i++) {
		var obj = document.createElement("input");
		obj.setAttribute("type", "hidden");
		obj.setAttribute("name", myVarTable.getNameAt(i));
		obj.setAttribute("value", myVarTable.getValueAt(i));
		frm.appendChild(obj);
	}
	document.body.appendChild(frm);
	return frm;
}

function array_intersect(arrayOfArrays) {
	if (arrayOfArrays.length < 2) return null;
	var arrCommon = new Array();
	for (var i=0;i<arrayOfArrays[0].length;i++) arrCommon.push("" + arrayOfArrays[0][i]);
	for (var i=arrCommon.length-1;i>=0;i--) {
		for (var j=1;j<arrayOfArrays.length;j++) {
			if (!in_array(arrCommon[i], arrayOfArrays[j])) {
				arrCommon.splice(i,1);
				break;
			}
		}
	}
	return arrCommon;
}

function in_array(strNeedle, arr, argBoolCS) {
	if (typeof argBoolCS == "undefined") argBoolCS = true;
	for (var i=0;i<arr.length;i++) {
		if (argBoolCS && arr[i] == strNeedle) {
			return true;
		}
		if (!argBoolCS && arr[i].toLowerCase() == strNeedle.toLowerCase()) {
			return true;
		}
	}
	return false;
}

function addEvent(elm, evType, fn, argUseCapture) {
	if (elm == null) return;
	if (typeof argUseCapture == "undefined") argUseCapture = false;
	if (elm.addEventListener) {elm.addEventListener(evType, fn, argUseCapture); return true; }
	else if (elm.attachEvent) {var r = elm.attachEvent('on' + evType, fn); return r; } 
	else {elm['on' + evType] = fn;}
}

function preventDefault(e) {
	if (window.event) {
		window.event.returnValue = false;
	} else {
		e.preventDefault();
	}
}

function removeAllChildNodes(elm) {
	while (elm.childNodes.length > 0) {
		elm.removeChild(elm.childNodes[0]);
	}
	//elm.innerHTML = ""; //ie6 ...
}

function findTarget(e) {
	if (window.event) return window.event.srcElement;
	return e.target;
}


function ratingClicked(argRating, strdomprefix) {
	var strClassName = "";
	argRating = "" + argRating;
	switch (argRating) {
		case "0": strClassName = "rating zerostar"; break;
		case "1": strClassName = "rating onestar"; break;
		case "2": strClassName = "rating twostar"; break;
		case "3": strClassName = "rating threestar"; break;
		case "4": strClassName = "rating fourstar"; break;
		case "5": strClassName = "rating fivestar"; break;
		default: strClassName = "rating zerostar";
	}
	document.getElementById(strdomprefix + "_rating_li_" + argRating).blur();
	document.getElementById(strdomprefix + '_rating_ul').className = strClassName;
}

function getClickRatingListener(argRating, strdomprefix) {
	return function(e) {
		preventDefault(e);
		ratingClicked(argRating, strdomprefix);
	}
}

function getRatingValue(strdomprefix) {
	var objRatingUl = document.getElementById(strdomprefix + "_rating_ul");
	switch (objRatingUl.className) {
		case "rating nostar": return "-1";
		case "rating zerostar": return "0";
		case "rating onestar": return "20";
		case "rating twostar": return "40";
		case "rating threestar": return "60";
		case "rating fourstar": return "80";
		case "rating fivestar": return "100";
		default: return -1;
	}
}

function getRadioButtonValue(arrDom) {
	for (var i=0;i<arrDom.length;i++) {
		if (arrDom[i].checked) {
			return arrDom[i].value;
		}
	}
	return -1;
}


function checkanchor(skipActions) {
	if (typeof skipActions == "undefined") skipActions = false;
	var doResetTimeout = true;
	if (anchorHasChanged()) {
		var anchorVars = getAnchorParameters();
		var handledVars = 0;
		handledVars += anchorChangedHandler1(anchorVars, skipActions);
		//handledVars += anchorChangedHandler2(anchorVars);
		if (handledVars != anchorVars.getLength()) {
			//not all vars have been "consumed" by the handlers, translation may be needed, this will occur only once everytime the anchor has changed
			//strPrevAnchor is still our "current" anchor
			var translatedAnchor = translateAnchor(strPrevAnchor);
			if (translatedAnchor != null && translatedAnchor != strPrevAnchor) {
				document.location.href = "#" + translatedAnchor;
				doResetTimeout = false;
				checkanchor(skipActions);
			}
		}
	}
	if (doResetTimeout) setTimeout("checkanchor();", 750);
}

function translateAnchor(strAnchor) {
	var myVars = new VarTable();
	myVars.add("anchor", strAnchor);
	var xmlDoc = loadXML("/_services/common/translateAnchor", myVars, true);
	if (xmlDoc != null) {
		var xmlretval = getNodeTextContent(xmlDoc.getElementsByTagName('returnvalue')[0]);
		if (xmlretval == "true") {
			return getNodeTextContent(xmlDoc.getElementsByTagName('anchor')[0]);
		}
	}
	return strAnchor;
}

function anchorChangedHandler1(anchorVars, skipActions) {
	var retval = 0;
	strSortBy = getSortByFromUrl(anchorVars); //global var strSortBy
	if (strSortBy.length == 0) {
		strSortBy = initVars.get("default_sort");
	} else {
		retval = 1;
	}
	if (!skipActions && strSortBy != et.getLinksManager().getSortName()) {
		for (var i=0;i<arrLinkTabObjs.length;i++) {
			arrLinkTabObjs[i].setCurrentOrderBy(strSortBy);
		}
		et.getLinksRenderer().changeOrderBy(strSortBy);
	}
	return retval;
}

function anchorHasChanged() {
	var strURL = window.document.location.href.toString();
	var arrURL = strURL.split("#");
	if (arrURL.length == 2) {
		if (strPrevAnchor != arrURL[1]) {
			strPrevAnchor = arrURL[1];
			return true;
		} else {
			return false;
		}
	} else {
		return false;
	}
}

function getAnchorParameters() {
	var myVars = new VarTable();
	var strURL = window.document.location.href.toString();
	var arrURL = strURL.split("#");
	if (arrURL.length == 2) {
		var arrParams = arrURL[1].split("&");
		for (var i=0;i<arrParams.length;i++) {
			var nameAndValue = arrParams[i].split("=");
			if (nameAndValue.length == 2) {
				myVars.add(nameAndValue[0], nameAndValue[1]);
			}
		}
	}
	return myVars;
}

function getSortByFromUrl(myVars) {
	var strsortby = "";
	var paramSort = myVars.get(initVars.get("anchor_param_sort"));
	if (paramSort != null) strsortby = paramSort;
	switch (strsortby) {
		case initVars.get("sn_Newest"): return "Newest";
		case initVars.get("sn_LastVisited"): return "LastVisited";
		case initVars.get("sn_MostVisited"): return "MostVisited";
		case initVars.get("sn_TopRated"): return "TopRated";
		case "":
		default: return "";
	}
}

function addDefaultListeners() {
	if (!document.cookie) {
		var objNoCookies = document.getElementById("nocookies");
		if (objNoCookies != null) {
			objNoCookies.className = "";
			objNoCookies.appendChild(document.createTextNode(DICT.get("MSG_ENABLE_COOKIES")));
		}
	}
	var arrLinks = document.getElementsByTagName('a');
	for (var i=0; i < arrLinks.length; i++) {
		if (arrLinks[i].name.beginsWith("viewoption_")) {addEvent(arrLinks[i], 'click', changeViewmode);}
		if (arrLinks[i].name.beginsWith("searchviewoption_")) {addEvent(arrLinks[i], 'click', changeSearchViewmode);}
		if (arrLinks[i].name.beginsWith("addFavoriteMember_")) {
			addEvent(arrLinks[i], 'click', getAddRemoveFavListener(getAddRemoveFavFunc("/_services/users/addFavoriteMember", "userid")));
		}
		if (arrLinks[i].name.beginsWith("removeFavoriteMember")) {
			addEvent(arrLinks[i], 'click', getAddRemoveFavListener(getAddRemoveFavFunc("/_services/users/removeFavoriteMember", "userid")));
		}
		if (arrLinks[i].name.beginsWith("addFavoriteClub_")) {
			addEvent(arrLinks[i], 'click', getAddRemoveFavListener(getAddRemoveFavFunc("/_services/clubs/addFavoriteClub", "clubid")));
		}
		if (arrLinks[i].name.beginsWith("removeFavoriteClub")) {
			addEvent(arrLinks[i], 'click', getAddRemoveFavListener(getAddRemoveFavFunc("/_services/clubs/removeFavoriteClub", "clubid")));
		}
		if (arrLinks[i].id == "silang") {
			addEvent(arrLinks[i], 'click', sendCurrentUrl);
		}
	}
	var txtSearch = document.getElementById("txtSearch");
	if (txtSearch != null) {
		addEvent(txtSearch, 'keyup', searchKeyUp);
	}
	var searchbutton = document.getElementById("searchbutton");
	if (searchbutton != null) {
		addEvent(searchbutton, 'click', searchClick);
	}
}

function sendCurrentUrl(e) {
	var myVars = new VarTable();
	myVars.add("url", window.document.location.href.toString());
	var xmlDoc = loadXML("/_services/common/setLastUrl", myVars, true);
}

function changeViewmode(e) {
	var target = findTarget(e);
	var strViewmode = target.name.replace("viewoption_", "");
	var myVars = new VarTable();
	myVars.add("viewmode", strViewmode);
	var xmlDoc = loadXML("/_services/common/setViewmode", myVars, true);
}
function changeSearchViewmode(e) {
	var target = findTarget(e);
	var strViewmode = target.name.replace("searchviewoption_", "");
	var myVars = new VarTable();
	myVars.add("viewmode", strViewmode);
	var xmlDoc = loadXML("/_services/common/setSearchViewmode", myVars, true);
}

function searchKeyUp(e) {
	if (e.keyCode == 13) {
		searchClick(e);
	}
}

function searchClick(e) {
	preventDefault(e);
	var txtSearch = document.getElementById("txtSearch");
	if (txtSearch.value.length < parseInt(initVars.get("MIN_SEARCHTERM_LENGTH"))) {
		alert(DICT.get("ERROR_SEARCHTERM_MIN_CHARS"));
	} else {
		var searchbutton = document.getElementById("searchbutton");
		var strUrl = searchbutton.href + UTF8.urlEncodePathComponent(txtSearch.value);
		document.location.href = strUrl;
	}
}

function joinTagStrings(domName) {
	var currentElement = null;
	var currentIndex = 1;
	var retval = new Array();
	do {
		currentElement = document.getElementById(domName + (currentIndex++));
		if (currentElement != null && currentElement.value.length > 0) {
			retval.push(currentElement.value);
		}
	} while (currentElement != null);
	return retval.join("\n");
}

function clearTags(lastTagTextBoxId) {
	var arrNameParts = lastTagTextBoxId.split("_");
	for (var i=1;i<=parseInt(arrNameParts[2]);i++) {
		document.getElementById(arrNameParts[0] + "_" + arrNameParts[1] + "_" + i).value = "";
	}
	for (var i=parseInt(arrNameParts[2])+1;true;i++) {
		var curobj = document.getElementById(arrNameParts[0] + "_" + arrNameParts[1] + "_" + i);
		if (curobj != null) {
			curobj.parentNode.parentNode.removeChild(curobj.parentNode);
		} else {
			break;
		}
	}
}

function addTagTextBox(objLastFieldId) {
	var objLastField = document.getElementById(objLastFieldId);
	var lastUnderScore = objLastFieldId.lastIndexOf("_");
	var strPrefix = objLastFieldId.substring(0, lastUnderScore + 1);
	var objIndex = parseInt(objLastFieldId.substring(lastUnderScore + 1));
	if (objIndex < parseInt(initVars.get("MAX_TAG_COUNT_PER_LINK"))) {
		if (objLastField.value.length > 0) {
			var objNext = document.getElementById(strPrefix + (objIndex + 1));
			if (objNext == null) {
				var newobjname = "";
				if (objLastField.name && objLastField.name.length > 0) {
					var posInName = objLastField.name.lastIndexOf("[");
					if (posInName > -1) {
						var strobjname = objLastField.name.substring(0, posInName);
						var nextnameindex = parseInt(objLastField.name.substring(posInName+1, objLastField.name.length-1)) + 1;
						newobjname = strobjname + "[" + nextnameindex + "]";
					}
				}
				var objNewLi = document.createElement("li");
				var objNewInput = document.createElement("input");
				objNewInput.id = strPrefix + (objIndex + 1);
				objNewInput.name = newobjname;
				objNewInput.maxLength = initVars.get("MAX_TAG_LENGTH");
				addEvent(objNewInput, 'keyup', function(e) {addTagTextBox(findTarget(e).id);});
				objNewLi.appendChild(objNewInput);
				var objOl = objLastField.parentNode.parentNode;
				objOl.appendChild(objNewLi);
			}
		}
	}
}

function fillTagBoxes(objLastFieldId, arrStrings) {
	var objLastField = document.getElementById(objLastFieldId);
	var lastUnderScore = objLastFieldId.lastIndexOf("_");
	var strPrefix = objLastFieldId.substring(0, lastUnderScore + 1);
	var objIndex = parseInt(objLastFieldId.substring(lastUnderScore + 1));
	for (var i=1;i<=arrStrings.length;i++) {
		var currentBox = document.getElementById(strPrefix + i);
		currentBox.value = arrStrings[i - 1];
		if (i>=objIndex) addTagTextBox(strPrefix + new String(i));
	}
}

function array_unique(arr) {
	for (var i=arr.length-1;i>=0;i--) {
		for (var j=0;j<i;j++) {
			if (arr[i] == arr[j]) {
				arr.splice(i,1);
				break;
			}
		}
	}
	return arr;
}

function getTagsFromText(strTags) {
	if (strTags.length == 0) return new Array();
	strTags = strTags.replaceAll("\r", "\n");
	strTags = strTags.trim();
	strTags = strTags.toLowerCase();
	while (strTags.indexOf("\n\n") != -1) strTags = strTags.replaceAll("\n\n", "\n");
	while (strTags.indexOf("  ") != -1) strTags = strTags.replaceAll("  ", " ");
	var arrTags = strTags.split("\n");
	for (var i=0;i<arrTags.length;i++) {
		arrTags[i] = arrTags[i].trim();
	}
	return array_unique(arrTags);
}

function setRatingStars(elementid, intRating) {
	var strClassName = "";
	var strRating = "" + intRating;
	switch (strRating) {
		case "-1": strClassName = "rating nostar"; break;
		case "0": strClassName = "rating zerostar"; break;
		case "1": strClassName = "rating onestar"; break;
		case "2": strClassName = "rating twostar"; break;
		case "3": strClassName = "rating threestar"; break;
		case "4": strClassName = "rating fourstar"; break;
		case "5": strClassName = "rating fivestar"; break;
		default: strClassName = "rating zerostar";
	}
	document.getElementById(elementid).className = strClassName;
}
	


function VarTable() {
	this.arrName = new Array();
	this.arrContent = new Array();
	
	this.get = function(argName) {
		for (i=0;i<this.getLength();i++) {
			if (this.arrName[i] == argName) {
				return this.arrContent[i];
			}
		}
		return null;
	}
	
	this.remove = function(argName) {
		for (i=0;i<this.getLength();i++) {
			if (this.arrName[i] == argName) {
				this.arrName.splice(i, 1);
				this.arrContent.splice(i, 1);
				break;
			}
		}
	}
	
	this.set = function(argName, argValue) {
		for (i=0;i<this.getLength();i++) {
			if (this.arrName[i] == argName) {
				this.arrContent[i] = argValue;
				return true;
			}
		}
		this.arrName.push(argName);
		this.arrContent.push(argValue);
		return true;
	}
	
	this.add = this.set;
	
	this.getLength = function() {
		return this.arrName.length;
	}
	
	this.getURLEncodedString = function() {
		var i;
		var retval = "";
		for (i=0;i<this.getLength();i++) {
			if (i>0) retval += "&";
			retval += this.arrName[i] + "=" + UTF8.urlEncodeString(this.arrContent[i]);
		}
		return retval;
	}
	
	this.getNameAt = function(i) {
		return this.arrName[i];
	}
	
	this.getValueAt = function(i) {
		return this.arrContent[i];
	}
}







function loadXMLFromString(strXML) {
	var xmlDoc = null;
	if (document.implementation && document.implementation.createDocument) {
		var parser = new DOMParser();
		xmlDoc = parser.parseFromString(strXML, "text/xml");
	} else if (window.ActiveXObject) {
		xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
		xmlDoc.loadXML(strXML);
	} else {
		alert("There was a problem creating an XML document.");
	}
	return xmlDoc;
}

function loadXMLDoc(url, ispost, poststring, callbackfunction) {
	var req = false;
	var method = "POST";
	if (!ispost) {
		method = "GET";
		poststring = "";
	}
	if(window.XMLHttpRequest) {
		try {
			req = new XMLHttpRequest();
		} catch(e) {
			req = false;
		}
	} else if(window.ActiveXObject) {
		try {
			req = new ActiveXObject("Msxml2.XMLHTTP");
		} catch(e) {
			try {
				req = new ActiveXObject("Microsoft.XMLHTTP");
			} catch(e) {
				req = false;
			}
		}
	}
	if (req) {
		req.open(method, url, callbackfunction?true:false);
		if (ispost) {
			req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;');
		}
		req.send(poststring);
		if (callbackfunction) {
			req.onreadystatechange = createCallbackFunction(callbackfunction, req);
			return null;
		} else {
			if (req.status == 200) {
				return req.responseXML;
			} else {
				alert("There was a problem retrieving the XML data:\n" + req.statusText);
			}
		}
	} else {
		return null;
	}
}

function createCallbackFunction(callbackfunction, objRequest) {
		return function() {
			callbackfunction(objRequest);
			if (objRequest.readyState == 4) {
				objRequest = null; //mem leak
				callbackfunction = null;
			}
		}
}

function loadXML(url, vars, ispost) {
	if (ispost) {
		var poststring = vars.getURLEncodedString();
		return loadXMLDoc(url, ispost, poststring);
	} else {
		var newurl = url + "?" + vars.getURLEncodedString();
		return loadXMLDoc(newurl, ispost, "");
	}
}

var ELEMENT_NODE = 1;
var ATTRIBUTE_NODE = 2;
var TEXT_NODE = 3;
var CDATA_SECTION_NODE = 4;
var ENTITY_REFERENCE_NODE = 5;
var ENTITY_NODE = 6;
var PROCESSING_INSTRUCTION_NODE = 7;
var COMMENT_NODE = 8;
var DOCUMENT_NODE = 9;
var DOCUMENT_TYPE_NODE = 10;
var DOCUMENT_FRAGMENT_NODE = 11;
var NOTATION_NODE = 12;
function getNodeTextContent(el) {
	var retval = null;
	if (typeof el == "undefined" || !el) {
		retval = "";
	} else if (el.nodeType == ATTRIBUTE_NODE || el.nodeType == ELEMENT_NODE) {
		if (el.childNodes.length > 0) {
			retval = el.childNodes[0].nodeValue;
		} else if (typeof el.nodeValue != "undefined" && el.nodeValue != null) {
			retval = el.nodeValue;
		}
	}
	if (retval == null) return "";
	return retval;
}

function HTMLEncode(str) {
	var div = document.createElement('div');
	div.appendChild(document.createTextNode(str));
	return div.innerHTML;
}

function getFailedReturnValue(xmlDoc) {
	var retval = new VarTable();
	retval.add("returnvalue", false);
	retval.add("errormessagecode", getNodeTextContent(xmlDoc.getElementsByTagName('errormessage')[0].attributes.getNamedItem("code")));
	retval.add("errormessage", getNodeTextContent(xmlDoc.getElementsByTagName('errormessage')[0]));
	errorsNode = xmlDoc.getElementsByTagName('errors')[0];
	var i=0;
	var myErrors = new VarTable();
	for (i=0;i<errorsNode.childNodes.length;i++) {
		if (errorsNode.childNodes[i].nodeType == 1) {
			myErrors.add(errorsNode.childNodes[i].nodeName, getNodeTextContent(errorsNode.childNodes[i]));
		}
	}
	retval.add("errormessages", myErrors);
	//LOGIN_REQUIRED?
		var temp = xmlDoc.getElementsByTagName('url_login');
		if (temp.length == 1) retval.add("url_login", getNodeTextContent(temp[0]));
		temp = xmlDoc.getElementsByTagName('url_autologin');
		if (temp.length == 1) retval.add("url_autologin", getNodeTextContent(temp[0]));
	return retval;
}








function Tags(count, totalCount, filter) {
	this.tags = new Array();
	this.isInited = false;
	this.count = count;
	this.totalCount = totalCount;
	this.filter = filter;
	
	this.add = function(tag) {
		this.tags.push(tag);
	}
	
	this.get = function(i) {
		if (this.tags.length < (i-1)) return null;
		return this.tags[i];
	}
	
	this.getTagById = function (tagid) {
		for (i=0;i<this.size();i++) {
			if (this.get(i).tagid == tagid) {
				return this.get(i);
			}
		}
		return null;
	}
	
	this.size = function() {
		return this.tags.length;
	}
	
	this.findTag = function(strFind) {
		var i=0;
		for (i=0;i<this.size();i++) {
			if (this.get(i).tag == strFind) {
				return this.get(i);
			}
		}
		return null;
	}
	
	this.initCloud = function() {
		//calculate mean
			var total = 0;
			var i=0;
			for (i=0;i<this.size();i++) {
				total += parseInt(this.get(i).usagecount);
			}
			this.myMean = total / this.size();
		//calculate variance
			var arrDev = new Array();
			var i=0;
			for (i=0;i<this.size();i++) {
				arrDev.push(Math.pow(this.get(i).usagecount - this.myMean, 2));
			}
			var total = 0;
			for (i=0;i<arrDev.length;i++) {
				total += parseFloat(arrDev[i]);
			}
			this.myVariance = total / arrDev.length;
		//calculate standard deviation
			this.myStandardDeviation = Math.sqrt(this.myVariance);
		this.isInited = true;
	}
	
	this.getFontSize = function(tag) {
		if (!this.isInited) this.initCloud();
		var factor = (tag.usagecount - this.myMean) / (this.myStandardDeviation);
		if (isNaN(factor)) factor = 0;
		if (factor <= -2) {
			return "xx-small";
		} else if (-2 < factor && factor <= -1.2) {
			return "x-small";
		} else if (-1.2 < factor && factor <= -0.4) {
			return "small";
		} else if (-0.4 < factor && factor < 0.4) {
			return "medium";
		} else if (0.4 <= factor && factor < 1.2) {
			return "large";
		} else if (1.2 <= factor && factor < 2) {
			return "x-large";
		} else {
			return "xx-large";
		}
	}
	
	this.sortAlfa = function(asc) {
		if (asc) {
			this.tags.sort(this.tagsTagComparerAsc);
		} else {
			this.tags.sort(this.tagsTagComparerDesc);
		}
	}
	
	this.sortUsage = function(asc) {
		if (asc) {
			this.tags.sort(this.tagsUsageComparerAsc);
		} else {
			this.tags.sort(this.tagsUsageComparerDesc);
		}
	}
	
	this.getSubSet = function(tagcount, filter) {
		var retval = new Tags(tagcount, this.totalCount, filter);
		for (var i=0;i<this.size() && (retval.size()<tagcount || tagcount == 0);i++) {
			if (filter.length == 0 || this.tags[i].tag.substr(0, filter.length).toLowerCase() == filter.toLowerCase()) {
				retval.add(this.tags[i]);
			}
		}
		return retval;
	}
	
	this.tagsUsageComparerAsc = function(a, b) {
		var res = (a.usagecount - b.usagecount);
		if (res == 0) {
			res = (a.tagid - b.tagid);
		}
		return res;
	}
	
	this.tagsUsageComparerDesc = function(a, b) {
		var res = (b.usagecount - a.usagecount);
		if (res == 0) {
			res = (b.tagid - a.tagid);
		}
		return res;
	}
	
	this.tagsTagComparerAsc = function(a, b) {
		return (b.tag < a.tag) - (a.tag < b.tag);
	}
	
	this.tagsTagComparerDesc = function(a, b) {
		return (a.tag < b.tag) - (b.tag < a.tag);
	}
}



function Tag(tagid, tag, usagecount) {
	this.tagid = tagid;
	this.tag = tag;
	this.usagecount = usagecount;
	
	this.getTag = function() {
		return this.tag;
	}
	
	this.getUrl = function() {
		return initVars.get("myurl") + "/" + initVars.get("pc1_tags") + "/" + UTF8.urlEncodePathComponent(this.tag);
	}
}


function FoldersNameComparerAsc(a, b) {
	var strA = a.getName().toLowerCase();
	var strB = b.getName().toLowerCase();
	return (strB < strA) - (strA < strB);
}

function FoldersNameComparerDesc(a, b) {
	var strA = a.getName().toLowerCase();
	var strB = b.getName().toLowerCase();
	return (strA < strB) - (strB < strA);
}

function Folders() {
	this.hm_f = {};
	this.hm_c = {};
	this.folders = new Array();
	
	this.initAdd = function(folder) {
		//save the folders and the childfolders in a hashmap
		this.folders.push(folder);
		this.hm_f[folder.folderid] = folder;
		if (folder.parentfolderid > 0) {
			var my_c = this.hm_c[folder.parentfolderid];
			if (typeof (my_c) == "undefined") {
				this.hm_c[folder.parentfolderid] = new Array();
				my_c = this.hm_c[folder.parentfolderid];
			}
			my_c.push(folder);
		}
	}
	
	this.afterInitAdd = function() {
		for (var cur_folderid in this.hm_c) {
			var cur_folder = this.hm_f[cur_folderid];
			cur_folder.childFolders = this.hm_c[cur_folderid];
			for (i=0;i<cur_folder.childFolders.length;i++) {
				cur_folder.childFolders[i].setParentFolder(cur_folder);
			}
		}
	}
	
	this.add = function(folder) {
		this.folders.push(folder);
		this.hm_f[folder.folderid] = folder;
		if (folder.parentfolderid > 0) {
			var parentfolder = this.hm_f[folder.parentfolderid];
			if (typeof parentfolder != "undefined") {
				parentfolder.addChildFolder(folder);
				folder.setParentFolder(parentfolder);
			}
		}
	}
	
	this.get = function(i) {
		if (this.folders.length < (i-1)) return null;
		return this.folders[i];
	}
	
	this.size = function() {
		return this.folders.length;
	}
	
	this.getRootFolders = function() {
		var retval = new Array();
		var i=0;
		for (i=0;i<this.folders.length;i++) {
			if (this.folders[i].parentfolderid == 0) {
				retval.push(this.folders[i]);
			}
		}
		return retval;
	}
	
	this.getFolderById = function(folderid) {
		var retval = this.hm_f[folderid];
		if (typeof retval == "undefined") return null;
		return retval;
		/*for (i=0;i<this.folders.length;i++) {
			if (this.folders[i].folderid == folderid) {
				return this.folders[i];
			}
		}
		return null;*/
	}
	
	this.deleteFoldersByIds = function(arrids) {
		for (var i=0;i<arrids.length;i++) {
			for (var j=0;j<this.folders.length;j++) {
				if (this.folders[j].folderid == arrids[i]) {
					var objParent = this.folders[j].getParent();
					if (objParent != null) {
						objParent.deleteChildFolder(this.folders[j]);
					}
					this.folders.splice(j, 1);
					delete this.hm_f[arrids[i]];
					break;
				}
			}
		}
	}
	
	this.moveFoldersByIds = function(arrids, parentid) {
		var parentFolder = this.getFolderById(parentid);
		for (var i=0;i<arrids.length;i++) {
			for (var j=0;j<this.folders.length;j++) {
				if (this.folders[j].folderid == arrids[i]) {
					var objParent = this.folders[j].getParent();
					if (objParent != null) {
						objParent.deleteChildFolder(this.folders[j]);
					}
					this.folders[j].setParentFolder(parentFolder);
					if (parentFolder != null) {
						parentFolder.addChildFolder(this.folders[j]);
					}
					break;
				}
			}
		}
		if (parentFolder == null) {
			this.sortByName(true);
		} else {
			parentFolder.sortByName(true);
		}
	}
	
	this.sortByName = function(asc) {
		if (asc) {
			this.folders.sort(FoldersNameComparerAsc);
		} else {
			this.folders.sort(FoldersNameComparerDesc);
		}
	}
	
	this.fillDropDownList = function(objFolderList, noFolderString, indentString, arrExcludeIds) {
		//objFolderList.options.length = 0;
		/*while (objFolderList.options.length > 0) {
			objFolderList.remove(0);
		}*/
		objFolderList.innerHTML = ""; //ie6 ...
		var objOption = document.createElement('option');
		objOption.value = 0;
		objOption.appendChild(document.createTextNode(noFolderString));
		objFolderList.appendChild(objOption);
		var rootFolders = this.getRootFolders();
		this.fillFoldersDropDownListR(objFolderList, rootFolders, indentString, 0, arrExcludeIds);
	}
	
	this.fillFoldersDropDownListR = function(objFolderList, folders, indentString, levelcounter, arrExcludeIds) {
		var i=0;
		var j=0;
		for (i=0;i<folders.length;i++) {
			var inarray = false;
			for (j=0;j<arrExcludeIds.length;j++) {
				if (arrExcludeIds[j] == folders[i].getId()) {
					inarray = true;
					break;
				}
			}
			if (!inarray) {
				var strIndent = "";
				for (j=0;j<levelcounter;j++) strIndent += indentString;
				var objOption = document.createElement('option');
				objOption.value = folders[i].getId();
				objOption.appendChild(document.createTextNode(strIndent + folders[i].getName()));
				objFolderList.appendChild(objOption);
				if (folders[i].hasChildren()) {
					this.fillFoldersDropDownListR(objFolderList, folders[i].getChildFolders(), indentString, levelcounter + 1, arrExcludeIds);
				}
			}
		}
	}
}



function Folder(folderid, foldername, parentfolderid) {
	this.checked = false;
	this.parentfolder = null;
	this.childFolders = new Array();
	this.isopened = false;
	this.folderid = folderid;
	this.foldername = foldername;
	this.parentfolderid = parentfolderid;
	
	this.addChildFolder = function(folder) {
		this.childFolders.push(folder);
	}
	
	this.getChildFolders = function() {
		return this.childFolders;
	}
	
	this.isOpen = function() {
		return this.isopened;
	}
	
	this.openFolder = function() {
		this.isopened = true;
	}
	
	this.closeFolder = function() {
		this.isopened = false;
	}
	
	this.hasChildren = function() {
		return (this.childFolders.length > 0);
	}
	
	this.switchOpen = function() {
		this.isopened = !this.isopened;
	}
	
	this.getName = function() {
		return this.foldername;
	}
	
	this.getId = function() {
		return this.folderid;
	}
	
	this.getUrl = function() {
		var folderNames = new Array(UTF8.urlEncodePathComponent(this.foldername));
		var currentFolder = this;
		while (currentFolder.parentfolder != null) {
			folderNames.splice(0, 0, UTF8.urlEncodePathComponent(currentFolder.getParent().getName()));
			currentFolder = currentFolder.getParent();
		}
		return initVars.get("myurl") + "/" + initVars.get("pc1_folders") + "/" + folderNames.join("/");
	}
	
	this.getParent = function() {
		return this.parentfolder;
	}
	
	this.setParentFolder = function(parentfolder) {
		if (parentfolder == null) {
			this.parentfolderid = 0;
		} else {
			this.parentfolderid = parentfolder.getId();
		}
		this.parentfolder = parentfolder;
	}
	
	this.setName = function(foldername) {
		this.foldername = foldername;
	}
	
	this.sortByName = function(asc) {
		if (asc) {
			this.childFolders.sort(FoldersNameComparerAsc);
		} else {
			this.childFolders.sort(FoldersNameComparerDesc);
		}
	}
	
	this.deleteChildFolder = function(objFolder) {
		var i=0;
		for (i=0;i<this.childFolders.length;i++) {
			if (this.childFolders[i] == objFolder) {
				this.childFolders.splice(i, 1);
				break;
			}
		}
	}
	
	this.isChecked = function() {
		return this.checked;
	}
	
	this.setChecked = function(blnChecked) {
		this.checked = blnChecked;
	}
}




function Links() {
	this.totalLinkCount = -1;
	this.links = new Array();
	
	this.add = function(link) {
		this.links.push(link);
	}
	
	this.size = function() {
		return this.links.length;
	}
	
	this.get = function(i) {
		return this.links[i];
	}
	
	this.getTotalLinkCount = function() {
		return this.totalLinkCount;
	}
	
	this.getLinkById = function(linkid) {
		for (var i=0;i<this.links.length;i++) {
			if (this.links[i].getId() == linkid) {
				return this.links[i];
			}
		}
		return null;
	}
	
	this.sortByRating = function(asc) {
		if (asc) {
			this.links.sort(this.ratingComparerAsc);
		} else {
			this.links.sort(this.ratingComparerDesc);
		}
	}
	
	this.ratingComparerAsc = function(a, b) {
		return b.getRating() - a.getRating();
	}
	
	this.ratingComparerDesc = function(a, b) {
		return a.getRating() - b.getRating();
	}
}








function Link(id, title, description, url, folderid, tags, rating, explicit, privacylevelid, privacylevelname, languageid, screenshots) {
	this.id = id;
	this.title = title;
	this.description = description;
	this.url = url;
	this.folderid = folderid;
	this.tags = tags;
	this.screenshots = screenshots;
	this.explicit = explicit;
	this.rating = rating;
	this.languageid = languageid;
	this.privacylevelid = privacylevelid;
	this.privacylevelname = privacylevelname;
	
	this.getId = function() {
		return this.id;
	}
	
	this.getTitle = function() {
		return this.title;
	}
	
	this.getDescription = function() {
		return this.description;
	}
	
	this.getDescriptionNodes = function() {
		var d = this.description.replaceAll("\r\n", "\n");
		d = d.replaceAll("\r", "\n");
		var arrPieces = d.split("\n");
		var arrElements = new Array();
		for (var i=0;i<arrPieces.length;i++) {
			arrElements.push(document.createTextNode(arrPieces[i]));
			arrElements.push(document.createElement("br"));
		}
		return arrElements;
	}
	
	this.getUrl = function() {
		return this.url;
	}
	
	this.getScreenshotUrl = function(ssIndex) {
		return this.screenshots.get("screenshot" + ssIndex);
	}
	
	this.getFolderId = function() {
		return this.folderid;
	}
	
	this.getTags = function() {
		return this.tags;
	}
	
	this.isExplicit = function() {
		return this.explicit;
	}
	
	this.getRating = function() {
		return this.rating;
	}
	
	this.getPrivacyLevelId = function() {
		return this.privacylevelid;
	}
	
	this.getPrivacyLevelName = function() {
		return this.privacylevelname;
	}
	
	this.getLanguageId = function() {
		return this.languageid;
	}
	
	this.setFolderId = function(folderid) {
		this.folderid = folderid;
	}
	
	this.setRating = function(rating) {
		this.rating = rating;
	}
}








function CloudTagsRenderer(tagsmanager, tagsdomid, filterdomid, tagscount) {
	this.tagsmanager = tagsmanager;
	this.tagsdomid = tagsdomid;
	this.filterdomid = filterdomid; //no direct reference (IE6 memory leaks)
	this.tagscount = tagscount;
	
	this.render = function() {
		var filter = document.getElementById(this.filterdomid).value;
		var objTags = document.getElementById(this.tagsdomid);
		var arrTags = this.tagsmanager.getSubSet(this, this.tagscount, filter);
		if (arrTags != null) {
			removeAllChildNodes(objTags);
			arrTags.sortAlfa(true);
			var objDiv = document.createElement("div");
			if (arrTags.size() > 0) {
				var objTagsHeader = document.getElementById("tagsheader");
				var objTcb = document.getElementById("tcb");
				if (objTagsHeader != null) objTagsHeader.style.display = "block";
				if (objTcb != null) objTcb.style.display = "block";
			}
			for (var i=0;i<arrTags.size();i++) {
				var myTag = arrTags.get(i);
				var elm = document.createElement("a");
				elm.style.fontSize = arrTags.getFontSize(myTag);
				elm.href = myTag.getUrl();
				elm.appendChild(document.createTextNode(myTag.getTag()));
				objDiv.appendChild(elm);
				objDiv.appendChild(document.createTextNode(" "));
				myTag = null;
				elm = null;
			}
			objTags.appendChild(objDiv);
			objDiv = null;
		}
		arrTags = null;
		filter = null;
		objTags = null;
	}
	
	this.getTagById = function(tagid) {
		return this.tagsmanager.getTagById(tagid);
	}
	
	this.setTagsCount = function(tagscount) {
		this.tagscount = tagscount;
	}
	
	this.loadTags = function(strXML) {
		this.tagsmanager.loadTags(strXML);
		this.render();
	}
	
	this.getKeyUpListener = function(tagsRenderer) {
		return function(e) {
			tagsRenderer.render();
		}
	}
	
	//"constructor"
	if (filterdomid.length > 0) {
		document.getElementById(this.filterdomid).tagsRenderer = this;
		addEvent(document.getElementById(this.filterdomid), 'keyup', this.getKeyUpListener(this));
	}
}


function TreeFoldersRenderer(foldersmanager, foldersdomid, activeFolderId, isEditMode) {
	this.foldersmanager = foldersmanager;
	this.foldersdomid = foldersdomid;
	this.activeFolderId = activeFolderId;
	this.folderCheckedListeners = new Array();
	this.isEditMode = isEditMode;
	this.renderIsRefresh = false;
	
	this.render = function() {
		if (!this.renderIsRefresh) {
			var objFolders = document.getElementById(this.foldersdomid);
			removeAllChildNodes(objFolders);
			var myFolders = this.foldersmanager.getFolders();
			var rootFolders = myFolders.getRootFolders();
			var mainUL = this.renderFoldersR(rootFolders, true, true);
			mainUL.className = "items";
			objFolders.appendChild(mainUL);
		} else {
			document.location.href = document.location.href;
		}
	}
	
	this.renderFoldersR = function(folders, isVisible, isFirst) {
		var objUL = document.createElement("ul");
		if (!isFirst && !isVisible) objUL.className = "hidden";
		for (var i=0;i<folders.length;i++) {
			var folder = folders[i];
			var objLI = document.createElement("li");
			objLI.id = "folder_li_" + folder.getId();
			var objDiv = document.createElement("div");
			objDiv.id = "folder_div_" + folder.getId();
			objDiv.className = this.getFolderClassName(folder);
			//addEvent(objDiv, 'mouseover', this.getMouseOverListener(this, folder.getId()));
			//addEvent(objDiv, 'mouseout', this.getMouseOutListener(this, folder.getId()));
			objLI.appendChild(objDiv);
			//plus or minus?
			if (folder.hasChildren()) {
				var objPlusMinus = document.createElement("a");
				objPlusMinus.href = "#";
				objPlusMinus.className = (folder.isOpen())?"minus":"plus";
				addEvent(objPlusMinus, 'click', this.getOpenCloseListener(this, folder));
				objDiv.appendChild(objPlusMinus);
			}
			//checkbox
			if (this.isEditMode) {
				var chkBox = document.createElement("input"); chkBox.id = "chkfolder_" + folder.getId(); chkBox.name = "chkfolderid"; chkBox.type = "checkbox"; chkBox.value = folder.getId();
				chkBox.defaultChecked = folder.isChecked(); //needed for ie6 ...
				chkBox.checked = folder.isChecked();
				addEvent(chkBox, 'click', this.getCheckListener(this, folder.getId()));
				objDiv.appendChild(chkBox); 
			}
			//clickable foldername
			var aMyName = document.createElement("a");
			aMyName.href = folder.getUrl();
			aMyName.appendChild(document.createTextNode(folder.getName()));
			objDiv.appendChild(aMyName);
			if (folder.hasChildren()) {
				var childUL = this.renderFoldersR(folder.getChildFolders(), folder.isOpen(), false);
				objLI.appendChild(childUL);
			}
			objUL.appendChild(objLI);
		}
		return objUL;
	}
	
	this.getFolderClassName = function(folder) {
		var cName = (folder.hasChildren() && folder.isOpen())?"folder":"cfolder";
		if (folder.getId() == this.activeFolderId) cName += "active";
		if (folder.isChecked()) {
			cName += "checked";
		}
		return cName;
	}

	this.getOpenCloseListener = function(foldersRenderer, myFolder) {
		return function(e) {
			preventDefault(e);
			foldersRenderer.openCloseFolder(myFolder, findTarget(e));
		}
	}
	
	this.loadFolders = function(strXML) {
		this.foldersmanager.loadFolders(strXML);
		this.render();
	}
	
	this.openCloseFolder = function(folder, objPlusMinus) {
		folder.switchOpen();
		objPlusMinus.className = (folder.isOpen())?"minus":"plus";
		var objLI = document.getElementById("folder_li_" + folder.getId());
		var objDiv = document.getElementById("folder_div_" + folder.getId());
		if (objLI != null) {
			for (var i=0;i<objLI.childNodes.length;i++) {
				if (objLI.childNodes[i].tagName.toLowerCase() == "ul") {
					objLI.childNodes[i].className = folder.isOpen()?"":"hidden";
				}
			}
		}
		if (objDiv != null) {
			objDiv.className = this.getFolderClassName(folder);
		}
	}

	this.fillDropDownList = function(objFolderList, arrExcludeIds) {
		var myFolders = this.foldersmanager.getFolders();
		myFolders.fillDropDownList(objFolderList, " ", "     ", arrExcludeIds); //spaces are nbsp = alt + 0160
	}
	
	this.getAllCheckedFolders = function() {
		var retval = new Array();
		var arrIds = this.getCheckedFolderIds();
		for (var i=0;i<arrIds.length;i++) {
			retval.push(this.foldersmanager.getFolders().getFolderById(arrIds[i]));
		}
		return retval;
	}
	
	this.getSingleCheckedFolder = function() {
		var arrAll = this.getAllCheckedFolders();
		if (arrAll.length == 1) {
			return arrAll[0];
		} else {
			return null;
		}
	}
	
	this.folderChecked = function(folderid, checked) {
		var myFolders = this.foldersmanager.getFolders();
		var folder = myFolders.getFolderById(folderid);
		if (folder != null) {
			folder.setChecked(checked);
			var objCurrent = document.getElementById("folder_div_" + folderid);
			var curClassName = objCurrent.className;
			if (checked) {
				curClassName = curClassName.replace("over", "") + "checked";
			} else {
				curClassName = curClassName.replace("checked", "");
			}
			objCurrent.className = curClassName;
		}
		this.notifyFolderCheckedListeners();
	}
	
	this.getCheckListener = function(foldersrenderer, folderid) {
		return function(e) {
			foldersrenderer.folderChecked(folderid, findTarget(e).checked);
		}
	}
	
	this.getMouseOverListener = function(foldersrenderer, folderid) {
		return function(e) {
			if (typeof findTarget == "function") foldersrenderer.mouseOver(folderid, findTarget(e));
		}
	}
	
	this.getMouseOutListener = function(foldersrenderer, folderid) {
		return function(e) {
			if (typeof findTarget == "function") foldersrenderer.mouseOut(folderid, findTarget(e));
		}
	}
	
	this.mouseOver = function(folderid, target) {
		var objDiv = document.getElementById("folder_div_" + folderid);
		if (target.className != "plus" && target.className != "minus" && !objDiv.className.endsWith("checked") && !objDiv.className.endsWith("over")) {
			objDiv.className += "over";
		}
	}
	
	this.mouseOut = function(folderid, target) {
		var objDiv = document.getElementById("folder_div_" + folderid);
		if (target.className != "plus" && target.className != "minus" && objDiv.className.endsWith("over")) {
			objDiv.className = objDiv.className.substr(0, objDiv.className.length - 4);
		}
	}
	
	this.getCheckedFolderIds = function() {
		//var objs = document.getElementsByName("chkfolderid");  //iexplore 6 bug: createElement + getElementsByName
		var objs = document.getElementById(this.foldersdomid).getElementsByTagName("input");
		var arrChecked = new Array();
		for (var i=0;i<objs.length;i++) {
			if (objs[i].checked) {
				arrChecked.push(objs[i].value);
			}
		}
		return arrChecked;
	}
	
	this.addFolderCheckedListener = function(obj) {
		var exists = false;
		for (var i=0;i<this.folderCheckedListeners.length;i++) {
			if (this.folderCheckedListeners[i] == obj) {
				exists = true;
				break;
			}
		}
		if (!exists) this.folderCheckedListeners.push(obj);
	}
	
	this.notifyFolderCheckedListeners = function() {
		for (var i=0;i<this.folderCheckedListeners.length;i++) {
			this.folderCheckedListeners[i].folderChecked();
		}
	}
}


function ThumbnailsLinksRenderer(et, linksmanager, foldersmanager, linksdomid, pagenavigationdomid, displayMode) {
	this.strClassName = "ThumbnailsLinksRenderer";
	this.et = et;
	this.linksmanager = linksmanager;
	this.linksdomid = linksdomid;
	this.arrLinkIds = new Array();
	this.siteCheckedListeners = new Array();
	this.displayMode = displayMode; //"private", "members", "public"
	this.copyLinkListeners = new Array();
	this.visitLinkListeners = new Array();
	this.ratingListeners = new Array();
	this.arrStarsClassNames = new Array("zero", "one", "two", "three", "four", "five");
	this.arrStarsTitles = new Array(DICT.get("ZERO"), DICT.get("POOR"), DICT.get("FAIR"), DICT.get("GOOD"), DICT.get("VERY_GOOD"), DICT.get("EXCELLENT"));
	this.screenshotindex = 1;
	this.foldersmanager = foldersmanager;
	
	this.addVisitLinkListener = function(obj) {
		var exists = false;
		for (var i=0;i<this.visitLinkListeners.length;i++) {
			if (this.visitLinkListeners[i] == obj) {
				exists = true;
				break;
			}
		}
		if (!exists) this.visitLinkListeners.push(obj);
	}
	
	this.notifyVisitLinkListeners = function(linkid) {
		var doPreventDefault = false;
		for (var i=0;i<this.visitLinkListeners.length;i++) {
			if (this.visitLinkListeners[i].linkVisitRequested(linkid)) {
				doPreventDefault = true;
			}
		}
		return doPreventDefault;
	}
	
	this.getVisitLinkListener = function(linksRenderer, linkid) {
		return function(e) {
			if (linksRenderer.notifyVisitLinkListeners(linkid)) {
				preventDefault(e);
			}
		}
	}
	
	this.render = function() {
		this.arrLinkIds = new Array();
		var myLinks = this.linksmanager.getLinks();
		if (document.getElementById("div_msgnolinks") != null && myLinks.size() == 0) return;
		var objLinks = document.getElementById(this.linksdomid);
		removeAllChildNodes(objLinks);
		for (var i=0;i<myLinks.size();i++) {
			var myLink = myLinks.get(i);
			this.arrLinkIds.push(myLink.getId());
			this.renderSingleLink(objLinks, myLink);
		}
		var objDivClear = document.createElement("div");
		objDivClear.className = "clear";
		objLinks.appendChild(objDivClear);
		//page navigation:
		var hrefAnchor = "";
		if (!this.linksmanager.useDefaultSort()) {
			hrefAnchor = "#" + initVars.get("anchor_param_sort") + "=" + initVars.get("sn_" + this.linksmanager.getSortName());
		}
		var cleanhref = getCleanHref();
		var objLinksPages = document.getElementById(pagenavigationdomid);
		removeAllChildNodes(objLinksPages);
		var totalLinks = myLinks.getTotalLinkCount();
		var totalPages = Math.ceil(totalLinks / this.linksmanager.getLinksPerPage());
		var currentPage = this.linksmanager.getPageIndex();
		var maxRight = 5;
		var maxLeft = 5;
		var startAtPage = currentPage - maxLeft; if (startAtPage < 1) startAtPage = 1;
		var stopAtPage = currentPage + maxRight; if (stopAtPage > totalPages) stopAtPage = totalPages;
		//if (startAtPage > 1) {
		if (currentPage > 1) {
			var objFirst = document.createElement("a");
			objFirst.appendChild(document.createTextNode(DICT.get("FIRST")));
			objFirst.href = cleanhref + hrefAnchor;
			objLinksPages.appendChild(objFirst);
			
			var strhref = cleanhref;
			if (currentPage - 1 != 1) strhref = cleanhref + "/" + (currentPage-1);
			strhref += hrefAnchor;
			var objPrevious = document.createElement("a");
			objPrevious.appendChild(document.createTextNode(DICT.get("PREVIOUS")));
			objPrevious.href = strhref;
			objLinksPages.appendChild(objPrevious);
		}
		for (var i=startAtPage;i<=stopAtPage;i++) {
			if (i == currentPage) {
				var objPage = document.createElement("span");
				objPage.appendChild(document.createTextNode(i));
				objLinksPages.appendChild(objPage);
			} else {
				var objPage = document.createElement("a");
				objPage.appendChild(document.createTextNode(i));
				var strhref = cleanhref;
				if (i != 1) strhref = cleanhref + "/" + i;
				strhref += hrefAnchor;
				objPage.href = strhref;
				objLinksPages.appendChild(objPage);
			}
		}
		//if (stopAtPage < totalPages) {
		if (currentPage < totalPages) {
			var strhref = cleanhref + "/" + (currentPage+1);
			strhref += hrefAnchor;
			var objNext = document.createElement("a");
			objNext.appendChild(document.createTextNode(DICT.get("NEXT")));
			objNext.href = strhref;
			objLinksPages.appendChild(objNext);
			
			var strhref = cleanhref + "/" + totalPages;
			strhref += hrefAnchor;
			var objLast = document.createElement("a");
			objLast.appendChild(document.createTextNode(DICT.get("LAST")));
			objLast.href = strhref;
			objLinksPages.appendChild(objLast);
		}
		var objB = document.createElement("b");
		objB.appendChild(document.createTextNode("-"));
		objLinksPages.appendChild(objB);
		this.notifySiteCheckedListeners();
	}
	
	this.renderSingleLink = function(objLinks, myLink) {
		var objDiv = document.createElement("div");
			objDiv.className = "item";
			objDiv.id = "divlink_" + myLink.getId();
		var objA = document.createElement("a");
			objDiv.appendChild(objA);
			objA.className = "site";
			objA.href = myLink.getUrl();
			objA.target = "_blank";
			objA.title = myLink.getTitle();
			addEvent(objA, 'click', this.getVisitLinkListener(this, myLink.getId()));
			//addEvent(objA, 'mouseover', this.getMouseOverListener(objDiv));
			//addEvent(objA, 'mouseout', this.getMouseOutListener(objDiv));
		var objImg = document.createElement("img");
			objImg.src = myLink.getScreenshotUrl(this.screenshotindex);
			objImg.alt = myLink.getTitle();
			//addEvent(objImg, 'mouseover', this.getMouseOverListener(objDiv));
			//addEvent(objImg, 'mouseout', this.getMouseOutListener(objDiv));
		var objSpan = document.createElement("span");
			objSpan.appendChild(document.createTextNode(myLink.getTitle()));
		
		//order of span, img
		if (this.strClassName == "ThumbnailsLinksRenderer" || this.strClassName == "TilesLinksRenderer") {
			objA.appendChild(objSpan);
			objA.appendChild(objImg);
		} else {
			objA.appendChild(objImg);
			objA.appendChild(objSpan);
		}
		
		//inputbox
		var objInput = null;
		if (this.displayMode == "private") {
				objInput = document.createElement("input");
				objInput.type = "checkbox";
				objInput.id = "chklink_" + myLink.getId();
				objInput.value = myLink.getId();
				objInput.className = "sitecheck";
				//addEvent(objInput, 'mouseover', this.getMouseOverListener(objDiv));
				//addEvent(objInput, 'mouseout', this.getMouseOutListener(objDiv));
				addEvent(objInput, 'click', this.getCheckListener(this, objDiv));
				objDiv.appendChild(objInput);
		}
		
		//rating
		var objDivStars = document.createElement("div");
		if (this.displayMode == "private") {
			objDivStars.className = "stars";
			var objUl = document.createElement("ul");
			objUl.className = this.getStarsClassName(myLink.getRating());
			objDivStars.appendChild(objUl);
			for (var j=0;j<this.arrStarsClassNames.length;j++) {
				var objLi = document.createElement("li");
				objUl.appendChild(objLi);
				objLi.className = this.arrStarsClassNames[j];
				objLiA = document.createElement("a");
				objLi.appendChild(objLiA);
				objLiA.href="#";
				objLiA.title=this.arrStarsTitles[j];
				objLiA.appendChild(document.createTextNode(this.arrStarsTitles[j]));
				addEvent(objLiA, 'click', this.getRateLinkListener(this, myLink.getId(), objUl));
			}
		} else {
			objDivStars.className = this.getStarsClassName(myLink.getRating());
		}
		
		//copy link
		var objCopy = null;
		if (this.displayMode == "members" || (this.displayMode == "private" && this.et.hasCopyLinkInPrivate())) {
			var objCopy = document.createElement("a");
			objCopy.title = DICT.get("COPY_THIS_LINK");
			objCopy.className = "copy";
			objCopy.href = "#";
			addEvent(objCopy, 'click', this.getCopyLinkListener(this, myLink.getId(), objUl));
		}
		
		//order and parent of inputbox, stars, copy ...
		if (this.strClassName == "TilesLinksRenderer") {
			var objTParentDiv = document.createElement("div");
			objTParentDiv.className = "in";
				if (objInput != null) objTParentDiv.appendChild(objInput);
				if (objCopy != null) objTParentDiv.appendChild(objCopy);
				objTParentDiv.appendChild(objDivStars);
			objDiv.appendChild(objTParentDiv);
		} else if (this.strClassName == "ThumbnailsLinksRenderer") {
			var objTParentDiv = document.createElement("div");
			objTParentDiv.className = "in";
				if (objInput != null) objTParentDiv.appendChild(objInput);
				objTParentDiv.appendChild(objDivStars);
				if (objCopy != null) objTParentDiv.appendChild(objCopy);
			objDiv.appendChild(objTParentDiv);
		} else {
			if (objInput != null) objDiv.appendChild(objInput);
			objDiv.appendChild(objDivStars);
			if (objCopy != null) objDiv.appendChild(objCopy);
		}
		
		var objPLDiv = document.createElement("div");
			objPLDiv.className = myLink.getPrivacyLevelName().toLowerCase();
			objPLDiv.appendChild(objDiv);
		objLinks.appendChild(objPLDiv);
	}
	
	this.rateLink = function(e, linkid, objUl) {
		findTarget(e).blur();
		var cName = findTarget(e).parentNode.className;
		var rating = 0;
		switch (cName) {
			case "zero": rating = 0; break;
			case "one": rating = 20; break;
			case "two": rating = 40; break;
			case "three": rating = 60; break;
			case "four": rating = 80; break;
			case "five": rating = 100; break;
		}
		/*if (this.linksmanager.rateLink(linkid, rating)) {
			//this.render();
		}*/
		this.notifyRatingListeners(linkid, rating);
		var myLinks = this.linksmanager.getLinks();
		var objLink = myLinks.getLinkById(linkid);
		objUl.className = this.getStarsClassName(objLink.getRating());
	}
	
	this.addRatingListener = function(obj) {
		var exists = false;
		for (var i=0;i<this.ratingListeners.length;i++) {
			if (this.ratingListeners[i] == obj) {
				exists = true;
				break;
			}
		}
		if (!exists) this.ratingListeners.push(obj);
	}
	
	this.notifyRatingListeners = function(linkid, rating) {
		for (var i=0;i<this.ratingListeners.length;i++) {
			this.ratingListeners[i].linkRated(linkid, rating);
		}
	}
	
	this.getRateLinkListener = function(linksRenderer, linkid, objUl) {
		return function(e) {
			preventDefault(e);
			linksRenderer.rateLink(e, linkid, objUl);
		}
	}
	
	this.getStarsClassName = function(rating) {
		if (rating == -1) {
			return "rating nostar";
		} else if (rating < 10) {
			return "rating zerostar";
		} else if (rating < 30) {
			return "rating onestar";
		} else if (rating < 50) {
			return "rating twostar";
		} else if (rating < 70) {
			return "rating threestar";
		} else if (rating < 90) {
			return "rating fourstar";
		} else {
			return "rating fivestar";
		}
	}
	
	this.checkAll = function(bln) {
		//var objs = window.document.getElementsByName("chklinkid"); //iexplore 6 bug: createElement + getElementsByName
		var objs = document.getElementById(this.linksdomid).getElementsByTagName("input");
		for (var i=0;i<objs.length;i++) {
			objs[i].checked = bln;
			this.siteChecked(objs[i], document.getElementById("divlink_" + objs[i].value));
		}
	}
	
	this.getLinkById = function(id) {
		return this.linksmanager.getLinks().getLinkById(id);
	}
	
	this.loadLinks = function(strXML) {
		this.linksmanager.loadLinks(strXML);
		this.render();
	}
	
	this.changeOrderBy = function(orderby) {
		if (parseInt(initVars.get("pagenumber")) == 1) {
			this.linksmanager.changeOrderBy(orderby);
			this.render();
		} else {
			var cleanhref = getCleanHref();
			document.location.href = cleanhref + "#" + translateAnchor(initVars.get("anchor_param_sort") + "=" + orderby);
		}
	}
	
	this.getAllCheckedLinks = function() {
		var myLinks = this.linksmanager.getLinks();
		var retval = new Array();
		var checkedIds = this.getCheckedLinkIds();
		for (var i=0;i<checkedIds.length;i++) {
			retval.push(myLinks.getLinkById(checkedIds[i]));
		}
		return retval;
	}
	
	this.getSingleCheckedLink = function() {
		var arrAll = this.getAllCheckedLinks();
		if (arrAll.length == 1) {
			return arrAll[0];
		} else {
			return null;
		}
	}
	
	this.getCheckedLinkIds = function() {
		//var objs = document.getElementsByName("chklinkid"); //iexplore 6 bug: createElement + getElementsByName
		var objs = document.getElementById(this.linksdomid).getElementsByTagName("input");
		var arrChecked = new Array();
		for (var i=0;i<objs.length;i++) {
			if (objs[i].checked) {
				arrChecked.push(objs[i].value);
			}
		}
		return arrChecked;
	}
	
	this.getCheckListener = function(linksRenderer, objDiv) {
		return function(e) {
			linksRenderer.siteChecked(findTarget(e), objDiv);
		}
	}
	
	this.siteChecked = function(chkbox, objDiv) {
		objDiv.className = (chkbox.checked)?"itemchecked":"item";
		this.notifySiteCheckedListeners();
	}
	
	this.getMouseOverListener = function(objDiv) {
		return function(e) {
			if (objDiv.className=="item" && objDiv.className!="itemchecked"){
				objDiv.className = "itemover";
			}
		}
	}
	
	this.getMouseOutListener = function(objDiv) {
		return function(e) {
			if (objDiv.className=="itemover" && objDiv.className!="itemchecked"){
				objDiv.className = "item";
			}
		}
	}
	
	this.getCheckAllLinksListener = function(linksrenderer, bln) {
		return function(e) {
			preventDefault(e);
			linksrenderer.checkAll(bln);
		}
	}
	
	this.addSiteCheckedListener = function(obj) {
		var exists = false;
		for (var i=0;i<this.siteCheckedListeners.length;i++) {
			if (this.siteCheckedListeners[i] == obj) {
				exists = true;
				break;
			}
		}
		if (!exists) this.siteCheckedListeners.push(obj);
	}
	
	this.notifySiteCheckedListeners = function() {
		for (var i=0;i<this.siteCheckedListeners.length;i++) {
			this.siteCheckedListeners[i].siteChecked();
		}
	}
	
	this.getCopyLinkListener = function(linksRenderer, linkid) {
		return function(e) {
			preventDefault(e);
			linksRenderer.copyLink(linkid);
		}
	}
	
	this.copyLink = function(linkid) {
		var myLinks = this.linksmanager.getLinks();
		var objLink = myLinks.getLinkById(linkid);
		this.notifyCopyLinkListeners(objLink);
	}
	
	this.addCopyLinkListener = function(obj) {
		var exists = false;
		for (var i=0;i<this.copyLinkListeners.length;i++) {
			if (this.copyLinkListeners[i] == obj) {
				exists = true;
				break;
			}
		}
		if (!exists) this.copyLinkListeners.push(obj);
	}
	
	this.notifyCopyLinkListeners = function(objLink) {
		for (var i=0;i<this.copyLinkListeners.length;i++) {
			this.copyLinkListeners[i].copyLinkRequested(objLink);
		}
	}
	
	//"constructor"
	var objSelectAllLinks = document.getElementById("objSelectAllLinks");
	var objDeselectAllLinks = document.getElementById("objDeselectAllLinks");
	if (objSelectAllLinks != null) addEvent(objSelectAllLinks, 'click', this.getCheckAllLinksListener(this, true));
	if (objDeselectAllLinks != null) addEvent(objDeselectAllLinks, 'click', this.getCheckAllLinksListener(this, false));
	//ie6 mem leak
	objSelectAllLinks = null;
	objDeselectAllLinks = null;
}
function TilesLinksRenderer(et, linksmanager, foldersmanager, linksdomid, pagenavigationdomid, displayMode) {
	this.base = ThumbnailsLinksRenderer;
	this.base(et, linksmanager, foldersmanager, linksdomid, pagenavigationdomid, displayMode);
	this.strClassName = "TilesLinksRenderer";
	this.screenshotindex = 2;
}
function ListLinksRenderer(et, linksmanager, foldersmanager, linksdomid, pagenavigationdomid, displayMode) {
	this.base = ThumbnailsLinksRenderer;
	this.base(et, linksmanager, foldersmanager, linksdomid, pagenavigationdomid, displayMode);
	this.strClassName = "ListLinksRenderer";
	this.renderSingleLink = function(objLinks, myLink) {
		var objDiv = document.createElement("div");
			objDiv.className = "item";
			objDiv.id = "divlink_" + myLink.getId();
		if (this.displayMode == "private") {
			var objInput = document.createElement("input");
				objInput.type = "checkbox";
				objInput.id = "chklink_" + myLink.getId();
				objInput.value = myLink.getId();
				objInput.className = "sitecheck";
				addEvent(objInput, 'click', this.getCheckListener(this, objDiv));
				objDiv.appendChild(objInput);
		}
		var objA = document.createElement("a");
			objDiv.appendChild(objA);
			objA.href = myLink.getUrl();
			objA.appendChild(document.createTextNode(myLink.getTitle()));
			objA.target = "_blank";
			objA.title = myLink.getTitle();
			addEvent(objA, 'click', this.getVisitLinkListener(this, myLink.getId()));
		if (this.displayMode == "members" || (this.displayMode == "private" && this.et.hasCopyLinkInPrivate())) {
			var objCopy = document.createElement("a");
			objCopy.title = DICT.get("COPY_THIS_LINK");
			objCopy.className = "copy";
			objCopy.href = "#";
			addEvent(objCopy, 'click', this.getCopyLinkListener(this, myLink.getId(), objUl));
			objDiv.appendChild(objCopy);
		}
		if (myLink.getDescription().length > 0) {
			var objP = document.createElement("p");
			objDiv.appendChild(objP);
			var dNodes = myLink.getDescriptionNodes();
			for (var n=0;n<dNodes.length;n++) objP.appendChild(dNodes[n]);
		}
		var objSpan = document.createElement("span");
			objDiv.appendChild(objSpan);
			objSpan.appendChild(document.createTextNode(myLink.getUrl()));
		//rating
		var objDivStars = document.createElement("div");
		objDiv.appendChild(objDivStars);
		if (this.displayMode == "private") {
			objDivStars.className = "stars";
			var objUl = document.createElement("ul");
			objUl.className = this.getStarsClassName(myLink.getRating());
			objDivStars.appendChild(objUl);
			for (var j=0;j<this.arrStarsClassNames.length;j++) {
				var objLi = document.createElement("li");
				objUl.appendChild(objLi);
				objLi.className = this.arrStarsClassNames[j];
				objLiA = document.createElement("a");
				objLi.appendChild(objLiA);
				objLiA.href="#";
				objLiA.title=this.arrStarsTitles[j];
				objLiA.appendChild(document.createTextNode(this.arrStarsTitles[j]));
				addEvent(objLiA, 'click', this.getRateLinkListener(this, myLink.getId(), objUl));
			}
		} else {
			objDivStars.className = this.getStarsClassName(myLink.getRating());
		}
		objLinks.appendChild(objDiv);
	}
}
function DetailsLinksRenderer(et, linksmanager, foldersmanager, linksdomid, pagenavigationdomid, displayMode) {
	this.base = ThumbnailsLinksRenderer;
	this.base(et, linksmanager, foldersmanager, linksdomid, pagenavigationdomid, displayMode);
	this.strClassName = "DetailsLinksRenderer";
	this.screenshotindex = 2;
	this.renderSingleLink = function(objLinks, myLink) {
		var objDiv = document.createElement("div");
			objDiv.className = "item";
			objDiv.id = "divlink_" + myLink.getId();
		//c1
		var objC1 = document.createElement("div");
			objC1.className = "c1";
			objDiv.appendChild(objC1);
		if (this.displayMode == "private") {
			var objInput = document.createElement("input");
				objInput.type = "checkbox";
				objInput.id = "chklink_" + myLink.getId();
				objInput.value = myLink.getId();
				objInput.className = "sitecheck";
				addEvent(objInput, 'click', this.getCheckListener(this, objDiv));
				objC1.appendChild(objInput);
		}
		if (this.displayMode == "members" || (this.displayMode == "private" && this.et.hasCopyLinkInPrivate())) {
			var objCopy = document.createElement("a");
			objCopy.title = DICT.get("COPY_THIS_LINK");
			objCopy.className = "copy";
			objCopy.href = "#";
			addEvent(objCopy, 'click', this.getCopyLinkListener(this, myLink.getId(), objUl));
			objC1.appendChild(objCopy);
		}
		if (this.displayMode == "private") {
			var objDivPL = document.createElement("div");
			objDivPL.className = myLink.getPrivacyLevelName().toLowerCase();
			objDiv.appendChild(objDivPL);
		}
		var objA = document.createElement("a");
			objC1.appendChild(objA);
			objA.href = myLink.getUrl();
			objA.target = "_blank";
			objA.title = myLink.getTitle();
			addEvent(objA, 'click', this.getVisitLinkListener(this, myLink.getId()));
		var objImg = document.createElement("img");
			objA.appendChild(objImg);
			objImg.src = myLink.getScreenshotUrl(this.screenshotindex);
			objImg.alt = myLink.getTitle();
		//rating
		var objDivStars = document.createElement("div");
		objC1.appendChild(objDivStars);
		if (this.displayMode == "private") {
			objDivStars.className = "stars";
			var objUl = document.createElement("ul");
			objUl.className = this.getStarsClassName(myLink.getRating());
			objDivStars.appendChild(objUl);
			for (var j=0;j<this.arrStarsClassNames.length;j++) {
				var objLi = document.createElement("li");
				objUl.appendChild(objLi);
				objLi.className = this.arrStarsClassNames[j];
				objLiA = document.createElement("a");
				objLi.appendChild(objLiA);
				objLiA.href="#";
				objLiA.title=this.arrStarsTitles[j];
				objLiA.appendChild(document.createTextNode(this.arrStarsTitles[j]));
				addEvent(objLiA, 'click', this.getRateLinkListener(this, myLink.getId(), objUl));
			}
		} else {
			objDivStars.className = this.getStarsClassName(myLink.getRating());
		}
		//c2
		var objC2 = document.createElement("div");
			objC2.className = "c2";
			objDiv.appendChild(objC2);
		var objA = document.createElement("a");
			objC2.appendChild(objA);
			objA.href = myLink.getUrl();
			objA.appendChild(document.createTextNode(myLink.getTitle()));
			objA.target = "_blank";
			objA.title = myLink.getTitle();
			addEvent(objA, 'click', this.getVisitLinkListener(this, myLink.getId()));
		var objP = document.createElement("p");
			objC2.appendChild(objP);
			var dNodes = myLink.getDescriptionNodes();
			for (var n=0;n<dNodes.length;n++) objP.appendChild(dNodes[n]);
		var objSpan = document.createElement("span");
			objC2.appendChild(objSpan);
			objSpan.appendChild(document.createTextNode(myLink.getUrl()));
		if (myLink.getFolderId() > 0) {
			var objUlFolders = document.createElement("ul");
			objUlFolders.className = "folder";
			objC2.appendChild(objUlFolders);
			var objLiFolder = document.createElement("li");
			objUlFolders.appendChild(objLiFolder);
			var objA = document.createElement("a");
			objLiFolder.appendChild(objA);
			var curFolder = this.foldersmanager.getFolders().getFolderById(myLink.getFolderId());
			objA.href = curFolder.getUrl();
			var foldername = curFolder.getName();
			objA.title = foldername;
			objA.appendChild(document.createTextNode(foldername));
		}
		var arrTags = myLink.getTags();
		if (arrTags.length > 0) {
			var objUlTags = document.createElement("ul");
			objC2.appendChild(objUlTags);
			objUlTags.className = "tags";
			for (var x=0;x<arrTags.length;x++) {
				var objLiTag = document.createElement("li");
				objUlTags.appendChild(objLiTag);
				var objA = document.createElement("a");
				objLiTag.appendChild(objA);
				objA.href = initVars.get("myurl") + "/" + initVars.get("pc1_tags") + "/" + UTF8.urlEncodePathComponent(arrTags[x]);
				objA.title = arrTags[x];
				objA.appendChild(document.createTextNode(arrTags[x]));
			}
		}
		if (typeof getanurllink == "function") {
			var obj_link = getanurllink(myLink.getUrl());
			var objmyspan = document.createElement("span");
			objmyspan.appendChild(obj_link);
			objmyspan.style.marginTop = "5px";
			objC2.appendChild(objmyspan);
			addEvent(obj_link, 'click', getanurllinkhandler());
		}
		objLinks.appendChild(objDiv);
	}
}



function TagsTabHandler(allTabs, thisTabIndex, tagsRenderer, intCount, activeClassName, inactiveClassName) {
	this.allTabs = allTabs;
	this.thisTabIndex = thisTabIndex;
	this.tagsRenderer = tagsRenderer;
	this.intCount = intCount;
	this.activeClassName = activeClassName;
	this.inactiveClassName = inactiveClassName;
	
	this.getClickListener = function(tagsTabHandler) {
		return function(e) {
			preventDefault(e);
			tagsTabHandler.handle();
		}
	}
	
	this.handle = function() {
		var myTab = document.getElementById(this.allTabs[thisTabIndex]);
		if (myTab.className != this.activeClassName) {
			for (var i=0;i<this.allTabs.length;i++) {
				var curTab = document.getElementById(this.allTabs[i]);
				if (curTab != myTab) {
					curTab.className = this.inactiveClassName;
				} else {
					curTab.className = this.activeClassName;
				}
				curTab = null;
			}
			this.tagsRenderer.setTagsCount(this.intCount);
			this.tagsRenderer.render();
		}
		myTab = null;
	}
	
	//"constructor"
	addEvent(document.getElementById(this.allTabs[thisTabIndex]), 'click', this.getClickListener(this));
}

function LinksTabHandler(allTabs, thisTabIndex, thisTabOrderBy, currentOrderBy, linksRenderer, activeClassName, inactiveClassName) {
	this.allTabs = allTabs;
	this.thisTabIndex = thisTabIndex;
	this.thisTabOrderBy = thisTabOrderBy;
	this.currentOrderBy = currentOrderBy;
	this.linksRenderer = linksRenderer;
	this.activeClassName = activeClassName;
	this.inactiveClassName = inactiveClassName;
	this.clickListeners = new Array();
	
	this.addClickedListener = function(obj) {
		var exists = false;
		for (var i=0;i<this.clickListeners.length;i++) {
			if (this.clickListeners[i] == obj) {
				exists = true;
				break;
			}
		}
		if (!exists) this.clickListeners.push(obj);
	}
	
	this.notifyClickListeners = function() {
		for (var i=0;i<this.clickListeners.length;i++) {
			this.clickListeners[i].linksTabClicked();
		}
	}
	
	this.getClickListener = function(linksTabHandler) {
		return function(e) {
			//preventDefault(e);
			linksTabHandler.handle();
		}
	}
	
	this.setCurrentOrderBy = function(currentOrderBy) {
		this.currentOrderBy = currentOrderBy;
		if (this.thisTabOrderBy == this.currentOrderBy || (this.currentOrderBy == "" && this.thisTabOrderBy == initVars.get("default_sort")) ) {
			this.activateMe();
		}
	}
	
	this.activateMe = function() {
		var myTab = document.getElementById(this.allTabs[thisTabIndex]);
		for (var i=0;i<this.allTabs.length;i++) {
			var curTab = document.getElementById(this.allTabs[i]);
			if (curTab != myTab) {
				curTab.className = this.inactiveClassName;
			} else {
				curTab.className = this.activeClassName;
			}
			curTab = null;
		}
		myTab = null;
	}
	
	this.handle = function() {
		var myTab = document.getElementById(this.allTabs[thisTabIndex]);
		if (myTab.className != this.activeClassName) {
			this.notifyClickListeners();
			this.activateMe();
			this.linksRenderer.changeOrderBy(this.thisTabOrderBy);
		}
		myTab = null;
	}
	
	//"constructor"
	var myTab = document.getElementById(this.allTabs[thisTabIndex]);
	addEvent(myTab, 'click', this.getClickListener(this));
	if (this.thisTabOrderBy == this.currentOrderBy || (this.currentOrderBy == "" && this.thisTabOrderBy == initVars.get("default_sort")) ) {
		myTab.className = this.activeClassName;
	}
	myTab = null;
}

function XMLMessageHandler() {
	this.tblFields = new VarTable();
	this.generalErrorId = "";
	this.generalMessageId = "";
	
	this.add = function(xmlTagName, elmId) {
		this.tblFields.add(xmlTagName, elmId);
	}
	
	this.setGeneralErrorId = function(generalErrorId) {
		this.generalErrorId = generalErrorId;
	}
	
	this.setGeneralMessageId = function(generalMessageId) {
		this.generalMessageId = generalMessageId;
	}
	
	this.handleMessages = function(res) {
		var blnHandled = false;
		if (res.get("errormessagecode") != null && res.get("errormessagecode").length > 0) {
			switch (res.get("errormessagecode")) {
				case "LOGIN_REQUIRED":
					blnHandled = true;
					if (GetCookie("autologin")) {
						document.location.href = "http://www." + initVars.get("DNAME") + res.get("url_autologin") + "?url=" + UTF8.urlEncodeString(document.location.href.toString());
					} else {
						document.location.href = "http://www." + initVars.get("DNAME") + res.get("url_login") + "?url=" + UTF8.urlEncodeString(document.location.href.toString());
					}
					break;
				case "PAGE_EXPIRED":
					blnHandled = true;
					document.location.href = document.location.href;
					break;
				default: ;
			}
		}
		if (!blnHandled) {
			if (res.get("errormessage") != null && res.get("errormessage").length > 0) {
				if (this.generalErrorId.length > 0) {
					document.getElementById(this.generalErrorId).className = "main_error";
					document.getElementById(this.generalErrorId).appendChild(document.createTextNode(res.get("errormessage")));
				} else {
					alert(res.get("errormessage"));
				}
			}
			
			if (res.get("generalmessage") != null && res.get("generalmessage").length > 0) {
				if (this.generalMessageId.length > 0) {
					document.getElementById(this.generalMessageId).className = "main_message";
					document.getElementById(this.generalMessageId).appendChild(document.createTextNode(res.get("generalmessage")));
				} else {
					alert(res.get("generalmessage"));
				}
			} 
			
			var errMessages = res.get("errormessages");
			if (errMessages != null) {
				for (var i=0;i<errMessages.getLength();i++) {
					var errMessage = errMessages.getValueAt(i);
					var elmId = this.tblFields.get(errMessages.getNameAt(i));
					var elm = document.getElementById(elmId);
					elm.appendChild(document.createTextNode(errMessage));
					elm.className = "";
					elm.parentNode.className = "error";
				}
			}
		}
	}
	
	this.clearMessages = function() {
		if (this.generalErrorId.length > 0) {
			document.getElementById(this.generalErrorId).className = "hidden";
			removeAllChildNodes(document.getElementById(this.generalErrorId));
		}
		if (this.generalMessageId.length > 0) {
			document.getElementById(this.generalMessageId).className = "hidden";
			removeAllChildNodes(document.getElementById(this.generalMessageId));
		}
		for (var i=0;i<this.tblFields.getLength();i++) {
			var elmId = this.tblFields.getValueAt(i);
			var elm = document.getElementById(elmId);
			elm.className = "hidden";
			removeAllChildNodes(elm);
			elm.parentNode.className = "no_error";
		}
	}
}

var UTF8 = {
	urlEncodePathComponent : function(utftext) {
		return this.urlEncodeString(utftext);
	},
	urlEncodeString : function(utftext) {
		utftext = new String(utftext);
		var arrBytes = this.getByteArrayFromString(utftext);
		var retval = "";
		for (var i=0;i<arrBytes.length;i++) {
			if ((arrBytes[i] >= 48 && arrBytes[i] <= 57) || (arrBytes[i] >= 65 && arrBytes[i] <= 90) || (arrBytes[i] >= 97 && arrBytes[i] <= 122) || arrBytes[i] == 45 || arrBytes[i] == 46 || arrBytes[i] == 95) {
				retval += String.fromCharCode(arrBytes[i]);
			} else {
				retval += this.urlEncodeByte(arrBytes[i]);
			}
		}
		return retval;
	},
	urlDecodeString : function(encodedtext) {
		encodedtext = new String(encodedtext);
		return this.getStringFromByteArray(this.getByteArrayFromEncodedString(encodedtext));
	},
	urlEncodeByte : function(num) {
		num = parseInt(num);
		if (num < 0 || num > 255) return "";
		var res = "0" + num.toString(16);
		res = res.substr(res.length-2, 2);
		return "%" + res.toUpperCase();
	},
	getByteArrayFromString : function(utftext) {
		var retval = new Array();
		for (var i=0;i<utftext.length;i++) {
			var arrChar = this.getByteArrayFromCharCode(utftext.charCodeAt(i));
			for (var j=0;j<arrChar.length;j++) retval.push(arrChar[j]);
		}
		return retval;
	},
	getByteArrayFromCharCode : function(charcode) {
		var arr = new Array();
		charcode = parseInt(charcode);
		if (isNaN(charcode)) return arr;
		if (charcode < 0) return arr;
		if (charcode < 128) {
			arr.push(charcode);
			return arr;
		}
		var bytesneeded = Math.ceil(((Math.log(charcode+1) / Math.log(2)) - 1) / 5);
		if (bytesneeded < 2 || bytesneeded > 7) return arr;
		arr.push(charcode >>> ((bytesneeded-1)*6) | (65280 >>> bytesneeded & 255));
		for (var i=2;i<=bytesneeded;i++) arr.push(charcode >>> ((bytesneeded-i)*6) & 63 | 128);
		return arr;
	},
	getStringFromByteArray : function(arr) {
		var cur = -1;
		var firstbyte;
		var utftext = "";
		var i=0;
		while (i<arr.length) {
			if (arr[i] < 128) {
				utftext += String.fromCharCode(arr[i]);
			} else if (arr[i] >= 192) {
				firstbyte = arr[i];
				var pos = 8;
				while (firstbyte >= (128 >>> (8-pos))) {
					firstbyte = firstbyte & (Math.pow(2, pos-1)-1);
					pos-=1;
				}
				cur = firstbyte;
				while (i+1 < arr.length && arr[i+1] >= 128 && arr[i+1] < 192) {
					i++;
					cur = (cur << 6) | (arr[i] & 63);
				}
				utftext += String.fromCharCode(cur);
			} else {
				//this can't (must not) happen with a valid utf byte array
			}
			i++;
		}
		return utftext;
	},
	getByteArrayFromEncodedString : function(encodedtext) {
		var i=0;
		var arrBytes = new Array();
		while (i<encodedtext.length) {
			if (encodedtext.charCodeAt(i) == 37 && i <= encodedtext.length - 3 && "0123456789ABCDEFabcdef".indexOf(encodedtext.charAt(i+1)) != -1 && "0123456789ABCDEFabcdef".indexOf(encodedtext.charAt(i+2)) != -1) {
				arrBytes.push(parseInt(encodedtext.substr(i+1, 2), 16));
				i+=3;
			} else {
				arrBytes.push(encodedtext.charCodeAt(i));
				i++;
			}
		}
		return arrBytes;
	}
}


function getAddRemoveFavListener(theFunc) {
	return function(e) {
		preventDefault(e);
		var obj = findTarget(e);
		var arr = obj.name.split("_");
		var entityid = arr[1];
		theFunc(entityid);
	}
}
function getAddRemoveFavFunc(addr, fname) {
	return function(entityid) {
		var myVars = new VarTable();
		myVars.add(fname, entityid);
		var xmlDoc = loadXML(addr, myVars, true);
		if (xmlDoc != null) {
			var xmlretval = getNodeTextContent(xmlDoc.getElementsByTagName('returnvalue')[0]);
			if (xmlretval == "true") {
				document.location.href = document.location.href;
			} else if (xmlretval == "false") {
				var res = getFailedReturnValue(xmlDoc);
				var msgHandler = new XMLMessageHandler();
				msgHandler.handleMessages(res);
			}
		}
	}
}

removeFavoriteMember = getAddRemoveFavFunc("/_services/users/removeFavoriteMember", "userid");
removeFavoriteClub = getAddRemoveFavFunc("/_services/clubs/removeFavoriteClub", "clubid");









function LinkVisitListener(et, linksrenderer) {
	this.et = et;
	linksrenderer.addVisitLinkListener(this);
	
	this.linkVisitRequested = function(linkid) {
		loadXMLDoc(this.et.gURL("out"), true, "linkid=" + linkid, this.getOutListener());
		return false;
	}
	
	this.getOutListener = function() {
		return function(req) {
			if (req.readyState == 4) {
				var xmlDoc = req.responseXML;
				if (xmlDoc != null) {
					var xmlretval = getNodeTextContent(xmlDoc.getElementsByTagName('returnvalue')[0]);
					if (xmlretval == "false") {
						var res = getFailedReturnValue(xmlDoc);
						var msgHandler = new XMLMessageHandler();
						msgHandler.handleMessages(res);
					}
				}
			}
		}
	}
}


function ReferLinkVisitListener(et, linksrenderer) {
	this.et = et;
	this.linksrenderer = linksrenderer;
	linksrenderer.addVisitLinkListener(this);
	
	this.linkVisitRequested = function(linkid) {
		var objLink = this.linksrenderer.getLinkById(linkid);
		if (initVars.get("e_pl").toLowerCase() == "private" || objLink.getPrivacyLevelName().toLowerCase() == "private") {
			var myVarTable = new VarTable();
			myVarTable.add("url", objLink.getUrl());
			var frm = getDForm(myVarTable, "http://www." + initVars.get("DNAME") + "/refer", "post");
			frm.target = "_blank";
			frm.submit();
			return true; //asks for preventDefault
		} else {
			return false;
		}
	}
}









































function EntityInit() {
	checkanchor(true); //strSortBy
	var requesterid = initVars.get("requesterid");
	var entityid = initVars.get("e_id");
	var myurl = initVars.get("myurl");
	var arrTagIds = new Array();
	var numTopTags = initVars.get("num_top_tags");
	var tid = initVars.get("tagid");
	if (tid != null) {
		arrTagIds.push(tid);
	}
	var arrFolderIds = new Array();
	var fid = initVars.get("folderid");
	if (fid != null) {
		arrFolderIds.push(fid);
	} else {
		fid = 0;
	}
	var q = initVars.get("q"); if (q == null) q = "";
	var TheLinksRenderer = initVars.get("LR");
	var acclvl = initVars.get("acclvl"); if (acclvl == "friends") acclvl = "members";
	
	this.mTagsManager = new TagsManager(this, requesterid, entityid);
	this.mFoldersManager = new FoldersManager(this, requesterid, entityid, fid);
	this.mLinksManager = new LinksManager(this, requesterid, entityid, arrTagIds, arrFolderIds, q, initVars.get("links_per_page"), initVars.get("pagenumber"), strSortBy, this.mTagsManager, this.mFoldersManager);
	
	this.mTagsRenderer = new CloudTagsRenderer(this.mTagsManager, "objTags", "objTagFilter", numTopTags);
	this.mFoldersRenderer = new TreeFoldersRenderer(this.mFoldersManager, "objFolders", fid, (acclvl=="private"));
	this.mLinksRenderer = new TheLinksRenderer(this, this.mLinksManager, this.mFoldersManager, "objLinks", "objLinksPages", acclvl);
	
	arrTagsTabs = new Array("objTabAllTags", "objTabTopTags");
	myShowAllTagsTabHandler = new TagsTabHandler(arrTagsTabs, 0, this.mTagsRenderer, 0, "activetab", "");
	myShowTopTagsTabHandler = new TagsTabHandler(arrTagsTabs, 1, this.mTagsRenderer, numTopTags, "activetab", "");
	
	arrLinksTabs = new Array("objTabTopRatedLinks", "objTabNewestLinks", "objTabLastVisitedLinks", "objTabMostVisitedLinks");
	myShowTopRatedLinksTabHandler = new LinksTabHandler(arrLinksTabs, 0, "TopRated", strSortBy, this.mLinksRenderer, "activetab", "");
	myShowNewestLinksTabHandler = new LinksTabHandler(arrLinksTabs, 1, "Newest", strSortBy, this.mLinksRenderer, "activetab", "");
	myShowLastVisitedLinksTabHandler = new LinksTabHandler(arrLinksTabs, 2, "LastVisited", strSortBy, this.mLinksRenderer, "activetab", "");
	myShowMostVisitedLinksTabHandler = new LinksTabHandler(arrLinksTabs, 3, "MostVisited", strSortBy, this.mLinksRenderer, "activetab", "");
	arrLinkTabObjs = [myShowTopRatedLinksTabHandler, myShowNewestLinksTabHandler, myShowLastVisitedLinksTabHandler, myShowMostVisitedLinksTabHandler];
	
	allHandlers = new Array();
	if (acclvl == "private") {
		allHandlers.push(new AddFolderHandler(this, requesterid, entityid, this.mFoldersManager, this.mFoldersRenderer));
		allHandlers.push(new EditFolderHandler(this, requesterid, entityid, this.mFoldersManager, this.mFoldersRenderer));
		allHandlers.push(new DeleteFoldersHandler(this, requesterid, entityid, this.mFoldersManager, this.mFoldersRenderer));
		allHandlers.push(new EditFoldersHandler(this, requesterid, entityid, this.mFoldersManager, this.mFoldersRenderer));
		allHandlers.push(new AddLinkHandler(this, requesterid, entityid, this.mTagsRenderer, this.mFoldersRenderer, this.mLinksRenderer, "addlink_tags_4", arrLinkTabObjs));
		allHandlers.push(new EditLinkHandler(this, requesterid, entityid, this.mTagsRenderer, this.mFoldersRenderer, this.mLinksRenderer, "editlink_tags_4", arrLinkTabObjs));
		allHandlers.push(new DeleteLinksHandler(this, requesterid, entityid, this.mTagsRenderer, this.mLinksRenderer, arrLinkTabObjs));
		allHandlers.push(new EditLinksHandler(this, requesterid, entityid, this.mTagsRenderer, this.mFoldersRenderer, this.mLinksRenderer, "editlinks_tags_4", arrLinkTabObjs));
		new RateLinkHandler(this, requesterid, this.mLinksManager, this.mLinksRenderer);
		if (!this.handleAllLinkVisits()) new LinkVisitListener(this, this.mLinksRenderer);
	}
	if (this.handleAllLinkVisits()) new LinkVisitListener(this, this.mLinksRenderer);
	new ReferLinkVisitListener(this, this.mLinksRenderer);
	if (acclvl == "members" || (acclvl == "private" && this.hasCopyLinkInPrivate())) {
		var etUser = new EntityUser();
		requesterFoldersManager = new FoldersManager(etUser, requesterid, requesterid, 0);
		requesterFoldersManager.loadFolders(initVars.get("xml_folders_req"));
		requesterFoldersRenderer = new TreeFoldersRenderer(requesterFoldersManager, "objFolders", 0, false);
		allHandlers.push(new CopyLinkHandler(etUser, requesterid, requesterid, requesterFoldersRenderer, this.mLinksRenderer, "copylink_tags_4", arrLinkTabObjs));
	}
	for (var i=0;i<allHandlers.length;i++) allHandlers[i].setOtherHandlers(allHandlers);
	
	this.mTagsRenderer.loadTags(initVars.get("xml_tags"));
	this.mFoldersRenderer.loadFolders(initVars.get("xml_folders"));
	this.mLinksRenderer.loadLinks(initVars.get("xml_links"));
	if (acclvl == "public") {
		document.getElementById("objFolders").style.display = "block";
		document.getElementById("objTags").style.display = "block";
		document.getElementById("objLinks").style.display = "block";
	}
}

function EntityUser() {
	this.mTagsManager = null;
	this.mFoldersManager = null;
	this.mLinksManager = null;
	this.mTagsRenderer = null;
	this.mFoldersRenderer = null;
	this.mLinksRenderer = null;
	
	this.init = EntityInit;
	
	this.getTagsManager = function() {
		return this.mTagsManager;
	}
	
	this.getLinksManager = function() {
		return this.mLinksManager;
	}
	
	this.getLinksRenderer = function() {
		return this.mLinksRenderer;
	}

	this.getTagsRenderer = function() {
		return this.mTagsRenderer;
	}
	
	this.gFN = function(arg) {
		switch (arg) {
			case "entityid": return "userid";
			case "folder": return "userfolder";
			case "folderid": return "userfolderid";
			case "foldername": return "userfoldername";
			case "parentfolderid": return "parentuserfolderid";
			case "linkid": return "userlinkid";
			default: alert("gFN: " + arg); return "";
		}
	}
	
	this.gURL = function(arg) {
		switch (arg) {
			case "getLinks": return "/_services/users/getUserLinks";
			case "getTags": return "/_services/users/getUserTags";
			case "getFolders": return "/_services/users/getUserFolders";
			case "addFolder": return "/_services/users/addUserFolder";
			case "editFolder": return "/_services/users/editUserFolder";
			case "editFolders": return "/_services/users/editUserFolders";
			case "deleteFolders": return "/_services/users/deleteUserFolders";
			case "addLink": return "/_services/users/addUserLink";
			case "editLink": return "/_services/users/editUserLink";
			case "deleteLinks": return "/_services/users/deleteUserLinks";
			case "editLinks": return "/_services/users/editUserLinks";
			case "rateLink": return "/_services/users/rateUserLink";
			case "out": return "/_services/users/out";
			default: alert("gURL: " + arg); return "";
		}
	}
	
	this.hasPrivacyLevel = function() {
		return true;
	}
	
	this.hasCopyLinkInPrivate = function() {
		return false;
	}
	
	this.canEditRating = function() {
		return true;
	}
	
	this.handleAllLinkVisits = function() {
		return false;
	}
	
}

function EntityClub() {
	this.mTagsManager = null;
	this.mFoldersManager = null;
	this.mLinksManager = null;
	this.mTagsRenderer = null;
	this.mFoldersRenderer = null;
	this.mLinksRenderer = null;
	
	this.init = EntityInit;
	
	this.getTagsManager = function() {
		return this.mTagsManager;
	}
	
	this.getLinksManager = function() {
		return this.mLinksManager;
	}
	
	this.getLinksRenderer = function() {
		return this.mLinksRenderer;
	}
	
	this.getTagsRenderer = function() {
		return this.mTagsRenderer;
	}
	
	this.gFN = function(arg) {
		switch (arg) {
			case "entityid": return "clubid";
			case "folder": return "clubfolder";
			case "folderid": return "clubfolderid";
			case "foldername": return "clubfoldername";
			case "parentfolderid": return "parentclubfolderid";
			case "linkid": return "clublinkid";
			default: alert("gFN: " + arg); return "";
		}
	}
	
	this.gURL = function(arg) {
		switch (arg) {
			case "getLinks": return "/_services/clubs/getClubLinks";
			case "getTags": return "/_services/clubs/getClubTags";
			case "getFolders": return "/_services/clubs/getClubFolders";
			case "addFolder": return "/_services/clubs/addClubFolder";
			case "editFolder": return "/_services/clubs/editClubFolder";
			case "editFolders": return "/_services/clubs/editClubFolders";
			case "deleteFolders": return "/_services/clubs/deleteClubFolders";
			case "addLink": return "/_services/clubs/addClubLink";
			case "editLink": return "/_services/clubs/editClubLink";
			case "deleteLinks": return "/_services/clubs/deleteClubLinks";
			case "editLinks": return "/_services/clubs/editClubLinks";
			case "rateLink": return "/_services/clubs/rateClubLink";
			case "out": return "/_services/clubs/out";
			default: alert("gURL: " + arg); return "";
		}
	}
	
	this.hasPrivacyLevel = function() {
		return false;
	}
	
	this.hasCopyLinkInPrivate = function() {
		return true;
	}
	
	this.canEditRating = function() {
		return false;
	}
	
	this.handleAllLinkVisits = function() {
		return true;
	}
	
}










function LinksManager(et, requesterid, entityid, arrtagids, arrfolderids, q, linksperpage, pageindex, orderby, tagsmanager, foldersmanager) {
	this.et = et;
	this.requesterid = requesterid;
	this.entityid = entityid;
	this.links = null;
	this.linksperpage = linksperpage;
	this.pageindex = pageindex;
	if (orderby.length == 0) {
		this.orderby = initVars.get("default_sort");
		this.defaultSort = true;
	} else {
		this.orderby = orderby;
		this.defaultSort = false;
	}
	this.tagsmanager = tagsmanager;
	this.foldersmanager = foldersmanager;
	this.arrtagids = arrtagids;
	this.arrfolderids = arrfolderids;
	this.q = q;
	
	this.loadLinks = function(strXML) {
		if (strXML.length > 0 && initVars.get("default_sort") != this.orderby) {
			//reload needed
			strXML = "";
		}
		var res = this.dlLinks(this.arrtagids, this.arrfolderids, this.q, this.linksperpage, this.pageindex, this.orderby, strXML);
		if (res && res.get("returnvalue")) {
			this.links = res.get("links");
		} else {
			this.msgHandler = new XMLMessageHandler();
			this.msgHandler.handleMessages(res);
		}
	}
	
	this.dlLinks = function(arrtagids, arrfolderids, q, linkcount, pageIndex, orderby, strXML) {
		var myVars = new VarTable();
		myVars.add("requesterid", this.requesterid);
		myVars.add(this.et.gFN("entityid"), this.entityid);
		myVars.add("linkcount", linkcount);
		myVars.add("page", pageIndex);
		myVars.add("orderby", orderby);
		for (var i=0;i<arrtagids.length;i++) {
			myVars.add("tagids[" + i + "]", arrtagids[i]);
		}
		for (var i=0;i<arrfolderids.length;i++) {
			myVars.add("folderids[" + i + "]", arrfolderids[i]);
		}
		myVars.add("q", q);
		var xmlDoc;
		if (strXML.length == 0) {
			xmlDoc = loadXML(this.et.gURL("getLinks"), myVars, true);
		} else {
			xmlDoc = loadXMLFromString(strXML);
		}
		if (xmlDoc != null) {
			var xmlretval = getNodeTextContent(xmlDoc.getElementsByTagName('returnvalue')[0]);
			if (xmlretval == "true") {
				var retvalLinks = new Links();
				var linksNode = xmlDoc.getElementsByTagName('links')[0];
				retvalLinks.totalLinkCount = parseInt(getNodeTextContent(linksNode.attributes.getNamedItem("totalLinkCount")));
				for (var i=0;i<linksNode.childNodes.length;i++) {
					if (linksNode.childNodes[i].nodeType == 1) {
						var linkid = getNodeTextContent(linksNode.childNodes[i].getElementsByTagName("id")[0]);
						var linktitle = getNodeTextContent(linksNode.childNodes[i].getElementsByTagName("title")[0]);
						var linkdescription = getNodeTextContent(linksNode.childNodes[i].getElementsByTagName("description")[0]);
						var linkurl = getNodeTextContent(linksNode.childNodes[i].getElementsByTagName("url")[0]);
						var rating = getNodeTextContent(linksNode.childNodes[i].getElementsByTagName("rating")[0]);
						var privacylevelid = getNodeTextContent(linksNode.childNodes[i].getElementsByTagName("privacylevel")[0]);
						var privacylevelname = getNodeTextContent(linksNode.childNodes[i].getElementsByTagName("privacylevel")[0].attributes.getNamedItem("name"));
						var languageid = getNodeTextContent(linksNode.childNodes[i].getElementsByTagName("languageid")[0]);
						var linkexplicit = getNodeTextContent(linksNode.childNodes[i].getElementsByTagName("explicit")[0]);
						linkexplicit = (linkexplicit == "true");
						
						var ssIndex = 1;
						var myShots = new VarTable();
						while (linksNode.childNodes[i].getElementsByTagName("url")[0].attributes.getNamedItem("s" + ssIndex) != null) {
							myShots.add("screenshot" + ssIndex, getNodeTextContent(linksNode.childNodes[i].getElementsByTagName("url")[0].attributes.getNamedItem("s" + ssIndex)));
							ssIndex++;
						}
						
						var linkfolderid = getNodeTextContent(linksNode.childNodes[i].getElementsByTagName("folderid")[0]);
						
						var tagsNode = linksNode.childNodes[i].getElementsByTagName('tags')[0];
						var j=0;
						var arrTagStrings = new Array();
						for (j=0;j<tagsNode.childNodes.length;j++) {
							if (tagsNode.childNodes[j].nodeType == 1) {
								arrTagStrings.push(getNodeTextContent(tagsNode.childNodes[j]));
							}
						}
						
						retvalLinks.add(new Link(linkid, linktitle, linkdescription, linkurl, linkfolderid, arrTagStrings, rating, linkexplicit, privacylevelid, privacylevelname, languageid, myShots));
					}
				}
				var retval = new VarTable();
				retval.add("returnvalue", true);
				retval.add("links", retvalLinks);
				return retval;
			} else if (xmlretval == "false") {
				return getFailedReturnValue(xmlDoc);
			} else {
				return null;
			}
		} else {
			return null;
		}
	}
	
	this.getLinks = function() {
		return this.links;
	}
	
	this.getLinksPerPage = function() {
		return parseInt(this.linksperpage);
	}
	
	this.getPageIndex = function() {
		return parseInt(this.pageindex);
	}
	
	this.changePage = function(pageindex) {
		this.pageindex = pageindex;
		this.loadLinks("");
	}
	
	this.changeOrderBy = function(orderby) {
		this.defaultSort = false;
		this.orderby = orderby;
		this.loadLinks("");
	}
	
	this.useDefaultSort = function() {
		return this.defaultSort;
	}
	
	this.getSortName = function() {
		return this.orderby;
	}
	
	this.moveLinksByIds = function(linkids, parentid) {
		for (var i=0;i<linkids.length;i++) {
			this.links.getLinkById(linkids[i]).setFolderId(parentid);
		}
	}
	
}












function TagsManager(et, requesterid, entityid) {
	this.et = et;
	this.requesterid = requesterid;
	this.entityid = entityid;
	this.tags = null;
	this.poststring = "";
	
	this.getTags = function() {
		return this.tags;
	}
	
	this.getTagById = function(tagid) {
		return this.tags.getTagById(tagid);
	}
	
	this.getSubSet = function(objrenderer, tagcount, filter) {
		if (this.tmrTags != null) clearTimeout(this.tmrTags);
		var needUpdate = true;
		if ((this.tags.count == 0 && this.tags.filter.length == 0) || (this.tags.count == this.tags.totalCount)) {
			needUpdate = false;
		} else if (filter.toLowerCase().beginsWith(this.tags.filter.toLowerCase()) && (this.tags.count == 0 || this.tags.count == this.tags.totalCount)) {
			needUpdate = false;
		} else if (filter.toLowerCase() == this.tags.filter.toLowerCase() && (tagcount != 0 && this.tags.count >= tagcount)) {
			needUpdate = false;
		}
		if (needUpdate) {
			var myVars = new VarTable();
			myVars.add("requesterid", this.requesterid);
			myVars.add(this.et.gFN("entityid"), this.entityid);
			myVars.add("count", tagcount);
			myVars.add("filter", filter);
			this.poststring = myVars.getURLEncodedString();
			var jobname = AsyncTagsManager.addJob(this, objrenderer);
			this.tmrTags = setTimeout("AsyncTagsManager.execJob('" + jobname + "');", 750);
			return null;
		} else {
			return this.tags.getSubSet(tagcount, filter);
		}
	}
	
	this.startAsyncLoad = function(objrenderer) {
		loadXMLDoc(this.et.gURL("getTags"), true, this.poststring, this.getLoadTagsListener(this, objrenderer));
	}
	
	this.getLoadTagsListener = function(objmanager, objrenderer) {
		return function(req) {
			if (req.readyState == 4) {
				objmanager.loadTags(req.responseText);
				objrenderer.render();
			}
		}
	}
	
	this.loadTags = function(strXML, argCount, argFilter) {
		if (this.tags != null && strXML.length == 0 && (typeof argCount == "undefined") && (typeof argFilter == "undefined")) {
			//refresh after "add link" etc.
			if (this.tags.totalCount <= initVars.get("MTAGS_BA")) {
				argCount = 0;
				argFilter = "";
			} else {
				argCount = this.tags.count;
				argFilter = this.tags.filter;
			}
		} else {
			if (typeof argCount == "undefined") argCount = 0;
			if (typeof argFilter == "undefined") argFilter = "";
		}
		var res = this.dlTags(strXML, argCount, argFilter);
		if (res != null) {
			if (res.get("returnvalue")) {
				this.tags = res.get("tags");
			} else {
				this.msgHandler = new XMLMessageHandler();
				this.msgHandler.handleMessages(res);
			}
		}
	}
	
	this.dlTags = function(strXML, argCount, argFilter) {
		if (typeof argCount == "undefined") argCount = 0;
		if (typeof argFilter == "undefined") argFilter = "";
		var myVars = new VarTable();
		myVars.add("requesterid", this.requesterid);
		myVars.add(this.et.gFN("entityid"), this.entityid);
		myVars.add("count", argCount);
		myVars.add("filter", argFilter);
		var xmlDoc;
		if (strXML.length == 0) {
			xmlDoc = loadXML(this.et.gURL("getTags"), myVars, true);
		} else {
			xmlDoc = loadXMLFromString(strXML);
		}
		if (xmlDoc != null) {
			var xmlretval = getNodeTextContent(xmlDoc.getElementsByTagName('returnvalue')[0]);
			if (xmlretval == "true") {
				var tagsNode = xmlDoc.getElementsByTagName('tags')[0];
				var retvalTags = new Tags(getNodeTextContent(tagsNode.attributes.getNamedItem("count")), getNodeTextContent(tagsNode.attributes.getNamedItem("totalCount")), getNodeTextContent(tagsNode.attributes.getNamedItem("filter")));
				for (var i=0;i<tagsNode.childNodes.length;i++) {
					if (tagsNode.childNodes[i].nodeType == 1) {
						var tagid = getNodeTextContent(tagsNode.childNodes[i].attributes.getNamedItem("id"));
						var tag = getNodeTextContent(tagsNode.childNodes[i].attributes.getNamedItem("tag"));
						var usagecount = getNodeTextContent(tagsNode.childNodes[i].attributes.getNamedItem("n"));
						retvalTags.add(new Tag(tagid, tag, usagecount));
					}
				}
				var retval = new VarTable();
				retval.add("returnvalue", true);
				retval.add("tags", retvalTags);
				return retval;
			} else if (xmlretval == "false") {
				return getFailedReturnValue(xmlDoc);
			} else {
				return null;
			}
		} else {
			return null;
		}
	}
}








function FoldersManager(et, requesterid, entityid, activeFolderId) {
	this.et = et;
	this.requesterid = requesterid;
	this.entityid = entityid;
	this.folders = null;
	this.activeFolderId = activeFolderId;
	
	this.loadFolders = function(strXML) {
		var res = this.dlFolders(strXML);
		if (res && res.get("returnvalue")) {
			this.folders = res.get("folders");
			this.showActiveFolder();
		} else {
			this.msgHandler = new XMLMessageHandler();
			this.msgHandler.handleMessages(res);
		}
	}
	
	this.dlFolders = function(strXML) {
		var myVars = new VarTable();
		myVars.add("requesterid", this.requesterid);
		myVars.add(this.et.gFN("entityid"), this.entityid);
		var xmlDoc;
		if (strXML.length == 0) {
			xmlDoc = loadXML(this.et.gURL("getFolders"), myVars, true);
		} else {
			xmlDoc = loadXMLFromString(strXML);
		}
		if (xmlDoc != null) {
			var xmlretval = getNodeTextContent(xmlDoc.getElementsByTagName('returnvalue')[0]);
			if (xmlretval == "true") {
				var retvalFolders = new Folders();
				var foldersNode = xmlDoc.getElementsByTagName('folders')[0];
				var i=0;
				for (i=0;i<foldersNode.childNodes.length;i++) {
					if (foldersNode.childNodes[i].nodeType == 1) {
						var folderid = getNodeTextContent(foldersNode.childNodes[i].attributes.getNamedItem("id"));
						var foldername = getNodeTextContent(foldersNode.childNodes[i].attributes.getNamedItem("name"));
						var parentfolderid = getNodeTextContent(foldersNode.childNodes[i].attributes.getNamedItem("parentid"));
						retvalFolders.initAdd(new Folder(folderid, foldername, parentfolderid));
					}
				}
				retvalFolders.afterInitAdd();
				var retval = new VarTable();
				retval.add("returnvalue", true);
				retval.add("folders", retvalFolders);
				return retval;
			} else if (xmlretval == "false") {
				return getFailedReturnValue(xmlDoc);
			} else {
				return null;
			}
		} else {
			return null;
		}
	}
	
	this.showActiveFolder = function() {
		if (this.activeFolderId > 0) {
			var folder = this.folders.getFolderById(this.activeFolderId);
			if (folder != null) {
				var curFolder = folder;
				do {
					curFolder = curFolder.getParent();
					if (curFolder != null) curFolder.openFolder();
				} while (curFolder != null);
			}
		}
	}
	
	this.getFolders = function() {
		return this.folders;
	}
	
	this.addFolder = function(folderid, foldername, parentid) {
		this.folders.add(new Folder(folderid, foldername, parentid));
		if (parentid == 0) {
			this.folders.sortByName(true);
		} else {
			var parentFolder = this.folders.getFolderById(parentid);
			if (parentFolder != null) parentFolder.sortByName(true);
		}
	}
	
	this.editFolder = function(folderid, parentid, newname) {
		var objFolder = this.folders.getFolderById(folderid);
		if (objFolder != null) {
			objFolder.setName(newname);
			this.moveFoldersByIds([folderid], parentid);
			var parentFolder = objFolder.getParent();
			if (parentFolder != null) {
				parentFolder.sortByName(true);
			} else {
				this.folders.sortByName(true);
			}
		}
	}
	
	this.deleteFoldersByIds = function(arrIds) {
		this.folders.deleteFoldersByIds(arrIds);
	}
	
	this.moveFoldersByIds = function(arrIds, parentid) {
		this.folders.moveFoldersByIds(arrIds, parentid);
	}
}




var AsyncTagsManager = {

	myJobs : {
	},
	randomName : function() {
		var strChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; //only chars that don't need js escaping ...
		var retval = "";
		for (var i=0;i<8;i++) {
			var rnum = Math.floor(Math.random() * strChars.length);
			retval += strChars.substr(rnum, 1);
		}
		return retval;
	},
	getNextJobName : function() {
		var aname = this.randomName();
		while (typeof this.myJobs[aname] != "undefined") {
			aname = this.randomName();
		}
		return aname;
	},
	addJob : function(tagsmanager, tagsrenderer) {
		var jobname = this.getNextJobName();
		this.myJobs[jobname] = [tagsmanager, tagsrenderer];
		return jobname;
	},
	execJob : function(jobname) {
		var thejob = this.myJobs[jobname];
		if (typeof thejob != "undefined") {
			thejob[0].startAsyncLoad(thejob[1]);
			delete this.myJobs[jobname];
		}
		thejob = null;
	}
}

function GetCookie(name) {
	var arg = name + "=";
	var alen = arg.length;
	var clen = document.cookie.length;
	var i = 0;
	while (i < clen) {
		var j = i + alen;
		if (document.cookie.substring(i, j) == arg) return getCookieVal (j);
		i = document.cookie.indexOf(" ", i) + 1;
		if (i == 0) break;
	}
	return null;
}

function getCookieVal(offset) {
	var endstr = document.cookie.indexOf (";", offset);
	if (endstr == -1) endstr = document.cookie.length;
	return unescape(document.cookie.substring(offset, endstr));
}