/**
 * Набор переключателей. Часто возникает задача переключать что-то между двумя 
 * состояниями. Например: скрыть/показать форму авторизации, свернуть/развернуть
 * выпадающий блок. Иногда в переходе между такими состояниями задействовано много
 * элементов. Например, мы хотим при нажатии на ссылку с иконкой - развернуть под
 * ней что-то, сменив иконку и стиль ссылки. Тут будет задействовано три элемента,
 * изменять состояния которых нужно согласованно. Данный класс позволяет "сцепить"
 * все эти элементы в одно целое и переключать состояния каждого из них вызовом
 * одной функции класса. 
 *
 * Пример использования:
 *		s = new YsSwitches();
 *		s.addDisplaySwitch('el_01');
 *		s.addDisplaySwitch('el_02');
 *		s.addImageSwitch('img_01', './img/1.gif', './img/2.gif'));
 * в HTML коде onclick="s.doSwitch()"
 * В результате выполнения onclick все переключатели будут переключены, т.е.
 * el_01 и el_02 станут невидимыми (или видимыми, если были невидимыми), 
 * а в img_01 установится картика ./img/2.gif.
 *
 * @initialState	Boolean. Опциональный. Флаг "предметного" состояния. 
 *					По умолчанию - выключено. 
 * @onSwitch		Function. Опциональный. Пользовательская функция с одним параметров, 
 *					вызываемая каждый раз при переключении переключателя. В качестве
 *					параметра передается новое состояние "предметного" флага.
 */
function YsSwitches(initialState, onSwitch)
{
	this.m_switches = new Array();
	this.m_state = initialState;
	this.m_onSwitch = onSwitch;
}

/**
 * Добавить переключатель свойства display элемента. 
 * @elem					элемент для переключения его свойства display. 
 * @visibleDisplayValue		Строка. Опциональный. Следует устанавливать только в том
 *							случае, если начальное состояние свойства display элемента 
 *							elemId - none. В этом случае значение этого аргумента укажет
 *							то, на которое нужно переключить значение свойства display
 *							для отображения элемента, например, "inline" или "block". 
 *							По умолчанию - "block". 
 */
YsSwitches.prototype.addDisplaySwitch = function(elem, visibleDisplayValue)
{
	this.addSwitch(new YsDisplaySwitch(elem, visibleDisplayValue));
}

/**
 * Добавить переключатель картинки в элементе img. 
 * @imgElem					Элемент img для переключения в нем картинки. 
 * @secondSource			URL картинки для второго состояния. 
 *							Картинка начинает загружаться сразу после вызова метода. 
 */
YsSwitches.prototype.addImageSwitch = function(imgElem, secondSource)
{
	this.addSwitch(new YsImageSwitch(imgElem, secondSource));
}

/**
 * Переключить все переключатели в противоположное состояние. все элементы
 * @return	Возвращает новое состояние. 
 */
YsSwitches.prototype.doSwitch = function()
{
	for (var i=0; i<this.m_switches.length; ++i)
		this.m_switches[i].doSwitch();
	this.m_state = !this.m_state;
	if (this.m_onSwitch)
		this.m_onSwitch(this.m_state);
	return this.m_state;
}

/**
 * Добавить произвольный переключатель
 * @concreteSwitch	класс с одной функцией - doSwitch
 */
YsSwitches.prototype.addSwitch = function(concreteSwitch)
{
	this.m_switches[this.m_switches.length] = concreteSwitch;
}




/*
 * Переключатель заданного свойства елемента между текущим и другим значением. 
 * @elem				элемент для отображения
 * @propName			имя свойства для переключения, в JS нотации. Пример: borderColor. 
 * @propSecondValue		необходимое после первого переключения значение свойства 
 */
function YsStylePropertySwitch(elem, propName, propSecondValue)
{
	this.m_element = YAHOO.util.Dom.get(elem);
	this.m_propName = propName;
	this.m_propFirstValue = YAHOO.util.Dom.getStyle(this.m_element, this.m_propName);
	this.m_propSecondValue = propSecondValue;
}

YsStylePropertySwitch.prototype.doSwitch = function()
{
	var propValue = YAHOO.util.Dom.getStyle(this.m_element, this.m_propName);
	if (propValue == this.m_propFirstValue) 
		YAHOO.util.Dom.setStyle(this.m_element, this.m_propName, this.m_propSecondValue);
	else 
		YAHOO.util.Dom.setStyle(this.m_element, this.m_propName, this.m_propFirstValue);
}


/*
 * Переключатель видимости элемента. 
 */
function YsDisplaySwitch(elem, visibleDisplayValue)
{
	element = YAHOO.util.Dom.get(elem);
	if (!visibleDisplayValue) visibleDisplayValue = "block";
	var secondDisplayValue = (YAHOO.util.Dom.getStyle(element, "display") == "none") ? 
		visibleDisplayValue : "none";
	YsDisplaySwitch.baseConstructor.call(this, element, "display", secondDisplayValue);
}
ys.extend(YsDisplaySwitch, YsStylePropertySwitch);



/*
 * Переключатель изображения. 
 */
function YsImageSwitch(imgElem, secondSource)
{
	// Предзагрузка для помещения в кеш
	this.m_preloadedImage = new Image();
	this.m_preloadedImage.src = secondSource;
	
	// Остальная инициализация
	this.m_imgElement = YAHOO.util.Dom.get(imgElem);
	this.m_firstSource = this.m_imgElement.src;
	this.m_secondSource = secondSource;
}

YsImageSwitch.prototype.doSwitch = function()
{
	 
	if (this.m_imgElement.src == this.m_firstSource) 
		this.m_imgElement.src = this.m_secondSource;
	else
		this.m_imgElement.src = this.m_firstSource;
}



/*
 * Переключатель класса элемента. При переключении добавляет или удаляет заданный класс. 
 * @elem				элемент для манипуляции
 * @className			имя класса для переключения
 */
function YsClassSwitch(elem, className)
{
	this.m_element = YAHOO.util.Dom.get(elem);
	this.m_className = className;
}

YsClassSwitch.prototype.doSwitch = function()
{
	if (this.m_element.className.lastIndexOf(this.m_className) >= 0)
		this.m_element.className = this.m_element.className.replace(this.m_className, '');
	else
		this.m_element.className += " " + this.m_className;
}
