﻿// Ensure Root Namespaces are existing..

if( aspdnsf == undefined || aspdnsf == null ) {
    var aspdnsf = new function(){};
}

if( aspdnsf.Products == undefined || aspdnsf.Products == null ) {
    aspdnsf.Products = new function(){};
}


aspdnsf.Products.ProductController = {
    
    initialize : function() {
        this.products = new Hash();
        this.observers = new Array();
    },
    
    registerProduct : function(product) {
        if(product) {
            this.products[product.getId()] = product;
            this.notifyObservers(product);
            
            return product;
        }
    },
    
    getProduct : function(id) {
        return this.products[id];
    },
    
    addObserver : function(observer) {
        if(observer) {
            this.observers[this.observers.length] = observer;
        }
    },
    
    notifyObservers : function(product) {
        for(var ctr=0; ctr< this.observers.length; ctr++) {
            this.observers[ctr].notify(product);
        }
    }
}

aspdnsf.Products.ProductController.initialize();

aspdnsf.Products.ImagePreLoader = Class.create();
aspdnsf.Products.ImagePreLoader.prototype = {
    
    initialize : function(id) {
        this.id = id;
        this.images = new Array();
        this.preLoadingCompleteEventHandlers = new Array();
    },
    
    add : function(img) {
        this.images.push(img);
    },
    
    addPreloadingCompleteEventHandler : function(handler) {
        this.preLoadingCompleteEventHandlers.push(handler);
    },
    
    process : function() {
        var lambda = this.doProcess.bind(this);
        this.doProcess(lambda);
    },
    
    doProcess : function(lambda) {
        if(this.images.length > 0) {
            var recurse = function(){if(lambda){lambda(lambda)};}
            var current = this.images.pop();
            if(current && current.src) {
                var req = new Ajax.Request(current.src,
                    {
                        method : 'get',
                        onSuccess : function(transport) {
                            current.exists = (200 == transport.status);
                            recurse();
                        },
                        onFailure : function(transport) {
                            current.exists = false;
                            recurse();
                        }
                    }
                );
            }
            else {
                recurse();
            }
        }
        else {
            this.onPreloadingComplete();
        }
        
    },
    
    onPreloadingComplete : function() {
        for(var ctr=0;ctr<this.preLoadingCompleteEventHandlers.length; ctr++) {
            var handler = this.preLoadingCompleteEventHandlers[ctr];
            handler(this);
        }
    }
}

aspdnsf.Products.Product = Class.create();
aspdnsf.Products.Product.prototype = {

    initialize : function(id, itemCode, itemType) {
        this.id = id;
        this.itemCode = itemCode;
        this.itemType = itemType;
        
        this.currentUnitMeasure = null;
        this.price = null;
        this.imageData = null;
        
        this.priceChangedEventHandlers = new Array();
        this.attributeChangedEventHandlers = new Array();
        this.unitMeasures = new Array();
        this.unitMeasureChangedEventHandlers = new Array();
        
        this.restrictedQuantities = null;
        this.minQuantity = 0;
        this.hidePriceUntilCart = false;
        
        this.imagesLoadedEventHandlers = new Array();
        
        this.hasVat = false;
        this.vatSetting = aspdnsf.Constants.VAT_SETTING_EXCLUSIVE;
        
        this.showBuyButton = true;
    },
    
    setUnitMeasureIntrinsics : function(unitMeasures) {
        this.unitMeasures = unitMeasures;
        
        if(this.unitMeasures.length>0) {
            this.setUnitMeasure(this.unitMeasures[0].code);
        }
        
        this.onAttributeChanged();
    },
    
    getUnitMeasures : function() {
        return this.unitMeasures;
    },
    
    getId : function() {
        return this.id;
    },
    
    getItemCode : function() {
        return this.itemCode;
    },
    
    getItemType : function() {
        return this.itemType;
    },
    
    getUnitMeasure : function() {
        return this.currentUnitMeasure.code;
    },
    
    getUnitMeasureQuantity : function() {
        return this.currentUnitMeasure.unitMeasureQuantity;
    },
    
    getPrice : function() {
        return this.currentUnitMeasure.price;
    },
    
    getPriceFormatted : function() {
        return this.currentUnitMeasure.priceFormatted;
    },
    
    getPromotionalPrice : function() {
        return this.currentUnitMeasure.promotionalPrice;
    },
    
    getPromotionalPriceFormatted : function() {
        return this.currentUnitMeasure.promotionalPriceFormatted;
    },

    // InterpriseCZ BEGIN
    getUsedPriceWithoutVAT: function () {
        return this.currentUnitMeasure.usedPriceWithoutVAT;
    },

    getUsedPriceWithoutVATFormatted: function () {
        return this.currentUnitMeasure.usedPriceWithoutVATFormatted;
    },

    getRetailPrice: function () {
        return this.currentUnitMeasure.retailPrice;
    },

    getRetailPriceFormatted: function () {
        return this.currentUnitMeasure.retailPriceFormatted;
    },

    getYouSave: function () {
        return this.currentUnitMeasure.youSave;
    },

    getYouSaveFormatted: function () {
        return this.currentUnitMeasure.youSaveFormatted;
    },

    getPHE: function () {
        return this.currentUnitMeasure.phe;
    },

    getPHEFormatted: function () {
        return this.currentUnitMeasure.pheFormatted;
    },

    getInstalmentsFrom: function () {
        return this.currentUnitMeasure.instalmentsFrom;
    },

    getInstalmentsFromFormatted: function () {
        return this.currentUnitMeasure.instalmentsFromFormatted;
    },

    hasRetailPricing: function () {
        return this.currentUnitMeasure.retailPricing;
    },

    getProductAttributes: function () {
        return this.currentUnitMeasure.productAttributes;
    },

    getStockAvailability: function () {
        return this.currentUnitMeasure.stockAvailability;
    },
    // InterpriseCZ END

    hasPromotionalPrice: function () {
        return this.currentUnitMeasure.hasPromotionalPrice;
    },
    
    getHasVat : function() {
        return this.hasVat;
    },
    
    setHasVat : function(hasVat) {
        this.hasVat = hasVat;
    },
    
    getVatSetting : function() {
        return this.vatSetting;
    },
    
    setVatSetting : function(vatSetting) {
        this.vatSetting = vatSetting;
    },
    
    getVat : function() {
        return this.currentUnitMeasure.tax;
    },
    
    getFreeStock : function() {
        return this.currentUnitMeasure.freeStock;
    },
    
    hasAvailableStock : function() {
        return this.getFreeStock() > 0;
    },
    
    hasRestrictedQuantities : function() {
        return null != this.restrictedQuantities && this.restrictedQuantities.length > 0;
    },
    
    getRestrictedQuantities : function() {
        return this.restrictedQuantities;
    },
    
    setRestrictedQuantities : function(quantities) {
        this.restrictedQuantities = quantities;
    },
    
    setMinimumOrderQuantity : function(qty) {
        this.minQuantity = qty;
    },
    
    getMinimumOrderQuantity : function() {
        return this.minQuantity;
    },
    
    setHidePriceUntilCart : function(hide) {
        this.hidePriceUntilCart = hide;
    },
    
    getHidePriceUntilCart : function() {
        return this.hidePriceUntilCart;
    },
    
    setShowBuyButton : function(show) {
        this.showBuyButton = show;
    },
    
    getShowBuyButton : function() {
        return this.showBuyButton;
    },
    
    setUnitMeasure : function(unitMeasure) {
        for(var ctr=0; ctr< this.unitMeasures.length; ctr++) {
            var currentUnitMeasure =  this.unitMeasures[ctr];
            if(currentUnitMeasure.code == unitMeasure) {
                this._setCurrentUnitMeasure(currentUnitMeasure);
            }
        }
        
        this.onUnitMeasureChanged();
    },
    
    addUnitMeasureChangedEventHandler : function(handler) {
        this.unitMeasureChangedEventHandlers[this.unitMeasureChangedEventHandlers.length] = handler;
    },
    
    onUnitMeasureChanged : function() {
        for(var ctr=0;ctr< this.unitMeasureChangedEventHandlers.length; ctr++) {
            var handler = this.unitMeasureChangedEventHandlers[ctr];
            handler(this);
        }
    },
    
    _setCurrentUnitMeasure : function(unitMeasure) {
        this.currentUnitMeasure = unitMeasure;
        
        this.onPriceChanged();
    },    
    addPriceChangedEventHandler : function(handler) {
        this.priceChangedEventHandlers[this.priceChangedEventHandlers.length] = handler;
    },
    
    addAttributeChangedEventHandler : function(handler) {
        this.attributeChangedEventHandlers[this.attributeChangedEventHandlers.length] = handler;
    },
    
    onPriceChanged : function() {
        for(var ctr=0;ctr< this.priceChangedEventHandlers.length; ctr++) {
            var handler = this.priceChangedEventHandlers[ctr];
            handler(this);
        }
    },
    
    onAttributeChanged : function() {
        for(var ctr=0;ctr< this.attributeChangedEventHandlers.length; ctr++) {
            var handler = this.attributeChangedEventHandlers[ctr];
            handler(this);
        }
    },
    
    getImageData : function() {
        return this.imageData;
    },
    
    
    areImagesLoaded : function() {
        return this.imagesAreLoaded;
    },
    
    
    addImagesLoadedEventHandler : function(handler) {
        this.imagesLoadedEventHandlers.push(handler);
    },
    
    onImagesLoaded : function() {
        for(var ctr=0; ctr<this.imagesLoadedEventHandlers.length; ctr++) {
            var handler = this.imagesLoadedEventHandlers[ctr];
            handler(this);
        }
    },
    
    setImageData : function(data) {
        this.imageData = data;
        
        if(data.isRemote) {
            this.imagesAreLoaded = false;
            this.preLoadImages();
            
        }
        else {
            this.imagesAreLoaded = true;
        }
    },
    
    preLoadImages : function() {
        if(this.imageData) {
            var loader = new aspdnsf.Products.ImagePreLoader(this.id);
            loader.add(this.imageData.medium);
            loader.add(this.imageData.large);
            loader.add(this.imageData.swatch);
            for(var ctr=0; ctr<10; ctr++) {
                loader.add(this.imageData.mediumImages[ctr]);
                loader.add(this.imageData.largeImages[ctr]);
                loader.add(this.imageData.microImages[ctr]);
            }
            
            loader.addPreloadingCompleteEventHandler(this.onPreloadingImagesCompleteEventHandler.bind(this));
            loader.process();
        }
    },
    
    onPreloadingImagesCompleteEventHandler : function() {
        this.imagesAreLoaded = true;
        this.onImagesLoaded();
    },
    
    getMediumImage : function(index) {
        if(arguments.length == 0) {
            return this.imageData.medium;
        }
        else {
            return this.imageData.mediumImages[index];
        }
    },
    
    getLargeImage : function(index) {
        if(arguments.length == 0) {
            return this.imageData.large;
        }
        else {
            return this.imageData.largeImages[index];
        }
    },
    
    getMicroImage : function(index) {
        return this.imageData.microImages[index];
    },
    
    serializeToForm : function() {
        
    },
    
    toString : function() {
        return 'aspdnsf.Products.Product';
    }
}

/**********************************************************************/


/**********************************************************************/

aspdnsf.Products.MatrixProduct = Class.create();
aspdnsf.Products.MatrixProduct.prototype = {
    
    initialize : function(id, itemCode, itemType) {
        Object.extend(this, new aspdnsf.Products.Product(id, itemCode, itemType));
        
        this.attributes = null;
    },
    
    setAttributes : function(attributes) {
        this.attributes = $H(attributes);
    },
    
    getAttributes : function() {
        return this.attributes;
    },    
    
    matches : function(selectedAttributes) {
        var matchCount = 0;
        
        var ownAttributes = this.attributes;
        
        selectedAttributes.each(
            function(selectedAttribute) {
                if(ownAttributes[selectedAttribute.key] == selectedAttribute.value) {
                    matchCount++;
                }
            }
        );
        
        return  (selectedAttributes.keys().length == this.attributes.keys().length) && 
                (matchCount == this.attributes.keys().length);
    },
    
    toString : function() {
        return 'aspdnsf.Products.MatrixProduct';
    }
    
}

aspdnsf.Products.MatrixGroupProduct = Class.create();
aspdnsf.Products.MatrixGroupProduct.prototype = {

    initialize : function(id, itemCode, itemType) {
        Object.extend(this, new aspdnsf.Products.Product(id, itemCode, itemType));
        
        this.matrixProducts = new Array();
        this.interChangeEventHandlers = new Array();
        
        this.attributes = null;
        this.selectedMatrixProduct = null;
        this.matrixProductsWithImagesPreloaded = 0;        
        this.onImagesLoaded = this.onMatrixImagesLoaded;
    },    
    
    onMatrixImagesLoaded : function() {
        if(this.matrixProductsWithImagesPreloaded == this.matrixProducts.length) {
            for(var ctr=0; ctr<this.imagesLoadedEventHandlers.length; ctr++) {
                var handler = this.imagesLoadedEventHandlers[ctr];
                handler(this);
            }
        }
    },
    
    registerMatrixProduct : function(product) {
        this.matrixProducts[this.matrixProducts.length] = product;
        product.addImagesLoadedEventHandler(this.onMatrixItemImageLoaded.bind(this));
    },
    
    onMatrixItemImageLoaded : function() {
        this.matrixProductsWithImagesPreloaded++;
        this.onMatrixImagesLoaded();
    },
    
    chooseMatrixItem : function(itemCode) {
        var matchFound = false;
        
        for(var ctr=0; ctr<this.matrixProducts.length; ctr++) {
            var currentMatrixProduct = this.matrixProducts[ctr];
            if(currentMatrixProduct.getItemCode() == itemCode) {
                this.setSelectedMatrixProduct(currentMatrixProduct);
                matchFound = true;
            }
        }
        
        if(!matchFound) {
            this.selectedMatrixProduct = null;
        }
    },
    
    chooseAttributes : function(attributes) {
        var matchFound = false;
        
        for(var ctr=0; ctr<this.matrixProducts.length; ctr++) {
            var currentMatrixProduct = this.matrixProducts[ctr];
            if(currentMatrixProduct.matches(attributes)) {
                this.setSelectedMatrixProduct(currentMatrixProduct);
                matchFound = true;
            }
        }
        
        if(!matchFound) {
            this.selectedMatrixProduct = null;
        }
    },
    
    getSelectedMatrixProduct : function() {
        return this.selectedMatrixProduct;
    },
    
    hasSelectedMatrixProduct :function() {
        return null != this.selectedMatrixProduct;
    },
    
    setSelectedMatrixProduct : function(selectedMatrixProduct) {
        this.selectedMatrixProduct = selectedMatrixProduct;        
        this.ownAsSelf(selectedMatrixProduct);
    },
    
    ownAsSelf : function(other) {
        this.id = other.getId();
        this.itemCode = other.getItemCode();
        this.setRestrictedQuantities(other.getRestrictedQuantities());
        this.setHidePriceUntilCart(other.getHidePriceUntilCart());
        this.setShowBuyButton(other.getShowBuyButton());
        this.setMinimumOrderQuantity(other.getMinimumOrderQuantity());
        this.setUnitMeasureIntrinsics(other.getUnitMeasures());
        this.setImageData(other.getImageData());
        this.setAttributes(other.getAttributes());
        
        this.onInterChange();
    },
    
    getAttributes : function() {
        return this.attributes;
    },
    
    setAttributes : function(attributes) {
        this.attributes = attributes;
    },
    
    addInterChangeEventHandler : function(handler) {
        this.interChangeEventHandlers[this.interChangeEventHandlers.length] = handler;
    },
    
    onInterChange : function() {
        for(var ctr=0; ctr<this.interChangeEventHandlers.length; ctr++) {
            var handler = this.interChangeEventHandlers[ctr];
            handler(this);
        }
    },
    
    getSwatchImage : function(id) {
        for(var ctr=0; ctr<this.matrixProducts.length; ctr++) {
            var matrixProduct = this.matrixProducts[ctr];
            if(matrixProduct.getId() == id) {
                return matrixProduct.imageData.swatch;
            }
        }
    },
    
    toString : function() {
        return 'aspdnsf.Products.MatrixGroupProduct';
    }
    
}


aspdnsf.Products.Highlight = Class.create();
aspdnsf.Products.Highlight.prototype = {
  
  initialize : function(id) {
    this.elem = $(id);
    this.ctr = 0;
    
    this.doHighLight();
  },
  
  colors : ['#ff9999','#ffaaaa','#ffbbbb', '#ffcccc', '#ffdddd', '#ffeeee', '#ffffff'],
  
  doHighLight : function(pe) {
    if(this.elem) {
      if(this.ctr < this.colors.length) {
        this.elem.style.background = this.colors[this.ctr];
        this.ctr += 1;

        new PeriodicalExecuter(this.doHighLight.bind(this), .1);
      }
      else {
        pe.stop();
      }
      
    }
  }
        
}

aspdnsf.Products.PriceControl = Class.create();
aspdnsf.Products.PriceControl.prototype = {
    // InterpriseCZ
    initialize: function (id, clientId, displayMode) {
        this.id = id;
        this.ctrl = $(clientId);

        // InterpriseCZ
        this.displayMode = displayMode;
    },

    // InterpriseCZ
    setProduct: function (product) {
        this.setProductWithLabel(product, true);
    },

    setProductWithLabel: function (product, showLabel) {
        if (product) {
            this.product = product;
            this.attachPriceChangedEventHandler();

            //this.buildDisplay();
            this.buildDisplayWithLabel(showLabel);
        }
        else {
            aspdnsf.Products.ProductController.addObserver(this);
        }
    },

    notify: function (product) {
        if (product.getId() == this.id) {
            this.setProduct(product);
        }
    },

    attachPriceChangedEventHandler: function () {
        if (this.product) {
            this.product.addPriceChangedEventHandler(this.onProductPriceChanged.bind(this));
        }
    },

    clearDisplay: function () {
        this.ctrl.innerHTML = "";
    },

    // InterpriseCZ
    buildDisplay: function () {
        this.buildDisplayWithLabel(true);
    },

    buildDisplayWithLabel: function (displayLabel) {
        if (!this.product) return;

        this.clearDisplay();

        // InterpriseCZ
        switch (this.displayMode) {
            case 1: // Product detail page
                // Price, or promotional price if available
                var pPrice = document.createElement('p');
                pPrice.className = 'yourPrice';
                var spnPriceLabel = document.createElement('span');
                spnPriceLabel.className = 'priceLabel';
                var spnPrice = document.createElement('span');
                spnPrice.className = 'priceValue';
                if (this.product.hasPromotionalPrice()) {
                    spnPrice.innerHTML = this.product.getPromotionalPriceFormatted();
                    spnPriceLabel.innerHTML = aspdnsf.StringResource.getString('is_showproduct.promotionalprice') + ' ' + aspdnsf.StringResource.getString('is_showproduct.withvat');
                } else {
                    spnPrice.innerHTML = this.product.getPriceFormatted();
                    spnPriceLabel.innerHTML = aspdnsf.StringResource.getString('is_showproduct.yourprice') + ' ' + aspdnsf.StringResource.getString('is_showproduct.withvat');
                }
                //spnPriceLabel.innerHTML = aspdnsf.StringResource.getString('is_showproduct.yourprice');
                pPrice.appendChild(spnPriceLabel);
                pPrice.appendChild(spnPrice);
                this.ctrl.appendChild(pPrice);

                // Same as above without VAT
                pPrice = document.createElement('p');
                pPrice.className = 'yourPriceWithoutVAT';
                spnPriceLabel = document.createElement('span');
                spnPriceLabel.className = 'priceLabel';
                spnPriceLabel.innerHTML = aspdnsf.StringResource.getString(/*'is_showproduct.yourprice'*/'is_showproduct.withoutvat');
                spnPrice = document.createElement('span');
                spnPrice.className = 'priceValue';
                spnPrice.innerHTML = this.product.getUsedPriceWithoutVATFormatted();
                pPrice.appendChild(spnPriceLabel);
                pPrice.appendChild(spnPrice);
                this.ctrl.appendChild(pPrice);

                if (this.product.getRetailPrice() > this.product.getPrice()) // Final price is lower then suggested so/and suggested is higher then regular, so show suggested
                {
                    pPrice = document.createElement('p');
                    pPrice.className = 'regularPrice';
                    spnPriceLabel = document.createElement('span');
                    spnPriceLabel.className = 'priceLabel';
                    spnPriceLabel.innerHTML = aspdnsf.StringResource.getString('is_showproduct.regularprice') + ' ' + aspdnsf.StringResource.getString('is_showproduct.withvat');
                    spnPrice = document.createElement('span');
                    spnPrice.className = 'priceValue';
                    spnPrice.innerHTML = this.product.getRetailPriceFormatted();
                    pPrice.appendChild(spnPriceLabel);
                    pPrice.appendChild(spnPrice);
                    this.ctrl.appendChild(pPrice);
                }
                else if (this.product.hasPromotionalPrice()) // Suggested lower then regular but there is a promotional, so show regular.
                {
                    pPrice = document.createElement('p');
                    pPrice.className = 'regularPrice';
                    spnPriceLabel = document.createElement('span');
                    spnPriceLabel.className = 'priceLabel';
                    spnPriceLabel.innerHTML = aspdnsf.StringResource.getString('is_showproduct.regularprice') + ' ' + aspdnsf.StringResource.getString('is_showproduct.withvat');
                    spnPrice = document.createElement('span');
                    spnPrice.className = 'priceValue';
                    spnPrice.innerHTML = this.product.getPriceFormatted();
                    pPrice.appendChild(spnPriceLabel);
                    pPrice.appendChild(spnPrice);
                    this.ctrl.appendChild(pPrice);
                }

                // PHE if available
                if (this.product.getPHE() != 0) {
                    pPrice = document.createElement('p');
                    pPrice.className = 'phe';
                    spnPriceLabel = document.createElement('span');
                    spnPriceLabel.className = 'priceLabel';
                    spnPriceLabel.innerHTML = aspdnsf.StringResource.getString('is_showproduct.phe');
                    spnPrice = document.createElement('span');
                    spnPrice.className = 'priceValue';
                    spnPrice.innerHTML = this.product.getPHEFormatted();
                    pPrice.appendChild(spnPriceLabel);
                    pPrice.appendChild(spnPrice);
                    this.ctrl.appendChild(pPrice);
                }

                // Instalments if available
                if (this.product.hasRetailPricing() && this.product.getInstalmentsFrom() != 0) {
                    pPrice = document.createElement('p');
                    pPrice.className = 'instalmentsFrom';
                    spnPriceLabel = document.createElement('span');
                    spnPriceLabel.className = 'priceLabel';
                    spnPriceLabel.innerHTML = aspdnsf.StringResource.getString('is_showproduct.instalmentsfrom');
                    spnPrice = document.createElement('span');
                    spnPrice.className = 'priceValue';
                    spnPrice.innerHTML = this.product.getInstalmentsFromFormatted();
                    pPrice.appendChild(spnPriceLabel);
                    pPrice.appendChild(spnPrice);
                    this.ctrl.appendChild(pPrice);
                }

                // You save if available
                if (this.product.getYouSave() > 0) {
                    pPrice = document.createElement('p');
                    pPrice.className = 'youSave';
                    spnPriceLabel = document.createElement('span');
                    spnPriceLabel.className = 'priceLabel';
                    spnPriceLabel.innerHTML = aspdnsf.StringResource.getString('is_showproduct.yousave');
                    spnPrice = document.createElement('span');
                    spnPrice.className = 'priceValue';
                    spnPrice.innerHTML = this.product.getYouSaveFormatted();
                    pPrice.appendChild(spnPriceLabel);
                    pPrice.appendChild(spnPrice);
                    this.ctrl.appendChild(pPrice);
                }

                var dvAttributes = document.getElementById('productAttributes')
                if (dvAttributes) dvAttributes.innerHTML = this.product.getProductAttributes();
                var dvAvailability = document.getElementById('stockAvailability')
                if (dvAvailability) dvAvailability.innerHTML = this.product.getStockAvailability();

                break;
            case 2: // Entity list
                pPrice = document.createElement('p');
                spnVatLabel = document.createElement('span');
                spnVatLabel.className = 'vatLabel';
                spnPrice = document.createElement('span');
                spnPrice.className = 'priceValue';
                pPrice.className = 'yourPrice';
                if (this.product.hasRetailPricing()) {
                    //spnPriceLabel.innerHTML = spnPriceLabel.innerHTML + ' ' + aspdnsf.StringResource.getString('is_showproduct.withvat');
                    spnVatLabel.innerHTML = aspdnsf.StringResource.getString('is_showproduct.withvat');
                    if (this.product.hasPromotionalPrice()) {
                        spnPrice.innerHTML = this.product.getPromotionalPriceFormatted();
                    } else {
                        spnPrice.innerHTML = this.product.getPriceFormatted();
                    }
                } else {
                    //spnPriceLabel.innerHTML = spnPriceLabel.innerHTML + ' ' + aspdnsf.StringResource.getString('is_showproduct.withoutvat');
                    spnVatLabel.innerHTML = aspdnsf.StringResource.getString('is_showproduct.withoutvat');
                    spnPrice.innerHTML = this.product.getUsedPriceWithoutVATFormatted();
                }
                //pPrice.appendChild(spnPriceLabel);
                pPrice.appendChild(spnPrice);
                pPrice.appendChild(spnVatLabel);
                this.ctrl.appendChild(pPrice);
                break;
            default: // Default cart handling
                if (!this.product.getHidePriceUntilCart()) {
                    var pnlPrice = document.createElement('DIV');
                    pnlPrice.id = 'pnlPrice_' + this.id;
                    this.ctrl.appendChild(pnlPrice);

                    var lblPriceCaption = document.createElement('SPAN');
                    lblPriceCaption.id = 'lblPriceCaption_' + this.id;

                    // InterpriseCZ
                    if (displayLabel == true) {
                        lblPriceCaption.innerHTML = aspdnsf.StringResource.getString('is_showproduct.aspx.52') + '&nbsp;';
                    } else {
                        lblPriceCaption.style.display = 'none';
                    }

                    pnlPrice.appendChild(lblPriceCaption);

                    var lblPrice = document.createElement('SPAN');
                    lblPrice.id = 'lblPrice_' + this.id;
                    lblPrice.innerHTML = this.product.getPriceFormatted() + '&nbsp';
                    pnlPrice.appendChild(lblPrice);

                    var lblPrice_VAT = document.createElement('SPAN');
                    lblPrice_VAT.id = 'lblPrice_VAT';
                    if (this.product.getHasVat()) {
                        if (this.product.getVatSetting() == aspdnsf.Constants.VAT_SETTING_INCLUSIVE) {
                            lblPrice_VAT.innerHTML = aspdnsf.StringResource.getString('is_showproduct.aspx.57');
                        }
                        else {
                            lblPrice_VAT.innerHTML = aspdnsf.StringResource.getString('is_showproduct.aspx.56');
                        }
                    }

                    pnlPrice.appendChild(lblPrice_VAT);
                    lblPrice_VAT.className = 'VATLabel';
                    pnlPrice.className = "SalesPrice";

                    if (this.product.hasPromotionalPrice()) {
                        var pnlPromotionalPrice = document.createElement('DIV');
                        pnlPromotionalPrice.id = 'pnlPromotionalPrice_' + this.id;
                        this.ctrl.appendChild(pnlPromotionalPrice);

                        var lblPromotionalPriceCaption = document.createElement('SPAN');
                        lblPromotionalPriceCaption.id = 'lblPromotionalPriceCaption_' + this.id
                        lblPromotionalPriceCaption.innerHTML = aspdnsf.StringResource.getString('is_showproduct.aspx.53') + '&nbsp;';
                        pnlPromotionalPrice.appendChild(lblPromotionalPriceCaption);

                        var lblPromotionalPrice = document.createElement('SPAN');
                        lblPromotionalPrice.id = 'lblPromotionalPrice_' + this.id
                        lblPromotionalPrice.innerHTML = this.product.getPromotionalPriceFormatted() + '&nbsp';
                        pnlPromotionalPrice.appendChild(lblPromotionalPrice);

                        var lblPromotionalPrice_VAT = document.createElement('SPAN');
                        lblPromotionalPrice_VAT.id = 'lblPromotionalPrice_VAT'
                        if (this.product.getHasVat()) {
                            if (this.product.getVatSetting() == aspdnsf.Constants.VAT_SETTING_INCLUSIVE) {
                                lblPromotionalPrice_VAT.innerHTML = aspdnsf.StringResource.getString('is_showproduct.aspx.57');
                            }
                            else {
                                lblPromotionalPrice_VAT.innerHTML = aspdnsf.StringResource.getString('is_showproduct.aspx.56');
                            }
                        }
                        pnlPromotionalPrice.appendChild(lblPromotionalPrice_VAT);

                        pnlPromotionalPrice.className = 'PromotionalPrice';
                        pnlPrice.className = "SalesPriceOverridden";
                        lblPromotionalPrice_VAT.className = 'VATLabel';
                    }
                }
                break;
        }
    },

    onProductPriceChanged: function (product) {
        this.buildDisplay();
    }

}

aspdnsf.Products.UnitMeasureControl = Class.create();
aspdnsf.Products.UnitMeasureControl.prototype = {

    initialize : function(id, clientId) {
        this.id = id;
        this.ctrl = $(clientId);
        this.product = null;
    },
    
    setProduct : function(product) {
        if(product) {
            this.product = product;
            this.buildDisplay();
            
            if(this.product.getItemType() == 'Matrix Group') {
                this.product.addInterChangeEventHandler(this.onProductInterChanged.bind(this));
            }
        }
        else {
            aspdnsf.Products.ProductController.addObserver(this);
        }
    },
    
    notify : function(product) {
        if(product.getId() == this.id) {
            this.setProduct(product);
        }
    },
    
    onUnitMeasureChanged : function(sender) {
        if(this.product) {
            var selectedUnitMeasure = sender.options[sender.selectedIndex].value;
            
            this.product.setUnitMeasure(selectedUnitMeasure);
        }
    },
    
    onProductInterChanged : function() {
        this.buildDisplay();
    },
    
    buildDisplay : function() {
        this.clearDisplay();
        
        var umCode = this.product.getUnitMeasure();
        var idx = 0;
        
        var unitMeasures = this.product.getUnitMeasures();
        if(unitMeasures.length > 1) {
            var span = document.createElement('SPAN');
            span.id = 'lblUnitMeasure_' + this.id;
            span.innerHTML = aspdnsf.StringResource.getString('is_showproduct.aspx.51') + '&nbsp;';
            this.ctrl.appendChild(span);
            
            var select = document.createElement('SELECT');
            select.id = 'UnitMeasureCode_' + this.id;
            select.name = 'UnitMeasureCode';
            
            for(var ctr=0; ctr<unitMeasures.length; ctr++) {
                var current = unitMeasures[ctr];
                select.options.add(new Option(current.description, current.code));
                
                if(umCode == current.code) {
                    idx = ctr;
                }
            }
            
            $(select).selectedIndex = idx;
            $(select).observe('change', this.onUnitMeasureChanged.bind(this, select))
            this.ctrl.appendChild(select);
        }
        else {
            var input = document.createElement('INPUT');
            input.type = 'hidden';
            input.id = 'UnitMeasureCode_' + this.id;
            input.name = 'UnitMeasureCode';            
            this.ctrl.appendChild(input);
            
            var span = document.createElement('SPAN');
            span.id = 'lblUnitMeasure_' + this.id;
                             // InterpriseCZ
            span.innerHTML = /*aspdnsf.StringResource.getString('is_showproduct.aspx.51') + '&nbsp;' +*/ unitMeasures[0].description;
            this.ctrl.appendChild(span);
        }
    },
    
    clearDisplay : function() {
        this.ctrl.innerHTML = '';
    }
    
}

aspdnsf.Products.MatrixAttributeControl = Class.create();
aspdnsf.Products.MatrixAttributeControl.prototype = {
    
    initialize : function(id, attribute) {
        this.ctrl = $(id);
        this.attribute = attribute;
        
        this.attributeChangedEventHandlers = new Array();
        
        if(this.ctrl) {
            this._attachAttributeChangedEventHandler();
        }
    },
    
    _attachAttributeChangedEventHandler : function() {
        this.ctrl.observe('change', this.onAttributeChanged.bind(this));
    },
    
    onAttributeChanged : function() {
        var value = this.ctrl.options[this.ctrl.selectedIndex].value;
        
        for(var ctr=0; ctr< this.attributeChangedEventHandlers.length; ctr++) {
            var handler = this.attributeChangedEventHandlers[ctr];
            handler(value);
        }
    },
    
    addAttributeChangedEventHandler : function(handler) {
        this.attributeChangedEventHandlers[this.attributeChangedEventHandlers.length] = handler;
    },
    
    getAttribute : function() {
        return this.attribute;
    },
    
    getValue : function() {
        if(this.hasAttributeSelected()) {
            var value = this.ctrl.options[this.ctrl.selectedIndex].value;
            return value;
        }
        
        return aspdnsf.Constants.EMPTY_STRING;
    },
    
    setValue : function(value) {
        var idx = 0;
        
        for(var ctr=0;ctr<this.ctrl.options.length; ctr++) {
            var option = this.ctrl.options[ctr];
            if(option.value == value) {
                idx = ctr;
                break;
            }
        }
        
        this.ctrl.selectedIndex = idx;
    },
    
    hasAttributeSelected : function() {
        return this.ctrl.selectedIndex > 0;
    }
    
}

aspdnsf.Products.MatrixAttributeGroupControl = Class.create();
aspdnsf.Products.MatrixAttributeGroupControl.prototype = {

    initialize : function(id) {
        this.id = id;
        
        this.attributeControls = new Array();
        this.product = null;
        
        this.pnlError = $('pnlMatrixAttribute_Error_' + id);
        this.pnlSelectCaption = $('pnlMatrixAttribute_SelectCaption_' + id);
        this.pnlStockHint = $('pnlStockHint_' + id);

        this.attachFormHandler();
    },
    
    setProduct : function(product) {
        if(product) {
            this.product = product;
            
            if(this.product.getItemType() == 'Matrix Group') {
                this.product.addInterChangeEventHandler(this.onProductInterChanged.bind(this));
            }
        }
        else {
            aspdnsf.Products.ProductController.addObserver(this);
        }
    },
    
    notify : function(product) {
        if(product.getId() == this.id) {
            this.setProduct(product);
        }
    },
    
    attachFormHandler : function() {
        var addToCartForm = aspdnsf.Products.AddToCartFormController.getForm(this.id);
        
        var addToCartFormValidatingEventHandler = this.onAddToCartFormValidating.bind(this);
        if(addToCartForm) {
            addToCartForm.addAddToCartValidatingEventHandler(addToCartFormValidatingEventHandler);
        }
        else {
            var id = this.id;
            
            var observer = {
            
                notify : function(form) {
                    if(form.getId() == id) {
                        form.addAddToCartValidatingEventHandler(addToCartFormValidatingEventHandler);
                    }
                }
                
            }
            
            aspdnsf.Products.AddToCartFormController.addObserver(observer);
        }
    },
    
    onAddToCartFormValidating : function(e) {
        if(!this.ensureAllAttributesAreSelected()) {
            e.cancel = true;
                        
            this.pnlError.innerHTML = aspdnsf.StringResource.getString('is_showproduct.aspx.59') + ' ';
            this.pnlSelectCaption.hide();
            
            var appendComma = false;
            
            for(var ctr=0; ctr<this.attributeControls.length; ctr++) {
                var ctrl = this.attributeControls[ctr];            
                if(!ctrl.hasAttributeSelected()) {
                    this.pnlError.innerHTML += (appendComma? ', ' : '') + ctrl.getAttribute();
                    appendComma = true;
                }
            }
        }
        else {
            if(!this.product.hasSelectedMatrixProduct()) {
                e.cancel = true;                
                this.pnlError.innerHTML = aspdnsf.StringResource.getString('is_showproduct.aspx.58');
            }
        }
    },
    
    onProductInterChanged : function() {
        this.clearError();
        
        var attributes = this.product.getAttributes();
        var controls = this.attributeControls;
        
        attributes.each(
            function(attribute) {
                for(var ctr=0; ctr<controls.length; ctr++) {
                    var currentControl = controls[ctr];
                    if(currentControl.getAttribute() == attribute.key) {
                        currentControl.setValue(attribute.value);
                    }
                }
            }
        );
    },
    
    clearError : function() {
        this.pnlError.innerHTML = '';
    },
    
    registerAttributeControl : function(control) {
        this.attributeControls[this.attributeControls.length] = control;
        
        control.addAttributeChangedEventHandler(this.onAttributeChangedEventHandler.bind(this));
    },
    
    onAttributeChangedEventHandler : function(selectedValue) {
        this.clearError();
        
        if(this.ensureAllAttributesAreSelected()) {
            var allAttributes = new Hash();
            
            for(var ctr=0; ctr<this.attributeControls.length; ctr++) {
                var ctrl = this.attributeControls[ctr];
                allAttributes[ctrl.getAttribute()] = ctrl.getValue();
            }
            this.product.chooseAttributes(allAttributes);
            
            if(!this.product.hasSelectedMatrixProduct()) {
                this.pnlError.innerHTML = aspdnsf.StringResource.getString('is_showproduct.aspx.58');
                this.pnlSelectCaption.hide();
                if (this.pnlStockHint) {
                    this.pnlStockHint.hide()
                }
            }
        }
        else
        {
            this.pnlSelectCaption.show();
            if (this.pnlStockHint) {
                this.pnlStockHint.hide()
            }
        }
    },
    
    ensureAllAttributesAreSelected : function() {
        for(var ctr=0; ctr<this.attributeControls.length; ctr++) {
            var ctrl = this.attributeControls[ctr];
            
            if(!ctrl.hasAttributeSelected()) {
                return false;
            }
        }
        
        return true;
    }

}

aspdnsf.Products.ImageMultipleControl = Class.create();
aspdnsf.Products.ImageMultipleControl.prototype = {

    initialize : function(id, index, src) {
        this.id = id;
        this.index = index;
        
        this.ctrl = $(id);
        this.ctrl.src = src;
        
        this.attachClickEventHandler();
        this.attachHoverEventHandler();
        
        this.selectEventHandlers = new Array();
        this.hoverEventHandlers = new Array();
    },
    
    getIndex : function() {
        return this.index;
    },
    
    attachClickEventHandler : function() {
        this.ctrl.observe('click', this.onClickEventHandler.bind(this));
    },
    
    addSelectEventHandler : function(handler) {
        this.selectEventHandlers[this.selectEventHandlers.length] = handler;
    },
    
    attachHoverEventHandler : function() {
        this.ctrl.observe('mouseover', this.onHoverEventHandler.bind(this));
    },
    
    onClickEventHandler : function() {
        for(var ctr=0; ctr<this.selectEventHandlers.length; ctr++) {
            var handler = this.selectEventHandlers[ctr];
            handler(this);
        }
    },
    
    addHoverEventHandler : function(handler) {
        this.hoverEventHandlers[this.hoverEventHandlers.length] = handler;
    },
    
    onHoverEventHandler : function() {
        for(var ctr=0; ctr<this.hoverEventHandlers.length; ctr++) {
            var handler = this.hoverEventHandlers[ctr];
            handler(this);
        }
    },
    
    setImage : function(src) {
        this.ctrl.src = src;
    },
    
    show : function() {
        this.ctrl.style.display = "";
    },
    
    hide : function() {
        this.ctrl.style.display = "none";
    }
}

aspdnsf.Products.ImageSwatchControl = Class.create();
aspdnsf.Products.ImageSwatchControl.prototype = {

    initialize : function(id, clientId, itemCode){
        this.id = id;
        this.itemCode = itemCode;
        
        this.ctrl = $(clientId);
        
        this.attachClickEventHandler();
        this.selectEventHandlers = new Array();
    },
    
    getId : function() {
        return this.id;
    },
    
    getItemCode : function() {
        return this.itemCode;
    },
    
    attachClickEventHandler : function() {
        this.ctrl.observe('click', this.onClickEventHandler.bind(this));
    },
    
    
    addSelectEventHandler : function(handler) {
        this.selectEventHandlers[this.selectEventHandlers.length] = handler;
    },
    
    onClickEventHandler : function() {
        for(var ctr=0; ctr<this.selectEventHandlers.length; ctr++) {
            var handler = this.selectEventHandlers[ctr];
            handler(this);
        }
    },
    
    setImage : function(src) {
        this.ctrl.src = src;
    },
    
    show : function() {
        this.ctrl.style.display = "";
    },
    
    hide : function() {
        this.ctrl.style.display = "none";
    }
    
}

aspdnsf.Products.LargeImageLinkControl = Class.create();
aspdnsf.Products.LargeImageLinkControl.prototype = {
    
    initialize : function(id) {
        this.id = id;
        this.ctrl = $(id);
        
        this.attachClickEventHandler();
        this.selectEventHandlers = new Array();
    },
    
    attachClickEventHandler : function() {
        this.ctrl.observe('click', this.onClickEventHandler.bind(this));
    },
    
    
    addSelectEventHandler : function(handler) {
        this.selectEventHandlers[this.selectEventHandlers.length] = handler;
    },
    
    onClickEventHandler : function() {
        for(var ctr=0; ctr<this.selectEventHandlers.length; ctr++) {
            var handler = this.selectEventHandlers[ctr];
            handler(this);
        }
    },
    
    show : function() {
        this.ctrl.style.display = "";
    },
    
    hide : function() {
        this.ctrl.style.display = "none";
    }
    
}

aspdnsf.Products.ImageControl = Class.create();
aspdnsf.Products.ImageControl.prototype = {
    
    initialize : function(id, clientId) {
        this.id = id;
        this.ctrl = $(clientId);
        
        this.lnkLargeImage = null;
        this.multipleControls = new Array();
        this.swatchControls = new Array();
        this.product = null;
        
        this.multipleImageIndex = -1;
        
        this.useMicroImages = false;
        this.handleHover = false;
    },
    
    setProduct : function(product) {
        if(product) {
            this.product = product;
            
            if(this.product.areImagesLoaded()) {
                this.arrangeDisplay();
            }
            else {
                this.product.addImagesLoadedEventHandler(this.onProductImagesLoaded.bind(this));
            }
            
            if(this.product.getItemType() == 'Matrix Group') {
                this.attachInterChangeEventHandler();
            }
        }
        else {
            aspdnsf.Products.ProductController.addObserver(this);
        }
    },
    
    notify : function(product) {
        if(product.getId() == this.id) {
            this.setProduct(product);
        }
    },
    
    arrangeDisplay : function() {
        if(this.product) {
            var src = this.product.getMediumImage().src;
            this.setImage(src);
            
            this.toggleLargeImageVisibility();
            this.arrangeMultipleControls();
            
            if(this.product.getItemType() == 'Matrix Group') {
                this.arrangeSwatchControls();
            }
        }
    },
    
    onProductImagesLoaded : function() {
        this.arrangeDisplay();
    },
    
    setLargeImageControl : function(control) {
        if(control) {
            this.lnkLargeImage = control;
            this.lnkLargeImage.addSelectEventHandler(this.onLargeImageLinkSelected.bind(this));
            this.toggleLargeImageVisibility();
        }
    },
    
    setUseMicroImages : function(useMicro) {
        this.useMicroImages = useMicro;
    },
    
    setHandleHover : function(handle) {
        this.handleHover = handle;
    },
    
    attachInterChangeEventHandler : function() {
        this.product.addInterChangeEventHandler(this.onProductInterChanged.bind(this));
    },
    
    refreshImage : function() {
        var src = this.product.getMediumImage().src;
        this.setImage(src);
        
        this.multipleImageIndex = -1;
        
        this.toggleLargeImageVisibility();
        this.arrangeMultipleControls();
    },
    
    onProductInterChanged : function() {
       this.refreshImage();
    },
    
    registerMultipleControl : function(control) {
        this.multipleControls[this.multipleControls.length] = control;
        
        control.addSelectEventHandler(this.onMultipleImageControlSelected.bind(this));
        
        if(this.handleHover) {
            control.addHoverEventHandler(this.onMultipleImageControlSelected.bind(this));
        }
        
        this.arrangeMultipleControls();
    },
    
    toggleLargeImageVisibility : function() {
        if(this.lnkLargeImage && this.product) {
            
            var img = null;
            if(this.multipleImageIndex == -1) {
                img = this.product.getLargeImage();
            }
            else {
                img = this.product.getLargeImage(this.multipleImageIndex);
            }
            
            if(img && img.exists) {
                this.lnkLargeImage.show();
            }
            else {
                this.lnkLargeImage.hide();
            }
        }
    },
    
    onLargeImageLinkSelected : function() {
        this.showLargeImage();
    },
    
    showLargeImage : function() {
        var img = null;
        if(this.multipleImageIndex == -1) {
            img = this.product.getLargeImage();
        }
        else {
            img = this.product.getLargeImage(this.multipleImageIndex);
        }
        
        var url = 'popup.aspx?psrc='+ encodeURIComponent(img.src);
        var name = 'LargeImage';
        var resizable = img.resizable?'yes':'no';
        var params = 'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=' + resizable + ',resizable=' + resizable + ',copyhistory=no,width=' + img.size.width + ',height=' + img.size.height + 'left=0,top=0';
        window.open(url, name, params);
    },
    
    arrangeMultipleControls : function() {
        if(this.product) {
            for(var ctr=0; ctr<this.multipleControls.length; ctr++) {
                var control = this.multipleControls[ctr];
                var img = this.product.getMediumImage(ctr);
                if(img && img.exists) {
                    control.show();
                    
                    if(this.useMicroImages) {
                        var micro = this.product.getMicroImage(ctr);
                        control.setImage(micro.src);
                    }
                }
                else {
                    control.hide();
                }
            }
        }
    },
    
    onMultipleImageControlSelected : function(control) {
        var index = control.getIndex();
        this.multipleImageIndex = index;
        
        var src = this.product.getMediumImage(index).src;
        
        this.setImage(src);
        this.toggleLargeImageVisibility();
    },
    
    registerSwatchControl : function(control) {
        this.swatchControls[this.swatchControls.length] = control;
        
        control.addSelectEventHandler(this.onSwatchImageControlSelected.bind(this));
    },
    
    arrangeSwatchControls : function() {
        for(var ctr=0; ctr<this.swatchControls.length; ctr++) {
            var swatchControl = this.swatchControls[ctr];
            var id = swatchControl.getId();
            var swatch = this.product.getSwatchImage(id);
            if(swatch && swatch.exists) {
                swatchControl.setImage(swatch.src);
                swatchControl.show();
            }
            else {
                swatchControl.hide();
            }
        }
    },
    
    onSwatchImageControlSelected : function(control) {
        var itemCode = control.getItemCode();
        this.product.chooseMatrixItem(itemCode);
    },
    
    setImage : function(src) {
        this.ctrl.src = src;
    }
        
}

aspdnsf.Products.StockHintControl = Class.create();
aspdnsf.Products.StockHintControl.prototype = {
    
    initialize : function(id, clientId, inStockSrc, outOfStockSrc) {
        this.id = id;
        this.ctrl = $(clientId);
        this.inStockSrc = inStockSrc;
        this.outOfStockSrc = outOfStockSrc;
                
        this.attributeControls = new Array();
        
        this.pnlSelectCaption = $('pnlMatrixAttribute_SelectCaption_' + id);
        this.pnlStockHint = $('pnlStockHint_' + id);
    },
    
     setProduct : function(product) {
        if(product) {
            this.product = product;
            this.arrangeDisplay();
            
            if(this.product.getItemType() == 'Matrix Group') {
                this.product.addInterChangeEventHandler(this.onProductInterChanged.bind(this));
            }
        }
        else {
            aspdnsf.Products.ProductController.addObserver(this);
        }
    },
    
    notify : function(product) {
        if(product.getId() == this.id) {
            this.setProduct(product);
        }
    },
    
    onProductInterChanged : function() {
        this.arrangeDisplay();
    },
    
    arrangeDisplay : function() {
        if(this.product) {
           
           
            if(this.product.getItemType() == 'Matrix Group') {            
                if (this.product.hasSelectedMatrixProduct())
                {
                    this.pnlSelectCaption.hide();                
                
                    this.pnlStockHint.show();
                }
                else
                {                
                    this.pnlSelectCaption.innerHTML = aspdnsf.StringResource.getString('is_showproduct.aspx.73') + '<br/><br/>';
                    this.pnlSelectCaption.show();
                
                    this.pnlStockHint.hide();
                }
            }
                        
            if(this.product.hasAvailableStock()) {
                this.showInStock();
            }
            else {
                this.showOutOfStock();
            }
        }
    },
    
    showInStock : function() {
        this.ctrl.src = this.inStockSrc;
    },
    
    showOutOfStock : function() {
        this.ctrl.src = this.outOfStockSrc;
    },
    
    show : function() {
        this.style.display = "";
    },
    
    hide : function() {
        this.style.display = "none";
    }

    
}

aspdnsf.Products.PricingLevelControl = Class.create();
aspdnsf.Products.PricingLevelControl.prototype = {

    initialize : function(id, clientId) {
        this.id = id;
        this.ctrl = $('pnlPricingLevel_' + id);
        this.pnlInline = $('pnlPricingLevelInline_' + id);
        this.pnlPopUp = $('pnlPricingLevelPopUp_' + id);
        this.lnkPopUp = $('lnkPricingLevelPopUp_' + id);
        
        this.product = null;
        this.showInline = true;
        this.backColor = '';
    },
    
     setProduct : function(product) {
        if(product) {
            this.product = product;
            this.buildDisplay();
            
            if(this.product.getItemType() == 'Matrix Group') {
                this.product.addInterChangeEventHandler(this.onProductInterChanged.bind(this));
            }
        }
        else {
            aspdnsf.Products.ProductController.addObserver(this);
        }
    },
    
    notify : function(product) {
        if(product.getId() == this.id) {
            this.setProduct(product);
        }
    },
    
    onProductInterChanged : function() {
        this.buildDisplay();
    },
    
    setShowInline : function(inline) {
        this.showInline = inline;
    },
    
    setBackColor : function(color) {
        this.backColor = color;
    },
    
    clearDisplay : function() {
        this.pnlInline.hide();
        this.pnlPopUp.hide();
    },
    
    buildDisplay : function() {
        this.clearDisplay();
        if(this.product && !this.product.hasPromotionalPrice()) {
        
            var display = this.arrangeDisplay.bind(this);
            
            var req = new Ajax.Request('action.axd?action=pricingLevel&itemCode=' + encodeURIComponent(this.product.getItemCode()),
                {
                    method : 'get',
                    onSuccess : function(transport) {
                        display(transport.responseText);
                    },
                    onFailure : function(transport) {
                    }
                }
            );
        }
    },
    
    arrangeDisplay : function(html) {
        if(this.showInline) {
            this.pnlInline.innerHTML = '<p><b>' + aspdnsf.StringResource.getString('showproduct.aspx.8') + '<br/>' + html + '<br/> </b></p>';
            
            this.pnlInline.show();
        }
        else {
            this.lnkPopUp.onmouseover = function(){ddrivetip(html, this.backColor, 300)};
            this.lnkPopUp.onmouseout = hideddrivetip;
            
            this.pnlPopUp.show();
        }
    }

}

aspdnsf.Products.QuantityControl = Class.create();
aspdnsf.Products.QuantityControl.prototype = {
    
    initialize : function(id, clientId, initialQuantity) {
        this.id = $(id);
        this.ctrl = $(clientId);
        this.initialQuantity = initialQuantity;
        
        this.product = null;
        this.getValueDelegate = null
    },
    
    getValue : function() {
        if(this.getValueDelegate) {
            return this.getValueDelegate();
        }
        
        return 0;
    },
    
    setProduct : function(product) {
        if(product) {
            this.product = product;
            this.buildDisplay();
            
            if(this.product.getItemType() == 'Matrix Group') {
                this.product.addInterChangeEventHandler(this.onProductInterChanged.bind(this));
            }
        }
        else {
            aspdnsf.Products.ProductController.addObserver(this);
        }
    },
    
    notify : function(product) {
        if(product.getId() == this.id) {
            this.setProduct(product);
        }
    },
    
    onProductInterChanged : function() {
        this.buildDisplay();
    },
    
    buildDisplay : function() {
        this.clearDisplay();
        
        var span = document.createElement('SPAN');
        span.id = 'lblQuantity_' + this.id;
        span.innerHTML = aspdnsf.StringResource.getString('is_showproduct.aspx.50') + '&nbsp;';

        // InterpriseCZ
        span.style.display = 'none';
        span.style.visibility = 'hidden';
        span.style.width = '0px';

        this.ctrl.appendChild(span);
            
        if(this.product.hasRestrictedQuantities()) {
            var restrictedQuantities = this.product.getRestrictedQuantities();
            var select = document.createElement('SELECT');
            select.id = 'Quantity_' + this.id;
            select.name = 'Quantity';
            
            for(var ctr=0; ctr<restrictedQuantities.length; ctr++) {
                var quantity = restrictedQuantities[ctr];
                select.options.add(new Option(quantity, quantity));
            }
            
            this.ctrl.appendChild(select);
            
            this.getValueDelegate = function(){ return select.options[select.selectedIndex].value; };
        }
        else {
            var input = document.createElement('INPUT');
            input.type = 'text';
            input.id = 'Quantity' + this.id;
            input.name = 'Quantity';

            // InterpriseCZ
            input.className = 'textBox basketAmount';

            input.size = 3;
            input.maxLength = 7;
            input.value = this.initialQuantity;
            this.ctrl.appendChild(input);
            
            this.getValueDelegate = function(){ return input.value; };
        }
    },
    
    clearDisplay : function() {
        this.ctrl.innerHTML = '';
    }

}

/***************************************************************************/



/***************************************************************************/

aspdnsf.Products.AddToCartForm = Class.create();
aspdnsf.Products.AddToCartForm.prototype = {
    
    initialize : function(id) {
        this.id = $(id);
        this.pnlAddToCart = $('pnlAddToCartForm_' + id);
        
        this.form = $('AddToCartForm_' + id);        
        this.form.onsubmit = this.onAddToCartClick.bind(this);
        
        this.btnAddToCart = $('AddToCart_' + id);
        this.btnAddToCart.onclick = this.onAddToCartClick.bind(this);
        
        this.btnAddToWishList = $('AddToWishList_' + id);
        if(this.btnAddToWishList) {
            this.btnAddToWishList.onclick = this.onAddToWishListClick.bind(this);
        }
        
        this.ctrlQuantity = null;
        this.checkForFreeStock = false;
        this.product = null;
        
        this.addToCartValidatingEventHandlers = new Array();
    },
    
    getId : function() {
        return this.id;
    },
    
    setProduct : function(product) {
        if(product) {
            this.product = product;
            this.toggleVisibility();
            
            if(this.product.getItemType() == 'Matrix Group') {
                this.product.addInterChangeEventHandler(this.toggleVisibility.bind(this));
            }
        }
        else {
            aspdnsf.Products.ProductController.addObserver(this);
        }
    },
    
    toggleVisibility : function() {
        if(this.product.getShowBuyButton()) {
            this.pnlAddToCart.show();
        }
        else {
            this.pnlAddToCart.hide();
        }
    },
    
    notify : function(product) {
        if(product.getId() == this.id) {
            this.setProduct(product);
        }
    },
    
    addAddToCartValidatingEventHandler : function(handler) {
        this.addToCartValidatingEventHandlers.push(handler);
    },
    
    onAddToCartValidating : function(cancelEventArgs) {
        
        for(var ctr=0; ctr<this.addToCartValidatingEventHandlers.length; ctr++) {
            var cancelEventHandler = this.addToCartValidatingEventHandlers[ctr];
            cancelEventHandler(cancelEventArgs);
            if(cancelEventArgs.cancel) {
                return true;
            }
        }
        
        return false;
    },    
    
    setCheckForFreeStock : function(check) {
        this.checkForFreeStock = check;
    },
    
    onAddToCartClick : function() {
        if(this.validate()) {
            return this.doSubmit();
        }
        else {
            return false;
        }
    },
    
    onAddToWishListClick : function() {
        if(this.validate()) {
            $('IsWishList_' + this.id).value = 1;
            
            return this.doSubmit();
        }
        else {
            return false;
        }
    },
    
    setQuantityControl : function(control) {
        this.ctrlQuantity = control;
    },
    
    validate : function() {
        if(null == this.product) {
            alert(aspdnsf.StringResource.getString('is_showproduct.aspx.57'));
            return false;
        }
        
        // check for other handlers
        var cancelEventArgs = { cancel : false }
        this.onAddToCartValidating(cancelEventArgs);
        if(cancelEventArgs.cancel) {        
            return false;
        }
        
        if(this.product.getItemType() == 'Matrix Group' && !this.product.hasSelectedMatrixProduct()) {
            alert(aspdnsf.StringResource.getString('is_showproduct.aspx.48'));
            return false;
        }
        
        var quantity = this.ctrlQuantity.getValue();
        
        if(!quantity.match(/^\d+$/)) {
            alert(aspdnsf.StringResource.getString('common.cs.80'));
            return false;
        }        
        
        if(quantity == 0) {
            alert(aspdnsf.StringResource.getString('common.cs.84'));
            return false;
        }
        
        if(quantity < this.product.getMinimumOrderQuantity()) {
            alert(aspdnsf.StringResource.getString('is_showproduct.aspx.55') + this.product.getMinimumOrderQuantity());
            return false;
        }
        
        if(this.checkForFreeStock) {
        
            if( this.product.getItemType() == 'Stock' || 
                this.product.getItemType() == 'Matrix Group' || 
                this.product.getItemType() == 'Matrix Item' || 
                this.product.getItemType() == 'Assembly') {
            
                if(this.product.getFreeStock() <= 0) {
                    alert(aspdnsf.StringResource.getString('is_showproduct.aspx.49'));
                    return false;
                }
                
                if(this.product.getFreeStock() < quantity) { 
                    alert(aspdnsf.StringResource.getString('is_showproduct.aspx.61') + '   ' + this.product.getFreeStock());
                    return false;
                }            
            }
            else if(this.product.getItemType() == "Kit") {
                var allHasStock = true;
                
                for(var ctr=0; ctr<this.product.groups.length; ctr++) {
                    if(allHasStock) {
                        var group = this.product.groups[ctr];
                        var items = group.getSelectedItems();
                        
                        for(var ictr=0; ictr<items.length; ictr++) {
                            var item = items[ictr];
                            
                            if( item && 
                                (item.getItemType() == 'Stock' || item.getItemType() == 'Matrix Item' || item.getItemType() == 'Assembly')) {
                                if(item.getFreeStock() < quantity) { 
                                    allHasStock = false;
                                    break;
                                }
                            }
                        }
                    }
                }
                
                if(!allHasStock) {
                    alert(aspdnsf.StringResource.getString('is_showproduct.aspx.70'));
                    return false;
                }
            }            
            
        }
        
        if(this.product.getItemType() == "Kit") {
            this.product.persistComposition();
        }
        
        return true;
    },
        
    doSubmit : function() {
        if(this.product.getItemType() == 'Matrix Group' && this.product.hasSelectedMatrixProduct()) {
            $('ProductID_' + this.id).value = this.product.getId();
        }
        
        return true;
    }
    
}

aspdnsf.Products.AddToCartFormController = {
    
    initialize : function() {
        this.forms = new Hash();
        this.observers = new Array();
    },
    
    registerForm : function(form) {
        this.forms[form.getId()] = form;
        this.notifyObservers(form);
    },
    
    getForm : function(id) {
        return this.forms[id];
    },
    
    addObserver : function(observer) {
        this.observers.push(observer);
    },
    
    notifyObservers : function(form) {
        for(var ctr=0; ctr<this.observers.length; ctr++) {
            var observer = this.observers[ctr];
            observer.notify(form);
        }
    }

}

aspdnsf.Products.AddToCartFormController.initialize();

