var ecsSkuSelector = {
	/* all SKUs */
	skus: {},

	/* all Attrs */
	attrs: {},

	/* all <selects /> */
	selectors: {},

	/* current filter */
	currentFilter: {},

	/* last filter results */
	filteredSkus: null,
	filteredAttributes: null,

	/* callbacks */
	callback: null,

	addSku: function(id, attributes) {
		this.skus[id] = attributes;
		this.skus[id].id = id;
	},


	filter: function(conds) {
		var skus = [];
		var valid;
		var validAttr;
		var activeAttrs = {};
		
		/* remove cascade filters */
		var lastAttribute = '';
		if (conds) {
			var startDeleting = 0;
			for (var attr in this.selectors) {
				if (typeof(conds[attr])!='undefined' && startDeleting < this.selectors[attr].cascadeIndex) {
					startDeleting = this.selectors[attr].cascadeIndex;
					lastAttribute = attr;
					
				}
			}
			for (var attr in this.selectors) {
				if (startDeleting < this.selectors[attr].cascadeIndex && this.selectors[attr].applySkuFilter) {
					this.currentFilter[attr] = null;
					this.selectors[attr].truncate();
				}
			}
		}

		/* conds is actually a condition CHANGE for the attributes in conds */		
		for (var attr in conds) {this.currentFilter[attr] = conds[attr];}
		
		/* pupulates skus that match conds and activeAttrs - attributes to display in selectors */
		for(var skuId in this.skus) {
			valid = true;


			/*
			 * validate SKU if has necessary attributes from filter
			 */
			for (var attr in this.currentFilter) {
				if (!this.currentFilter[attr]) continue;
				if (!this.selectors[attr].comparator(this.skus[skuId][attr], this.currentFilter[attr])) {
					valid = false; break;
				}
			}

			
			var validAttr = valid;

/*
			// dont understand this old piece of code
			//
			if (!valid) for (var attr in this.currentFilter) {
				if (console) console.log(attr);
				if (attr == lastAttribute) break;
				if (this.selectors[attr].comparator(this.skus[skuId][attr], this.currentFilter[attr])) {
					validAttr = false; break;
				}
			}
*/

			if (valid) skus.push(this.skus[skuId]);

			/*
			 * Add all attributes from valid SKU as allowed attributes
			 */
			for (var attr in this.attrs) {
				if (!activeAttrs[attr]) activeAttrs[attr] = {};
				
				if (validAttr || !this.selectors[attr].applySkuFilter) {
					if (typeof(this.skus[skuId][attr])=='object') {
						for(var i = 0; i<this.skus[skuId][attr].length; i++) {
							activeAttrs[attr][this.skus[skuId][attr][i]] = this.skus[skuId][attr][i];
						}
					} else {
						activeAttrs[attr][this.skus[skuId][attr]] = this.skus[skuId][attr];
					}
				}
			}
		}

		/* remember filtered data for future usage */
		this.filteredSkus = skus;
		this.filteredAttributes = activeAttrs;

		/* 
		 * populate all selectors based on the active attributes (valid SKUs)
		 */
		for (var attr in this.attrs) {
			if (!this.selectors[attr]) alert('Missing "'+attr+'" attribute selector.');
			var val = this.currentFilter[attr]?this.currentFilter[attr]:this.selectors[attr].value();

			this.selectors[attr].truncate();
			for (var i=0;i<this.attrs[attr].length;i++) {
				var key = this.attrs[attr][i][0];
				if (!key || activeAttrs[attr][key]) {
					this.selectors[attr].append(new Option(this.attrs[attr][i][1], key, !key, val.indexOf(key) !== -1));
				}
			}
			/* if only one option - choose it */
			if (this.selectors[attr].options().length == 2) this.selectors[attr].select(1);
		}

		if (this.callback) this.callback(skus);
	},

	addAttributeOption: function(attr, id, name) {
		if (!this.attrs[attr]) this.attrs[attr] = [];
		this.attrs[attr].push([id,name]);
	},


	registerSelector: function(attr, selector, applyFilter, type) {
		if (type == 'checkbox') {
		        var _s = new EcsCheckboxSelector(selector);
		} else {
		        var _s = new EcsSelector(selector);
		}
		_s.setOnchangeHandler(function() { var f={}; f[attr] = _s.value(); ecsSkuSelector.filter(f); } );
		_s.applySkuFilter = applyFilter ? 1 : 0;
		if (!this.cascadeIndexCounter) this.cascadeIndexCounter = 0;
		_s.cascadeIndex = this.cascadeIndexCounter++;
		this.selectors[attr] = _s;

	},


	registerCallback: function(func) {
		this.callback = func;
	},

	decomposeMultiEnum: function(data) {
		var ret = [];
		var matches = data.match(/"(.+?)"/ig);
		for (var i = 0; i<matches.length; i++) ret.push(matches[i].replace(/"/g,''));
		return ret;
	}

}


/*
 * Selectbox selector abstraction. DOM select object at constructor
 */
function EcsSelector(object) {
	this.selector = object;
	this.multiselect = 0;

	this.append = function(opt) {
		this.selector.options[this.selector.options.length] = opt;
	}

	this.truncate = function () {
		this.selector.options.length = 0;
	}

	this.select = function(pos) {
		this.selector.options[pos].selected = true;
	}

	this.setOnchangeHandler = function(f) {
		this.selector.onchange = f;
	}

	this.value = function() {
		return this.selector.value;
	}

	this.options = function() {
		return this.selector.options;
	}

	this.comparator = function(skuAttr, filterVal) {
		return skuAttr == filterVal;
	}

}


/*
 * Checkboxed multi-selector abstraction. DOM div/span object as content area
 */
function EcsCheckboxSelector(object) {
	this.container = object;
	this.options = [];
	this.multiselect = 1;

	this.append = function(opt) {
		this.options[this.options.length] = opt;
		var e = document.createElement('div');
		e.className = 'cbSelectorBlock';
		e.innerHTML = '<span class="cbSelectorCB"><input type="checkbox" value="'+opt.value+'" '+(opt.selected?'checked':'')+'/></span><span class="cbSelectorLabel">'+opt.text+'</span>';
		this.container.appendChild(e);
		
		var _this = this;
		e.getElementsByTagName('input')[0].onclick = function() { _this.onchange(); }
		
	}

	this.truncate = function () {
		this.options.length = 0;
		this.container.innerHTML = '';
	}

	this.select = function(pos) { alert(pos);	}

	this.setOnchangeHandler = function(f) {
		this.onchange = f;
	}

	this.value = function() {
		var ret = [];
		var _tags = this.container.getElementsByTagName('input');
		for (var i = 0; i < _tags.length; i++) {
			if (_tags[i].checked) ret.push(_tags[i].value);
		}
		return ret;
	}

	this.options = function() {
		return this.options;
	}

	this.comparator = function(skuAttr, filterVal, model) {
		if (!filterVal || !filterVal.length) return true;
		if (!model) model = 'AND';

		if (typeof(filterVal) == 'string') filterVal = [filterVal];

		for (var i = 0; i < filterVal.length; i++) {
			if (skuAttr.indexOf(filterVal[i]) == -1) {
				if (model == 'AND') {
					return false;
				}
			}
		}

		return true;
	}

}
