var customOptions = function(price, combinations, variations, hash, fields, saved)
{
	this.combinations = combinations;
	this.variations = variations;
	this.attributeTypeMap = new Object();
	this.attributeValueMap = new Object();
	this.combinationsHash = hash;
	this.fields = fields;
	this.hasFields = false;


	this.saved = saved;
	this.quantity = 1;
	this.customerOptions = new Object();
	this.currentPrice = price;
	this.engravingPrice = 0.00;
	this.engravings = new Object();
	this.firstOption = true;
	this.userClick = false;
	this.userLast = '';
	this.engravingMode = 'none'; // none / same / different
	
	this.load = function()
	{
		$('ul.tabs').tabs({ fx: { opacity: 'toggle' } });
	

		// setup combination attributevalue => type hash
		jQuery.each(this.variations, function(name, values){
			jQuery.each(values, function(){
				options.attributeTypeMap[this.voptionid] = name;
				options.attributeValueMap[this.voptionid] = this.vovalue;
			});
		});

		if(this.saved)
		{
			// load previous options (if they are valid
			if(this.combinations[this.saved.variation])
			{
				var combination = this.combinations[this.saved.variation].combination;
				var varIds = new Array();
				if(combination.match(','))
				{
					varIds = combination.split(',');
				}
				else
				{
					varIds[0] = combination;
				}
				jQuery.each(varIds,function(){
					var name = options.attributeTypeMap[this];
					options.customerOptions[name] = this;
				});
			}
			//setup engravings
			var count = 0;
			var first = true;
			this.engravings = this.saved.fields;
			this.engravingPrice = 0.00;
			jQuery.each(this.saved.fields, function(k,v){
				jQuery.each(v,function(){
					if(first) count++;
					options.engravingPrice+=parseFloat(options.fields[k].vfieldprice);
				});
				first = false;
			});
			if(count == 1)
			{
				this.engravingMode = 'same';
			}
			else if(count > 1)
			{
				this.engravingMode = 'different';
			}
			this.quantity = this.saved.quantity;
			$("input[name='cartitemid']").attr('value',this.saved.CartItemId);
			$("input[name='qty']").attr('value',this.quantity);
			$("input[name='variation_id']").attr('value',this.saved.variation);
			$("input[name='customfields']").attr('value',encodeURIComponent(jQuery.toJSON(this.engravings)));
		}
		else
		{
			// set default selected options
			jQuery.each(this.combinations, function(){
				if(this.combination)
				{
					var attributes = this.combination.split(',');
					jQuery.each(attributes, function(){
						options.customerOptions[options.attributeTypeMap[this]] = this;
//						options.update(options.attributeTypeMap[this], this);
					});
					return false;
				}
			});
		}

		this.setup();

		jQuery.each(this.variations, this.drawOption);

		// select the first option
		if(this.saved)
		{
			this.refresh();
		}
		else
		{
			jQuery.each(this.variations, function(name, values){
				jQuery.each(values, function(){
					options.update(name, this.voptionid, true);
					return false;
				});
				return false;
			});
		}
		this.refresh();
	}

	this.setup = function()
	{
		var html = '<div class="variation"><div class="title">Quantity</div><div>';
		html+= '<input type="text" name="qty" value="'+this.quantity+'" onkeyup="options.updateQuantity(this.value);" onclick="this.select();" class="quantity"/>';
		html+= '</div></div><div class="choices"></div>';
		var ref = this;
		jQuery.each(this.fields, function(k,v){
			ref.hasFields = true;
			return false;
		});
		if(this.hasFields)
		{
			var checked = new Object();
			checked['none'] = '';
			checked['same'] = '';
			checked['different'] = '';
			checked[this.engravingMode] = ' checked="checked"';
			html+= '<div class="variation"><div class="title">Engraving options</div>';
			if(tips['Engraving options'])
			{
				html+= '<span class="learnmore" onclick="$(\'.engravingoptionshelp\').toggle();">learn more</span><div class="engravingoptionshelp tip" style="display:none">'+tips['Engraving options']+'</div>';
			}
			html+= '<label onclick="options.setEngravingMode(\'none\');"><input type="radio" name="engravingoptions"'+checked['none']+'/>No engraving</label>';
			html+= '<label onclick="options.setEngravingMode(\'same\');"><input type="radio" name="engravingoptions"'+checked['same']+'/>Same engraving</label>';
			html+= '<label onclick="options.setEngravingMode(\'different\');"><input type="radio" name="engravingoptions"'+checked['different']+'/>Different engravings</label>';
			html+= '</div>';
		}
		html+= '<div class="engravings"></div><div class="subtotal">';
		html+= '<div class="subtotal"><div class="title">SUBTOTAL</div><div class="total">&pound;'+this.currentPrice+'</div><div class="clear"></div></div>';
		var option = $('#options').append(html);
	}

	this.setEngravingMode = function(mode)
	{
		// need to trim engravings so they don't get sent to checkout
		this.engravingMode = mode;
		if(mode == 'same' || mode == 'none' || true)
		{
			var limit = 0;
			if(mode == 'none')
			{
				
				limit = -1;
			}
			this.engravingPrice = 0.00;
			jQuery.each(this.engravings, function(k, v){
				var row = 0;
				var last = '';
				jQuery.each(v, function(k2, v2){
					if(row == 0)
					{
						last = v2;
					}
					if(row >= limit)
					{
						if(mode == 'none')
						{
							options.engravingPrice = 0.00;
							delete options.engravings[k][row];
						}
						else 
						{
							if(v2 != '' && typeof (v2) != 'undefined')
							{
								options.engravingPrice += parseFloat(options.fields[k].vfieldprice);
							}
							if(mode == 'same')
							{
								options.engravings[k][row] = v2;
							}
						}
					}
					row++;
				});
			});
		}
		if(this.engravingMode == 'none')
		{
			this.engravingPrice = 0;
		}
		this.refresh();
	}

	/**
	 * Update product quantity, updates number of attributes where appropriate
	 */
	this.updateQuantity = function(quantity)
	{
		this.quantity = quantity;
		$("input[name='qty']").attr('value',this.quantity);
		this.refresh();
	}

	/**
	 * Convert a jquery object or other object to a normal array
	 */
	this.objectToArray = function(obj)
	{
		var tmpArray = new Array();
		jQuery.each(obj, function(k, v)
		{
			tmpArray[tmpArray.length] = v;
		});
		return tmpArray;
	}

	/**
	 * Adds an option to the may set of options for the product
	 */
	this.drawOption = function(name, data)
	{
		var type = data[0].vtype;
		var classname = name.replace(/ /g, '_');
		var help = '';
		if(tips[name])
		{
			help = '<span class="learnmore" onclick="$(\'.'+classname+'help\').toggle();">learn more</span><div class="'+classname+'help tip" style="display:none">'+tips[name]+'</div>';
		}
		var option = $('#options > .choices').append('<div class="variation"><div class="title">'+name+'</div>'+help+'<div class="option'+classname+'"></div></div>');


		switch(type)
		{
			case 'text':
			{
				break;
			}
			case 'radio':
			case 'default':
			default:
			{
				var validOptions = 0;
				var firstKey = '';
				var firstValue = '';
				var firstIteration = true;
				jQuery.each(data, function(key, values)
				{
					var label = values.vovalue;
					var checked = '';
					// is this a valid option based on combinations?
					if(!options.isCurrentlyValidOption(values.voname, values.voptionid) && !options.firstOption)
					{
						return;
					}
					if(firstIteration)
					{
						firstKey = values.voname;
						firstValue = values.voptionid;
						firstIteration = false;
					}
					validOptions++;

					//label+='('+values.voptionid+')';
					if(options.customerOptions[values.voname] && options.customerOptions[values.voname] == values.voptionid) // GLOBAL VARIABLE options
					{
						label+=' [included in price]';
						checked = ' checked="checked"';
					}
					else
					{
						var change = options.getVariationPrice(values.voname, values.voptionid);
						var perproduct = '';
						if(options.quantity > 1)
						{
							perproduct = ' per product';
						}
						if(change < 0)
						{
							label+=' [subtract &pound;'+(change*-1)+perproduct+']';	
						}
						else
						{
							label+=' [add &pound;'+change+perproduct+']';
						}
					}
					$('.option'+classname).append('<label class="'+values.voptionid+'" onclick="options.update(\''+name+'\',\''+values.voptionid+'\', true);"><input type="radio" name="option'+name+'" value="'+values.voptionid+'"'+checked+'/><span class="label">'+label+'</span></label>');
					//$('.'+values.voptionid).onclick = function(){options.update(name, values.voptionid, true);};
				});
				
				if(name != options.userLast)
				{
					//options.update(firstKey, firstValue, false);
				}
				options.firstOption = false;
				break;
			}
			case 'select':
			{
				break;
			}
		}
	}
	
	this.drawEngravings = function()
	{
		var engravings = $('#options > .engravings').empty();	
		if(this.engravingMode == 'none')
		{
			return;
		}
		var extra;
		var limit = parseInt(this.quantity)+1;
		for(i=1; i < limit; i++)
		{
			if(this.quantity == 1 || this.engravingMode == 'same')
			{
				extra = '';
			}
			else
			{
				extra = ' '+i;
			}
			var areas = '';
			jQuery.each(this.fields, function(k, v){
				var currentField = '';
				var label = '';
				if(options.engravings[k] && options.engravings[k][i-1] && typeof(options.engravings[k][i-1]) != 'undefined')
				{
					currentField = options.engravings[k][i-1];
					label = '[included in price]';
				}
				else
				{
					label = '[add &pound;'+options.formatPrice(parseFloat(v.vfieldprice));
					if(options.engravingMode == 'same' && options.quantity > 1)
					{
						label+=' per product';
					}
					label+=']';
				}
				areas+='<label>'+v.vfieldname+' '+label+'</label><textarea onblur="options.addEngraving('+k+','+i+',this.value);">'+currentField+'</textarea><div class="clear"></div>';
			});
			var option = engravings.append('<div class="variation"><div class="title">Engraving'+extra+'</div><div class="engraving'+i+'">'+areas+'</div></div>');	
			if(this.engravingMode == 'same')
			{
				break;
			}
		}
	}


	this.isCurrentlyValidOption = function(name, value)
	{
		var combination = this.getCombination(name, value);
		
		// think this needs to only look at the values selected up to this point?
		var valid = false;
		if(this.combinationsHash[combination])
		{
			valid = true;
		}
		return valid;
	}

	this.getValidCombination = function(name, value, update)
	{
		// find the first valid combination that matches

		var changeOptions = false;
		var combination = '';
		jQuery.each(this.variations, function(k, v){
			if(changeOptions)
			{
				// update this option to the first option that matches
				// this.customerOptions[k]	= 
				combination+=','+v[0].voptionid;
				// should probably be recursive
				if(update)
				{
					options.customerOptions[k] = v[0].voptionid;
				}
			}
			else
			{
				combination+=','+options.customerOptions[k];
			}
			if(k == name || name == null)
			{
				changeOptions = true;
			}
		});
		return combination.substr(1);
	}

	this.getCombination = function(name, value)
	{
		// probably need to sort all values in an order?
		var index = '';
		jQuery.each(this.customerOptions, function(k,v){
			if(k == name)
			{
				index+=','+value;
			}
			else
			{
				index+=','+v;
			}
		});
		index = index.substring(1);
		return index;
	}

	this.getVariationPrice = function(name, value)
	{
		var combinationPrice = 0;
		var combination = this.getCombination(name, value);

		if(!this.combinationsHash[combination])
		{
			combination = this.getValidCombination(null, null, false);
		}
		if(this.combinationsHash[combination])
		{
			combinationPrice = this.combinationsHash[combination].price;
		}
		else
		{
			// find first equivalent match
			jQuery.each(this.combinationsHash, function(k, v){
				var ids = k.split(',');
				jQuery.each(ids, function(){
					if(this == value)
					{
						combinationPrice = options.combinationsHash[k].price;
						return false;
					}
				});
				return false;
			});
		}

		return this.formatPrice(combinationPrice - this.currentPrice);
	}

	this.update = function(name, value, isUserClick)
	{
		if(isUserClick)
		{
			this.userLast = name;
		}
		this.userClick = isUserClick;
		var combination = this.getCombination(name, value);
		
		if(!this.combinationsHash[combination])
		{
			// invalid combination, need to try next value
			combination = this.getValidCombination(name, value, true);
		}

		this.currentPrice = this.combinationsHash[combination].price;	
		
		this.customerOptions[name] = value;

		$("input[name='variation_id']").attr('value',this.combinationsHash[combination].variation );


		this.refresh();
	}
	this.addEngraving = function(id, i, value)
	{
		if(!this.engravings[id])
		{
			this.engravings[id] = new Array();
		}
		
		i = i - 1;
		if((this.engravings[id][i] == '' || typeof(this.engravings[id][i]) == 'undefined') && value != '')
		{
			this.engravingPrice += parseFloat(this.fields[id].vfieldprice);
		}
		else if(this.engravings[id][i] != '' && typeof(this.engravings[id][i]) != 'undefined' && value == '')
		{
			this.engravingPrice -= parseFloat(this.fields[id].vfieldprice);
		}
		this.engravings[id][i] = value;
		if(this.quantity > 1 && this.engravingMode == 'same')
		{
			// mutiply 
			for(var j=1; j < this.quantity;j++)
			{
				this.engravings[id][j] = value;
			}
		}
		this.refresh();
		$("input[name='customfields']").attr('value',encodeURIComponent(jQuery.toJSON(this.engravings)));
	}

	this.refresh = function()
	{
		$('#options > .choices').empty();
		this.firstOption = true;
		jQuery.each(this.variations, this.drawOption);
		this.drawEngravings();

		var summary = '';
		jQuery.each(this.customerOptions, function(k, v){
			summary+='<li class="option"><div class="label">'+k+'</div><div class="value">'+options.attributeValueMap[v]+'</div><div class="clear"></div></li>';
		});
		jQuery.each(this.engravings, function(k, v){
			summary+='<li class="option"><div class="label">'+options.fields[k].vfieldname+'</div><div class="value">';
			var count = 0;
			jQuery.each(v,function(){
				count++;
			});
			summary+=' x '+count+'</div></li>';
		});
		$('.specification > .options').html(summary);

		var engravingPrice = this.engravingPrice;
		if(this.engravingMode == 'same')
		{
			engravingPrice = engravingPrice * this.quantity;
		}
		var total = (this.currentPrice * this.quantity) + engravingPrice;
		
		$('.baseprice > .value').html('&pound;'+this.formatPrice(total / 1.175));
		$('.vat > .value').html('&pound;'+this.formatPrice(total - total / 1.175));
		$('.subtotal > .value').html('&pound;'+this.formatPrice(total));
		$('.subtotal > .total').html('&pound;'+this.formatPrice(total));
	}

	this.formatPrice = function(value)
	{
		value = value.toFixed(2);
		return value;
	}
}
