/**
 * Subsys_JsHttpRequest_Js: JavaScript DHTML data loader.
 * (C) 2005 Dmitry Koterov, http://forum.dklab.ru/users/DmitryKoterov/
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * See http://www.gnu.org/copyleft/lesser.html
 *
 * Do not remove this comment if you want to use script!
 * Не удаляйте данный комментарий, если вы хотите использовать скрипт!
 *
 * This library tries to use XMLHttpRequest (if available), and on 
 * failure - use dynamically created <script> elements. Backend code
 * is the same for both cases.
 *
 * @author Dmitry Koterov 
 * @version 3.20
 */

function Subsys_JsHttpRequest_Js() { this._construct() }
(function() { // to create local-scope variables
	var COUNT       = 0;
	var PENDING     = {};
	var CACHE       = {};

	// Called by server script on data load.
	Subsys_JsHttpRequest_Js.dataReady = function(id, text, js) {
		var undef;
		var th = PENDING[id];
		delete PENDING[id];
		if (th) {
			delete th._xmlReq;
			if (th.caching) CACHE[th.hash] = [text, js];
			th._dataReady(text, js);
		} else if (typeof(th) != typeof(undef)) {
			alert("ScriptLoader: unknown pending id: "+id);
		}
	}
	
	Subsys_JsHttpRequest_Js.prototype = {
		// Standard properties.
		onreadystatechange: null,
		readyState:         0,
		responseText:       null,
		responseXML:        null,
		status:             200,
		statusText:         "OK",
		
		// Additional properties.
		session_name:       "PHPSESSID",  // set to SID cookie or GET parameter name
		responseJS:         null,         // JavaScript response array/hash
		caching:            false,        // need to use caching?

		// Internals.
		_span:              null,
		_id:                null,
		_xmlReq:            null,
		_openArg:           null,
		_reqHeaders:        null,

		abort: function() {
			if (this._xmlReq) return this._xmlReq.abort();
			if (this._span) {
				this.readyState = 0;
				if (this.onreadystatechange) this.onreadystatechange();
				this._cleanupScript();
			}
		},
			
		open: function(method, url, asyncFlag, username, password) {
			this._openArg = {
				'method':    method,
				'url':       url,
				'asyncFlag': asyncFlag,
				'username':  username,
				'password':  password
			};
			this._id = null;
			this._xmlReq = null;
			this._reqHeaders = [];
			return true;
		},
		
		send: function(content) {
			var id = COUNT++;
			// Build QUERY_STRING from query hash.
			var query = this._hash2query(content);

			// Append SID to original URL now.
			var url = this._openArg.url;
			var sid = this._getSid();
			if (sid) url += (url.indexOf('?')>=0? '&' : '?') + this.session_name + "=" + escape(sid);

			// Solve hash BEFORE appending ID.
			var hash = this.hash = url + '?' + query;
			if (this.caching && CACHE[hash]) {
				var c = CACHE[hash];
				this._dataReady(c[0], c[1]);
				return false;
			}

			// Try to use XMLHttpRequest.
			this._xmlReq = this._obtainXmlReq(id, url);

			// Pass data in URL (GET, HEAD etc.) or in request body (POST)?
			var hasSetHeader = this._xmlReq && (window.ActiveXObject || this._xmlReq.setRequestHeader); 
			var href, body;
			if (this._xmlReq && hasSetHeader && (""+this._openArg.method).toUpperCase() == "POST") {
				// Use POST method. Pass query in request body.
				// Opera 8.01 does not support setRequestHeader, so no POST method.
				this._openArg.method = "POST";
				href = url;
				body = query;
			} else {
				this._openArg.method = "GET";
				href = url + (url.indexOf('?')>=0? '&' : '?') + query;
				body = null;
			}

			// Append ID: a=aaa&b=bbb&<id>
			href = href + (href.indexOf('?')>=0? '&' : '?') + id;

			// Save loading script.
			PENDING[id] = this;

			if (this._xmlReq) {
				// Open request now & send it.
				// In XMLHttpRequest mode request URL MUST be ended with "&".
				var a = this._openArg;
				this._xmlReq.open(a.method, href+"&", a.asyncFlag, a.username, a.password);
				if (hasSetHeader) {
					// Pass pending headers.
					for (var i=0; i<this._reqHeaders.length; i++)
						this._xmlReq.setRequestHeader(this._reqHeaders[i][0], this._reqHeaders[i][1]);
					// Set non-default Content-type. We cannot use 
					// "application/x-www-form-urlencoded" here, because 
					// in PHP variable HTTP_RAW_POST_DATA is accessible only when 
					// enctype is not default (e.g., "application/octet-stream" 
					// is a good start). We parse POST data manually in backend 
					// library code.
					this._xmlReq.setRequestHeader('Content-Type', 'application/octet-stream');
				}
				// Send the request.
				return this._xmlReq.send(body);
			} else {
				// Create <script> element and run it.
				this._obtainScript(id, href);
				return true;
			}
		},

		getAllResponseHeaders: function() {
			if (this._xmlReq) return this._xmlReq.getAllResponseHeaders();
			return '';
		},
			
		getResponseHeader: function(label) {
			if (this._xmlReq) return this._xmlReq.getResponseHeader(label);
			return '';
		},

		setRequestHeader: function(label, value) {
			// Collect headers.
			this._reqHeaders[this._reqHeaders.length] = [label, value];
		},


		//
		// Internal functions.
		//

		// Constructor.
		_construct: function() {},

		// Do all work when data is ready.
		_dataReady: function(text, js) { with (this) {
			if (text !== null || js !== null) {
				readyState = 4;
				responseText = responseXML = text;
				responseJS = js;
			} else {
				readyState = 0;
				responseText = responseXML = responseJS = null;
			}
			if (onreadystatechange) onreadystatechange();
			_cleanupScript();
		}},

		// Create new XMLHttpRequest object.
		_obtainXmlReq: function(id, url) {
			// If url.domain specified, cannot use XMLHttpRequest!
			if (url.match(new RegExp('^[a-z]+://', 'i'))) return null;
			
			// Try to use built-in loaders.
			var req = null;
			if (window.XMLHttpRequest) {
				try { req = new XMLHttpRequest() } catch(e) {}
			} else if (window.ActiveXObject) {
				try { req = new ActiveXObject("Microsoft.XMLHTTP") } catch(e) {}
				if (!req) try { req = new ActiveXObject("Msxml2.XMLHTTP") } catch (e) {}
			}
			if (req) {
				var th = this;
				req.onreadystatechange = function() { 
					if (req.readyState == 4) {
						// Call associated dataReady().
						eval(req.responseText);
					} else {
						th.readyState = req.readyState;
						if (th.onreadystatechange) th.onreadystatechange() 
					}
				};
				this._id = id;
			}
			return req;
		},

		// Create new script element and start loading.
		_obtainScript: function(id, href) { with (document) {
			var span = null;
			// Oh shit! Damned stupid fucked Opera 7.23 does not allow to create SCRIPT 
			// element over createElement (in HEAD or BODY section or in nested SPAN - 
			// no matter): it is created deadly, and does not respons on href assignment.
			// So - always create SPAN.
			span = body.appendChild(createElement("SPAN"));
			span.style.display = 'none';
			span.innerHTML = 'Text for stupid IE.<s'+'cript></' + 'script>';
			setTimeout(function() {
				var s = span.getElementsByTagName("script")[0];
				s.language = "JavaScript";
				if (s.setAttribute) s.setAttribute('src', href); else s.src = href;
			}, 10);
			this._id = id;
			this._span = span;
		}},

		// Remove last used script element (clean memory).
		_cleanupScript: function() {
			var span = this._span;
			if (span) {
				this._span = null;
				setTimeout(function() {
					// without setTimeout - crash in IE 5.0!
					span.parentNode.removeChild(span);
				}, 50);
			}
			return false;
		},

		// Convert hash to QUERY_STRING.
		_hash2query: function(content) {
			var query = [];
			if (content instanceof Object) {
				// TODO: build more nested objects in PHP-style.
				for (var k in content) {
					query[query.length] = escape(k) + "=" + escape(content[k]);
				}
			} else {
				query = [content];
			}
			return query.join('&');
		},
	
		// Return value of SID based on QUERY_STRING or cookie
		// (PHP compatible sessions).
		_getSid: function() {
			var m = document.location.search.match(new RegExp('[&?]'+this.session_name+'=([^&?]*)'));
			var sid = null;
			if (m) {
				sid = m[1];
			} else {
				var m = document.cookie.match(new RegExp(s='(;|^)\\s*'+this.session_name+'=([^;]*)'));
				if (m) sid = m[2];
			}
			return sid;
		}
	}
})();


/**
Библиотека js-классов, позволяющая конструировать различные объекты, использующие блоки, которые умеют:
- обновлять свое внутреннее содержимое по переданному url без перезагрузки страницы
- раскрываться и закрываться
- плавать на поверхности экрана в указанном месте
*/

/** Класс, который позволяет подгружать содержимое из указанного Url-a */
function urler(name) {

	this.className  = "urler";
	this.insName	= this.className + '_' + name;
    window[this.insName]= this;
	//var urler_iframe = document.createElement("iframe");
	//urler_iframe.style.display = "none";
	//document.body.appendChild(urler_iframe);	
	document.write('<iframe name="'+this.insName+'" id="'+this.insName+'" scrolling="no" width=0 height=0 frameborder=0></iframe>');
	var urler_iframe = document.getElementById(this.insName);
	this.iframe = urler_iframe;
	this.loaded = false;
	this.text = '';
	
	function go2Url(url) {
		this.iframe.src = url;
		this.loaded = false;
	}
	
	function getText() {
	   return this.text;
	}
	
	this.getText = getText;
	this.go2Url = go2Url;
}

function urler_onload(urler_insName,text) {
   if (window[urler_insName] != null) {
   	 window[urler_insName].loaded = true;
	 window[urler_insName].text = text;
   } 
}	

/** Класс, который позволяет хранить в памяти несколько вариантов некоторой сущности и переключаться между ними
*/
function contentVariants() {

this.data = new Array(); //массив с вариантами содержимого данного блока. Ключ - строка(url), value-значение блока

	/** Возвращает один из возможных вариантов значения данного блока
	* @param string ключевая строка, вариант использования для которой нужно возвратить
	*/	
	function get(key) {
	    if (this.data[key] != null) {
			return this.data[key];	
		} else {
		    return null;
		}
	};
	
	/** Устанавливает один из возможных вариантов значения данного блока
	* @param string ключевая строка, по кторой данное значение можно будет выбрать среди варинатов
	* @param тип параметра определяется объектом, в котором используется. Может быть текстом или изображением или еще чем-то
	*/	
	function set(key,value) {
		this.data[key] = value;	
	};

	/** Ликвидирует один из возможных вариантов значения данного блока
	* @param string ключевая строка для варианта использования 
	*/	
	function unset(key) {
		this.data[key] = null;	
	};
	
	/** Стирает все варианты контента (ресетит)
	*/	
	function reset() {
		this.data = new Array();	
	};

	this.get = get;
	this.set = set;
	this.unset = unset;
	this.reset = reset;
}

/* Класс, который реализует текстовый блок (DIV), имеющие несколько режимов отображения 
   - плавать поверх других элементов страницы
   - сохранять свое положение на экране во время проктрутки
   - раскрываться и закрываться
   - обновлять свое содержимое по данному url, помнить ранее загруженные урлы
   - отображаться в определенном месте (требуется CalendarPopup)
   
   @param boolean отображается или нет при создании контрол на экране
*/
function contentBlock(name,contentDiv) {
    // вставить данный объект в DOM текщего документа 
	this.className  = "contentBlock";
	this.insName	= this.className + '_' + name;
    window[this.insName]= this;
	//инициализация полей объекта
	if (contentDiv == null) {
	     this.contentDiv = document.createElement("DIV"); //html-элемент, в котором отображается данный блок
    } else { 
		this.contentDiv = contentDiv;	
	}	
    this.step       = 10; //количество пикселей, на которое раскрывается div на итерации

	this.shown  = true; //является div в данный момент раскрытым или нет
	this.showType = "sudden"; //каким образом объект поялвяется на экране, сразу-"sudden", плавно-"smooth"
	this.timeout = 10; //задержка во времени - для постепенного раскрытия блока
	this.usualClass = ''; //стиль, который определяет внешний вид блока в обычном состоянии
	this.variants = new contentVariants(); //объект с вариантами значений для данного блока
	this.timeoutLoad = 10; //задержка во времени - для загрузки url
	this.loadingText = 'loading...'; //текст объекта во время загрузки из urla
	this.loadingClass = ''; //стиль, который поределяет внешний вид блока в состояни загрузки
	this.loadingUrl = ''; //url,который загружается в данный момент
	this.urler_insName = 'urler_global'; //название объекта, который используется для загрузки данного объекта
	this.offsetX = 0; //смещение отностилеьно якоря по X
	this.offsetY = 0; //смещение отностилеьно якоря по Y
	/* поддержка отображения дива в рамках заданной области
	У дива можно указать границы некоторой области, и тогда он будет отображаться 
	внутри некоторых рамок, то есть сели он выходит за эти рамки, то разворачивается вверх
	можно указывать границу только по одному из измерений, а по другому оставить 0
	*/
	this.limitMinY = 0; //отступ от верхнего края страницы до указанной области
	this.limitMaxY = 0; //высота ограничивающей вывод области
	this.limitMinX = 0; //отступ от левого края страницы до указанной области
	this.limitMaxX = 0; //ширина ограничивающей вывод области	
	this.xLimited = false; //внутренняя переменная указывающая на то что требуется вписать в область
	this.yLimited = false; //внутренняя переменная указывающая на то что требуется вписать в область
	this.xPos = 0; //внутренняя переменная хранится последнее положения якоря
	this.yPos = 0; //внутренняя переменная хранится последнее положения якоря
	this.onLoadReturnFunction = null;
	this.onLostFocusFunction = null;
	this.autoHideEnabled = false; //нужно ли скрывать див когда кто-то кликает за его пределами
	
	contentBlock.prototype.setLoadReturnFunction = function(name) {
		this.onLoadReturnFunction = name;
	}
	
	/* функции для отображения дива в рамках заданной области */
	/** устанавливает границы области по горизонтали
	* @param int отступ от верхнего края страницы до указанной области
	* @param int высота ограничивающей вывод области
	*/	
	function setYLimit(min,max) {
		this.limitMinY = min;
		this.limitMaxY = max;
		this.yLimited = true;
	}	
	/** устанавливает границы области по вертикали
	* @param int отступ от верхнего края страницы до указанной области
	* @param int высота ограничивающей вывод области
	*/	
	function setXLimit(min,max) {
		this.limitMinX = min;
		this.limitMaxX = max;
		this.xLimited = true;
	}		
	
	function moveToAnchor(anchorName) {
		coord = getAnchorPosition(anchorName);
		//document.getElementById('debug').value = document.getElementById('debug').value+'\n ------moving-------------- \n'+anchorName;
		this.moveToXY(this.offsetX+coord.x,this.offsetY+coord.y);
	}
	
	function setPosToAnchor(anchorName) {
		coord = getAnchorPosition(anchorName);
		//document.getElementById('debug').value = document.getElementById('debug').value+'\n ------moving-------------- \n'+anchorName;
		this.setPos(this.offsetX+coord.x,this.offsetY+coord.y);
	}	
	
	/* Функция определяет высоту блока (даже если в текущий момент он не отображается)
	*/
	function getHeight() {
	var height = 0;
/*	
		if (this.contentDiv.style.display != 'none') {
			height = this.contentDiv.clientHeight;
		} else {
			this.contentDiv.style.visibility = 'hidden';
			this.contentDiv.style.display = '';
			height = this.contentDiv.clientHeight;
			this.contentDiv.style.display = 'none';
			this.contentDiv.style.visibility = 'visible';
		} */
		
		if (this.contentDiv.style.display != 'none') {
			coordTop = getAnchorPosition('download_contents_begin');
			coordBot = getAnchorPosition('download_contents_end');
			height = coordBot.y - coordTop.y;
		} else {
			this.contentDiv.style.visibility = 'hidden';
			this.contentDiv.style.display = '';
			coordTop = getAnchorPosition('download_contents_begin');
			coordBot = getAnchorPosition('download_contents_end');
			height = coordBot.y - coordTop.y;
			this.contentDiv.style.display = 'none';
			this.contentDiv.style.visibility = 'visible';
		} 
		/*
			coordTop = getAnchorPosition('download_contents_begin');
			coordBot = getAnchorPosition('download_contents_end');
			height = coordBot.y - coordTop.y;		*/
				
		//coordTop = getAnchorPosition('download_contents_begin');
		//coordBot = getAnchorPosition('download_contents_end');

		//document.getElementById('debug').value = document.getElementById('debug').value + ' fgheight '+height;
	    return height; 	
	}
	
	/* Функция определяет ширину блока (даже если в текущий момент он не отображается)
	*/
	function getWidth() {
	var width = 0;
		if (this.contentDiv.style.display != 'none') {
			height = this.contentDiv.clientWidth;
		} else {
			this.contentDiv.style.visibility = 'hidden';
			this.contentDiv.style.display = '';
			height = this.contentDiv.clientWidth;
			this.contentDiv.style.display = 'none';
			this.contentDiv.style.visibility = 'visible';
		}
	return width; 	
	}	
	
	/** передвигает див в точку с координатами x y
	* @param int x - координата
	* @param int y - координата
	*/	
	function moveToXY(x,y) {
	
		if (this.yLimited&&y!=null) {
			//вычислить высоту блока
			var height = this.getHeight();
			//document.getElementById('debug').value = document.getElementById('debug').value+'\n-----------------------------------------------\n before x'+x+' y'+y+' height '+height;
			if (this.limitMaxY<height+y) { //попап не умещается вниз
				//document.getElementById('debug').value = document.getElementById('debug').value+'\n не умещается вниз';
				if (y-height>this.limitMinY) { //умещается вверх
					//скорректировать местоположение - вывести вверх
					//document.getElementById('debug').value = document.getElementById('debug').value+'\n умещается вверх';
					y = this.limitMaxY-height;
					//document.getElementById('debug').value = document.getElementById('debug').value+'\n corr: height'+height+' limitMaxY'+this.limitMaxY;
				} else {
				    //document.getElementById('debug').value = document.getElementById('debug').value+'\n не умещается вверх';
					y = this.limitMinY;
					//document.getElementById('debug').value = document.getElementById('debug').value+'\n corr: height'+height+' limitMaxY'+this.limitMaxY;
				}
			}
		}	

		this.setPos(x,y);
	}
	
	/** передвигает див в точку с координатами x y
	* @param int x - координата
	* @param int y - координата
	*/	
	function setPos(x,y) {
		this.contentDiv.style.left = x + "px";
		this.contentDiv.style.top = y + "px";	
		this.xPos = x;
		this.yPos = y;
	}	
	
	/** Встраивает данный блок внутрь указанного контейнера на странице
	* @param object objectDOM
	*/
	function attachMe(parentObject) {
		parentObject.appendChild(this.contentDiv);	
	}
	
	/** Устанавливает текст внутри блока
	* @param string текст, который устанавливается в данном блоке
	*/	
	function setText(str) {
		this.contentDiv.innerHTML = str;	
	};
	
	/** Устанавливает CSS по умолчанию для элемента
	* @param string название CSS-класса
	*/	
	function setUsualClass(str) {
		this.usualClass = str;
		this.contentDiv.className = this.usualClass;	
	};	
	
	/** Загружает в блок содержимое некоторого urla, записывает url в варинаты использования
	* @param url;
	function load(url) {
		
		var savedText = this.variants.get(url);
		//document.getElementById('screen').value = url+' '+document.getElementById('screen').value;
		if (savedText != null) {
			this.setText(savedText);	
			if (this.yLimited||this.xLimited) {
				x = this.xPos;
				y = this.yPos;
				this.moveToXY(x,y);
			}
		} else {
			window[this.urler_insName].go2Url(url); //приказываем загрузить
			this.loadingUrl = url;
			this.contentDiv.className = this.loadingClass;
			if (this.loadingWidth != null) this.contentDiv.style.width = this.loadingWidth;
			if (this.loadingHeight != null) this.contentDiv.style.height = this.loadingHeight;
			this.setText(this.loadingText);
			clearInterval(this.intervalLoad);
			this.intervalLoad   = setInterval(this.insName+".waitLoad()", this.timeoutLoad);
		}
	}	*/
	
	// Вызывается по тайм-ауту или при щелчке на кнопке.
    function load(query) {
		this.loadingUrl = query;
		this.contentDiv.className = this.loadingClass;

		//поменять курсор на песочные часы
		if (window.loadingItemsQty==null) window.loadingItemsQty = 0;
		if (window.loadingItemsQty==0) switchCursor(document.body,'wait');
		window.loadingItemsQty++;
		//alert('start'+window.loadingItemsQty);
		
		if (this.loadingWidth != null) this.contentDiv.style.width = this.loadingWidth;
		if (this.loadingHeight != null) this.contentDiv.style.height = this.loadingHeight;
		this.setText(this.loadingText);	

        // Создаем новый объект JSHttpRequest.
        var req = new Subsys_JsHttpRequest_Js();
		// Код, АВТОМАТИЧЕСКИ вызываемый при окончании загрузки.
        
		req.onreadystatechange = function() {
			if (req.readyState == 4) {
                if (req.responseJS) {
					var t = window[req.divInsName].contentDiv;
					
                    // Записываем в <div> результат работы. 
					text = req.responseJS.content;
					window[req.divInsName].contentDiv.className = window[req.divInsName].usualClass;
					window[req.divInsName].setText(text);
					//переключить в подгруженном тексте курсоры
					switchCursor(window[req.divInsName].contentDiv,'wait');
					if (window[req.divInsName].yLimited||window[req.divInsName].xLimited) {
						x = window[req.divInsName].xPos;
						y = window[req.divInsName].yPos;
						window[req.divInsName].moveToXY(x,y);
					}	
					if (req.responseJS.js_source) eval(req.responseJS.js_source);
					
					//активировать кнопку сабмит после загрузки
					/* Основная идея такая, что нужно пробежаться по дереву родительских элементов и передать фокус форме
					   чтобы она сабмитилась по Enter */
					/*
					if (document.all) {
						while (t.parentElement != null) {
							//alert('I amhere'+t.tagName);
							
							if (t.tagName=='FORM') {
									submits = t.getElementsByTagName('INPUT');
									for (i=submits.length-1; i >=0; i--) { 
										if (submits[i].getAttribute('TYPE') == 'text') {
											submits[i].setActive();
											submits[i].value = '10';
											submits[i].select();
											submits[i].focus();
											//alert('ddd');
											break;
										}
									}
									//alert('ddd');
									//t.focus();
									//t.select();
									//t.fireEvent("onclick");
									break;
								}

							t = t.parentElement;
							}					
					}
					*/ 
					
								
                }
                if (req.onLoadReturnFunction) {
                	eval(this.onLoadReturnFunction)();
                }
				//поменять песочные часы на обычный курсор
				window.loadingItemsQty--;
				if (window.loadingItemsQty==0) switchCursor(document.body,'default');
				
					/* Основная идея такая, что нужно пробежаться по дереву дочерних элементов, найти какойнибудь элемент формы и поставить на него фокус */					
					if (document.all) {
						//alert('I amhere'+t.tagName);
						$formElement = getFormElementChild(t.children);
						if ($formElement != null) {
							//alert($formElement.tagName);
							//$formElement.setActive();
						}
						/*
						while (t != null) {
								oColl = t.children;
								for(x=0;x<oColl.length;x++){
									if (t.children[x].tagName == 'SELECT') {
										t.children[x].focus();
									}
								}
								t = t.children[0];
							}	*/		
					}		
						
				//alert('stop'+window.loadingItemsQty);
                // Отладочная информация.
                //document.getElementById('debug').innerHTML = req.responseText;
				//alert(req.responseText);
            }
        }
        // Разрешаем кэширование (чтобы при одинаковых запросах
        // не обращаться к серверу несколько раз).
        req.caching = true;

		req.divInsName = this.insName;
		// название функции, которая будет вызываться, когда объект загрузился
		req.onLoadReturnFunction = this.onLoadReturnFunction;
        // Подготваливаем объект.
 		req.open('POST', query, true);
		// Посылаем данные запроса (задаются в виде хэша).
		req.send();
    }
	
	/** Функция, раскрывает текcтовый блок на экране страницы
	*/
    function show()
    {
		switch (this.showType) {
			case 'smooth':
		        if (this.interval) {
        		    clearInterval(this.interval);
		            this.interval   = null;
        		}
				this.contentDiv.style.display = "block";
		        this.scrollHeight   = this.contentDiv.scrollHeight;
        		this.currentHeight  = 0;
				this.interval   = setInterval(this.insName+".proceed()", this.timeout);
				break;
			default:
				this.contentDiv.style.display = "block";	
		}		
		this.shown  = true;
    };
	
	/** Функция, скрывает текcтовый блок на экране страницы
	*/
    function hide()
    {
		switch (this.showType) {
			case 'smooth':
				this.contentDiv.style.overflow = "hidden";
		        if (this.interval) {
    	    	    clearInterval(this.interval);
        	    	this.interval   = null;
        		}
	        	this.contentDiv.style.height   = 1;
				this.contentDiv.style.display = "none";
				break;
			default:
				this.contentDiv.style.display = "none";
		}		
		this.shown  = false;
    };

    function proceed()
    {
        if (this.currentHeight + this.step < this.scrollHeight)
        {
            this.currentHeight  += this.step;
            this.contentDiv.style.height   = this.currentHeight;
        } else {
            clearInterval(this.interval);
            this.interval   = null;
            this.shown  = true;
            this.contentDiv.style.height   = this.scrollHeight;
        }
    };
	
	function waitLoad()
    {
		if (window[this.urler_insName].loaded)
        {   
            this.contentDiv.className = this.usualClass;
			text = window[this.urler_insName].getText();
			this.setText(text);
			this.variants.set(this.loadingUrl, text);
			//если прямоугольник ограничен по высоте, нужно скорректировать его положение после загрузки
			if (this.yLimited||this.xLimited) {
				x = this.xPos;
				y = this.yPos;
				this.moveToXY(x,y);
			}
			clearInterval(this.intervalLoad);
            this.intervalLoad   = null;
        }
    };
	
	//обработка события означающего что кликнули внутри этого дива
	function isClicked(e) {
		if (e.originalTarget) {
			var t = e.originalTarget;
            try{
                while (t.parentNode != null) {
                    if (t.id==this.contentDiv.id) {
                        return true;
                    }
                    t = t.parentNode;
                }
            }
            catch(e){}
		} else if (document.all) {
			var t = window.event.srcElement;
			while (t.parentElement != null) {
				if (t.id==this.contentDiv.id) {
					return true;
					}
				t = t.parentElement;
				}
		}
		return false;
	}
	
	
	//Внутренняя функция для обработки onMouseDown
	function hideIfNotClicked(e) {
		if (this.autoHideEnabled && !this.isClicked(e)) {
			  if (this.shown) {
				  this.hide();
			  	  //вызываем функцию которая отвечает за скрытие дива
		          if (this.onLostFocusFunction) {
        		      eval(this.onLostFocusFunction)();
		          }					  
			  }	 
			}
		}
	//Эту функцию нужно вызывать на тех объектах, которые должны прятаться, если кликнули вне дива

	function autoHide() {
		//повесить обработчик на onmouseup
		addEvent(window.document,'mouseup',new Function("e"," window['"+this.insName+"'].hideIfNotClicked(e);"));
		this.autoHideEnabled = true;
		}	
	
    function getDivObj()
    {
        return this.contentDiv;
    };		

	this.setYLimit = setYLimit;
    this.setXLimit = setXLimit;	
	this.show = show;
    this.hide = hide;
	this.load = load;
	this.waitLoad = waitLoad;
    this.proceed = proceed;
	this.attachMe = attachMe;
	this.setText = setText;
	this.getDivObj = getDivObj;
	this.getHeight = getHeight;
	this.getWidth = getWidth;
	this.moveToAnchor = moveToAnchor;
	this.moveToXY = moveToXY;	
	this.setPos = setPos;
	this.setPosToAnchor = setPosToAnchor;
	this.setUsualClass = setUsualClass;	
	this.autoHide = autoHide;
	this.hideIfNotClicked = hideIfNotClicked;
	this.isClicked = isClicked;
	this.isClicked = isClicked;
	
};

/* Класс, который реализует графичеcкий блок (IMG)
   - обновлять свое содержимое по данному url, скрываться и раскрываться
*/
function imageBlock(name)
{
    // вставить данный объект в DOM текщего документа 
	this.className  = "imageBlock";
	this.insName	= this.className + '_' + name;
    window[this.insName]= this;
	//инициализация полей объекта
	this.contentImg = document.createElement("IMG"); //html-элемент, в котором отображается данный блок
    this.hideImgSrc = 'design/pixel.gif'; //прозрачный gif, который используется для того, чтобы скрыть данный блок
	this.hiddenImgSrc = null; //картинка, которая была скрыта
	this.loadingImgSrc = 'design/loading_eng.gif'; //картинка, которая была скрыта
	
	/** Подгружает требующиеся картинки */
	function preLoad() {
		if (this.loadingImgSrc) {
			this.loadingImg = new Image;
			this.loadingImg.src = this.loadingImgSrc;
		}		
	}
	
	/** Встраивает данный блок внутрь указанного контейнера на странице
	* @param object objectDOM
	*/
	function attachMe(parentObject) {
		this.parentObject = parentObject;
		parentObject.appendChild(this.contentImg);	
	}
	
	function openOrHide() {
		if (this.shown) {
			this.hide();
		} else {
			this.show();
		};
	}	
	
	/** Функция, раскрывает текcтовый блок на экране страницы
	*/
    function show()
    {
		if (this.hiddenImgSrc != null && !this.shown) {
			this.load(this.hiddenImgSrc);
			this.shown  = true;
		}		
    };
	
	/** Функция, скрывает текcтовый блок на экране страницы
	*/
    function hideBlock()
    {
		this.parentObject.style.display = 'None';
    };		
	
	/** Функция, раскрывает картинку внутри блока
	*/
    function showBlock()
    {
		this.parentObject.style.display = 'Block';
    };
	
	/** Функция, скрывает картинку внутри блока
	*/
    function hide()
    {
		if (this.hideImgSrc != null && this.shown) {
			this.hiddenImgSrc = this.contentImg.src;
			this.load(this.hideImgSrc);
			this.shown  = false;
		}	
    };	
	
	/** Загружает в блок содержимое некоторого urla, записывает url в варинаты использования
	* @param url;
	*/
	function load(url) {
		if (this.loadingImgSrc) {
			this.contentImg.src = this.loadingImg.src;
		}
		this.contentImg.src = url;
		this.showBlock();
		this.shown = true;
	}
	
    function getImgObj()
    {
        return this.contentImg;
    };	
	
	//Внутренняя функция для обработки onMouseDown
	this.show   = show;
    this.hide   = hide;
	this.load   = load;
    this.hideBlock   = hideBlock;
	this.showBlock   = showBlock;	
	this.preLoad   = preLoad;
	this.attachMe    = attachMe;
	this.getImgObj    = getImgObj;
	this.openOrHide    = openOrHide;

};

/* Здесь хранится объект, который реализует функциональность inline drop down menu 
* этот объект состоит из 2-х дивов, один из которых является заголовком, а второй раскрывается при щелчке
* у первого в углу есть стрелка, которая является индикатором - раскрыт див или нет
* Во втором диве находится скрытое содержимое
*
* @param object объект внутрь которого встраивается заголовок
* @param object объект внутрь которого встраивается область с раскрывающимся содержимим
* @param boolean является ли объект раскрытым по умолчанию
*/

function dropDownInline(name,parentHeaderObject,ContentDiv,isShown,openedHeaderText,closedHeaderText,dropdownType)
{
    this.className  = "dropDownInline";
    this.insName	= this.className + '_' + name;
    window[this.insName]= this;
	this.openedHeaderText = openedHeaderText;
	this.closedHeaderText = closedHeaderText;

	var oHeaderBlock = new contentBlock(name,parentHeaderObject);
	    oHeaderDiv = oHeaderBlock.getDivObj();
		oHeaderDiv.onmousedown = new Function(this.insName+".onMouseDown()");
//		oHeaderBlock.attachMe(parentHeaderObject); //глючит в ИЕ5.0
		oHeaderBlock.setText(openedHeaderText); 

	var oContentBlock = new contentBlock(name,ContentDiv);
		if (dropdownType == 'floating')	{
			oContentBlock.contentDiv.style.position = "absolute"
		};	
		oContentBlock.showType = 'smooth'; 
		
	if (!isShown) {
		oContentBlock.hide();
	} 
		
	this.headerBlock = oHeaderBlock;
	this.contentBlock = oContentBlock;

	function onMouseDown() {
	    if (this.shown()) {
			this.hide();
		} else {
			this.show();
		}
	}

    function getHeaderObj()
    {
        return this.headerBlock.getDivObj();
    }

    function getContentObj()
    {
        return this.contentBlock.getDivObj();
    }
	
    function shown() {
        return this.contentBlock.shown;
    }	
	
	function hide() {
		this.contentBlock.hide();
		this.headerBlock.setText(this.closedHeaderText);			
	}

	function show() {
		this.contentBlock.show();
		this.headerBlock.setText(this.openedHeaderText);			
	}	

	function hideIfNotClicked(e) {
		if (this.autoHideEnabled && !this.contentBlock.isClicked(e) && !this.headerBlock.isClicked(e)) {
				if (this.shown()) {
					this.hide();
				}	
			}
		}	
	
	//Эту функцию нужно вызывать на тех объектах, которые должны прятаться, если кликнули вне дива
	function autoHide() {
		//повесить обработчик на onmouseup
		/*if (document.layers) {
			document.captureEvents(Event.MOUSEUP);
		}*/
		addEvent(window.document,'mouseup',new Function("e"," window['"+this.insName+"'].hideIfNotClicked(e);"));
		this.autoHideEnabled = true;
		}		
	
    this.getHeaderObj   = getHeaderObj;
    this.getContentObj     = getContentObj;
    this.onMouseDown    = onMouseDown;
	this.hide = hide;
	this.show = show;
	this.shown = shown;
	this.autoHide = autoHide;
	this.hideIfNotClicked = hideIfNotClicked;
}


