﻿var _idReg = /([a-z]+)([\d]+)$/i;   //regex to parse the control's ID which should always end in the choiceID

function productChoiceManager(productString, showRealTimeSubtotal, showRealTimeAvailability, showUnitPrice, showChoiceItemPrice)
{
    //Initialize
    this.product = null;
    if (productString)
    {
        this.product = json_parse(productString);
    }
    this.orderItem = new orderItem();
    this.choiceControls = new Array();   //store all choice control ID's as they are registered
    this.selectedChoices = new Array();  //store array of the currently selected choices
    
    var _lineItemTemplateReg = /\[\[([^\]]+?)\]\]$/i;    //regex to parse the item details template for the line item template
    var _showChoiceItemPrice;
    var _webServiceProxy = new WebServices2();
    var _showRealTimeSubtotal = showRealTimeSubtotal;
    var _showRealTimeAvailability = showRealTimeAvailability;
    var _showUnitPrice = showUnitPrice;
    var _showChoiceItemPrice = showChoiceItemPrice;
    
    /*
    *  see http://javascript.crockford.com/private.html under the 'Private' section; seems to be a known issue
    *   with using 'this' within private methods
    */
    var _localThis = this;
    var _choiceCount = _localThis.product.choices.length;
    var _defaultCPPercent = 100;
    var _siteID = _localThis.product.siteID;
    
    updateChoiceControls = function()
    {
        var i, x;
        for(i=0;i<_localThis.product.choices.length;i++)
        {
            for(x=0;x<_localThis.choiceControls.length;x++)
            {
                if(_localThis.product.choices[i].ID == _localThis.choiceControls[x].choiceID)
                {
                    if (_localThis.choiceControls[x].updateChoiceItems)
                    {
                        if (_siteID == 2)
                        {
                            _defaultCPPercent = _localThis.product.voldisc[0].perc;
                        }


                        _localThis.choiceControls[x].updateChoiceItems(_localThis.product.choices[i].choiceItems, 
                            (_showChoiceItemPrice ? showChoiceItemPrice(_localThis.product.choices[i]): 0), 
                            getCurrentPrice(_localThis.choiceControls[x].choiceID), _localThis.savingsTemplate, _choiceCount, _defaultCPPercent, _siteID);
                    }
                    break;
                }
            }
        }
    }
    
    getCurrentPrice = function(choiceID, calculateVolDisc)
    {
        var currentPrice;
        var volDisc = 0;
        //TODO: SJB - re-activate
//        var keys;
//        
//        if (choiceID == -1)
//        {
//            keys = getSelectedInv();
//            
//            if(keys.length = 1)
//            {
//                currentPrice = keys[0].currentSKUPrice;
//            }
//            else
//            {
//                currentPrice = _localThis.product.basePrice;
//            }
//            
//        }
//        else
//        {
            currentPrice = _localThis.product.basePrice;
//        }
         
        if(_localThis.product.voldisc && calculateVolDisc)
        {
            var qty = getCurrentQty();
            var disc = 0;
            var volPrice = 0;
            for(x=0;x<_localThis.product.voldisc.length;x++)
            {
                if(parseInt(qty) < _localThis.product.voldisc[x].qty)
                {
                    break;
                }else{
                    disc = _localThis.product.voldisc[x].perc;
                }
            }
            if(disc > 0)
            {
                volPrice = ((1 - (disc / 100)) * currentPrice).toFixed(2);
                if(volPrice < currentPrice){volDisc = currentPrice - volPrice;}
                //TODO: SJB - re-activate
                //currentPrice = currentPrice - volDisc;

            }
        }
        
        //TODO: SJB - REMOVE
        currentPrice = currentPrice - volDisc;
        
        //TODO: SJB - REMOVE
        for(i=0;i<_localThis.selectedChoices.length;i++)
        {
            if(choiceID){
                if(_localThis.selectedChoices[i].choiceID != choiceID)
                {
                    currentPrice += _localThis.selectedChoices[i].priceAdjustment;
                }
            }else{
                currentPrice += _localThis.selectedChoices[i].priceAdjustment;
            }
        }
        
        if(!choiceID || choiceID <= 0)
        {
            for(i=0;i<_localThis.selectedChoices.length;i++)
            {
                if(_localThis.selectedChoices[i].discount != null)
                {
                    currentPrice = applyDiscount(_localThis.selectedChoices[i].discount, currentPrice);
                }
            }
        }
        return currentPrice;
    }
    
    getChoiceItemUnitPrice = function(choiceItem, startingPrice)
    {
        var basePrice;
        if(startingPrice)
        {
            basePrice = startingPrice;
        }
        else
        {
            basePrice = getCurrentPrice(choiceItem.choiceID, false);
        }
        basePrice += choiceItem.priceAdjustment;
        for(i=0;i<_localThis.selectedChoices.length;i++)
        {
            if(_localThis.selectedChoices[i].choiceID != choiceItem.choiceID)
            {
                if(_localThis.selectedChoices[i].discount != null)
                {
                    basePrice = applyDiscount(_localThis.selectedChoices[i].discount, basePrice);
                }
            }
        }
        if(choiceItem.discount != null)
        {
            basePrice = applyDiscount(choiceItem.discount, basePrice);
        }
        return basePrice;
    }
    
    applyDiscount = function(discount, price)
    {
        var discountedPrice = price;
        switch(discount.discType){
            case 1: //percentage
                discountedPrice -= (discountedPrice * (discount.discAmount / 100));
                break;
            case 2: //dollar amount
                discountedPrice -= discount.discAmount;
                break;
            default:
                break;
        }
        return discountedPrice;
    }
    
    getCurrentQty = function()
    {
        var qtyControl = document.getElementById(_localThis.quantityElementID);
        
        return qtyControl.value;
    }
    updatePriceAdjustmentNote = function(display)
    {
        if(_localThis.priceAdjustNoteElementID)
        {
            var e = $get(_localThis.priceAdjustNoteElementID);
            if(e)
            {
                if(display)
                {
                    e.className = 'price_adjustment_note';
                }else{
                    e.className = 'price_adjustment_note_nonvisible';
                }
            }
        }
    }
    //inserts new choice item selection, or updates existing choice item selection
    this.choiceSelected = function(choiceID, choiceItemID)
    {
        var found = 0;
        var i, x, j;
        var choiceItem;
        updatePriceAdjustmentNote(false);
        
        if(choiceItemID == -1)
        {
            for(i = 0; i < _localThis.selectedChoices.length; i++)
            {
                if(_localThis.selectedChoices[i].choiceID == choiceID)
                {
                    _localThis.selectedChoices.splice(i, 1);   //remove from selectedChoices arr
                    break;
                }
            }
        }
        else
        {
            for(x=0;x<_localThis.product.choices.length;x++)
            {
                if(_localThis.product.choices[x].ID == choiceID)
                {
                    for(j=0;j<_localThis.product.choices[x].choiceItems.length;j++)
                    {
                        if(_localThis.product.choices[x].choiceItems[j].ID == choiceItemID)
                        {
                            choiceItem = _localThis.product.choices[x].choiceItems[j];
                            break;
                        }
                    }
                }
                if(choiceItem != undefined){break;}
            }
            //if user just changed their selection, then update existing index
            for(i = 0; i < _localThis.selectedChoices.length; i++)
            {
                if(_localThis.selectedChoices[i].choiceID == choiceID)
                {
                    _localThis.selectedChoices[i] = choiceItem;
                    found = 1;
                    break;
                }//end if - selectedchoice.choiceID
            }//end for
            if (found == 0)
            {
                _localThis.selectedChoices.push(choiceItem);
                _localThis.selectedChoices.sort(sortChoices);
                
            }//end found == 0
        }        
        _localThis.updateChoiceAvailability();
    }//selectedChoice
    //Sorts choiceItems based upon the choiceItem's choiceSortOrder
    sortChoices = function(choiceItemA, choiceItemB)
    {
        return choiceItemA.choiceSortOrder == choiceItemB.choiceSortOrder ? 0 : 
            choiceItemA.choiceSortOrder > choiceItemB.choiceSortOrder ? 1 : -1;
    }
    //determines if the choiceItem prices should be shown for 'choice'
    showChoiceItemPrice = function(choice)
    {
        var choiceWithAdjustments = 0;
        var choiceWithAdjustmentMade = 0;
        var choiceItemWithAdjustments = 0;
        var choiceItemWithAdjustmentMade = 0;
        var choiceSelected = 2;
        var i,x,n;            
        var basePrice = getCurrentPrice(choice.ID, false);
        var currentChoiceHasAdjustment = false;
        var showPriceAdjustmentNote = false;
        for(i=0;i<_localThis.product.choices.length;i++)
        {
            choiceItemWithAdjustments = 0;
            choiceItemWithAdjustmentMade= 0;
            for(n=0;n<_localThis.product.choices[i].choiceItems.length;n++)
            {
                if(_localThis.product.choices[i].choiceItems[n].priceAdjustment != 0)
                {
                    choiceItemWithAdjustments++;
                    if(choice.ID == _localThis.product.choices[i].ID){choiceSelected = 0;}
                    for(x=0;x<_localThis.selectedChoices.length;x++)
                    {
                        if(_localThis.selectedChoices[x].choiceID == _localThis.product.choices[i].ID)
                        {
                            if(choice.ID == _localThis.selectedChoices[x].choiceID){choiceSelected = 1;}
                            choiceItemWithAdjustmentMade++;
                            break;
                        }
                    }
                }
                _localThis.product.choices[i].choiceItems[n].unitPrice = getChoiceItemUnitPrice(
                    _localThis.product.choices[i].choiceItems[n], basePrice);
                if(choice.ID == _localThis.product.choices[i].ID)
                {
                    if(!currentChoiceHasAdjustment)
                    {
                        currentChoiceHasAdjustment = choiceItemHasAdjustmentOrDiscount(_localThis.product.choices[i].choiceItems[n]);
                    }
                    _localThis.product.choices[i].choiceItems[n].showAdjustmentIndicator = 
                        (_localThis.product.choices[i].choiceItems[n].unitPrice != _localThis.product.basePrice);
                }
                if( _localThis.product.choices[i].choiceItems[n].showAdjustmentIndicator){showPriceAdjustmentNote = true;}
            }
            if(choiceItemWithAdjustments > 0){choiceWithAdjustments++;}
            if(choiceItemWithAdjustmentMade > 0){choiceWithAdjustmentMade++;}
        }
        if(!currentChoiceHasAdjustment)
        {
            return 0;
        }
        else if((_localThis.product.choices.length == 1) || (_localThis.product.choices.length == _localThis.selectedChoices.length))
        {
            if(showPriceAdjustmentNote){updatePriceAdjustmentNote(true)};
            return 1; //only have 1 choice, or all choices made
        }
        else if(choiceWithAdjustments == choiceWithAdjustmentMade)
        {
            if(showPriceAdjustmentNote){updatePriceAdjustmentNote(true)};
            return 1; //more than 1 choice, but all choices with adjustments have been made
        }
        else if(((choiceWithAdjustments - choiceWithAdjustmentMade) == 1) && (choiceSelected == 0))
        {
            if(showPriceAdjustmentNote){updatePriceAdjustmentNote(true)};
            return 1;
        }
        else
        {
            return 0;
        }
    }
    
    choiceItemHasAdjustmentOrDiscount = function(choiceItem)
    {
        return (choiceItem.priceAdjustment != 0 || (choiceItem.discount && choiceItem.discount.discAmount != 0))
    }
    
    this.updateChoiceAvailability = function()
    {
        var activeChoiceItems = new Array();
        var i, x;
        
        for(i=0;i<_localThis.product.choices.length;i++)
        {
            if(_localThis.product.choices[i].typeCode == 2 || _localThis.product.choices[i].typeCode == 8)
            {
                for(x=0;x<_localThis.product.choices[i].choiceItems.length;x++)
                {
                    _localThis.product.choices[i].choiceItems[x].available = 
                        isChoiceItemAvailable(_localThis.product.choices[i].ID, _localThis.product.choices[i].choiceItems[x].ID);

                }
            }
        }
        updateChoiceControls();
        updateItemDetails();
    }
            
    isChoiceItemAvailable = function(choiceID, choiceItemID)
    {
        var invKeys = new Array();
        //get all inventory keys for choice item
        invKeys = getInventoryKeysForChoiceItem(choiceID, choiceItemID);
        for(var i = 0;i<invKeys.length;i++)
        {
            if(invKeys[i].available){return 1};//if any are available, then choice item must be available
        }
        return 0;
    }
    
    getInventoryKeysForChoiceItem = function(choiceID, currentChoiceItemID)
    {
        var invKeys = new Array();
        var i;
        
        for(i=0;i<_localThis.product.inventoryKeys.length;i++)
        {
            if(_localThis.product.inventoryKeys[i].inventoryKey.indexOf(currentChoiceItemID) >= 0)
            {
                if(_localThis.orderItem && _localThis.orderItem.transientItem && 
                    _localThis.orderItem.key == _localThis.product.inventoryKeys[i].inventoryKey)
                {
                    _localThis.product.inventoryKeys[i].available = 1;
                    invKeys.push(_localThis.product.inventoryKeys[i]);
                }
                else if(choiceItemInventoryKeySelectedChoice(0, _localThis.product.inventoryKeys[i].inventoryKey, choiceID))
                {
                    invKeys.push(_localThis.product.inventoryKeys[i]);
                }
            }//end inventoryKey.indexOf()
        }
        return invKeys;
    }
    
    /*
    *   Determines if the inventory key contains the choice items that have already been selected; recursively calls itself
    *   looping through each selected choice
    */
    choiceItemInventoryKeySelectedChoice = function(selectedChoiceIndex, inventoryKey, choiceID)
    {
        if(_localThis.selectedChoices.length > 0)
        {
            if((choiceID == -1) || _localThis.selectedChoices[selectedChoiceIndex].choiceID != choiceID)
            {
                if(inventoryKey.indexOf(_localThis.selectedChoices[selectedChoiceIndex].ID) < 0)
                {
                    return 0;
                }
                else if(selectedChoiceIndex == (_localThis.selectedChoices.length - 1))
                {
                    return 1;
                }
                else
                {
                    selectedChoiceIndex++;
                    return choiceItemInventoryKeySelectedChoice(selectedChoiceIndex, inventoryKey, choiceID);
                }
            }
            else if(selectedChoiceIndex < (_localThis.selectedChoices.length - 1))
            {
                selectedChoiceIndex++;
                return choiceItemInventoryKeySelectedChoice(selectedChoiceIndex, inventoryKey, choiceID);
            }
            else{return 1;}
        }else{return 1;}
    }
    
    /*
    *   Selected choice details methods
    */
    updateItemDetails = function()
    {
        var availabilityElement = document.getElementById(_localThis.availabilityElementID);
        if(availabilityElement != null)
        {
            availabilityElement.innerHTML = '';
        }
        var subtotalElement = $get(_localThis.itemSubtotalElementID);
        if(subtotalElement)
        {
            subtotalElement.innerHTML = '';
        }
        
        if(_localThis.selectedChoices.length == 0 && _localThis.product.choices.length > 0) //no selected choices, but product has choices
        {
            if (_localThis.itemDetailsElementID != null)
            {
                var detailElement = document.getElementById(_localThis.itemDetailsElementID);
                                
                if(detailElement != null)
                {
                    detailElement.innerHTML = '';
                }
            }
        }
        else
        {
            var template;
            var itemDetails = new StringBuilder();
            if (_localThis.product && _localThis.itemDetailsElementID && _localThis.itemDetailsTemplate)
            {
                lineItemTemplate = _lineItemTemplateReg.exec(_localThis.itemDetailsTemplate)[1];
                itemDetails.append(_localThis.itemDetailsTemplate.substr(0, (_localThis.itemDetailsTemplate.length - (lineItemTemplate.length + 4))));
                itemDetails.append(updateChoiceDetail(lineItemTemplate));
                if(getSelectedInv().length == 1)
                {
                    if(_showUnitPrice){itemDetails.append(getSKUPrice(lineItemTemplate));}
                    itemDetails.append(getQuantity(lineItemTemplate));
                    updateAvailability();
                    _localThis.updateSubtotal();
                }
                                
                var detailElement = document.getElementById(_localThis.itemDetailsElementID);
                if(detailElement != null)
                {
                    detailElement.innerHTML = itemDetails.toString();
                }
            }//end null check
        }
    }
    
    getSelectedInv = function()
    {
        var invKeys = new Array();
        
        for(x=0;x<_localThis.product.inventoryKeys.length;x++)
        {
            if(choiceItemInventoryKeySelectedChoice(0, _localThis.product.inventoryKeys[x].inventoryKey, -1))
            {
                invKeys.push(_localThis.product.inventoryKeys[x]);
            }
        }
        return invKeys;
    }
      
    getSKUPrice = function(itemTemplate)
    {
        var currentPrice = getCurrentPrice(-1, true);
        
        itemTemplate = itemTemplate.replace(/{key}/i, 'Price: $');
        itemTemplate = itemTemplate.replace(/{value}/i, currentPrice.toFixed(2) + ' each');
        
        return itemTemplate;
    }
    
    getQuantity = function(itemTemplate)
    {
        itemTemplate = itemTemplate.replace(/{key}/i, 'Quantity: ');
        var qty = getCurrentQty();
        if(isNaN(qty))
        {
            itemTemplate = itemTemplate.replace(/{value}/i, 'N/A');
        }else{
            itemTemplate = itemTemplate.replace(/{value}/i, qty);
        }        
        
        
        return itemTemplate;
    }
    
    updateChoiceDetail = function(template)
    {
        var detail = new StringBuilder();
        var tempTemplate;
        var i, x;
        
        for(x = 0; x < _localThis.selectedChoices.length; x++)
        {
            for(i = 0; i < _localThis.product.choices.length; i++)
            {
                if(_localThis.product.choices[i].ID == _localThis.selectedChoices[x].choiceID)
                {
                    var value = '';                    
                    if(_localThis.selectedChoices[x].imageURL)
                    {
                        value = '<img src="' + _localThis.selectedChoices[x].imageURL + '" />&nbsp;';
                    }
                    value += trimString ? trimString(_localThis.selectedChoices[x].name, _localThis.maxChoiceItemLength): _localThis.selectedChoices[x].name;
                    tempTemplate = template;
                    
                    tempTemplate = tempTemplate.replace(/{key}/i, _localThis.product.choices[i].name + ': ');
                    detail.append(tempTemplate.replace(/{value}/i, value));
                    break;
                }
            }
        }
        return detail.toString();
    }//updateChoices
    /*
    *   END Selected choice details methods
    */
    
    /*
    *   Availability Methods
    */
    updateAvailability = function()
    {
        var keys, inv, qty, pID, oid;
        
        if(!_showRealTimeAvailability){return;}
        
        keys = getSelectedInv();
        if(keys.length != 1)
        {
            return;
        }
        inv = keys[0].ID;
        qty = parseInt(document.getElementById(_localThis.quantityElementID).value);
        try
        {
            var availabilityElement = $get(_localThis.availabilityElementID);
            availabilityElement.innerHTML = '<font style="color: red;">Calculating Availability...</font>';
            WebServices2.GetEstimatedAvailability(inv, qty, _localThis.product.ID, _localThis.orderItem.ID, onAvailabilitySuccess, OnAvailabilityFailed);
        }
        catch (err)
        {
            alert('We were not able to determine the availability of your selection.  Please add the item to your cart, and proceed to the checkout to see the availability.');
            var availabilityElement = $get(_localThis.availabilityElementID);
            availabilityElement.innerHTML = '';
        }//end try
    }
    
    onAvailabilitySuccess = function(result, userContext, methodName)
    {
        var availability = new String(result).split('|');
        
        if(availability)
        {
            var availabilityElement = $get(_localThis.availabilityElementID);
            if(availabilityElement != null)
            {
                availabilityElement.innerHTML = availability[0];
            }
            
            var quantity = $get(_localThis.quantityElementID);
            if(quantity != null)
            {
                if(parseInt(availability[1]) == 0)
                {
                    if(parseInt(availability[2]) <= 0)
                    {
                        //inv key is not available, now or in the future, remove all selected choices and reset all choice controls
                        var keys = getSelectedInv();
                        if(keys.length != 1)
                        {
                            return;
                        }
                        keys[0].available = 0;
                        for(x=0;x<_localThis.choiceControls.length;x++)
                        {
                            if (_localThis.choiceControls[x].deselect)
                            {
                                _localThis.choiceControls[x].deselect();
                            }
                        }
                        _localThis.selectedChoices.splice(0, _localThis.selectedChoices.length);
                        _localThis.updateChoiceAvailability();
                    }
                    else if(parseInt(quantity.value) > parseInt(availability[2]))
                    {
                        //we have less than customer requested - reduct quantity
                        quantity.value = availability[2];
                        _localThis.updateSubtotal();
                    }
                }
            }
        }
    }
    
    OnAvailabilityFailed = function(error, userContext, methodName)
    {
        if(error !== null) 
        {
            var availabilityElement = $get(_localThis.availabilityElementID);
            if(availabilityElement != null)
            {
                availabilityElement.innerHTML = 'Add item to cart, then view your shopping bag to see availability.';
            }
        }
    }
    
    /*
        Subtotal
    */
    var _subtotalRequest;
    this.updateSubtotal = function()
    {
        if(!_showRealTimeSubtotal){return;}
        
        var keys, inv, qty, pID, oid;
        
        keys = getSelectedInv();
        if(keys.length != 1)
        {
            return;
        }
        
        inv = keys[0].ID;
        qty = parseInt(document.getElementById(_localThis.quantityElementID).value);
        
        try
        {
            if(_subtotalRequest)
            {
                //abort current request - when quantity changes, availability could alter the quantity
                var executor = _subtotalRequest.get_executor();
                if(executor.get_started())
                {
                    executor.abort();
                }
            }
            _subtotalRequest = _webServiceProxy.GetOrderItemSubtotal(inv, qty, _localThis.product.ID, _localThis.orderItem.ID, onSubtotalSuccess, OnSubtotalFailed);
        }
        catch (err)
        {
            alert('We were not able to determine the subtotal of your selection.  Please add the item to your cart, and proceed to the checkout to see the availability.');
            
        }//end try        
    }
    
    onSubtotalSuccess = function(result, userContext, methodName)
    {
        var subtotalElement = $get(_localThis.itemSubtotalElementID);
        if(subtotalElement)
        {
            subtotalElement.innerHTML = result;
        }
    }
    
    OnSubtotalFailed = function(error, userContext, methodName)
    {
        if(_subtotalRequest && _subtotalRequest.get_executor().get_aborted())
        {
            return 0;
        }
        else if(error !== null) 
        {
            var subtotalElement = $get(_localThis.itemSubtotalElementID);
            if(subtotalElement)
            {
                subtotalElement.innerHTML = '';
            }
        }
        return;
    }
    /*
    *   END subtotal Methods
    */
    
}//end ProductChoiceManager

/*
*   ProductChoiceManager.Prototype attributes
*/
productChoiceManager.prototype.itemDetailsElementID = null;
productChoiceManager.prototype.itemDetailsTemplate = null;
productChoiceManager.prototype.quantityElementID = null;
productChoiceManager.prototype.availabilityElementID = null;
productChoiceManager.prototype.loadingPanelID = null;
productChoiceManager.prototype.loadingPanelFocusElementID = null;
productChoiceManager.prototype.itemSubtotalElementID = null;
productChoiceManager.prototype.savingsTemplate = null;
productChoiceManager.prototype.maxChoiceItemLength = null;
productChoiceManager.prototype.priceAdjustNoteElementID = null;

productChoiceManager.prototype.registerProductChoiceDropdownControl = function(choiceControl)
{
    if(this.product)
    {
        this.choiceControls.push(new ASPNETInputElementDropdownControl(_idReg.exec(choiceControl.id)[2], 
            this.choiceSelected, this, choiceControl.id));
    }
}

productChoiceManager.prototype.registerProductChoiceControl = function(choiceControl)
{
    if(this.product)
    {
        this.choiceControls.push(new ASPNETInputElementListControl(_idReg.exec(choiceControl.id)[2], 
            this.choiceSelected, this, choiceControl.id));
    }
}

productChoiceManager.prototype.registerTelerikProductChoiceControl = function(choiceControl)
{
    if(this.product)
    {
        this.choiceControls.push(new ProductChoiceTelerikControlHandler(_idReg.exec(choiceControl.get_id())[2], 
            this.choiceSelected, this, choiceControl.get_id()));
    }
}

productChoiceManager.prototype.registerQuantityControl = function(qtyElementID)
{
    if(qtyElementID)
    {
        this.quantityElementID = qtyElementID;
        var qtyControl = document.getElementById(this.quantityElementID);
        EventUtil.addEventHandler(qtyControl, 'change', this.onQuantityUpdated);
    } 
}

productChoiceManager.prototype.onQuantityUpdated = function(e)
{
    var eSource = ((e.srcElement != null) ? e.srcElement: e.target);
    
    if(eSource != null)
    {
        if(eSource.value == '' || isNaN(eSource.value))
        {
            return 0;
        }
        updateItemDetails();
    }
}

productChoiceManager.prototype.showLoadingPanel = function()
{
    if(this.loadingPanelID && this.loadingPanelFocusElementID)
    {
        var loadingPanel = $find(this.loadingPanelID);
        var focusElement = $get(this.loadingPanelFocusElementID);
        if(loadingPanel && focusElement)
        {
            if(centerElementOverFocusElement)
            {
                centerElementOverFocusElement(loadingPanel, focusElement);
                loadingPanel = $find(this.loadingPanelID);
                loadingPanel.show(focusElement.id);
            }
        }
    }   
}

productChoiceManager.prototype.hideLoadingPanel = function()
{
    if(this.loadingPanelID && this.loadingPanelFocusElementID)
    {
        var loadingPanel = $find(this.loadingPanelID);
        var focusElement = $get(this.loadingPanelFocusElementID);
        if(loadingPanel)
        {
            loadingPanel.hide(this.loadingPanelFocusElementID);
        }
    }
}
    
/*
*   Order Item class
*/
function orderItem(id, orderid, inventorykey, transientitem, productID)
{
    this.ID = id;
    this.OID = orderid;
    this.key = inventorykey;
    this.transientItem = transientitem;
    this.productID = productID;
    this.productmgr = null;
    
    var _localThis = this;
    
    UpdatePersonalizationDetails_Success = function(result, userContext)
    {
        if(_localThis.productmgr){_localThis.productmgr.hideLoadingPanel();}
        if(_localThis.personalizationDetailElementID)
        {
            var el = $get(_localThis.personalizationDetailElementID);
            if(el)
            {
                el.innerHTML = result;
                try
                {
                    if(_localThis.personalizationButtons)
                    {
                        var methods = _localThis.personalizationButtons.split(';');
                        for(var i=0;i<methods.length;i++)
                        {
                            //update the add vs update button images
                            var props = methods[i].split(',');
                            if(props[0] == userContext)
                            {
                                var link = $get(props[1]);
                                if(link)
                                {
                                    var img = link.getElementsByTagName('img');
                                    var index = (result == ''? 2 : 3);
                                    if(img && img.length > 0){img[0].src = props[index];}
                                }
                            }
                        }
                    }
                }catch(e){}
            }
        }
    }
    
    UpdatePersonalizationDetails_Failure = function(result, userContext)
    {
        if(_localThis.productmgr){_localThis.productmgr.hideLoadingPanel();}
        if(_localThis.personalizationDetailElementID)
        {
            var el = $get(_localThis.personalizationDetailElementID);
            if(el)
            {
                el.innerHTML = 'Add item to cart, then view cart to see personalization.';
            }
        }
    }
    
    RemovePersonalizationDetails_Success = function(result, userContext)
    {
        _localThis.productmgr.hideLoadingPanel();
        if(_localThis.personalizationDetailElementID)
        {
            var el = $get(_localThis.personalizationDetailElementID);
            if(el)
            {
                el.innerHTML = result;
                try
                {
                    if(_localThis.personalizationButtons)
                    {
                        var methods = _localThis.personalizationButtons.split(';');
                        for(var i=0;i<methods.length;i++)
                        {
                            //update the add vs update button images
                            var props = methods[i].split(',');
                            if(props[0] = userContext)
                            {
                                var link = $get(props[1]);
                                if(link)
                                {
                                    var img = link.getElementsByTagName('img');
                                    if(img && img.length > 0){img[0].src = props[2];}
                                }
                            }
                        }
                    }
                }catch(e){}                
            }
        }
    }
    
    RemovePersonalizationDetails_Failure = function(result, userContext)
    {
        _localThis.productmgr.hideLoadingPanel();
        if(_localThis.personalizationDetailElementID)
        {
            var el = $get(_localThis.personalizationDetailElementID);
            if(el)
            {
                el.innerHTML = '';
            }
        }
    }
    
    setupShadowbox = function(link)
    {
        if(Shadowbox)
        {
            Shadowbox.setup(link);
        }
    }
}

orderItem.prototype.personalizationDetailElementID = null;
orderItem.prototype.personalizationButtons = null;

orderItem.prototype.personalizationDetailsUpdated = function(personalizationMethodID)
{
    WebServices2.GetPersonalizationDetails(this.ID, personalizationMethodID, this.productmgr.product.ID, new Boolean(this.transientItem), UpdatePersonalizationDetails_Success, UpdatePersonalizationDetails_Failure, personalizationMethodID);
    if(this.productmgr){this.productmgr.showLoadingPanel();}
}

orderItem.prototype.removePersonalizationDetails = function(personalizationMethodID)
{
    if(confirm('Are you sure you want to delete the personalization?'))
    {
        WebServices2.RemovePersonalizationDetails(this.ID, personalizationMethodID, this.productmgr.product.ID, new Boolean(this.transientItem), RemovePersonalizationDetails_Success, RemovePersonalizationDetails_Failure, personalizationMethodID);
        if(this.productmgr){this.productmgr.showLoadingPanel();}
    }
}

/*
*   Telerik combo box control handler
*/
function ProductChoiceTelerikControlHandler(productChoiceID, choiceSelectedHandler, choiceSelectedHandlerObject, telerikChoiceControlID)
{
    this.choiceID = productChoiceID;
    this.onChoiceSelectedHandler = choiceSelectedHandler;
    this.choiceControlID = telerikChoiceControlID;
    this.choiceSelectedHandlerObj = choiceSelectedHandlerObject;
    var _localThis = this;
    
    this.initializeTelerikChoice = function(choiceControl)
    {
        choiceControl.add_selectedIndexChanged(_localThis.telerikChoiceChanged);
        if (choiceControl != null && (choiceControl.get_selectedItem().get_value() != -1))
        {
            var items = choiceControl.get_items();
            for(x=0;x<items.get_count();x++)
            {
                if(items.getItem(x).get_value() == choiceControl.get_selectedItem().get_value())
                {
                    _localThis.onChoiceSelected(_idReg.exec(choiceControl.get_id())[2], items.getItem(x).get_value());
                    break;
                }
            }
        }
    }
    
    this.telerikChoiceChanged = function(sender, eventargs)
    {
        _localThis.onChoiceSelected(_idReg.exec(sender.get_id())[2], sender.get_selectedItem().get_value());
    }
    
    this.onChoiceSelected = function(id, selectedValue)
    {
        //call method on choiceSelectedHandlerObj (i.e. productChoiceMgr instance)
        _localThis.onChoiceSelectedHandler.apply(this.choiceSelectedHandlerObj, arguments);
    }
    
    this.initializeTelerikChoice($find(this.choiceControlID));
}

ProductChoiceTelerikControlHandler.prototype.updateChoiceItems = function(choiceItems, showChoiceItemPrice, currentBasePrice, savingsTemplate, choiceCount, defaultCPPercent, siteID)
{
    var control = $find(this.choiceControlID);
    var items = control.get_items();
    var i, x, n;
    
    for(x=0;x<choiceItems.length;x++)
    {
        for(i=0;i<items.get_count();i++)
        {   
            if(items.getItem(i).get_value() == choiceItems[x].ID)
            {
                var label = document.getElementById(items.getItem(i).get_attributes().getAttribute('priceLabelID'));
                if(label != null)
                {
                    label.innerHTML = '';
                }

                if(choiceItems[x].available)
                {
                    items.getItem(i).enable();
                    if(showChoiceItemPrice == 1)
                    {
                        if(label != null)
                        {
                            var itemPrice;
                            var priceToShow;
                            
                            if (siteID == 1)
                            {
                                //TODO: SJB - comment out
                                priceToShow = choiceItems[x].unitPrice;
                                
                                //TODO: SJB - re-activate
                                //priceToShow = choiceItems[x].currentSKUPrice;
                            }
                            if (siteID == 2)
                            {
                                //If CP Site then show lowest qty. Vol. Discount price
                                priceToShow = currentBasePrice - (currentBasePrice * (defaultCPPercent / 100)) + choiceItems[x].priceAdjustment;
                            }
                                
                            itemPrice = '<span class="ChoiceItemPrice">$' + priceToShow.toFixed(2) + 
                            (choiceItems[x].showAdjustmentIndicator ? '*': '') + '</span>';
   
                            if(choiceItems[x].discount && savingsTemplate && savingsTemplate != '')
                            {
                                var dollarAmt = 0;
                                var percAmt = 0;
                                //TODO: SJB - comment out
                                dollarAmt = (currentBasePrice + choiceItems[x].priceAdjustment) - choiceItems[x].unitPrice;
                                percAmt = (1 - (choiceItems[x].unitPrice / (currentBasePrice + choiceItems[x].priceAdjustment))) * 100;
                                
                                //TODO: SJB - re-activate
//                                dollarAmt = priceToShow;
//                                percAmt = (1 - priceToShow) * 100;
                                savingsTemplate = savingsTemplate.replace(/\[\[dollaramt\]\]/i, '$' + dollarAmt.toFixed(2));
                                savingsTemplate = savingsTemplate.replace(/\[\[percentamt\]\]/i, percAmt.toFixed(0) + '%');
                                itemPrice += '&nbsp;<span class="ChoiceItemDiscountSavings">' + savingsTemplate + '</span>';
                            }
                            label.innerHTML = itemPrice;
                        }
                    }
                }
                else
                {
                    items.getItem(i).disable();
                    if(control.get_selectedItem().get_value() == items.getItem(i).get_value())
                    {
                        for(n=0;n<items.get_count();n++)
                        {
                            if(items.getItem(n).get_value() == -1)
                            {
                                items.getItem(n).select();
                                break;
                            }
                        }
                        this.onChoiceSelected(this.choiceID, -1);
                    }
                }
                break;
            }       
        }
    }
}

ProductChoiceTelerikControlHandler.prototype.deselect = function()
{
    var control = $find(this.choiceControlID);
    var items = control.get_items();
    var n;
    
    for(n=0;n<items.get_count();n++)
    {
        if(items.getItem(n).get_value() == -1)
        {
            items.getItem(n).select();
            break;
        }
    }
}

/*
*   ASP.Net input list control - handles dropdown list
*   NOTE: inputElementID should represent the HTML table that MS builds for checkbox and radio button lists
*/
function ASPNETInputElementListControl(productChoiceID, choiceSelectedHandler, choiceSelectedHandlerObject, inputElementID)
{
    this.choiceID = productChoiceID;
    this.onChoiceSelectedHandler = choiceSelectedHandler;
    this.choiceControlID = inputElementID;
    this.choiceSelectedHandlerObj = choiceSelectedHandlerObject;
    var _localThis = this;

    this.initializeListChoice = function(choiceControl)
    {
        //get all input elements that are children of this.choiceControlID
        var elements = choiceControl.getElementsByTagName('input');
        var i;
            
        if (elements)

        {
            //iterate over all child elements
            for(i=0;i<elements.length;i++)
            {
                //add click handler that should call method in this class
                $addHandler(elements[i], 'click', _localThis.listTypeChoiceChanged);
                
                //check to see if this item was pre-selected b/c of editing an order item    
                if(elements[i].checked)
                {
                    _localThis.onChoiceSelected(_localThis.choiceID, elements[i].value);
                }
            }
        }

    }
    
    this.listTypeChoiceChanged = function(e)
    {
        var eSource = ((e.srcElement != null) ? e.srcElement: e.target);
        _localThis.onChoiceSelected(_localThis.choiceID, eSource.value);
    }
    
    this.onChoiceSelected = function(id, selectedValue)
    {
        //call method on choiceSelectedHandlerObj (i.e. productChoiceMgr instance)
        _localThis.onChoiceSelectedHandler.apply(this.choiceSelectedHandlerObj, arguments);
    }
    
    this.initializeListChoice($get(this.choiceControlID));
}

ASPNETInputElementListControl.prototype.updateChoiceItems = function(choiceItems, showChoiceItemPrice, currentBasePrice, savingsTemplate, choiceCount, defaultCPPercent, siteID)
{
    var control = $get(this.choiceControlID);
    var items = control.getElementsByTagName('input');
    var i, x, n;

    for(x=0;x<choiceItems.length;x++)
    {
        for(i=0;i<items.length;i++)
        {   
            if(items[i].value == choiceItems[x].ID)
            {
                var label = items[i].parentNode.getElementsByTagName('label');
                if(label && label.length > 1)
                {
                    label[1].innerHTML = '';
                }

                if(choiceItems[x].available)
                {
                    if(label && label.length > 0){label[0].className = '';}
                    items[i].disabled = false;
                    if(showChoiceItemPrice == 1)
                    {
                        if(label && label.length > 1)
                        {
                            var itemPrice;
                            var priceToShow;
                            
                            if (siteID == 1)
                            {
                                //TODO: SJB - comment out
                                priceToShow = choiceItems[x].unitPrice;
                                
                                //TODO: SJB - re-activate
                                //priceToShow = choiceItems[x].currentSKUPrice;
                            }
                            if (siteID == 2)
                            {
                                //If CP Site then show lowest qty. Vol. Discount price
                                priceToShow = currentBasePrice - (currentBasePrice * (defaultCPPercent / 100)) + choiceItems[x].priceAdjustment;
                            }
                                
                            itemPrice = '<span class="ChoiceItemPrice">$' + priceToShow.toFixed(2) + 
                            (choiceItems[x].showAdjustmentIndicator ? '*': '') + '</span>';
                            
                            if(choiceItems[x].discount && savingsTemplate && savingsTemplate != '')
                            {
                                var dollarAmt = 0;
                                var percAmt = 0;
                                //TODO: SJB - comment out
                                dollarAmt = (currentBasePrice + choiceItems[x].priceAdjustment) - choiceItems[x].unitPrice;
                                percAmt = (1 - (choiceItems[x].unitPrice / (currentBasePrice + choiceItems[x].priceAdjustment))) * 100;
                                
                                //TODO: SJB - re-activate
//                                dollarAmt = priceToShow;
//                                percAmt = (1 - priceToShow) * 100;
                                savingsTemplate = savingsTemplate.replace(/\[\[dollaramt\]\]/i, '$' + dollarAmt.toFixed(2));
                                savingsTemplate = savingsTemplate.replace(/\[\[percentamt\]\]/i, percAmt.toFixed(0) + '%');
                                itemPrice += '&nbsp;<span class="ChoiceItemDiscountSavings">' + savingsTemplate + '</span>';
                            }
                            label[1].innerHTML = itemPrice;
                        }
                    }
                }
                else
                {
                    if(label && label.length > 0){label[0].className = 'ChoiceItemDisabled';}
                    items[i].disabled = true;
                    var checked = items[i].checked;
                    items[i].checked = false;
                    if(checked){this.onChoiceSelected(this.choiceID, -1);}
                }
                break;
            }       
        }
    }
}

ASPNETInputElementListControl.prototype.deselect = function()
{
    var control = $get(this.choiceControlID);
    var items = control.getElementsByTagName('input');
    var i, x, n;
    
    for(i=0;i<items.length;i++)
    {   
        items[i].checked = false
    }
}


/*
*   ASP.Net input list control - handles drpodown list
*/
function ASPNETInputElementDropdownControl(productChoiceID, choiceSelectedHandler, choiceSelectedHandlerObject, inputElementID)
{
    this.choiceID = productChoiceID;
    this.onChoiceSelectedHandler = choiceSelectedHandler;
    this.choiceControlID = inputElementID;
    this.choiceSelectedHandlerObj = choiceSelectedHandlerObject;
    var _localThis = this;
    //var _showChoiceItemPrice = showChoiceItemPrice;
    
//    if (document.getElementsByTagName) { 
//        var s = document.getElementsByTagName("select"); 
//            if (s.length > 0) { 
//            window.select_current = new Array(); 
//            for (var i=0, select; select = s[i]; i++) { 
//            select.onfocus = function(){ window.select_current[this.id] = this.selectedIndex; } 
//            select.onchange = function(){ restore(this); } 
//            emulate(select); 
//            } 
//        } 
//    }           
    this.initializeListChoice = function(choiceControl)
    {
        //get all input elements that are children of this.choiceControlID
        var elements = document.getElementById(this.choiceControlID);

            if (elements.length > 0)
            {
                $addHandler(elements, 'change', _localThis.listTypeChoiceChanged);            
            }
    }
    
    this.listTypeChoiceChanged = function(e)
    {
        var eSource = ((e.srcElement != null) ? e.srcElement: e.target);
        _localThis.onChoiceSelected(_localThis.choiceID, eSource.value);
    }
    
    this.onChoiceSelected = function(id, selectedValue)
    {
        //call method on choiceSelectedHandlerObj (i.e. productChoiceMgr instance)
        _localThis.onChoiceSelectedHandler.apply(this.choiceSelectedHandlerObj, arguments);
    }
    
    this.initializeListChoice($get(this.choiceControlID));
}

ASPNETInputElementDropdownControl.prototype.updateChoiceItems = function(choiceItems, showChoiceItemPrice, currentBasePrice, savingsTemplate, choiceCount, defaultCPPercent, siteID)
{
    var control = $get(this.choiceControlID);
    var items = control.getElementsByTagName('option');
    var i, x, n;

    for(x=0;x<choiceItems.length;x++)
    {
        for(i=0;i<items.length;i++)
        {   
            if(items[i].value == choiceItems[x].ID)
            {

                if(choiceItems[x].available)
                {
                    //var label = items[i].getElementsByTagName('op');
                    //if(label && label.length > 0){label[0].className = '';}
                    items[i].disabled = false;
                    if(showChoiceItemPrice == 1)
                    {
                        //if(label && label.length > 1)
                        //{
                            var itemPrice;
                            var priceToShow;
                            
                            if (siteID == 1)
                            {
                                //TODO: SJB - comment out
                                priceToShow = choiceItems[x].unitPrice;
                                
                                //TODO: SJB - re-activate
                                //priceToShow = choiceItems[x].currentSKUPrice;
                            }
                            if (siteID == 2)
                            {
                                //If CP Site then show lowest qty. Vol. Discount price
                                priceToShow = currentBasePrice - (currentBasePrice * (defaultCPPercent / 100)) + choiceItems[x].priceAdjustment;
                            }
                                
                            itemPrice = '<span class="ChoiceItemPrice">$' + priceToShow.toFixed(2) + 
                            (choiceItems[x].showAdjustmentIndicator ? '*': '') + '</span>';
                            
                            if(choiceItems[x].discount && savingsTemplate && savingsTemplate != '')
                            {
                                var dollarAmt = 0;
                                var percAmt = 0;
                                //TODO: SJB - comment out
                                dollarAmt = (currentBasePrice + choiceItems[x].priceAdjustment) - choiceItems[x].unitPrice;
                                percAmt = (1 - (choiceItems[x].unitPrice / (currentBasePrice + choiceItems[x].priceAdjustment))) * 100;
                                
                                //TODO: SJB - re-activate
//                                dollarAmt = priceToShow;
//                                percAmt = (1 - priceToShow) * 100;
                                savingsTemplate = savingsTemplate.replace(/\[\[dollaramt\]\]/i, '$' + dollarAmt.toFixed(2));
                                savingsTemplate = savingsTemplate.replace(/\[\[percentamt\]\]/i, percAmt.toFixed(0) + '%');
                                itemPrice += '&nbsp;<span class="ChoiceItemDiscountSavings">' + savingsTemplate + '</span>';
                            }
                            items[i].innerHTML += itemPrice;
                        //}
                    }
                }
                else
                {
                    //items[i].className = 'ChoiceItemDisabled';
                    items[i].disabled = true;
                    //var selected = items[i].selected;

//                    if (items[i].disabled) { 
//                    items[i].style.color = "graytext"; 
//                    } 
//                    else { 
//                    items[i].style.color = "menutext"; 
//                    } 

                    //items[i].selected = false;
                    //if(selected){this.onChoiceSelected(this.choiceID, -1);}
                    
                    //control.remove(i);
                    
                    
//                    if(label && label.length > 0){label[0].className = 'ChoiceItemDisabled';}
//                    items[i].disabled = true;
//                    var checked = items[i].checked;
//                    items[i].checked = false;
//                    if(checked){this.onChoiceSelected(this.choiceID, -1);}
                }
                break;
            }       
        }
    }
}

ASPNETInputElementDropdownControl.prototype.deselect = function()
{
    var control = $get(this.choiceControlID);
    var items = control.getElementsByTagName('option');
    var i, x, n;
    
    for(i=0;i<items.length;i++)
    {   
        items[i].checked = false
    }
}
