function Product()
{
	this.criteria = new Array();
	this.skus = new Array();	
	this.matchedSkus = new Array();
	this.listeners = new Array();
}

Product.prototype.addSku = function(sku)
{
	this.skus[this.skus.length] = sku;
	if(this.defaultSku == null || sku.isDefault)
		this.defaultSku = sku;
}

Product.prototype.addListener = function(listener)
{
	this.listeners[this.listeners.length] = listener;
}

Product.prototype.setPropertyCriteria = function(index, value, reset)
{
    if(reset) 
        for(var i=index+1; i<this.criteria.length; ++i)
            this.criteria[i] = null;
    
	this.criteria[index] = value;
	this.matchedSkus = this.findSkus();
	this.refresh();
}

Product.prototype.findSkus = function(criteria)
{
    if(criteria == null) criteria = this.criteria;

    var skus = new Array();
	for(var a=0; a<this.skus.length; ++a)
	{
		var sku = this.skus[a];
		var match = true;
		for(var i=0; i< sku.properties.length; ++i)
		{
			if(criteria[i] != '' && criteria[i] != null && sku.properties[i] != criteria[i])
				match = false;
		}
		if(match)
		{
			skus[skus.length] = sku;
		}
	}
	return skus;
}

Product.prototype.refresh = function()
{
	for(var i=0; i<this.listeners.length; ++i) 
		this.listeners[i].notifyProductCriteriaChange();
}

Product.prototype.getPropertyCriteria = function(index)
{
	return this.criteria[index];
}

Product.prototype.getSku = function()
{
	if(this.matchedSkus.length != 1) return null;
	var sku = this.matchedSkus[0];
	for(var i=0;i<sku.properties.length;++i)
	    if(this.criteria[i] != sku.properties[i])
	        return null;
	return sku;
}

Product.prototype.getQuantity = function()
{
	if(this.matchedSkus.length > 1) return null;
	return this.matchedSkus[0].quantity;
}

Product.prototype.getMinMaxPrice = function(index)
{
	var result = new Object;
	result.min = 0;
	result.max = 0;
	result.minText = '';
	result.maxText = '';
	
	for(var i=0; i<this.matchedSkus.length; ++i) {
	    var sku = this.matchedSkus[i];
		if(result.min == 0 || result.min > sku.prices[index][0])
		{
			result.min = sku.prices[index][0];
			result.minText = sku.prices[index][1];
		}
		if(result.max == 0 || result.max < sku.prices[index][0])
		{
			result.max = sku.prices[index][0];						
			result.maxText = sku.prices[index][1];	
		}
	}
	
	if(result.min == 0) result.min = result.max;
	return result;
}

Product.prototype.getOptionsByProperty = function(index)
{
    //make new criteria from index 0 - [index-1]
    var criteria = new Array();
    for(var i=0;i<index;++i) criteria[i] = this.criteria[i];

    var skus = this.findSkus(criteria);
	var tmp = new Array();
    for(i=0;i<skus.length;++i)
		tmp[skus[i].properties[index]] = true;
		
	var result = new Array();
	for(var key in tmp)
		result[result.length] = key;

	return result;
}

function Sku(id, code, quantity, properties, images, prices, isDefault, isActualImage, maximum, isBackOrderAllowed)
{
	this.id = id;
	this.code = code;
	this.quantity = quantity;
	this.properties = properties;
	this.images = images;
	this.prices = prices;
	this.isDefault = isDefault;
	this.isActualImage = isActualImage;
    this.maximum = maximum;
    this.isBackOrderAllowed = isBackOrderAllowed;
}

function OurPriceControl(product, ctlName, ourIndex)
{
	this.product = product;
	this.ourIndex = ourIndex;
	this.control = document.getElementById(ctlName);
	product.addListener(this);
}

OurPriceControl.prototype.getPriceText = function(minmax)
{
	var price;
	if(minmax.min == minmax.max)
		price = minmax.minText;
	else {
		price = minmax.minText + " - " + minmax.maxText;
	}
	return price;
}

OurPriceControl.prototype.notifyProductCriteriaChange = function()
{
	var ourResult = this.product.getMinMaxPrice(this.ourIndex);
    this.control.innerHTML = this.getPriceText(ourResult);
}

function SalePriceControl(product, ctlName, saleIndex)
{
    this.product = product;
    this.saleIndex = saleIndex;
    this.control = document.getElementById(ctlName);
    product.addListener(this);
}

SalePriceControl.prototype.getPriceText = function(minmax)
{
	var price;
	if(minmax.min == minmax.max)
		price = minmax.minText;
	else
		price = minmax.minText + " - " + minmax.maxText;
	return price;
}

SalePriceControl.prototype.notifyProductCriteriaChange = function()
{
    var saleResult = this.product.getMinMaxPrice(this.saleIndex);

    if ((saleResult.min != 0) && (saleResult.max != 0) && (this.product.getQuantity() != null))
        this.control.innerHTML = "Sale " + this.getPriceText(saleResult);
    else
        this.control.innerHTML = "&nbsp;";
}

function PropertySelectorControl(product, ctlName, index, text, order)
{
	var me = this;
	
	function onChange()
	{
		var value = me.control.options[me.control.selectedIndex].value;
		me.product.setPropertyCriteria(me.criteriaIndex, value, true);
	}

	this.product = product;
	this.criteriaIndex = index;
	this.control = document.getElementById(ctlName);	
	this.control.onchange = onChange;
	this.text = text;
	this.order = order;
	product.addListener(this);
}

PropertySelectorControl.prototype.notifyProductCriteriaChange = function()
{
	var me = this;

    function ordinalSort(a, b) 
    { 
        a = me.order[a];
        b = me.order[b];
        if(a > b) 
            return 1;
        if(a == b) 
            return 0;
        return -1;
    }
    
	//clear current options
	for (var i = this.control.options.length - 1; i >= 0; i--)
		this.control.options[i] = null;

    //get selectable options
	var properties = this.product.getOptionsByProperty(this.criteriaIndex);   
    properties.sort(ordinalSort);
		
	//add blank option and selectable options
	if(this.text != null)
	    this.control.options[this.control.options.length] = new Option(this.text, '');
	    
	for (i=0; i<properties.length; ++i)
	{
		this.control.options[this.control.options.length] = new Option(properties[i], properties[i]);	
		if(properties[i] == this.product.criteria[this.criteriaIndex]) this.control.selectedIndex = this.control.options.length-1;
	}

    var selectedValue = '';
	if(this.control.selectedIndex != -1) 
		selectedValue = this.control.options[this.control.selectedIndex].value;
    var criteriaValue = this.product.criteria[this.criteriaIndex];
    if(criteriaValue == null) criteriaValue = '';

	if(selectedValue != criteriaValue)
	    this.product.setPropertyCriteria(this.criteriaIndex, selectedValue, true);
}

function ImageControl(product, ctlName, index, ctlActualImgTxt, actualImgTxt)
{
	this.product = product;
	this.control = document.getElementById(ctlName);
	this.imgIndex = index;
	this.ctlActualImgTxt = document.getElementById(ctlActualImgTxt);
	this.actualImgTxt = actualImgTxt;
	product.addListener(this);
}

ImageControl.prototype.notifyProductCriteriaChange = function()
{
    this.ctlActualImgTxt.innerHTML = "";
	if(this.product.matchedSkus.length >= 1) {
   	    this.control.src = this.product.matchedSkus[0].images[this.imgIndex];

        if(this.product.matchedSkus[0].isActualImage)
        {
	        this.ctlActualImgTxt.innerHTML = "";
	    }
	    else
	    {
	        this.ctlActualImgTxt.innerHTML = this.actualImgTxt;
	    }
	    
	} else {
	    this.control.src = this.product.defaultSku.images[this.imgIndex];
    }	

    this.control.style.visibility = "visible";    
}

function SkuIdControl(product, ctlName)
{
	this.product = product;
	this.control = document.getElementById(ctlName);
	product.addListener(this);
}

SkuIdControl.prototype.notifyProductCriteriaChange = function()
{
    var sku = this.product.getSku();
    if(sku==null)
	    this.control.value = "";
	else 
	    this.control.value = sku.id;
}

function SkuMaximumControl(product, ctlName, language_id)
{
    this.product     = product;
    this.control     = document.getElementById(ctlName);
    this.language_id = language_id;
    product.addListener(this);
}

SkuMaximumControl.prototype.notifyProductCriteriaChange = function()
{
    var sku = this.product.getSku();

    this.control.innerHTML= "";
    if ((sku != null) && (sku.quantity <= 0))
    {
        if ((sku.maximum == 0) || (!sku.isBackOrderAllowed)) {
	       this.control.innerHTML = this.language_id == 1 ? "(Sold out)" : "(Stock &eacute;puis&eacute;)";
	       // alert(location.pathname);
	    }
    }
}

/*
function QuantityControl(product, ctlName)
{
	this.product = product;
	this.control = document.getElementById(ctlName);
	product.addListener(this);
}

QuantityControl.prototype.notifyProductCriteriaChange = function()
{
    while(this.control.options.length > 0)
      this.control.options[0] = null;

    var sku = this.product.getSku();    
    if(sku != null)
      for(i=1;i<=sku.quantity && i<=5;++i)
        this.control.options[this.control.options.length] = new Option(i, i);
}
*/
function CurrencyFormatted(amount)
{
	var i = parseFloat(amount);
	if(isNaN(i)) { i = 0.00; }
	var minus = '';
	if(i < 0) { minus = '-'; }
	i = Math.abs(i);
	i = parseInt((i + .005) * 100);
	i = i / 100;
	s = new String(i);
	if(s.indexOf('.') < 0) { s += '.00'; }
	if(s.indexOf('.') == (s.length - 2)) { s += '0'; }
	s = minus + s;
	return s;
}

