var Shopium = window.Shopium || {};



Shopium.ProductSelectorOption = function(id, name, state) {
	this.id = id;
	this.name = name;
	this.state = state;
}

Shopium.ProductSelector = function(config) {
	this.config = jQuery.extend({}, this.defaultConfig, config);
	this.state = {};
	this.current_variants = [];
	this.possible_values = {}
	this.allowed_values = {};
	this.init();
}

Shopium.ProductSelector.prototype = {
	defaultConfig: {
		renderer: null,
		attributes: null
	},
	
	init: function() {
		if (!this.config.renderer) {
			this.config.renderer = this.defaultRenderer;
		}
		this.filterVariants();
		this.buildAllowedValues();
		$.extend(this.possible_values, this.allowed_values);
		this.render();
	},
	
	getAttribute: function(id_or_code) {
		for (var i=0;i<this.config.attributes.length;i++) {
			var attr = this.config.attributes[i];
			if (attr.code == id_or_code || attr.id == id_or_code)
				return attr;
		}
	},

	getOption: function(attr_id_or_code, option_id_or_code) {
		var attr = this.getAttribute(attr_id_or_code);
		if (!attr) {
			return;
		}
		
		for (var i=0;i<attr.options.length;i++) {
			var opt = attr.options[i];
			if (opt.code == option_id_or_code || opt.id == option_id_or_code)
				return opt;
		}
	},

	getSelectedAttributes: function() {
		var state=this.state;
		return $.map(this.config.attributes, function(attr) {
			return state[attr.id] ? attr : null;
		});
	},

	getNotSelectedAttributes: function() {
		var state=this.state;
		return $.map(this.config.attributes, function(attr) {
			return state[attr.id] ? null : attr;
		});
	},

	select: function(attr, val) {
		if (!this.possible_values[attr] || !this.possible_values[attr][val]) {
			throw "Invalid attribute/value combination";
		}
		if (!this.allowed_values[attr] || !this.allowed_values[attr][val]) {
			this.state = {};
		}
		this.state[attr] = val;
		this.filterVariants();
		this.buildAllowedValues();
		this.render();
	},

	deselect: function(attr) {
		delete this.state[attr];
		this.filterVariants();
		this.buildAllowedValues();
		this.render();
	},

	isSelected: function(attr_id) {
		var state = this.state;
		
		if (attr_id) {
			return typeof state[attr_id] !== 'undefined';
		}
		
		var vals=$.map(this.config.attributes, function(attr) {
			return state[attr.id];
		});
		return vals.length === this.config.attributes.length;
	},
	
	getCurrent: function() {
		return this.current_variants[0];
	},
	
	render: function() {
		var that = this;
		var attrs = this.config.attributes;
		var renderer = this.config.renderer;
		
		for (var i=0;i<attrs.length;i++) {
			var attr = attrs[i];
			var opts = $.map(attr.options, function(el) {return {id:el.id, name:el.name, code:el.code, state: that.getOptState(attr, el)}});
			var html = renderer(attr, opts);
			
			var sel = jQuery('.product-selector-' + attr.id); 
			sel.html(html);
		}
		
		if (typeof(this.config.update_state) === typeof(Function)) {
			this.config.update_state.call(this);
		}
	},
	
	getOptState: function(attr, opt) {
		if (this.state[attr.id] == opt.id) {
			return 'selected';
		}

		if (this.state[attr.id])
			return 'allowed';
		
		if (this.isSelected()) {
			return 'allowed';
		}
		
		if (this.allowed_values[attr.id][opt.id]) {
			return 'allowed';
		}
		return 'notallowed';
	},
	
	filterVariants: function() {
		this.current_variants = $.map(this.config.variants, $.proxy(function(v) {
			var attrs = v.attrs;
			var matches = true;
			$.each(this.state, function(key, val) {
				if (val) {
					matches = matches && attrs[key] === val;
				}
			});
			
			if (matches) {
				return v;
			}
		}, this));
		
		this.current_variants.sort(function(a,b) {
			return a.price - b.price;
		})
	},
	
	buildAllowedValues: function() {
		$.each(this.config.attributes, $.proxy(function(key, attr) {
			this.allowed_values[attr.id] = {};
			$.each(this.current_variants, $.proxy(function(idx, variant) {
				this.allowed_values[attr.id][variant.attrs[attr.id]] = true;
			}, this));		
		}, this));
	},
	
	defaultRenderer1: function(attr, options) {
		var buf=['<select name="' + attr.id + '"><option></option>'];
		for (var i=0;i<options.length;i++) {
			var opt = options[i];
			var availability = !opt.available ? '':'disabled';
			var selected = !opt.selected ? 'selected':'';
			buf.push('<option value="' + opt.id + '" ' + availability + ' ' + selected + '>' + opt.name + '</option>');
		}
		buf.push('</select>');
		return buf.join('');
	},
	defaultRenderer: function(attr, options) {
		var buf=[];
		for (var i=0;i<options.length;i++) {
			var opt = options[i];
			//var availability = !opt.available ? '':'disabled';
			//var selected = !opt.selected ? 'checked':'';
			var availability = opt.state==="allowed" ? '':'disabled';
			var selected = opt.state==="selected" ? 'checked':'';
			buf.push('<label><input type="radio" name="' + attr.id + '" value="' + opt.id + '" ' + availability + ' ' + selected + '>' + opt.name + '</label>');
		}
		return buf.join('');
	}
	
}

