function Interface() {
	this.oInterface  = false;
	this.addDataType = false;
	this.oForUpdate = false;
	this.TypeUpdate = 'overwrite';
	this.oParam = {};
	this.oForm = false;
	this.uid = 1;
	
	this.lookupTmst = 0;
	this.lookupTimeOut = 800; // при значениях больше 999, пересмотреть корректировку msec в методе GetCurrentMilliseconds();

	// миимум символов, при котором начинаем контекстный подбор
	this.inputLengthLookupStart = 2;
	
	this.LookupAjaxSettings = {};
	this.oAmpluaOptions = false;
	this.oTypeOptions = false;
	this.oGenreOptions = {};
}
/**
*
*	typeUpdate		- тип вставки в HTML-код: 
		overwrite - полностью перезаписываем элемент с id = forUpdateId
		append - добавляем данные в конец элемента с id = forUpdateId
		prepend - добавляем данные в начало элемента с id = forUpdateId
*
*
*	oParam - данные из этого объекта передаются в форму скрытыми полями
*
*
**/
Interface.prototype.Open = function(oLink, interfaceId, forUpdateId, typeUpdate, oParam, uid) {
	this.oInterface = $('#' + interfaceId);
	this.addDataType = interfaceId;
	this.oForUpdate = $('#' + forUpdateId);
	this.TypeUpdate = typeUpdate;
	this.oParam = oParam;
	this.uid = uid;
	
	if(this.uid == 0) {
		ShowAlert('no_login');
		return false;
	}

	this.ResetVisuality();
	// закрываем все открытые интерфейсы, кроме текущего
	$('.interface').not(this.oInterface).fadeOut('slow');
	
	this.Show(oLink, interfaceId);
	this.OpenPanel('panelLookup');
	
	this.Attach();
	
	this.oForm = $('#panelInfo').children('form').get(0);

	return false;
}

// сбрасываем внешний вид
Interface.prototype.ResetVisuality = function() {

	// снимаем подсветку
	/*
	$('li', this.oInterface).each(function(i) {
		this.className = '';
	});
	*/

	// убираем думалку
	$('#inputLookup').removeClass('wait').addClass('pass').val('');

	$('#oLookupNext').hide();
	$('#oResults').html('').hide();

}

Interface.prototype.Show = function(oLink, interfaceId) {
	var position = this.GetPosition(oLink);
	this.oInterface.css('left', position[0] + 'px').css('top', position[1] + 'px').show();
}
Interface.prototype.Hide = function() {
	this.oInterface.hide();
	return false;
}
Interface.prototype.GetPosition = function(obj) {
	return [FindPosX(obj)-400, FindPosY(obj)+20];
}

Interface.prototype.Check = function() {
	var count = 1;
	var sum = 0;

	if (this.addDataType == 'product2person' && !$('#product_id').val()) {
		
		if($('#name').val().length ==0){
			alert('Укажите, Название на русском');
			return false;
		}
		//проверяем заполненность типа
		if ($('#type').val() <= 0) {
			alert('Укажите, пожалуйста, тип добавляемой записи.');
			return false;
		}
		
		//проверяем заполненность жанров
		while($('#genre_id' + count).length) {
			sum += parseInt($('#genre' + count).val());
			++count;		
		}
		if (sum <= 0 && 
			$('#type').val() != 2 && //Студийное шоу 
			$('#type').val() != 3) //Реалити-шоу, они без жанров 
		{
			alert('Укажите, пожалуйста, жанр(ы).');
			return false;
		}
	}
	
	if(this.addDataType == 'person2product' && !$('#person_id').val()){
		if($('#name').val().length ==0){
			alert('Укажите, Имя на русском');
			return false;
		}
	}
	
	//проверяем заполненность амплуа
	count = 1;
	sum = 0;
	while($('#amplua_id' + count).length) {
		sum += parseInt($('#amplua' + count).val());
		++count;		
	}
	if (sum <= 0) {
		alert('Укажите, пожалуйста, амплуа.');
		return false;
	}
	
	this.Send();
}

Interface.prototype.Send = function() {
	
	//Добавим к форме скрытые поля
	//Это данные из обекта oParam
	for (var i = 0 in this.oParam) {
		$('#hidden_' + i).remove();
		$('<input type="hidden" id="hidden_' + i + '" name="' + i + '" value="' + this.oParam[i] + '" />').appendTo(this.oForm);
	}

	//Назначим обработчик на submit формы
	var options = { 
    	success: this.showResponse,
    	timeout: 3000 // тайм-аут
  	};
  	
	$(this.oForm).submit(function() { 
   	    $(this).ajaxSubmit(options); 
        return false;
  	});  
  	$(this.oForm).submit();
  	
  	return false;
}

Interface.prototype.showResponse = function(response, statusText) {
	oInterface.Hide();
	if (oInterface.TypeUpdate == 'append') {
		oInterface.oForUpdate.append(response);
	} else if (oInterface.TypeUpdate == 'prepend') {
		oInterface.oForUpdate.prepend(response);
	}  else {
		oInterface.oForUpdate.html(response);
	}
	
	$(oInterface.oForm).unbind('submit');
}

// назначаем обработчики событий элементам
Interface.prototype.Attach = function() {
	if(this.addDataType == 'person2product' || this.addDataType == 'product2person') {
		$('#inputLookup').keyup(this.Lookup);
	}
}

Interface.prototype.OpenPanel = function(panelId) {
	$.each($('.panel'), function(i, elem) {
		$('#' + elem.id).css("display", elem.id == panelId ? 'block' : 'none');
	});
	return true;
}

// генерит строку из MMSSMsMs для сравнения, indent - отступ от текущего времени в ms
Interface.prototype.GetCurrentMilliseconds = function(indent) {

	var time = new Date();

	var sec = time.getSeconds().toString();
	var msec = time.getMilliseconds().toString();

	if(indent) {
		msec = msec - indent;
		if(msec < 0) {
			msec = 999 + msec;
			sec--;
		}
	}

	sec = sec.length < 2 ? '0' + sec : sec;
	msec = msec.length < 2 ? '0' + msec : msec;
	msec = msec.length < 3 ? '0' + msec : msec;

	var tmst = time.getMinutes() + sec + msec;

	return tmst;
}

// выполняем контекстный подбор
Interface.prototype.Lookup = function() {

	// сохраняем время запроса поиска
	oInterface.lookupTmstSave = oInterface.GetCurrentMilliseconds();

	var iLookup = $('#inputLookup').get(0);

	if(iLookup.value == iLookup.getAttribute('oldvalue'))
		return false;

	iLookup.setAttribute('oldvalue', iLookup.value);

	if(iLookup.value.length <= oInterface.inputLengthLookupStart) {
		$('#oLookupNext').hide('fast');
		$('#oResults').hide('fast');
		return false;;
	}
	
	if(oInterface.addDataType == 'person2product') {
		var script = '/person/lookup/';
	} else if (oInterface.addDataType == 'product2person') {
		var script = '/product/lookup/';
	}
	params = {q: iLookup.value.toLowerCase()};
	oInterface.LookupAjaxSettings = {
		type: 'GET',
		url: script,
		dataType: 'json',
		data: params,
		success: oInterface.ShowLookupResults
	};

	setTimeout(function() {
		if(this.oInterface.LookupAjaxSettings.data && this.oInterface.LookupAjaxSettings.data.q && this.oInterface.LookupAjaxSettings.data.q.length == $('#inputLookup').val().length) {
			this.oInterface.lookupTmst = this.oInterface.GetCurrentMilliseconds(-this.oInterface.lookupTimeOut);
			if(this.oInterface.lookupTmst >= this.oInterface.lookupTmstSave) {
				$('#inputLookup').removeClass('pass').addClass('wait');
				$.ajax(this.oInterface.LookupAjaxSettings);
			}
		}
	}, oInterface.lookupTimeOut);

	return false;

}

// отображаем результаты контекстного поиска
Interface.prototype.ShowLookupResults = function(json) {
	//Убираем думалку
	$('#inputLookup').removeClass('wait').addClass('pass');
	
	var str = '';
	if (json.length > 0) {
		
		$('#oLookupNext').hide();
		for (var i in json) {
			str += '<a href="#" onclick="return oInterface.ClickLookupResult(this)" id="item_' + json[i].id + '">' + json[i].name + '</a><br/>';
		}
		
	} else {
		$('#oLookupNext').show();
		
		if (oInterface.addDataType == 'person2product') {
			//$('#oLookupNext').show();
			str = 'Персоны не найдены.';
		} else if (oInterface.addDataType == 'product2person') {
			str = '<br/>Записи не найдены.';
			//str += '<br/><br/><a href="/product/new/">Добавить фильм (передачу)</a>';
		}
		
	}
	
	$('#oResults').show();
	$('#oResults').html(str);
   	return false;
}

Interface.prototype.ClickLookupResult = function(e) {
	
	var ar = $(e).html().split(/-/);
	var tmp = new Array();
	
	if(ar[1] != undefined)
		 tmp = ar[1].split(/,/);
	
	var object = {};
	object.id = e.id.split(/_/)[1];
	
	if(this.addDataType == 'person2product') {
		object.name = jQuery.trim(ar[0].split(/ /)[0]);
		object.last_name = jQuery.trim(ar[0].split(/ /)[1]);
		object.name_en = jQuery.trim(jQuery.trim(tmp[0]).split(/ /)[0]);
		object.last_name_en = jQuery.trim(jQuery.trim(tmp[0]).split(/ /)[1]);
		object.year = jQuery.trim(tmp[1]);
	} else if (this.addDataType == 'product2person') {
		object.name = jQuery.trim(ar[0]);
		object.name_en = jQuery.trim(tmp[0]);
		object.year = jQuery.trim(tmp[1]);
	}

	oInterface.OpenFormInfo(object);
	return false;
}


Interface.prototype.OpenFormInfo = function(object) {
	
	this.ResetInfoPanel();
	
	this.OpenPanel('panelInfo');

	this.FillInfoFields(object);

	return false;

}

// обнуляем второй экран
Interface.prototype.ResetInfoPanel = function() {

	var aFields = new Array();

	$('#objectInfo > tbody').html('');

	if(this.addDataType == 'person2product') {

		aFields[aFields.length] = {id: 'name_en',		type: 'text', name: 'Имя на английском'};
		aFields[aFields.length] = {id: 'last_name_en',	type: 'text', name: 'Фамилия на английском'};
		aFields[aFields.length] = {id: 'name',			type: 'text', name: 'Имя на русском'};
		aFields[aFields.length] = {id: 'last_name',		type: 'text', name: 'Фамилия на русском'};
		aFields[aFields.length] = {id: 'gender',		type: 'select', name: 'Пол'};
		aFields[aFields.length] = {id: 'year',			type: 'text', name: 'Дата рождения'};

		$('#person_id', this.oForm).val('');

	} else if(this.addDataType == 'product2person') {

		aFields[aFields.length] = {id: 'name_en',		type: 'text', name: 'Название на английском'};
		aFields[aFields.length] = {id: 'name',			type: 'text', name: 'Название на русском'};
		aFields[aFields.length] = {id: 'year',			type: 'text', name: 'Год выпуска'};

		$('#product_id', this.oForm).val('');

	}
	
	this.BuildInfoTable(aFields);
	//this.BuildSelectYear();
	this.BuildSelectGender();

	//if (this.addDataType == 'product2person' && !$('#product_id').val()) {
		this.AddType();
	//}

	this.AddAmplua();
}

// строим строки в таблице с инфой о массиву aFields 
//и вставляем в конец или после tr#idPlace
Interface.prototype.BuildInfoTable = function(aFields, idPlace) {

	var str = '';

	for(var i=0; i < aFields.length; i++) {
		str += '<tr id="line_' + aFields[i].id + '">';
		str += '<td>' + aFields[i].name + '</td>';
		str += '<td class="td_border" id="cell_' + aFields[i].id + '">' + ((aFields[i].type == 'text') ? '<input type="text" id="' + aFields[i].id + '" name="' + aFields[i].id + '" value="">' : '') + '</td>';
		str += '</tr>';
	}

	if(idPlace)
		$('#objectInfo > tbody > tr#' + idPlace).after(str);
	else
		$('#objectInfo').append(str);

	// расставляем правильно закрашенность строчек
	$('#objectInfo > tbody > tr').each(function(i) {
		$(this).removeClass('td_bg').addClass(i%2==0 ? 'td_bg' : '');
	});

}

//строим option для select'a пола
Interface.prototype.BuildSelectGender = function() {

	$('#cell_gender', this.oInterface).html('<select id="gender" name="gender" class="text"></select>');

	if(this.addDataType == 'person2product') {
		$('#gender', this.oInterface).html('<option value="1">Мужской</option><option value="0">Женский</option>');
		$('#gender', this.oInterface).val(1);
	}
	return false;
}

Interface.prototype.FillInfoFields = function(object) {
	if (object) {

		for (var i in object) {
			$('#cell_' + i).html(object[i]);
		}
		
		if(oInterface.addDataType == 'person2product') {
			//Т.к. персона уже есть и пол указыват не нужно
			$('#line_gender').remove();
			
			if ($('#person_id').length == 0) {
				$('<input type="hidden" id="person_id" name="person_id" value="' + object.id + '" />').appendTo(this.oForm);
			} else {
				$('#person_id').val(object.id);
			}
		} else if (oInterface.addDataType == 'product2person') {
			if ($('#product_id').length == 0) {
				$('<input type="hidden" id="product_id" name="product_id" value="' + object.id + '" />').appendTo(this.oForm);
			} else {
				$('#product_id').val(object.id);
			}
		}
		
		if (this.addDataType == 'product2person') {
			$('#line_type').remove();
		}
	} else {
		//Новая запись получаем данные из inputLookup
		var name = '';
		var lastname = '';
		var potfix = '';

		var lookupStr = $('#inputLookup').val().replace(/^\s+/, '').replace(/\s+$/, '').replace(/\s+/, ' ');

		if(lookupStr.match(/\s/) && this.addDataType == 'person2product') {
			name = lookupStr.replace(/^([^ ]+)\s+(.+)$/, '$1');
			lastname = lookupStr.replace(/^([^ ]+)\s+(.+)$/, '$2');
		} else {
			name = lookupStr;
		}

		potfix = lookupStr.match(/[a-z]/i) ? '_en' : '';

		$('#name' + potfix).val(name);
		$('#last_name' + potfix).val(lastname);
	}
	
	if (this.addDataType == 'person2product') {
		$('#line_type').remove();
	}
}

// создаем еще одну строчку с амплуа
Interface.prototype.AddAmplua = function() {

	var ampluaCount = 1;

	// получаем порядковый номер последнего амплуа
	while($('#amplua_id' + ampluaCount).length)
		++ampluaCount;

	var aFields = new Array();
	aFields[0] = {id: 'amplua' + ampluaCount, type: 'select', name: 'Амплуа ' + (ampluaCount != 1 ? ampluaCount : '')};

	this.BuildInfoTable(aFields);

	// наполняем новый tr select'ом
	$('#cell_amplua' + ampluaCount).html('<input type="hidden" id="amplua_id' + ampluaCount + '" value=""><select id="amplua' + ampluaCount + '" name="amplua[' + ampluaCount + ']" class="select_amplua" onchange="oInterface.OnChangeAmplua(this);"></select>');

	this.BuildSelectAmplua($('#amplua' + ampluaCount).get(0));

	$('#amplua' + ampluaCount).val((this.ampluaId && ampluaCount == 1) ? this.ampluaId : '');

	this.OnChangeAmplua($('#amplua' + ampluaCount).get(0));

	return false;
}

// убираем или создаем строку роли для изменившегося амплуа
Interface.prototype.OnChangeAmplua = function(oSelect) {

	if(!oSelect)
		return false;

	var position = oSelect.id.replace('amplua','');
	var aFields = new Array();

	// выбрали актера и строчки роли пока нет? делаем её
	/*
	if(oSelect.value == 63 && $('#role').length == 0) {
		aFields[aFields.length] = {id: 'role', type: 'text', name: 'В этом фильме'};
		oInterface.BuildInfoTable(aFields, 'line_amplua' + position);
		$('#role').val(oInterface.aFieldVal['role']).change(function() {
			oInterface.aFieldVal['role'] = this.value;
		});
	}
	*/

	oInterface.RecalcAccessibleAmplua();

	return false;
}

// строим строки в таблице с инфой о массиву aFields и вставляем в конец или после tr#idPlace
Interface.prototype.BuildSelectAmplua = function(oSelect) {

	if(!oSelect)
		return false;
	
	if (false == oInterface.oAmpluaOptions) {
		$.ajax({
			async:false,
			url: '/interface/amplua/',
			dataType : "json",
			success: function (data, textStatus) {
				oInterface.oAmpluaOptions = data;
			}	    
	    });
	}
	
	// запоминаем выделенный option
	var selectedValue = $(oSelect).val();
	var strOptions = '';

	// строим заново все option
	$.each(oInterface.oAmpluaOptions, function(i, n) {
		strOptions += '<option value="' + i + '">' + n + '</option>';
	});

	// удаляем все option
	$(oSelect).html(strOptions);

	// вспоминаем выделенный option
	$(oSelect).val(selectedValue == '' ? 0 : selectedValue);

	return false;
}

// пересчитываем доступные амплуа для всех селектов
Interface.prototype.RecalcAccessibleAmplua = function() {

	var isNullAmpluaExists = false;
	var isActorSelectExists = false;

	// добавляем все пропущенные option в каждый ampluaX
	var ampluaCount = 1;
	while($('#amplua' + ampluaCount).length) {
//		oInterface.BuildSelectAmplua($('#amplua' + ampluaCount).get(0));
		++ampluaCount;
	}

	ampluaCount = 1;
	while($('#amplua' + ampluaCount).length) {

		oInterface.ampluaIdTemp = $('#amplua' + ampluaCount).val();
		++ampluaCount;

		if(oInterface.ampluaIdTemp == '63' && !isActorSelectExists) {
			isActorSelectExists = true;
		} else if(oInterface.ampluaIdTemp == '0') {
			isNullAmpluaExists = true;
			continue;
		}

		$('option', oInterface.oInterface)
			.not($('option', $('.select_type', oInterface.oInterface)))
			.not($('option', $('.select_genre', oInterface.oInterface)))
			.each(function(i) {
				if(this.value == oInterface.ampluaIdTemp && $(this.parentNode).val() != oInterface.ampluaIdTemp)
					$(this).remove();
			});

	}

	if(!isActorSelectExists)
		$('tr#line_role').remove();

	if(isNullAmpluaExists)
		$('#addAmplua').hide(0);
	else
		$('#addAmplua').show(0);

	return false;
}

Interface.prototype.BuildSelectType = function(oSelect) {

	if(!oSelect)
		return false;
	
	if (false == oInterface.oTypeOptions) {
		$.ajax({
			async:false,
			url: '/interface/type/',
			dataType : "json",
			success: function (data, textStatus) {
				oInterface.oTypeOptions = data;
			}	    
	    });
	}
	
	// запоминаем выделенный option
	var selectedValue = $(oSelect).val();
	var strOptions = '';

	$.each(oInterface.oTypeOptions, function(i, n) {
		strOptions += '<option value="' + i + '">' + n + '</option>';
	});
	$(oSelect).html(strOptions);

	// вспоминаем выделенный option
	$(oSelect).val(selectedValue == '' ? 0 : selectedValue);

	return false;
}

//создаем еще одну строчку с типом фильма
Interface.prototype.AddType = function() {

	var aFields = new Array();
	aFields[0] = {id: 'type', type: 'select', name: 'Тип '};

	this.BuildInfoTable(aFields);

	// наполняем новый tr select'ом
	$('#cell_type').html('<input type="hidden" id="type_id" value=""><select id="type" name="type" class="select_type" onchange="oInterface.OnChangeType(this);"></select>');

	this.BuildSelectType($('#type').get(0));

	return false;
}

Interface.prototype.OnChangeType = function(oSelect) {
	//Удаляем все предыдущие жанры (от прежнего типа)
	var genreCount = 1;
	while($('#genre' + genreCount).length) {
		$('#line_genre' + genreCount).remove();
		++genreCount;
	}
	
	this.AddGenre();
}

//создаем еще одну строчку с жанром фильма
Interface.prototype.AddGenre = function() {

	var genreCount = 1;

	// получаем порядковый номер последнего амплуа
	while($('#genre_id' + genreCount).length)
		++genreCount;

	var aFields = new Array();
	aFields[0] = {id: 'genre' + genreCount, type: 'select', name: 'Жанр ' + (genreCount != 1 ? genreCount : '')};

	//Вычисляем после чего подставлять
	var line_id = (genreCount == 1) ? 'line_type' : 'line_genre' + (genreCount - 1);
	
	this.BuildInfoTable(aFields, String(line_id));

	// наполняем новый tr select'ом
	$('#cell_genre' + genreCount).html('<input type="hidden" id="genre_id' + genreCount + '" value=""><select id="genre' + genreCount + '" name="genre[' + genreCount + ']" class="select_genre" onchange="oInterface.OnChangeGenre(this);"></select>');

	this.BuildSelectGenre($('#genre' + genreCount).get(0), $('#type').val());

	this.OnChangeGenre($('#genre' + genreCount).get(0));

	return false;
}

Interface.prototype.BuildSelectGenre = function(oSelect, type_id) {

	if(!oSelect)
		return false;

	if (undefined == oInterface.oGenreOptions[type_id]) {
		$.ajax({
			async:false,
			url: '/interface/genre/',
			data: {'type_id': type_id},
			dataType : "json",
			success: function (data, textStatus) {
				oInterface.oGenreOptions[type_id] = data;
			}	    
	    });
	}
	
	// запоминаем выделенный option
	var selectedValue = $(oSelect).val();
	var strOptions = '';

	$.each(oInterface.oGenreOptions[type_id], function(i, n) {
		strOptions += '<option value="' + i + '">' + n + '</option>';
	});
	$(oSelect).html(strOptions);

	// вспоминаем выделенный option
	$(oSelect).val(selectedValue == '' ? 0 : selectedValue);

	return false;
}

Interface.prototype.OnChangeGenre = function(oSelect) {
	
	var isNullAmpluaExists = false;

	var genreCount = 1;
	while($('#genre' + genreCount).length) {

		oInterface.genreIdTemp = $('#genre' + genreCount).val();
		++genreCount;

		if(oInterface.genreIdTemp == '0') {
			isNullAmpluaExists = true;
			continue;
		}

		$('option', oInterface.oInterface)
			.not($('option', $('.select_amplua', oInterface.oInterface)))
			.not($('option', $('.select_type', oInterface.oInterface)))
			.each(function(i) {
				if(this.value == oInterface.genreIdTemp && $(this.parentNode).val() != oInterface.genreIdTemp)
					$(this).remove();
			});

	}

	(isNullAmpluaExists) ? $('#addGenre').hide(0) : $('#addGenre').show(0);

	return false;
}

