﻿// Javascript for Item Code Selection on product page.
// Used by PFMembers.ascx.

var PFItemNumbers = $A(new Array());
var prodGroupId, narrowedList, choiceTypes;
chosenValues = { item_code: '', choiceValue1: '', choiceValue2: '', choiceValue3: '', choiceValue4: '' };
var choiceValueFunctions = {
    set: function(index, value) { eval('this.choiceValue' + index.toString() + ' = value'); },
    get: function(index) { return eval('this.choiceValue' + index.toString()); }
};
chosenValues = Object.extend(chosenValues, choiceValueFunctions);

var choiceSelectName = 'ddl_choice_';
var linkSwatchesToChoice = { name: '', sort_index: 0 };
//var chosenSwatchValue = '';
var PFSwatches = new Array();
var MainPFImage; // set this in the presentation control to $('colorset');
var chosenSwatchInput; // set this in the presentation control
var chosenItemCodeInput; // set this in the BuyBox control
var chosenProdGroupID; // set this in the BuyBox control
var AddToBasketHookID; // set this in the BuyBox control (registered script block)
var AddToRegistryHookID; // set this in the BuyBox control (registered script block)
var ErrorMessages = {   'SELECT_OPTIONS':'Please select all options above.', 
                        'SPECIAL_HANDLING':'Please fill in all required information above.',
                        'QUANTITY_0':'Please enter a valid quantity above.' };
var throbberTimeout; // used to display throbber if the request is taking too long.
                        
// add to basket
function addToBasket(qty, addOrUpdate, chosenHook) {
    // chosen item
    var selected = chosenItem(chosenValues);
    if (!selected) { errorMessage('SELECT_OPTIONS'); return false; }
    if (chosenItemCodeInput) { chosenItemCodeInput.value = selected.item_code; }    
    if (!allSpecialHandlingOK()) { errorMessage('SPECIAL_HANDLING'); return false }
    if (qty <= 0) { errorMessage('QUANTITY_0'); return false }
    if (__doPostBack) { __doPostBack(chosenHook, addOrUpdate); }
    return false;
}

function getAction(form) {
    return form.readAttribute('action') + '?' + form.serialize();
}

// form validation
function allSpecialHandlingOK() { return true; }

// error message
function errorMessage(type) {
    var msg = ErrorMessages[type];
    if (msg) { alert(msg); }
}

// finds selected item from PFItemNumbers
function chosenItem(chosen) {
    if (chosen.item_code != '') {
        if (myItem = PFItemNumbers.find(function(n){ return (n.item_code == this.item_code); }, chosen)) { return myItem; }
    } else if (PFItemNumbers.length == 1) { return PFItemNumbers[0]; 
    } 
    if (chosen.choiceValue1 == '') { // have more than one item number, and no choicevalue1. read from inputs.
        [ '1', '2', '3', '4' ].each(function(n) {
            var ddl, svalue; 
            if (ddl = $(choiceSelectName + n)) {
                svalue = ddl.options[ddl.selectedIndex].value;
                chosen.set(ddl.choice_ValueKey, svalue);
                //eval('chosen.choiceValue' + n + ' = svalue');
            }
        });
    }
    narrowedList = narrow(chosen);
    if (narrowedList.length == 1) { return narrowedList[0]; }
    return false;
}

// expects an object, chosen, with properties for each chosen value.
function narrow(chosen) {

    var narrowed = PFItemNumbers;
    /* set up our choice value functions, it's easier this way */
    if (!check(chosen.get)) { Object.extend(chosen, choiceValueFunctions); }
    narrowed.each(function(i) { 
        if (!check(i.get)) { Object.extend(i, choiceValueFunctions); }
    });
    
    [ '1', '2', '3', '4' ].each(function(n) {
        if (!hasChoice(n)) { return; }
        var ddl, vkey = n, val; 
        if (ddl = $(choiceSelectName + n)) {
            /* find drop-down, so we can get the choicevaluekey. */
            vkey = ddl.choice_ValueKey;
        }
        if ((val = chosen.get(vkey)) != '') {
            narrowed = narrowed.findAll(function(i){
                /* vkey should be accessible within this closure */
                return i.get(vkey) == this.get(vkey); 
            }, chosen);            
        }
    });
    
    /*
    if (hasChoice(1)) {
        if (chosen.choiceValue1 != '') {
        narrowed = narrowed.findAll(function(n){ 
            return n.choiceValue1 == this.choiceValue1; }, chosen);
    }
    if (hasChoice(2) && chosen.choiceValue2 != '') {
        narrowed = narrowed.findAll(function(n){ 
            return n.choiceValue2 == this.choiceValue2; }, chosen);
    }
    if (hasChoice(3) && chosen.choiceValue3 != '') {
        narrowed = narrowed.findAll(function(n){ 
            return n.choiceValue3 == this.choiceValue3; }, chosen);
    }
    if (hasChoice(4) && chosen.choiceValue4 != '') {
        narrowed = narrowed.findAll(function(n){ 
            return n.choiceValue4 == this.choiceValue4; }, chosen);
    }
    */
    return narrowed;
}

function hasChoice(sortIndex) {
    if (check(choiceTypes)) {
        return check(choiceTypes.find(function(c) { 
            return (c.sort_index == this); 
        }, sortIndex));
    }
}

function fillChoiceSelects(startsFrom) {
    var narrowed; 
    // figure out a starting point for filling other drop-downs based
    // on choice value already selected.
    if (startsFrom.choice_SortIndex > 0) {
        var selected = { item_code: '', choiceValue1: '', choiceValue2: '', choiceValue3: '', choiceValue4: '' };
        selected = Object.extend(selected, choiceValueFunctions);
        selected.set(startsFrom.choice_ValueKey, startsFrom.options[startsFrom.selectedIndex].value);
        //selected.set(startsFrom.choice_SortIndex, startsFrom.options[startsFrom.selectedIndex].value);
        //eval('selected.choiceValue' + startsFrom.choice_SortIndex.toString() + '="' + startsFrom.options[startsFrom.selectedIndex].value + '"');
        narrowed = narrow(selected);
      
    } else { narrowed = PFItemNumbers; } // we're not really sure where we are
    
    [ '1', '2', '3', '4' ].each(
        function(n) {
            var ddl;
            if (ddl = $(choiceSelectName + n)) {  
                var svalue = chosenValues.get(ddl.choice_ValueKey);
                //var svalue = chosenValues.get(n);              
                //var svalue = eval('chosenValues.choiceValue' + n.toString());
                if (ddl == startsFrom) { return; }
                if (ddl.selectedIndex > 0) { 
                    // already selected;
                    svalue = ddl.options[ddl.selectedIndex].value;
                }
                //alert(ddl.options.length);
                var prompt = ddl.options[0];
                ddl.options.length = 0;
                ddl.options[0] = prompt;
                //alert(ddl.options.length);
                var prop = 'choiceValue' + n;
                var fillValues = narrowed.pluck(prop).uniq();
                var fillAvail = narrowed.pluck('availMsg');
                var fillWith = (fillValues.length == fillAvail.length)? fillValues.zip(fillAvail): fillValues.zip(fillValues.collect(function(x){return '';}));
                fillWith.each(function(o, index) {
                    if (o[0] == svalue) { 
                        this.options[index + 1] = new Option(o[0].toString() + o[1].toString().stripTags(), o[0], false, true);
                    } else {
                        this.options[index + 1] = new Option(o[0].toString() + o[1].toString().stripTags(), o[0], false, false);
                    }
                }, ddl);                
            }            
        }
    );
}

var choiceSelectHandler = function(e) { 
    var element = Event.element(e);
    if (element.choice_SortIndex < 1) { throw 'Choice ' + element.name + ' has a bad sort index'; return; }
    if (element.choice_ValueKey < 1) { element.choice_ValueKey = element.choice_SortIndex; }
    var sort = element.choice_SortIndex;
    var vkey = element.choice_ValueKey;
    var value = element.options[element.selectedIndex].value;
    //alert([ 'sort:', sort, 'value:', value ].join(' '));

    // tie this to the swatches
    if (linkSwatchesToChoice.sort_index == sort) { 
        set_chosenSwatchColor(value);
        ChangeImage(value); 
    }
    
    chosenValues.set(vkey, value);
    //eval('chosenValues.choiceValue' + sort.toString() + '="' + value + '"');
    chosenValues.item_code = '';
    //alert(Object.toJSON(chosenValues));
    
    narrowedList = narrow(chosenValues);
    
    if (narrowedList.length < 1) { // didn't find any. Reset.
        chosenValues = { item_code: '', choiceValue1: '', choiceValue2: '', choiceValue3: '', choiceValue4: '' };
        chosenValues = Object.extend(chosenValues, choiceValueFunctions);
        chosenValues.set(vkey, value);
        //eval('chosenValues.choiceValue' + sort.toString() + '="' + value + '"');
        narrowedList = narrow(chosenValues);
    }
    
    if (narrowedList.length == 1) { 
        oneLeft = narrowedList[0];
        chosenValues.item_code = oneLeft.item_code;
        chosenValues.choiceValue1 = oneLeft.choiceValue1;
        chosenValues.choiceValue2 = oneLeft.choiceValue2;
        chosenValues.choiceValue3 = oneLeft.choiceValue3;
        chosenValues.choiceValue4 = oneLeft.choiceValue4;
    }

    // I don't think this is necessary, but syncs up old page object with new.
    pageState.currentChoiceValues.ChoiceValue1 = chosenValues.choiceValue1;
    pageState.currentChoiceValues.ChoiceValue2 = chosenValues.choiceValue2;
    pageState.currentChoiceValues.ChoiceValue3 = chosenValues.choiceValue3;
    pageState.currentChoiceValues.ChoiceValue4 = chosenValues.choiceValue4;
     
    // fill the rest of the select boxes.
    fillChoiceSelects(element);
    
}
;

function SelectChoice(sortIndex, value, cascade) {
    var sel, changed = false;
    if (sel = $(choiceSelectName + sortIndex.toString())) {
        if (sel.options.length <= 1) { changed = true; }
        $A(sel.options).each(
            function(o, i) {
                if (o.value == value) { 
                    o.selected = true;
                    changed = true;                    
            }});
        if (changed) { 
            chosenValues.item_code = '';
            chosenValues.set(sel.choice_ValueKey, value);
            
            if (cascade) { 
            fillChoiceSelects(sel);
            }
        }
    }
}

function SelectColor(colorValue, eh) { 
    ChangeImage(colorValue);
    set_chosenSwatchColor(colorValue);
    //chosenSwatchValue = colorValue;
    if (linkSwatchesToChoice.sort_index > 0) {
        //chosenValues.set(linkSwatchesToChoice.sort_index, colorValue); -- do this in SelectChoice.
        //eval("chosenValues.choiceValue" + linkSwatchesToChoice.sort_index.toString() + "='" + colorValue + "'");
        SelectChoice(linkSwatchesToChoice.sort_index, colorValue, true);
    }
}

function ChangeImage(colorValue) { var s;
    if (s = PFSwatches.find(function(i) { return (i.item_color == colorValue); })) {
        HideRichFX();
        MainPFImage.src = s.src;
    }
}

function ShowRichFX() {
    var i;
    if (i = $('withRichFX')) { 
        if (Prototype.Browser.IE6) { i.hide(); }
        else { i.addClassName("showUnderRichFX"); i.removeClassName("showOverRichFX"); }
    }
}
function HideRichFX() {
    var i;
    if (i = $('withRichFX')) { 
        if (Prototype.Browser.IE6) { i.show(); }
        else { i.addClassName("showOverRichFX"); i.removeClassName("showUnderRichFX"); }
    }

}

function get_chosenSwatchColor() { 
    if (chosenSwatchInput) { return chosenSwatchInput.value; }
    return '';
}
function set_chosenSwatchColor(value) {
    if (chosenSwatchInput) { chosenSwatchInput.value = value; return chosenSwatchInput.value; }
    return '';
}

function preSelectChoices() {
   
    if (PFItemNumbers.length == 1) { // we only have one item code.
        chosenValues.choiceValue1 = PFItemNumbers[0].choiceValue1;
        chosenValues.choiceValue2 = PFItemNumbers[0].choiceValue2;
        chosenValues.choiceValue3 = PFItemNumbers[0].choiceValue3;
        chosenValues.choiceValue4 = PFItemNumbers[0].choiceValue4;
        chosenValues.item_code = PFItemNumbers[0].item_code;
    }
    
    //if (linkSwatchesToChoice.sort_index > 0 && chosenSwatchValue != "") {
    var chosenSwatch = get_chosenSwatchColor();
    if (chosenSwatch != "") { SelectColor(chosenSwatch); }
    //if (linkSwatchesToChoice.sort_index > 0 && chosenSwatch != "") {
    // we have linked swatches.  Maintain the chosen swatch value if possible.
    //    eval('chosenValues.choiceValue' + linkSwatchesToChoice.sort_index.toString() + '="' + chosenSwatch + '"');
    //}

    [ '1', '2', '3', '4' ].each(function(n) {
        var ddl = $(choiceSelectName + n); //, propName;
        if (ddl) { chosenValue = chosenValues.get(ddl.choice_ValueKey); }
        else { chosenValue = chosenValues.get(n); }
        //chosenValue = eval('chosenValues.choiceValue' + n);
        if ((chosenValue != '') && (ddl)) {
            if (n == linkSwatchesToChoice.sort_index) {
                ChangeImage(chosenValue);
                set_chosenSwatchColor(chosenValue);
            }
            SelectChoice(n, chosenValue, true);
        } else if (ddl && ddl.selectedIndex > 0) { 
            // already selected (possibly from a page reload?);
            chosenValue = ddl.options[ddl.selectedIndex].value;
            if (n == linkSwatchesToChoice.sort_index) {
                ChangeImage(chosenValue);
                set_chosenSwatchColor(chosenValue);
            }
            SelectChoice(n, chosenValue, true);
        }
    });
}

/*** AJAX Member Selection ***/
var memberContainer, memberChoiceSelectCallbackTarget, memberElementName;


function InitMember(prodgroupid) {
    // identify the input associated with the member, add it to the PFMembers collection
    // and set a handler on it for our custom "member:select" event.
    var mo = $('pf_Member_' + prodgroupid.toString());
    mo.prodgroupID = prodgroupid;
    PFMembers.push(mo);
    Event.observe(mo, "member:select", SelectMember.bindAsEventListener(mo));
}

function SelectMember(selectedPGID) {
    if (selectedPGID > 0) {
        // if this has been called externally, check for a member element and fire the custom selection event on it.
        var sM;
        if (check(sM = PFMembers.find(function(member) { return (member.prodgroupID == selectedPGID); }))) {
            sM.fire("member:select"); 
            return;
        } // if there's no member element available, fall through.
    } else { 
        // format the members to UNSELECTED.
        PFMembers.each(function(element) { element.addClassName('unselected'); element.removeClassName('selected'); });

        // if this has been called as an event handler on a member element, fetch the prodgroupid and set it to SELECTED.
        selectedPGID = this.prodgroupID;
        this.addClassName('selected');
        this.removeClassName('unselected');
    }
    // if we're not actually changing the member, don't re-fetch.
    if (pageState.prodGroupID == selectedPGID) { return; }
    // set a throbber to display a message after 1/2 second.
    throbberTimeout = window.setTimeout(function(){memberContainer.update('<span class="throbber">Please wait while we load further options.</span>');}, 500);
    // fetch the member info AJAXily.
    pageState.prodGroupID = selectedPGID;
    if (chosenProdGroupID) { chosenProdGroupID.value = selectedPGID; }
    callMeBack(
        Object.toJSON({ "pf_id": pageState.pfid, "prodgroupid": pageState.prodGroupID }), 
        memberChoiceSelectCallbackTarget, 
        function(retValue) { 
            var status, content, ret;
            ret = retValue.split('|');
            status = ret[0]; content = ret[1];
            window.clearTimeout(throbberTimeout);
            if (check(content)) {
                memberContainer.update(content); }
            else { 
                status = retValue.substring(0, 1);
                content = retValue.substring(1, retValue.length)
                if (status == "e") { //error
                    content = "<span class='error'>" + content + "</span>";
                    }
                memberContainer.update(content); }
        },
        function(errorObj) { window.clearTimeout(throbberTimeout); memberContainer.update("<span class='error'>We're sorry, an error has occurred on our server.</span>"); } // this should change
    );
       
}

/* Buy Another */
Event.observe(document, "basket_add:choose", function(e) { e.stop(); if (hideBasketStatus) { hideBasketStatus(); } if (buyAnother) { buyAnother(); }});
//Event.observe(document, "gr_add:choose", function(e) { e.stop(); if (clearGiftRegURL) { clearGiftRegURL(); } if (buyAnother) { buyAnother(); } if (hideBasketStatus) { hideBasketStatus(); }});

/*** Page State -- from ProductPageScripts.js ***/

//Represents the state of common page level variables
function PageState(){
    this.__type = 'Orvis.ProductPage.ProductPageState';
    this.pfid = '';
    this.prodGroupID = '';
    this.imagePath = '';
    this.currentChoiceValues = null; 
} // add item_code property to this class. Then we can use it for chosenValues.

//Represents the current choice value selections
function CurrentChoiceValues(){
    this.__type = 'Orvis.ProductPage.CurrentChoiceValues';
    this.ChoiceValue1 = '';
    this.ChoiceValue2 = '';
    this.ChoiceValue3 = '';
    this.ChoiceValue4 = '';
}

var pageState;
