
//-----------------------------------------------------------------------------

Events = {
	add : function (el, evname, func) {
	    if (el.attachEvent) { // IE  
	        el.attachEvent("on" + evname, func); 
	    } else if (el.addEventListener) { // Gecko / W3C  
	        el.addEventListener(evname, func, true);
	    } else { el["on" + evname] = func; }
	}	
}

//-----------------------------------------------------------------------------

var CSRecordChanged = 2;
var CSMasterRecordChanged = 4;
var CSDisabled = 10;
var CSEnabled = 15;

//-----------------------------------------------------------------------------
/*
Linked Select's - data format
key, title = required
hint - 
class = option class
new Array (
	{
		key: key1,
		value : new Array (
			{key: key111, title: "some title1" },
			....
		),
		key: key2,
		value : new Array (
			{key: key222, title: "some title2", 
			...
		),
		...
	}
);
CSelect (select, data, cont) -
select - html select reference
data -
cont - container to display hints
*/
function CSelect (select, data, cont) {
	if (select && data) {
		this.select = select;
		this.select.obj = this;
		if (cont != null) this.cont = cont;
		this.data = data;
		this.childs = new Array ();
		this.curr = -1;
		this.handlers = new Array ();
	}
}

CSelect.prototype = {	
	/*
		dispatcher
		handlers[somemessage] = somehandler;
	*/
	notify : function (msg, param) {
		for (var i in this.handlers) {
			if (i == msg) {	
				this.handlers[i] (this, msg, param);
			}
		}
	},
	
	notifyChilds : function (msg, param) {
		for (var i = 0; i < this.childs.length; i++) {
			this.childs[i].notify (msg, param);	
		}
	},

	ntfRecordChanged : function (obj, msg, param) {
		for (var i=0; i < obj.childs.length; i++) {
			obj.childs[i].notify (CSMasterRecordChanged, obj.getActiveRecord().key);				
		}
		obj.hint (obj);
	},
	
	ntfMasterRecordChanged : function (obj, msg, param) {
		obj.setMasterRecord (param);
		obj.notify (CSRecordChanged);
	},
	
	ntfDisabled: function (obj, msg, param) {
		obj.setEnabled (false);		
		obj.notifyChilds (msg, param);
		obj.hint (obj);
	},
	
	ntfEnabled: function (obj, msg, param) {
		obj.setEnabled (true);		
		this.notifyChilds (msg, param);
		obj.hint (obj);
	},
	
	setMasterRecord : function (id) {
		var result = false;
		for (var i=0; i < this.data.length; i++) {
			if (this.data[i].key == id) {
				this.setSelectContent (this.data[i], i);
				result = true;
			}	
		}
		if (!result || this.locked) this.notify (CSDisabled);
		else {
			this.setEnabled (true);
		}
		return result;
	},
	
	setMaster : function (master) {
		master.addChild (this);
		this.setMasterRecord (master.getActiveRecord().key);
	},
	
	addChild : function (child) {
		this.childs[this.childs.length] = child;
	},
	
	setSelectContent : function (data, index) {
		this.select.options.length = 0;
		this.curr = index;
		for (var i=0; i < data.value.length; i++) {
			var option = new Option (data.value[i].title, data.value[i].key);
			if (data.value[i].className) option.className = data.value[i].className;
			this.select.options[this.select.options.length] = option;
		}
	},
	
	init : function () {	
		this.handlers[CSRecordChanged] = this.ntfRecordChanged;
		this.handlers[CSMasterRecordChanged] = this.ntfMasterRecordChanged;
		this.handlers[CSDisabled] = this.ntfDisabled;
		this.handlers[CSEnabled] = this.ntfEnabled;
		if (this.data && this.data.length) this.setSelectContent (this.data[0], 0);
		Events.add (this.select, 'change', this.createChangeEvent (this.select));
	},
	
	createChangeEvent : function (select) {
		return function () {
			select.obj.notify (CSRecordChanged);
		};
	},
	
	getActiveRecord: function () {
		var result = {key: null, title: ''};
		if (this.data) {
			var data = this.data[this.curr].value;
			var currkey = this.select.options[this.select.selectedIndex].value;
			if (data.length) {
				for (var i in data) {
					if (data[i].key == currkey) {
						result = data[i];
					}
				}
			}
		}
		return result;
	},
	
	isEnabled : function () {
		return this.select.parentNode.style.visibility != 'hidden';	
	},
	
	setEnabled : function (state) {
		if (state) {
			this.select.parentNode.style.visibility = 'visible';
		} else {
			this.select.parentNode.style.visibility = 'hidden';
		}
	}, 
	
	hint : function (obj) {
		if (obj.cont && obj.getActiveRecord().hint) {
			if (obj.isEnabled()) {
				obj.cont.innerHTML = obj.getActiveRecord().hint;				
			} else {
				obj.cont.innerHTML = '';
			}
		}	
	}
	
}
