; (function($)
{

	$.rgsUI = $.rgsUI || {};
	$.fn.extend({
		collapser: function(options, args)
		{
			return this.each(function()
			{
				if (typeof options == "string")
				{
					var calc = $.data(this, "ui-collapser");
					calc[options].apply(calc, args);
				}
				else
				{
					$.data(this, "ui-collapser", new $.rgsUI.collapser(this, options));
				}
			});
		},
		cascadeDropDown: function(options, args)
		{
			return this.each(function()
			{
				if (typeof options == "string")
				{
					var obj = $.data(this, "ui-cascadeDropDown");
					if (obj != null)
					{
						if (args)
						{
							obj[options].apply(obj, args);
						}
						else
						{
							obj[options].apply(obj);
						}
					}
				}
				else
				{
					$.data(this, "ui-cascadeDropDown", new $.rgsUI.cascadeDropDown(this, options));
				}
			});
		},
		refresh: function()
		{
			this.cascadeDropDown("refresh", null);
		}
	});

	$.rgsUI.collapser = function(container, options)
	{
		this.element = container;
		this.options = options = $.extend({}, $.rgsUI.collapser.defaults, options);
		$(this.element).click(this.toggleForm);
	};

	$.rgsUI.collapser.prototype = {
		toggleForm: function()
		{
			var collapser = $.data(this, "ui-collapser");
			$(collapser.options.container).hide();
			var next = $(this).next();
			var display = next.css('display');
			if (display == 'block' || display == '')
			{
				next.hide();
			} else
			{
				next.show();
			}
		}
	};

	$.rgsUI.cascadeDropDown = function(container, options)
	{
		this.element = container;
		this.options = options = $.extend({}, $.rgsUI.cascadeDropDown.defaults, options);
		this.element.thisObj = this;
		$(this.element).bind("change", function(e)
		{
			this.thisObj.refresh();
		});
	};

	$.rgsUI.cascadeDropDown.prototype = {
		refresh: function()
		{
			var selValue = $(this.element).val();
			if ($.isArray(this.options.target))
			{
				for (var i = 0; i < this.options.target.length; i++)
				{
					var target = this.options.target[i];
					if (target.action && target.action == "changeState")
					{
						target.actionHandler();
					}
					else
					{
						var completedSync = true;

						var container = $(target.control);
						target.backupValue = container.val();
						var isVisible = true;
						if (container.css("display") == "none")
						{
							isVisible = false;
						}
						container.disable();
						if (isVisible)
						{
							container.empty();
							if (target.emptyItem)
							{
								container.addOption("", target.promtText, true);
							}
						}
						if (selValue != null && selValue != "")
						{
							var isCall = true;
							if ($.isArray(target.eventValues) && $.inArray(selValue, target.eventValues) == -1)
							{
								isCall = false;
							}
							if (isCall)
							{
								if (target.isAjax)
								{
									var ajaxOptions = target.ajax;
									var requestUrl = target.ajax.servicePath + "?" + target.ajax.paramCallBack(selValue);

									var obj = new successCallback(container, target, selValue.split(";")[0]);
									$.get(requestUrl, function(data) { obj.success(data); });
									completedSync = false;
								}
								else if ($.isFunction(target.loadCallBack))
								{
									target.loadCallBack(target);
									if ($("option", container).length > (target.emptyItem ? 1 : 0))
									{
										container.enable();
									}
									if (target.selected != null && target.selected != "")
									{
										container.val(target.selected);
										target.selected = null;
									}
									else if (target.backupValue != null && target.backupValue != "")
									{
										container.val(target.backupValue);
									}
								}
							}
						}
					}

					if (completedSync)
					{
						// TODO: надо вызывать не обновление, а очистку для случаев isCall = false. Иначе могут быть одновременно вызваны 2 ajax для одного поля.
						// Сейчас это обходится хаком, смотрите ниже.
						if (target.triggerChangeEvent)
						{
							container.change();
						}
						else
						{
							container.refresh();
						}
					}
				}
			}
		}
	};

	successCallback = function(container, options, selValue)
	{
		this.element = container;
		this.options = options;
		this.selValue = selValue;
	};

	successCallback.prototype = {
		success: function(data)
		{
			// Хак, обходяший 2 запроса Ajax, описание смотрите выше.
			this.element.empty();
			if (this.options.emptyItem)
			{
				this.element.addOption("", this.options.promtText, true);
			}

			var list = eval("(" + data + ")")[this.options.ajax.category][this.selValue];
			for (var i = 0, l = list.length, opt; i < l; i++)
			{
				if (list[i] && list[i][0] != "")
				{
					var selected = false;
					if (list[i][2])
					{
						$("option:selected", this.element).selected = false;
						isSelected = selected = true;
					}
					this.element.addOption(list[i][0], list[i][1], selected);
				}
			}
			if ($("option", this.element).length > (this.options.emptyItem ? 1 : 0))
			{
				this.element.enable();
			}

			if (this.options.triggerChangeEvent)
			{
				this.element.change();
			}
			else
			{
				this.element.refresh();
			}
		}
	};


	$.extend($.rgsUI.collapser, { defaults: { container: null} });

	$.extend($.rgsUI.cascadeDropDown, {
		defaults: {
			initSelected: false,
			initValue: "",
			target: []
		}
	});

	$.fn.check = function(mode)
	{
		var mode = mode || 'on';
		return this.each(function()
		{
			switch (mode)
			{
				case 'on':
					this.checked = true;
					break;
				case 'off':
					this.checked = false;
					break;
				case 'toggle':
					this.checked = !this.checked;
					break;
			}
		});
	};

	$.fn.checked = function()
	{
		return this[0].checked;
	};

	$.fn.setChecked = function(isChecked)
	{
		if (isChecked)
		{
			this.attr('checked', 'checked');
		}
		else
		{
			this.removeAttr('checked');
		}
	};

	$.fn.disable = function()
	{
		return this.each(function()
		{
			this.disabled = true;
			$('input, select, textarea', $(this)).disable();
		});
	};

	$.fn.enable = function()
	{
		return this.each(function()
		{
			this.disabled = false;
			$('input, select, textarea', $(this)).enable();
		});
	};

	$.fn.clearOptions = function()
	{
		return this.each(function()
		{
			if (this.options)
			{
				this.options.length = 0;
			}
		});
	};

	$.fn.addOption = function(value, text, selected)
	{
		return this.each(function()
		{
			if ($('option[value=' + value + ']', this).length == 0)
			{
				var option = document.createElement("option");
				option.value = value;
				option.text = text;
				if (selected)
				{
					option.selected = true;
				}

				this[$('option', this).length] = option;
				if (selected)
					$(this).val(value);
			}
		});
	};

	$.fn.addOptions = function(options)
	{
		var hasSelected = false;
		for (var i = 0; i < options.length; ++i)
		{
			hasSelected |= options[i].selected;
		}

		if (!hasSelected)
		{
			options[0].selected = true;
		}

		for (var i = 0; i < options.length; ++i)
		{
			this.addOption(options[i].value, options[i].text, options[i].selected);
		}
	};

	$.fn.setDisabled = function()
	{
		this.attr('disabled', 'disabled');
	};

	$.fn.setEnabled = function()
	{
		this.removeAttr('disabled');
	};

	$.fn.isEnabled = function()
	{
		return this.attr('disabled') == false;
	};

	$.fn.toggleInput = function(state) {
		return this.each(function() {
			if (state) {
				$(this).show().find(':input').removeAttr('disabled');
			} else {
				$(this).hide().find(':input').attr('disabled', 'disabled');
			}
		});
	};
})
(jQuery);
