﻿/*************************************************************************************************/
/*************************************************************************************************/
/***
/***  Web Services
/***
/*************************************************************************************************/
/*************************************************************************************************/

var G_Service = new Array();
var GP = {
    Item: {
        StatusOfAvailability: { Available: 0, TBD: 1, SoldOut: 2, Discontinued: 3, Error: 4, Unavailable: 5 }
    }
}

/**************
/* Method used to add item to wishlist
/***/
function AddItemToWishlist(obj) {
    if (obj.id) {
        var arIds = obj.id.split('_');
        G_Service[arIds[0]] = new Commerce().AddItemToWishlist(arIds[0], arIds[1], _AddItemToWishlist_OnComplete, _MSAjax_OnError, _MSAjax_OnTimeOut);
    }
}

function _AddItemToWishlist_OnComplete(arg) {
    var ReturnObj = eval('(' + arg + ')');

    if (!ReturnObj.Error) {
        var Plant = ReturnObj.Item.Plant;
        var imagePath = WG.BasePath + '/images/layout/noimageavailable.gif';
        for (i = 0; i < Plant.MediaFiles.length; i++) {
            if (Plant.MediaFiles[i].MediaType.match(/thum/gi))
                imagePath = WG.BasePath + '/images/lib/plants/' + Plant.MediaFiles[i].FileName;
        }

        var str = '<div><h1 style="font-size:10pt">' + Plant.Name.AsHtml + ' was added to your wishlist</h1>';
        str += '<img src="' + imagePath + '" alt="' + Plant.Name.AsText + '" Title="' + Plant.Name.AsText + '"';
        str += ' class="plant" style="width:75px;height:75px;float:left;margin-right:15px;" />';

        str += '<div style="float:left; width: 375px;font-size:11px">';

        str += '<strong>Common Name: </strong>' + Plant.Common + '<br />';

        if (typeof (PR) == "undefined") {
            str += '<strong>Sizes Offered:<br /></strong>';
            for (i = 0; i < Plant.SizesOffered.length; i++)
                str += '&nbsp; ' + Plant.SizesOffered[i].Name + '<br />';
        }

        str += '<strong>Hardiness Zone:</strong> ' + Plant.HardinessZone + '<br />';
        str += '<strong>Height:</strong> ' + Plant.Height + '<br />';
        str += '<strong>Spread:</strong> ' + Plant.Spread + '<br />';
        str += '<strong>Exposure:</strong> ' + Plant.Exposure + '<br />';
        str += '<strong>Bloom Time:</strong> ' + Plant.BloomTime + '<br />';

        str += '</div></div>';

        str += '<div style="clear:both">';
        str += '<br /><br/ ><div style="padding: 8px 5px 0 0; text-align:right; background: #d7bb98">';
        str += ' <img src="' + WG.BasePath + '/images/buttons/close.gif" onclick="WG.Dialog.Close();" style="cursor:pointer;border:0px none" />';
        str += ' &nbsp; <a href="' + WG.BasePath + '/wishlist"><img src="' + WG.BasePath + '/images/buttons/proceedtowishlist.gif"';
        str += ' border="0" /></a></div>';

        WG.Dialog.Create(str);
        WG.Dialog.ToggleOverlay(true);
    }
}

/**************
/* Method used to located a great plains item by it's full great plains key
/***/
var SecondsToTimeout = 2250;
var TimeoutQueue = new Array();
function QueuePlant(i, obj) {
    if (obj.value.length >= 7) {
        for (var n = 0; n < TimeoutQueue.length; n++) {
            if (TimeoutQueue[n].Index == i) {
                clearTimeout(TimeoutQueue[n].Timer);
                TimeoutQueue.splice(n, 1);
                break;
            }
        }
        //console.log('waiting... ' + i);
        TimeoutQueue.push({ Index: i, Obj: obj, Timer: false });
        TimeoutQueue[TimeoutQueue.length - 1].Timer = setTimeout('LoadPlant(' + i + ');', SecondsToTimeout);
    }
    else
        HidePlant(obj);
}
function LoadPlant(i) {
    for (var n = 0; n < TimeoutQueue.length; n++) {
        if (TimeoutQueue[n].Index == i) {
            FindPlantByGreatPlainsId(TimeoutQueue[n].Index, TimeoutQueue[n].Obj);
            TimeoutQueue.splice(n, 1);
        }
    }
}

function HidePlant(o) {
    jQuery(o).parents('table').find('#item-container, #item-substitution-container').empty()
        .end().css('border', '0px none').find('img#imgNoToAll').hide();
}

function FindPlantByGreatPlainsId(i, obj) {

    //WG.QuickOrderForm.Queue.Add(i, obj);

    if (obj.value.length >= 7 && WG.QuickOrderForm.Queue.Exists(i, obj))
        return true;

    HidePlant(obj);

    if (obj.value.length >= 7) {
        if (jQuery('#txtRequestedShipDate').val().length > 0) {
            jQuery('#QuickOrderForm_ValidationSummary1, #QuickOrderForm_ValidationSummary1 span').hide();

            WG.QuickOrderForm.Notice.Worker({ load: true, index: i, ctrl: obj });
            var comm = new Commerce();
            var shipDate = jQuery('#txtRequestedShipDate').val();
            G_Service[i] = comm.FindPlantByGreatPlainsId(i, obj.value, 'true', shipDate,
                                                                _FindPlantByGreatPlainsId_OnComplete, _MSAjax_OnError, _MSAjax_OnTimeOut);

            WG.QuickOrderForm.Controls.NewRow(i, obj);
        }
        else
            jQuery('#QuickOrderForm_ValidationSummary1, #QuickOrderForm_ValidationSummary1 span:eq(0)').show();
    }
    else
        WG.QuickOrderForm.Notice.Worker({ load: false, index: i });
}

/**************
/* Method used to located a great plains item by it's base key and size key
/***/
function FindPlantByPartialGreatPlainsId(gp_id_base, obj) {
    if (!obj)
        obj = jQuery('select[id$="ddlSize"]').get(0);
    var size_id = jQuery(obj).val();

    jQuery('#item-container, #item-substitution-container').empty();
    jQuery('#item-init').css('display', 'block');

    if (gp_id_base.length >= 5 && size_id.length > 0 && jQuery('#txtRequestedShipDate').val().length > 0) {
        jQuery('select[id$=ddlSize]').attr('disabled', 'disabled');

        WG.QuickOrderForm.Notice.Worker({ load: true, index: 0, ctrl: obj });
        G_Service[0] = new Commerce().FindPlantByPartialGreatPlainsId(gp_id_base, size_id, jQuery('#txtRequestedShipDate').val(),
                                                                        _FindPlantByGreatPlainsId_OnComplete, _MSAjax_OnError, _MSAjax_OnTimeOut);
    }
    else
        WG.QuickOrderForm.Notice.Worker({ load: false, index: 0 });
}

/**************
/* Callback for FindPlantByGreatPlainsId
/***/
function _FindPlantByGreatPlainsId_OnComplete(arg) {
    var ReturnObj = eval('(' + arg + ')');
    var ControlIndex = ReturnObj.Params[0];
    DisplayGreatPlainsItem(ReturnObj, ControlIndex, 0);
}

function DisplayGreatPlainsItem(ReturnObj, ControlIndex, SubstituteIndex) {
    var IsMultiForm = false;

    if (!ReturnObj.Error) {
        WG.QuickOrderForm.Notice.Worker({ load: false, index: ControlIndex });

        // gather details about plant
        IsMultiForm = (ReturnObj.Params[1] == 'true' ? true : false);
        var RequestedShipDate = ReturnObj.RequestedShipDate;
        var Plant = ReturnObj.Plant;
        Plant.RequestedShipDate = RequestedShipDate;
        var SelectedSize = WG.QuickOrderForm.ParseSelectedSizeList(Plant.SizesOffered, Plant.GreatPlains.Id);

        var now = new Date(), currentSeason, shipSeason, isCurrentSeason;
        currentSeason = getSeasonForDate(now);
        shipSeason = getSeasonForDate(RequestedShipDate);
        isCurrentSeason = (currentSeason === shipSeason);

        /* don't think this is necessary
        // clear prices for out of season items
        if (!isCurrentSeason) {
            var j = Plant.GreatPlains.Item.Prices.length;
            while (j--) {
                Plant.GreatPlains.Item.Prices[j].Value = 0;
            }
        }
        */

        // the main reference control to append items to will be deciphered by either the multi form quick-order-items 
        // container or just a single container selector
        var refSelectorContainerId = '';

        // if this is the single add to cart page, then remove all child nodes
        if (!IsMultiForm)
            jQuery('#item-init').css('display', 'none');
        else
            refSelectorContainerId = 'div.quick-order-items:eq(' + ControlIndex + ') '; // must reference the appropriate index group

        // copy the template item and alter the id then append this item to the item container, then
        // control/values will be populated later
        var refContainerId = Plant.IsSubstitute ? '#item-substitution-container' : '#item-container';
        refSelectorContainerId += refContainerId;

        // substitution header, should only be added once and first per substiution grouping
        if (Plant.IsSubstitute && jQuery(refSelectorContainerId + ' #substitutions-header').length == 0)
            jQuery(refSelectorContainerId).append('<div id="substitutions-header"><strong>Suggested Substitute(s):</strong></div>');

        // create unique indexed id for referencing. substitutions will have the same index as their parent item.. to maintain
        // uniqueness attach the substituted plant
        var newItemControlId = refContainerId + '-' + ControlIndex + (Plant.IsSubstitute ? '-' + SubstituteIndex : '');
        newItemControlId = newItemControlId.replace('#', '');
        var htmlTemplate = jQuery('#item-template').html();
        var newItemControlContainer = jQuery('<div id="' + newItemControlId + '">' + htmlTemplate + '</div>');

        if (jQuery(refSelectorContainerId).find('#' + newItemControlId).length > 0) {
            // returning to avoid potential request double-load rendering from the quick-order form
            return;
        }

        // add new control set to page
        jQuery(refSelectorContainerId).append(jQuery(newItemControlContainer));

        // the template has an item number/field div attached, for the quickorder form we will remove this as
        // this portion already exists, however, it will not exist on substitute records
        if (!Plant.IsSubstitute && IsMultiForm)
            jQuery(refSelectorContainerId + ' #item-number-container').remove();

        var ControlRef = jQuery((IsMultiForm ? 'div.quick-order-items:eq(' + ControlIndex + ') #' : '#') + newItemControlId);

        // if plant is substitute and the plant is not sold out, then hide substitutions
        if (Plant.IsSubstitute && Plant.HideSubstituteOnLoad) {
            jQuery(refSelectorContainerId).hide();
            WG.QuickOrderForm.Quantity.Disable(jQuery(ControlRef));
            WG.QuickOrderForm.ProvenWinners.Disable(jQuery(ControlRef));
        }

        // populate data controls and set element visibility
        WG.QuickOrderForm.initPlantForm(ControlRef, Plant);

        // setup references to new control objects to variables
        var ddlQuantity = jQuery(ControlRef).find('select#ddlQuantity');
        var ddlAvailability = jQuery(ControlRef).find('select#ddlAvailability');
        var hdnBin = jQuery(ControlRef).find('input[id$=hdnBin]');
        var noticePanel = WG.QuickOrderForm.ProvenWinners.Controls.noticePanel(ControlRef);
        var containerSelect = WG.QuickOrderForm.ProvenWinners.Controls.containerSelect(ControlRef);

        // this field needs a unique id in order for the calendar plugin to work appropriately. onSelect will just
        // take this value and auto-populate a hidden form field "hdnRequestedShipDateAlt"
        jQuery(ControlRef).find('input#txtRequestedShipDateAlt').attr('id', 'txtRequestedShipDateAlt' + Plant.GreatPlains.Id.TrueId + ControlIndex);

        var txtRequestedShipDateAlt = jQuery(ControlRef).find('input[id^=txtRequestedShipDateAlt]');
        var hdnRequestedShipDateAlt = jQuery(ControlRef).find('input#hdnRequestedShipDateAlt');

        var txtQuantity = jQuery(ControlRef).find('input#txtQuantity');
        var lblItemNumber = jQuery(ControlRef).find('span#lblItemNumber');
        var txtItemNumber = jQuery(ControlRef).find('input#txtItemNumber');


        // bind events
        if (!Plant.IsSubstitute) {

            jQuery(ddlAvailability).change(function(e) {

                var selValue = jQuery(this).val(), availBinSelected = true;

                if (selValue == null) {
                    selValue = '';
                    availBinSelected = false;
                }

                var controlRef = jQuery(this).parents('div.item-control-container');

                jQuery(ControlRef).find('input[id$="hdnBin"]').val((availBinSelected ? selValue : ''));

                var itemNumber = ScopeKey(ControlRef),
                    binKey = selValue + itemNumber; // create unique key to match when initializing calendar
                var txtRequestedShipDateAlt = jQuery(controlRef).find('input[id^=txtRequestedShipDateAlt]');
                var substituationContainer = jQuery(this).parents('div#item-container').nextAll('#item-substitution-container');

                var makeControlsUseable = false;

                if (jQuery(substituationContainer).length > 0) {

                    if (!availBinSelected) {
                        jQuery(substituationContainer).show();
                        WG.QuickOrderForm.Quantity.Disable(jQuery(ControlRef));
                        WG.QuickOrderForm.ProvenWinners.Disable(ControlRef);
                        WG.QuickOrderForm.RequestedShipDateAlt.Disable(jQuery(ControlRef));
                    }
                    else {
                        // if we have a substitute item with only one availability and it's auto-selected, since we don't show the dropdown, 
                        // we can't disable the quantity or clear out the hidden bin, because these cannot be re-enabled.. need to visit further
                        jQuery(substituationContainer).find('input[id$=hdnBin]').each(function() {

                            var ddl = jQuery(this).parent().find('select[id$=ddlAvailability]');
                            WG.QuickOrderForm.Quantity.Disable(jQuery(this).parent());
                            WG.QuickOrderForm.ProvenWinners.Disable(jQuery(this).parent());
                            WG.QuickOrderForm.RequestedShipDateAlt.Disable(jQuery(this).parent());

                            if (jQuery(ddl).find('option').length > 0)
                                jQuery(this).val(''); // clear bin

                            jQuery(ddl).attr('selectedIndex', '-1').children('option').attr('selected', ''); // clear availability ddl

                        });

                        makeControlsUseable = true;
                    }
                }
                else
                    makeControlsUseable = true;

                if (makeControlsUseable) {
                    WG.QuickOrderForm.Quantity.Enable(jQuery(ControlRef));
                    WG.QuickOrderForm.ProvenWinners.Enable(ControlRef);
                    WG.QuickOrderForm.RequestedShipDateAlt.Enable(jQuery(ControlRef));
                    createShippingCalendar(jQuery(txtRequestedShipDateAlt), ControlIndex, ScopeKey(ControlRef), selValue);
                }

                WG.QuickOrderForm.Quantity.Display(ControlIndex, itemNumber, jQuery(ControlRef), selValue);
            });
        }
        else {
            jQuery(ddlAvailability).change(function (e) {

                var mainControlRef = jQuery('div#item-container-' + ControlIndex).find('div.item-control-container:first');

                WG.QuickOrderForm.Quantity.Disable(jQuery(mainControlRef));
                WG.QuickOrderForm.ProvenWinners.Disable(mainControlRef);
                WG.QuickOrderForm.RequestedShipDateAlt.Disable(jQuery(mainControlRef));

                jQuery(mainControlRef).find('select#ddlAvailability').attr('selectedIndex', '-1')
                    .children('option').attr('selected', ''); // clear availability ddl

                jQuery(mainControlRef).find('input#hdnBin').val('');

                var selValue = jQuery(this).val(), availBinSelected = true;
                if (selValue == null) {
                    selValue = ''; availBinSelected = false;
                }

                jQuery(ControlRef).find('input[id$="hdnBin"]').val((availBinSelected ? selValue : ''));

                var itemNumber = ScopeKey(ControlRef),
                    binKey = selValue + itemNumber; // create unique key to match when initializing calendar

                var txtRequestedShipDateAlt = jQuery(ControlRef).find('input[id^=txtRequestedShipDateAlt]');

                WG.QuickOrderForm.Quantity.Enable(jQuery(ControlRef));
                WG.QuickOrderForm.ProvenWinners.Enable(jQuery(ControlRef));
                WG.QuickOrderForm.RequestedShipDateAlt.Enable(jQuery(ControlRef));
                createShippingCalendar(jQuery(txtRequestedShipDateAlt), ControlIndex, ScopeKey(ControlRef), selValue);
                WG.QuickOrderForm.Quantity.Display(ControlIndex, itemNumber, jQuery(ControlRef), selValue);
            });
        }

        jQuery(ddlQuantity).change(function() {
            WG.QuickOrderForm.Price.Calculate(ControlIndex, ControlRef);
        });

        if (Plant.IsSubstitute) {
            jQuery(ddlQuantity).change(function () {
                var mainControlRef = jQuery('div#item-container-' + ControlIndex).find('div.item-control-container:first');
                jQuery(mainControlRef).find('input#hdnBin').val('');
                jQuery(mainControlRef).find('select[id$=ddlAvailability]').attr('selectedIndex', '-1').children('option').attr('selected', '');
                WG.QuickOrderForm.Quantity.Disable(jQuery(mainControlRef));
                WG.QuickOrderForm.ProvenWinners.Disable(mainControlRef);
                WG.QuickOrderForm.RequestedShipDateAlt.Disable(jQuery(mainControlRef));

                WG.QuickOrderForm.Reinstate.Toggle(ControlIndex, this);
            });
        }

        jQuery(txtQuantity).bind('keyup', function() { WG.QuickOrderForm.Price.Adjust(ControlIndex, this); })
            .bind('keypress', function(e) { return validChar('numeric', this, e); })
            .bind('blur', function() { doZeroDefault(this); });

        jQuery(ControlRef).find('input#chkReInstate').click(function() {
            WG.QuickOrderForm.Reinstate.Toggle(ControlIndex, this);
        });

        jQuery(ControlRef).parents('table').find('img#imgNoToAll').click(function() {
            var ref = jQuery(this).parents('div.quick-order-items').next('div.quick-order-items');
            jQuery(this).parents('div.quick-order-items').empty();
            WG.QuickOrderForm.Controls.NewRowNeeded();
            if (ref.length == 1)
                jQuery(ref).find('input#txtItemNumber').focus();
        });

        // populate visual entities
        jQuery(lblItemNumber).html(Plant.GreatPlains.Id.TrueId);
        if (Plant.IsSubstitute)
            jQuery(txtItemNumber).val(Plant.GreatPlains.Id.TrueId);

        var str = '';

        for (p = 0; p < Plant.MediaFiles.length; p++) {
            if (Plant.MediaFiles[p].MediaType.match(/thum/gi))
                jQuery(ControlRef).find('img#imgThumb').attr('src', WG.BasePath + '/images/lib/plants/' + Plant.MediaFiles[p].FileName);
        }

        if (Plant.IsSubstitute && !IsMultiForm)
            str += '<a href="' + WG.BasePath + '/plants/view/?plant=' + Plant.Id + '"><strong>' + Plant.Name.AsHtml + '</strong></a><br />';
        else
            str += '<strong>' + Plant.Name.AsHtml + '</strong><br />';

        if (SelectedSize) str += SelectedSize.Name + '<br />';

        jQuery(ControlRef).find('input#hdnScopeKey').val(Plant.GreatPlains.Id.TrueId);

        if (typeof WG.QuickOrderForm.MultiplesInUse[ControlIndex] == 'undefined')
            WG.QuickOrderForm.MultiplesInUse[ControlIndex] = [];

        WG.QuickOrderForm.MultiplesInUse[ControlIndex].push({ Key: Plant.GreatPlains.Id.TrueId, Value: SelectedSize.Multiples, Description: SelectedSize.UnitofMeasure });

        if (typeof WG.QuickOrderForm.AvailablePricing[ControlIndex] == 'undefined')
            WG.QuickOrderForm.AvailablePricing[ControlIndex] = [];

        WG.QuickOrderForm.AvailablePricing[ControlIndex].push({
            Key: Plant.GreatPlains.Id.TrueId,
            Prices: Plant.GreatPlains.Item.Prices
        });


        // check if array is initialized; if not create new and append new bin object. this array will at most hold three sets of bin
        // objects per control (1xitem, 2xsubstitutes)
        if (typeof WG.QuickOrderForm.AvailableBins[ControlIndex] == 'undefined')
            WG.QuickOrderForm.AvailableBins[ControlIndex] = [];
        WG.QuickOrderForm.AvailableBins[ControlIndex].push({ Key: Plant.GreatPlains.Id.TrueId, Bins: Plant.GreatPlains.Item.Bins });

        WG.QuickOrderForm.BindQuantityList(ControlIndex, jQuery(ControlRef));

        /////
        // Builds the quantity/price breakdown list as a table, then tacks on the string to the main
        // description string.
        // Prices.length == 1 should always be true due to tiered pricing being phased out //mn
        /////

        var Prices = Plant.GreatPlains.Item.Prices;
        if (Prices.length > 0) {
            var uom = 'each', strPriceList = '';
            if (Prices.length > 1) {
                // for current season plants                
                strPriceList += '<tr><td colspan="2" style="padding-top:6px">Price(s):</td></tr>';
                for (var i = 0; i < Prices.length; i++) {
                    var qfrom_to = Prices[i].QuantityFrom + ' - ' + Prices[i].QuantityTo;
                    if (Prices.length == 1)
                        qfrom_to = SelectedSize.Multiples;
                    else if (i == Prices.length - 1 && Prices.length != 1)
                        qfrom_to = Prices[i].QuantityFrom + '+';

                    strPriceList += '<tr><td align="right">' + qfrom_to + ' plants: &nbsp;</td>';
                    strPriceList += '<td>$ ' + formatNumber(Prices[i].Value, 3, true, true) + '</td></tr>';
                }
            }
            else if (Prices.length == 1) { //mn
                strPriceList += '<tr><td colspan="2" style="padding-top:6px">Price: $' + formatNumber(Prices[0].Value, 3, true, true) + ' ' + uom + '</td></tr>';
            }
 
            var tblDislay = isCurrentSeason ? '' : 'none';
            strPriceList = '<div name="pricelist" style="display:' + tblDislay + ';"><table border="0" cellpadding="0" cellspacing="0" >' + strPriceList + '</table></div>';
            str = str + strPriceList;

            // for out of season plants pricing not available
            var dv = document.createElement('div');
            dv.setAttribute('name', 'pricena');
            dv.style.paddingTop = '6px';
            dv.style.marginRight= '6px';
            dv.className = 'item_disclaimer';
            dv.appendChild(document.createTextNode('Pricing for the next season will be available soon. '));
            var a = document.createElement('a');
            a.setAttribute('href', '../contactus/');
            a.setAttribute('target', '_blank');
            a.appendChild(document.createTextNode('Contact us'));
            dv.appendChild(a);
            dv.appendChild(document.createTextNode(' with questions.'));
            if (isCurrentSeason) {
                dv.style.display = 'none'; // hide when plant is in season
            }

            var pkg = document.createElement('div');
            pkg.appendChild(dv);
            str += pkg.innerHTML;
            pkg = null;
        }

        var subtotalCell = (jQuery(ControlRef).find('span#lblSubtotal').parent());
        if (isCurrentSeason) {
            // pricing available, show subtotal
            subtotalCell.css({ visibility: 'visible' });
        }
        else {
            // ship date is out of this season, hide subtotal
            subtotalCell.css({ visibility: 'hidden' });
        }

        // set available status
        var statusOfAvail = Plant.GreatPlains.Item.StatusOfAvailability;
        var SelectedBin = false;

        // if we're able to find the exact bin for the user, then auto-load the available quantity for viewing
        if (Plant.GreatPlains.Item.SelectedBin)
            SelectedBin = Plant.GreatPlains.Item.SelectedBin;

        // if status is unavailable, that means an error occurred with loading all required GP object(s)
        if (GP.Item.StatusOfAvailability.Error != statusOfAvail) {

            /////
            // Builds the available quantities and dates
            /////

            // 1. if we have an available bin within user ship date and not sold out
            // 2. or plant is sold out
            if (Plant.GreatPlains.Item.SelectedBin && !Plant.GreatPlains.Item.SelectedBin.IsSoldOut ||
                !Plant.IsSubstitute && statusOfAvail == GP.Item.StatusOfAvailability.SoldOut) {
                jQuery(ddlAvailability).parents('tr:first').hide();
            }
            else {
                var Bins = Plant.GreatPlains.Item.Bins;
                var hasValidBin = false;

                for (var i = 0; i < Bins.length; i++) {
                    if (Bins[i].InSeason) hasValidBin = true; // future years qualify for "in season"
                }

                if (hasValidBin) {
                    jQuery(ddlAvailability).empty();
                    var bin_opt_html = ''; //'<option value="">---</option>';

                    for (var i = 0; i < Bins.length; i++) {
                        // 1. do not show out of season items for all
                        // 2. do not show sold out items for plant..
                        // 3. ..unless a substitute is available
                        // 4. and do not add sold out items to substitutes, only the original item
                        if (Bins[i].InSeason) {
                            if (!Plant.IsSubstitute && !Bins[i].IsSoldOut ||
                            /*!Plant.IsSubstitute && Bins[i].IsSoldOut && Plant.Substitutions.length > 0 ||*/
                                !Bins[i].IsSoldOut && Plant.IsSubstitute) {
                                var bin_opt_text = Bins[i].AvailableFromAsString + ' - ' + Bins[i].AvailableToAsString + ' available';
                                var selected = Bins[i].AutoSelect ? '"selected"="selected"' : '';
                                if (!Plant.GreatPlains.Item.SelectedBin && Bins[i].AutoSelect) {
                                    SelectedBin = Bins[i];
                                }
                                bin_opt_html += '<option value="' + Bins[i].Id + '" ' + selected + '>';
                                bin_opt_html += bin_opt_text + '</option>';
                            }
                        }
                    }
                    jQuery(ddlAvailability).append(bin_opt_html);
                    jQuery(ddlAvailability).removeAttr('disabled');

                    jQuery(txtRequestedShipDateAlt).parents('tr:first').show();
                }
                else
                    jQuery(ddlAvailability).attr('disabled', 'disabled');
            }

            // set available quantity for selected bin
            var quantityForSelectedBin = 0;
            if (SelectedBin)
                quantityForSelectedBin = WG.QuickOrderForm.Quantity.Display(ControlIndex, Plant.GreatPlains.Id.TrueId, jQuery(ControlRef), SelectedBin.Id);
        }

        if (statusOfAvail > GP.Item.StatusOfAvailability.TBD) {
            if (statusOfAvail == GP.Item.StatusOfAvailability.SoldOut)
                message = '<b>This item is currently sold out.</b>';
            else if (statusOfAvail == GP.Item.StatusOfAvailability.Discontinued)
                message = '<b>This item has been discontinued.</b>';
            else if (statusOfAvail == GP.Item.StatusOfAvailability.Error) {
                if (Plant.GreatPlains.IsFound) {
                    var js = '<a href="javascript:FindPlantByPartialGreatPlainsId(\'' + Plant.GreatPlains.Id.BaseId + '\');">Please try again</a>';
                    message = 'This item could not be retreived at this time. ' + js;
                }
                else
                    message = '<b>This item is currently unavailable.</b>';
            }
            else if (statusOfAvail == GP.Item.StatusOfAvailability.Unavailable)
                message = '<b>This item is currently unavailable.</b>';
            if (statusOfAvail != GP.Item.StatusOfAvailability.Error && statusOfAvail != GP.Item.StatusOfAvailability.Available) {
                if (Plant.Substitutions.length > 0)
                    message += ' See suggested substitute(s) below.';
                else
                    message += ' There is no suggested substitute.';
            }
            WG.QuickOrderForm.Notice.Availability({ ctrl: jQuery(ControlRef), status: statusOfAvail, msg: message });

            if (!Plant.IsSubstitute && statusOfAvail == GP.Item.StatusOfAvailability.SoldOut) {
                var pnlReinstate = jQuery(ControlRef).find('div#pnlReinstate');
                var nextAvailDate = Plant.GreatPlains.Item.NextAvailabilityDate;
                jQuery(pnlReinstate).css({ display: 'block' }).find('span').css({ display: 'none' });
                if (nextAvailDate.length > 0)
                    jQuery(pnlReinstate).find('span:eq(1)').css({ display: 'inline' }).find('strong').html(Plant.GreatPlains.Item.NextAvailabilityDate);
                else
                    jQuery(pnlReinstate).find('span:eq(0)').css({ display: 'inline' });

                jQuery(ControlRef).find('div.item-control-container').addClass('soldout')
                    .parents('table[id$="tblQuickOrderItem"]').css('border', '3px solid #4b3828').end()
                    .find('img#imgThumb, div#pnlDescription, div#pnlItemContainer tr:first td')
                    .each(function() { jQuery(this).fadeTo(0, 0.65); });
            }
        }
        else {
            // if the selected bin is sold out, it means that there are other bins available, however, this one is selected to
            // auto-show substitutions; in this case, show a special message
            if ((!SelectedBin || SelectedBin.IsSoldOut) && !Plant.IsSubstitute) {
                statusOfAvail = GP.Item.StatusOfAvailability.Unavailable;
                message = '<b>This item is currently unavailable to ship ' + RequestedShipDate + '.</b><br />';
                message += 'Please select an alternate shipping date' + (Plant.Substitutions && Plant.Substitutions.length > 0 ? ', or view available substitutions below.' : '.');
                jQuery(ControlRef).find('div.item-control-container').parents('table[id$="tblQuickOrderItem"]').css('border', '3px solid #4b3828').end();
                WG.QuickOrderForm.Notice.Availability({ ctrl: jQuery(ControlRef), status: statusOfAvail, msg: message });
            }

            //if (parseInt(quantityForSelectedBin) < 0)
            //    strQuantityAvailable = '(TBD)';

            //jQuery(ControlRef).find('span#lblQuantityAvailable').html(strQuantityAvailable);

            /*var strDisclaimer = 'If you would like to purchase more than the current inventory quantity (' + (parseInt(quantityForSelectedBin) >= 0 ? quantityForSelectedBin : 'TBD') + ')';
            strDisclaimer += ', please <a href="/contactus">contact us</a> for assistance';
            if (statusOfAvail == GP.Item.StatusOfAvailability.TBD)
            strDisclaimer = 'Please <a href="/contactus">contact us</a> for available inventory.';
            
            if (statusOfAvail <= GP.Item.StatusOfAvailability.TBD)
            {
            jQuery(ControlRef).find('div#divDisclaimer').html(strDisclaimer).css('display','block');                
            if (statusOfAvail == GP.Item.StatusOfAvailability.TBD)
            {
            var message = 'The availability of this is item is to be determined.';
            WG.QuickOrderForm.Notice.Availability({ctrl:jQuery(ControlRef), status:statusOfAvail, msg:message});
            }
            }*/
        }

        // populate hidden form/data fields
        jQuery(ControlRef).find('input[type="hidden"]').each(function() {
            var id = jQuery(this).attr('id');

            if (id == 'hdnPlantId') {
                jQuery(this).val(Plant.Id);
            }
            //else if (id == 'hdnScopeKey') { jQuery(this).val(Plant.GreatPlains.Id.TrueId); }
            else if (id == 'hdnSize' && SelectedSize) {
                jQuery(this).val(SelectedSize.Id);
            }
            else if (id == 'hdnIsSubstituteFor' && Plant.IsSubstitute) {
                jQuery(this).val(Plant.IsSubstituteFor);
            }
            else if (id == 'hdnStatusOfAvailability' && !Plant.IsSubstitute) {
                jQuery(this).val(Plant.GreatPlains.Item.StatusOfAvailability);
            }
            else if (id == 'hdnBin') {
                for (var i = 0; i < Plant.GreatPlains.Item.Bins.length; i++) {
                    if (Plant.GreatPlains.Item.Bins[i].AutoSelect && !Plant.GreatPlains.Item.Bins[i].IsSoldOut) {
                        jQuery(this).val(Plant.GreatPlains.Item.Bins[i].Id); break;
                    }
                }
                if (!Plant.IsSubstitute && jQuery(this).val() == '')
                    jQuery(ddlAvailability).trigger('change'); // this will invoke substitution display
            }
        });

        // calculating and displaying a base price upon first load        
        WG.QuickOrderForm.Price.Calculate(ControlIndex, jQuery(ControlRef));

        jQuery(ControlRef).find('div#pnlDescription').html(str);
        
        // do not show item information if a critical error has occured
        if (statusOfAvail != GP.Item.StatusOfAvailability.Error)
            jQuery(ControlRef).find('div#pnlItemContainer').css('display', 'block');

        /*******************************
        * Adjusting main parameters for substitution presentation if current item is sold out or discontinued
        ******/

        //if ( (statusOfAvail == GP.Item.StatusOfAvailability.SoldOut || statusOfAvail == GP.Item.StatusOfAvailability.Discontinued) 
        if (Plant.Substitutions && Plant.Substitutions.length > 0) {
        
            // set flag to indicate whether to auto-show substitutions or to rely on user interaction
            // this flag only applies to when an item is sold out; if an item is unavailable but has other available dates, and the
            // unavailable date is auto-selected, or if there is no selected bin, but available dates are present.
            var hideSubstitutePanel = Plant.GreatPlains.Item.HasAvailability && (null != jQuery(ddlAvailability).val() || jQuery(hdnBin).val().length > 0);
            
            if (!SelectedBin && Plant.GreatPlains.Item.HasAvailability)
                hideSubstitutePanel = false;

            for (var i = 0; i < Plant.Substitutions.length; i++) {
                var ReturnSubstitutionObj = new Object();
                for (obj in ReturnObj) {
                    if (obj != 'Plant')
                        ReturnSubstitutionObj[obj] = ReturnObj[obj];
                }
                // set plant to main substitutional plant object
                ReturnSubstitutionObj.Plant = Plant.Substitutions[i];
                // set flag to avoid certain declarations in the reused function
                ReturnSubstitutionObj.Plant.IsSubstitute = true;
                ReturnSubstitutionObj.Plant.IsSubstituteFor = Plant.Id + ':' + Plant.GreatPlains.Id.TrueId + ':' + statusOfAvail;
                ReturnSubstitutionObj.Plant.HideSubstituteOnLoad = hideSubstitutePanel;

                DisplayGreatPlainsItem(ReturnSubstitutionObj, ControlIndex, i);
            }
            
            if (IsMultiForm && !hideSubstitutePanel)
                jQuery(ControlRef).parents('table').find('img#imgNoToAll').show();
        }


        if (IsMultiForm)
            WG.QuickOrderForm.Queue.Remove(ControlIndex, ControlRef);
    }
    else {
        if (ReturnObj.Error == "0") {
            IsMultiForm = ReturnObj.Params[1] == 'true' ? true : false;

            if (IsMultiForm) {
                var ControlRef = jQuery('div.quick-order-items:eq(' + ReturnObj.Params[0] + ')');
                var gpId = jQuery(ControlRef).find('input#txtItemNumber:first').val().toUpperCase();
                var msg = gpId + ' appears to be an invalid item number.';
            }
            else {
                var gpId = jQuery('input[id$="txtItemNumber"]:first').val().toUpperCase();
                var js = "FindPlantByPartialGreatPlainsId('" + gpId + "');";
                var msg = 'Plant ' + gpId + ' could not be retreived at this time. <a href="javascript:' + js + '">Please try again</a>';
            }
            WG.QuickOrderForm.Notice.Worker({ load: false, index: ControlIndex, ctrl: ControlRef, error: msg });
        }
        else if (ReturnObj.Error == "1")
            window.location = WG.BasePath + '/plants';
    }

    jQuery('select[id$=ddlSize]').removeAttr('disabled');
}

function ScopeKey(ref) { return jQuery.trim(jQuery(ref).find('input#hdnScopeKey').val()); }
function ScopePricing(controlIndex, ref) {
    if (isStaticForm())
        return WG.QuickOrderForm.AvailablePricing[controlIndex].Prices;

    var key = ScopeKey(ref);
    for (var i = 0; i < WG.QuickOrderForm.AvailablePricing[controlIndex].length; i++) {
        if (WG.QuickOrderForm.AvailablePricing[controlIndex][i].Key == key)
            return WG.QuickOrderForm.AvailablePricing[controlIndex][i].Prices
    }
    return [];
}
function ScopeMultiples(controlIndex, ref) {
    if (isStaticForm())
        return WG.QuickOrderForm.MultiplesInUse[controlIndex];

    var key = ScopeKey(ref);
    for (var i = 0; i < WG.QuickOrderForm.MultiplesInUse[controlIndex].length; i++) {
        if (WG.QuickOrderForm.MultiplesInUse[controlIndex][i].Key == key)
            return WG.QuickOrderForm.MultiplesInUse[controlIndex][i];
    }
    return {};
}

function isUnavailableForSelection(item, selectedbin) {
    if (!item.IsSubstitute) {
        var status = item.GreatPlains.Item.StatusOfAvailability;
        if ((!selectedbin && status != GP.Item.StatusOfAvailability.Unavailable) ||
             status > GP.Item.StatusOfAvailability.TBD)
            return true;
    }
    return false;
}

function createShippingCalendar(o, controlIndex, greatPlainsId, binId) {
    var dtConstraint1 = false, dtConstraint2 = false;
    var Bins = WG.QuickOrderForm.AvailableBins[controlIndex];
    for (a = 0; a < Bins.length; a++) {
        if (Bins[a].Key == greatPlainsId) {
            for (b = 0; b < Bins[a].Bins.length; b++) {
                var bin = Bins[a].Bins[b];
                if (bin.Id == binId) {
                    dtConstraint1 = bin.AvailableFromAsString;
                    dtConstraint2 = bin.AvailableToAsString;
                    break;
                }
            }
        }
    }
    if (!jQuery(o).hasClass('hasDatepicker'))
        jQuery(jQuery(o)).datepicker({ showAnim: '' });
    jQuery(jQuery(o)).datepicker('option', {
        beforeShowDay: WG.ShippingCalendar.getDayFilterWithConstraints(dtConstraint1, dtConstraint2),
        defaultDate: new Date(dtConstraint1),
        onSelect: function(dateText, inst) {
            jQuery('#' + inst.id).parents('div.item-control-container').find('#hdnRequestedShipDateAlt').val(dateText);
        }
    });
}
// expecting div.item-control-container as o
function isInSubstituteScope(o) {
    //alert(jQuery(o).find('input[id^=hdnIsSubstituteFor]').val());
    return jQuery(o).find('input#hdnIsSubstituteFor]').val().length > 0 ? true : false;
}
function isStaticForm() { return !window.location.href.match(/(cart\/add|quickorder)/gi); }

function getSeasonForDate(date) {

    if (typeof (date) === 'string') {
        date = new Date(date);
    }

    var season = date.getFullYear();
    if (date.getTime() <= (new Date(season, 6, 1)).getTime()) { // july 1st, relevant year
        season--; // date belongs to previous season
    }

    return season;
}

/**************
/* Method used to persist session state when on the quick order form
/***/
var KeepAliveAttempts = 0;
function PersistSession() {
    if (KeepAliveAttempts < 30)
        Commerce.PersistSessionState('{}', _PersistSession_OnComplete, _MSAjax_OnError, _MSAjax_OnTimeOut);
}

function _PersistSession_OnComplete(arg) {
    var ReturnObj = eval('(' + arg + ')');
    if (ReturnObj.Error && ReturnObj.Error > 0)
        window.location = WG.BasePath + '/plants';
    else {
        KeepAliveAttempts += 1;
        var to = window.setTimeout('PersistSession();', 900000);
    }
}

/*************************************************************************************************/
/*************************************************************************************************/
/***
/***  Common Services
/***
/*************************************************************************************************/
/*************************************************************************************************/

var G_HasAborted = false;
function _MSAjax_Abort(i) {
    if (G_Service[i] && G_Service[i].get_executor().get_started()) {
        G_HasAborted = true;
        G_Service[i].get_executor().abort();
        G_Service[i] = false;
    }
}

function _MSAjax_OnComplete(arg) {
    //alert(arg);
    return true;
}
function _MSAjax_OnError(arg) {
    if (!G_HasAborted) {
        //alert("error has occured: " + arg.get_message());//_message);
        G_HasAborted = false;
    }
}
function _MSAjax_OnTimeOut(arg) {
    alert("timeout has occured");
}
