/**
 * Класс для работы с Ajax вызовами
 * 		Параметры вызова:
 * 		Адрес строится исходя из передачи двух параметров. 
 * 		Если передана форма - она становится базой для адреса, и дополняется параметрами из строки URL (Предполагается передача только параметров a=b)
 * 		Если форма не задана, сам URL является базовым адресом и используется как есть
 * 
 * 		loader - функция, выставляющая загрузчик
 * 		sucessCallback - функция вызова при успешной загрузке
 * 		errorCallback - функция вызова при неудачной загрузке
 * 		target - цель загрузки, она же цель загрузчика
 */

function Ajax()
{
	this.requestQuery = new Array();
	this.requestActive = null;
	this.defaultParams = {};
	
	this.constructor = function()
	{
		var def = {
			dataType: "xml", 
			loader: this.defaultLoader,
			sucessCallback: this.defaultSuccessCallback,
			errorCallback: this.defaultErrorCallback,
			target: null
		}
		this.setDefaultParams(def);
	}
	/**
	 * Стартер GET запроса
	 */
	this.get = function(params) 
	{
		if(params != null) {
			params.method = "GET";
			this.request(params);
 		}
	}
	
	/**
	 * Стартер POST запроса
	 */
	this.post = function(params)
	{
		if(params != null) {
			params.method = "POST";
			this.request(params);
 		}
	}
	
	/**
	 * Выставить список параметров по-умолчанию для запросов
	 */
	this.setDefaultParams = function(params)
	{
		for(var name in params) {
			this.setDefaultParam(name, params[name]);
		}
	}
	
	/**
	 * Выставить одиночный параметр по умолчанию
	 */
	this.setDefaultParam = function(name, value)
	{
		this.defaultParams[name] = value;
	}
	
	/*
	 * Private
	 */
	
	/**
	 * Сформировать запрос
	 */
	this.request = function(params)
	{
		params = mergeObjects(params, this.defaultParams);
		
		if(params.confirm) {
			var result = confirm(params.confirm);
			if(!result)
				return;
		}
		var requestObject = new RequestObject(params);
		this.setRequest(requestObject);
	}
	
	/**
	 * Взять следующий запрос
	 */
	this.getNextRequest = function()
	{
		if(this.requestActive == null) {
			var query = this.requestQuery;
			var request = query.shift();
			if(request) {
				this.requestQuery = query;
				this.requestActive = request;
				this.send(request);
			}
		}
	}

	/**
	 * Поставить запрос в очередь
	 */
	this.setRequest = function(request)
	{
		if(request.getLoader()) {
			var fc = request.getLoader();
			fc(request.getTarget());
		}
		
		var query = this.requestQuery;
		query.push(request);
		this.requestQuery = query;
		
		this.getNextRequest();
	}
	
	this.send = function(requestObject)
	{
		// Конфигурирование ajax
		var options = {};
		options.url = requestObject.getURL();
		options.data = requestObject.getData();
		options.dataType = requestObject.getDataType();
		options.type = requestObject.getMethod();
		
		options.error = function(x) {
			return function(answer) { x.errorCallback(answer, status) };
		}(this);
		options.success = function(x) {
			return function(answer) { x.successCallback(answer, status) };
		}(this);
		options.complete = function(x) {
			return function(answer) { x.ajaxComplete(answer, status) };
		}(this);
		
		$.ajax(options);
	}
	
	/**
	 * Сбросить активный запрос, вызвать следующий
	 */
	this.ajaxComplete = function(answer, status)
	{
		this.requestActive = null;
		this.getNextRequest();
	}
	
	/**
	 * Загрузчик по-умолчанию, стартует при установке запроса в очередь запросов
	 */
	this.defaultLoader = function(target)
	{
		if(target) {
			var progressBar = $("#progressBar");
			if(progressBar.size() == 0) {
				progressBar = $("<div class=\"progressBar\" id=\"progressBar\"></div>");
	
				var loadedArea = $(target);
				loadedArea.css("position", "relative");
				loadedArea.css("min-height", progressBar.css("height"));
				progressBar.css("width", loadedArea.width()+"px");
				progressBar.css("height", loadedArea.height()+"px");
			
				progressBar.css("position", "absolute");
				progressBar.css("left", "0px");
				progressBar.css("top", "0px");
				loadedArea.append(progressBar);
			}
		}
	}
	
	/**
	 * Успешный вызов
	 */
	this.successCallback = function(answer, status)
	{
		var request = this.requestActive;
		var fc = request.getSuccessCallback();
		if(fc != null) 
			fc(answer, request);
	}
	
	/**
	 * Вызов, закончившийся ошибкой
	 */
	this.errorCallback = function(answer, status)
	{
		var request = this.requestActive;
		var fc = request.getErrorCallback();
		if(fc != null) 
			fc(answer, request);
	}
	
	/*
	 * Обработчики по-умолчанию
	 */

	this.defaultSuccessCallback = function(xmlAnswer, request)
	{
		var redirect = $("redirect", xmlAnswer);
		if(redirect.size() == 1) {
			jajax.get( {url: redirect.text(), target: request.getTarget()} );
		}
		else {
			var html = $("content", xmlAnswer).eq(0).text();
			$(request.getTarget()).html(html);
			var script = $("script", xmlAnswer).eq(0).text();
			eval(script);
		}
	}
	
	this.defaultErrorCallback = function(xmlAnswer, request)
	{
		var progressBar = $("#progressBar");
		if(progressBar.size()) {
			progressBar.remove();
		}
	}
	
	this.constructor();
}


/**
 * Класс запроса
 */

function RequestObject(params)
{
	this.url = ""; // Адрес обращения
	this.method = "GET";
	this.target = null; // Тэг, куда направлено обращение
	this.data = null; // 
	this.sucessCallback = null; // Вызов функции при успешном выполнении
	this.errorCallback = null; // Вызов функции при провале
	this.dataType = "html"; // Тип ожидаемых данных
	this.loader = null; // Загрузчик, ставится в target
		
	this.constructor = function(params)
	{
		// Проверяем форму
		var form = null;
		if(params.form) {
			var jForm = $(params.form);
			if(jForm.size() == 1) {
				form = jForm;
			}
		}
		
		// Формируем адрес
		var url = new URL();
		if(form) {
			url.parseURL(form.attr("action"));
			if(params.url) {
				url.addParams(params.url);
			}
		}
		else if(params.url) {
			url.parseURL(params.url);
		}
		url.addParam("ajax", "on");
		this.url = url.getURL();
			
		// Формируем данные
		var baseData = {};
		if(form != null) {
			baseData = this.formFieldsToObj(form);
		}
		if(params.data) {
			baseData = mergeObjects(baseData, params.data, true);
		}
		this.data = baseData;
		
		// Напрямую переходят параметры
		if(params.method)
			this.method = params.method;
		this.target = params.target;
		this.sucessCallback = params.sucessCallback;
		this.errorCallback = params.errorCallback;
		if(params.dataType) {
			this.dataType = params.dataType;
		}
		
		if(params.loader) {
			this.loader = params.loader;
		}
	}
	
	/*
	 * Interface
	 */
		
	this.getURL = function() {
		return this.url;
	}
	
	this.getData = function() {
		return this.data;
	}
	
	this.getDataType = function() {
		return this.dataType;
	}
	
	this.getSuccessCallback = function() {
		return this.sucessCallback;
	}
	
	this.getErrorCallback = function() {
		return this.errorCallback;
	}
	
	this.getMethod = function() {
		return this.method;
	}
	
	this.getTarget = function() {
		return this.target;
	}
	
	this.getLoader = function()
	{
		return this.loader;
	}
	
	/*
	 * Protected
	 */
	
	this.formFieldsToObj = function(form)
	{
		var formElements = form.get(0).elements;
		var data = {};
		if (formElements && formElements.length) {
			var nameField;
			var value;
			var elem;
			for (var i = 0; i < formElements.length; i++)  {
				elem = $(formElements[i]);
				nameField = elem.attr("name");
				// Если не задано имя - в данные формы не попадает
				if(!nameField)
					continue;
				
				// Исключение для checkbox и 
				if(elem.attr("type") == "checkbox" || elem.attr("type") == "radio") {
					if(elem.attr("checked")) {
						value = elem.val();
					}
					else 
						value = null;
				}
				else {
					value = elem.val();
				}
				
				// Если нет значения - передавать нечего
				if(value == null)
					continue;
				
				//var encodeValue = encodeURIComponent(value);
				if(this.isArrayField(nameField)) {
					// Если поле - часть массива
					var arrayName = this.buildArrayName(nameField);
					var arrayValue = data[arrayName];
					if(!arrayValue) {
						arrayValue = new Array();
					}
					arrayValue.push(value);
					data[arrayName] = arrayValue;
				}
				else {
					// Если одиночное поле
					data[nameField] = value;
				}
			}
		}
		return data;
	}
	
	/**
	 * Определить тип имени поля, часть масисва или нет
	 */
	this.isArrayField = function(nameField)
	{
		if(nameField.indexOf("[") > 0) {
			return true;
		}
		return false;
	}
	
	this.buildArrayName = function(nameField)
	{
		var position = nameField.indexOf("[");
		return nameField.substring(0, position);
	}
	
	
	this.constructor(params);
}


/**
 * Класс для работы с адресами
 */
function URL(url)
{
	this.protocol = "";
	this.www = "";
	this.domain = "";
	this.path = "";
	this.params = {};
	this.anhcor = "";
	
	
	this.constructor = function(url)
	{
		url = url || null;
		if(url != null) {
			this.parseURL(url);
		}
	}
	
	this.getProtocol = function()
	{
		return this.protocol;
	}
	
	this.getPath = function()
	{
		return this.path;
	}

	this.getDomain = function()
	{
		return this.domain;
	}
		
	this.getParams = function()
	{
		return this.params;
	}
	
	this.getAnchor = function()
	{
		return this.anchor;
	}
	
	/**
	 * Получить полный путь
	 */
	this.getURL = function()
	{
		return this.getURLByPattern(['protocol', 'www', 'domain', 'path', 'params', 'anchor']);
	}
	
	/**
	 * Получить текстовое представление адреса по шаблону
	 * pattren ['protocol', 'www', 'domain', 'path', 'params', 'anchor']
	 */
	this.getURLByPattern = function(pattern)
	{
		if(!pattern || pattern.length == 0)
			return "";
		
		var position;
		var str = "";
		
		// Протокол
		if(inArray('protocol', pattern) && this.protocol) {
			str += this.protocol + "://";
		}
		// Домен
		if(inArray('domain', pattern) && this.domain) {
			if(inArray('www', pattern) && this.www) {
				str += this.www + ".";
			}
			str += this.domain;
		}
		var pathWas = false;
		// Путь
		if(inArray('path', pattern) && this.path) {
			if(str != "") {
				str += "/";
				pathWas = true;
			}
			str += this.path;
			pathWas = true;
		}
		// Параметры
		if(inArray('params', pattern)) {
			var paramsStr = this.buildParams();
			if(paramsStr) {
				if(str != "" && !pathWas) {
					str += "/";		
					pathWas = true;
				}
				str += "?" + paramsStr;
			}
		}
		// Якорь
		if(inArray('anchor', pattern) && this.anchor) {
			if(str != "" && !pathWas) {
				str += "/";		
				pathWas = true;
			}
			str += "#" + this.anchor;
		}
		
		return str;
	}
	
	/**
	 * Парсить строку в объект 
	 */
	this.parseURL = function(urlString)
	{
		if(urlString != null && urlString != "") {
			pattern = /(?:([a-z]*):\/\/)?(?:(www)\.)?(?:([a-z0-9\._-]+\.[a-z0-9\._-]+)\/?)?([^\?]*)\??([^\s#]*)(?:#([^\s]*))?/i;
			var findArray = pattern.exec(urlString);
			if (findArray != null) {	
				// протокол
				var protocol = findArray[1];
				if(!protocol)
					protocol = "";
				this.protocol = protocol;
				
				// www
				var www = findArray[2];
				if(!www)
					www = "";
				this.www = www;
				
				// Домен
				var domain = findArray[3];
				if(!domain)
					domain = "";
				this.domain = domain;
				
				// Путь 
				var path = findArray[4];
				if(!path)
					path = "";
				this.path = path;
				
				// Параметры
				var params = findArray[5];
				var paramsObj = {};
				if(params) {
					paramsObj = this.parseParams(params);
				}
				this.params = paramsObj;
				
				// Якорь
				var anchor = findArray[6];
				if(!anchor)
					anchor = "";
				this.anchor = anchor;
			}
		}
	}
	
	/**
	 * Внести в список парамтеров
	 */
	this.addParam = function(name, value)
	{
		var params = this.params;
		params[name] = value;
		this.params = params;
	}
	
	/**
	 * Добавить параметры
	 * @param object/string params
	 * @return
	 */
	this.addParams = function(params)
	{
		if(!params)
				return;
		
		if((typeof params) != "object") {
			params = this.parseParams(params);
		}
		for (var name in params) {
			this.addParam(name, params[name]);
		}
	}
	
	/*
	 * Private 
	 */
	
	/**
	 * Парсить параметры
	 */
	this.parseParams = function(paramsString)
	{
		var paramsObj = {};
		if(paramsString) {
			var paramArray = paramsString.split("&");
			var paramItem;
			for(var index = 0; index < paramArray.length; index++) {
				paramItem = paramArray[index].split('=');
				paramsObj[paramItem[0]] = paramItem[1];
			}
		}
		return paramsObj;
	}
	
	/**
	 * Потстроить строку из параметров
	 */
	this.buildParams = function()
	{
		var params = this.params;
		var str = "";
		for(var name in params) {
			if(str)
				str += "&";
			str += name + "=" + params[name];
		}
		return str;
	}
	
	
	this.constructor(url);
}
// ДИНАМИЧЕСКИЕ ЭЛЕМЕНТЫ

// Быстрое редактирование
function edit_item (row, url, time)
{
	close_edit_window();
	var q_table = create_element('TBODY');		
	var q_header = create_element ('TH', {colspan: '2'}, "Параметры");
	q_header = create_element('TR', null, q_header);
	q_table.appendChild(q_header);
	
	var q_field;
	
	for(var field in row) {
				
		var q_field_title = create_element('TD', {className: 'title'}, row[field][0]+":");
		
		// Назначем параметры элементу формы
		if (!row[field][2]) {
			var param_struct = {name: field, value: row[field][1] || "", type: 'text'};
		}
		else if(row[field][2]=="file") {
			var param_struct = {name: field, type: 'file'};
		}
		else if(row[field][2]=="textarea") {
			var param_struct = {name: field, className: 'small'};
		}
		else if(row[field][2]=="hidden") {
			var param_struct = {name: field, type: 'hidden', value: row[field][1] || ""};
		}
		// Создаем элемент формы
		if(row[field][2]=="textarea") {
			var q_field_value = create_element('textarea', param_struct);
			q_field_value.value = row[field][1];
		}
		else {
			var q_field_value = create_element('input', param_struct);
		}
		q_field_value = create_element('TD', null, q_field_value);
					
		q_field = create_element ('TR', null, [q_field_title, q_field_value]);
		if(row[field][2]=="hidden")
			q_field.style.display = 'none';
			
		q_table.appendChild(q_field);
	}
	
	var q_submit = create_element ('INPUT', {type: 'submit', value: 'Сохранить', className: 'button'});
	q_submit =create_element('TH', {colspan: 2}, q_submit);
	q_submit = create_element('TR', null, q_submit);
	q_table.appendChild(q_submit);

	q_table = create_element ('TABLE', {border: '0', cellspacing: '0', cellpadding: '0', className: 'edit format'}, q_table);
	var q_form =  create_element ('FORM', {name: 'quick_form', method: 'post', action: url, enctype: 'multipart/form-data'}, q_table);
	
	var q_close = create_element('A', {className: 'close_button', href: 'javascript: void(0)'}, "X");
	
	if(typeof attachEvent != "undefined") 
		q_close.attachEvent("onclick", close_edit_window);
	else
		q_close.addEventListener("click", close_edit_window, false);
							
	var container = create_element ('DIV', {id: 'quick_edit', className: 'quick_edit'}, [q_close, create_element("BR"), q_form]);
	if(BrowserDetect.browser=="Explorer") {
		var height = window.screenTop +(document.body.clientHeight/2);
	}
	else {
		var height = window.pageYOffset +(document.body.clientHeight/2);
	}
	container.style.top = height+'px';
	document.body.insertBefore(container, document.body.firstChild);
}
function close_edit_window ()
{
	var open_object = select_object('quick_edit');
	if(open_object)	
		open_object.parentNode.removeChild(open_object);
}

// Модульное окно
function dialog(title, content)
{
	dialog_alert.create('window_notice', title, content);
}
// Загрузчик
function loader_set()
{
	var old_loader = select_object("widget_loader");
	if(old_loader)
		return false;
	var elem_loader = create_element("div",  {className: 'widget_loader', id: "widget_loader"}, " ");
	document.body.appendChild(elem_loader);
}
function loader_clear()
{
	var old_loader = select_object("widget_loader");
	if(old_loader)
		old_loader.parentNode.removeChild(old_loader);
}

// РАБОТА С КАРТИНКАМИ

// Содержит список пар id имя файла
var img_array = new Array();

// Загрузить список - ргументы это пары id и img_array
function image_preload()
{
	for(i=0; i<arguments.length; i=i+2 ) {
		img = new Image();
		img.src = "images/"+arguments[i+1];
		img_array[arguments[i]] = img;
	}
}
// Заменить картинку по id
// img_id - uid картинки
// pic_id - имя из списка img_array (если пусто, то используется img_id)
// actor_uid - кто вызвал смену картинки, если при наведении на саму же картинку - можно пропустить
function image_swap (img_uid, actor_uid, pic_id)
{
	elem_pic = select_object(img_uid);
	
	actor_uid = actor_uid || img_uid;
	elem_actor = select_object(actor_uid);
	
	pic_id = pic_id || elem_pic.id;
	
	if (elem_pic!=undefined && img_array[pic_id]!=undefined && img_array[pic_id].src!=elem_pic.src) {
		// Заменяем, старую подвешиваем на tmp_src
		if (elem_pic.tmp_src==undefined) {
			elem_pic.tmp_src = elem_pic.src;
			elem_pic.src = img_array[pic_id].src;
			
			// Привязываем id вызываемой картинки картинку
			elem_actor.bind_id = elem_pic.id;
			add_event(actor_uid, "mouseout", image_restore, false);
		}
	}
}
// Востановить замененную картинку
function image_restore (evt) 
{
	var elem_actor = select_target(evt);
	var pic = elem_actor.bind_id || elem_actor.id;
	var elem_pic = select_object(pic);
	
	if (elem_actor!=undefined) {
		delete_event(elem_actor, "mouseout", image_restore);
		// Возвращаем из tmp_src
		if (elem_pic.tmp_src!=undefined) {
			elem_pic.src = elem_pic.tmp_src;
			elem_pic.tmp_src = undefined;
		}
	
	}
}

// ФУНКЦИИ 2 РЕДАКЦИИ

// Скопировать поля
// Первый аргумент - имя формы куда перенести элемент
// Второй аргумент имя формы из которой берется элемент
// Дальше повторяются имена полей для переноса
function element_copy (form_from, form_to, elem_array) 
{
	var inp;
	var elem_source = select_object(form_from);
	var elem_insert = select_object(form_to);
	
	for (var i=0; elem_array.length>i; i+=1) {		
		if (elem_insert.elements[elem_array[i]]) {
			elem_insert.elements[elem_array[i]].value=elem_source.elements[elem_array[i]].value;
		}
		else {
			inp  = document.createElement('INPUT');
			inp.setAttribute("type", "hidden");
			inp.setAttribute("name", elem_array[i]);
			inp.setAttribute("value", elem_source.elements[elem_array[i]].value);
			elem_insert.appendChild(inp);
		}
	}

	return false;
}
// Выбор элементов по значению
// elem_uid - Имя элементов
// arg - массив значений, элемент с которым нужно выбрать
function form_element_select (elem_uid, arg) 
{
	if(!arg)
		return false;
	if(!is_array(arg))
		arg = new Array(arg);
	
	var elem = select_object(elem_uid);

	if (elem.length) {
		
		for (var item=0; elem.length>item; item++ ) {
			var val = get_value(elem[item]);

			for (var arg_item=0; arg.length>arg_item; arg_item++) {
				if (val==arg[arg_item])
					set_select(elem[item]);
			}
		}			
	}
}


// Отметить все Checkbox
// elem_uid - имя чекбоксов
// invers - если 1 - то убрать выделение
function form_mark_field(elem_uid, invers)
{
	invers = invers || 0;
	
	if (invers==0)
		make_var = true;
	else
		make_var = false;
		
	var elem = select_object(elem_uid);
		
	if (!elem)
		return false;
		
	if (elem.length) {
		for (var i=0; i < elem.length; i++) {
	 		elem[i].checked=make_var;
		}
	}
	else {
		elem.checked=make_var;
	}
}


// ДИНАМИКА ОБЪЕКТОВ

// Dыбрать элемент
// Только один список
var select_item_last = null;
function select_item(uid, effect_type, effect, effect_default)
{
	var elem = select_object(uid);
	if(!elem)
		return false;
		
	if (select_item_last && select_item_last==elem)
		return false;
		
	switch (effect_type) 
	{
		case "color":
				if (select_item_last!=null)
					select_item_last.style.color = effect_default;
				elem.style.color = effect;
			break;
		default: 
				
			break;	
	}
	select_item_last = elem;
}
// Показать один из элементов, остальные скрыты
// elem_baseid - базовое имя элемента (к нему прибавляется номер, начиная с 0)
// elem_index - номер элемента для показа (undefined  - скрыть все)
function display_one (elem_baseid, elem_index)
{ 
	var current_index=0;
	var elem = select_object(elem_baseid+current_index);
	// Скрыть все
	while ( elem ) {
		elem.style.display="none";
		current_index++;
		elem = select_object(elem_baseid+current_index);
	}
	// Открыть один
	if(elem_index!=undefined) {
		elem = elem = select_object(elem_baseid+elem_index);
		if (elem)
			elem.style.display="";
	}
}


// Показать элемент в зависимости от того поставлен флажок checkbox или нет
// uid - элемент чекбокс
// show_uid - показываемый объект
function display_condition (uid, show_uid)
{ 
	elem = select_object(uid);
	showelem = select_object(show_uid);
	
	if(elem==undefined || showelem==undefined)
		return false;

	if(elem.checked==true)
		show = '';
	else
		show = 'none';
		
	showelem.style.display = show;
}

// Показать элемент в зависимости от значения
// uid - элемент чекбокс
// status_table - массив какие элементы к какому знач привязаны [[знач, элементб элемент], ]
function display_condition_value (uid, status_table)
{ 
	var elem = select_object(uid);
	
	if(elem==undefined)
		return false;
		
	var elem_value = elem.value;

	// Сброс всей видимости
	for(var i=0; i<status_table.length; i++){
		elem_array = status_table[i];
		
		elem_change_status (array_shift(elem_array), 0);	
	}
	
	for(i=0; i<status_table.length; i++){
		elem_array = status_table[i];
	
		if (elem_array[0]==elem_value && elem_array.length>1) {
			elem_change_status (array_shift(elem_array), 1);
		}
	}
}
// elem_array - [uid,]
// elem_status - (0 - не виден, 1 - виден, 2 - инвертировать)
function elem_change_status (elem_array, elem_status)
{
	if(elem_status)
		show = '';
	else
		show = 'none';

	if(!is_array(elem_array)) {
		elem_array = [elem_array];
	}
	for(var i=0; i<elem_array.length; i++){
		elem_current = select_object(elem_array[i]);
		if(elem_status==1)
			show = '';
		else if (elem_status==2) {
			if (elem_current.style.display!="none")
				show = 'none';
			else
				show = '';
		}
		else
			show = 'none';
		if(elem_current)
			elem_current.style.display =  show;
	}
}

// Добавить объект в таблицу
// clone_elem - название клонируемого объекта 
// name_insert - место вставки

// inputs - Число ввставок
// max_inputs - Максимальное число вставок
var inputs = Array();
var max_inputs = Array();

function row_insert(clone_elem, insert_place, after){
	var clone_point = select_object(clone_elem);
	var insert_point = select_object(insert_place);
	var clone_node;
	var after = after || 0;
	clone_node = clone_point.cloneNode(true);
	
	clone_node.setAttribute("id", "new_"+inputs);
	//clone_node.style.display="";
	if (inputs[insert_place]==undefined || max_inputs[insert_place]==undefined || max_inputs[insert_place]==0 || inputs[insert_place]<max_inputs[insert_place]) {
		if(after)
			insert_point.parentNode.insertBefore(clone_node,insert_point.nextSibling);
		else
			insert_point.parentNode.insertBefore(clone_node,insert_point);
		if (inputs[insert_place]==undefined)
			inputs[insert_place]=0;
		else
			inputs[insert_place]++;
	}
}
// выставить максимум элементов для вставки
function row_max(insert_place, count) {
	max_inputs[insert_place]=count;
}
// выставить текущее число элементов
function row_current(insert_place, count) {
	inputs[insert_place]=count;
}
// выставить текущее число элементов
function row_decrease(insert_place, count) {
	count = count || 1;
	if (inputs[insert_place]!=undefined)
		inputs[insert_place]=inputs[insert_elem] - count;
	else
		inputs[insert_place] = 0;
}


// ПРОЧЕЕ

// Сгенерировать Пароль
function generate_password(field, size) 
{
	size = size || 8;
	var digit = new Array("0","1","2","3","4","5","6","7","8","9")
	var symbol_b = new Array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","Y","Z")
	var symbol_l = new Array("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","y","z")

	var password = "";

	for (var i= 0; i<size; i++)
	{
		var rand = Math.random();
		if ( (rand - 1.0/3.0) < 0.0)
		{
			rand = Math.floor(Math.random() * 9);
			password += digit[rand]
 		}
		else if ( (rand - 2.0/3.0) < 0.0)
		{
			rand = Math.floor(Math.random() * 24);
			password += symbol_b[rand]
 		}
		else
		{
			rand = Math.floor(Math.random() * 24);
			password += symbol_l[rand]
		}
	}
	
	elem = select_object(field);
	elem.value = password;
}


//РАБОТА С ОКНАМИ

//url, pic_width, pic_height, new_win, win_scroll, win_toolbar
function win(param)
{
	param = win_param_default (param);
	if(param==false)
		return false;
	
	var NewWin=window.open("", param.win_name,'width='+param.win_width+',height='+param.win_height+',resizable=yes,menubar='+param.win_toolbar+',toolbar='+param.win_toolbar+',scrollbars='+param.win_scroll+',status=no,location=no');
	NewWin.document.open();
	NewWin.document.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">');
	NewWin.document.write('<html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><title>Галерея</title></head><body style="margin:0px;padding:0px">');
	NewWin.document.write('<a href="javascript:self.close()"><img src=upload/'+param.url+' border=0></a>');
	NewWin.document.write('</body></html>');
	NewWin.document.close();
}

function win_page(param) 
{
	param = win_param_default (param);
	if(param==false)
		return false;

	var NewWin=window.open(param.url, param.win_name,'width='+param.win_width+',height='+param.win_height+',resizable=yes,menubar='+param.win_toolbar+',toolbar='+param.win_toolbar+',scrollbars='+param.win_scroll+',status=no,location=no');
}

//Установить параметры по умолч
function win_param_default (param)
{
	if(param && param.url)
	{
		param.win_width  = param.win_width || 600; 
		param.win_height  = param.win_height || 400; 
		param.new_win = param.new_win || 1;
		param.win_scroll  = param.win_scroll || 'no';
		param.win_toolbar  = param.win_toolbar || 'no';  
		
		if (param.new_win) 
			param.win_name = (Math.floor(Math.random()*1000) ).toString();
		else 
			param.win_name = 'default';
			
		return param;
	}

	return false;	
}
// Объединить две структуры
// objectSource - основной объект
// objectAdd - объект, который записывается поверх
// overwrite - если false, то добавлять, но не менять уже установленые значения
function mergeObjects(objectSource, objectAdd, overwrite)
{
	overwrite = overwrite || false;
	if(objectAdd) {
		for(var name in objectAdd) {
			if(overwrite || objectSource[name] == undefined) {
				objectSource[name] = objectAdd[name];
			}
		}
	}
	return 	objectSource;
}

// Аналог in_array php
function inArray(needle, array)
{
	var length = array.length;
	for(var i = 0; i < length; i++) {
		if(needle == array[i])
			return true;
	}
	return false;
}

// Создать элемент
// tag - имя тега
// param - объект с параметрами
// inner_element - Вложеный элемент (может быть массивом или текстом)
function create_element (tag, param, inner_element)
{
	inner_element = inner_element || null;
	
	var elem;
	if(typeof(tag) == "string")
		elem  = document.createElement(tag);
	else
		elem = tag;
			
	if (param) {
		for(var key in param) {
			switch (key) {
				case "inner":
						var html = param[key];
					break;
				case "class":
				case "className":
					if(BrowserDetect.browser=="Explorer") 
						elem.setAttribute("className", param[key]);
					else
						elem.setAttribute("class", param[key]);
					break;
				case "name":
						elem.setAttribute("name", param[key]);
					break;
				case "enctype":
						elem.setAttribute("enctype", param[key]);
						elem.setAttribute("encoding", param[key]);					
					break;
				case "colspan":
					if(BrowserDetect.browser=="Explorer") 
						elem.setAttribute("colSpan", param[key]);
					else
						elem.setAttribute("colspan", param[key]);
					break;
				default:
						elem.setAttribute(key, param[key]);
					break;
			}
		}
	}
	
	if (inner_element) {
		if(typeof(inner_element) == "string")
			elem.appendChild(create_text_element(inner_element));
		else if(is_array(inner_element))
			for(var i=0; i<inner_element.length; i++)
				elem.appendChild(inner_element[i]);
		else
			elem.appendChild(inner_element);
	}
	
	if(html!=undefined) {
		elem.innerHTML = html;
	}
	
	return elem;
}

// Создать текстовый элемент
function create_text_element (text_inner)
{
	var elem;
	elem = document.createTextNode(text_inner);
	return elem;
}


// СИСТЕМНЫЕ

// Выбор объекта
// На входе структура 
//  	form: [form_name, elem_name],
//		id:,
//   	pointer: 
function select_object(uni_id)
{
	var elem;
		
	if(typeof( uni_id ) == 'string') {
		uni_id = {id: uni_id};
	}
		
	if(typeof(uni_id) == "object" && uni_id.nodeType) {
		return uni_id;
	}
	if (uni_id.form){
		if ( is_array(uni_id.form) )
			form_name = uni_id.form[0];
		else
			form_name = uni_id.form;
		
		elem = document.forms[form_name];

		if (is_array(uni_id.form) && uni_id.form[1]) {
			var subelem = uni_id.form[1];
		}
		else if(uni_id.element) 
			var subelem = uni_id.element;
		if(subelem)	
			elem = elem.elements[subelem];
		
		return elem;
	}
	if (uni_id.id) {
		return document.getElementById(uni_id.id);
	}
	if (uni_id.pointer) {
		return uni_id.pointer;
	}
	
	return undefined;
}

function get_attribute (elem, attribute)
{
	var attribute_array = elem.attributes;
	if(!attribute_array || attribute_array.length<1)
		return null;
	
	for (var i=0; attribute_array.length>i; i++) {
		if(attribute_array[i].name==attribute)
			return attribute_array[i].value;
	}
}

function set_attribute (elem, attribute, new_value)
{
	var attribute_array = elem.attributes;
	if(!attribute_array || attribute_array.length<1)
		return null;
	
	for (var i=0; attribute_array.length>i; i++) {
		if(attribute_array[i].name==attribute) {
			attribute_array[i].value = new_value;
			return true;
		}
	}
}

// Получить крозбраузерный target объекта вызвавшего событие
function select_target(evt)
{
	var evt = evt || false;
	
	if(window.event) {
		return window.event.srcElement;
	}
	else if(evt) {
		if(typeof(Event)!="undefined" && evt instanceof Event) {
			return evt.target; 
		}
		else {
			return evt;
		}
	}
	else {
		return false;
	}
		
}


// Получить текст или свойство объекта формы
// elem_pointer - Ссылка на объект
function get_value(elem_pointer) 
{
	if (elem_pointer==undefined)
		return NULL;
		
	var elem_value;
	
	if(elem_pointer.value!=undefined)
		elem_value = elem_pointer.value;
	else if (elem_pointer.text!=undefined)
		elem_value = elem_pointer.text;
	else
		elem_value = elem_pointer.innerHTML;
		
	return elem_value;
}

// Поставить текст или свойство объекта формы
// elem_pointer - Ссылка на объект
function set_value(elem_pointer, elem_value) 
{
	if (elem_pointer==undefined)
		return false;
	
	if(elem_pointer.value!=undefined)
		elem_pointer.value = elem_value;
	else if (elem_pointer.text!=undefined)
		elem_pointer.text = elem_value;
	else
		elem_pointer.innerHTML = elem_value;
		
	return true;
}

// Привязать функцию к событию
// event_name - тип события
// function_pointer - указатель на функцию
// execute - выполнить сразу (для списка - только первому объекту)
function add_event(uid, event_name, function_pointer, execute)
{
	var elem = select_object(uid);
	if(elem) {
		execute = execute || false;
		
		if(!elem.length)
			elem = new Array(elem);
		
		for(var i=0; i< elem.length; i++) {
			if(typeof attachEvent != "undefined") 
				elem[i].attachEvent("on"+event_name, function_pointer );
			else
				elem[i].addEventListener(event_name, function_pointer, false);
			if(execute) { // Выполнить для первого объекта
				function_pointer(elem[i]);
				execute = false;
			}
		}
	}
}

// Привязать функцию к событию
// event_name - тип события
// function_pointer - указатель на функцию
// execute - выполнить сразу (для списка - только первому объекту)
function delete_event(uid, event_name, function_pointer)
{
	var elem = select_object(uid);
	if(elem) {
		
		if(!elem.length)
			elem = new Array(elem);
		
		for(var i=0; i< elem.length; i++) {
			if(typeof detachEvent != "undefined") 
				elem[i].detachEvent("on"+event_name, function_pointer );
			else
				elem[i].removeEventListener(event_name, function_pointer, false);
		}
	}
}


// Системные команды
function is_array( mixed_var ) {   
 
    return ( mixed_var instanceof Array );
}

function array_shift( elem_array ) {    
 
    var tmp_arr = [];
 
    // input sanitation
    if( !elem_array || !elem_array.length ){
        return null;
    }
 	
 	for (var i=1; i<elem_array.length; i++) {
 		tmp_arr[i-1]=elem_array[i];
 	}
 	
    return tmp_arr;
}

// Поставить значение выбрано
function set_select(elem)
{
	if (elem==undefined)
		return false;
		
	if (elem.type=="checkbox" || elem.type=="radio")
		elem.checked=true;
	else
		elem.select=true;
}


// Скопировать из объекта в клипбоард
function copy_clipboard(uid)
{
	var elem = select_object(uid);
	var val = get_value(elem);

	if(val)
		window.clipboardData.setData('Text',val);
}

function set_cookie (name, value, expires, path, domain, secure) {
      document.cookie = name + "=" + escape(value) +
        ((expires) ? "; expires=" + expires : "") +
        ((path) ? "; path=" + path : "") +
        ((domain) ? "; domain=" + domain : "") +
        ((secure) ? "; secure" : "");
}

function get_cookie(name) {
	var cookie = " " + document.cookie;
	var search = " " + name + "=";
	var setStr = null;
	var offset = 0;
	var end = 0;
	if (cookie.length > 0) {
		offset = cookie.indexOf(search);
		if (offset != -1) {
			offset += search.length;
			end = cookie.indexOf(";", offset)
			if (end == -1) {
				end = cookie.length;
			}
			setStr = unescape(cookie.substring(offset, end));
		}
	}
	return(setStr);
}



function debug_object(obj, level)
{
	if(typeof(obj)!='object')
		return false;
	container = debug_object_inner(obj);
	document.body.appendChild(container);
}
function debug_object_inner(obj, title_obj, level)
{
	level = level || 0;
	title_obj = title_obj || "";
	var arr = new Array();
	
	if(title_obj)
		arr[arr.length] = create_element("DIV", {style: "font-weight: bold;"}, title_obj+"=>");

	for(var field in obj) {
		if(typeof(obj[field]) == 'object' && level)
			arr[arr.length]= debug_object_inner(obj[field], field, level);
		else 
			arr[arr.length] = create_element("DIV", null, field+": "+obj[field]);
	}	
			
	container = create_element("DIV", {style: "padding-left: 20px;"}, arr);
	return container;
}

function is_ie(version) {
	version = version || 7;
	if(document.all !== undefined && typeof document.body.style.maxHeight == "undefined" && version==6) // Глупый осел
		return true;
	if(document.all !== undefined && version == 7)
		return true;

	return false;
}

var BrowserDetect = {
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
		{ 	string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari"
		},
		{
			prop: window.opera,
			identity: "Opera"
		},
		{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
		},
		{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
		}
	],
	dataOS : [
		{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			subString: "Mac",
			identity: "Mac"
		},
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]

};
BrowserDetect.init();
// Получить позицию прокрутки кросбраузерно
function document_scroll()
{
	var yScrolltop;
    var xScrollleft;
    if (self.pageYOffset || self.pageXOffset) {
      yScrolltop = self.pageYOffset;
      xScrollleft = self.pageXOffset;
    } else if(document.documentElement && document.documentElement.scrollTop || document.documentElement.scrollLeft ){   // Explorer 6 Strict
      yScrolltop = document.documentElement.scrollTop;
      xScrollleft = document.documentElement.scrollLeft;
    } else if (document.body) {// all other Explorers
      yScrolltop = document.body.scrollTop;
      xScrollleft = document.body.scrollLeft;
    }
		return new Array(xScrollleft, yScrolltop);
}
// Получить отображаемую высоту документа кросбраузерно
function document_size()
{
	if(window.innerHeight || window.innerWidth) {  
		h = window.innerHeight;
	  	w = window.innerWidth;
	}
	else if (document.documentElement.clientHeight || document.documentElement.clientWidth) {
		h = document.documentElement.clientHeight;
		w = document.documentElement.clientWidth;
	}
					
	return new Array(w, h);
}
// Высота внут реней части окна
function page_size(){
	if (window.innerHeight && window.scrollMaxY) {// Firefox
		yWithScroll = window.innerHeight + window.scrollMaxY;
		xWithScroll = window.innerWidth + window.scrollMaxX;
	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
		yWithScroll = document.body.scrollHeight;
		xWithScroll = document.body.scrollWidth;
	} else { // works in Explorer 6 Strict, Mozilla (not FF) and Safari
		yWithScroll = document.body.offsetHeight;
		xWithScroll = document.body.offsetWidth;
  	}
	arrayPageSizeWithScroll = new Array(xWithScroll,yWithScroll);
	//alert( 'The height is ' + yWithScroll + ' and the width is ' + xWithScroll );
	return arrayPageSizeWithScroll;
}
// AJAX

var store_function_array = new Array();

function store_function (str_function)
{
	store_function_array[store_function_array.length] = str_function;
}
function store_function_execute ()
{
	var i;
	for (i=0; i < store_function_array.length; i++) {
		eval(store_function_array[i]);
	}
}

function ajax_class() {
	
this.req = null;
this.query = new Array();
this.time_out = null;
this.param = null;

// Работа с очередью
// param - параметр
this.query_request = function (param)
{
	if(this.param==null) { // Если нет текущего выполняемого
		this.param = param;
		this.ajax_send(param);
	}
	else {
		this.query.push(param); // Добавить в конец очереди
		return false;
	}
	return true;
}

this.set_timeout = function()
{
	//this.time_out = setTimeout( ajax.handle_error, 20000);
}
this.clear_timeout = function()
{
	if (this.time_out)
		clearTimeout(this.time_out);
}
// Если Timeout  (Внешний вызов)
this.handle_error = function (message)
{
	ajax.finish();
	if(message)
		alert(message);
}
// Все сбросить
this.finish = function ()
{
	this.clear_timeout();
	this.req.abort();
	setTimeout(ajax.next_query, 100);
	return true;
}
// Следующий элемент в очереди (Внешний вызов)
this.next_query = function()
{
	if(is_array(ajax.query) && ajax.query.length>0) {
		param_next = ajax.query.shift();
		ajax.param = param_next;
		ajax.ajax_send(param_next);
	}
	else
		ajax.param = null;
}



// Ассинхронное обращение get
// param - необработаный набор аргументов
this.get = function(param) {
	if (!param)
		return false;
	if (param.confirm) {
		var result = confirm(param.confirm);
		if(!result)
			return false;
	}
	param=this.compile_param(param, "GET");
	
    return this.query_request(param);
}

// Ассинхронное обращение post
this.post = function(param) {
	if (!param)
		return false;
	if (param.confirm) {
		var result = confirm(param.confirm);
		if(!result)
			return false;
	}
	param=this.compile_param(param, "POST");
	
    return this.query_request(param);
}

// Обработать параметр
this.compile_param = function(param, method)
{
	param.method = method;
	// Данные для POST
	if(param.form) {
		param.data = this.form_to_data({form: param.form});
		// Если нет адреса - использовать форму
		if(!param.url)
			param.url = select_object({form: param.form}).action
	}
	if(param.url_add) {
		if(param.url)
			param.url = param.url + "&";
		else 
			param.url = "";
		param.url = param.url + param.url_add;
	}
	// Функция обработки
	if(!param.processing)
		param.processing = this.default_processing;
				
	// Функция обработки
	if(param.executer && typeof(param.executer) == "string") {
		if(param.executer=="search_holder")
			param.executer = ajax.executer_search_holder;
	}
	
	return param; 
}

// Данные из формы в переменную для отправки
this.form_to_data = function(formname_uid)
{
	var form_elements = select_object(formname_uid).elements;
	var data_post = "";
	if (form_elements && form_elements.length) {
		for (i=0; i<form_elements.length; i++)  {
			var res = true;
			if(!form_elements[i].name) 
				res = false;
			if(form_elements[i].type=="checkbox" && form_elements[i].checked!=true)
				res = false;
						
			if(res) {
				if (data_post!="")
					data_post+="&";
				data_post += form_elements[i].name + "=" + encodeURIComponent( form_elements[i].value );
			}
		}
	}
	return data_post;
}

// Запуск
// param - Обработаный набор аргументов
this.ajax_send = function(param)
{
	if (param.method == "GET") {
		param.data = null;
	}
	
	if (param.simple==true) {
		document.location = param.url;
		return true;
	}

    if (window.XMLHttpRequest) {		// для "родного" XMLHttpRequest
		this.req = new XMLHttpRequest();
		var req_type = 0;
    } else if (window.ActiveXObject) { 	// для версии с ActiveX
        this.req = new ActiveXObject("Microsoft.XMLHTTP");
		var req_type = 1;
    }
    if (this.req) {
    	this.req.onreadystatechange = param.processing;
        this.req.open(param.method, param.url+"&ajax=on", true);
        
     	if (param.method == "GET") {
     		if(req_type==1)
      			this.req.send();
      		else
      			this.req.send(param.data);
      	}
      	else {
      	    this.req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
      		this.req.send(param.data);
      	}
    	this.set_timeout();
	
		return true;
   }
   return false;
}

// Получить результат (Внешний вызов)
this.default_processing = function() {
	var req = ajax.req;
    if (req.readyState == 4) {
		var param = ajax.param;
		var status = req.status;
		var response = req.responseXML;
		ajax.finish(); // С этого места локальна
		
        // для статуса "OK"
        if (status == 200) 
           	ajax.build_result(response, param);     
		// Редирект
		else if (status == 302 )
			alert("Страница переместилась");
		else 
            alert("Страница не найдена");
    }
}
// Обработать результат
this.build_result = function(result, param) {
	if(!result)
		return false;
	
	var executer;
	if(param.executer) {
		executer = param.executer;
	}
	else {
		executer = this.executer_default;
	}
	var data = new Array();
	data['redirect'] = select_tag(result, 'redirect');
	data['content'] = select_tag(result, 'content');
	data['response'] = select_tag(result, 'response', 'list');
	data['parametr'] = param;
	
	return executer(data);
}

// Обработчик полученых данных по-умолчанию
this.executer_default = function (data)
{
	if(data['redirect']) {
		ajax.get( {tag: data['parametr'].tag, url:data['redirect']} );
	}
	else if(data['parametr'].tag) {
		var elem = select_object(data['parametr'].tag);
		if(elem) {
			elem.innerHTML=data['content'];
		}
		store_function_execute();
	}
	
	return true;
}
// Обработчик полученых данных по-умолчанию
this.executer_search_holder = function (data)
{
	ajax.post( {tag: data['parametr'].tag, form:"search_holder"} );

	return true;
}
	
}
var ajax = new ajax_class();

// Получить данные из XML
function select_tag(source, id, type)
{
	type = type || "single";
	elem = source.getElementsByTagName(id);
	if (!elem || elem.length!=1)
		return null;
		
	elem = elem[0];
	
	var list;
	switch(type)
	{
		case "single":
			if(elem.firstChild)
				list = elem.firstChild.nodeValue;
			break;
		
		case "list": // Взять списком содержимое тег
			list = new Array();
			elem = elem.childNodes;
			for(var i=0; i < elem.length; i++) {
				var cur_elem = elem.item(i);
				if(cur_elem.nodeType != "TEXT_NODE" && cur_elem.firstChild)
					list[cur_elem.tagName] = cur_elem.firstChild.nodeValue;
			}
			break;
	}
		
	return list;
}




// Работа с формами

function form_class() {
		
	// Отправить форму
	// param - необработаный набор аргументов
	this.send = function(param) {
		if (!param)
			return false;
		// Если есть параметр запроса подтверждения
		if (param.confirm) {
			var result = confirm(param.confirm);
			if(!result)
				return false;
		}
		param=this.compile_param(param);
		
	    return this.request(param);
	}
	
	// Перейти по ссылке
	this.link = function(param) {
		if (!param)
			return false;
		// Если есть параметр запроса подтверждения
		if (param.confirm) {
			var result = confirm(param.confirm);
			if(!result)
				return false;
		}
		param=this.compile_param(param);
		if(param.url)
			document.location = param.url;
		return true;
	}
	
	// Обработать параметр
	this.compile_param = function(param) {
		if(param.url_add) {
			if(param.url)
				param.url = param.url + "&";
			else 
				param.url = "";
			param.url = param.url + param.url_add;
		}
			
		return param; 
	}
	
	// Обработка формы, если та задана
	this.request = function(param) {
		// Данные для POST
		if(param.form) {
			var elem = select_object(param.form);
			
			if(elem) {
				// Сменить адрес
				if(param.url) {
					elem.action = param.url;
				}
				// Метод
				if(param.method) {
					elem.method = param.method;
				}
				// Новые или измененные поля
				if(param.change) {
					this.change_element(param.form, param.change);
				}
				
				elem.submit();
				return true;
			}
		}
		return false;
	}
	
	// Присвоить значения присутсвующим в форме элементам или создать новые поля
	// change_list - массив, который должен прибавиться к форме [имя_поля, значение, ]
	this.change_element = function(uid_form, change_list) {
		var elem_form = select_object(uid_form);
		if(!elem_form)
			return false;
		if(is_array(change_list)) {
			for (var i=0; change_list.length>i; i+=2) {		
				var element_list = elem_form.elements;
				if (element_list[change_list[i]]) {
					element_list[change_list[i]].value = change_list[i+1];
				}
				else {
					var param = {type: "hidden", name:change_list[i], value:change_list[i+1]};
					var input = create_element ("INPUT", param);
					elem_form.appendChild(input);
				}
			}
		}
		return true;
	}
	
	// Проверка заполнения
	// form_name - имя формы, 
	// В форме проверяется все, что содержит атрибут need_check, как название используется атрибут need_check_title
	// имя email Всегда вызывает проверку по типу email
	// Все поля с непустым атрибутом need_clear предварительно очищаются
	this.check = function(form_uid) {
		var err_string="";
		var elem = select_object(form_uid);
		var need_check_title;
		var error;
		
		if(!elem)
			return false;
		
		elem = elem.elements;
				
		for (var i=0; elem.length > i; i++) {
			// Очистка предзаполненого поля
			var need_clear = get_attribute (elem[i], "need_clear");
			if(need_clear) {
				elem[i].value = "";
			}
			var need_check = get_attribute (elem[i], "need_check");
			error = false;
			if(need_check) {
				if(need_check=='email') {
					reg_mail=/[0-9a-z_]+@[0-9a-z_^.]+.[a-z]{2,3}/i;
					if (reg_mail.test(elem[i].value)==false) {
							error = true;
					}
				}
				else {
					if (get_value(elem[i]) == undefined || get_value(elem[i])=="") {// Для текстовых полей и select
						error = true;
					}
				}
				if(error) {
					// Если не была ранее ошибкой - сделать бордер красным
					if(elem[i].need_check_last_border==undefined) {
						elem[i].need_check_last_border = elem[i].style.borderColor;
						elem[i].style.borderColor = "red";
					}
					need_check_title = get_attribute (elem[i], "need_check_title");
					err_string = err_string+"- "+need_check_title+" <br>"; 	
				}	
				else {
					if(elem[i].need_check_last_border!=undefined)
						elem[i].style.borderColor = elem[i].need_check_last_border;
				}
			}
		}
		if (err_string!="") {
			err_string="<div style='padding: 20px;'>Неправильно заполнены следующие поля: <br><br>" + err_string + "</div>";
			dialog("Ошибка заполнения", err_string);
			//alert(err_string);
			return false;
		}
		return true;
	}
	
	// Проверить форму на наличие полей с необходимостью очистки, присвоить им события очистки
	this.compile_form  = function(form_uid) {
		var elem_form = select_object(form_uid);
		if(!elem_form)
			return false;
		
		elem = elem_form.elements;
		
		for (var i=0; elem.length > i; i++) {
			// Очистка предзаполненого поля
			var need_clear = get_attribute (elem[i], "need_clear");
			if(need_clear) {
				$(elem[i]).bind("click",formwork.clear_fc);
			}
		}
		return true;
	}
	
	// Статическая функция очистки поля 
	this.clear_fc = function(event)
	{
		var elem = event.target;
		set_value(this, "");
		$(elem).unbind("click", formwork.clear_fc);
		set_attribute (elem, "need_clear", "");
	}
}
var formwork = new form_class();
// Класс нестандартных элементов
function element_class()
{
	// Замена всех элементов
	this.start = function()
	{
		var list = document.getElementsByTagName('select');
		var i_counter;
		if (list.length) 
		  for(i_counter=0; i_counter<list.length; i_counter++) {
			  if(get_attribute (list[i_counter], 'ns'))
				  this.element_select(list[i_counter]);
		  }
		
		add_event(document, 'click', this.document_click);
	}
	// Клик по документу
	this.document_click = function(e)
	{
		var target = (window.event) ? window.event.srcElement : e.target;
	
		if(document.nsselect_expanded)
		{
			//принадлежит ли соответствующий li списку заменителю select
			if((target.srIndex || target.srIndex === 0) && document.nsselect_expanded == target.parentNode.parentNode	)
				document.nsselect_expanded.srCollapse(target);
			else {
				document.nsselect_expanded.srCollapse();
			}
		}
		else
		{
			if(target.is_ns==true)
				target.parentNode.srExpand();
		}
	}
	
	// Элемент Select
	this.element_select = function(sel)
	{
		//а вдруг мы на осле :)
		var ie6 = (navigator.userAgent.search('MSIE 6.0') != -1);
		
		var div = document.createElement('div');
		//список заменяющий select, свернутый, не в фокусе
		div.className = 'nsselect_list nsselect_collapsed nsselect_blur';
		
		//связь между ul и select
		div.srSelect = sel;
		sel.srReplacement = div;
		
		//устанавливаем для элемента select
		//класс показывающий, что он замещен
		sel.className += ' nsselect_replaced';
		
		//меняем класс элемента ul
		//при получении и потере фокуса
		//элементом select
		sel.onfocus = function() { this.srReplacement.className = this.srReplacement.className.replace(/[\s]?nsselect_blur/, ' nsselect_focus'); }
		
		sel.onblur = function() {
			//this.srReplacement.srCollapse();
			this.srReplacement.className = this.srReplacement.className.replace(/[\s]?nsselect_focus/, ' nsselect_blur');
		}
		
		//каждый браузер болеет по своему
		//поэтому обрабатываем и onchange и onkeypress
		sel.onchange = function()
		{
			var div = this.srReplacement;
			var ul = div.childNodes[1];
			div.srSelectLi(ul.childNodes[this.selectedIndex]);
		}
		
		sel.onkeypress = function(e)
		{
			var i = this.selectedIndex;
			var div = this.srReplacement;
			var ul = div.childNodes[1];
			switch (e.keyCode) {
				case 9:
					this.srReplacement.srCollapse();
				break;
		
				case 37: // влево
				case 38: // вверх
					if (i - 1 >= 0)
						div.srSelectLi(ul.childNodes[i - 1]);
				break;
		
				case 40: // вниз
					if(e.altKey)
					{
						//ul.srExpand();
						//break;
					}
				case 39: // вправо
		
					if (i + 1 < ul.childNodes.length)
						div.srSelectLi(ul.childNodes[i + 1]);
				break;
		
				case 33: // Page Up
				case 36: // Home
					div.srSelectLi(ul.firstChild);
				break;
		
				case 34: // Page Down
				case 35: // End
					div.srSelectLi(ul.lastChild);
				break;
			}
		}
		
		//меняем класс элемента ul
		//при наведении на него мышки
		div.onmouseover = function() { this.className += ' nsselect_hover'; }
		
		div.onmouseout = function() { this.className = this.className.replace(/[\s]?nsselect_hover/, ''); }
		
		div.srSelectLi = function(li)
		{
			var ul = li.parentNode;
			var div = ul.parentNode;
			var span = ul.previousSibling;
		
			//если уже есть выбранный элемент
			//то назначаем снимаем выделение
			if(div.srSelectesIndex != null)
				ul.childNodes[div.srSelectesIndex].className = '';
		
			//запоминаем индекс выбранного элемента
			div.srSelectesIndex = li.srIndex;
		
			//устанавливаем для выбранного элемента
			//класс srSelectedLi
			ul.childNodes[li.srIndex].className = 'srSelectedLi';
			
			// Ставим выбраный элемент в окошко
			span.removeChild(span.firstChild);
			span.appendChild(document.createTextNode(li.innerHTML));
			return li.srIndex;
		}
		
		div.srExpand = function()
		{
			if(!this.nsselect_expanded)
			{
				if(document.nsselect_expanded)
					document.nsselect_expanded.srCollapse();
		
				document.nsselect_expanded = this;
		
				//разворачиваем список
				this.className  = this.className.replace(/[\s]?nsselect_collapsed/, ' nsselect_expanded');
				this.nsselect_expanded = true;
				
				//при раскрытии элемента передаем фокус
				//соответствующему select
				this.srSelect.focus();
		
				//для особо одаренного браузера
				//разворачиваем список особенным способом
			/*	if(ie6) 
				{
					var node = this.firstChild;
					var offset = 0;
					var height = node.clientHeight;
					while(node)
					{
						node.style.position = 'absolute';
						node.style.top = offset;
						offset += height; 
						node = node.nextSibling;
					}
				}*/
			}
		}
		
		div.srCollapse = function(li)
		{	
			if(this.nsselect_expanded)
			{
				document.nsselect_expanded = null;
		
				//выбираем элемент списка на который кликнул пользователь
				//и устанавливаем соответсвующий индекс выбранного элемента
				//для спрятанного элемента select
				if(li) {
					this.srSelect.selectedIndex = this.srSelectLi(li);
					//при клике на элементы списка
					//соответствующий спрятанный select
					//теряет фокус нужно вернуть на место
					this.srSelect.focus();
				}
				
	
		
				//сворачиваем список
				this.className = this.className.replace(/[\s]?nsselect_expanded/, ' nsselect_collapsed');
				this.nsselect_expanded = false;
		
				//для особо одаренного браузера
				//сворачивам список особенным способом
				/*if(ie6)
				{
					var node = this.firstChild;
					while(node)
					{
						node.style.position = '';
						node = node.nextSibling;
					}
				}*/
			}
		}
		
		var ul = document.createElement('ul');
		var options = sel.options;
		var len = options.length;
		
		for(var i = 0; i < len; i++)
		{
			//для каждого элемента option
			//создаем соответствущий li
			var li = document.createElement('li');
			li.appendChild(document.createTextNode(options[i].text));
		
			//в каждом элементе списка
			//храним индекс соответствующего
			//элемента option
			li.srIndex = i;
		
			//псевдо класс hover в IE работает только для ссылок
			//поэтому будем менять класс при наведении мышки
			li.onmouseover = function() { this.className += ' srHoverLi'; }
		
			li.onmouseout = function() { this.className = this.className.replace(/[\s]?srHoverLi/, ''); }
		
			ul.appendChild(li);
		}
		
		//если по умолчанию не выбран никакой элемент
		//выбираем первый
		if(sel.selectedIndex == null)
			sel.selectedIndex = 0;
				
		// Добавляем список и выбраный элемент
		var span = document.createElement('span');
		span.is_ns = true;
		div.appendChild(span);
		div.appendChild(ul);
		
		//устанавливаем элемент выбранный по умолчанию
		span.appendChild(document.createTextNode(sel.options[sel.selectedIndex].text));		
		div.srSelectLi(ul.childNodes[sel.selectedIndex]);
		
		//вставляем созданный список
		//перед заменяемым select
		sel.parentNode.insertBefore(div, sel);
	}
}

var ns_element = new element_class();







// var class_pointer = new Array();

function date_calendar() {

	// field - id поля
	// date - дата
	this.create = function (field, date, show_time) 
	{
		this.field = field;
		this.base_name = 'calendar_'+field;
		//class_pointer[field] = this;
		
		if(show_time)
			this.show_time=true;
		else
			this.show_time=false;
		
		var cur_date = new Date();
		real_date = new Array();
		
		real_date['day'] = cur_date.getDate();
		real_date['month'] = cur_date.getMonth();
		real_date['year'] = cur_date.getFullYear();
		real_date['hour'] = cur_date.getHours();
		real_date['minute'] = cur_date.getMinutes();
		
		this.real_date = real_date;
		
		this.date = this.build_date(date);
	
		elem = select_object(this.base_name);
		var str = '<div class="calendar_widget" id="'+this.base_name+'">';
		str+= '<div style="float: left" id="'+this.base_name+'_month_holder"></select></div>';
		str+= '<div style="float: right" id="'+this.base_name+'_year_holder"></div>';
		str+= '<div style="clear: both"></div>';
		str+= '<table border="0" cellspacing="0" cellpadding="0">';
		str+= '		<tr id="'+this.base_name+'_insert_point">';
		str+= '			<th>Пн</th>';
		str+= '			<th>Вт</th>';
		str+= '			<th>Ср</th>';
		str+= '			<th>Чт</th>';
		str+= '			<th>Пт</th>';
		str+= '			<th>Сб</th>';
		str+= '			<th>Вс</th>';
		str+= ' 	</tr>';
		str+= '</table>';
		str+=  '</div>';
		elem.innerHTML = str;
		
		this.create_month();
		this.create_year();
		
		date = this.date;
		this.rebuild_day(date['day']);
	}
	
	this.build_date = function (date)
	{
		real_date = this.real_date;
		real_date['month'] = real_date['month']+1;
		result_date = new Array();
	
		if(date=="") {
			result_date = real_date;
		}
		else {
			var reg_search = /([\d]+)/g;
			var this_date = new Array();
			var temp_date = new Array();
			
			do {
				temp_date = reg_search.exec(date);
				if(temp_date && temp_date[0])
					this_date[this_date.length] = temp_date[0];
			} while(temp_date!=null);
			var counter =0;
			for(var x in real_date){
				if (this_date[counter]!=undefined)
					result_date[x]=parseInt(this_date[counter], 10);
				else
					result_date[x]=real_date[x];
				counter ++;
			}
		}
		return result_date;
	}
	
	this.create_month = function ()
	{
		var date = [["январь",1], ["февраль",2], ["март",3], ["апрель",4], ["май",5], ["июнь",6], ["июль",7], ["август",8], ["сентябрь",9], ["октябрь",10], ["ноябрь",11], ["декабрь",12]];
		
		var select_date = this.date;
		select_date = select_date['month'];
		
		this.create_select(date, select_date, "month");
	}
	
	this.create_year = function ()
	{
		var date = new Array();
		var year = this.real_date;
		year = year['year'];
		
		var count = 0;
		for(var i=year-10; i<year+10; i++) {
			date[count] = new Array();
			date[count][0]=i;
			date[count][1]=i;
			count++;
		}
		var select_date = this.date;
		select_date = select_date['year'];
		
		this.create_select(date, select_date, "year");
	}
	
	this.create_select = function (date, select_date, select_name)
	{
		var elem_select  = document.createElement('SELECT');
		elem_select.setAttribute ("id", this.base_name+"_"+select_name);
		elem_select.setAttribute ("class", "calendar_widget_"+select_name);
		elem_select.setAttribute ("className", "calendar_widget_"+select_name);
		elem_select.field = this.field;
	
		if(typeof attachEvent != "undefined")
			elem_select.attachEvent("onchange", function (x) { 
						return function() {x.rebuild_day()}
					}(this)       );
		else
			elem_select.addEventListener("change", function (x) { 
				return function() { x.rebuild_day()}
				}(this), false);
		
		for(var i=0; i < date.length; i++){
			elem_inner = document.createElement('OPTION'); 
			elem_inner.setAttribute ("value", date[i][1]);
			if (select_date == date[i][1])
				elem_inner.setAttribute ("selected", "selected");
			
			elem_text = document.createTextNode(date[i][0]); 
			elem_inner.appendChild(elem_text);
			
			elem_select.appendChild(elem_inner);
		}
		
		var holder = select_object(this.base_name+'_'+select_name+'_holder');
		
		holder.appendChild(elem_select);
	}
	// Взять выделение месяца и года из выпадашек
	this.get_selected_date = function ()
	{
		elem_month = select_object(this.base_name+"_month");
		month = elem_month.value;
		elem_year = select_object(this.base_name+"_year");
		year = elem_year.value;
		
		var date = new Array(2);
		date[0] = month;
		date[1] = year;
		
		return date;
	}
	
	this.rebuild_day = function (mark_day) 
	{
		mark_day = mark_day || 0;
		
		date_select = this.get_selected_date();
		var date = new Date(date_select[1], date_select[0], 0); // Месяц в выпадашках с 1, в JS c 0, нулевая дата - последний день прошлого
	
		max_day = date.getDate();
		
		date = new Date(date_select[1], date_select[0]-1, 1);
		var first_day = date.getDay();
	
		first_day = first_day - 1;
		if (first_day < 0)
			first_day = 6;
		
			
		var aMonth = new Array();
		aMonth[0] = new Array(7);
		aMonth[1] = new Array(7);
		aMonth[2] = new Array(7);
		aMonth[3] = new Array(7);
		aMonth[4] = new Array(7);
		aMonth[5] = new Array(7);
		aMonth[6] = new Array(7);
		
	
		
		// Пошли далее
		var counter = 1;
		for (var i = first_day; i < 7; i++) {
			aMonth[1][i] = counter;
			counter++;
		}
		
		for (w = 2; w < 7; w++) {
			for (d = 0; d < 7; d++) {
				if (counter <= max_day) {
					aMonth[w][d] = counter;
						counter++;
		   		}
		 	}
		}
		this.clear_day();
		
		this.draw_day(aMonth, mark_day);
	}
	
	this.clear_day = function () 
	{
		var check_elem = this.base_name+'_insert_point';
	
		elem = select_object(check_elem);
	
		for(i=0; i<6; i++) {
			
			if (elem.nextSibling) {			
				elem.parentNode.removeChild(elem.nextSibling);
			}
		}
	}
	
	this.draw_day = function (day_row, mark_day) 
	{
		elem = select_object(this.base_name+'_insert_point');
		elem_parent = elem.parentNode;
		
		var full_name;
		
		for (w = 1; w < 7; w++) {
			var elem_tr  = document.createElement('TR');
			
			for (d = 0; d < 7; d++) {
				var day = day_row[w][d];
				elem_td  = document.createElement('TD');
				if (day!=undefined) {
					elem_a  = document.createElement('A');
					elem_a.setAttribute ("href", "javascript:void(0)");
					if (day==mark_day) {
						elem_a.setAttribute ("class", "day_select");
						elem_a.setAttribute ("className", "day_select");
					}
					full_name = this.base_name+"_"+day;
					elem_a.setAttribute ("id", full_name);
			
					if(typeof attachEvent != "undefined") 
						elem_a.attachEvent("onclick", function(x) {
									return function () { x.set_date()} 
								}(this) );
					else
						elem_a.addEventListener("click", function (x) {  
									return function (evt) {x.set_date(evt)}
								}(this), false);
					a_text  = document.createTextNode(this.int_to_date(day));	
					elem_a.appendChild(a_text);
						
					elem_td.appendChild(elem_a);
				}
				else {
					a_text  = document.createTextNode("\xA0");	
					elem_td.appendChild(a_text);	
				}
				// Привязать
				elem_tr.appendChild(elem_td);		
			}
			
			elem_parent.appendChild(elem_tr);
		}	
	}
	
	this.set_date = function (even) 
	{
		elem_month = select_object(this.base_name+"_month");
		month = elem_month.value;
		elem_year = select_object(this.base_name+"_year");
		year = elem_year.value;
		
		var elem = select_object(this.field);
		if (window.event)
			even_elem = window.event.srcElement;
		else
			even_elem = even.target;
		if(this.show_time) {
			date = this.date;
			elem.value = even_elem.innerHTML+"-"+this.int_to_date(month)+"-"+this.int_to_date(year)+" "+this.int_to_date(date['hour'])+":"+this.int_to_date(date['month']);
		}
		else	
			elem.value = even_elem.innerHTML+"-"+month+"-"+year;
		
		this.clear_mark();
		this.select_mark(even_elem);
	}
	// Очистить выделение с дней
	this.clear_mark = function ()
	{
		var check_elem = this.base_name+'_insert_point';
	
		var elem = select_object(check_elem);
		elem = elem.nextSibling;
	
		for(i=0; i<6; i++) {
			td_list = elem.childNodes;
			for(var count=0; count < td_list.length; count++) {
	
				var tmp_child = td_list.item(count).childNodes;
				if ( tmp_child.length &&  tmp_child.item(0).nodeType==1) {	
					tmp_child.item(0).className = "";
				}
			}
			elem = elem.nextSibling;
		}
	}
	// Поставить выделение на текущий день
	this.select_mark = function (select_elem)
	{
		select_elem.className = "day_select";
	}
	// Перевести дату в строку, используя подстановку ноля
	this.int_to_date = function(value)
	{
		value = value.toString();
		if(value.length==1) {
			value = "0"+value;
		}
		return value;
	} 
} 








/*
* Скроллинг
*/
function scroll_class() 
{
	this.parametr = new Array();
	this.scroll_area = undefined;
	this.direction = undefined;
	this.delay = 40;
	
	this.init = function (uid, scroll_to, arrow_left, arrow_right) 
	{
		var elem = select_object(uid);
		var elem_holder = elem.parentNode;
		if(!elem || !elem_holder) 
			return false;	
			
		
		this.scroll_area = elem;
		this.parametr['max_width'] = elem_holder.scrollWidth;
		this.parametr['scroll_width'] = elem_holder.clientWidth;
		
		this.parametr['arrow'] = [select_object(arrow_left), select_object(arrow_right)];
		
		var scroll_to_elem = select_object(scroll_to);
		if(scroll_to_elem) {
			var indent_to_center = Math.round((this.parametr['scroll_width']/2) - (scroll_to_elem.clientWidth/2));
			scroll_offset = scroll_to_elem.offsetLeft - indent_to_center;

			if(scroll_offset<0)
				scroll_offset=0;
		}
		else
			scroll_offset = 0;
				
		if(scroll_offset >= (this.parametr['max_width']-this.parametr['scroll_width']) ) {
			scroll_offset = (this.parametr['max_width']-this.parametr['scroll_width']);
			var end = 1;
		}
		
		if(scroll_offset!=0) 
			select_object(arrow_left).style.display = 'block';	
		if(end!=1) 
			select_object(arrow_right).style.display = 'block';
		
		
		this.parametr['scroll_offset'] = scroll_offset;	
		elem.style.marginLeft = '-'+scroll_offset+'px';
		
		elem.style.visibility = 'visible';
	}
	
	this.clear_scroll = function ()
	{
		this.direction=undefined ;
		if(this.timeout)
			clearTimeout(this.timeout);
	}
	
	this.set_scroll = function (direction)
	{
		if(direction!=-1)
			this.direction = direction;
		else {
			if(this.direction==undefined) 
				return false;
		}		
		if(typeof(this.make_scroll) == 'function')
			this.make_scroll(this.scroll_area, this.direction, 4);
		
		if(this.timeout)
			clearTimeout(this.timeout);
		this.timeout = setTimeout("scroll_widget.set_scroll(-1)", this.delay); //! Нужно без прямого указания
	}
	
	this.make_scroll = function(elem, direction, delta)
	{
		if(!elem)
			return false;

		var modifer = 1;
		var end = 0;
		
		var max_scroll = this.parametr['max_width']-this.parametr['scroll_width'];
		
		if(direction == 0) {
			var space = this.parametr['scroll_offset'];
			modifer = -1;
		}
		else  
			var space = max_scroll-this.parametr['scroll_offset'];
			
		if (delta > space) {
			delta = space;
			end = 1; // Пограничное значение
		}

		this.parametr['scroll_offset'] = this.parametr['scroll_offset'] + (delta*modifer);
		elem.style.marginLeft = '-'+ this.parametr['scroll_offset']+'px';
		// Если было достигнуто пограничное состояние, скрыть одну из кнопок прокрутки
		if(end) {
			var arrow =  this.parametr['arrow'][direction];
			if(arrow)
				arrow.style.display = 'none';
		}
		else {
			if(direction==0)
				direction=1;
			else
				direction=0;
			var arrow = this.parametr['arrow'][direction];
			if(arrow.style.display == 'none')
				arrow.style.display = 'block';		
		}
	}
		
	this.wheel_scroll = function (evt)
	{	
		var event = select_event(evt);
		var elem = event.target || event.srcElement;
	
		for(var i=0; i<9; i++) {
			if(elem==this.scroll_area)
				break;	
			else if(!elem || !elem.parentNode)
				return true;
			else if(i!=8)
				elem = elem.parentNode;
			else
				return true;
		}	
		
		
		if (elem && elem.id != 'scroll_area')
			return true;
		
		var delta; // Направление скролла
		// -1 - скролл вниз
		// 1  - скролл вверх	
	
		// Opera и IE работают со свойством wheelDelta
		if (event.wheelDelta) {
			delta = event.wheelDelta / 120;
		    // В Опере значение wheelDelta такое же, но с противоположным знаком
			if (window.opera) 
				delta = -delta;	// В реализации Gecko получим свойство detail
		} 
		else if (event.detail) {
			delta = -event.detail / 3;
		}
		if(delta<0)
			delta = 0;
		else
			delta = 1;
		// Запрещаем обработку события браузером по умолчанию
		if (event.preventDefault)  event.preventDefault();
			event.returnValue = false; 	
				
		this.make_scroll(this.scroll_area, delta, 10);
		
		return false;
	}	
	
	this.external = function(evt)
	{		
		return scroll_widget.wheel_scroll(evt);
	}
}	
var scroll_widget = new scroll_class();






// Класс нестандартных элементов
function element_class()
{
	// Замена всех элементов
	this.start = function()
	{
		var list = document.getElementsByTagName('select');
		var i_counter;
		if (list.length) 
		  for(i_counter=0; i_counter<list.length; i_counter++) {
			  if(get_attribute (list[i_counter], 'ns'))
				  this.element_select(list[i_counter]);
		  }
		
		add_event(document, 'click', this.document_click);
	}
	// Клик по документу
	this.document_click = function(e)
	{
		var target = (window.event) ? window.event.srcElement : e.target;
	
		if(document.nsselect_expanded)
		{
			//принадлежит ли соответствующий li списку заменителю select
			if((target.srIndex || target.srIndex === 0) && document.nsselect_expanded == target.parentNode.parentNode	)
				document.nsselect_expanded.srCollapse(target);
			else {
				document.nsselect_expanded.srCollapse();
			}
		}
		else
		{
			if(target.is_ns==true)
				target.parentNode.srExpand();
		}
	}
	
	// Элемент Select
	this.element_select = function(sel)
	{
		//а вдруг мы на осле :)
		var ie6 = (navigator.userAgent.search('MSIE 6.0') != -1);
		
		var div = document.createElement('div');
		//список заменяющий select, свернутый, не в фокусе
		div.className = 'nsselect_list nsselect_collapsed nsselect_blur';
		
		//связь между ul и select
		div.srSelect = sel;
		sel.srReplacement = div;
		
		//устанавливаем для элемента select
		//класс показывающий, что он замещен
		sel.className += ' nsselect_replaced';
		
		//меняем класс элемента ul
		//при получении и потере фокуса
		//элементом select
		sel.onfocus = function() { this.srReplacement.className = this.srReplacement.className.replace(/[\s]?nsselect_blur/, ' nsselect_focus'); }
		
		sel.onblur = function() {
			//this.srReplacement.srCollapse();
			this.srReplacement.className = this.srReplacement.className.replace(/[\s]?nsselect_focus/, ' nsselect_blur');
		}
		
		//каждый браузер болеет по своему
		//поэтому обрабатываем и onchange и onkeypress
		sel.onchange = function()
		{
			var div = this.srReplacement;
			var ul = div.childNodes[1];
			div.srSelectLi(ul.childNodes[this.selectedIndex]);
		}
		
		sel.onkeypress = function(e)
		{
			var i = this.selectedIndex;
			var div = this.srReplacement;
			var ul = div.childNodes[1];
			switch (e.keyCode) {
				case 9:
					this.srReplacement.srCollapse();
				break;
		
				case 37: // влево
				case 38: // вверх
					if (i - 1 >= 0)
						div.srSelectLi(ul.childNodes[i - 1]);
				break;
		
				case 40: // вниз
					if(e.altKey)
					{
						//ul.srExpand();
						//break;
					}
				case 39: // вправо
		
					if (i + 1 < ul.childNodes.length)
						div.srSelectLi(ul.childNodes[i + 1]);
				break;
		
				case 33: // Page Up
				case 36: // Home
					div.srSelectLi(ul.firstChild);
				break;
		
				case 34: // Page Down
				case 35: // End
					div.srSelectLi(ul.lastChild);
				break;
			}
		}
		
		//меняем класс элемента ul
		//при наведении на него мышки
		div.onmouseover = function() { this.className += ' nsselect_hover'; }
		
		div.onmouseout = function() { this.className = this.className.replace(/[\s]?nsselect_hover/, ''); }
		
		div.srSelectLi = function(li)
		{
			var ul = li.parentNode;
			var div = ul.parentNode;
			var span = ul.previousSibling;
		
			//если уже есть выбранный элемент
			//то назначаем снимаем выделение
			if(div.srSelectesIndex != null)
				ul.childNodes[div.srSelectesIndex].className = '';
		
			//запоминаем индекс выбранного элемента
			div.srSelectesIndex = li.srIndex;
		
			//устанавливаем для выбранного элемента
			//класс srSelectedLi
			ul.childNodes[li.srIndex].className = 'srSelectedLi';
			
			// Ставим выбраный элемент в окошко
			span.removeChild(span.firstChild);
			span.appendChild(document.createTextNode(li.innerHTML));
			return li.srIndex;
		}
		
		div.srExpand = function()
		{
			if(!this.nsselect_expanded)
			{
				if(document.nsselect_expanded)
					document.nsselect_expanded.srCollapse();
		
				document.nsselect_expanded = this;
		
				//разворачиваем список
				this.className  = this.className.replace(/[\s]?nsselect_collapsed/, ' nsselect_expanded');
				this.nsselect_expanded = true;
				
				//при раскрытии элемента передаем фокус
				//соответствующему select
				this.srSelect.focus();
		
				//для особо одаренного браузера
				//разворачиваем список особенным способом
			/*	if(ie6) 
				{
					var node = this.firstChild;
					var offset = 0;
					var height = node.clientHeight;
					while(node)
					{
						node.style.position = 'absolute';
						node.style.top = offset;
						offset += height; 
						node = node.nextSibling;
					}
				}*/
			}
		}
		
		div.srCollapse = function(li)
		{	
			if(this.nsselect_expanded)
			{
				document.nsselect_expanded = null;
		
				//выбираем элемент списка на который кликнул пользователь
				//и устанавливаем соответсвующий индекс выбранного элемента
				//для спрятанного элемента select
				if(li) {
					this.srSelect.selectedIndex = this.srSelectLi(li);
					//при клике на элементы списка
					//соответствующий спрятанный select
					//теряет фокус нужно вернуть на место
					this.srSelect.focus();
				}
				
	
		
				//сворачиваем список
				this.className = this.className.replace(/[\s]?nsselect_expanded/, ' nsselect_collapsed');
				this.nsselect_expanded = false;
		
				//для особо одаренного браузера
				//сворачивам список особенным способом
				/*if(ie6)
				{
					var node = this.firstChild;
					while(node)
					{
						node.style.position = '';
						node = node.nextSibling;
					}
				}*/
			}
		}
		
		var ul = document.createElement('ul');
		var options = sel.options;
		var len = options.length;
		
		for(var i = 0; i < len; i++)
		{
			//для каждого элемента option
			//создаем соответствущий li
			var li = document.createElement('li');
			li.appendChild(document.createTextNode(options[i].text));
		
			//в каждом элементе списка
			//храним индекс соответствующего
			//элемента option
			li.srIndex = i;
		
			//псевдо класс hover в IE работает только для ссылок
			//поэтому будем менять класс при наведении мышки
			li.onmouseover = function() { this.className += ' srHoverLi'; }
		
			li.onmouseout = function() { this.className = this.className.replace(/[\s]?srHoverLi/, ''); }
		
			ul.appendChild(li);
		}
		
		//если по умолчанию не выбран никакой элемент
		//выбираем первый
		if(sel.selectedIndex == null)
			sel.selectedIndex = 0;
				
		// Добавляем список и выбраный элемент
		var span = document.createElement('span');
		span.is_ns = true;
		div.appendChild(span);
		div.appendChild(ul);
		
		//устанавливаем элемент выбранный по умолчанию
		span.appendChild(document.createTextNode(sel.options[sel.selectedIndex].text));		
		div.srSelectLi(ul.childNodes[sel.selectedIndex]);
		
		//вставляем созданный список
		//перед заменяемым select
		sel.parentNode.insertBefore(div, sel);
	}
}

var ns_element = new element_class();







// var class_pointer = new Array();

function date_calendar() {

	// field - id поля
	// date - дата
	this.create = function (field, date, show_time) 
	{
		this.field = field;
		this.base_name = 'calendar_'+field;
		//class_pointer[field] = this;
		
		if(show_time)
			this.show_time=true;
		else
			this.show_time=false;
		
		var cur_date = new Date();
		real_date = new Array();
		
		real_date['day'] = cur_date.getDate();
		real_date['month'] = cur_date.getMonth();
		real_date['year'] = cur_date.getFullYear();
		real_date['hour'] = cur_date.getHours();
		real_date['minute'] = cur_date.getMinutes();
		
		this.real_date = real_date;
		
		this.date = this.build_date(date);
	
		elem = select_object(this.base_name);
		var str = '<div class="calendar_widget" id="'+this.base_name+'">';
		str+= '<div style="float: left" id="'+this.base_name+'_month_holder"></select></div>';
		str+= '<div style="float: right" id="'+this.base_name+'_year_holder"></div>';
		str+= '<div style="clear: both"></div>';
		str+= '<table border="0" cellspacing="0" cellpadding="0">';
		str+= '		<tr id="'+this.base_name+'_insert_point">';
		str+= '			<th>Пн</th>';
		str+= '			<th>Вт</th>';
		str+= '			<th>Ср</th>';
		str+= '			<th>Чт</th>';
		str+= '			<th>Пт</th>';
		str+= '			<th>Сб</th>';
		str+= '			<th>Вс</th>';
		str+= ' 	</tr>';
		str+= '</table>';
		str+=  '</div>';
		elem.innerHTML = str;
		
		this.create_month();
		this.create_year();
		
		date = this.date;
		this.rebuild_day(date['day']);
	}
	
	this.build_date = function (date)
	{
		real_date = this.real_date;
		real_date['month'] = real_date['month']+1;
		result_date = new Array();
	
		if(date=="") {
			result_date = real_date;
		}
		else {
			var reg_search = /([\d]+)/g;
			var this_date = new Array();
			var temp_date = new Array();
			
			do {
				temp_date = reg_search.exec(date);
				if(temp_date && temp_date[0])
					this_date[this_date.length] = temp_date[0];
			} while(temp_date!=null);
			var counter =0;
			for(var x in real_date){
				if (this_date[counter]!=undefined)
					result_date[x]=parseInt(this_date[counter], 10);
				else
					result_date[x]=real_date[x];
				counter ++;
			}
		}
		return result_date;
	}
	
	this.create_month = function ()
	{
		var date = [["январь",1], ["февраль",2], ["март",3], ["апрель",4], ["май",5], ["июнь",6], ["июль",7], ["август",8], ["сентябрь",9], ["октябрь",10], ["ноябрь",11], ["декабрь",12]];
		
		var select_date = this.date;
		select_date = select_date['month'];
		
		this.create_select(date, select_date, "month");
	}
	
	this.create_year = function ()
	{
		var date = new Array();
		var year = this.real_date;
		year = year['year'];
		
		var count = 0;
		for(var i=year-10; i<year+10; i++) {
			date[count] = new Array();
			date[count][0]=i;
			date[count][1]=i;
			count++;
		}
		var select_date = this.date;
		select_date = select_date['year'];
		
		this.create_select(date, select_date, "year");
	}
	
	this.create_select = function (date, select_date, select_name)
	{
		var elem_select  = document.createElement('SELECT');
		elem_select.setAttribute ("id", this.base_name+"_"+select_name);
		elem_select.setAttribute ("class", "calendar_widget_"+select_name);
		elem_select.setAttribute ("className", "calendar_widget_"+select_name);
		elem_select.field = this.field;
	
		if(typeof attachEvent != "undefined")
			elem_select.attachEvent("onchange", function (x) { 
						return function() {x.rebuild_day()}
					}(this)       );
		else
			elem_select.addEventListener("change", function (x) { 
				return function() { x.rebuild_day()}
				}(this), false);
		
		for(var i=0; i < date.length; i++){
			elem_inner = document.createElement('OPTION'); 
			elem_inner.setAttribute ("value", date[i][1]);
			if (select_date == date[i][1])
				elem_inner.setAttribute ("selected", "selected");
			
			elem_text = document.createTextNode(date[i][0]); 
			elem_inner.appendChild(elem_text);
			
			elem_select.appendChild(elem_inner);
		}
		
		var holder = select_object(this.base_name+'_'+select_name+'_holder');
		
		holder.appendChild(elem_select);
	}
	// Взять выделение месяца и года из выпадашек
	this.get_selected_date = function ()
	{
		elem_month = select_object(this.base_name+"_month");
		month = elem_month.value;
		elem_year = select_object(this.base_name+"_year");
		year = elem_year.value;
		
		var date = new Array(2);
		date[0] = month;
		date[1] = year;
		
		return date;
	}
	
	this.rebuild_day = function (mark_day) 
	{
		mark_day = mark_day || 0;
		
		date_select = this.get_selected_date();
		var date = new Date(date_select[1], date_select[0], 0); // Месяц в выпадашках с 1, в JS c 0, нулевая дата - последний день прошлого
	
		max_day = date.getDate();
		
		date = new Date(date_select[1], date_select[0]-1, 1);
		var first_day = date.getDay();
	
		first_day = first_day - 1;
		if (first_day < 0)
			first_day = 6;
		
			
		var aMonth = new Array();
		aMonth[0] = new Array(7);
		aMonth[1] = new Array(7);
		aMonth[2] = new Array(7);
		aMonth[3] = new Array(7);
		aMonth[4] = new Array(7);
		aMonth[5] = new Array(7);
		aMonth[6] = new Array(7);
		
	
		
		// Пошли далее
		var counter = 1;
		for (var i = first_day; i < 7; i++) {
			aMonth[1][i] = counter;
			counter++;
		}
		
		for (w = 2; w < 7; w++) {
			for (d = 0; d < 7; d++) {
				if (counter <= max_day) {
					aMonth[w][d] = counter;
						counter++;
		   		}
		 	}
		}
		this.clear_day();
		
		this.draw_day(aMonth, mark_day);
	}
	
	this.clear_day = function () 
	{
		var check_elem = this.base_name+'_insert_point';
	
		elem = select_object(check_elem);
	
		for(i=0; i<6; i++) {
			
			if (elem.nextSibling) {			
				elem.parentNode.removeChild(elem.nextSibling);
			}
		}
	}
	
	this.draw_day = function (day_row, mark_day) 
	{
		elem = select_object(this.base_name+'_insert_point');
		elem_parent = elem.parentNode;
		
		var full_name;
		
		for (w = 1; w < 7; w++) {
			var elem_tr  = document.createElement('TR');
			
			for (d = 0; d < 7; d++) {
				var day = day_row[w][d];
				elem_td  = document.createElement('TD');
				if (day!=undefined) {
					elem_a  = document.createElement('A');
					elem_a.setAttribute ("href", "javascript:void(0)");
					if (day==mark_day) {
						elem_a.setAttribute ("class", "day_select");
						elem_a.setAttribute ("className", "day_select");
					}
					full_name = this.base_name+"_"+day;
					elem_a.setAttribute ("id", full_name);
			
					if(typeof attachEvent != "undefined") 
						elem_a.attachEvent("onclick", function(x) {
									return function () { x.set_date()} 
								}(this) );
					else
						elem_a.addEventListener("click", function (x) {  
									return function (evt) {x.set_date(evt)}
								}(this), false);
					a_text  = document.createTextNode(this.int_to_date(day));	
					elem_a.appendChild(a_text);
						
					elem_td.appendChild(elem_a);
				}
				else {
					a_text  = document.createTextNode("\xA0");	
					elem_td.appendChild(a_text);	
				}
				// Привязать
				elem_tr.appendChild(elem_td);		
			}
			
			elem_parent.appendChild(elem_tr);
		}	
	}
	
	this.set_date = function (even) 
	{
		elem_month = select_object(this.base_name+"_month");
		month = elem_month.value;
		elem_year = select_object(this.base_name+"_year");
		year = elem_year.value;
		
		var elem = select_object(this.field);
		if (window.event)
			even_elem = window.event.srcElement;
		else
			even_elem = even.target;
		if(this.show_time) {
			date = this.date;
			elem.value = even_elem.innerHTML+"-"+this.int_to_date(month)+"-"+this.int_to_date(year)+" "+this.int_to_date(date['hour'])+":"+this.int_to_date(date['month']);
		}
		else	
			elem.value = even_elem.innerHTML+"-"+month+"-"+year;
		
		this.clear_mark();
		this.select_mark(even_elem);
	}
	// Очистить выделение с дней
	this.clear_mark = function ()
	{
		var check_elem = this.base_name+'_insert_point';
	
		var elem = select_object(check_elem);
		elem = elem.nextSibling;
	
		for(i=0; i<6; i++) {
			td_list = elem.childNodes;
			for(var count=0; count < td_list.length; count++) {
	
				var tmp_child = td_list.item(count).childNodes;
				if ( tmp_child.length &&  tmp_child.item(0).nodeType==1) {	
					tmp_child.item(0).className = "";
				}
			}
			elem = elem.nextSibling;
		}
	}
	// Поставить выделение на текущий день
	this.select_mark = function (select_elem)
	{
		select_elem.className = "day_select";
	}
	// Перевести дату в строку, используя подстановку ноля
	this.int_to_date = function(value)
	{
		value = value.toString();
		if(value.length==1) {
			value = "0"+value;
		}
		return value;
	} 
} 








/*
* Скроллинг
*/
function scroll_class() 
{
	this.parametr = new Array();
	this.scroll_area = undefined;
	this.direction = undefined;
	this.delay = 40;
	
	this.init = function (uid, scroll_to, arrow_left, arrow_right) 
	{
		var elem = select_object(uid);
		var elem_holder = elem.parentNode;
		if(!elem || !elem_holder) 
			return false;	
			
		
		this.scroll_area = elem;
		this.parametr['max_width'] = elem_holder.scrollWidth;
		this.parametr['scroll_width'] = elem_holder.clientWidth;
		
		this.parametr['arrow'] = [select_object(arrow_left), select_object(arrow_right)];
		
		var scroll_to_elem = select_object(scroll_to);
		if(scroll_to_elem) {
			var indent_to_center = Math.round((this.parametr['scroll_width']/2) - (scroll_to_elem.clientWidth/2));
			scroll_offset = scroll_to_elem.offsetLeft - indent_to_center;

			if(scroll_offset<0)
				scroll_offset=0;
		}
		else
			scroll_offset = 0;
				
		if(scroll_offset >= (this.parametr['max_width']-this.parametr['scroll_width']) ) {
			scroll_offset = (this.parametr['max_width']-this.parametr['scroll_width']);
			var end = 1;
		}
		
		if(scroll_offset!=0) 
			select_object(arrow_left).style.display = 'block';	
		if(end!=1) 
			select_object(arrow_right).style.display = 'block';
		
		
		this.parametr['scroll_offset'] = scroll_offset;	
		elem.style.marginLeft = '-'+scroll_offset+'px';
		
		elem.style.visibility = 'visible';
	}
	
	this.clear_scroll = function ()
	{
		this.direction=undefined ;
		if(this.timeout)
			clearTimeout(this.timeout);
	}
	
	this.set_scroll = function (direction)
	{
		if(direction!=-1)
			this.direction = direction;
		else {
			if(this.direction==undefined) 
				return false;
		}		
		if(typeof(this.make_scroll) == 'function')
			this.make_scroll(this.scroll_area, this.direction, 4);
		
		if(this.timeout)
			clearTimeout(this.timeout);
		this.timeout = setTimeout("scroll_widget.set_scroll(-1)", this.delay); //! Нужно без прямого указания
	}
	
	this.make_scroll = function(elem, direction, delta)
	{
		if(!elem)
			return false;

		var modifer = 1;
		var end = 0;
		
		var max_scroll = this.parametr['max_width']-this.parametr['scroll_width'];
		
		if(direction == 0) {
			var space = this.parametr['scroll_offset'];
			modifer = -1;
		}
		else  
			var space = max_scroll-this.parametr['scroll_offset'];
			
		if (delta > space) {
			delta = space;
			end = 1; // Пограничное значение
		}

		this.parametr['scroll_offset'] = this.parametr['scroll_offset'] + (delta*modifer);
		elem.style.marginLeft = '-'+ this.parametr['scroll_offset']+'px';
		// Если было достигнуто пограничное состояние, скрыть одну из кнопок прокрутки
		if(end) {
			var arrow =  this.parametr['arrow'][direction];
			if(arrow)
				arrow.style.display = 'none';
		}
		else {
			if(direction==0)
				direction=1;
			else
				direction=0;
			var arrow = this.parametr['arrow'][direction];
			if(arrow.style.display == 'none')
				arrow.style.display = 'block';		
		}
	}
		
	this.wheel_scroll = function (evt)
	{	
		var event = select_event(evt);
		var elem = event.target || event.srcElement;
	
		for(var i=0; i<9; i++) {
			if(elem==this.scroll_area)
				break;	
			else if(!elem || !elem.parentNode)
				return true;
			else if(i!=8)
				elem = elem.parentNode;
			else
				return true;
		}	
		
		
		if (elem && elem.id != 'scroll_area')
			return true;
		
		var delta; // Направление скролла
		// -1 - скролл вниз
		// 1  - скролл вверх	
	
		// Opera и IE работают со свойством wheelDelta
		if (event.wheelDelta) {
			delta = event.wheelDelta / 120;
		    // В Опере значение wheelDelta такое же, но с противоположным знаком
			if (window.opera) 
				delta = -delta;	// В реализации Gecko получим свойство detail
		} 
		else if (event.detail) {
			delta = -event.detail / 3;
		}
		if(delta<0)
			delta = 0;
		else
			delta = 1;
		// Запрещаем обработку события браузером по умолчанию
		if (event.preventDefault)  event.preventDefault();
			event.returnValue = false; 	
				
		this.make_scroll(this.scroll_area, delta, 10);
		
		return false;
	}	
	
	this.external = function(evt)
	{		
		return scroll_widget.wheel_scroll(evt);
	}
}	
var scroll_widget = new scroll_class();






// Добавить эффект:
// uid - универсальный id
// param - {current: 0, end: 100, type:'alpha', step: 1, special: 'visibility'}
function effect_class() {

this.effect_array = new Array();
this.interval = 10;
this.block = false;
this.timeout_id = undefined;

// Добавить в таблицу объектов новый с привязаным эфффектом
this.add_effect = function (object_uid, param) 
{
    object = select_object(object_uid);
    var num = this.effect_array.length;
    
    // Ищем наличие такого эффекта для этого объекта
    var effect_result = new Array();
    
    var effect_array = this.effect_array;
    var effect_array_length = effect_array.length;
   	// Просеяли эффекты
    for(var i=0; i<effect_array_length;i++) {
        if(object!=effect_array[i]['object'] || param.type!=effect_array[i]['param']['type'])
            effect_result[effect_result.length]=effect_array[i];
    }
    // Внесли новый  
    effect_result[effect_result.length] = this.start_effect(object, param);
    this.effect_array = effect_result;
    
    this.set_interval();
}
// Обработать эффект - сделать старт обработку
this.start_effect = function (object, param)
{
	var new_row = new Array();
    new_row['object'] = object;
    new_row['param'] = param;
	
	this.make_effect(object, param);
    
    return new_row;
}
// Интервал перезапуска эффектов
this.set_interval = function ()
{
    clearTimeout(this.timeout_id);
    this.timeout_id = setTimeout("effect.compile_effect()", this.interval);
}

// Обработать эффект
this.compile_effect = function ()
{
	if (this.block) {
		this.set_interval();
		return false;
	}
	else
		this.block = true; // Залочили
	
    var effect_array = this.effect_array;
    var effect_array_length = effect_array.length;
    
    if (effect_array_length!=0) {
        var effect_array_result= new Array();
        for(var i=0; i<effect_array_length;i++)
        {
            var effect_row = effect_array[i];
            
            effect_row['param']['current'] = (effect_row['param']['current']) + (effect_row['param']['step'] || 1);
     
            if (effect_row['param']['current']>effect_row['param']['end']) {
                effect_row['param']['current'] = effect_row['param']['end'];
            }
            // Применить эффект
            this.make_effect(effect_row['object'], effect_row['param']);
            // Если не закончен, то сохранить в таблице
            if (effect_row['param']['current']<effect_row['param']['end'])
                effect_array_result[effect_array_result.length] =  effect_row;
        }
        if (effect_array_result.length!=0)
            this.set_interval();
    }
    this.effect_array = effect_array_result;
	this.block = false;
}

// 
this.make_effect = function(object, effect_param)
{
    switch(effect_param.type) {
        case "alpha":
                this.effect_set_visibility(object, effect_param.current, effect_param.special);
            break;
        case "size":
                this.effect_set_size(object, effect_param.current, effect_param.special);
            break;
    }
}

// Выставить видимость объекту
this.effect_set_size = function (object, value, special)
{
	special = special || "height";
			
	if (value>100) 
        value = 100;
    else if(value<0) 
        value = 0;
      
	if(object.style.overflow!='hidden')
		object.style.overflow='hidden';
		
	if(value!=0 && object.style.display=='none') {
		object.style.visibility = 'hidden';
		object.style.display = 'block';
		var make_visible = true;
	}
      
    if(special=='height')
     	var cur_value =  object.scrollHeight; 
    else
     	var cur_value =  object.scrollWidth; 
     		
	cur_value = (cur_value/100)*value;
	
	if(special=='height')
    	object.style.height = cur_value+"px";
    else
    	object.style.width = cur_value+"px";
    	
    if(make_visible)
    	object.style.visibility = 'visible';
    if(value==0) {
		object.style.display = 'none';
	}
}

// Выставить видимость объекту
this.effect_set_visibility = function (object, value, special)
{
	special = special || "";
	
    if (value>100) 
        value = 100;
    else if(value<0) 
        value = 0;
       
           
    if (value == 0 && special) {
		if(special=="visibility")
			object.style.visibility = "hidden";
		if(special=="display")	
			object.style.display = "none";
    }
    else if (special) {
		if(special=="visibility") {
			if(object.style.visibility == "hidden")
				object.style.visibility = "visible";
		}
		if(special=="display") {
			if(object.style.display == "none")
				object.style.display = "";
		}
    }
    
    object.style.opacity = value/100; 
    object.style.filter = 'alpha(opacity=' + value + ')';
}

}
var effect = new effect_class();
/**
 * Управление формой
 * Lazy инициализция формы
 */
function FormController(form)
{
	this.jForm = null;
	
	this.isInit = false;
	this.form = form;
	
	/*
	 * Интерфейс
	 */
	
	this.isValid = function()
	{
		this.init();
		
		if(this.jForm == null)
			return false;
		return true;
	};
	
	/**
	 * Получить поле или группу полей, как объект FieldController
	 * Неверное обозначение вернет null
	 */
	this.getField = function(name)
	{
		if(!this.isValid())
			return null;
		
		var jField = $("[name='" + name + "']", this.jForm.get(0));
		if(jField.size() != 0) {
			var fieldObject = new FieldController(jField);
			if(fieldObject.isValid())
				return fieldObject;
		}
		return null;
	};
	
	this.isSetVariable = function(name)
	{
		if(!this.isValid())
			return null;
		
		if(this.getField(name) != null)
			return true;
		else 
			return false;
	};

	/**
	 * Создать поле типа hidden в форме, если поле уже есть - выбрать текущее и поменять его значение на value
	 */
	this.setVariable = function(name, value)
	{
		if(!this.isValid())
			return null;
		
		var fieldObject = this.getField(name);
		if(fieldObject == null) {
			// Создат и внести в форму
			var jField = this.createDomField("input", {name: name, type: 'hidden', value: value} );
			this.jForm.prepend(jField);			
			fieldObject = new FieldController(jField);
		}
		else {
			if(fieldObject.isTextField() && !fieldObject.multiField) {
				fieldObject.setValue(value);
			}
			else {
				fieldObject = null;
			}
		}
		if(fieldObject != null)
			return true;
		return false;
	};
	
	/**
	 * Выставить параметр форме
	 */
	this.setFormAttribute = function(name, paramValue)
	{
		if(!name || !this.isValid())
			return null;
		
		this.jForm.attr(name, paramValue);
	}
	
	/**
	 * Вернуть параметр формы
	 */
	this.getFormAttribute = function(name)
	{
		if(!name || !this.isValid())
			return null;
		
		return this.jForm.attr(name);
	}
	
	/**
	 * Отправить форму
	 */
	this.submit = function()
	{
		if(!this.isValid())
			return null;
		
		this.jForm.submit();
	}
	
	/*
	 * Private
	 */
	
	this.init = function()
	{
		if(this.isInit)
			return;
		
		var jForm = $(this.form);
		if(jForm.size() == 1) {
			this.jForm = jForm.eq(0);
		}
		this.form = null;
		this.isInit = true;
	};
	
	/**
	 * Создать DOM узел
	 */
	this.createDomField = function(tagName, data)
	{
		var jField = $(document.createElement(tagName));
		// Присвоить параметры
		if(data) {
			for (var variable in data) {
				jField.attr(variable, data[variable]);
			}
		}
		return jField;
	};
	
}

/**
 * Управление полем
 * Lazy инициализация поля
 */
function FieldController(field)
{
	this.jField;
	this.multiField;
	this.type;
	
	this.isInit = false;
	this.field = field;
	
	/*
	 * Interface
	 */
	
	this.isValid = function()
	{
		this.init();
		
		if(!this.jField) 
			return false;
		return true;
	};
	
	/**
	 * Очистить поле - различное поведение различных видов полей
	 */
	this.clearValue = function()
	{
		if(!this.isValid()) 
			return;
		
		if(this.type == "RADIO" || this.type == "CHECKBOX") {
			// Убрать все выделения
			this.jField.attr('checked', false);
		}
		else if(this.type == "SELECT") {
			// Сбросить на первый пункт
			this.jField.val('');
		}
		else if(this.type == "OPTION") {
			// Убрать все выделения
			this.jField.attr('selected', false);
		}
		else {
			this.setValueText(this.jField, "");
		}
	};
	
	/**
	 * Выставить значение полю - различное поведение различных видов полей
	 */
	this.setValue = function(value)
	{
		if(!this.isValid()) 
			return;
		
		if(this.type == "RADIO" || this.type == "CHECKBOX") {
			// Выставляем выбранным пунктом - пункт  в переданым значением
			this.setValueChecked(this.jField, value);
		}
		else if(this.type == "SELECT") {
			// Выставляем выбранным пунктом - пункт  в переданым значением
			this.jField.val(value);
		}
		else if(this.type == "OPTION") {
			// Option можно поставить selected только, если это одиночное поле
			if(!this.multiField)
				this.jField.attr('selected', value);
		}
		else {
			this.setValueText(this.jField, value);
		}
	};
	
	/**
	 * Взять значение или массив значений
	 */
	this.getValue = function()
	{
		var value = null;
		if(this.isValid()) {
			if(this.type == "RADIO") {
				// Для RADIO - всегда смотрим на него, как на multiField
				var jChecked = this.getChecked(this.jField);
				if(jChecked != null) {
					value = jChecked.val();
				}
			}
			else {
				// Остальные по принципу - Если мультиполе - то массив значений
				if(this.multiField) {
					value = this.getArrayValue(this.jField);
				}
				else {
					value = this.jField.val();
				}
			}
		}
		return value;
	};
	
	/**
	 * Проверка на подобность
	 * Поле подобно тогда, когда SetValue того же значения не приводит к изменению формы в плане данных
	 */
	this.identityType = function(type, multiField)
	{
		if(multiField != this.multiField) {
			return false;
		}
	};
	
	/**
	 * Проверить что является текстового типа
	 */
	this.isTextField = function()
	{
		if(!this.jField) 
			return false;
		
		if(this.type == "TEXTAREA" || this.type == "TEXT" || this.type == "HIDDEN")		
			return true;
		return false;
	};
	
	/*
	 * Private
	 */ 
	
	this.init = function()
	{
		if(this.isInit)
			return;
		
		this.jField = null;
		this.type = null;
		
		var jField = $(this.field);
		if(jField.size() != 0 ) {
			// Тип определяется первым полем в наборе
			var type = this.getFieldType(jField.eq(0));
			this.type = type;
			
			if(type != null) {
				if(jField.size() > 1)
					this.multiField = true;
				else
					this.multiField = false;
				this.jField = jField;
			}
		}
		
		this.field = null;
		this.isInit = true;
	};
	
	this.setValueChecked = function(jField, value)
	{
		this.setValueAttr(jField, value, "checked");
	};
	
	this.setValueSelected = function(jField, value)
	{
		this.setValueAttr(jField, value, "selected");
	};
		
	/**
	 * Выставить аттрибут элементу из набора со значением value
	 */
	this.setValueAttr = function(jField, value, attr)
	{
		for(var i = 0; i < jField.size(); i++) {
			if(jField.eq(i).val() == value) {
				jField.eq(i).attr(attr, true);
			}
		}
	};
	
	/**
	 * Выставить текстовые значения 
	 */
	this.setValueText = function(jField, value)
	{
		for(var i = 0; i < jField.size(); i++) {
			jField.eq(i).val(value);
		}
	};
	
	/**
	 * Взять значения checked объекта
	 */
	this.getChecked = function(jField)
	{
		for(var i = 0; i < jField.size(); i++) {
			if(jField.eq(i).attr('checked')) {
				return jField.eq(i);
			}
		}
		return null;
	};
	
	/**
	 * Взять массив из значений для списка объектов
	 */
	this.getArrayValue = function(jField)
	{
		var valueArray = new Array();
		for(var i = 0; i < jField.size(); i++) {
			valueArray.push(jField.eq(i).val());
		}
		return valueArray;
	};
	
	this.getFieldType = function(jField)
	{
		var tagName = jField.get(0).tagName.toUpperCase();
		var type = null;
		if(tagName == "INPUT") {
			var typeAttr = $(jField).attr("type").toUpperCase();
			if(typeAttr == "radio") {
				type = "RADIO";
			}
			else if(typeAttr == "checkbox") {
				type = "CHECKBOX";
			}
			else if(typeAttr == "hidden") {
				type = "HIDDEN";
			}
			else if(typeAttr == "button") {
				type = "BUTTON";
			}
			else {
				type = "TEXT";
			}
		}
		else if(tagName == "TEXTAREA") {
			type = "TEXTAREA";
		}
		else if(tagName == "SELECT") {
			type = "SELECT";
		}
		else if(tagName == "OPTION") {
			type = "OPTION";
		}
	
		return type;
	};
		
	/*
	 * Constructor
	 */
}
/**
 * Класс для работы с параметризованной отправкой формы и переадресацией
 */

function DataSend()
{
	this.defaultParams = {};
	
	this.constructor = function()
	{		
		var def = {
			loader: this.defaultLoader,
			target: null
		}
		this.setDefaultParams(def);
	}
	
	/**
	 * Стартер GET запроса
	 */
	this.submit = function(params) 
	{
		if(params != null) {
			return this.request(params);
 		}
		return false;
	}
	
	/**
	 * Выставить список параметров по-умолчанию для запросов
	 */
	this.setDefaultParams = function(params)
	{
		for(var name in params) {
			this.setDefaultParam(name, params[name]);
		}
	}
	
	/**
	 * Выставить одиночный параметр по умолчанию
	 */
	this.setDefaultParam = function(name, value)
	{
		this.defaultParams[name] = value;
	}
	
	/*
	 * Private
	 */
	
	/**
	 * Сформировать запрос
	 */
	this.request = function(params)
	{
		params = mergeObjects(params, this.defaultParams);

		if(params.confirm) {
			var result = confirm(params.confirm);
			if(!result)
				return false;
		}
		var requestObject = new FormRequestObject(params);
		// Проверка условий правильности запроса
		if(requestObject.getForm() == null || requestObject.getURL() == null)
			return false;
		
		this.setRequest(requestObject);
		this.send(requestObject);
		return true;
	}
	
	/**
	 * Поставить запрос в очередь
	 */
	this.setRequest = function(request)
	{
		if(request.getLoader()) {
			var fc = request.getLoader();
			fc(request.getTarget());
		}
	}
	
	this.send = function(requestObject)
	{
		var form = requestObject.getForm();
		var urlParser;
		if(form != null) {
			// Отправка формы
			var data;
			if( (data = requestObject.getData()) != null ) {
				// Дописать поля
				for ( var fieldName in data) {
					form.setVariable(fieldName, data[fieldName]);
				}
			}
			
			if( requestObject.getURL() != null ) {
				// Изменить адрес
				form.setFormAttribute( "action", requestObject.getURL() );
			}
			
			// Отправить форму
			form.submit();
		}
		else {
			// Переадресация без формы
			var url = requestObject.getURL();
			
			if( (data = requestObject.getData()) != null) {
				// Использовать доп данные, как параметры адреса
				urlParser = new URL(url);
				// Дописать поля
				urlParser.addParams(data);
				url = urlParser.getURL();
			}
	
			// Переадресация
			document.location = url;
		}
	}
	
	/**
	 * Загрузчик по-умолчанию, стартует при установке запроса в очередь запросов
	 */
	this.defaultLoader = function(target)
	{
		var progressBar = $("#progressBar");
		if(progressBar.size() == 0) {
			progressBar = $("<div class=\"progressBar\" id=\"progressBar\"></div>");

			var loadedArea = $(target);
			loadedArea.css("position", "relative");
			loadedArea.css("min-height", progressBar.css("height"));
			progressBar.css("width", loadedArea.width()+"px");
			progressBar.css("height", loadedArea.height()+"px");
		
			progressBar.css("position", "absolute");
			progressBar.css("left", "0px");
			progressBar.css("top", "0px");
			loadedArea.append(progressBar);
		}
	}	
	
	this.constructor();
}


/**
 * Класс запроса
 */

function FormRequestObject(params)
{
	this.url = "";
	this.target = null;
	this.data = null;
	this.loader = null;
	this.form = null;
		
	this.constructor = function(params)
	{
		// Проверяем форму
		var form = null;
		if(params.form) {
			form = new FormController(params.form);
			if(form.isValid())
				this.form = form;
		}
	
		// Формируем адрес
		var urlParser = new URL();
		if(this.form) {
			urlParser.parseURL( this.form.getFormAttribute("action"));
			if(params.url) {
				urlParser.addParams(params.url);
			}
		}
		else if(params.url) {
			urlParser.parseURL(params.url);
		}
		this.url = urlParser.getURL();
		
		// Дополнительные поля
		if(this.data) {
			this.data = params.data;
		}
		// Загрузчик
		if(params.loader) {
			this.loader = params.loader;
		}
		// Напрямую переходят параметры
		if(params.target)
			this.target = params.target;
	}
	
	/*
	 * Interface
	 */
		
	this.getURL = function() {
		return this.url;
	}
	
	this.getData = function() {
		return this.data;
	}
	
	this.getForm = function() {
		return this.form;
	}
	
	this.getTarget = function() {
		return this.target;
	}
	
	this.getLoader = function()
	{
		return this.loader;
	}
	
	this.constructor(params);
}

/**
 * Быстрые вызовы
 */

function dataSendSubmit(params)
{
	var ds = new DataSend();
	return ds.submit(params);
}
function Tree(adapter)
{
	this.selectItem = null;
	this.adapter = null;

	this.construct = function(adapter)
	{
		this.setAdapter(adapter);
	};
		
	/**
	* Добавить элемент в список
	* Интерфейс элемента [active(), getData(), equals()]
	*/
	this.addItem = function(treeItem)
	{
		if(treeItem) {
			if(this.getSelect() && treeItem.equals(this.getSelect()) ) {
				this.replaceSelect(treeItem);
			}
			treeItem.addListener(this);
		}
	};
	
	/**
	 * Выставить адаптер к дереву, адаптер определяет активные действия
	 * Интерфейс элемента [update()]
	 */
	this.setAdapter = function(adapter)
	{
		this.adapter = adapter;
	};

	/**
	* Получить уведомление о событии
	*/
	this.notify = function(item, type)
	{
		if(type == "click") {
			if(this.getSelect() != item) {
				this.setSelect(item);
				this.callAdapter(item);
			}
		}
	};
	
	/*
	 * Private
	 */
	
	this.setSelect = function(item)
	{
		if(this.selectItem != null)
			this.selectItem.active(false);
		this.selectItem = item;
	};
	
	/**
	 * Заменить выделение на этот элемент - актулально при постраничной навигации по списку, когда возвращаемся на страницу, где ранее выделен элемент 
	 */
	this.replaceSelect = function(item)
	{
		this.selectItem = item;
		item.active(true);
	};
	
	this.getSelect = function()
	{
		return this.selectItem;
	};
	
	this.callAdapter = function(item)
	{
		if(this.adapter) {
			this.adapter.update(item);
		}
	};
	
	this.construct(adapter);
}




/**
* Адаптер данных к формам полей
*/
function FormAdapter(form)
{		
	this.formObject = null;

	this.construct = function(form)
	{
		this.formObject = new FormController(form);
	};

	/**
	 * Обновить поля формы
	 */
	this.update = function(item) 
	{
		if(item) {
			var data = item.getData();
			if(data) {
				for(var name in data) {
					this.formObject.setVariable(name, data[name]);
				}
			}
		}
	};

	/*
	* Конструктор
	*/
	this.construct(form);
}




/**
* Элемент дерева
*/
function TreeItem(data, idItem, idSubSet, enable)
{
	this.opened = false;
	this.enable = enable || true;
	this.data = null;

	this.idItem = null;
	this.idSet = null;

	

	/**
	*	Связать с HTML объектом, передав указатели на название и область с потомками
	*/
	this.construct = function(idItem, idSubSet, data)
	{
		this.data = data;
		this.idItem = idItem;
		if($(idSubSet).length == 1)
			this.idSubSet = idSubSet;
		this.setEvents();
	};
	
	this.equals = function(item)
	{
		if(item && item.idItem == this.idItem)
			return true;
		
		return false;
	};

	this.setData = function(data)
	{
		this.data = data;
	};

	this.getData = function()
	{
		return this.data;
	};

	this.setEvents = function()
	{
		if(this.idItem != null) {
			$(this.idItem).bind("click", {object: this}, this.clickHandler);
		}
	};

	/**
	* Клик по объекту
	*/
	this.click = function()
	{
		this.active(true);
		if(this.opened) {
			this.close();
		}
		else {
			this.open();
		}
		if(this.enable && this.listener != null) {
			this.listener.notify(this, "click");
		}
	};

	/**
	* Имеет потомков
	*/
	this.hasSubs = function()
	{
		if(this.idSubSet == null) {
			return false;
		}
		return true;
	};

	this.close = function()
	{
		this.opened = false;
		if(this.hasSubs()) {
			$(this.idSubSet).css("display", "none");
		}
	};

	this.open = function()
	{
		this.opened = true;
		if(this.hasSubs()) {
			$(this.idSubSet).css("display", "block");
		}
	};

	/**
	* Выделить или убрать выделение
	*/
	this.active = function(value)
	{
		if(value == true) {
			if(this.enable) {
				$(this.idItem).addClass("selected");
			}
		}
		else {
			$(this.idItem).removeClass("selected");
		}
	};

	/**
	* Выставить объект-слушаетля
	*/
	this.addListener = function(listener)
	{
		this.listener = listener;
	};	

	this.clickHandler = function(event)
	{
		var object = event.data.object;
		object.click();
		return false;
	};

	/**
	* Конструтктор
	*/

	this.construct(idItem, idSubSet, data);
}
/**
 * Базовое окно
 */
function dialog_class(fixed_width, fixed_height, show_loader, position_type)
{
	this.dialog = null;
	this.show_loader = show_loader || false;
	this.width = fixed_width || 0;
	this.height = fixed_height || 0;
	this.position_type = position_type || "center"; // center, right
	this.elements = new Array();
	
	this.timer= null;
	this.interval = 10;
	this.loader = null;
	
	this.offset_x = 0;
	this.offset_y = 0;
	
	this.get_body = function()
	{
		return this.dialog;
	}
	
	this.show = function()
	{
		this.dialog.style.visibility = 'visible'; 
	}
	
	/* 
	 * Включить слежение за размером и положением окна
	 */
	this.actual_position = function()
	{
		this.set_in_place();
		this.set_timer();
		if(this.dialog)
			this.dialog.style.visibility = "visible";
	}
	
	this.set_offset = function(x, y)
	{
		this.offset_x = x;
		this.offset_y = y;
		this.set_in_place();
	}
	
	this.modify_offset = function(x, y)
	{
		this.offset_x += x;
		this.offset_y += y;
		this.set_in_place();
	}
	
	/* 
	 * Поставить наблюдатель за изменениями размера
	 */
	this.set_timer = function ()
	{
	    clearTimeout(this.timer);
	    var fc  = function(x) {
	    	return function(){x.actual_position();}
	    }(this); 
	    this.timer = setTimeout(fc, this.interval);
	}
	
	/*
	 * Очистить таймер
	 */
	this.clear_timer = function()
	{
		if(this.timer != null)
			clearTimeout(this.timer);
	}
	
	/*
	 * Выравнять по центру, для ie 6 эмуляция fixed
	 */
	this.set_in_place = function()
	{
		var elem_container = this.get_body();
		var left, top;
		if(this.position_type == "center") {
			var dialog_width = elem_container.clientWidth;
			var dialog_height = elem_container.clientHeight;
			
			if(dialog_width && dialog_height) {			
				left = (document_size()[0]/2) + document_scroll()[0] - dialog_width/2  + this.offset_x;
				top = (document_size()[1]/2) + document_scroll()[1] - dialog_height/2  + this.offset_y;
				this.move_dialog(left, top);
			}
		}
		else if(this.position_type == "right") {
			left = this.offset_x;
			top = this.offset_y;
			this.move_dialog(left, top);
		}
	}
	
	this.set_elements = function(element_args)
	{
		var element_set = this.elements;
		for(var elem in element_args) {
			element_set[elem] = element_args[elem];
		}
		this.elements = element_set;
	}
	
	this.get_element = function(name)
	{
		var elem = this.elements;
		if(elem[name] != undefined)
			return elem[name];
		else 
			return null;
	}
	
	this.clear_elements = function()
	{
		this.elements = new Array();
	}
	
	/* 
	 * Удалить окно 
	 */
	this.close = function()
	{
		if(this.dialog != null) {
			this.clear_timer ();
			this.dialog.parentNode.removeChild(this.dialog);
			
			this.dialog = null;
			this.offset_x = 0;
			this.offset_y = 0;
			
			this.remove_loader();
		}
	}
	
	/* 
	* Создать базовое окно
	*/
	this.create = function(id)
	{
		this.close();
		var elem_dialog = create_element("div",  {className: 'widget_dialog'}, null);
		this.dialog = elem_dialog;
		
		elem_dialog.style.visibility = "hidden";
		// Если есть фиксированые ширины - ставим
		if(this.width)
			elem_dialog.style.width = this.width;
		if(this.height)
			elem_dialog.style.height = this.height;
			
		// Добавляем в тел
		document.body.insertBefore(elem_dialog, document.body.firstChild);
		this.set_loder();
		
		return elem_dialog;
	}
	
	/* 
	 * Построить заглушку контента
	 */
	this.set_loder = function()
	{
		if(this.show_loader && this.loader == null){
			var loader = create_element("div", {className: 'widget_loader'}, null);
			if(is_ie(6)) {
				loader.style.position = "absolute";
				loader.style.height = document.body.clientHeight;
			}
			$(document.body).prepend(loader);
			this.loader = loader;
		}
	}
	
	/*
	 * Убрать заглушку
	 */
	this.remove_loader = function()
	{
		if(this.loader!=null) {
			document.body.removeChild(this.loader);
			this.loader = null;
		}
	}
	
	this.move_dialog = function(x, y) 
	{
		elem_container = this.get_body();
		if(elem_container) {
			elem_container.style.top = y + "px";
			elem_container.style.left = x + "px";
		}
	}
}

/**
 * Окно с функциями движения, закрытия по клику и базовой структурой
 */
function dialog_float_class(fixed_width, fixed_height, show_loader)
{
	this.base = new dialog_class(fixed_width, fixed_height, false, "right");
	this.actor = null;
	this.timer = null;
	
	this.create = function(actor, content)
	{
		if(this.actor != null && actor == this.actor) {
			if(this.timer)
				clearTimeout(this.timer);
		}
		else {
			if(this.actor != null)
				this.close();
	
			id = "dialog_float";
			var elem_dialog = this.base.create(id);
			
			var photo_container = create_element("div", {className: 'dialog_photo'}, null);
			var elem_container = create_element("div", {className: 'dialog_container'}, photo_container);
			
			// TODO - Класс со списком картинок, передается индекс, происходит выбор
			var image = create_element("img", {src: content}, null);
			photo_container.appendChild(image);
			
			var arg = new Array();
			arg['photo_container'] = photo_container;
			this.set_elements(arg);	
			
			this.set_move_action(actor);
			$(elem_dialog).append(elem_container);
		}
	}
	
	/* 
	 * Поставить наблюдатель за изменениями размера
	 */
	this.set_move_action = function(actor)
	{
		this.actor = actor;
	    this.fc_move  = function(x) {
	    	return function(e){x.make_move(e.pageX, e.pageY);}
	    }(this); 
	    $(document.body).bind("mousemove", this.fc_move);
	    
	    this.fc_suspended_close = function(x) {
	    	return function(){x.suspended_close();}
	    }(this); 
	    $(actor).bind("mouseout", this.fc_suspended_close);
	}
	
	this.make_move = function(x, y)
	{
		this.base.set_offset(x + 10, y + 10);
		this.base.show();
	}
	
	this.suspended_close = function()
	{
		this.fc_close = function(x) {
			return function(){x.close();}
		}(this); 
		this.timer = setTimeout(this.fc_close, 100);
	}
	
	this.set_elements = function(element_args)
	{
		this.base.set_elements(element_args);
	}
	
	this.get_element = function(name)
	{
		return this.base.get_element(name);
	}
	
	this.clear_elements = function()
	{
		this.base.clear_elements();
	}
	
	this.close = function()
	{
		$(document.body).unbind("mousemove", this.fc_move);
		clearTimeout(this.timer);
		$(this.actor).unbind("mouseout", this.fc_suspended_close);
		this.actor = null;
		this.base.close();
	}
}
var dialog_float = new dialog_float_class();

/**
 * Окно с функциями движения, закрытия по клику и базовой структурой
 */
function dialog_extend_class(fixed_width, fixed_height)
{
	this.base = new dialog_class(fixed_width, fixed_height, true);
	
	this.mouse_click_x = 0;
	this.mouse_click_y = 0;
	
	this.create = function(id, title)
	{
		var elem_dialog = this.base.create(id);
		
		var header_buttonset = create_element("div",  {className: 'dialog_buttonset'});
		var elem_title = create_element("div",  {className: 'dialog_title'}, title);
		var elem_header = create_element("div",  {className: 'dialog_header'}, [header_buttonset, elem_title]);
		var elem_body = create_element("div",  {className: 'dialog_body', id: id});
		var elem_container = create_element("div", {className: 'dialog_container'}, [elem_header, elem_body]);
		
		var arg = new Array();
		arg['container'] = elem_container;
		arg['body'] = elem_body;
		arg['header'] = elem_header;
		arg['title'] = elem_title;
		arg['buttonset'] = header_buttonset;
		this.set_elements(arg);
		
		this.set_title(title);
		this.add_button_close();
		this.add_effect_move(elem_header);
		
		$(elem_dialog).append(elem_container);
		this.base.actual_position();
	}
	
	this.set_elements = function(element_args)
	{
		this.base.set_elements(element_args);
	}
	
	this.get_element = function(name)
	{
		return this.base.get_element(name);
	}
	
	this.clear_elements = function()
	{
		this.base.clear_elements();
	}
	
	this.set_title = function(title)
	{
		var title_element = this.get_element('title');
		var title_text_node = create_text_element(title);
		$(title_element).empty();
		$(title_element).append(title_text_node);
	}
	
	/* 
	 * Добавить кнопку закрытия 
	 */
	this.add_button_close = function()
	{
		var buttonset = this.get_element('buttonset')
		if(buttonset != null) {
			var elem_button = create_element("a",  {className: 'button_close', href: 'javascript: void(0)'});
			this.add_effect_close(elem_button);
			$(buttonset).append(elem_button);
		}
	}
	
	/*
	 * Выставить элементу ф-ции перемещения
	 */
	this.add_effect_move = function(elem)
	{
		// При клике таскаем окно 
		var fc = function(x) {
			return function(e) {x.start_drag(e.pageX, e.pageY)}
		}(this);
		$(elem).bind("mousedown", fc);
	}
	
	/*
	 * Эффект закрытия на нажатие элемента
	 */
	this.add_effect_close = function(elem)
	{
		var fc = function(x)
		{
			return function() {x.close()};
		}(this);
		$(elem).bind("click", fc);
	}
	
	
	/*
	 * Поставить статус Drag
	 */
	this.start_drag = function(click_x, click_y)
	{
		if(is_ie(6))
			return;
		this.mouse_click_x = click_x;
		this.mouse_click_y = click_y;
		
		this.fc_move = function(x) {
			return function(e) {x.drag(e.pageX, e.pageY); return true;};
		}(this);
		
		$(document.body).bind("mousemove", this.fc_move);
		$(document.body).bind("mouseup", function(){
			$(document.body).unbind("mousemove", this.fc_move);
		});
	}
	
	/*
	 * Переместить окно
	 */
	this.drag = function(x, y)
	{
		var delta_x = x - this.mouse_click_x;
		var delta_y = y - this.mouse_click_y;
		this.mouse_click_x += delta_x;
		this.mouse_click_y += delta_y;
			
		this.base.modify_offset(delta_x, delta_y);
	}
	
	this.close = function()
	{	
		if(this.dialog) {
			this.clear_elements();
		}
		this.base.close();
	}
}
/**
 * Окно с сообщение EXTENDS dialog_extend_class
 */

function dialog_alert_class(fixed_width, fixed_height)
{	
	this.prototype = new dialog_extend_class(fixed_width, fixed_height, true);
	
	this.create = function(id, title, content)
	{
		title = title || "Ошибка";
		id = id || "dialod_alert"; 
		this.prototype.create(id, title);
		this.set_content(content);
	}
	
	this.set_content = function(content)
	{
		var elem_content = create_element("div",  {className: 'dialog_body'});
		elem_content.innerHTML = content;
		var elem_body = this.prototype.get_element('body');
		$(elem_body).empty();
		$(elem_body).append(elem_content);
	}	
}

var dialog_alert = new dialog_alert_class();

/**
 * Окно для вывода картинок EXTENDS dialog_extend_class
 */
function dialog_image_class(fixed_width, fixed_height)
{	
	this.prototype = new dialog_extend_class(fixed_width, fixed_height);

	this.picture_list = new Array();
	this.index = 0;
	
	/* Элементы окна */
	this.link_left;
	this.link_right;
	this.photo;
	this.text;
	
	/* Настройки */
	this.id = 'dialod_image';
	this.title = 'Галерея';
	
	/*
	 * Показать окно, выбрав один из элементов списка
	 */
	this.show = function(index, id, title)
	{
		id = id || this.id;
		title = title || this.title;
		this.prototype.create(id, title);
		
		this.create_structure();
		this.select_index(index);
		this.fill();
	}
	
	/*
	 * Создать структуру контейнеров, для распределения элементов
	 */
	this.create_structure = function()
	{
		var elem_body = this.prototype.get_element('body');
					
		var link_left = create_element('div', {className: 'item_left'});
		var link_right = create_element('div', {className: 'item_right'});
		var link_container = create_element('div', {className: 'dialog_link'}, [link_left, link_right] );
		
		var photo_container = create_element('div', {className: 'dialog_photo'});
		var fc = function(x) {
			return function() {x.close()};
		}(this);
		$(photo_container).bind("click", fc);
		
		var describe_container = create_element('div', {className: 'dialog_description'});
		
		var arg = new Array();
		arg['link_left'] = link_left;
		arg['link_right'] = link_right;
		arg['photo_container'] = photo_container;
		arg['describe_container'] = describe_container;
		this.prototype.set_elements(arg);
		
		$(elem_body).empty();
		$(elem_body).append(link_container).append(photo_container).append(describe_container);
	}
	
	this.close = function ()
	{
		this.prototype.close();
	}
	
	/*
	 * Добавить список картинок
	 */
	this.add_list = function(img_array)
	{
		if(is_array(img_array)) {
			for(var i=0; i<img_array.length; i++) {
				this.add(img_array[i]);
			}
		}
	}
	
	/*
	 * Добавить элемент в список
	 * {url: ,img_width:, img_height: ,title: }
	 */
	this.showRuntime = function(elem) 
	{
		var saveList = this.picture_list;
		
		this.picture_list = new Array();
		this.add(elem);
		this.show(0);
		
		this.picture_list = saveList;
	}
	
	/*
	 * Добавить элемент в список
	 * {url: ,img_width:, img_height: ,title: }
	 */
	this.add = function(elem) 
	{
		this.picture_list[this.picture_list.length] = elem;
	}
	
	/*
	 * Переместить указатель
	 */
	this.select_index = function(index)
	{
		if(index<0) {
			this.index = 0;
			return true;
		}
		
		var pl = this.picture_list;
		if(index>(pl.length-1)) {
			this.index = pl.length-1;
			return true;
		}
		
		this.index = index;
		return true;
	}
	/*
	 * Сменить индекс и перестроить окно
	 */
	this.change_index = function(index)
	{
		this.select_index(this.index+index);	
		this.fill();
	}
	
	/*
	 * Построить элемент ссылка 
	 */
	this.build_link = function(index) 
	{
		var pl = this.picture_list;
		var new_index = this.index + index;
		if(new_index>=0 && new_index< pl.length) {
			var title="";
			if(index==-1)
				title = "<< Предыдущее фото";
			else
				title = "Следующее фото >>"; // Ниже по списку
			var a = create_element('a', {href:'#'}, title);
			a.onclick = function(x){
				return function(){ x.change_index(index)}
			}(this);
			return a;
		}
		else
			return null;
	}
	
	/*
	 * Выставить элементы в поля
	 */
	this.fill = function()
	{
	
		var record_dom = this.build_select_state();
		
		this.replace_dom(this.prototype.get_element('link_left'), record_dom.link_left);
		this.replace_dom(this.prototype.get_element('link_right'), record_dom.link_right);
		this.replace_dom(this.prototype.get_element('photo_container'), record_dom.photo);
		this.replace_dom(this.prototype.get_element('describe_container'), record_dom.text);
	}
	
	/*
	 * Вставить элемент в контейнер, заменив старый
	 */
	this.replace_dom = function(container, element)
	{
		$(container).empty().append(element);
	}
	
	/*
	 * Получит дом набор текущего элемента списка
	 */
	this.build_select_state = function() 
	{
		return {link_left: this.build_link(-1), link_right: this.build_link(1), photo: this.build_photo(), text: this.build_describe()};
	}
	
	/*
	 * Построить лемент фото
	 */
	this.build_photo = function()
	{
		var pl = this.picture_list;
		var record = pl[this.index];
		if(record != undefined) {
			return create_element('img', {src: record.url, width: record.width, height: record.height});
		}
		else 
			return null;
	}
	
	/*
	 * Построить элемент текст
	 */
	this.build_describe = function()
	{
		var pl = this.picture_list;
		var record = pl[this.index];
		var elem_title;
		if(record!=undefined && record.title != null && record.title != "") {
			elem_title = create_element('div', {className: 'title'}, record.title);
		}
		else
			elem_title = null;
		
		/* temp	 */
		var elem_text;
		if(record!=undefined && record.text != null && record.text != "") {
			elem_text = create_element('div', {style: 'margin-top: 5px'}, record.text);
		}
		else
			elem_text = null;
		
		var container;
		if(elem_title != null || elem_text != null) {
			container = create_element('div', null, [elem_title, elem_text]);
			if(record.max_width) {
				container.style.width = record.max_width + 'px';
			}
		}
		else
			container = null;
	
		return container;
	}
}