// Sidebar Writer //
String.prototype.replaceAll = function(s1, s2) {return this.split(s1).join(s2)};
var clfSizeForFolding = 130;

function CLFSidebarWriter(htmlElement) {
	this.lastCategID = null;
	this.root = htmlElement;
	this.place4instances = null;
	this.findTags = /<\/?[a-zA-Z0-9_\.-]+\s*[^>]*?\/?>/g;
	this.findSpaces = /[\s\n\t\r_]+/g;
}

CLFSidebarWriter.prototype.addCategory = function(categName, categID) {
	var niceCategName = categName.addSpaces();
	var categClass = _clfResult.isTerm(categName)?"CLFSBAnyTerm":"CLFSBAnyEvent";
	categClass += " CLFSBCateg CLFSBCateg" + categName;
	var sidebarElm = new SidebarElement(categID, "-1", categClass);
	sidebarElm.addCMD_ToggleVisibility();
	sidebarElm.addCMD_Highlight();
	sidebarElm.addText(niceCategName);
	this.root.appendChild(sidebarElm.getElement());
	var div = document.createElement("div");
	div.className = "CLFSBInstances";
	div.id = "CLFSBInstances" + categID;
	this.root.appendChild(div);
	this.lastCategID = categID;
	this.place4instances = div;
}

CLFSidebarWriter.prototype.addTopic = function(topicName, topicScore) {
	var sidebarElement = new SidebarElement('topic', "-1", 'CLFSBTopic');
	sidebarElement.addText(topicName.replace(this.findSpaces, ' '), "CLFSBTopicTXT");
	if (!behavior.hideTopicsScore)
		sidebarElement.addText(topicScore + "%", "CLFSBTopicPRC");
	this.root.appendChild(sidebarElement.getElement());
}

CLFSidebarWriter.prototype.addSocialTag = function(stName, stScore) {
	var stName = stName.replace(this.findSpaces, ' ');
	var sidebarElement = new SidebarElement('socialtag', "-1", 'CLFSBSocialTag');
	sidebarElement.addText(stName.replace(this.findSpaces, ' '), "CLFSBSocialTagTXT");
	if (!behavior.hideSocialTagsStars)
		sidebarElement.addImage(_imagePath + "/ST" + stScore + ".gif", "CLFSBSocialTagIMG");
	this.root.appendChild(sidebarElement.getElement());
}

CLFSidebarWriter.prototype.addTerm = function(termName, termIndex) {
	var sidebarElm = new SidebarElement(this.lastCategID, termIndex, "CLFSBTerm");
	sidebarElm.addCMD_Feedback();
	sidebarElm.addCMD_Highlight();
	sidebarElm.addClickableText();
	this.place4instances.appendChild(sidebarElm.getElement());
}

CLFSidebarWriter.prototype.addRelation = function(relationName, relationIndex) {
	var sidebarElm = new SidebarElement(this.lastCategID, relationIndex, "CLFSBFrame");
	if (behavior.showAllAtributes)
		sidebarElm.content.style.overflow = "visible";
	sidebarElm.addCMD_Feedback();
	sidebarElm.addCMD_Highlight();
	sidebarElm.addClickableText();
	this.place4instances.appendChild(sidebarElm.getElement());
}

CLFSidebarWriter.prototype.addHeader = function(nameHeader, isTerm) {
	var sidebarElm = new SidebarElement("-1", "-1", "CLFSBHeader");
	sidebarElm.addText(nameHeader, "CLFSBHeaderCaption");
	if (isTerm != null)
	    sidebarElm.addCMD_HighlightAllNone(isTerm);
	this.root.appendChild(sidebarElm.getElement());
}

// Sidebar Element //

function SidebarElement(categID, instanceID, className) {
	this.categID = categID;
	this.instanceID = instanceID;
	this.root = document.createElement("div");
	this.root.className = className;
	this.content = document.createElement("div");
	this.root.appendChild(this.content);
	this.findTags = /<\/?[a-zA-Z0-9_\.-]+\s*[^>]*?\/?>/g;
	this.findSpaces = /[\s\n\t\r_]+/g;
}

SidebarElement.prototype.addCMD_Highlight = function() {
	var highlightCMD = document.createElement("input");
	highlightCMD.type = "image";
	highlightCMD.className = "checkboxIcon";
	highlightCMD.id = "CLFSideBar." + this.categID + "." + this.instanceID;
	highlightCMD.setAttribute("categID", this.categID);
	highlightCMD.setAttribute("instanceID", this.instanceID);
	highlightCMD.src = _imagePath + "/V.gif";
	if (highlightCMD.attachEvent) {// IE
		highlightCMD.attachEvent("onclick", function(e) {changeHighlight(e.srcElement.src.charAt(e.srcElement.src.length - 5) != "V", e.srcElement.categID, e.srcElement.instanceID);} );	
	} else { // Firefox
		highlightCMD.setAttribute("onclick", "changeHighlight(this.src.charAt(this.src.length - 5) != 'V', " + this.categID + ", " + this.instanceID + ");");
	}
	this.content.appendChild(highlightCMD);
}

SidebarElement.prototype.addCMD_Feedback = function() {
	if (behavior == null || !behavior.feedbak)
		return;
	if (!document['feedbacksupported'])
		return;
	if (_feedbackFlavor > 0) {
		var feedbackPositiveCMD = document.createElement("input");
		feedbackPositiveCMD.type = "image";
		feedbackPositiveCMD.className = "checkboxIcon";
		feedbackPositiveCMD.id = "CLFSideBarFB-Yes." + this.categID + "." + this.instanceID;
		feedbackPositiveCMD.setAttribute("categID", this.categID);
		feedbackPositiveCMD.setAttribute("instanceID", this.instanceID);
		feedbackPositiveCMD.src = _imagePath + "/yes_dimed_tiny.gif";
		if (feedbackPositiveCMD.attachEvent) {// IE
			feedbackPositiveCMD.attachEvent("onclick", function(e) { sendfeedback(true, e.srcElement.id, e.srcElement.categID); });
			feedbackPositiveCMD.attachEvent("onmouseover", function(e) { e.srcElement.src = _imagePath + "/yes_tiny.gif"; });
			feedbackPositiveCMD.attachEvent("onmouseout", function(e) { fixFBIconState(e.srcElement.id); });
		} else { // Firefox
			feedbackPositiveCMD.setAttribute("onclick", "sendfeedback(true, this.id , " + this.categID + ");");
			feedbackPositiveCMD.setAttribute("onmouseover", "this.src='" + _imagePath + "/yes_tiny.gif';");
			feedbackPositiveCMD.setAttribute("onmouseout", "fixFBIconState(this.id);");

		}
		this.root.appendChild(feedbackPositiveCMD);
		var feedbackNegativeCMD = document.createElement("input");
		feedbackNegativeCMD.type = "image";
		feedbackNegativeCMD.className = "checkboxIcon";
		feedbackNegativeCMD.id = "CLFSideBarFB-No." + this.categID + "." + this.instanceID;
		feedbackNegativeCMD.setAttribute("categID", this.categID);
		feedbackNegativeCMD.setAttribute("instanceID", this.instanceID);
		feedbackNegativeCMD.src = _imagePath + "/no_dimed_tiny.gif";
		if (feedbackNegativeCMD.attachEvent) {// IE
			if (_feedbackFlavor == 1) {
				feedbackNegativeCMD.attachEvent("onclick", function(e) { sendfeedback(false, e.srcElement.id, e.srcElement.categID); });
			} else if (_feedbackFlavor >= 2) {
				var tooltipTxt = [];
				tooltipTxt.push("<div><b>Feedback</b>");
				tooltipTxt.push("<br>Comment:<br>");
				tooltipTxt.push("<textarea id='" + feedbackNegativeCMD.id + ".comment'></textarea><br>");
				if (_feedbackFlavor >= 3) {
					tooltipTxt.push("<br>Priority:<br>");
					tooltipTxt.push("<select id='" + feedbackNegativeCMD.id + ".priority'>");
					tooltipTxt.push("<option><option>Blocker<option>Critical<option>Major<option>Minor<option>Trivial");
					tooltipTxt.push("</select><br>");
					tooltipTxt.push("<br>Problem Type:<br>");
					tooltipTxt.push("<select id='" + feedbackNegativeCMD.id + ".feedbackType'>");
					tooltipTxt.push(_getOptions(_feedbackTypes));
					tooltipTxt.push("</select><br>");
					tooltipTxt.push("<br>Test Type:<br>");
					tooltipTxt.push("<select id='" + feedbackNegativeCMD.id + ".testType'>");
					tooltipTxt.push(_getOptions(_testType));
					tooltipTxt.push("</select><br>");
					tooltipTxt.push("<br>Regression:<br>");
					tooltipTxt.push("<select id='" + feedbackNegativeCMD.id + ".regression'>");
					tooltipTxt.push(_getOptions(_regression));
					tooltipTxt.push("</select><br>");

				}
				tooltipTxt.push("<input value='Send' type='button' onclick='sendfeedback(false,\"" + feedbackNegativeCMD.id + "\",\"" + this.categID + "\");clf_tolltip.callinern(\"tt_HideInit()\");'>");
				tooltipTxt.push("<input value='Close' type='button' onclick='clf_tolltip.callinern(\"tt_HideInit()\");'>");
				tooltipTxt.push("</div>")
				feedbackNegativeCMD.attachEvent("onclick", function(e) { clf_tolltip.gentip(tooltipTxt.join(''), STICKY, true, false, true, ABOVE, false, OFFSETY, 0); });
			}
			feedbackNegativeCMD.attachEvent("onmouseover", function(e) { e.srcElement.src = _imagePath + "/no_tiny.gif"; });
			feedbackNegativeCMD.attachEvent("onmouseout", function(e) { fixFBIconState(e.srcElement.id); });
		} else { // Firefox
			if (_feedbackFlavor == 1) {
				feedbackNegativeCMD.setAttribute("onclick", "sendfeedback(false, this.id , " + this.categID + ");");
			} // option 2 if needed

			feedbackNegativeCMD.setAttribute("onclick", "sendfeedback(false, this.id , " + this.categID + ");");
			feedbackNegativeCMD.setAttribute("onmouseout", "fixFBIconState(this.id);");
		}
		this.root.appendChild(feedbackNegativeCMD);
	}
}

SidebarElement.prototype.addCMD_ToggleVisibility = function() {
	var toggleVisibilityCMD = document.createElement("input");
	toggleVisibilityCMD.type = "image";
	toggleVisibilityCMD.src = _imagePath + "/collapsesmall.gif";
	toggleVisibilityCMD.className = "collapseExpandIcon";
	toggleVisibilityCMD.id = "toggleVisibilityImage" + this.categID;
	if (toggleVisibilityCMD.attachEvent) {// IE
		toggleVisibilityCMD.setAttribute("categID", this.categID);
		toggleVisibilityCMD.attachEvent("onclick", function(e) {toggleInstancesVisibility(e.srcElement.categID);} );	
	} else { // Firefox
		toggleVisibilityCMD.setAttribute("onclick", "toggleInstancesVisibility(" + this.categID + ");");
	}
	this.content.appendChild(toggleVisibilityCMD);
}

SidebarElement.prototype.addText = function(text, className) {
	var txt = document.createTextNode(text.unescapeHTML());
	if (className == null) {
		this.content.appendChild(txt);
		return this.content;
	}
	var txtctr = document.createElement('div');
	txtctr.className = className;
	txtctr.appendChild(txt);
	this.content.appendChild(txtctr);
	return txtctr;
}

SidebarElement.prototype.addImage = function(src, className, tooltip) {
	var img = document.createElement('img');
	img.src = src;
	if (className != null)
		img.className = className;
	if (tooltip != null)
		img.title = tooltip;
	this.root.appendChild(img);
	return img;
}

SidebarElement.prototype.addClickableText = function() {
	var categName = _clfResult.getCategs()[this.categID];
	var termName = _clfResult.getCategTerms(categName)[this.instanceID];
	var termId = _clfResult[categName][termName][0];
	var d = this.content;
	d.className = "CLFSBTextWithLink";
	if (!behavior.showAllAtributes || _clfResult.isTerm(categName)) {
		d.onmouseover = function(e) {
			var nameText = null;
			var relevanceText = null;
			if (e) { // FF
				nameText = e.target;
			} else { // IE
				nameText = event.srcElement;
			}
			if (nameText.className == "CLFSBTextWithLink")
				relevanceText = nameText.childNodes[1];
			else {
				relevanceText = nameText;
				nameText = nameText.parentNode;
			}
			nameText.style.color = "#0f9ff1";
			//if (relevanceText) relevanceText.style.color = "#ff8f8f";
			if (_clfResult.getMeta(termId)._tooltip == null)
				_clfResult.getMeta(termId)['_tooltip'] = convertTooltip2HTML(createTooltipFromMeta(_clfResult.getMeta(termId)));
			clf_tolltip.gentip(_clfResult.getMeta(termId)._tooltip, BALLOON, false, OFFSETX, 10);
		};
		d.onmouseout = function(e) {
			var nameText = null;
			var relevanceText = null;
			if (e) { // FF
				nameText = e.target;
			} else { // IE
				nameText = event.srcElement;
			}
			if (nameText.className == "CLFSBTextWithLink")
				relevanceText = nameText.childNodes[1];
			else {
				relevanceText = nameText;
				nameText = nameText.parentNode;
			}
			nameText.style.color = "";
			//if (relevanceText) relevanceText.style.color = "";
		};
	}
	d.onclick = function(e) {
		var inputElm = null;
		if (e) { // FF
			inputElm = e.target;
		} else { // IE
			inputElm = event.srcElement;
		}
		while (inputElm != null && inputElm.firstChild != null && inputElm.firstChild.className != "checkboxIcon")
			inputElm = inputElm.parentNode;
		if (inputElm != null && inputElm.firstChild != null)
			inputElm = inputElm.firstChild
		else
			return;
		var categID = inputElm.getAttribute("categID");
		var instanceID = inputElm.getAttribute("instanceID");
		var categName = _clfResult.getCategs()[categID];
		var instanceName = _clfResult.getCategTerms(categName)[instanceID];
		var firstInstanceID = _clfResult[categName][instanceName][0];
		if (behavior != null && behavior.oneclick) {
			changeHighlightAll(false);
			changeHighlight(true, categID, instanceID);
			selectID("CLFH" + firstInstanceID + ".0", true);
		} else {
			selectID("CLFH" + firstInstanceID + ".0");
		}
		if (behavior != null && behavior.freebase && categName == "PersonCareer") {
			window.open("http://sws.clearforest.com/freebasecheck/personcareer.html?company=" + encodeURIComponent(_clfResult.getMeta(firstInstanceID).company) + "&name=" + encodeURIComponent(_clfResult.getMeta(firstInstanceID).person), '_blank');
		}
		if (behavior != null && behavior.repository && _clfResult.getMeta(firstInstanceID)._url != null)
			window.open(_clfResult.getMeta(firstInstanceID)._url, '_blank');
	};
	if (_clfResult.isTerm(categName)) {
		var text = termName;
	} else {
		var text = new StringBuilder();
		if (behavior.EFDetection || behavior.showAllAtributes) {
			if (behavior.showAllAtributes) {
				var ul = document.createElement("ul");
				ul.className = "CLFSBListOfAttributesValues";
				for (var key in _clfResult.getMeta(termId)) {
					if (key.indexOf('_') != 0) {
						var li = document.createElement("li");
						li.appendChild(document.createTextNode(key + ": " + _clfResult.getMeta(termId)[key]));
						ul.appendChild(li);
					}
				}
			}
			text.Append(_clfdoc.getString(_clfResult.getMeta(termId)._offset, _clfResult.getMeta(termId)._length).replace(this.findTags, " ").replace(this.findSpaces, " ").trim());
			text.Append(', ');
		} else {
			for (var key in _clfResult.getMeta(termId)) {
				if (key.indexOf('_') != 0) {
					text.Append(_clfResult.getMeta(termId)[key]);
					text.Append(', ');
				}
			}
		}
		text.Pop();
		text = text.ToString();
	}
	if (text.length > clfSizeForFolding)
		text = text.substr(0, clfSizeForFolding - 2) + "...";
	d.appendChild(document.createTextNode(text.unescapeHTML()));
	if (!_clfResult.isTerm(categName) && behavior.showAllAtributes)
		d.appendChild(ul);
	if (_clfResult.isTerm(categName)) {
		_clfResult.getMeta(termId)._count = _clfResult[categName][termName].length;
		if (_clfResult.getMeta(termId)._relevance != null)
			this.addImage(_imagePath + "/rel" + Math.round(_clfResult.getMeta(termId)._relevance / 10) + ".gif", "CLFSBRelevanceIMG", _clfResult.getMeta(termId)._relevance + "%");
	}
}

SidebarElement.prototype.addCMD_HighlightAllNone = function(isTerm) {
	var highlightNoneCMD = document.createElement("input");
	highlightNoneCMD.type = "image";
	highlightNoneCMD.src = _imagePath + "/highlightnone.gif";
	highlightNoneCMD.title = "Clear Highlights";
	highlightNoneCMD.className = "CLFclearhighlights";
	if (isTerm)
		highlightNoneCMD.onclick = function(e) {changeHighlightByTerm(false, true);};
	else
		highlightNoneCMD.onclick = function(e) {changeHighlightByTerm(false, false);};
	var highlightAllCMD = document.createElement("input");
	highlightAllCMD.type = "image";
	highlightAllCMD.src = _imagePath + "/highlightall.gif";
	highlightAllCMD.title = "Highlight All";
	highlightAllCMD.className = "CLFhighlightsall";
	if (isTerm)
		highlightAllCMD.onclick = function(e) {changeHighlightByTerm(true, true);};	
	else
		highlightAllCMD.onclick = function(e) {changeHighlightByTerm(true, false);};	
	var spanHighlights = document.createElement("span");
	spanHighlights.className = "CLFHighlightAllNone";
	spanHighlights.appendChild(highlightAllCMD);
	spanHighlights.appendChild(highlightNoneCMD);
	this.content.appendChild(spanHighlights);
}

SidebarElement.prototype.addCMD_MarkNextPrev = function() {
	var nextCMD = document.createElement("input");
	nextCMD.type = "image";
	nextCMD.src = _imagePath + "/findnext.gif";
	nextCMD.className = "findnext";
	nextCMD.title = "Select next";
	nextCMD.onclick = function(e) { markNextPrev(true); };
	var prevCMD = document.createElement("input");
	prevCMD.type = "image";
	prevCMD.src = _imagePath + "/findprev.gif";
	prevCMD.className = "findprev";
	prevCMD.title = "Select previous";
	prevCMD.onclick = function(e) { markNextPrev(false); };
	var spanNextPrev = document.createElement("span");
	spanNextPrev.className = "CLFNextPrev";
	spanNextPrev.appendChild(prevCMD);
	spanNextPrev.appendChild(nextCMD);
	this.content.appendChild(spanNextPrev);
}

SidebarElement.prototype.addCMD_CollapseExpandAll = function() {
	var collapseCMD = document.createElement("input");
	collapseCMD.type = "image";
	collapseCMD.src = _imagePath + "/treecollapseall.gif";
	collapseCMD.className = "collapseAll";
	collapseCMD.title = "Collapse all";
	collapseCMD.onclick = function(e) { collapseExpandAll(true); };
	var expandCMD = document.createElement("input");
	expandCMD.type = "image";
	expandCMD.src = _imagePath + "/treeexpandall.gif";
	expandCMD.className = "expandAll";
	expandCMD.title = "Expand all";
	expandCMD.onclick = function(e) { collapseExpandAll(false); };
	var spanCollapseExpand = document.createElement("span");
	spanCollapseExpand.className = "CLFCollapseExpand";
	spanCollapseExpand.appendChild(expandCMD);
	spanCollapseExpand.appendChild(collapseCMD);
	this.content.appendChild(spanCollapseExpand);
}

SidebarElement.prototype.getElement = function() {
	return this.root;
}

// Document Writer //

function CLFDOCWriter(htmlElement) {
	this.rootElement = htmlElement;
	this.currentElement = htmlElement;
	this.currentType = "ROOT";
	this.currentTag = "ROOT";
	this.openHighlight = new Array();
	this.tmpClosedHighlight = new Array();
	this.highlightInfo = new Object();
	this.RXurl = /^https?:\/\/[^ ]+$/i;
	this.textdata = new StringBuilder();
	this.RXonlynewline = /([^ ])\n([^ ])/g;
}

CLFDOCWriter.prototype.changeCurrentElement = function(newElm, newParent, newType) {
	if (this.currentType == "TEXT") {
		if (!this.textdata.IsEmpty()) {
			var s = this.textdata.ToString();
			this.currentElement.appendChild(document.createTextNode(s.replace(this.RXonlynewline, "$1 \n$2").unescapeHTML()));  // IE bug - don't save \n in text
		}
	}
	if (newType != null)
		this.currentType = newType;
	if (newElm != null) {
		this.currentElement.appendChild(newElm);
		if (newParent)
			this.currentElement = newElm;
	}
}

CLFDOCWriter.prototype.addHeaderElement = function(headerName) {
	this.optimize();
	var elm = document.createElement("DIV");
	elm.className = "CLFDOCHeader CLFTAG" + headerName;
	elm.appendChild(document.createTextNode(headerName.unescapeHTML()));
	this.changeCurrentElement(elm, false, "HEADER");
	this.currentTag = headerName;
}

CLFDOCWriter.prototype.addP = function() {
	//this.optimize();
	var elm = document.createElement("BR");
	this.changeCurrentElement(elm, false, null);
}

CLFDOCWriter.prototype.addTable = function() {
	var elm = document.createElement("BR");
	this.changeCurrentElement(elm, false, null);
}

CLFDOCWriter.prototype.addTableRow = function() {
	var elm = document.createElement("BR");
	this.changeCurrentElement(elm, false, null);
}

CLFDOCWriter.prototype.addTextElement = function() {
	if (this.currentType == "TEXT")
		return;
	this.optimize();
	this.changeCurrentElement(null, false, "TEXT");
}

CLFDOCWriter.prototype.appendStr = function(str) {
	if (behavior.createLinks && str.match(this.RXurl) != null) {
		var txt = document.createElement("a");
		txt.href = str;
		txt.target = "_blank";
		txt.className = "CLFDOCLink";
		txt.appendChild(document.createTextNode(str));
		this.changeCurrentElement(null, null, null);
		this.currentElement.appendChild(txt);
	} else
		this.textdata.Append(str);
}

CLFDOCWriter.prototype.beginHighlight = function(id, category) {
	var hgl = document.createElement("SPAN");
	var hglID = "CLFH" + id + ".";
	var nextFID = 0;
	if (this.highlightInfo[id] != null) {
		for (; nextFID < 9; nextFID++) {
			var tempid = hglID + nextFID
			var n = document.getElementById(tempid);
			if (n == null)
				break;	
		}
	}
	hgl.id = hglID + nextFID;
	hgl.className = "CLF" + category;
	if (this.currentType != "TEXT")
		this.addTextElement();
	this.changeCurrentElement(hgl, true, null);
	this.openHighlight.push(id);
	this.highlightInfo[id] = [id, category];
}

CLFDOCWriter.prototype.endHighlight = function(id) {
	this.popHighlight();
	var lastID = this.openHighlight.pop();
	// close all overlapping
	while (lastID != id) {
		this.tmpClosedHighlight.push(lastID);
		this.popHighlight();
		lastID = this.openHighlight.pop();
	}
	// open back all overlapping
	while (this.tmpClosedHighlight.length > 0) {
		var arv = this.highlightInfo[this.tmpClosedHighlight.pop()];
		this.beginHighlight(arv[0], arv[1]);
	}
}

CLFDOCWriter.prototype.popHighlight = function() {
	this.changeCurrentElement(null, null, null);
	if (this.currentElement.childNodes.length == 0) {
		var tmp = this.currentElement;
		this.currentElement = this.currentElement.parentNode;
		this.currentElement.removeChild(tmp);
	} else {
		this.currentElement = this.currentElement.parentNode;
	}
}

CLFDOCWriter.prototype.eod = function() {
	this.changeCurrentElement(null, null, null);
	this.optimize();
}

CLFDOCWriter.prototype.optimize = function() {
	// patch to remove div with only spaces
	if (this.currentElement.childNodes.length == 1)
		if (this.currentElement.firstChild.nodeType == 3)
			if (this.currentElement.firstChild.data.trim().length == 0)
				this.rootElement.removeChild(this.currentElement);
	// end of patch
}