/* Класс, который реализует текстовый блок (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.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.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) {
                    // Записываем в <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);
                }
                if (req.onLoadReturnFunction) {
                	eval(this.onLoadReturnFunction)();
                }
				//поменять песочные часы на обычный курсор
				window.loadingItemsQty--;
				if (window.loadingItemsQty==0) switchCursor(document.body,'default');
				//alert('stop'+window.loadingItemsQty);
                // Отладочная информация.
                /*document.getElementById('debug').innerHTML = 
                    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;
			while (t.parentNode != null) {
				if (t.id==this.contentDiv.id) {
					return true;
					}
				t = t.parentNode;
				}
		} 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();
			  }	  
			}
		}
	//Эту функцию нужно вызывать на тех объектах, которые должны прятаться, если кликнули вне дива

	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,ContentTd,isShown,openedHeaderText,closedHeaderText,dropdownType,showDiv)
{
    this.className  = "dropDownInline";
    this.insName	= this.className + '_' + name;
    window[this.insName]= this;
	this.openedHeaderText = openedHeaderText;
	this.closedHeaderText = closedHeaderText;
	this.showDiv = showDiv;

	var oHeaderBlock = parentHeaderObject;
		//oHeaderBlock.onmouseover = new Function(this.insName+".show()");
		//oHeaderBlock.onmouseout = new Function(this.insName+".hide()");

		ContentTd.onmouseover = new Function(this.insName+".show()");
		ContentTd.onmouseout = new Function(this.insName+".hide()");
		
		
	var oContentBlock = new contentBlock(name,ContentDiv);
		if (dropdownType == 'floating')	{
			oContentBlock.contentDiv.style.position = "absolute"
		};	
		//oContentBlock.showType = 'smooth'; 
		
	if (isShown) {
		oContentBlock.show();
	} else {
		oContentBlock.hide();
	}
		
	this.headerBlock = oHeaderBlock;
	this.contentBlock = oContentBlock;

    function getHeaderObj()
    {
        return this.headerBlock.getDivObj();
    }

    function getContentObj()
    {
        return this.contentBlock.getDivObj();
    }
	
    function shown() {
        return this.contentBlock.shown;
    }	
	
	function hide() {
		if (this.showDiv) this.contentBlock.hide();
		this.headerBlock.src = this.closedHeaderText;	
	}

	function show() {
		if (this.showDiv) this.contentBlock.show();
		this.headerBlock.src = this.openedHeaderText;			
	}	


    this.getHeaderObj   = getHeaderObj;
    this.getContentObj     = getContentObj;
	this.hide = hide;
	this.show = show;
	this.shown = shown;

}

