String.prototype.toUTF8 = function(){
	var n, sReturn = '';
	for (var i = 0, iTextLen = this.length; i < iTextLen; i++) {
		n = this.charCodeAt(i);
		if (n < 128) sReturn += String.fromCharCode(n)
		else if (n < 2048) sReturn += String.fromCharCode(192 | n >> 6) + String.fromCharCode(128 | n & 63);
		else if (n < 65536) sReturn += String.fromCharCode(224 | n >> 12) + String.fromCharCode(128 | n >> 6 & 63) + String.fromCharCode(128 | n & 63);
		else sReturn += String.fromCharCode(240 | n >> 18) + String.fromCharCode(128 | n >> 12 & 63) + String.fromCharCode(128 | n >> 6 & 63) + String.fromCharCode(128 | n & 63);
	}
	return sReturn;
};
String.prototype.ltrim = function() {
	return this.replace( /^\s+/ , '' );
};
String.prototype.rtrim = function() {
	return this.replace( /\s+$/ , '' );
};
String.prototype.trim = function() {
	return this.replace( /^\s+|\s+$/g , '' );
};

Array.prototype.push = function(value){
	this[this.length]=value;
	return this;
};
Array.prototype.pop = function() {
	var r,i;
	if (i = this.length) {
		r = this[i-1];
		delete this[i];
		return r;
	}
	else return;
};
Array.prototype.find = function(value) {
	for (var i=0; i<this.length; i++) if (this[i] === value) return i;
	return -1;
};

function ge(id) {
	return document.getElementById ? document.getElementById(id) : document.all[id];
}

function makesure() {
	return confirm('Вы действительно хотите удалить эту запись?');
}

function iPaste(iString,actType){
	if (!actType) {
		iString=iString+' ';
	}
	else if (actType==1) {
		if (iString=='') alert('Выделите фразу или текст, который хотите процитировать.');
		else iString='[quote]'+iString+'[/quote]'+'\n';
	}
	else if (actType==2) {
		iString='[b]'+iString+'[/b]'+'\n';
	}
	else {
//		var txtarea = document.forms["add"].elements["add_text"];
//		theSelection = document.selection.createRange().text;
        if (selection) {
			document.selection.createRange().text = '['+actType+']' + iString + '[/'+actType+']';
			var textParsing = 1;
        }
		else {
            iString += '['+actType+']' + '[/'+actType+']';
		}
	}
	var isForm=document.forms["add"];
	if (isForm) {
		var input=document.forms["add"].elements["add_text"];
		if (textParsing!=1) {
			input.value=input.value+iString;
		}
		input.focus();
	}
	else alert('Невозможно выполнить действие.\nСкорее всего Вы не авторизованы.\nВыполните, пожалуйста, вход в систему!');
}

function pasteSel() {
	if(document.getSelection) selection=document.getSelection(); 
	else if(document.selection) selection=document.selection.createRange().text; 
	else if(window.getSelection) selection=window.getSelection(); 
	else selection=''; 
}

function isIE() {
	return (navigator.userAgent.toLowerCase().indexOf("msie") != -1);
}

(function(){
	if (isIE()) {
		try{
			document.execCommand("BackgroundImageCache", false, true);
		} catch(e) {
			
		}
	};
})();

function fixPNG(element) {
	if (/MSIE (5\.5|6).+Win/.test(navigator.userAgent)) {
		var src;

		if (element.tagName == 'IMG') {
			if (/\.png$/.test(element.src)) {
				src = element.src;
				element.src = "/img/empty.gif";
			}
		} else {
			src = element.currentStyle.backgroundImage
					.match(/url\("(.+\.png)"\)/i)
			if (src) {
				src = src[1];
				element.runtimeStyle.backgroundImage = "none";
			}
		}

		var m = /iesizing\-(\w+)/.exec(element.className);

		var scale_mode = (m) ? m[1] : 'crop';

		if (src)
			element.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"
					+ src + "',sizingMethod='" + scale_mode + "')";
	}
}

function iChangeImg(id, src) {
	var img=ge(id);
	if (img) img.src=src;
}

function iExpand(id) {
	var div = ge("div_" + id);
	if (!div) return;
	var visible = (div.style.display == 'none');
	
	if (visible) {
		var s=div.tagName || "";
		if (s.toLowerCase()=='table') {
			try { div.style.display = 'table'; }
			catch(e) {
				div.style.display = 'block';
			}
		}
		else div.style.display = 'block';
		div.style.visibility = 'visible';
		setTimeout(function(){ iChangeImg("bul_"+id, "/img/buttons/listbul_minus.gif"); }, 1);
	} else {
		div.style.visibility = 'hidden';
		div.style.display = 'none';
		setTimeout(function(){ iChangeImg("bul_"+id, "/img/buttons/listbul_plus.gif"); }, 1);
	}
}

function iSubFormExpand (form, id, total) {
	for (var i=0; i<total; i++) {
		var hidden_div = ge("subform_" + form + "[" + i + "]");
		hidden_div.style.display = 'none';
		hidden_div.style.visibility = 'hidden';
	}
	var div = ge("subform_" + form + "[" + id + "]");
	div.style.display = 'block';
	div.style.visibility = 'visible';
	//document.getElementById("subform").innerHTML = document.getElementById("subform_"+id).innerHTML;
}

function copyToClipboard(inputData) {
	window.clipboardData.setData('Text', inputData);
}

function SelectFile( fileUrl ) {
	// window.opener.SetUrl( url, width, height, alt);
	if (window.opener != null) {
		window.opener.SetUrl( fileUrl ) ;
		window.close() ;
	}
}

function iAddField ( id, code ) {
	var div = ge("div_" + id);
	if (div) div.innerHTML+=code;
}

function iDecValue ( cnt_id, btn_id ) {
	var hid = ge(cnt_id);
	if (!hid) return;
	var i = new Number(hid.value);
	i--;
	hid.value = ''+i;
	if (i>0) return;
	var btn = ge(btn_id);
	if (btn) btn.style.display = 'none';
}

function iAttachAddField ( cnt_id, div_id, code ) {
	var hid = ge(cnt_id);
	if (!hid) return;
	var i = new Number(hid.value);
	if (i<=0) return;
	var div = ge("div_" + div_id + "_" + i);
	if (!div) return;
	i--;
	if (i) code+='<div id="div_attachments_ext_files_' + i + '">' + div.innerHTML + '</div>';
	hid.value = ''+i;
	div.innerHTML=code;
	return;
}

function iSetValue( field_id, value ) {
	var field = ge(field_id);
	if (field) field.value=value;
}

function iMoveTo( what_id, to_id ) {
	var field1 = ge(what_id);
	var field2 = ge(to_id);
	if (!field1 || !field2) return;
	field1.style.x=field2.style.x;
	field1.style.y=field2.style.y;
	return;
}

function iShow( id, show ) {
	var field = ge(id);
	if (field) {
		field.style.visibility = show ? "visible" : "hidden";
		return true;
	}
	else return false;
}

function iShowNonEmpty( id, cnt_id ) {
	var field = ge(id);
	var cnt = ge(cnt_id);
	if (!field || !cnt) return;
	field.style.visibility = cnt.innerHTML ? "visible" : "hidden";
	return;
}

function iTextLength (text_id, span_id, max) {
	var a=ge(text_id);
	var b=ge(span_id);
	if (!a || !b) return;
	b.innerHTML=L=a.value.length;
	if (L>max) b.style.color='#f00';
	else b.style.color='';
}

function CreateXMLHTTP() {
	var xmlHttp=null;
	try{	xmlHttp=new XMLHttpRequest();	}	// Firefox, Opera 8.0+, Safari
	catch(e){	// Internet Explorer
		try{	xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");	}	// IE 6.0+
		catch(e){
			try{	xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");	}	// IE 5.5+
			catch(e){}
		}
	}
	return xmlHttp;
}

/**
*  do ajax query
* @param string method Request method: 'POST' or 'GET'
* @param string action Request url (not uri)
* @param object args Associative array with params to post (special argument '__id' will be used in result function)
* @param function result Function will call for __id with receiving result: function(id, result);
*/
function ajax(method, action, args, result) {
	var xmlHttp=CreateXMLHTTP();
	if(xmlHttp==null) return;
	xmlHttp.onreadystatechange=function(){
		/* 0 - The request is not initialized; 1 - The request has been set up; 2 - The request has been sent; 3 - The request is in process; 4 - The request is complete */
		if(xmlHttp.readyState==4) result( args['__id'], xmlHttp.responseText );
	}
	var params="";
	var key;
	for (key in args) if (key!='__id') params+=(params?'&':'')+key+'='+escape(args[key].toUTF8());
	
	if (method.toUpperCase() == "POST") {
		xmlHttp.open("POST",action,true);
		xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		xmlHttp.setRequestHeader("Content-Length", params.length);
		xmlHttp.setRequestHeader("X-Requester-With", "CMS/2.0 AJAX");
		xmlHttp.setRequestHeader("Connection", "close");
		xmlHttp.send(params);
	}
	else {
		if (params) action+='?';
		xmlHttp.open("GET",action+params,true);
		xmlHttp.setRequestHeader("X-Requester-With", "CMS/2.0 AJAX");
		xmlHttp.send(null);
	}
}

function iTextselAjaxResult(id,result) {
	if (iShow('divAjax_'+id, result?true:false)) {
		var div_cnt = ge('divAjax_'+id+'_cnt');
		if (div_cnt) div_cnt.innerHTML = result;
	}
}

function ajaxDirItems(result_id,l,g,s) {
	ajax("POST", "/fnc/ajaxdirs.php", {'__id':result_id, 'l':l, 'g':g, 's':s, 'id':result_id}, iTextselAjaxResult);
}

function ajaxQueryItems(result_id,s) {
	ajax("POST", "/fnc/ajaxq.php", {'__id':result_id, 's':s, 'id':result_id}, iTextselAjaxResult);
}

function ajaxSitemap(id,l,p) {
	var div;
	if ((div=ge('div_'+id)) && div.innerHTML.substr(0,11).toLowerCase()=='<div class=') {
		ajax("POST", l+"/sitemap/id/"+id, {'__id':id, 'path':p}, function(id,result){
			var div=ge('div_'+id);
			if (div) div.innerHTML=result;
		});
	}
}

function iPopup(url, args) {
/* width : int
 * height : int
 * left : int
 * top : int
 * location : bool
 * menubar : bool
 * resizable : bool
 * scrollbars : bool
 * status : bool
 * toolbar : bool
 */
	args = args || {};
	args.location = args.location || false;
	args.menubar = args.menubar || false;
	args.resizable = args.resizable || true;
	args.status = args.status || false;
	args.toolbar = args.toolbar || false;
	
	var a = [], v, b = typeof false;
	for (var k in args) {
		v = args[k];
		if (typeof v == b) v = v ? 'yes' : 'no';
		a.push(k + '=' + v);
	};
	var r;
	try {
		r = window.open(url, '_blank', a.join(','));
	}
	catch (e) {
		r = null;
	};
	return r;
};

function iCutBlock(o) {
	while (o && !(/(^|\s)icut-title(\s|$)/i.test(o.className))) o = o.parentNode;
	var b = o ? o.nextSibling : null;
	if (b) {
		var open = /(^|\s)open(\s|$)/i.test(o.className);
		if (open) {
			o.className = o.className.replace(/(^|\s+)open(\s+|$)/gi, ' ').replace(/\s\s+/g, ' ').trim();
			b.className = b.className.replace(/(^|\s+)open(\s+|$)/gi, ' ').replace(/\s\s+/g, ' ').trim();
		}
		else {
			o.className += ' open';
			b.className += ' open';
		};
	};
};

function dump(o, scalar){
	if (typeof o == 'string') return o ? 'string['+o.length+']' + (scalar ? '='+o : '') : '""';
	else if (typeof o == 'number' || typeof o == 'boolean' || o == void 0 || o == null) return o;
	else if (o instanceof Array) {
		if (scalar) {
			var L = o.length;
			return L ? 'Array['+L+']' : 'Array()';
		}
		else {
			var s = [];
			for (var i = 0, L = o.length; i < L; i++) s.push(i + ' : ' + dump(o[i], true));
			s = s.length ? '\n' + s.join('\n') + '\n' : '';
			return 'Array(' + s + ')';
		};
	}
	else if (typeof o == 'object') {
		if (scalar) {
			return 'Object {}';
		}
		else {
			var s = [];
			for (var i in o) s.push(i + ' : ' + dump(o[i], true));
			s = s.length ? '\n' + s.join('\n') + '\n' : '';
			return 'Object {' + s + '}';
		};
	}
	else return typeof o;
};
function Dump(o) {
	alert(dump(o));
};

var iDebugEvent =
{
	add : function(id, ev) {
		var o=ge(id);
		if (o) addEvent(o, ev, this.handler);
	},
	handler : function(e) {
		var k, s=[];
		for (k in e) s.push(k + ' : ' + e[k]);
		alert("{\n" + s.join(",\n") + "\n}");
	}
};

function addEvent(el, ev, handler) {
	if (!el) return;
	if (el.addEventListener) el.addEventListener(ev, handler, false);
	else if (el.attachEvent) el.attachEvent("on"+ev, handler);
	else el["on"+ev] = handler;
}

function delEvent(el, ev, handler) {
	if (!el) return;
	if (el.removeEventListener) el.removeEventListener(ev, handler, false);
	else if (el.detachEvent) el.detachEvent("on"+ev, handler);
	else el["on"+ev] = null;
}

function setText(el, text) {
	if (typeof(el.innerText)!='undefined') el.innerText = text;
	else el.textContent = text;
}

function classAdd(el, class_) {
	var classes = el.className;
	if (!classes) classes = '';
	classes = classes.trim().split( /\s+/ );
	if (classes.find(class_) == -1) {
		classes.push(class_);
		el.className = classes.join(" ");
	}
}

function classRemove(el, class_) {
	var classes = el.className;
	if (!classes) return;
	classes = classes.trim().split( /\s+/ );
	var i = classes.find(class_);
	if (i != -1) {
		classes[i] = '';
		el.className = classes.join(" ");
	}
}

function iList() {
	this._items = {};
	return this;
}
var oList = new iList();
iList.prototype._idFromName = function(name) {
	var m = name.match( /Ajax_(\d+)$/ );
	return m ? m[1] : null;
};
iList.prototype.ajaxResult = function(id, result) {
	var o = oList._items[id], i;
	if (o && o.list) {
		o.qValue = o.newValue;
		o.cValue = null;
		for (i=o.listItems.length; --i >= 0 ; ) {
			o.list.removeChild( o.listItems[i] );
			o.listItems[i] = null;
		}
		o.listItems.length = 0;
		o.oResult = null;
		if (result.length) {
			try {
				o.oResult = eval(result);
			}
			catch (e) {
				o.oResult = null;
			}
		}
		if (o.oResult && o.oResult.length) {
			var item, r;
			for (var i=0; i<o.oResult.length; i++) {
				item = o.list.appendChild(document.createElement('div'));
				r = o.oResult[i];
				if (r) {
					item.className = 'ajaxListItem';
					item.id = 'itemAjax_'+id+'_'+i;
					addEvent(item, 'click', o._onclickItem);
					addEvent(item, 'mouseover', o._onmouseoverItem);
					addEvent(item, 'mouseout', o._onmouseoutItem);
					setText(item, r.t);
					if (o.onResultItem) o.onResultItem(item, r);
				}
				else {
					setText(item, "...");
				}
				o.listItems[i] = item;
			}
		}
		else o.oResult = null;
	}
	oList.doShow(id);
};
iList.prototype._ajaxDirs = function(id) {
	var o = oList._items[id];
	if (o) ajax(
		"POST",
		"/fnc/ajaxdirs.php",
		{
			'__id' : id,
			'l' : o.args.lng,
			'g' : o.args.dir,
			's' : o.newValue = o.txt.value,
			'id' : id
		},
		oList.ajaxResult
	);
};
iList.prototype._ajaxQuery = function(id) {
	var o = oList._items[id];
	if (o) {
		ajax(
			"POST",
			"/fnc/ajaxq.php",
			{
				'__id' : id,
				's' : o.newValue = o.txt.value,
				'id' : id
			},
			oList.ajaxResult
		);
		if (o.hid) o.hid.value = '';
	}
};

function iListItem(id, type, args) {
	this.id = id;
	this.type = type;
	this.args = args;
	this.txt = ge('txtAjax_'+id);
	this.hid = ge('hidAjax_'+id);
	// if (this.hid && !this.hid.getAttribute('name')) this.hid = void 0;
	// alert(this.hid);
	this.div = ge('divAjax_'+id);
	this.list = ge('divAjax_'+id+'_cnt');
	this.qValue = ''; // queryed value which result list is based on
	this.cValue = null; // value from result selected by click list or null if nothing is selected from list
	this.newValue = '';
	this.oResult = null;
	this.listItems = [];
	this.listIndex = -1;
	this.visible = false;
	this.hideTimeout = null;
	
	if (type==1) this.query = oList._ajaxDirs;
	else this.query = oList._ajaxQuery;
	
	return this;
}
iListItem_idFromName = function(name) {
	var m;
	if (name && (m = name.toString().match( /Ajax_(\d+)_(\d+)$/i )) && m.length) return [new Number(m[1]), new Number(m[2])];
	else return null;
};
iListItem.prototype.show = function(b) {
	if (this.visible != b) {
		this.visible = b;
		if (this.div) this.div.style.visibility = b ? "visible" : "hidden";
		window.clearTimeout(this.hideTimeout);
		this.hideTimeout = null;
	}
};
iListItem.prototype.select = function(index, sel) {
	var o;
	if (o = this.listItems[index]) {
		if (sel) {
			if (this.oResult[index]) {
				classAdd(o, 'selected');
				this.txt.value = this.oResult[index].t;
			}
		}
		else {
			classRemove(o, 'selected');
			this.txt.value = (this.cValue === null) ? this.qValue : this.cValue;
		}
	}
};
iListItem.prototype.doSelect = function(index) {
	if (this.listIndex != -1 && this.listIndex != index) this.select(this.listIndex, false);
	if ((this.listIndex = index) != -1) this.select(index, true);
};
iListItem.prototype.doSelectNext = function(offsetSign) {
	var index = this.listIndex + (offsetSign >= 0 ? 1 : -1);
	if (index < -1) index = this.listItems.length-1;
	else if (index >= this.listItems.length) index = -1;
	this.doSelect(index);
};
iListItem.prototype._onclickItem = function(e) {
	e = e ? e : window.event;
	var obj;
	if (e && (obj = e.target ? e.target : e.srcElement)) {
		var ids, o, t;
		do {
			if ((ids = iListItem_idFromName(obj.id)) && (o = oList._items[ids[0]])) {
				if (t=o.oResult[ids[1]]) {
					o.txt.value = o.cValue = t.t;
					if (/*o.type == 2 &&*/ o.hid) o.hid.value = t.l;
					o.show(false);
					o.doSelect(-1);
				}
			}
		} while (!t && (obj = obj.parentNode));
	}
};
iListItem.prototype._onmouseoverItem = function(e) {
	e = e ? e : window.event;
	var obj;
	if (e && (obj = e.target ? e.target : e.srcElement)) {
		var ids, o, t;
		do {
			if ((ids = iListItem_idFromName(obj.id)) && (o = oList._items[ids[0]])) {
				o.doSelect(ids[1]);
			}
		} while (!o && (obj = obj.parentNode));
	}
};
iListItem.prototype._onmouseoutItem = function(e) {
	e = e ? e : window.event;
	var obj;
	if (e && (obj = e.target ? e.target : e.srcElement)) {
		var ids, o, t;
		do {
			if ((ids = iListItem_idFromName(obj.id)) && (o = oList._items[ids[0]])) {
				if (o.visible) o.doSelect(-1);
			}
		} while (!o && (obj = obj.parentNode));
	}
};

iList.prototype.doQuery = function(id) {
	var o = oList._items[id];
	if (o) {
		if (o.txt.value) o.query(id);
		else oList.doHide(id);
	}
};
iList.prototype.doShow = function(id) {
	var o = oList._items[id];
	if (o) o.show(o.txt.value.length && o.list.innerHTML.length ? true : false);
};
iList.prototype.doHide = function(id) {
	var o = oList._items[id];
	if (o) o.hideTimeout = window.setTimeout( function(){ o.show(false); o.hideTimeout=null; }, 200 );
};
iList.prototype._onkeyup = function(e) {
	e = e ? e : window.event;
	var obj;
	if (e && (obj = e.target ? e.target : e.srcElement)) {
		var id = oList._idFromName(obj.id);
		if (id) {
			var o = oList._items[id], type = e.type;
			type = (/keydown/i).test(e.type) ? 1 : ( (/keyup/i).test(e.type) ? 2 : 3 );
			if (e.keyCode == 38 && type==2) {	// up arrow
				if (o) o.doSelectNext(-1);
			}
			else if (e.keyCode == 40 && type==2) {	// down arrow
				if (o) o.doSelectNext(+1);
			}
			else if (e.keyCode == 13) {	// Enter
				if (o) {
					o.cValue = o.txt.value;
					if (o.listIndex != -1) {
						if (/*o.type == 2 &&*/ o.hid) o.hid.value = o.oResult[o.listIndex].l;
						if (o.onEnter) o.onEnter(o.oResult[o.listIndex]);
					}
					else {
						if (o.hid) o.hid.value = '';
					}
				}
				oList.doHide(id);
				e.returnValue = false;
				e.cancelBubble = true;
				if (e.preventDefault) e.preventDefault();
				if (e.stopPropagation) e.stopPropagation();
				obj.blur();
				return false;
				// @todo Opera steel makes submit(). We need to cancel form submitting or disable submit button
			}
			else if (e.keyCode == 27) {	// ESC
				if (o) o.doSelect(-1);
				oList.doHide(id);
				obj.blur();
			}
			else if (e.keyCode != 37 && e.keyCode != 39 && type==2) {	// other then ESC, Left or Right. Need to add some other nonprintable codes, like Shift, Ctrl, etc
				oList.doQuery(id);
			}
		}
	}
};
iList.prototype._onfocus = function(e) {
	e = e ? e : window.event;
	var obj;
	if (e && (obj = e.target ? e.target : e.srcElement)) {
		var id = oList._idFromName(obj.id);
		if (id) {
			//oList.doQuery(id);
			oList.doShow(id);
		}
	}
};
iList.prototype._onblur = function(e) {
	e = e ? e : window.event;
	var obj;
	if (e && (obj = e.target ? e.target : e.srcElement)) {
		var id = oList._idFromName(obj.id);
		if (id) oList.doHide(id);
	}
};
iList.prototype.add = function(id, type, args) {
	var o = new iListItem(id, type, args);
	addEvent(o.txt, 'keydown', this._onkeyup);
	addEvent(o.txt, 'keyup', this._onkeyup);
	addEvent(o.txt, 'focus', this._onfocus);
	addEvent(o.txt, 'blur', this._onblur);
	this._items[id] = o;
};

// cat form: add item: select type
function cat_type_change(type_id, path) {
	var text;
	if (type_id == 0) text = '';
	else {
		ajax('GET', path+'/types/'+type_id+'/form', {__id:0}, function(id, result) {
			ge('typed_fields').innerHTML = result;
		});
		text = '...';
	}
	ge('typed_fields').innerHTML = text;
}

