var jsPopup = {
	div_id: 'bx_popup_form_div',
	overlay_id: 'bx_popup_overlay',
	form_name: 'bx-popup-form',
	class_name: 'bx-popup-form',
	
	url: '',
	arParams: null,
	
	bDenyClose: false,

	__arRuntimeResize: {},
	
	bodyOverflow : "",
	currentScroll : 0,
	
	div: null,
	div_inner: null,
	
	x: 0,
	y: 0,
	
	DenyClose: function()
	{
		this.bDenyClose = true;
		
		var obSaveButton = document.getElementById('btn_popup_save');
		var obCloseButton = document.getElementById('btn_popup_close');
		var obCancelButton = document.getElementById('btn_popup_cancel');
		
		if (obSaveButton) obSaveButton.disabled = true;
		if (obCloseButton) obCloseButton.disabled = true;
		if (obCancelButton) obCancelButton.disabled = true;
	},
	
	AllowClose: function()
	{
		this.bDenyClose = false;

		var obSaveButton = document.getElementById('btn_popup_save');
		var obCloseButton = document.getElementById('btn_popup_close');
		var obCancelButton = document.getElementById('btn_popup_cancel');
		
		if (obSaveButton) obSaveButton.disabled = false;
		if (obCloseButton) obCloseButton.disabled = false;
		if (obCancelButton) obCancelButton.disabled = false;
	},
	
	__OnKeyPress: function(e) // do not use 'this': will be called in other context
	{
		if (!e) e = window.event
		if (!e) return;
		if (jsPopup.bDenyClose) return;
		if (e.keyCode == 27)
		{
			jsUtils_n.removeEvent(document, "keypress", jsPopup.__OnKeyPress);
			jsPopup.CloseDialog();
		}
	},
	
	AjaxAction: function(result) // do not use 'this': will be called in other context
	{
		CloseWaitWindow();

		var div = document.body.appendChild(document.createElement("DIV"));
		div.id = jsPopup.div_id;
		div.className = jsPopup.class_name;
		div.style.position = 'absolute';
		div.style.zIndex = 1020;
		
		div.innerHTML = result;

		if (null != jsPopup.arParams.height)
			div.style.height = jsPopup.arParams.height + 'px';
		if (null != jsPopup.arParams.width)
			div.style.width = jsPopup.arParams.width + 'px';

		var windowSize = jsUtils_n.GetWindowInnerSize();
		var windowScroll = jsUtils_n.GetWindowScrollPos();

		var left = parseInt(windowScroll.scrollLeft + windowSize.innerWidth/2 - div.offsetWidth/2);
		var top = parseInt(windowScroll.scrollTop + windowSize.innerHeight/2 - div.offsetHeight/2);

		jsFloatDiv.Show(div, left, top, 5, true);
		jsUtils_n.addEvent(document, "keypress", jsPopup.__OnKeyPress);
		
		jsPopup.div = div;
		jsPopup.div_inner = document.getElementById('bx_popup_content');

		if (jsPopup.arParams.resize && null != jsPopup.div && null != jsPopup.div_inner)
			jsPopup.createResizer();
		
		return div;
	},
	
	__AjaxPostAction: function(result) // do not use 'this': will be called in other context
	{
		CloseWaitWindow();

		jsPopup.div.innerHTML = result;
		jsPopup.div_inner = document.getElementById('bx_popup_content');

		jsPopup.AdjustShadow();

		if (jsPopup.arParams.resize && null != jsPopup.div && null != jsPopup.div_inner)
			jsPopup.createResizer();

	},

	/*
	arParams = {
		width: window width in px
		height: window height in px
		resize: true|false - flag showing whether window is resizable
		min_width: min window width while resizing (250 by def.)
		min_height: min window height while resizing (200 by def.)
	}
	*/
	ShowDialog: function(url, arParams)
	{
		if (document.getElementById(this.div_id))
			this.CloseDialog();

		if (null == arParams) arParams = {};
			
		if (null == arParams.resize) arParams.resize = true;
		if (null == arParams.min_width) arParams.min_width = 250;
		if (null == arParams.min_height) arParams.min_height = 200;

		var pos = url.indexOf('?');
		if (pos == -1)
			url += "?mode=public";
		else
			url = url.substring(0, pos) + "?mode=public&" + url.substring(pos+1);

		jsPopup.check_url = pos == -1 ? url : url.substring(0, pos);
		if (arParams.resize && null != jsPopup.__arRuntimeResize[jsPopup.check_url])
		{
			arParams.width = jsPopup.__arRuntimeResize[jsPopup.check_url].width;
			arParams.height = jsPopup.__arRuntimeResize[jsPopup.check_url].height;
			
			//console.log(url);
			var ipos = url.indexOf('bxpiheight');
			//console.log(ipos);
			if (ipos == -1)
				url += (pos == -1 ? '?' : '&') + 'bxpiheight=' + jsPopup.__arRuntimeResize[jsPopup.check_url].iheight;
			else
				url = url.substring(0, ipos) + 'bxpiheight=' + jsPopup.__arRuntimeResize[jsPopup.check_url].iheight;
				
			//console.log(url);
		}

		this.url = url;
		this.arParams = arParams;

		this.CreateOverlay();

		jsExtLoader.onajaxfinish = this.AjaxAction;
		jsExtLoader.start(url);
	},

	RemoveOverlay: function()
	{
		var overlay = document.getElementById(this.overlay_id);

		if (overlay)
			overlay.parentNode.removeChild(overlay);

		jsUtils_n.removeEvent(window, "resize", this.OverlayResize);
	},

	OverlayResize: function(event)
	{
		var overlay = document.getElementById(jsPopup.overlay_id);

		if (!overlay)
			return;

		var windowSize = jsUtils_n.GetWindowScrollSize();

		overlay.style.width = windowSize.scrollWidth + "px";
	},

	CreateOverlay: function()
	{
		var opacity = new COpacity();

		if (!opacity.GetOpacityProperty())
			return;

		//Create overlay
		var overlay = document.body.appendChild(document.createElement("DIV"));
		overlay.className = "bx-popup-overlay";
		overlay.id = this.overlay_id;

		var windowSize = jsUtils_n.GetWindowScrollSize();

		overlay.style.width = windowSize.scrollWidth + "px";
		overlay.style.height = windowSize.scrollHeight + "px";

		jsUtils_n.addEvent(window, "resize", this.OverlayResize);
	},

	CloseDialog: function()
	{
		jsUtils_n.onCustomEvent('OnBeforeCloseDialog');
		
		if (this.bDenyClose)
			return false;

		jsUtils_n.removeEvent(document, "keypress", this.__OnKeyPress);
		var div = document.getElementById(this.div_id);
		jsFloatDiv.Close(div);
		div.parentNode.removeChild(div);

		this.RemoveOverlay();
		
		return true;
	},
	
	GetParameters: function(form_name)
	{
		if (null == form_name)
			var form = document.forms[this.form_name];
		else
			var form = document.forms[form_name];
		
		if(!form)
			return "";

		var i, s = "";
		var n = form.elements.length;
		
		var delim = '';
		for(i=0; i<n; i++)
		{
			if (s != '') delim = '&';
			
			var el = form.elements[i];
			if (el.disabled)
				continue;

			switch(el.type.toLowerCase())
			{
				case 'text':
				case 'textarea':
				case 'password':
				case 'hidden':
					if (null == form_name && el.name.substr(el.name.length-4) == '_alt' && form.elements[el.name.substr(0, el.name.length-4)])
						break;
					s += delim + el.name + '=' + jsUtils_n.urlencode(el.value);
					break;
				case 'radio':
					if(el.checked)
						s += delim + el.name + '=' + jsUtils_n.urlencode(el.value);
					break;
				case 'checkbox':
					s += delim + el.name + '=' + jsUtils_n.urlencode(el.checked ? 'Y':'N');
					break;
				case 'select-one':
					var val = "";
					if (null == form_name && form.elements[el.name + '_alt'] && el.selectedIndex == 0)
						val = form.elements[el.name+'_alt'].value;
					else
						val = el.value;
					s += delim + el.name + '=' + jsUtils_n.urlencode(val);
					break;
				case 'select-multiple':
					var j;
					var l = el.options.length;
					for (j=0; j<l; j++)
						if (el.options[j].selected)
							s += delim + el.name + '=' + jsUtils_n.urlencode(el.options[j].value);
					break;
				default:
					break;
			}
		}
		
		if (null != jsPopup.arParams && jsPopup.arParams.resize && jsPopup.div_inner)
		{
			var inner_width = parseInt(jsPopup.div_inner.style.width);
			var inner_height = parseInt(jsPopup.div_inner.style.height);
		
			if (inner_width > 0)
				s += '&bxpiwidth=' + inner_width;
			if (inner_height > 0)
				s += '&bxpiheight=' + inner_height;
		}
		
		return s;
	},
	
	PostParameters: function(params)
	{
		jsExtLoader.onajaxfinish = jsPopup.__AjaxPostAction

		ShowWaitWindow();
		
		var url = jsPopup.url;
		if (null != params)
		{
			index = url.indexOf('?')
			if (index == -1)
				url += '?' + params;
			else
				url = url.substring(0, index) + '?' + params + "&" + url.substring(index+1);
		}
		
		jsExtLoader.startPost(url, jsPopup.GetParameters());
	},

	PostParametersOld: function(params)
	{
		CHttpRequest.Action = jsPopup.__AjaxPostAction;

		ShowWaitWindow();
		
		var url = jsPopup.url;
		if (null != params)
		{
			index = url.indexOf('?')
			if (index == -1)
				url += '?' + params;
			else
				url = url.substring(0, index) + '?' + params + "&" + url.substring(index+1);
		}
		
		CHttpRequest.Post(url, jsPopup.GetParameters());
	},
	
	AdjustShadow: function()
	{
		if (jsPopup.div)
			jsFloatDiv.AdjustShadow(jsPopup.div);
	},

	HideShadow: function()
	{
		if (jsPopup.div)
			jsFloatDiv.HideShadow(jsPopup.div);
	},

	UnhideShadow: function()
	{
		if (jsPopup.div)
			jsFloatDiv.UnhideShadow(jsPopup.div);
	},
	
	DragPanel: function(event, td)
	{
		var div = jsUtils_n.FindParentObject(td, 'div');
		div.style.left = div.offsetLeft+'px';
		div.style.top = div.offsetTop+'px';
		jsFloatDiv.StartDrag(event, div);
	},
	
	// ************* resizers ************* //
	createResizer: function()
	{
		jsPopup.diff_x = null;
		jsPopup.diff_y = null;
	
		jsPopup.arPos = jsUtils_n.GetRealPos(jsPopup.div);
		
		var zIndex = parseInt(jsUtils_n.GetStyleValue(jsPopup.div, 'z-index')) + 1;
		
		jsPopup.obResizer = document.createElement('DIV');
		jsPopup.obResizer.className = 'bxresizer';
		
		jsPopup.obResizer.style.position = 'absolute';
		jsPopup.obResizer.style.zIndex = zIndex;

		jsPopup.obResizer.onmousedown = jsPopup.startResize;
		
		jsPopup.div.appendChild(jsPopup.obResizer);
	},
	
	startResize: function (e)
	{
		if(!e)
			e = window.event;

		jsPopup.wndSize = jsUtils_n.GetWindowScrollPos();
		jsPopup.wndSize.innerWidth = jsUtils_n.GetWindowInnerSize().innerWidth;

		jsPopup.x = e.clientX + jsPopup.wndSize.scrollLeft;
		jsPopup.y = e.clientY + jsPopup.wndSize.scrollTop;

		if (jsUtils_n.IsIE())
		{
			jsPopup.arPos = jsPopup.div.getBoundingClientRect();
			jsPopup.arPos = {
				left: jsPopup.arPos.left + jsPopup.wndSize.scrollLeft,
				top: jsPopup.arPos.top + jsPopup.wndSize.scrollTop,
				right: jsPopup.arPos.right + jsPopup.wndSize.scrollLeft,
				bottom: jsPopup.arPos.bottom + jsPopup.wndSize.scrollTop
			}
			jsPopup.arPosInner = jsPopup.div_inner.getBoundingClientRect();
			jsPopup.arPosInner = {
				left: jsPopup.arPosInner.left + jsPopup.wndSize.scrollLeft,
				top: jsPopup.arPosInner.top + jsPopup.wndSize.scrollTop,
				right: jsPopup.arPosInner.right + jsPopup.wndSize.scrollLeft,
				bottom: jsPopup.arPosInner.bottom + jsPopup.wndSize.scrollTop
			}
		}
		else
		{
			jsPopup.arPos = jsUtils_n.GetRealPos(jsPopup.div);
			jsPopup.arPosInner = jsUtils_n.GetRealPos(jsPopup.div_inner);
		}
	
		document.onmouseup = jsPopup.stopResize;
		jsUtils_n.addEvent(document, "mousemove", jsPopup.doResize);
		
		if(document.body.setCapture)
			document.body.setCapture();

		var b = document.body;
	    b.ondrag = jsUtils_n.False;
	    b.onselectstart = jsUtils_n.False;
	    b.style.MozUserSelect = jsPopup.div.style.MozUserSelect = 'none';
		b.style.cursor = jsPopup.obResizer.style.cursor;
		
		jsPopup.HideShadow();
	},
	
	doResize: function (e)
	{
		if(!e)
			e = window.event;

		var x = e.clientX + jsPopup.wndSize.scrollLeft;
		var y = e.clientY + jsPopup.wndSize.scrollTop;
		
		if(jsPopup.x == x && jsPopup.y == y || x > jsPopup.wndSize.innerWidth + jsPopup.wndSize.scrollLeft - 10)
			return;

		jsPopup.Resize(x, y);
		jsPopup.x = x;
		jsPopup.y = y;
	},
	
	Resize: function(x, y)
	{
		if (null == jsPopup.diff_x)
		{
			jsPopup.diff_x = jsPopup.div.offsetWidth - jsPopup.div_inner.offsetWidth;
			jsPopup.diff_y = jsPopup.div.offsetHeight - jsPopup.div_inner.offsetHeight;
		}

		var new_width = x - jsPopup.arPos.left;
		var new_height = y - jsPopup.arPos.top;

		var dx = new_width - jsPopup.div.offsetWidth;
		var dy = y - jsPopup.y;
	
		if (new_width > jsPopup.arParams.min_width)
		{
			jsPopup.div.style.width = new_width + 'px';
			jsPopup.div_inner.style.width = (new_width - jsPopup.diff_x) + 'px';
		}
		
		if (new_height > jsPopup.arParams.min_height)
		{
			jsPopup.div_inner.style.height = (new_height - jsPopup.diff_y) + 'px';
			jsPopup.div.style.height = new_height + 'px';
		}
		
		if (jsUtils_n.IsIE())
			jsPopup.AdjustShadow();
	},
	
	stopResize: function ()
	{
		if(document.body.releaseCapture)
			document.body.releaseCapture();

		jsUtils_n.removeEvent(document, "mousemove", jsPopup.doResize);

		document.onmouseup = null;
		
		var b = document.body;
		b.ondrag = null;
		b.onselectstart = null;
		b.style.MozUserSelect = jsPopup.div.style.MozUserSelect = '';
	    b.style.cursor = '';
		
		jsPopup.UnhideShadow();
		jsPopup.AdjustShadow();
		
		jsPopup.SavePosition()
	},
	
	SavePosition: function()
	{
		var arPos = {
			width: parseInt(jsPopup.div.style.width), 
			height: parseInt(jsPopup.div.style.height), 
			iheight: parseInt(jsPopup.div_inner.style.height)
		};
		
		jsUserOptions.SaveOption('jsPopup', 'size_' + jsPopup.check_url, 'width', arPos.width);
		jsUserOptions.SaveOption('jsPopup', 'size_' + jsPopup.check_url, 'height', arPos.height);
		jsUserOptions.SaveOption('jsPopup', 'size_' + jsPopup.check_url, 'iheight', arPos.iheight);
		
		jsPopup.__arRuntimeResize[jsPopup.check_url] = arPos;
	},
	
	// **************** additional ************************* //
	ClearCache: function(params)	
	{
		CHttpRequest.Action = function(result)
		{
			window.location = window.location.href;
		}
		ShowWaitWindow();
		CHttpRequest.Send('/bitrix/admin/clear_component_cache.php?'+params);
	},
	
	IncludePrepare: function()
	{
		var obFrame = window.frames.editor;
		if (null == obFrame)
			return false;
		
		var obSrcForm = obFrame.document.forms.inner_form;
		var obDestForm = document.forms[this.form_name];
		
		if (null == obSrcForm || null == obDestForm)
			return false;
		
		obDestForm.include_data.value = obSrcForm.filesrc_pub.value;
		
		return true;
	},
	
	ShowError: function(error_text)
	{
		CloseWaitWindow();
		jsPopup.AllowClose();
		alert(error_text);
	}
}

function COpacity(element)
{
	this.element = element;
	this.opacityProperty = this.GetOpacityProperty();

	this.startOpacity = null;
	this.finishOpacity = null;
	this.delay = 30;

	this.currentOpacity = null;
	this.fadingTimeoutID = null;
}


COpacity.prototype.SetElementOpacity = function(opacity)
{
	if (!this.opacityProperty)
		return false;

	if (this.opacityProperty == "filter")
	{
		opacity = opacity * 100;
		var alphaFilter = this.element.filters['DXImageTransform.Microsoft.alpha'] || this.element.filters.alpha;
		if (alphaFilter) 
			alphaFilter.opacity = opacity;
		else 
			this.element.style.filter += "progid:DXImageTransform.Microsoft.Alpha(opacity="+opacity+")";
	}
	else
		this.element.style[this.opacityProperty] = opacity;

	return true;
}

COpacity.prototype.GetOpacityProperty = function()
{
	if (typeof document.body.style.opacity == 'string')
		return 'opacity';
	else if (typeof document.body.style.MozOpacity == 'string')
		return 'MozOpacity';
	else if (typeof document.body.style.KhtmlOpacity == 'string')
		return 'KhtmlOpacity';
	else if (document.body.filters && navigator.appVersion.match(/MSIE ([\d.]+);/)[1]>=5.5)
		return 'filter';

	return false;
}

COpacity.prototype.Fading = function(startOpacity, finishOpacity, callback)
{
	if (!this.opacityProperty)
		return;

	this.startOpacity = startOpacity;
	this.finishOpacity = finishOpacity;
	this.currentOpacity = this.startOpacity;

	if (this.fadingTimeoutID)
		clearInterval(this.fadingTimeoutID);

	var _this = this;
	this.fadingTimeoutID = setInterval(function () {_this.Run(callback)}, this.delay);
}

COpacity.prototype.Run = function(callback)
{
	this.currentOpacity = Math.round((this.currentOpacity + 0.1*(this.finishOpacity - this.startOpacity > 0 ? 1: -1) )*10) / 10;
	this.SetElementOpacity(this.currentOpacity);

	if (this.currentOpacity == this.startOpacity || this.currentOpacity == this.finishOpacity)
	{
		clearInterval(this.fadingTimeoutID);
		if (typeof(callback) == "function")
			callback(this);
	}
}

COpacity.prototype.Undo = function()
{
}

// this object can be used to load any pages with huge scripts structure via AJAX
var jsExtLoader = {
	obContainer: null,
	obContainerInner: null,
	
	url: '',

	httpRequest: null,
	httpRequest2: null, // for Opera bug fix

	obTemporary: null,
	
	onajaxfinish: null,
	
	obFrame: null,
	
	start: function(url)
	{
		this.url = url;

		this.obContainer = null;
		
		ShowWaitWindow();
		
		this.httpRequest = this._CreateHttpObject();
		this.httpRequest.onreadystatechange = jsExtLoader.stepOne;

		this.httpRequest.open("GET", this.url, true);
		this.httpRequest.send("");
	},
	
	startPost: function(url, data)
	{
		this.url = url;
		this.obContainer = null;
		
		ShowWaitWindow();
		
		this.httpRequest = this._CreateHttpObject();
		this.httpRequest.onreadystatechange = jsExtLoader.stepOne;

		this.httpRequest.open("POST", this.url, true);
		this.httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
		this.httpRequest.send(data);
	},
	
	post: function(form_name)
	{
		var obForm = document.forms[form_name];
		if (null == obForm)
			return;
	
		if (null == this.obFrame)
		{
			if (jsUtils_n.IsIE())
				this.obFrame = document.createElement('<iframe src="javascript:void(0)" name="frame_' + form_name + '">');
			else
			{
				this.obFrame = document.createElement('IFRAME');
				this.obFrame.name = 'frame_' + form_name;
				this.obFrame.src = 'javascript:void(0)';
			}
			
			this.obFrame.style.display = 'none';
			
			document.body.appendChild(this.obFrame);
		}

		obForm.target = this.obFrame.name;
		
		if (obForm.action.length <= 0)
			obForm.action = this.url;
		
		jsPopup.DenyClose();
		ShowWaitWindow();
		
		// another hack for editor.
		obForm.save.click();
	},
	
	urlencode: function(s)
	{
		return escape(s).replace(new RegExp('\\+','g'), '%2B');
	},
	
	__prepareOnload: function()
	{
		this.obTemporary = window.onload;
		window.onload = null;
	},

	__runOnload: function()
	{
		if (window.onload) window.onload();
		window.onload = this.obTemporary;
		this.obTemporary = null;
	},

	stepOne: function()
	{
		if (jsExtLoader.httpRequest.readyState == 4)
		{

			var content = jsExtLoader.httpRequest.responseText;
			var arCode = [];
			var matchScript;

			while ((matchScript = content.match('<script([^>]*)>', 'i')) !== null)
			{
				var end = content.search('<\/script>', 'i');
				if (end == -1)
					break;

				var bRunFirst = matchScript[1].indexOf('bxrunfirst') != '-1';
				
				var matchSrc;
				if ((matchSrc = matchScript[1].match('src=["\']([^"\']+)["\']', "i")) !== null)
					arCode[arCode.length] = {"bRunFirst": bRunFirst, "isInternal": false, "JS": matchSrc[1]};
				else
				{
					var start = matchScript.index + matchScript[0].length;
					arCode[arCode.length] = {"bRunFirst": bRunFirst, "isInternal": true, "JS": content.substr(start, end-start)};
				}

				content = content.substr(0, matchScript.index) + content.substr(end+9);
			}

			jsExtLoader.__prepareOnload();
			jsExtLoader.processResult(content, arCode);
			CloseWaitWindow();
			jsExtLoader.__runOnload();
		}
	},
	
	EvalGlobal: function(script)
	{
		if (window.execScript)
			window.execScript(script, 'javascript');
		else if (jsUtils_n.IsSafari())
			window.setTimeout(script, 0);
		else
			window.eval(script);
	},
	
	arLoadedScripts: [],
	
	__isScriptLoaded: function (script_src)
	{
		for (var i=0; i<jsExtLoader.arLoadedScripts.length; i++)
			if (jsExtLoader.arLoadedScripts[i] == script_src) return true;
		return false;
	},
	
	// evaluate external script
	EvalExternal: function(script_src)
	{
		if (jsExtLoader.__isScriptLoaded(script_src)) return;
		
		jsExtLoader.arLoadedScripts.push(script_src);

		if (script_src.substring(0, 8) != '/bitrix/')
			script_src = '/bitrix/admin/' + script_src;
		
		// fix Opera bug with combining syncronous and asynchronuos requests using one XHR object.
		if (jsUtils_n.IsOpera())
		{
			if (null == this.httpRequest2)
				this.httpRequest2 = this._CreateHttpObject();
			
			httpRequest = this.httpRequest2;
		}
		else
		{
			var httpRequest = this.httpRequest;
		}
		
		httpRequest.onreadystatechange = function (str) {};
		httpRequest.open("GET", script_src, false);
		httpRequest.send("");

		var s = httpRequest.responseText;

		httpRequest = null;
		
		try 
		{
			this.EvalGlobal(s);
		}
		catch(e)
		{
			//alert('script_src: ' + script_src + '<pre>' + s + '</pre>');
		}
	},

	processResult: function(content, arCode)
	{
		//Javascript
		jsExtLoader.processScripts(arCode, true);
		
		if (null == jsExtLoader.obContainer)
			jsExtLoader.obContainer = jsExtLoader.onajaxfinish(content);
		else
			jsExtLoader.obContainer.innerHTML = content;

		//Javascript
		jsExtLoader.processScripts(arCode, false);
	},
	
	processScripts: function(arCode, bRunFirst)
	{
		for (var i = 0, length = arCode.length; i < length; i++)
		{
			if (arCode[i].bRunFirst != bRunFirst)
				continue;
			
			if (arCode[i].isInternal)
			{
				arCode[i].JS = arCode[i].JS.replace('<!--', '');
				jsExtLoader.EvalGlobal(arCode[i].JS);
			}
			else
			{
				jsExtLoader.EvalExternal(arCode[i].JS);
			}
		}
	},

	_CreateHttpObject: function()
	{
		var obj = null;
		if(window.XMLHttpRequest)
		{
			try {obj = new XMLHttpRequest();} catch(e){}
		}
		else if(window.ActiveXObject)
		{
			try {obj = new ActiveXObject("Microsoft.XMLHTTP");} catch(e){}
			if(!obj)
				try {obj = new ActiveXObject("Msxml2.XMLHTTP");} catch (e){}
		}
		return obj;
	}
}

/*
public jsStyle - external CSS manager
*/
var jsStyle = {

	arCSS: {},
	bInited: false,
	
	httpRequest: null,
	
	Init: function()
	{
		var arStyles = document.getElementsByTagName('LINK');
		if (arStyles.length > 0)
		{
			for (var i = 0; i<arStyles.length; i++)
			{
				if (arStyles[i].href)
				{
					var filename = arStyles[i].href;
					var pos = filename.indexOf('://');
					if (pos != -1)
						filename = filename.substr(filename.indexOf('/', pos + 3));
					
					arStyles[i].bxajaxflag = false;
					this.arCSS[filename] = arStyles[i];
				}
			}
		}
		
		this.bInited = true;
	},
	
	Load: function(filename)
	{
		if (!this.bInited) this.Init();
	
		if (null != this.arCSS[filename])
		{
			this.arCSS[filename].disabled = false;
			return;
		}

		var link = document.createElement("STYLE");
		link.type = 'text/css';

		var head = document.getElementsByTagName("HEAD")[0];
		head.insertBefore(link, head.firstChild);
		//head.appendChild(link);
		
		if (jsUtils_n.IsIE())
		{
			link.styleSheet.addImport(filename);
		}
		else
		{
			try 
			{
				if (null == this.httpRequest)
					this.httpRequest = jsExtLoader._CreateHttpObject();
					
				this.httpRequest.onreadystatechange = null;

				this.httpRequest.open("GET", filename, false); // make *synchronous* request for css source
				this.httpRequest.send("");
				
				var s = this.httpRequest.responseText;
				
				link.appendChild(document.createTextNode(s));
			}
			catch (e) {}
		}
	},
	
	Unload: function(filename)
	{
		if (!this.bInited) this.Init();
	
		if (null != this.arCSS[filename])
		{
			this.arCSS[filename].disabled = true;
		}
	},
	
	UnloadAll: function()
	{
		if (!this.bInited) this.Init();	
		else
			for (var i in this.arCSS)
			{
				if (this.arCSS[i].bxajaxflag)
					this.Unload(i);
			}
	}
}

// for compatibility with IE 5.0 browser
if (!Array.pop)
{
	Array.prototype.pop = function()
	{
		if (this.length <= 0) return false;
		var element = this[this.length-1];
		delete this[this.length-1];
		this.length--;
		return element;
	}
	
	Array.prototype.shift = function()
	{
		if (this.length <= 0) return false;
		var tmp = this.reverse();
		var element = tmp.pop();
		this.prototype = tmp.reverse();
		return element;
	}
	
	Array.prototype.push = function(element)
	{
		this[this.length] = element;
	}
}
//************************************************************

function jsWizard()
{
	this.currentStep = null;
	this.firstStep = null;

	this.arSteps = {};

	this.nextButtonID = "btn_popup_next";
	this.prevButtonID = "btn_popup_prev";
	this.finishButtonID = "btn_popup_finish";
	this.cancelButtonID = "btn_popup_cancel";

	this.arButtons = {};
}

jsWizard.prototype.AddStep = function(stepID, arButtons)
{
	var element = document.getElementById(stepID);
	if (!element)
		return;

	if (typeof(arButtons) != "object")
		arButtons = {};

	this.arSteps[stepID] = {"element": element};

	//Actions
	for (var button in arButtons)
		this.arSteps[stepID][button] = arButtons[button];

	if (this.firstStep === null)
		this.firstStep = stepID;
}

jsWizard.prototype.SetCurrentStep = function(stepID)
{
	this.currentStep = stepID;
}

jsWizard.prototype.SetFirstStep = function(stepID)
{
	this.firstStep = stepID;
}

jsWizard.prototype.SetNextButtonID = function(buttonID)
{
	this.nextButtonID = buttonID;
}

jsWizard.prototype.SetPrevButtonID = function(buttonID)
{
	this.prevButtonID = buttonID;
}

jsWizard.prototype.SetFinishButtonID = function(buttonID)
{
	this.finishButtonID = buttonID;
}

jsWizard.prototype.SetCancelButtonID = function(buttonID)
{
	this.cancelButtonID = buttonID;
}


jsWizard.prototype.SetButtonDisabled = function(button, disabled)
{
	if (this.arButtons[button])
		this.arButtons[button].disabled = disabled;
}

jsWizard.prototype.IsStepExists = function(stepID)
{
	if (this.arSteps[stepID])
		return true;
	else
		return false;
}

jsWizard.prototype.Display = function()
{
	if (this.firstStep === null)
		return;

	this.currentStep = this.firstStep;

	var _this = this;
	var arButtons = {"next" : this.nextButtonID, "prev" : this.prevButtonID, "finish" : this.finishButtonID, "cancel" : this.cancelButtonID};
	for (var button in arButtons)
	{
		var buttonElement = document.getElementById(arButtons[button]);
		if (buttonElement && buttonElement.tagName == "INPUT")
		{
			buttonElement.buttonID = button;
			buttonElement.onclick = function() {_this._OnButtonClick(this.buttonID)};
			this.arButtons[button] = buttonElement;
		}
		else
			this.arButtons[button] = null;
	}

	this._OnStepShow();
}

jsWizard.prototype._OnButtonClick = function(button)
{
	if (this.arSteps[this.currentStep] )
	{
		var callback = this.arSteps[this.currentStep]["on" + button];
		if (callback && typeof(callback) == "function")
		{
			if (callback(this) === false)
				return;
		}
	}

	if (!this.arSteps[this.currentStep])
	{
		if (!this.arSteps[this.firstStep])
			return;

		this.currentStep = this.firstStep;
	}
	else if (this.arSteps[this.currentStep][button])
		this.currentStep = this.arSteps[this.currentStep][button];

	this._OnStepShow();
}

jsWizard.prototype._OnStepShow = function()
{
	//Display current step and hide others steps
	for (var stepID in this.arSteps)
		this.arSteps[stepID].element.style.display = (stepID == this.currentStep ? "" : "none");

	//Activate and disable buttons
	for (var button in this.arButtons)
	{
		if (this.arButtons[button])
		{
			var stepID = this.arSteps[this.currentStep][button];
			this.arButtons[button].disabled = (stepID && this.arSteps[stepID] ? false : true);
		}
	}

	//Execute onshow function
	if (this.arSteps[this.currentStep])
	{
		var callback = this.arSteps[this.currentStep]["onshow"];
		if (callback && typeof(callback) == "function")
			callback(this);
	}
}