/* xjs */
$id = function(elementId) { return document.getElementById(elementId); }

var xjs = {
		_uid : 100,
		uid: function () { this._uid = this._uid +1; return this._uid; },
		setClass: function (domElm, cssClassToSet, cssClassToUnset){        
					var elmClass = "";
					if (typeof(cssClassToUnset) == "undefined") { cssClassToUnset = ""; }
					if(domElm.getAttribute("class")){
						elmClass = domElm.getAttribute("class");
						elmClass = elmClass.replace(cssClassToUnset, "").trim();
						if(elmClass.length>0) {elmClass += " "+cssClassToSet } else { elmClass = cssClassToSet; }
					}
					else { elmClass = cssClassToSet; }
					domElm.className = elmClass;
				},
		cleanDom: function (node) {
					if(node == null || typeof(node) === 'undefined') { return; } 
					for (var atrb in node.attributes) { 
						if (typeof node[atrb] === 'function') {  node[atrb] = null; }
					}
					if(node.childNodes.length>0) {
						node = node.firstChild;            
						while (node) { this.cleanDom(node); node = node.nextSibling; }
					}
				}
	}
xjs.GenericComponent = function(){
            this._xmlhttp = null;
            this._component = null;

            this.endpoint = null;
            this.endpointParams = {};
            this.loadFromEndpoint = false;
            this.container = "elmContainer";
			this.cssClass = "xcomponent";
			this.fields = [];
            this.lookups =[];
            this.store = null;

            this._uid = null;
            this._transaction = 0;
            this.debug = {enabled:false,outputDomelmId:"formdebug"};
            this.transaction = function(){ return this._transaction; };
            this.transactionStart = function(){ var t=(new Date()).getTime(); this._transaction = t; return t; };
            this.transactionClear = function(){ _transaction = 0; };
            this.markEvent = function(elm,event,func){ elm.setAttribute("ev_"+event, func+""); }

            this.pickData = function(){ return component_pickData(this); }
            function component_pickData(cmp){ 
                var data = Array();
                for(var f=0; f<cmp.fields.length; f++){
					var elm = null;
					if (cmp.fields[f]["id"] != null && cmp.fields[f]["id"]) { elm = document.getElementById(cmp.fields[f]["id"]); }
                    else { elm = document.getElementById(cmp.fields[f]["name"] +cmp._uid); }
                    if(cmp.fields[f]["isEditable"] && elm){
                        switch (cmp.fields[f]["type"]){
                            case "number":
                            case "string":
                            case "lookup":
                                data[cmp.fields[f]["name"]] = elm.value;
                                break;
							case "boolean":
                                data[cmp.fields[f]["name"]] = (elm.checked) ? 1 : 0;
                                break;
                            default:
                                data[cmp.fields[f]["name"]] = elm.value;
                                break;
                        }
                    }                
                }
                return data;
            }

            this.pickPayload = function(){ return component_pickPayload(this); }
            function component_pickPayload(cmp){
                var data = cmp.pickData();
                var payload = Array();
				for(var prop in data){ payload.push( prop +"=" +encodeURIComponent(data[prop]) ); }
                for(var pkey in cmp.endpointParams){ payload.push( pkey +"=" +cmp.endpointParams[pkey] ); }

                return payload.join("&");
            }

            this.doRequest = function(stateChangedCallback, payload){ return component_doRequest(this, stateChangedCallback, payload); }
            function component_doRequest(cmp, stateChangedCallback, payload){ 
                if(cmp.endpoint == null) {alert("endpoint not configured !"); return; }
                if(cmp._xmlhttp == null) {
                    if (window.XMLHttpRequest) {  cmp._xmlhttp=new XMLHttpRequest(); }
                    else if (window.ActiveXObject) { cmp._xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); }
                }
                if (cmp._xmlhttp != null) {
                    cmp._xmlhttp.onreadystatechange=stateChangedCallback;
                    if(payload){
cmp.log("doRequest-Post payload["+payload+"]");
                        cmp._xmlhttp.open("POST",cmp.endpoint,true);
                        cmp._xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                        cmp._xmlhttp.setRequestHeader("Content-length", payload.length);
                        cmp._xmlhttp.setRequestHeader("Charset", "UTF-8");
                        cmp._xmlhttp.setRequestHeader("Connection", "close");
                        cmp._xmlhttp.send(payload);
                    }
                    else {
						var endpointParams = Array();
						for(var pkey in cmp.endpointParams){ endpointParams.push( pkey +"=" +cmp.endpointParams[pkey] ); }
cmp.log("doRequest-Get url["+cmp.endpoint+"] endpointParams["+endpointParams.join("&")+"]");
                        cmp._xmlhttp.open("GET",cmp.endpoint,true);
                        cmp._xmlhttp.send(endpointParams.join("&"));
                    }
                }   
                else { alert("Your browser does not support XMLHTTP."); }
            }

            this.log = function (message) { return component_log(this, message); }
            function component_log(cmp, message) { 
                if(cmp.debug.enabled && document.getElementById(cmp.debug.outputDomelmId)){
                    document.getElementById(cmp.debug.outputDomelmId).innerHTML += msg +"<br />";
                }
                if(cmp.debug.enabled){
                    try { console.log(message); } catch(ex){};
                }
             }
        }
xjs.Suggest = function() {
			this.isactive = true;
			this.formatFunc = null;
			this.oninputeventEventHandler = null;
			this.inputParseFunc = null;
			this._inp = null;
			this._endpointBase = null;
			this._suggestList = null;
			this._suggestListIx = -1;
			this._lastPhrase = "";
		    this.init = function(){ return suggest_init(this); }
			function suggest_init(cmp) {
				if(cmp.fields.lenght < 1) { alert("No configured input field to hook to!"); return; }
				else if(!cmp.fields[0].id || cmp.fields[0].id == "") { alert("Input field do not have id"); return; }

				cmp._inp = document.getElementById(cmp.fields[0].id);
				cmp._uid = xjs.uid();
				cmp._endpointBase = cmp.endpoint;
				cmp.store = [];
				cmp._suggestList = document.createElement("ul");
				cmp._suggestList.setAttribute("id", "suggest_"+cmp._uid+"_suggestlist");
				cmp._suggestList.className = "suggestlist dn";
				cmp._inp.parentNode.appendChild(cmp._suggestList);				
				cmp._inp.onblur		= function (evnt) { cmp.hidesuglist(); return cmp.oninputevent(27);  }
				cmp._inp.onkeydown	= function(evnt) { return cmp.oninputevent(evnt) };
				cmp._inp.onkeypress	= function(evnt) { return cmp.oninputevent(evnt) };
				cmp._inp.onkeyup	= function(evnt) { return cmp.oninputevent(evnt) };
			}
			this.getPhrase = function() { return this.pickData()[this.fields[0]["name"]]; }
			this.oninputevent = function(evnt) { return suggest_oninputevent(this, evnt); }
			function suggest_oninputevent(cmp, evnt){
				if(!evnt && window.event) { evnt = window.event; }
				var key = (evnt.keyCode) ? evnt.keyCode : evnt.which ? evnt.which : evnt.charCode;
				switch(evnt.type){
					case "keydown":
							if(cmp.oninputeventEventHandler){ return cmp.oninputeventEventHandler(cmp, evnt); }
						break;
					case "keypress":
							if(cmp.oninputeventEventHandler){ return cmp.oninputeventEventHandler(cmp, evnt); }
						break;
					case "keyup":
							var phrase = cmp.getPhrase();

							if(!cmp.isactive) { cmp.hidesuglist(); return; }
							else if(evnt){
								if(key == 27) { cmp.hidesuglist(); }
								else if(key == 38) { cmp._suggestListIx--; cmp.refreshsuglist(true); }
								else if(key == 40) { cmp._suggestListIx++; cmp.refreshsuglist(true); }
								else if(key == 37 || key == 39) {}
								else if (phrase.length>2 && phrase.length<12) {
									if(cmp._lastPhrase != phrase) {
										cmp.hidesuglist(phrase);
										window.setTimeout(function(){suggest_fetch(cmp, phrase);}, 200);
									}
								}
								else {
									cmp.hidesuglist(phrase);
								}
							}
							else {
								cmp.hidesuglist();
							}
							if(cmp.oninputeventEventHandler){ cmp.oninputeventEventHandler(cmp, evnt); }
						break;
				}
				return evnt;
			}
			this.fetch = function(phrase) { return suggest_fetch(this, phraseCheck); }
			function suggest_fetch(cmp, phraseCheck){
				var phrase = cmp.getPhrase();
				if(phraseCheck && phraseCheck != "" && phraseCheck == phrase) {
					cmp._lastPhrase = phrase;
					if(cmp.store[phrase] != null) { cmp.showsuglist(); return; }
					else {
						for(phrasex in cmp.store){
							 if	(phrase.indexOf(phrasex) == 0 && phrase.length > phrasex.length && cmp.store[phrasex].s.length<1) {
								cmp.hidesuglist();
								return;
							}
						}
					}
					if(cmp.inputParseFunc) { phrase = cmp.inputParseFunc(phrase); }
					cmp.endpoint = cmp._endpointBase +"/" +phrase;
					cmp.doRequest(function(){cmp.fetch_state_change(phrase)}, null);
				}
			}
			this.fetch_state_change = function(phrase) { return suggest_fetch_state_change(this, phrase); }                       
            function suggest_fetch_state_change(cmp, phrase) {
				if (cmp._xmlhttp.readyState==4) {                
					if (cmp._xmlhttp.status==200) {
						var suggestions = {p:"",s:[]};
						try { eval("suggestions="+cmp._xmlhttp.responseText); } catch(ex) { suggestions = {p:"",s:[]}; }
						cmp.store[suggestions.p] = suggestions;
						cmp.showsuglist();
					}
					else {
						cmp.hidesuglist();
cmp.log("problem retrieving data:" + cmp._xmlhttp.statusText);
					}
				}
			}
			this.showsuglist = function() { return suggest_showsuglist(this); }
			function suggest_showsuglist(cmp){
				var suggestions = (cmp.store[cmp._lastPhrase]) ? cmp.store[cmp._lastPhrase].s : [];
				cmp.hidesuglist();

				if(suggestions && suggestions != null && suggestions.length > 0){
					for(var ix=0; ix<suggestions.length; ix++){
						var sugLi = document.createElement("li");
						sugLi.innerHTML = suggestions[ix].p;
						sugLi.ix = ix;
						sugLi.onmouseover  = function() { suggest_moversuglistitem(cmp, this.ix); };
						sugLi.onclick = function() { if(cmp.oninputeventEventHandler){ cmp.oninputeventEventHandler(cmp, {keyCode:13}); } };
						if(cmp.formatFunc && cmp.formatFunc != null) { 
							var ffres = cmp.formatFunc(suggestions[ix].p);
							if(ffres && ffres != null) { sugLi.innerHTML = ffres;}  
						}
						cmp._suggestList.appendChild(sugLi);
					}

					cmp._suggestList.className= "suggestlist";
				}
			}

			this.refreshsuglist = function(updateInput) { return suggest_refreshsuglist(this, updateInput); }
			function suggest_refreshsuglist(cmp, updateInput){
				var rowcount = (cmp._suggestList.childNodes) ? cmp._suggestList.childNodes.length : 0;
				if(rowcount > 0 && cmp._suggestListIx < 0) { cmp._suggestListIx = rowcount -1; }
				else if(rowcount > 0 && cmp._suggestListIx >= rowcount) { cmp._suggestListIx = cmp._suggestListIx % rowcount; }
				if(updateInput) { cmp._inp.value = cmp.store[cmp._lastPhrase].s[cmp._suggestListIx].p; }
				for(var r=0; r<rowcount; r++){ cmp._suggestList.childNodes[r].className = (r == cmp._suggestListIx) ? "alt" : ""; }
			}
			this.hidesuglist = function() { return suggest_hidesuglist(this); }
			function suggest_hidesuglist(cmp){
				cmp._suggestListIx = -1;
				cmp._suggestList.className = "suggestlist dn";
				cmp._suggestList.innerHTML = "";
			}
			this.moversuglistitem = function(ix) { return suggest_moversuglistitem(this, ix); }
			function suggest_moversuglistitem(cmp, ix){
				cmp._suggestListIx = ix;
				for(var r=0; r<cmp._suggestList.childNodes.length; r++){
					cmp._suggestList.childNodes[r].className = (r == cmp._suggestListIx) ? "alt" : "";
				}
				cmp._inp.value = cmp.store[cmp._lastPhrase].s[cmp._suggestListIx].p;
			}
		}
		xjs.Suggest.prototype = new xjs.GenericComponent();
        xjs.Suggest.constructor = xjs.Suggest;			
xjs.UIComponent = function(){
			this._messagebox = null;
            this._foot = null;
            this._cover = null;
            this._coverMsg = null;

            this.container = "elmContainer";
			this.cssClass = "xcomponent";
            this.cover = function(message, cssClass) { return component_cover(this, message, cssClass); }
            function component_cover(cmp, message, cssClass) {
                if(!cmp._cover) { alert("cmp _cover is not set"); return; }
                if(!cmp._coverMsg) { alert("cmp _coverMsg is not set"); return; }
				cmp.showMessage(message, cssClass);

                while(cmp._coverMsg.hasChildNodes()) { cmp._coverMsg.removeChild(cmp._coverMsg.firstChild); }
                cmp._coverMsg.appendChild(document.createTextNode(message));
                cmp._coverMsg.setAttribute("style", "filter:alpha(opacity=100); opacity:1;");
                cmp._coverMsg.className = (cssClass) ? cssClass : "";

                cmp._cover.className = "cover";            
                cmp._cover.style.width = cmp._component.clientWidth +"px";
                cmp._cover.style.height = cmp._component.clientHeight +"px";
                cmp._cover.style.top = cmp._component.offsetTop +"px";
                cmp._cover.style.left = cmp._component.offsetLeft +"px";
            }

            this.uncover = function() { return component_uncover(this); }
            function component_uncover(cmp) { cmp._cover.className = "cover dn"; }
            this.fadeCover = function(step) {return component_fadeCover(this, step); }
            function component_fadeCover(cmp, step) {
                if(cmp._coverMsg){
                    if(!step){ step = 100; } 
                    if (step > 25){
                        cmp._coverMsg.setAttribute("style", "filter:alpha(opacity="+step+"); opacity: "+(step/100)+";");
                        step -= 3;
                        window.setTimeout(function(){component_fadeCover(cmp, step);}, 50);
                    }
                    else {
                        cmp._coverMsg.removeAttribute("fadestate");
                        cmp.uncover();
                    }
                }
            }
			this.showMessage = function(message, cssClass) {return component_showMessage(this, message, cssClass); }
            function component_showMessage(cmp,  message, cssClass) {
                if(!cmp._messagebox) { alert("Message box is not created for cmp " +cmp._uid); return; }
				while (cmp._messagebox.firstChild) { cmp._messagebox.removeChild(cmp._messagebox.firstChild); }
				cmp._messagebox.appendChild(document.createTextNode(message));
				if(cmp._messagebox.className) { cmp._messagebox.removeAttribute("class"); }
				cmp._messagebox.setAttribute("class", "messagebox "+ cssClass);
            }
			this.hideMessage = function() {return component_hideMessage(this); }
            function component_hideMessage(cmp) {
				cmp.showMessage(cmp, "", "notvisible");
            }
		}
		xjs.UIComponent.prototype = new xjs.GenericComponent();
        xjs.UIComponent.constructor = xjs.UIComponent;
xjs.Form = function() {
			this._fieldset = null;
			this._foot = null;
			this.legend = null;
			this.buttonExecute = {show:true, xmlhttpparamkey:"exec", xmlhttpparamval:"exec", text:"exec"};
			this.buttonReset = {show:true, xmlhttpparamkey:"reset", xmlhttpparamval:"reset", text:"reset"};
		    this.init = function(){ return form_init(this); }
			function form_init(cmp) {
				var elmContainer = document.getElementById(cmp.container);
				if(!elmContainer) { alert("Container not found: "+ cmp.container); return; }
				xjs.cleanDom(elmContainer);
				while (elmContainer.firstChild) { elmContainer.removeChild(elmContainer.firstChild); }

				cmp._uid = xjs.uid();
				cmp._component = (elmContainer.nodeName == "form")? elmContainer : document.createElement("form");
				cmp._component.setAttribute("class", cmp.cssClass);
				elmContainer.appendChild(cmp._component);

				cmp._fieldset = document.createElement("fieldset");
				cmp._component.appendChild(cmp._fieldset);
				cmp._foot = document.createElement("div");
				cmp._component.appendChild(cmp._foot);

				if(cmp.loadFromEndpoint && cmp.endpoint != null && cmp.endpoint.length > 0) { alert("do call to endpoint !"); }
				else { 
					cmp.buildFieldset(); 
					cmp.databindFieldset();
				}
				cmp._cover = document.createElement("div");
				cmp._cover.setAttribute("class", "cover dn");
				cmp._cover.appendChild(document.createElement("br"));            
				cmp._coverMsg = document.createElement("div");
				cmp._cover.appendChild(cmp._coverMsg);
				cmp._foot.appendChild(cmp._cover);
			} 
            this.execute = function() { return form_execute(this); }
			function form_execute(cmp){ 
				if (cmp.endpoint != null && cmp.endpoint.length > 0) {
					var tran = cmp.transactionStart();
					if(!cmp.endpointParams[cmp.buttonExecute.xmlhttpparamkey]){
					    cmp.endpointParams[cmp.buttonExecute.xmlhttpparamkey] = cmp.buttonExecute.xmlhttpparamval;
					}
					var payload = cmp.pickPayload() +"&t=" +tran;
					cmp.cover("В процес на изпращане ...", "busy");
					cmp.doRequest(function(){cmp.execute_state_change(tran)}, payload);
				} else {
					cmp._component.submit();
				}   
			}
            this.execute_state_change = function(tran) { return form_execute_state_change(this, tran); }                       
            function form_execute_state_change(cmp, tran) {
				if (cmp._xmlhttp.readyState==4) {                
					if(cmp.transaction() != tran) {
						cmp.uncover();
						return; 
					}

					if (cmp._xmlhttp.status==200) {
						cmp.cover(cmp._xmlhttp.responseText, "success");
						cmp.fadeCover();
						cmp.log(cmp._xmlhttp.responseText);
					}
					else {
						cmp.uncover();
						alert("Problem retrieving data:" + cmp._xmlhttp.statusText);
					}
				}
			}
            this.reset = function(){ return form_reset(this); }
            function form_reset(cmp){ 
				if (cmp.loadFromEndpoint && cmp.endpoint != null && cmp.endpoint.length > 0) {
				} else {
					cmp.databindFieldset();
				}
			}
            this.buildField = function(fieldConfig) { return form_buildField(this, fieldConfig); }
            function form_buildField(cmp, fieldConfig){
				var div = document.createElement("div");				
				var valElmId = fieldConfig.name;
				if(fieldConfig.cssClass) { div.setAttribute("class", fieldConfig.cssClass); }

				if(fieldConfig.isVisible) {
					var label = document.createElement("label");
					label.setAttribute("for", fieldConfig.name +cmp._uid);
					label.innerHTML = fieldConfig.caption;
					div.appendChild(label);
				}
				else {
					div.setAttribute("class", "notvisible");
				}

				if(fieldConfig.isEditable && !fieldConfig.isVisible) {
					var inp = document.createElement("input");
					inp.setAttribute("name", valElmId);
					inp.setAttribute("type", "hidden");     
					inp.setAttribute("id", valElmId +cmp._uid);
					div.appendChild(inp);  
				}
				else if(!fieldConfig.isEditable && fieldConfig.isVisible) {
					var readonly = document.createElement("div");
					readonly.appendChild(document.createTextNode(""));
					readonly.setAttribute("id", valElmId +cmp._uid);
					div.appendChild(readonly); 
				}
				else if(fieldConfig.isEditable){
					switch (fieldConfig.type){
						case "number":
							var inpN = document.createElement("input");
							inpN.setAttribute("id", valElmId +cmp._uid);
							inpN.setAttribute("name", valElmId);
							inpN.setAttribute("type", "text");                       
							div.appendChild(inpN);
							break;
						case "string":
							var inpS = document.createElement("input");
							inpS.setAttribute("id", valElmId +cmp._uid);
							inpS.setAttribute("name", valElmId);
							inpS.setAttribute("type", "text");
							div.appendChild(inpS);
							break;
						case "text":
							var tarea = document.createElement("textarea");
							tarea.setAttribute("id", valElmId +cmp._uid);
							tarea.setAttribute("name", valElmId);
							div.appendChild(tarea);
							break;
						case "lookup":
							var sel = document.createElement("select");
							var dataSourceFound = false;
							for(var l=0; l<cmp.lookups.length; l++){
								if(cmp.lookups[l].lookup == valElmId && cmp.lookups[l].data.length>0){									
									var opt = null;
									sel.setAttribute("id", valElmId +cmp._uid);
									sel.setAttribute("name", valElmId);

									for(var o=0; o<cmp.lookups[l].data.length; o++){
										opt = document.createElement("option");
										opt.value = cmp.lookups[l].data[o].val;
										opt.innerHTML = cmp.lookups[l].data[o].txt;							
										sel.appendChild(opt); 
									}
									dataSourceFound = true;
								}
							}
							if(!dataSourceFound) { alert("not found lookup (options) data source for: "+valElmId);}
							div.appendChild(sel);
							break;
						case "boolean":
							var inpN = document.createElement("input");
							inpN.setAttribute("id", valElmId +cmp._uid);
							inpN.setAttribute("name", valElmId);
							inpN.setAttribute("type", "checkbox");                       
							div.appendChild(inpN);
							break;
						default:
							var span = document.createElement("label");
							label.appendChild(document.createTextNode(""));
							div.appendChild(label); 
							break;
					}
				}
				if(fieldConfig.isVisible && fieldConfig.hint) {
					var hint = document.createElement("span");
					hint.innerHTML = fieldConfig.hint;
					div.appendChild(hint);
				}
				return div;
			}

            this.buildFieldset = function(){ return form_buildFieldset(this); }
            function form_buildFieldset(form){ 
				xjs.cleanDom(form._fieldset);
				while(form._fieldset.hasChildNodes()){ form._fieldset.removeChild(form.firstChild); }
				if(form.legend){
					var legend = document.createElement("legend");
					legend.innerHTML = form.legend;
					form._fieldset.appendChild(legend);
				}
				var msgbox = document.createElement("div");
				msgbox.setAttribute("id", "messagebox" +form._uid);
				msgbox.setAttribute("class", "messagebox notvisible");
				form._messagebox = msgbox;
				form._fieldset.appendChild(msgbox);
				var field = null;        
				for(var f=0; f<form.fields.length; f++){
					field = form.buildField(form.fields[f]);                
					form._fieldset.appendChild(field); 
				}
				if(form.buttonExecute.show || form.buttonReset.show){
					var div = document.createElement("div");
					div.setAttribute("class", "buttons");
					if(form.buttonExecute.show){
						var but = document.createElement("button");
						but.setAttribute("id", "execute" +form._uid);
						but.setAttribute("href", "#");
						but.setAttribute("class", "execute");
						but.innerHTML = form.buttonExecute.text;
						but.onclick = function(){form.execute(); return false;};
						form.markEvent(but, "onclick", "this.execute");
						div.appendChild(but);
					}
					if(form.buttonReset.show){
						var but = document.createElement("button");
						but.setAttribute("id", "reset" +form._uid);
						but.setAttribute("type", "reset");
						but.setAttribute("class", "reset");
						but.innerHTML = form.buttonReset.text;
						but.onclick = function(){form.reset(); return false;};
						form.markEvent(but, "onclick", "this.reset");
						div.appendChild(but);
					}
					form._fieldset.appendChild(div);
				}
			}
			this.databindFieldset = function(){ return form_databindFieldset(this); }
            function form_databindFieldset(cmp){
				for(var f=0; f<cmp.fields.length; f++){
					var fieldConfig = cmp.fields[f];
					var valElmId = fieldConfig.name;
					var valElmValue = (cmp.store.data[fieldConfig.name]) ? unescape(cmp.store.data[fieldConfig.name]) : "";
					if(!fieldConfig.isEditable && fieldConfig.isVisible) {
						var readonly = document.getElementById(valElmId +cmp._uid);
						if (readonly) { readonly.innerHTML = (valElmValue && valElmValue != "") ? valElmValue : "&nbsp;"; }
					}
					else if (fieldConfig.isEditable && !fieldConfig.isVisible) {
						var hiddenInput = document.getElementById(valElmId +cmp._uid);
						if (hiddenInput) { hiddenInput.value = valElmValue; }
					}
					else if (fieldConfig.isEditable && fieldConfig.isVisible) {
						switch (fieldConfig.type){
							case "number":
							case "string":
							case "text":
								var input = document.getElementById(valElmId +cmp._uid);
								if (input) { input.value = valElmValue; }
								break;
							case "lookup":
								var select = document.getElementById(valElmId +cmp._uid);
								if (select) { for(var o=0; o<select.options.length; o++) { select.options[o].selected = (select.options[o].value == valElmValue); } }
								break;
							case "boolean":
								var input = document.getElementById(valElmId +cmp._uid);
								if (input) { 
									if(valElmValue == 1 || valElmValue == true) {
										input.setAttribute("checked", "checked");
									} 
									else {
										input.removeAttribute("checked"); 
									}
								}
								break;
							default:
								var label = document.getElementById(valElmId +cmp._uid);
								if (label) { label.innerHTML = valElmValue; }
								break;
						}
					}
				}
			}
		}
		xjs.Form.prototype = new xjs.UIComponent();
        xjs.Form.constructor = xjs.Form;
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ""); }
/* xjs adds */
xjs.social = {
		sites : [
				{   id:"svejo",
					icon:"svejo.png",
					iconAlt:"svejo",
					url:"http://svejo.net/story/submit_by_url?url={url}&title={title}&summary={summary}",
					hint:"Svejo : {title}"
				},
				{   id:"delicious",
					icon:"delicious.png",
					iconAlt:"del.icio.us",
					url:"http://delicious.com/post?url={url}&description={title}",
					hint:"del.icio.us : {title}"
				},
				{   id:"digg",
					icon:"digg2.png",
					iconAlt:"digg",
					url:"http://digg.com/submit?url={url}&title={title}",					
					hint:"digg it : {title}"
				},
				{   id:"stumbleupon",
					icon:"stumbleupon.png",
					iconAlt:"stumble upon",
					url:"http://www.stumbleupon.com/submit?url={url}&title={title}",
					hint:"stumble upon : {title}"
				},
				{   id:"twitter",
					icon:"twitter.png",
					iconAlt:"twitter",
					url:"http://twitter.com/home?status={title}",
					hint:"tweet : {title}"
				},
				{   id:"facebook",
					icon:"facebook.png",
					iconAlt:"facebook",
					url:"http://www.facebook.com/sharer.php?u={url}&t={title}",
					hint:"facebook : {title}"
				}
			],
		imglocation : "/asset/img/socialicon/",
		data : {
				url:"",
				title:"",
				summary:"",
				isencoded:false
			},
		domelm:null,
		display:function(socials, domElmId){
			if(this.data.url.length<1) { this.data.url = window.location.href; }
			if(this.data.title.length<1) { this.data.title = document.title; }
			if(!this.data.isencoded){
				this.data.url = encodeURIComponent(this.data.url);
				this.data.title = encodeURIComponent(this.data.title);
				this.data.summary = encodeURIComponent(this.data.summary);
			}
			socials = socials.split(",");
			this.domelm = document.getElementById(domElmId);
			for(var so=0; so<socials.length; so++){
				for(var st=0; st<this.sites.length; st++){
					if(this.sites[st].id == socials[so]){
						var surl = this.sites[st].url;
						surl = surl.replace("{url}", this.data.url);
						surl = surl.replace("{title}", this.data.title);
						surl = surl.replace("{summary}", this.data.summary);
						var li = document.createElement("li");
						li.className = this.sites[st].id;
						var anchor = document.createElement("a");
						anchor.href=surl;
						anchor.target="_blank";
						anchor.title = this.sites[st].hint.replace("{url}", decodeURIComponent(this.data.url)).replace("{title}", decodeURIComponent(this.data.title));
						anchor.innerHTML = this.sites[st].iconAlt;
						li.appendChild(anchor);
						this.domelm.appendChild(li);
					}
				}
			}
		}
	};
xjs.validator = function(){
		this.fields = [];			
		this.onSuccessHandler = null;
		this.onFailureHandler = null;
		this.validate = function(){
			var isOverallValid=true;
			var message = "";
			for (var i=0; i< this.fields.length; i++){
				var field = this.fields[i];
				var isElmValid= false;
				for (var e=0; e < field.ids.length; e++){
					var id= field.ids[e];
					var elmType='unknown';
					try{
						var elm = $id(id);
						switch (elm.nodeName.toUpperCase()) {
							case 'INPUT':
								elmType = 'input';
								if(elm.type && elm.type == "checkbox" && elm.checked) { isElmValid = true; }
								else if(elm.type && elm.type != "checkbox" && elm.value.length>0) { isElmValid = true; }
								break;
							case 'SELECT':
								elmType = 'select' +elm.selectedIndex;
								if(elm.selectedIndex>-1 && elm.value.length > 0){
									isElmValid = true;
								}
								break;
							default:
								isElmValid = false;
								break;
						}
					} catch(e){alert('document.getElementById('+id+').nodeName.toUpperCase() fails !\r\n Error name:' +e.name +'\r\n Error message:' +e.message)}
					if(isElmValid) { break; }
				}
				if(!isElmValid) { message += field.errmsg +"\n"; }
				isOverallValid = isOverallValid && isElmValid;
			}
			if(isOverallValid && this.onSuccessHandler != null){ this.onSuccessHandler.call(this, message); }
			else if (this.onFailureHandler != null){ this.onFailureHandler.call(this, message); }

			return isOverallValid;
		};
	}

/* common */
function submitTranslation(p1) {
	if(document.getElementById("p") != null){
		var phrase = document.getElementById("p").value;
		var form = document.getElementById("sf");
		var reTrim = /^\s+|\s+$/gi;
		var reWS = /\s+/gi;
		var reBadChar = /[\/\\\^\$\|\(\)\[\\?\{\}\:\*\?\"\<\>\|\#\%]/gi;

		phrase = phrase.replace(reBadChar, "").replace(reTrim, "").replace(reWS, "+");
		location.href = form.action + phrase;	
	}
	return false;	
}

function parseChar(chr){
	var resChar = "";
	var whiteList = /^[,a-zA-Z0-9\-\_\'\(\)\s\.]$/;
	var cyrilMap = [["а","a"],["б","b"],["в","v"],["г","g"],["д","d"],["е","e"],["ж","zh"],["з","z"],["и","i"],["й","y"],["к","k"],["л","l"],["м","m"],["н","n"],["о","o"],["п","p"],["р","r"],["с","s"],["т","t"],["у","u"],["ф","f"],["х","h"],["ц","ts"],["ч","ch"],["ш","sh"],["щ","sht"],["ъ","a1"],["ь","y1"],["ю","yu"],["я","ya"]];
	if(whiteList.test(chr)) { resChar = chr; }
	else {
		for(var cn=0; cn<cyrilMap.length; cn++){
			if(cyrilMap[cn][0].toLowerCase() == chr.toLowerCase()) { resChar = cyrilMap[cn][1]; break; } 
		}
	}
	return resChar;
}

function parseSuggestion(text){
	var resText = "";
	for (var i = 0; i < text.length; i++) {
		var resChar = "";
		resChar = parseChar(text.substring(i, i+1)); 
		if(resChar.length>1) { resChar = "-"+resChar+"-"; } 
		resText += resChar;
	}
	return resText;
}

function onPhraseChange(){
	var text = document.getElementById("p").value;	
	var reEn = new RegExp("[a-zA-Z]");
	var reBg = /[а-яА-Я]/;
	var reWSpace = /[\s]/;
	var reNeutral = /[\d\_\-\.,']/;
	var countBg = 0;
	var countEn = 0;
	var countWSpace = 0;
	var countNeutral = 0;
	var countOther = 0;
	for(var i=0; i< text.length; i++){
		var chr = text.substring(i, i+1);
		if(reEn.test(chr)) { countEn++; }
		else if(reBg.test(chr)) { countBg++; }
		else if(reWSpace.test(chr)) { countWSpace++; }
		else if(reNeutral.test(chr)) { countNeutral++; }
		else { countOther++; }
	}
	var lf = (countOther>0) ? "xx" : ((countBg > countEn) ? "bg" : "en");
	var lt = (countOther>0) ? "bg" : ((countBg > countEn) ? "en" : "bg");
	document.getElementById("lf").value = lf;
	document.getElementById("lt").value = lt;
}

function autoWirePage(lf, lt){
	var phrase = (document.getElementById("p")) ? document.getElementById("p").innerHTML : "";
	var advs = document.getElementById("searchadds");
	if(!advs) { try{ console.log("missing searchadds; autoWirePage canceled"); } catch(e) {}; return; } 
	else { advs.innerHTML = ""; }
	var slf = document.createElement("input");
	slf.setAttribute("id","lf");
	slf.setAttribute("type","hidden");
	slf.setAttribute("value", lf);
	var slt = document.createElement("input");
	slt.setAttribute("id","lt");
	slt.setAttribute("type","hidden");
	slt.setAttribute("value", lt);
	advs.appendChild(slf);
	advs.appendChild(slt);
	var refweb = document.getElementById("refweb");
	if(refweb){
		refweb.appendChild(document.createTextNode("виж в "));
		var ancGgl = document.createElement("a");
		ancGgl.setAttribute("href","http://www.google.com/search?q="+phrase);
		ancGgl.setAttribute("title", phrase +" в Google");
		ancGgl.setAttribute("target","_blank");
		ancGgl.appendChild(document.createTextNode("google"));
		refweb.appendChild(ancGgl);
		refweb.appendChild(document.createTextNode(", "));
		var ancWki = document.createElement("a");
		ancWki.setAttribute("href","http://" +lf +".wikipedia.org/wiki/Special:Search?search="+phrase);
		ancWki.setAttribute("title", phrase +" в Wikipedia");
		ancWki.setAttribute("target","_blank");
		ancWki.appendChild(document.createTextNode("wikipedia"));
		refweb.appendChild(ancWki);
		refweb.appendChild(document.createTextNode(", "));
		var ancTfd = document.createElement("a");
		ancTfd.setAttribute("href", "http://www.thefreedictionary.com/"+phrase);
		ancTfd.setAttribute("title", phrase +" в The Free Dictionary");
		ancTfd.setAttribute("target","_blank");
		ancTfd.appendChild(document.createTextNode("tfd"));
		refweb.appendChild(ancTfd);
	}
	var sgs = new xjs.Suggest();		
	sgs.endpoint = "/suggest/en";
	sgs.fields = [{name:"p", id:"p", caption:"", hint:"", type:"", isEditable:true, isVisible:true}];
	sgs.formatFunc = function(sg) { var phr = sgs.getPhrase(); return sg.replace(phr,"<b>"+phr+"</b>"); }
	sgs.oninputeventEventHandler = function(cmp, evnt) {
		var key = (evnt.keyCode) ? evnt.keyCode : evnt.which ? evnt.which : evnt.charCode;
		switch(evnt.type){
			case "keydown":
				break;
			case "keypress":
				if(key == 13 || key == 27){ return false; } 
				break;
			case "keyup":
				onPhraseChange();
				var lfval = document.getElementById("lf").value;
				cmp.isactive = (lfval=="en" || lfval=="bg");
				if (cmp.isactive) { sgs._endpointBase = "/suggest/"+lfval; } 
				if(key == 13){ 
					submitTranslation(); 
					return false; 
				}
				break;
		}
		return evnt;
	}
	sgs.inputParseFunc = function(phrase){ return parseSuggestion(phrase); }	
	sgs.debug.enabled = true;
	sgs.init();
}
function sliceSrc(){
	var blockLen = 300;
	var blockLenMargin = 60;
	var slices = new Array();
	var txt = document.getElementById("mtsrc").innerHTML;

	for(var i=0; i<txt.length;){
		var slice = "";
		var start = i;
		var end = txt.length;
		if((start + blockLen) < end) {
			end = txt.indexOf(".", (start + blockLen)) +1;
			if(end<=start || end > (start + blockLen + blockLenMargin)) {  end = txt.indexOf(" ", (start + blockLen)) +1; }
			if(end<=start || end > (start + blockLen + blockLenMargin)) {  end = start+ blockLen; }
		}
		slice = txt.substring(start, end);
		slices.push(slice);
		i = end;
	}
	return slices;
}

function tranSlice(slices, snum, result){
	var mtstat = document.getElementById("mtstat");
	var mtres = document.getElementById("mtres");
	var lf =  document.getElementById("lf").value;
	var lt =  document.getElementById("lt").value;
	if (result) {
		if (result && result.error) {
			xjs.setClass(mtstat, "mwarning", "mloading");
			mtres.innerHTML = "Преводът се развали. Опитай пак!<br /><i>["+result.error.code+"] " +result.error.message +"</i>";
			return; 
		}
		mtstat.innerHTML = "преведени " + Math.round((snum * 100)/slices.length) +"%";
		mtres.innerHTML += result.translation +" ";
	}
	var slice = slices[snum];
	snum++;
	if(snum <= slices.length) {
		var glf = (lf == "xx") ? "" : lf;
		google.language.translate(slice, glf, lt, function(result) {	tranSlice(slices, snum, result); } );
	}
	else {
		xjs.setClass(mtstat, "msuccess", "mloading");
	}
}

function bingTranslateCallback(text){
	document.getElementById("mtres").innerHTML = text;	
}

function addToFavourites(){
	var url = "http://www.ezikov.com";
	var title = "www.Ezikov.com - речници, преводи, преводачи и агенции";
	if (window.sidebar) { window.sidebar.addPanel(title, url, ""); }
	else if(window.opera && window.print){
		var elem = document.createElement('a');
		elem.setAttribute('href',url);
		elem.setAttribute('title',title);
		elem.setAttribute('rel','sidebar');
		elem.click();
	} 
	else if(document.all) { window.external.AddFavorite(url, title); }
}
