﻿// класс формы. Является контейнером для элементов
function Form(formid)
{
	// массив элементов, корректность заполнения которых подлежит проверке
	this.allelements = new Array();

	//массив элементов, заполнение которых неверно
	this.faultelements = new Array();

	// функция добавления элементов в массив проверяемых
	this.addElement = function(element)
	{
		this.allelements.push(element);
	};

	//функция проверки корректности заполнения контролируемых элементов
	this.check = function()
	{
		for (var i = 0; i < this.faultelements.length; i++)
		{
			this.faultelements[i].reset();
		}
		this.faultelements = new Array();
		var rezCorrect = true;
		for (var i = 0; i < this.allelements.length; i++)
		{
			isCorrect = this.allelements[i].check();
			if (isCorrect == false)
			{
				this.faultelements.push(this.allelements[i]);
				rezCorrect = false;
			};
		};
		return rezCorrect;
	};

	//функция выделяет элементы формы, которые заполнены неверно
	this.fault = function(className)
	{
		for (i = 0; i < this.faultelements.length; i++)
		{
			this.faultelements[i].fault(className);
		};
	};
}

function Widget(elementid)
{
	// элемент, идентификатор которого передается в параметр констуктора объекта
	this.element = document.getElementById(elementid);

	this.getValue = function()
	{
		return null;
	};

	// функция сигнализирования об ошибке
	this.fault = function(className)
	{
		if (this.element.className.substring(0, this.element.className.indexOf(' ')) == className)
		{
			this.reset();
		};
		this.element.className = className + ' ' + this.element.className;
	};

	// функция сброса ошибки, установленной предыдущей функцией
	this.reset = function()
	{
		this.element.className = this.element.className.substring(this.element.className.indexOf(' '), this.element.className.length);
	};
};

function trim(instr)
{
	lpos = 0;
	while (instr.charAt(lpos) == ' ')
	{
		lpos = lpos + 1;
	};
	rpos = instr.length;
	while ((instr.charAt(rpos) == ' ') & (rpos > lpos))
	{
		rpos = rpos - 1;
	};
	return instr.substring(lpos, rpos);
};

//класс описания текстового поля
function TextField(elementid)
{
	this.superclass(elementid);

	// поле булевского типа, означает обязательность 
	//заполнения данного текстового элемента
	this.obligatory = true;

	// функция удаления пробелов в начале и конце строки
	this.check = function()
	{
		var elvalue = trim(this.element.value);
		var tmp;
		if ((this.obligatory == true) & (elvalue.length == 0))
		{
			tmp = false;
		}
		else
		{
			tmp = true;
		};
		return tmp;
	};

	// функция проверяет, заполенен текстовый элемент
	this.getValue = function()
	{
		return trim(this.element.value);
	};
};
TextField.prototype.superclass = Widget;

function TextArea(elementid, maxlength)
{
	this.superclass(elementid);
	this.maxlength = maxlength;
	this.obligatory = true;

	this.getValue = function()
	{
		return this.element.value;
	};

	this.check = function()
	{
		if ((trim(this.getValue()).length == 0) & (this.obligatory == true))
		{
			return false;
		};
		if (trim(this.getValue()).length >= this.maxlength)
		{
			return false;
		};
		return true;
	};

	this.fault = function(className)
	{
		if (this.element.className.substring(0, this.element.className.indexOf(' ')) == className)
		{
			this.reset();
		};
		if ((trim(this.getValue()).length == 0) & (this.obligatory == true))
		{
			this.element.className = className + ' ' + this.element.className;
		};
		if (trim(this.getValue()).length >= this.maxlength)
		{
			this.element.className = className + ' ' + this.element.className;
			alert('Введено слишком длинное сообщение!\n      Пожалуйста уменьшите длину');
		};
	};
};
TextArea.prototype.superclass = Widget;


function Selection(elementid)
{
	this.superclass(elementid);
	this.obligatory = true;
	this.unsatisfying = new Array();
	this.addUnsatisfying = function(value)
	{
		this.unsatisfying.push(value);
	};

	this.getValue = function()
	{
		return this.element.options.selectedIndex;
	};

	this.check = function()
	{
		selected_value = this.element.options.selectedIndex;
		isSatisfied = true;
		for (var i = 0; i < this.unsatisfying.length; i++)
		{
			if (this.unsatisfying[i] == selected_value)
			{
				isSatisfied = false;
			};
		};
		if ((this.obligatory == true) & (isSatisfied == false))
		{
			return false;
		}
		else
		{
			return true;
		};
	};
};
Selection.prototype.superclass = Widget;

//класс взаимозаменяющих элементов (необходимо корректно заполнить хотя бы 1 элемент из группы)
function Substitutor()
{
	this.elements = new Array();
	this.addElement = function(element)
	{
		this.elements.push(element);
	};

	this.check = function()
	{
		for (var i = 0; i < this.elements.length; i++)
		{
			if (this.elements[i].check() == true)
			{
				return true;
			};
		};
		return false;
	};

	this.fault = function(className)
	{
		for (var i = 0; i < this.elements.length; i++)
		{
			this.elements[i].fault(className);
		};
	};

	this.reset = function()
	{
		for (var i = 0; i < this.elements.length; i++)
		{
			this.elements[i].reset();
		};
	};
}

// класс описания зависимостей между элементами
//один элемент - master - является главным, другие (один или несколько) - зависимый (slave)
//коректность заполнения зависимого элемента определяется значением главного элемента
function Dependence(master, slave)
{
	this.master = master;	// главный элемент
	this.slaves = slave;	// зависимый элемент

	//пары значений элементов, которые считаются некорректным вводом
	this.incorrectpairs = new Array();
	this.addIncorrectPair = function(master_val, slave_val)
	{
		this.incorrectpairs.push({master_value: master_val, slave_value: slave_val});
	};
	this.check = function()
	{
		for (var i = 0; i < this.incorrectpairs.length; i++)
		{
			if ((this.incorrectpairs[i].slave_value == slave.getValue()) & (this.incorrectpairs[i].master_value == master.getValue()))
			{
				return false;
			};
		};
		return true;
	};
	this.fault = function(className)
	{
		slave.fault(className);
	};
	this.reset = function()
	{
		slave.reset();
	};
};