/**
* Globals in ModSelect namespace.
*/
var ModSelect_self = null;


/**
* ModSelect definition
*/
function ModSelect () {
	ModSelect_self = this;
}

ModSelect.prototype.nocache = false;
ModSelect.prototype.strChoose = '-';
ModSelect.prototype.optgmode = 0;
ModSelect.prototype.existonly = false;
ModSelect.prototype.locale = '';
ModSelect.prototype.queryroot = '/';

ModSelect.prototype.change = 100;
ModSelect.prototype.changeMakes = 104;
ModSelect.prototype.changeModels = 101;
ModSelect.prototype.changeModelPeriods = 102;
ModSelect.prototype.changeBodyTypes = 103;	/*deprecated, renamed to changeBodytypes*/
ModSelect.prototype.changeBodytypes = 103;

ModSelect.prototype.filterBodytype = 'data-bodytype';
ModSelect.prototype.filters = new Array();


/** Deprecated */
ModSelect.prototype.include = function (fname) {}
/** Deprecated */
ModSelect.prototype._populateFrom = function (src, container, item_selector, value_selector, label_selector, param_name) {}


/**
* ModSelect.bind()
* Binds realtions and actions to elements.
*/
ModSelect.prototype.bind = function (src_selector, tar_selector, type, params) {
	$(src_selector).bind('change', function(){
		var parent = this;

		$(tar_selector).each(function(){
			var target = this;
			var query = '';

			switch (type) {
				case ModSelect_self.changeMakes:
					query = 'services/data_json.php?q=makes&existonly=' + ModSelect_self.existonly + '&parent=' + parent.value;
					break;
				case ModSelect_self.changeModels:
					query = 'services/data_json.php?q=models&existonly=' + ModSelect_self.existonly + '&parent=' + parent.value;
					break;
				case ModSelect_self.changeModelPeriods:
					query = 'services/data_json.php?q=modperiods&existonly=' + ModSelect_self.existonly + '&parent=' + parent.value;
					break;
				case ModSelect_self.changeBodytypes:
					query = 'services/data_json.php?q=bodytypes&existonly=' + ModSelect_self.existonly + '&parent=' + parent.value + '&locale=' + ModSelect_self.locale;
					break;
				default:
					break;
			}

			if (query) {
				ModSelect_self._populateFromCache(target, ModSelect_self.queryroot + query, query);
			}
		});
	});
}


/**
* ModSelect.filter()
* Defines elements as filters.
*/
ModSelect.prototype.filter = function (filter_selector, type) {
	var jFilter = $(filter_selector);
	var filter_id = jFilter.attr('id');

	ModSelect_self.filters[filter_id] = type;

	jFilter.change(function(){
		$('[' + type + '-filter="true"]').each(function(){
			ModSelect_self._populateFromCache(this);
		});
	});
}


ModSelect.prototype._applyFilter = function (target, type, filter_el) {
	if (parseInt(filter_el.value)) {
		for (var j=target.options.length; j>0; j--) {
			var i = j-1;
			var this_option = target.options[i];

			var filter_value = filter_el.value;
			var target_filter = this_option.getAttribute(type);

			if (parseInt(target_filter)>0 && filter_value!=target_filter) {
				target.removeChild(this_option);
			}
		}
	}
}


ModSelect.prototype._triggerFilters = function (target) {
	for (var filter_id in ModSelect_self.filters) {
		var type = ModSelect_self.filters[filter_id];

		if (target.getAttribute(type + '-filter')) {
			var filter_el = document.getElementById(filter_id);
			ModSelect.prototype._applyFilter(target, type, filter_el);
		}
	}
}


ModSelect.prototype._populateFromCache = function (target, query, cache_id) {
	try {
		if (parseInt(target.value)>0) {
			target.cachedValue = target.value;
		}
	}catch(e){ModSelect_self._error(e)}

	ModSelect_self._removeChildren(target);


	if (cache_id) {
		target.setAttribute('data-cache-id', cache_id);
	}
	else {
		var cache_id = target.getAttribute('data-cache-id');
	}

	if (cache_id && ModSelect_self._isCached(cache_id)) {
		ModSelect_self._populate(target, ModSelect_self._getCache(cache_id), 0);
		ModSelect_self._triggerFilters(target);
	}
	else {
		$.getJSON(query, function(data){
			if (data.q.status==1){
				ModSelect_self._populate(target, data.q.response, 0);

				if(cache_id) {
					ModSelect_self._setCache(cache_id, data.q.response);
				}

				ModSelect_self._triggerFilters(target);
			}
		});
	}
}


ModSelect.prototype._populate = function (Container, data, level) {
	for (var i in data) {
		var label, value, children, datas;

		value = i;

		try{
			var label = data[i].label;
		}catch(e){ModSelect_self._error(e)}

		try{
			value = data[i].value;
		}catch(e){ModSelect_self._error(e)}

		try{
			var children = data[i].children;
		}catch(e){ModSelect_self._error(e)}

		try{
			var datas = data[i].data;
		}catch(e){ModSelect_self._error(e)}


		try{
			if(this.optgmode==1 && children){
				var Optgroup = document.createElement('optgroup');
				Optgroup.label = label;
				this._populate(Optgroup, children, level+1);
				Container.appendChild(Optgroup);
			}else{
				var Option = document.createElement('option');
				Option.value = value;
				Option.selected = value==Container.cachedValue;
				Option.className = 'level-' + level;
				Container.appendChild(Option);

				if(children){
					label += ' (' + this.strChoose + ')';
					this._populate(Container, children, level+1);
				}

				Option.label = Option.text = label;

				if (datas) {
					for (var att in datas) {
						Option.setAttribute('data-' + att, datas[att]);
						Container.setAttribute('data-' + att + '-filter', true);
					}
				}
			}
		}catch(e){}
	}
}


/**
* ModSelect._removeChildtren()
* Helper function to clear all children of element.
*/
ModSelect.prototype._removeChildren = function (Container) {
	try{
		if (Container.tagName=='SELECT') {
			var thisClone = document.createDocumentFragment();
			var this_options = Container.options;

			if (this_options.length && parseInt(this_options[0].value)==0) {
				thisClone.appendChild(this_options[0]);
			}
			if (this_options.length && this_options[0].getAttribute('data-multiToggler')=='true') {
				thisClone.appendChild(this_options[0]);
			}

			while (Container.firstChild) {
				Container.removeChild(Container.firstChild);
			}

			Container.appendChild(thisClone);
			Container.selectedIndex = 0;
		}
		else {
			while (Container.firstChild) {
				Container.removeChild(Container.firstChild);
			}
		}

	}catch(e){ModSelect_self._error(e)}
}


ModSelect.prototype._error = function (e, force) {
	if (force) {
		//alert(e);
	}
}


ModSelect.prototype._cache = new Array();
ModSelect.prototype._iscached = new Array();
ModSelect.prototype._unsetCache = function (name) {this._cache[name]=null; this._iscached[name]=false;}
ModSelect.prototype._setCache = function (name, value) {if(!this.nocache){this._cache[name] = value; this._iscached[name]=true;}}
ModSelect.prototype._getCache = function (name) {return this._cache[name];}
ModSelect.prototype._isCached = function (name) {return this._iscached[name];}
