go.selects = new (function() {

/*** cSelect ***/

this.cSelect = (
	function(select, name)
	{
		this.constrSelect(select, name);
	}
)

var pSelect = {
	"constrSelect": (
		function(select, name)
		{
			var sel = go.$(select);
			this.select = sel;	
			this.scanNormal();
			go.events.add(sel, "change", {"object": this, "method": this.onChange});
			if (!name) {
				name = aiSelects;
				aiSelects++;
			}
			this.name = name;
			if (l_items[name]) {
				this.l_items = l_items[name];
				this.l_full  = l_items[name];
				this.l_ajax  = l_ajax[name];
			} else {				
				this.l_items = l_items[name] = {};
				this.l_full  = l_full[name] = {};
				this.l_ajax  = l_ajax[name] = {};
			}
			return true;
		}
	),
	"value": (
		function() 
		{
			return this.select.value;
		}
	),
	"setValue": (
		function(value) 
		{
			this.select.value = value;
			this.onChange();
			return true;
		}
	),
	"currentOption": (
		function()
		{
			return this.select.getElementsByTagName("OPTION").item(this.select.selectedIndex);
		}
	),
	"load": (
		function(lines, current, add)
		{
			var sel = this.select;
			if (!add) {
				go.dom.clear(sel);
			}
			for (var value in lines) {
				var o = document.createElement("OPTION");
				o.setAttribute("value", value);
				o.appendChild(document.createTextNode(lines[value]));
				sel.appendChild(o);
			}
			if (current !== undefined) {
				sel.value = current;
			}
			if ((current) || (!add)) {
				this.onChange();
			}
			return true;
		}
	),
	"addListener": (
		function(handler)
		{
			if (!this._listener) {
				this._listener = [handler];
			} else {
				this._listener.push(handler);
			}
			return true;
		}
	),	
	"onChange": (
		function()
		{
			this.change();
			this.onChangeList();
			return true;
		}
	),
	"getValues": (
		function(all)
		{
			var options = this.select.getElementsByTagName("OPTION");
			var ret = {};
			var len = options.length;
			for (var i = 0; i < len; i++) {
				var option = options.item(i);
				var value = option.getAttribute("value");
				if ((value > 0) || (all)) {
					ret[value] = option.firstChild.nodeValue;
				}
			}
			return ret;
		}
	),
	"change": go.emptyFunction,
	"onChangeList": (
		function()
		{
			var l = this._listener;
			if (l) {
				var len = l.length;
				var v   = [this.select.value];
				for (var i = 0; i < len; i++) {
					me(l[i], true, v);
				}
			}
			return true;
		}
	),
	"scanNormal": (
		function()
		{
			var options = this.select.getElementsByTagName("OPTION");
			var len = options.length;
			for (var i = 0; i < len; i++) {
				var option = options.item(i);
				if (option.getAttribute("selected")) {
					this.select.value = option.getAttribute("value");
				}
			}
			return true;			
		}
	),
	"disable": (
		function()
		{
			this.select.disabled = true;
			if (!this._hidden) {
				var h = document.createElement("input");
				h.setAttribute("type", "hidden");
				h.setAttribute("value", "0");
				h.setAttribute("name", this.select.getAttribute("name"));
				this.select.parentNode.appendChild(h);				
				this._hidden = h;				
			}
			return true;
		}
	),
	"enable": (
		function() 
		{
			this.select.disabled = false;
			if (this._hidden) {
				this.select.parentNode.removeChild(this._hidden);
				this._hidden = null;
			}
			return true;
		}
	)
};
this.cSelect.prototype = pSelect;

/*** cLink (extends cSELECT) ***/
this.cLink = (
	function(select, parent, name)
	{
		this.constrLink(select, parent, name);
	}
);

function cpLink()
{
	var this_link = this;
	this.constrLink = (
		function(select, parent, name)
		{	
			this.constrSelect(select, name);
			this.parent = parent;
			parent.addListener({"object": this, "method": this.parentChange});
			var val = parent.value();
			this._parentValue = val;	
			if (val > 0) {
				if (!this.l_items[val]) {
					this.l_items[val] = this.getValues();
				}
			}						
		}
	);
	this.parentChange = (
		function(value)
		{
			if (value === undefined) {
				value = this.parent.value();
			}
			if (value <= 0) {
				this.parentNoValue(value);
			} else {
				this.parentValue(value);
			}
			this._parentValue = value;					
			return true;
		}
	);
	this.parentNoValue = (
		function()
		{
			if (this._status == "parent") {
				return true;
			}			
			this.load({0: this._msgParent});
			this.disable();
			return true;
		}
	);
	this.parentValue = (
		function(value)
		{
			this._status == "ok";
			if (value == this._parentValue) {
				return true;
			}
			return this.parentNewValue(value);
		}
	);
	this.parentNewValue = (
		function(value)
		{
			if (this.l_items[value]) {
				this.load({0: this._msgValue0});
				this.load(this.l_items[value], 0, true);
				if (this.l_items[value].length >= 15) {
					this.load({"-2": this._msgFull}, 0, true);
				}
				if (this._dOther) {
					this.load({"-1": this._msgOther}, 0, true);
				}
				this.enable();
				return true;
			}
			this.load({0: this._msgLoaded});
			this.disable();
			var l_ajax = this.l_ajax[value];
			if (l_ajax) {
				l_ajax.push(this);
				return true;
			}
			ajax = go.ajax.getAction("placies");
			this.l_ajax[value] = [this];
			ajax.get     = {"type": this.name, "parent": value};
			ajax.sname   = this.name;
			ajax.value   = value;
			ajax.handler = loaded;
			ajax.send();			
			return true;
		}
	);
	this.loaded = (
		function(ajax, value, data)
		{
			if (this._parentValue != value) {
				return true;
			}
			this.load({0: this._msgValue0});
			this.load(data, undefined, true);			
			this.load({"-2": this._msgFull}, undefined, true);			
			if (this._dOther) {
				this.load({"-1": this._msgOther}, undefined, true);
			}			
			this.enable();
			return true;
		}
	);
	this.change = (
		function()
		{
			if (this.select.value == -1) {
				if (this._dOther) {
					this._dOther.style.display = "";
				}
				return true;
			}
			if (this._dOther) {
				this._dOther.style.display = "none";
				this._dOther.value = "";
			}
			if (this.select.value == -2) {
				if (this.l_full[this._parentValue]) {
					this.load(this.l_full[this._parentValue], 0);							
				} else {
					this.disable();
					this.load({0: "- Загружаю... -"});
					var a = new go.ajax.getAction("placies");
					a.get = {"type": this.name, "full": 1, "parent": this._parentValue};
					a.select  = this;
					a.parent  = this._parentValue;
					a.handler = fullLoaded;
					a.send();
				}			
			}			
			return true;
		}
	),	
	this._status = "ok"; // "parent", "loaded"
	this._msgParent = "- Выберите родителя - ";
	this._msgValue0 = "- Выберите значение - ";
	this._msgLoaded = "- Загружаю... - ";
	this._msgOther  = "- Другой -";
	this._msgFull   = "- Полный список -";
	this._type = null;
	this._dOther    = true;
}

go.inherit(pSelect, cpLink, this.cLink);

/*** PRIVATE: ***/
function loaded()
{
	var l = l_ajax[this.sname][this.value];
	if (!l) {
		return false;
	}
	var len = l.length;
	var data = ajax.JSON();
	l_items[this.sname][this.value] = data;
	for (var i = 0; i < len; i++) {
		l[i].loaded(this, this.value, data);
	}
	return true;
}
function fullLoaded()
{
	var l = this.JSON();
	this.select.l_full[this.parent] = l;
	if (this.select._parentValue == this.parent) {
		this.select.load({"0": this.select._msgValue0});
		this.select.load(l, undefined, true);
		if (this.select._dOther) {
			this.select.load({"-1": this.select._msgOther}, undefined, true);
		}
	}
	this.select.enable();
	return true;
}
var this_lib = this;
var me = go.methodExec;
var aiSelects = 0;
var l_items = {};
var l_ajax  = {};
var l_full  = {};
})();