/*
 * iCMS JavaScript Extension
 * 
 * Copyright (c) 2006-2010 i-deal Studio
 */

// function returns element by ID
var ge = (document.all) ? function(id){ return document.all[id]; } : function(id){ return document.getElementById(id); };
window.ge = ge;

// class for events
var CEvents = function() {
	return this;
};
// add handler for element event
CEvents.prototype.Add = function(el, ev, handler) {
	if (el) {
		if (el.addEventListener) el.addEventListener(ev, handler, false);
		else if (el.attachEvent) el.attachEvent("on" + ev, handler);
		else el["on" + ev] = handler;
	};
};
// delete handler of element event
CEvents.prototype.Del = function(el, ev, handler) {
	if (el) {
		if (el.removeEventListener) el.removeEventListener(ev, handler, false);
		else if (el.detachEvent) el.detachEvent("on" + ev, handler);
		else el["on" + ev] = null;
	};
};

// class for DOM
var CDOM = function() {
	return this;
};
// assign inner text for element
CDOM.prototype.SetText = function(el, text) {
	if (el) {
		if (el.innerText != void 0) {
			try {
				el.innerText = text;
			}
			catch(e){
				el.innerHTML = text.HtmlEncode();
			};
		}
		else el.textContent = text;
	};
};
// return inner text of element
CDOM.prototype.GetText = function(el) {
	if (!el) return;
	else if (el.innerText != void 0) return el.innerText;
	else return el.textContent;
};
// add class name in element class
CDOM.prototype.ClassAdd = function(el, cl) {
	if (el && cl != void 0) {
		if (!(cl instanceof Array)) cl = [cl];
		var c = el.className ? el.className : '', n;
		for (var i = 0, L = cl.length; i < L; i++) {
			n = c.indexOf(cl[i]), ns = /\S/;
			if (n == -1 || (n > 0 && ns.test(c.SubStr(n - 1, 1))) || ns.test(c.SubStr(n + cl[i].length, 1))) c += " " + cl[i];
		};
		if (el.className != c) el.className = c;
	};
};
// delete class name from element class
CDOM.prototype.ClassDel = function(el, cl) {
	if (el && cl != void 0) {
		var c = el.className;
		if (c) {
			c = c.Trim().Split( /\s+/ );
			if (!(cl instanceof Array)) cl = [cl];
			var i = c.length, f = false;
			while (--i >= 0) {
				if (cl.Search(c[i]) != -1) {
					c[i] = "";
					f = true;
				};
			};
			if (f) el.className = c.join(" ").Replace( /  +/g, " ").Trim();
		};
	};
};
// check if element has class name
CDOM.prototype.ClassHave = function(el, cl) {
	if (el) {
		var c = el.className;
		if (c) {
			c = c.Trim().Split( /\s+/ );
			return c.Search(cl) != -1;
		};
	};
	return false;
};
// enumerate each child nodes of element and call a function with each of them; if not function specified, returns array or found elements
CDOM.prototype.EachChildNode = function(el, func, obj) {
	if (!el) return;
	var r = [], f = func || function(n) { r.Push(n); return true; };
	for (var o = el.firstChild; o; o = o.nextSibling) {
		if (o.nodeType == 1) {
			if (f.call(obj || o, o) === false) break;
		};
	};
	if (!func) return r;
};
// insert node after reference node into parent node of reference
CDOM.prototype.InsertAfter = function(node, ref) {
	var parent, n;
	if (node && ref && (parent = ref.parentNode)) {
		if (n = ref.nextSibling) parent.insertBefore(node, n);
		else parent.appendChild(node);
	};
};
// insert node before reference node into parent node of reference
CDOM.prototype.InsertBefore = function(node, ref) {
	var parent;
	if (node && ref && (parent = ref.parentNode)) {
		parent.insertBefore(node, ref);
	};
};
// set multiple styles to element
CDOM.prototype.SetStyles = function(el, st) {
	if (el && el.style && st) {
		var v;
		for (var n in st) {
			v = ('' + st[n]).Trim();
			if (n == 'opacity') this.SetOpacity(el, parseFloat(v));
			else el.style[n] = v;
		};
	};
};
// helper for opacity
CDOM.prototype.GetOpacityProperty = function() {
	if (typeof document.body.style.opacity == 'string') // CSS3 compliant (Moz 1.7+, Safari 1.2+, Opera 9)
		return 'opacity';
	else if (typeof document.body.style.MozOpacity == 'string') // Mozilla 1.6-, Firefox 0.8 
		return 'MozOpacity';
	else if (typeof document.body.style.KhtmlOpacity == 'string') // Konqueror 3.1, Safari 1.1
		return 'KhtmlOpacity';
	else if (document.body.filters && navigator.appVersion.match(/MSIE ([\d.]+);/)[1]>=5.5) // Internet Exploder 5.5+
		return 'filter';
	
	return false; //no opacity
};
// remembered value of GetOpacityProperty()
CDOM.prototype.OpacityProperty = void 0;
// real set opacity
CDOM.prototype.SetOpacity = function(el, val) {
	if (this.OpacityProperty == void 0) this.OpacityProperty = this.GetOpacityProperty();
	if (!el || !this.OpacityProperty) return;
	
	if (this.OpacityProperty == "filter") {	// Internet Exploder 5.5+
		val *= 100;
			// if opacity already set, then change it with filters collection, otherwise add opacity in style.filter
		var oAlpha;
		try {
			oAlpha = el.filters['DXImageTransform.Microsoft.alpha'] || el.filters.alpha;
		}
		catch (e) {
			oAlpha = false;
		};
		if (oAlpha) oAlpha.opacity = val;
		else el.style.filter += "progid:DXImageTransform.Microsoft.Alpha(opacity="+val+")"; // use += to keep other filters
	}
	else {	// other browsers
		el.style[this.OpacityProperty] = val;
	};
};

// class for HTTP routines
var CHTTP = function() {
	return this;
};
// value of signature header
CHTTP.prototype.VERSION = "i-CMS/2.0 AJAX";
// request types
CHTTP.prototype.METHOD_POST = 1;
CHTTP.prototype.METHOD_GET = 2;
// function return new instance of XMLHTTP object
CHTTP.prototype.NewXMLHTTP = function() {
	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;
};
// make HTTP request
CHTTP.prototype._Request = function(method, url, args, onresponce, obj) {
	var xmlHttp = this.NewXMLHTTP();
	if (!xmlHttp) return false;
	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) onresponce.call(obj || xmlHttp, xmlHttp.responseText, xmlHttp);
	};
	var params = [], key;
	if (args) for (key in args) params.Push(key + "=" + escape(('' + args[key]).toUTF8()));
	params = params.join("&");
	
	if (typeof method == typeof "") method = method.toUpperCase();
	switch (method) {
		case this.METHOD_POST:
		case "POST":
			xmlHttp.open("POST", url, true);
			xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
			xmlHttp.setRequestHeader("Content-Length", params.length);
			xmlHttp.setRequestHeader("X-Requested-With", this.VERSION);
			xmlHttp.setRequestHeader("Connection", "close");
			xmlHttp.send(params);
			break;
		case this.METHOD_GET:
		case "GET":
			if (params) url += '?';
			xmlHttp.open("GET", url + params, true);
			xmlHttp.setRequestHeader("X-Requested-With", this.VERSION);
			xmlHttp.setRequestHeader("Connection", "close");
			xmlHttp.send(null);
			break;
		default:
			return false;
	};
	return true;
};

// class for debugging
var CDebug = function() {
	return this;
};
// return text dump of a value
CDebug.prototype.Dump = function(o, recurs) {
	if (o === null) return "null";
	else if (o === void 0) return "undefined";
	else if (typeof o == typeof 1 || typeof o == typeof true) return o.toString();
	else if (typeof o == typeof "") return o.length ? "String[" + o.length + "]" + (recurs ? "" : ": " + o) : '""';
	else if (typeof o == "function") return recurs ? "Function" : o.toString();
	else if (typeof o == "object") {
		var a = o instanceof Array;
		var r;
		if (!recurs) {
			r = a ? "Array(" : "Object {";
			var items = [], k, L;
			if (a) for (k = 0, L = o.length; k < L; k++) items.Push("\n    " + k + ": " + this.Dump(o[k], true));
			else {
				var x;
				for (k in o) {
					try {
						x = o[k];
						x = this.Dump(x, true);
					}
					catch(e) {
						x = "* Error";
					};
					items.Push("\n    " + k + ": " + x);
				};
			};
			r += items.join(",");
			if (items.length) r += "\n";
			r += a ? ")" : "}";
		}
		else {
			if (a) r = "Array(" + o.length + ")";
			else {
				try {
					r = (o.toString) ? o.toString() : "[Object]";
				}
				catch(e) {
					r = "[Object]";
				};
				r = r.Replace( /^\[/ , '' ).Replace( /\]$/ , '' );
			};
		};
		return r;
	}
	else return typeof o;
};

// main iCMS class
var CiCMS = function() {
	this.LoadFuncs = [];
	this._onLoad = function() {
		this.Load = function(func) {
			func();
		};
		for (var i = 0, L = this.LoadFuncs.length; i < L; i++) {
			try {
				(this.LoadFuncs[i])();
			}
			catch(e) {};
		};
		this.LoadFuncs.length = 0;
	};
	// add a function to document onload event
	this.Load = function(func) {
		this.LoadFuncs.Push(func);
	};
	
	var o = this;
	this.Events.Add(window, 'load', function(){ o._onLoad(); });
	return this;
};
// create class for events
CiCMS.prototype.Events = new CEvents();
// create class for DOM
CiCMS.prototype.DOM = new CDOM();
// create class for debugging
CiCMS.prototype.Debug = new CDebug();
// create class for HTTP
CiCMS.prototype.HTTP = new CHTTP();
// function makes request for HTML
CiCMS.prototype.AJAH = function(method, url, args, onresponce, obj) {
	return this.HTTP._Request(method, url, args, onresponce, obj);
};
// function makes request for JavaScript (may be it should have name AJAJ ?)
CiCMS.prototype.AJAX = function(method, url, args, onresponce, obj) {
	return this.HTTP._Request(method, url, args, function(s, o) {
		var r;
		try {
			if (typeof s != typeof "" || !s.length) s = "void 0";
			eval("r = " + s + ";"); // @bug some browsers stores objects sorted by keys (Opera 10, Chrome)
		}
		catch (e) {
			// alert('Error: ' + e.message + '\r\n----\r\n' + s);
			r = void 0;
		};
		//alert(iCMS.Debug.Dump(r.groups[0]));
		onresponce.call(obj || o, r, o);
	});
};

// create main iCMS class
var iCMS = new CiCMS();
window.iCMS = iCMS;

// delete all options from a Select and fill it from directories
CDOM.prototype.SelectFromDirs = function(select, link, lng, skipfirst) {
	if (!select) return;
	var o = this.EachChildNode(select);
	for (var i = skipfirst ? 1 : 0; o && i < o.length; i++) {
		select.removeChild(o[i]);
		o[i] = null;
	};
	o = null;
	var f = function() {	// IE7 strange bug
		var c = select.className;
		select.className = '';
		select.className = c;
	};
	if (link) {
		iCMS.AJAX("POST", "/fnc/ajaxdirsq.php", {l:lng, g:link}, function(items){
			if (items && typeof items == typeof {}) {
				for (var i in items) {
					o = document.createElement('option');
					o.value = i;
					this.SetText(o, items[i].t);
					select.appendChild(o);
				};
			};
			f();
		});
	}
	else f();
};

// iform renaming fields
var iFormRenamingField = function(o) {
	this.fd = ge(o.id + "_title");
	this.fh = ge(o.id + "_help");
	this.d = o.d;
	this.h = o.h;
	return this;
};
var iFormRenaming = function(ids, value, fields) {
	var i, L, o;
	
	this.Fields = [];
	for (i = 0, L = fields.length; i < L; i++) this.Fields.Push( new iFormRenamingField(fields[i]) );
	
	//this.Items = [];
	for (i = 0, L = ids.length; i < L; i++) {
		o = ge(ids[i]);
		o._i_renaming = this;
		iCMS.Events.Add(o, 'click', this.OnClick);
		//this.Items.Push(o);
	};
	this.Rename(value);
	return this;
};
iFormRenaming.prototype.Rename = function(value) {
	for (var i = 0, L = this.Fields.length; i < L; i++) {
		if (this.Fields[i].fd && this.Fields[i].d) iCMS.DOM.SetText(this.Fields[i].fd, this.Fields[i].d[value]);
		if (this.Fields[i].fh && this.Fields[i].h) iCMS.DOM.SetText(this.Fields[i].fh, this.Fields[i].h[value]);
	};
};
iFormRenaming.prototype.OnClick = function(e) {
	e = e ? e : window.event;
	var o, obj;
	if (e && (o = e.target ? e.target : e.srcElement) && (obj = o._i_renaming)) {
		obj.Rename(o.value);
	};
};

var iFormRenamingSel = function(id, fields) {
	var i, L, o;
	
	this.Fields = [];
	for (var i = 0, L = fields.length; i < L; i++) this.Fields.Push( new iFormRenamingField(fields[i]) );
	
	o = ge(id);
	o._i_renaming = this;
	iCMS.Events.Add(o, 'change', this.OnClick);
	
	this.Rename(o.value);
	return this;
};
iFormRenamingSel.prototype = iFormRenaming.prototype;

// tabs
var TabPagesItem = function(a, index, parent) {
	this.oTab = a[0] && a[0].tagName ? a[0] : ge(a[0]);
	this.oPage = a[1] && a[1].tagName ? a[1] : ge(a[1]);
	this.Show(false);
	this.Index = index;
	this.Parent = parent;
	this.oTab._i_TabItem = this;
	iCMS.Events.Add(this.oTab, 'click', this.OnClick);
	return this;
};
TabPagesItem.prototype.Show = function(b) {
	if (b) iCMS.DOM.ClassAdd(this.oTab, 'selected');
	else iCMS.DOM.ClassDel(this.oTab, 'selected');
	this.oPage.style.display = b ? 'block' : 'none';
};
TabPagesItem.prototype.OnClick = function(e) {
	e = e ? e : window.event;
	var obj;
	if (e && (obj = e.target ? e.target : e.srcElement) && (obj = obj._i_TabItem)) {
		obj.Parent.Select(obj.Index);
	};
};
var TabPages = function(aItems) {
	this.Items = [];
	this.Selected = -1;
	for (var i = 0, L = aItems.length; i < L; i++) {
		this.Items.Push( new TabPagesItem(aItems[i], i, this) );
	};
	this.Select(0);
	return this;
};
TabPages.InitForElement = function(el) {
	el = el && el.tagName ? el : ge(el);
	if (!el) return;
	var Items = [], t, ctl, body, children, i, L, span, o;
	ctl = document.createElement('div');
	ctl.className = 'tabs-ctl';
	body = document.createElement('div');
	body.className = 'tabs-body';
	children = iCMS.DOM.EachChildNode(el);
	for (i = 0, L = children.length; i < L; i++) {
		o = children[i];
		span = document.createElement('span');
		span.className = 'i-tab-title';
		iCMS.DOM.SetText(span, o.getAttribute('i-tab-title') || 'Untitled');
		ctl.appendChild(span);
		o.parentNode.removeChild(o);
		body.appendChild(o);
		o.style.display = 'none';
		iCMS.DOM.ClassAdd(o, 'i-tab-item');
		Items.Push([span, o]);
	};
	el.appendChild(ctl);
	el.appendChild(body);
	new TabPages(Items);
};
TabPages.prototype.Select = function(index) {
	if (index != this.Selected) {
		if (this.Selected >= 0) this.Items[this.Selected].Show(false);
		this.Items[this.Selected = index].Show(true);
	};
};

// path selector
var PathSelectorItem = function(parent,R) {
	this.Parent = parent;
	this.ID = R.i;
	this.Link = (R.l != void 0) ? R.l : R.i;
	this.Title = R.t;
	this.oOption = document.createElement('option');
	this.oOption.value = this.ID;
	iCMS.DOM.SetText(this.oOption, this.Title);
	this.Parent.appendChild(this.oOption);
	return this;
};
PathSelectorItem.prototype.Free = function() {
	this.Parent.removeChild(this.oOption);
	this.oOption = null;
	this.Parent = null;
};

var PathSelector = function(parent, item, parentDiv, onEnd, modulePath, langSelect, langLoad, path) {
	this.ModulePath = modulePath;
	this.Lang_SelectArea = langSelect;
	this.Lang_Loading = langLoad;
	this.Path = path || modulePath;
	this.Parent = parent;
	this.Area = item ? item.ID : 0;
	this.ParentDiv = parentDiv;
	this.Child = null;
	this.OnEnd = onEnd;
	
	this.oSelect = document.createElement('select');
	this.oOptionDef = document.createElement('option');
	this.oOptionDef.value = 0;
	iCMS.DOM.SetText(this.oOptionDef, this.Lang_Loading);
	this.oSelect.appendChild(this.oOptionDef);
	if (this.Area) this.oSelect.style.display = 'none';
	this.ParentDiv.appendChild(this.oSelect);
	this.oSubDiv = document.createElement('div');
	this.ParentDiv.appendChild(this.oSubDiv);
	this.Items = {};
	
	var o = this;
	iCMS.Events.Add(this.oSelect, 'change', function(){ o.OnChange(); });
	
	iCMS.AJAX("POST", this.ModulePath + "/list", { id : this.Area.toString() }, this.OnResponce, this);
	return this;
};
PathSelector.prototype.GetPath = function() {
	var r = '', id, item;
	if ((id = this.oSelect.value) && (item = this.Items[id]) && item.oOption) {
		r = '/' + item.Link;
	};
	return this.Path + r;
};
PathSelector.prototype.GetID = function() {
	if (this.Child) return this.Child.GetID();
	var id, item;
	if ((id = this.oSelect.value) && (item = this.Items[id]) && item.oOption) return id;
	else return this.Area;
};
PathSelector.prototype.GetItem = function() {
	var id, item;
	if (this.Child) item = this.Child.GetItem();
	if (!item && (id = this.oSelect.value)) item = this.Items[id];
	return item;
};
PathSelector.prototype.OnChange = function() {
	if (this.Child) {
		this.Child.Free();
		this.Child = null;
	};
	var id, item;
	if ((id = this.oSelect.value) && (item = this.Items[id]) && item.oOption) {
		this.Child = new PathSelector(this, item, this.oSubDiv, this.OnEnd, this.ModulePath, this.Lang_SelectArea, this.Lang_Loading, this.GetPath());
	};
};
PathSelector.prototype.OnResponce = function(items, o) {
	var id, L = items ? items.length : 0;
	if (L) {
		for (var i = 0; i < L; i++) {
			id = items[i].i;
			this.Items[id] = new PathSelectorItem(this.oSelect, items[i]);
		};
		iCMS.DOM.SetText(this.oOptionDef, this.Lang_SelectArea);
		this.oSelect.style.display = 'block';
	}
	else {
		if (this.Area) this.oSelect.style.display = 'none';
		if (this.OnEnd) this.OnEnd(this);
	}
};
PathSelector.prototype.Free = function() {
	if (this.Child) {
		this.Child.Free();
		this.Child = null;
	};
	for (var id in this.Items) {
		this.Items[id].Free();
		this.Items[id] = null;
	};
	this.Items = null;
	this.ParentDiv.removeChild(this.oSubDiv);
	this.oSubDiv = null;
	this.oSelect.removeChild(this.oOptionDef);
	this.oOptionDef = null;
	this.ParentDiv.removeChild(this.oSelect);
	this.oSelect = null;
};

function SelectRegion(id) {
	window.open('/region.php?id='+id, 'region', 'width=400,height=200');
};

// region selector
var RegionSelectorItem = function(parent,R) {
	this.Parent = parent;
	this.ID = R.i;
	this.Title = R.t;
	this.oOption = document.createElement('option');
	this.oOption.value = this.ID;
	iCMS.DOM.SetText(this.oOption, this.Title);
	this.Parent.appendChild(this.oOption);
	return this;
};
RegionSelectorItem.prototype.Free = function() {
	this.Parent.removeChild(this.oOption);
	this.oOption = null;
	this.Parent = null;
};

var RegionSelector = function(parent, item, parentDiv, onEnd, modulePath, langSelect, langLoad) {
	this.ModulePath = modulePath;
	this.Lang_SelectArea = langSelect;
	this.Lang_Loading = langLoad;
	this.Parent = parent;
	this.Level = 1 + (parent ? parent.Level : 0);
	this.Area = item ? item.ID : 0;
	this.ParentDiv = parentDiv;
	this.Child = null;
	this.OnEnd = onEnd;
	
	this.oSelect = document.createElement('select');
	this.oOptionDef = document.createElement('option');
	this.oOptionDef.value = 0;
	iCMS.DOM.SetText(this.oOptionDef, this.Lang_Loading);
	this.oSelect.appendChild(this.oOptionDef);
	if (this.Area) this.oSelect.style.display = 'none';
	this.ParentDiv.appendChild(this.oSelect);
	this.oSubDiv = document.createElement('div');
	this.ParentDiv.appendChild(this.oSubDiv);
	this.Items = {};
	
	var o = this;
	iCMS.Events.Add(this.oSelect, 'change', function(){ o.OnChange(); });
	
	iCMS.AJAX("POST", this.ModulePath + "/list", { id : this.Area.toString(), t : this.Level.toString() }, this.OnResponce, this);
	return this;
};
RegionSelector.prototype.GetID = function() {
	if (this.Child) return this.Child.GetID();
	var id, item;
	if ((id = this.oSelect.value) && (item = this.Items[id]) && item.oOption) return id;
	else return this.Area;
};
RegionSelector.prototype.GetItem = function() {
	var id, item;
	if (this.Child) item = this.Child.GetItem();
	if (!item && (id = this.oSelect.value)) item = this.Items[id];
	return item;
};
RegionSelector.prototype.OnChange = function() {
	if (this.Child) {
		this.Child.Free();
		this.Child = null;
	};
	var id, item;
	if ((id = this.oSelect.value) && (item = this.Items[id]) && item.oOption) {
		this.Child = new RegionSelector(this, item, this.oSubDiv, this.OnEnd, this.ModulePath, this.Lang_SelectArea, this.Lang_Loading);
	};
};
RegionSelector.prototype.OnResponce = function(items, o) {
	var id, L;
	if (items && (L = items.length)) {	// array or null
		for (var i = 0; i < L; i++) {
			id = items[i].i;
			this.Items[id] = new RegionSelectorItem(this.oSelect, items[i]);
		};
		iCMS.DOM.SetText(this.oOptionDef, this.Lang_SelectArea);
		this.oSelect.style.display = 'block';
	}
	else {
		if (this.Area) this.oSelect.style.display = 'none';
		if (this.OnEnd) this.OnEnd(this);
	};
};
RegionSelector.prototype.Free = function() {
	if (this.Child) {
		this.Child.Free();
		this.Child = null;
	};
	for (var id in this.Items) {
		this.Items[id].Free();
		this.Items[id] = null;
	};
	this.Items = null;
	this.ParentDiv.removeChild(this.oSubDiv);
	this.oSubDiv = null;
	this.oSelect.removeChild(this.oOptionDef);
	this.oOptionDef = null;
	this.ParentDiv.removeChild(this.oSelect);
	this.oSelect = null;
};

var CClickHint = function(id) {
	this.oDiv = ge(id);
	if (!this.oDiv) this.IsVisible = this.Show = this.Toggle = function(){};
	return this;
};
CClickHint.prototype.oDiv = null;
CClickHint.prototype.IsVisible = function() {
	return this.oDiv.style.display != 'none';
};
CClickHint.prototype.Show = function(b) {
	this.oDiv.style.display = b ? 'block' : 'none';
};
CClickHint.prototype.Toggle = function() {
	this.Show(!this.IsVisible());
};
var SettingsBlock, LoginBlock;

var NumberFieldValidator = 
{
	Init : function() {
		var inp = document.getElementsByTagName('INPUT'), o, h;
		if (!inp) return;
		var c, s;
		for (var k = 0, N = inp.length; k < N; k++) {
			o = inp[k];
			if (!(s = o.type || o.getAttribute('type')) || s.toLowerCase() != 'text') continue;
			c = o.className;
			if (!c) continue;
			c = c.Trim().toLowerCase().Split( /\s+/ );
			if (c.Search('number') != -1 && !o._i_number) {
				var min = void 0, max = void 0, dec = void 0, typ = void 0, req = false, intr = false;
				for (var i = 0, L = c.length; (min == void 0 || max == void 0 || dec == void 0 || typ == void 0) && i < L; i++) {
					if (c[i] == 'interval') intr = true;
					s = c[i].SubStr(0, 4);
					if (s == 'max-') max = 0 + Number(c[i].SubStr(4));
					else if (s == 'min-') min = 0 + Number(c[i].SubStr(4));
					else if (s == 'dec-') dec = 0 + Number(c[i].SubStr(4));
					else if (s == 'typ-') typ = c[i].SubStr(4);
					else if (s == 'req') req = true;
				};
				if (min == void 0 || max == void 0) min = max = false;
				
				h = document.createElement('SPAN');
				h.className = 'number';
				
				if (intr) {
					for (intr = o.nextSibling; intr && (!intr.tagName || intr.tagName.toUpperCase() != 'INPUT'); intr = intr.nextSibling);
				};
				if (intr && intr.tagName && intr.tagName.toUpperCase() == 'INPUT') {
					iCMS.DOM.ClassAdd(intr, ['number', 'err']);
					intr._i_number = {required:req, type:typ, decimals:dec, min:min, max:max, hint:h, interval:o, from:false};
					this.DoValidate(intr);
					iCMS.Events.Add(intr, 'change', this.OnChange);
					iCMS.Events.Add(intr, 'keydown', this.OnChange);
					iCMS.Events.Add(intr, 'keypress', this.OnChange);
					iCMS.Events.Add(intr, 'keyup', this.OnChange);
					iCMS.Events.Add(intr, 'blur', this.OnBlur);
				};
				// iCMS.DOM.SetText(h, '');
				iCMS.DOM.InsertAfter(h, intr ? intr : o);
				
				o._i_number = {required:req, type:typ, decimals:dec, min:min, max:max, hint:h, interval:intr, from:true};
				this.DoValidate(o);
				iCMS.Events.Add(o, 'change', this.OnChange);
				iCMS.Events.Add(o, 'keydown', this.OnChange);
				iCMS.Events.Add(o, 'keypress', this.OnChange);
				iCMS.Events.Add(o, 'keyup', this.OnChange);
				iCMS.Events.Add(o, 'blur', this.OnBlur);
			};
		};
	},
	OnChange : function(e) {
		e = e || window.event;
		var obj = e.target ? e.target : e.srcElement, c;
		if (obj && (c = obj._i_number)) {
			NumberFieldValidator.DoValidate(obj);
		};
	},
	OnBlur : function(e) {
		e = e || window.event;
		var obj = e.target ? e.target : e.srcElement, c;
		if (obj && (c = obj._i_number)) {
			if (c.value != void 0) obj.value = c.value;
		};
	},
	DoValidate : function(obj) {
		var v = obj.value, error, n, c = obj._i_number;
		do {
			if (v == '' && !c.required) break;
			if (c.type == 'int') {
				if (! /^[-+]?\d+$/.test(v) ) {
					error = 'Введите целое число.';
					break;
				};
			}
			else if (c.type == 'float') {
				v = v.Replace(/,/, '.');
				var m = v.match(/^[-+]?\d+(?:[,\.](\d*))?$/);
				if (!m) {
					error = 'Введите число.';
					break;
				};
				if (m[1] && m[1].length > c.decimals) {
					error = 'Допустимы только ' + c.decimals + ' цифр после запятой.';
					break;
				};
			}
			else break;
			
			n = Number(v);
			if (c.min !== false && c.max !== false && (n < c.min || n > c.max)) {
				n = void 0;
				error = 'Число находится вне допустимого диапазона.';
				break;
			};
		} while (0);
		c.value = n;
		if (error) {
			c.error = error;
			iCMS.DOM.ClassAdd(obj, 'err');
			iCMS.DOM.SetText(c.hint, error);
			iCMS.DOM.ClassAdd(c.hint, 'err');
		}
		else {
			c.error = void 0;
			iCMS.DOM.ClassDel(obj, 'err');
			iCMS.DOM.SetText(c.hint, '');
			iCMS.DOM.ClassDel(c.hint, 'err');
		};
		
		if (c.interval && c.interval._i_number) {
			error = [];
			var f1, f2, c1, c2;
			f1 = f2 = obj;
			c1 = c2 = c;
			if (c.from) {
				c2 = c.interval._i_number;
				f2 = c.interval;
			}
			else {
				c1 = c.interval._i_number;
				f1 = c.interval;
			};
			if (c1.error != void 0) error.Push(c1.error);
			if (c2.error != void 0) error.Push(c2.error);
			if (!error.length) {
				var has1 = c1.value != void 0, has2 = c2.value != void 0;
				if (has1) {
					if (has2) {
						if (c1.value > c2.value) error.Push('Интервал задан неверно.');
					}
					else error.Push('Укажите второе число.');
				}
				else {
					if (has2) error.Push('Укажите первое число.');
					else {
						if (c1.required) error.Push('Укажите второе число.', 'Укажите первое число.');
					};
				};
			};
			if (error.length) {
				iCMS.DOM.SetText(c1.hint, error.join(' '));
				iCMS.DOM.ClassAdd(c1.hint, 'err');
			}
			else {
				iCMS.DOM.SetText(c1.hint, '');
				iCMS.DOM.ClassDel(c1.hint, 'err');
			};
		};
	}
};

/*
 * string title	Dialog title
 * bool   noClose	No close button
 * array  elems	Array of element-or-text
 * string elems	HTML code of all elements
 * string left	CSS left for dialog window
 * string top	CSS top for dialog window
 * string right	CSS right for dialog window
 * string bottom	CSS bottom for dialog window
 * string width	CSS width for dialog window
 * string height	CSS height for dialog window
 */
function iDialog(param) {
	if (param == void 0) return this;
	if (!param) param = {};
	this.Param = param;
	this.CreateBackground();
	
	var _T = this;
	
	// window
	this.oWindow = document.createElement('DIV');
	this.oWindow.className = 'idialog';
	this.oWindow.style.display = 'none';
	if (param.left != void 0) this.oWindow.style.left = param.left;
	if (param.top != void 0) this.oWindow.style.top = param.top;
	if (param.right != void 0) this.oWindow.style.right = param.right;
	if (param.bottom != void 0) this.oWindow.style.bottom = param.bottom;
	if (param.width != void 0) this.oWindow.style.width = param.width;
	if (param.height != void 0) this.oWindow.style.height = param.height;
	this.oWindow._iDialog = this;
	document.body.appendChild(this.oWindow);
	
	// title bar
	var t = document.createElement('DIV');
	t.className = 'title';
	if (!param.noClose) {
		// [X]
		var o = document.createElement('DIV');
		o.className = 'close';
		o.innerHTML = "&#215;";
		iCMS.Events.Add(o, 'click', function(){
			_T.Show(false);
		});
		t.appendChild(o);
	};
	// caption
	var o = document.createElement('SPAN');
	o.className = 'caption';
	if (param.title != void 0) iCMS.DOM.SetText(o, param.title);
	t.appendChild(o);
	this.oWindow.appendChild(t);
	
	// client area
	this.oClient = document.createElement('DIV');
	this.oClient.className = 'client';
	this.oWindow.appendChild(this.oClient);
	this.SetContent(param.elems);
};
iDialog.prototype.Background = null;
iDialog.prototype.CreateBackground = function() {
	if (!this.Background) {
		iDialog.prototype.Background = document.createElement('DIV');
		this.Background.className = 'idialog_back';
		iCMS.DOM.SetStyles(this.Background, {
			display : 'none',
			backgroundColor : '#fff',
			opacity : '0.5'
		});
		document.body.appendChild(this.Background);
	};
};
iDialog.prototype.ShowBackground = function(b) {
	if (b === void 0 || b === null) b = this.Background.style.display == 'none';
};
iDialog.prototype.Show = function(b) {
	if (b === void 0 || b === null) b = this.oWindow.style.display == 'none';
	this.oWindow.style.display = this.Background.style.display = b ? 'block' : 'none';
	return b;
};
iDialog.prototype.SetContent = function(elems) {
	if (elems) {
		if (elems instanceof Array) {
			for (var i = 0, L = elems.length; i < L; i++) {
				if (typeof elems[i] != 'object') {
					var o = document.createElement('DIV');
					iCMS.DOM.SetText(o, elems[i]);
					elems[i] = o;
				};
				this.oClient.appendChild(elems[i]);
			};
		}
		else if (typeof elems == typeof '') this.oClient.innerHTML = elems;
	};
};

var iCalendar =
{
	reDateTime : /^(\d{4})-(\d{1,2})-(\d{1,2})(?:\s+\d{1,2}:\d{1,2}(?::\d{1,2})?)?$/ ,
	DateDecode : function(date) {
		var m;
		if (typeof date == 'string' && (m = date.match(this.reDateTime)) && +m[1] >= 1700 && +m[1] <= 9999 && +m[2] >= 1 && +m[2] <= 12 && +m[3] >= 1 && +m[3] <= 31) {
			return m[1] * 10000 + m[2] * 100 + m[3] * 1;
		}
		else return;
	},
	IsDate : function(date) {
		return this.reDateTime.test(date);
	},
	Add : function(btn, tx, t, min, max) {
		if (typeof Calendar == 'undefined' || !Calendar) return;
		// http://www.dynarch.com/projects/calendar/doc/
		var conf = {
			showTime : !!t,
			dateFormat : t ? '%Y-%m-%d %H:%M' : '%Y-%m-%d',
			onSelect : function(cal) { cal.hide(); },
			trigger : btn,
			inputField : tx,
			min : this.DateDecode(min) || 17000101,
			max : this.DateDecode(max) || 99991231
		};
		Calendar.setup(conf);
	}
};

var iAttach =
{
	oField : null,
	oLastField : null,
	Index : 0,
	Name : 'file',
	Count : 10,
	AddField : function(btn) {
		if (!this.oField) {
			this.oField = ge('attach_file');
			this.Name = btn.getAttribute('i-add-name') || this.Name;
			this.Count = +btn.getAttribute('i-add-count') || this.Count;
			this.Index++;
			this.oLastField = this.oField;
		};
		if (this.Index > this.Count) return;
		
		var o = document.createElement('input');
		o.setAttribute('type', 'file');
		o.setAttribute('name', 'file[' + this.Index + ']');
		o.className = this.oField.className;
		iCMS.DOM.InsertAfter(o, this.oLastField);
		this.oLastField = o;
		if (++this.Index > this.Count) btn.style.display = 'none';
	}
};

var iBannerControl =
{
	Banners : null,
	oBanners : {},
	oBannerSelect : null,
	oBannerOptions : {},
	oBannerDialog : null,
	oBannerDialogOK : null,
	oBannerDialogOKOnClick : null,
	oBannerDialogOKOnClose : null,
	Hidden : null,
	Div : null,
	AppendDiv : null,
	aAppend : null,
	BakValue : null,
	oList : [],
	Init : function(hid) {
		var i, L, o, id, T = this;
		
		this.Hidden = ge(hid);
		this.BakValue = this.Hidden.value;
		
		this.oBannerSelect = document.createElement('select');
		this.oBannerSelect.className = 'select';
		for (i = 0, L = this.Banners.length; i < L; i++) {
			o = document.createElement('option');
			id = this.Banners[i][0];
			this.oBanners[id] = this.Banners[i][1];
			o.setAttribute('value', id);
			iCMS.DOM.SetText(o, this.Banners[i][1]);
			this.oBannerSelect.appendChild(o);
			this.oBannerOptions[id] = o;
		};
		this.oBannerDialogOK = document.createElement('input');
		this.oBannerDialogOK.setAttribute('type', 'button');
		this.oBannerDialogOK.className = 'submit';
		this.oBannerDialogOK.value = "OK";
		this.oBannerDialogOKOnClick = function() {
			if (T.oBannerDialogOKOnClose instanceof Function) T.oBannerDialogOKOnClose.call(T);
		};
		iCMS.Events.Add(this.oBannerDialogOK, 'click', this.oBannerDialogOKOnClick);
		this.oBannerDialog = new iDialog({
			width : '60%',
			left : '20%',
			top : '40%',
			title : "Выбор баннера",
			elems : [
				this.oBannerSelect,
				this.oBannerDialogOK
			]
		});
		
		this.Div = document.createElement('div');
		iCMS.DOM.InsertAfter(this.Div, this.Hidden);
		
		this.AppendDiv = document.createElement('div');
		iCMS.DOM.InsertAfter(this.AppendDiv, this.Div);
		
		this.aAppend = document.createElement('a');
		this.aAppend.setAttribute('href', '#');
		this.aAppend.setAttribute('title', "Добавить");
		this.aAppend.className = 'icon';
		this.aAppend.innerHTML = '<span class="plus"></span>';
		iCMS.Events.Add(this.aAppend, 'click', function(e){
			T.AppendItem();
			if (e.preventDefault) e.preventDefault();
			if (e.stopPropagation) e.stopPropagation();
			e.cancelBubble = true;
			return e.returnValue = false;
		});
		this.AppendDiv.appendChild(this.aAppend);
		
		this.aClear = document.createElement('a');
		this.aClear.setAttribute('href', '#');
		this.aClear.setAttribute('title', "Очистить");
		this.aClear.className = 'icon';
		this.aClear.innerHTML = '<span class="del"></span>';
		iCMS.Events.Add(this.aClear, 'click', function(e){
			T.ClearList();
			if (e.preventDefault) e.preventDefault();
			if (e.stopPropagation) e.stopPropagation();
			e.cancelBubble = true;
			return e.returnValue = false;
		});
		this.AppendDiv.appendChild(this.aClear);
		
		this.CreateList();
	},
	Reset : function() {
		this.ClearList();
		this.Hidden.value = this.BakValue;
		this.CreateList();
	},
	Apply : function() {
		var R = [], s, i, L, Item;
		for (i = 0, L = this.oList.length; i < L; i++) {
			Item = this.oList[i];
			s = '' + Item.id;
			if (iCalendar.reDateTime.test(Item.inpDate.value)) {
				s += ',' + Item.inpDate.value;
			};
			R.Push(s);
		};
		this.Hidden.value = R.join('|');
	},
	_DoAppend : function(item) {
		if (!item) return;
		item.Index = this.oList.length;
		this.oList[item.Index] = item;
		this.oBannerOptions[item.id].style.display = 'none';
		this.oBannerOptions[item.id].disabled = true;
		this.Div.appendChild(item.div);
	},
	_DoInsert : function(index, item) {
		if (!item) return;
		var i, L = this.oList.length;
		if (index < 0) index = 0;
		else if (index > L) index = L;
		item.Index = index;
		for (var i = L - 1; i >= index; i--) {
			this.oList[i].Index++;
			this.oList[i + 1] = this.oList[i];
		};
		this.oList[index] = item;
		this.oBannerOptions[item.id].style.display = 'none';
		this.oBannerOptions[item.id].disabled = true;
		if (index < L) iCMS.DOM.InsertBefore(item.div, this.oList[index + 1].div);
		else this.Div.appendChild(item.div);
	},
	_DoRemove : function(index) {
		var Item = this.oList[index], i, L;
		if (!Item) return;
		this.Div.removeChild(Item.div);
		delete this.oBannerOptions[Item.id].style.display;
		this.oBannerOptions[Item.id].disabled = false;
		this.oList.Unset(index);
		L = this.oList.length;
		for (i = index; i < L; i++) this.oList[i].Index = i;
	},
	ClearList : function() {
		var i, L, Item;
		L = this.oList.length;
		for (i = 0; i < L; i++) {
			Item = this.oList[i];
			this.Div.removeChild(Item.div);
			delete this.oBannerOptions[Item.id].style.display;
			this.oBannerOptions[Item.id].disabled = false;
		};
		this.oList.length = 0;
		this.Hidden.value = '';
	},
	CreateList : function() {
		this.oList = [];
		var List = this.Hidden.value || '', i, L, s, Item;
		if (List == '') return;
		List = List.split('|');
		for (i = 0, L = List.length; i < L; i++) {
			s = List[i].split(',');
			this._DoAppend(this.CreateItem(+s[0], s[1]));
		};
	},
	CreateItem : function(id, date) {
		if (!(id in this.oBanners)) return;
		date = date || '';
		var Item = { 'id' : id, 'date' : date }, T = this;
		Item.div = document.createElement('div');
		Item.div._i_Item = Item;
		
		Item.span = document.createElement('span');
		iCMS.DOM.SetText(Item.span, this.oBanners[id]);
		Item.div.appendChild(Item.span);
		
		Item.inpDate = document.createElement('input');
		Item.inpDate.setAttribute('type', 'text');
		Item.inpDate.setAttribute('title', "Истекает");
		Item.inpDate.className = 'date';
		Item.inpDate.value = date;
		Item.div.appendChild(Item.inpDate);
		Item.btnDate = document.createElement('input');
		Item.btnDate.setAttribute('type', 'button');
		Item.btnDate.className = 'button';
		Item.btnDate.value = '...';
		Item.div.appendChild(Item.btnDate);
		iCalendar.Add(Item.btnDate, Item.inpDate, true);
		
		Item.aAdd = document.createElement('a');
		Item.aAdd.setAttribute('href', '#');
		Item.aAdd.setAttribute('title', "Вставить");
		Item.aAdd.className = 'icon';
		Item.aAdd.innerHTML = '<span class="plus"></span>';
		iCMS.Events.Add(Item.aAdd, 'click', function(e) {
			T.InsertItem(Item.Index);
			if (e.preventDefault) e.preventDefault();
			if (e.stopPropagation) e.stopPropagation();
			e.cancelBubble = true;
			return e.returnValue = false;
		});
		Item.div.appendChild(Item.aAdd);
		
		Item.aDel = document.createElement('a');
		Item.aDel.setAttribute('href', '#');
		Item.aDel.setAttribute('title', "Удалить из списка");
		Item.aDel.className = 'icon';
		Item.aDel.innerHTML = '<span class="del"></span>';
		iCMS.Events.Add(Item.aDel, 'click', function(e) {
			T.DeleteItem(Item.Index);
			if (e.preventDefault) e.preventDefault();
			if (e.stopPropagation) e.stopPropagation();
			e.cancelBubble = true;
			return e.returnValue = false;
		});
		Item.div.appendChild(Item.aDel);
		
		Item.arrows = document.createElement('span');
		Item.arrows.className = 'arrows';
		Item.div.appendChild(Item.arrows);
		
		Item.aUp = document.createElement('a');
		Item.aUp.setAttribute('href', '#');
		Item.aUp.setAttribute('title', "Выше");
		Item.aUp.className = '';
		Item.aUp.innerHTML = '<u class="a">\u2191</u>';
		iCMS.Events.Add(Item.aUp, 'click', function(e) {
			T.MoveUpItem(Item.Index);
			if (e.preventDefault) e.preventDefault();
			if (e.stopPropagation) e.stopPropagation();
			e.cancelBubble = true;
			return e.returnValue = false;
		});
		Item.arrows.appendChild(Item.aUp);
		
		Item.aDown = document.createElement('a');
		Item.aDown.setAttribute('href', '#');
		Item.aDown.setAttribute('title', "Ниже");
		Item.aDown.innerHTML = '<u class="a">\u2193</u>';
		iCMS.Events.Add(Item.aDown, 'click', function(e) {
			T.MoveDownItem(Item.Index);
			if (e.preventDefault) e.preventDefault();
			if (e.stopPropagation) e.stopPropagation();
			e.cancelBubble = true;
			return e.returnValue = false;
		});
		Item.arrows.appendChild(Item.aDown);
		
		return Item;
	},
	DeleteItem : function(i) {
		if (i < 0 || i >= this.oList.length) return;
		this._DoRemove(i);
	},
	MoveUpItem : function(i) {
		if (i == 0 || i >= this.oList.length) return;
		var Item = this.oList[i], Prev = this.oList[i - 1];
		iCMS.DOM.InsertBefore(Item.div, Prev.div);
		Item.Index--;
		Prev.Index++;
		var tmp = this.oList[i];
		this.oList[i] = this.oList[i - 1];
		this.oList[i - 1] = tmp;
	},
	MoveDownItem : function(i) {
		if (i < 0 || i >= this.oList.length - 1) return;
		var Item = this.oList[i], Next = this.oList[i + 1];
		iCMS.DOM.InsertAfter(Item.div, Next.div);
		Item.Index++;
		Next.Index--;
		var tmp = this.oList[i];
		this.oList[i] = this.oList[i + 1];
		this.oList[i + 1] = tmp;
	},
	InsertItem : function(i) {
		if (i < 0 || i >= this.oList.length) return;
		this.SelectBanner(function(N) {
			this._DoInsert(i, this.CreateItem(N));
		});
	},
	AppendItem : function() {
		this.SelectBanner(function(N) {
			this._DoAppend(this.CreateItem(N));
		});
	},
	SelectBanner : function(onselect) {
		if (this.oList.length >= this.Banners.length) {
			alert("Все существующие баннеры уже добавлены в список.");
			return;
		};
		this.oBannerDialogOKOnClose = function() {
			this.oBannerDialog.Show(false);
			onselect.call(this, this.oBannerSelect.value);
		};
		this.oBannerDialog.Show(true);
	}
};

function iBannerSwitch(id) {
	var o, list = [], i, n, L = 0, f, cur;
	o = ge(id);
	iCMS.DOM.EachChildNode(o, function(div){
		if (i == void 0 && div.style.display != 'none') i = list.length;
		list.Push({
			div : div,
			dt : parseInt(div.getAttribute('i-dt') || 20)
		});
	});
	L = list.length;
	if (!L) return;
	if (i == void 0) {
		i = 0;
		list[i].div.style.display = '';
	};
	if (L <= 1) return;
	cur = list[i];
	setTimeout(f = function() {
		cur.div.style.display = 'none';
		i++;
		if (i >= L) i = 0;
		cur = list[i];
		cur.div.style.display = '';
		setTimeout(f, cur.dt * 1000);
	}, cur.dt * 1000);
};

var iFadeOut = (function(){
	var C = function(el, speed){
		if (!el) return;
		this.Opacity = 0;
		this.Speed = speed; // ms
		this.dx = 1 / (this.FPS * this.Speed / 1000);
		this.Running = false;
		iCMS.DOM.SetOpacity(el, this.Opacity);
		this.Layer = el;
		this.Layer.style.display = 'block';
		
		iCMS.Events.Add(el, 'mouseover', (function(T){
			return function(e){
				e = e || window.event;
				var o = e.target || e.srcElement;
				if (o == el) T.OnMouseOver();
			};
		})(this));
		iCMS.Events.Add(el, 'mouseout', (function(T){
			return function(e){
				e = e || window.event;
				var o = e.target || e.srcElement;
				if (o == el) T.OnMouseOut();
			};
		})(this));
	};
	C.prototype.FPS = 20;
	C.prototype.Stop = function() {
		if (this.Running) {
			clearInterval(this.Running);
			this.Running = false;
		};
	};
	C.prototype.OnMouseOver = function() {
		this.Stop();
		var T = this;
		this.Running = setInterval(function(){
			T.Opacity += T.dx;
			if (T.Opacity >= 1) {
				T.Opacity = 1;
				T.Stop();
			};
			iCMS.DOM.SetOpacity(T.Layer, T.Opacity);
		}, this.FPS);
	};
	C.prototype.OnMouseOut = function() {
		this.Stop();
		var T = this;
		this.Running = setInterval(function(){
			T.Opacity -= T.dx;
			if (T.Opacity <= 0) {
				T.Opacity = 0;
				T.Stop();
			};
			iCMS.DOM.SetOpacity(T.Layer, T.Opacity);
		}, this.FPS);
	};
	return C;
})();

iCMS.Load(function(){
	NumberFieldValidator.Init();
	SettingsBlock = new CClickHint('settings_menu');
	LoginBlock = new CClickHint('login_form');
	
	// add Ctrl+Enter to comment form
	var t = ge('id_comment_teaxarea'), f;
	if (t) {
		// search form for posting a comment
		for (f = t; f && f.tagName.toUpperCase() != 'FORM'; f = f.parentNode);
		// if find valid form
		if (f && f.submit) {
			iCMS.Events.Add(t, 'keydown', function(e) {
				e = e || window.event;
				if (e.keyCode == 13 && e.ctrlKey) {
					f.submit();
				};
			});
		};
	};
});


