function IdevSelections(options) {
    this.ElementCache = [];
    // get element from cache
    this.getSelectionElement = function(id) {
        if (!this.ElementCache["cache_" + id])
            this.ElementCache["cache_" + id] = document.getElementById(id);
        return this.ElementCache["cache_" + id];
    };

    // pre-initialize check
    if (!options.Variable || options.Variable == "") throw "No variable specified";
    if (!options.Container || options.Container == "") throw "No container specified";

    // initialize settings
    this.options = options;
    this.Container = this.getSelectionElement(this.options.Container);
    this.Classifications = [];
    this.Selections = [];
    this.Items = [];
    this.ItemProperties = [];
    this.DisplayCache = [];
    this.ClassificationsLength = 0;
    this.SelectionsLength = 0;
    this.ItemsLength = 0;

    // return the Classification from cache
    this.GetClassificationByClassificationId = function (i) { return this.Classifications[this.options.Variable + '_Classification_' + i]; };

    // return the Selection from cache
    this.GetSelectionBySelectionId = function(i) { return this.Selections[this.options.Variable + '_Selection_' + i]; };

    // return the Item with specified ItemId
    this.GetItemByItemId = function(id) { for (var i = 0; i < this.options.Items.length; i++) { if (this.options.Items[i].i == id) return this.options.Items[i]; } };

    // add Classifications and selections to cache
    if (this.options.Classifications) {
        for (var p = 0; p < this.options.Classifications.length; p++) {
            this.Classifications[this.options.Variable + '_Classification_' + this.options.Classifications[p].i] = this.options.Classifications[p];
            for (var s = 0; s < this.options.Classifications[p].s.length; s++) {
                this.Selections[this.options.Variable + '_Selection_' + this.options.Classifications[p].s[s].i] = this.options.Classifications[p].s[s];
                this.SelectionsLength++;
            }
        }

        // the number of Classifications
        this.ClassificationsLength = this.options.Classifications.length;

        // add items to cache
        for (var i = 0; i < this.options.Items.length; i++) {
            this.Items[this.options.Variable + '_Item_' + this.options.Items[i].s.toString()] = this.options.Items[i];
        }

        // the number of child items
        this.ItemsLength = this.options.Items.length;
    }

    // post-initialize check
    if (!this.Container) throw "Container not found";

    /* 
    Item Classifications - Add additional Classification definitions here 
    Valid Types are:
    SINGLE - does an innerHTML replacement
    IMAGE  - does a src replacement as well as an optional alt replacement
    HREF   - does an href replacement as well as adds an onclick (some browers don't play nice when you update the href attribute)
    Target is the jQuery selector for the DOM element(s) you want to target
    */
    var Suffix = (this.options.Suffix ? this.options.Suffix : '');
    this.ItemProperties['IP_ItemName'] = { Type: 'SINGLE', Target: '#hdngItemName' + Suffix };
    this.ItemProperties['IP_SKU'] = { Type: 'SINGLE', Target: '#spanSKU' + Suffix };
    this.ItemProperties['IP_Price'] = { Type: 'SINGLE', Target: '#spanPrice' + Suffix };
    this.ItemProperties['IP_ShortDesc'] = { Type: 'SINGLE', Target: '#pShortDesc' + Suffix };
    this.ItemProperties['IP_LongDesc'] = { Type: 'SINGLE', Target: '#longDescription' + Suffix };
    this.ItemProperties['IP_Callouts'] = { Type: 'SINGLE', Target: '#itemCallouts' + Suffix };
    this.ItemProperties['IP_Images'] = { Type: 'SINGLE', Target: '#altImages' + Suffix, OnHover: true };
    this.ItemProperties['IP_ImagesViewer'] = { Type: 'SINGLE', Target: '#altImagesViewer' + Suffix, OnHover: true };
    this.ItemProperties['IP_Image'] = { Type: 'IMAGE', Target: '#productImage' + Suffix + ' .mainImage', OnHover: true };
    this.ItemProperties['IP_Image360'] = { Type: 'IMAGE', Target: '#productImage' + Suffix + ' .rotate360 a img', OnHover: true };
    this.ItemProperties['IP_ImageLarge'] = { Type: 'IMAGE', Target: '#imageViewer' + Suffix + ' .mainImage img.imgEnlarge', OnHover: true };
    this.ItemProperties['IP_Pricing'] = { Type: 'SINGLE', Target: '#itemPricing' + Suffix };
    this.ItemProperties['IP_Link'] = { Type: 'HREF', Target: '.itemAnchor' + Suffix };
    this.ItemProperties['IP_PrintUrl'] = { Type: 'PRINTHREF', Target: '.print' + Suffix };
    this.ItemProperties['IP_SendUrl'] = { Type: 'SENDWINDOW', Target: '.email' + Suffix };

    // create the selection controls
    this.Create = function () {
    	var str = '<input type="hidden" id="hdnItem_' + this.options.Variable + '" name="hdnItem_' + this.options.Variable + '" ' + (this.options.SelectedItem ? 'value="' + this.options.SelectedItem + '"' : '') + ' />';

    	var CurrentItem = null;
    	if (this.options.SelectedItem) CurrentItem = this.GetItemByItemId(this.options.SelectedItem);

    	// markup before all selections
    	str += '<div class="productDetails"><div class="detailsRow">';

    	for (var p = 0; p < this.ClassificationsLength; p++) {
    		var Classification = this.options.Classifications[p];

    		str += '<input type="hidden" id="hdnClassification_' + this.options.Variable + '_' + Classification.i + '" name="hdnClassification_' + this.options.Variable + '_' + Classification.i + '" ' + (CurrentItem ? 'value="' + CurrentItem.s[p] + '"' : '') + ' />';

    		// markup before each selection
    		if (!Classification.m || Classification.m == '') {
    			str += '<div class="rowLabel floatLeft"><span title="' + Classification.n + '">' + Classification.n + '</span> <span class="selectedName" id="span_' + this.options.Variable + '_p_' + Classification.i + '"></span></div>';
    		} else {
    			str += '<div class="rowLabel floatLeft"><span title="' + Classification.n + '"><img src="' + Classification.m + '" alt="' + Classification.n + '" /></span> <span class="selectedName" id="span_' + this.options.Variable + '_p_' + Classification.i + '"></span></div>';
    		}

    		// all controls except dropdowns will have a clear link for resetting the selection
    		var clear = '<div class="floatLeft" style="display:none;margin-left:10px;" id="divClear_' + this.options.Variable + '_' + Classification.i + '"><a href="javascript:void(0);" class="smaller" onclick="window[\'' + this.options.Variable + '\'].Clear(' + Classification.i + ');' + this.options.Variable + '.UpdateDisplay(true);">Clear</a></div>';

    		// markup for each selection
    		switch (Classification.t) {
    			case "SWATCH":
    				// markup before each swatch Classification
    				str += clear;
    				str += '<div class="clear">&nbsp;</div><ul class="swatchList' + (this.options.IsSmall ? 'Small' : '') + '">\n';

    				for (var s = 0; s < Classification.s.length; s++) {
    					var Selection = Classification.s[s];
    					var alt = (Selection.a ? Selection.a : Selection.s);
    					str += '<li><a href="#" id="' + this.options.Variable + '_l_' + Selection.i + '" title="' + alt.replace('"', '&quot;') + '"><img src="' + (this.options.IsSmall ? 'small/' : '') + (Selection.m == undefined ? '' : Selection.m) + '" title="' + alt.replace('"', '&quot;') + '" alt="' + alt.replace('"', '&quot;') + '" style="width:' + this.options.SwatchWidth + 'px;height:' + this.options.SwatchHeight + 'px;" /></a></li>\n';
    				}

    				// markup after each swatch Classification
    				str += '</ul><div class="clear">&nbsp;</div>';

    				break;

    			case "TEXTLINK":
    				// markup before each textlink Classification
    				str += clear;
    				str += '<div class="clear">&nbsp;</div><ul class="textLink">\n';

    				for (var s = 0; s < Classification.s.length; s++) {
    					var Selection = Classification.s[s];
    					var alt = (Selection.a ? Selection.a : Selection.s);
    					str += '<li><a href="#" id="' + this.options.Variable + '_l_' + Selection.i + '" title="' + alt.replace('"', '&quot;') + '">' + Selection.s + '</a></li>\n';
    				}

    				// markup after each textlink Classification
    				str += '</ul><div class="clear">&nbsp;</div>';

    				break;

    			case "DROPDOWN":
    				// markup before each dropdown Classification
    				str += '<div class="clear">&nbsp;</div><select id="' + this.options.Variable + '_p_' + Classification.i + '" onchange="' + this.options.Variable + '.Select(' + Classification.i + ',this.value,true);"><option value="">' + Classification.a + '</option>';

    				for (var s = 0; s < Classification.s.length; s++) {
    					var Selection = Classification.s[s];
    					str += '<option value="' + Selection.i + '" ' + (CurrentItem && CurrentItem.s[p] == Selection.i ? 'selected="selected"' : '') + '>' + Selection.s + '</option>';
    				}

    				// markup after each dropdown Classification
    				str += '</select><div class="clear">&nbsp;</div>';

    				break;

    			case "RADIO":
    				// markup before each radio button Classification
    				str += clear;
    				str += '<div class="clear">&nbsp;</div>';

    				for (var s = 0; s < Classification.s.length; s++) {
    					var Selection = Classification.s[s];
    					var alt = (Selection.a ? Selection.a : Selection.s);
    					str += '<span style="white-space:nowrap;"><label style="margin-right:10px;" title="' + alt.replace('"', '&quot;') + '"><input type="radio" id="' + this.options.Variable + '_r_' + Selection.i + '" name="' + this.options.Variable + '_p_' + Classification.i + '" onmouseover="" onmouseout="" />' + Selection.s + '</label></span> ';
    				}

    				// markup after each radio button Classification
    				str += '<div class="clear">&nbsp;</div>';

    				break;
    		}
    	}

    	// markup following all selections
    	str += '</div></div>';

    	// render the controls
    	this.Container.innerHTML = str;

        if(!this.options.OnlySelections) {
    	    var btn = this.getSelectionElement(this.options.AddToCartBtn);
    	    if (btn) btn.onclick = new Function("window['" + this.options.Variable + "'].AddToCart();return false;");

    	    btn = this.getSelectionElement(this.options.AddToWishlistBtn);
    	    if (btn) btn.onclick = new Function("window['" + this.options.Variable + "'].AddToWishlist();return false;");

        }

    	if (CurrentItem) {
    		if (this.ClassificationsLength > 0) {
    			for (var p = 0; p < this.ClassificationsLength; p++) {
    				var Classification = this.options.Classifications[p];
    				this.Select(Classification.i, CurrentItem.s[p], true);
    			}
    		} else {
    			this.UpdateAvailability();
    		}
    	} else if (this.options.Classifications && this.ClassificationsLength > 0) {
            var selected = false;
            for (var p = 0; p < this.ClassificationsLength; p++) {
                var Property = this.options.Classifications[p];
                if (Property.s.length == 1) {
                    var Selection = Property.s[0];
                    this.Select(Property.i, Selection.i, true);
                    selected = true;
                }
            }
            if (!selected) this.Select(this.options.Classifications[0].i, "", true);
        }
    };

    this.Select = function(p, id, clicked) {
    	var Classification = this.GetClassificationByClassificationId(p);

        var h = this.getSelectionElement("hdnClassification_" + this.options.Variable + "_" + p);

        // store the previous value
        var prev = h.value;

        // clear current selections
        this.Clear(p);

        // set the current selection id
        h.value = id;

        // if the current selection has not been specified update display and exit
        if (id == "") { this.UpdateDisplay(true); return; }

        var Selection = this.GetSelectionBySelectionId(id);

        switch (Classification.t) {
            case "SWATCH":
                // set active status for current selection
                this.getSelectionElement(this.options.Variable + '_l_' + Selection.i).className = "active";
                break;

            case "TEXTLINK":
                // set active status for current selection
                this.getSelectionElement(this.options.Variable + '_l_' + Selection.i).className = "active";
                break;

            case "DROPDOWN":
                break;

            case "RADIO":
                // set checked status for current selection
                this.getSelectionElement(this.options.Variable + '_r_' + Selection.i).checked = true;
                break;
        }

        // set the selection text
        this.getSelectionElement("span_" + this.options.Variable + "_p_" + Classification.i).innerHTML = Selection.s;

        // show the clear link
        var clr = this.getSelectionElement("divClear_" + this.options.Variable + "_" + Classification.i);
        if (clr) clr.style.display = "";

        // update the display
        this.UpdateDisplay(clicked, Classification);
    };

    this.UpdateDisplay = function(clicked, objClassification) {
        var v = this.options.Variable;

        // string to help lookup the selected item (comma-separated SelectionIds)
        var str = '';
        var conn = '';

        // array with same length as # of Classifications for holding SelectionId associated with each Classification
        var arr = new Array;

        // number of selections made on the page
        var SelectedCount = 0;

        // loop through Classifications to populate the array
        for (var p = 0; p < this.ClassificationsLength; p++) {
            var Classification = this.options.Classifications[p];
            h = this.getSelectionElement("hdnClassification_" + v + "_" + Classification.i);
            str += conn + h.value;
            if (h.value == "") {
                // no selection, default to zero
                arr[arr.length] = 0;
            } else {
                // add the selection to the array
                arr[arr.length] = parseInt(h.value);

                // increment the counter
                SelectedCount++;
            }
            conn = ',';
        }

        var CurrentItem = this.Items[v + '_Item_' + str];

        // if CurrentItem is null and this Classification marked as image upload, set current item to first item with current selection
        var origClicked = clicked;
        if (!CurrentItem && objClassification && objClassification.u && this.getSelectionElement("hdnClassification_" + v + "_" + objClassification.i).value != "") {
            var val = parseInt(this.getSelectionElement("hdnClassification_" + v + "_" + objClassification.i).value);
            for (var x = 0; x < this.ItemsLength; x++) {
                if ($.inArray(val, this.options.Items[x].s) > -1) {
                    clicked = true;
                    CurrentItem = this.options.Items[x];
                    break;
                }
            }
        } else if (CurrentItem) {
            clicked = true;
        }

        if (clicked && (CurrentItem || SelectedCount == 0)) {
            // reset clicked state back to original status
            clicked = origClicked;

            // refresh item data, pull from cache if available
            var cachekey = 'ItemInfo_' + v + '_' + (CurrentItem ? CurrentItem.i : "");
            var o = window[cachekey];
            if (o) {
                this.HandleItemInfo(o, clicked);
            }
            else {
                var data = {
                    'F': 'GetSelectionItemInfo',
                    'ItemId': (CurrentItem ? CurrentItem.i : this.options.Items[0].i)
                };
                if (this.options.ImageFolder) data['ImageFolder'] = this.options.ImageFolder;
                if (!CurrentItem) data['IsParent'] = 'Y';

                $.ajax({
                    type: 'GET',
                    dataType: 'JSON',
                    data: data,
                    url: globalSiteSubDirectory + '/ajax/store/ajax.aspx',
                    success: function (o) {
                        window[cachekey] = o;
                        window[v].HandleItemInfo(o, clicked);
                    }
                });
            }
        }

        this.UpdateAvailability();

        // attempt to load the valid selections from cache
        var validSelections = this.DisplayCache[arr.toString()];

        // if cache is empty load the selections
        if (!validSelections) {
            // the array of valid SelectionIds
            validSelections = [];

            // the indicies & SelectionIds of the Classifications
            var indicies = [];
            for (var c = 0; c < arr.length; c++) {
                if (arr[c] != 0) {
                    // there's a selection specified on this Classification
                    indicies[indicies.length] = { "Index": c, "Value": arr[c] };
                }
            }

            if (indicies.length == 0) {
                for (var s in this.Selections) {
                    validSelections[validSelections.length] = this.Selections[s].i;
                }
            } else {
                for (var i = 0; i < this.ItemsLength; i++) {
                    var Item = this.options.Items[i];
                    var cDiff = [];
                    for (var s = 0; s < Item.s.length; s++) {
                        if (arr[s] != 0 && Item.s[s] != arr[s]) cDiff[cDiff.length] = Item.s[s];
                        if (cDiff.length > 1) break;
                    }
                    if (cDiff.length <= 1) {
                        if (cDiff.length == 0) {
                            for (var s = 0; s < Item.s.length; s++) {
                                if ($.inArray(Item.s[s], validSelections) == -1)
                                    validSelections[validSelections.length] = Item.s[s];
                            }
                        } else {
                            if ($.inArray(cDiff[0], validSelections) == -1)
                                validSelections[validSelections.length] = cDiff[0];
                        }
                    }
                }
            }

            // update the cache
            this.DisplayCache[arr.toString()] = validSelections;
        }

        var userAgent = navigator.userAgent.toLowerCase();
        var is_iOS = (userAgent.indexOf('iphone') >= 0 || userAgent.indexOf('ipad') >= 0 || userAgent.indexOf('ipod') >= 0) ? true : false;

        // update display status and event handlers
        for (var p = 0; p < this.ClassificationsLength; p++) {
            var Classification = this.options.Classifications[p];

            var h = this.getSelectionElement("hdnClassification_" + v + "_" + Classification.i);
            var prev = h.value;

            switch (Classification.t) {
                case "SWATCH":
                    // loop the selections
                    for (var s = 0; s < Classification.s.length; s++) {
                        var Selection = Classification.s[s];
                        // if the selection is not valid disable the control
                        var elem = this.getSelectionElement(v + '_l_' + Classification.s[s].i);
                        var tags = elem.getElementsByTagName('IMG');
                        for (var img = 0; img < tags.length; img++) {
                            parseInt(h.value) == Classification.s[s].i ? tags[img].className = "active" : tags[img].className = "";
                        }
                        if (SelectedCount > 0 && $.inArray(Classification.s[s].i, validSelections) == -1) {
                            elem.onclick = function() { return false; };
                            elem.onmouseover = null;
                            elem.onmouseout = null;
                            elem.className = 'disabled';
                            for (var img = 0; img < tags.length; img++) {
                                tags[img].className = 'disabled';
                            }
                            elem.getElementsByTagName('IMG').className = 'disabled';
                        } else {
                            elem.onclick = new Function("window['" + v + "'].Select(" + Classification.i + ", " + Selection.i + ", true); return false;");
                            if (clicked && !is_iOS) {
                                // only use mouse events if not an iOS touch device.
                                elem.onmouseover = new Function("window['" + v + "'].Select(" + Classification.i + ", " + Selection.i + ", false);");
                                elem.onmouseout = new Function("window['" + v + "'].Select(" + Classification.i + ", " + (prev == "" ? "'" + prev + "'" : prev) + ", false);");
                            }
                        }
                    }
                    break;

                case "TEXTLINK":
                    // remove all disabled status
                    for (var s = 0; s < Classification.s.length; s++) {
                        var Selection = Classification.s[s];
                        // if the selection is not valid disable the control
                        var elem = this.getSelectionElement(v + '_l_' + Classification.s[s].i);
                        parseInt(h.value) == Classification.s[s].i ? elem.className = "active" : elem.className = "";
                        if (SelectedCount > 0 && $.inArray(Classification.s[s].i, validSelections) == -1) {
                            elem.onclick = function() { return false; };
                            elem.onmouseover = null;
                            elem.onmouseout = null;
                            elem.className = 'disabled';
                        } else {
                            elem.onclick = new Function("window['" + v + "'].Select(" + Classification.i + ", " + Selection.i + ", true); return false;");
                            if (clicked && !is_iOS) {
                                // only use mouse events if not an iOS touch device.
                                elem.onmouseover = new Function("window['" + v + "'].Select(" + Classification.i + ", " + Selection.i + ", false);");
                                elem.onmouseout = new Function("window['" + v + "'].Select(" + Classification.i + ", " + (prev == "" ? "'" + prev + "'" : prev) + ", false);");
                            }
                        }
                    }
                    break;

                case "DROPDOWN":
                    var d = $("#" + v + "_p_" + Classification.i);
                    var val = d.val();

                    var html = '<option value="">' + Classification.n + '</option>';
                    for (var s = 0; s < Classification.s.length; s++) {
                        var Selection = Classification.s[s];
                        if (SelectedCount > 0 && $.inArray(Classification.s[s].i, validSelections) == -1) {
                            html += '<option value="' + Selection.i + '" disabled="disabled" onclick="return false;" style="color:#ccc;">' + Selection.s + '</option>';
                        } else {
                            html += '<option value="' + Selection.i + '"' + (parseInt(h.value) == Classification.s[s].i ? ' selected="selected"' : '') + '>' + Selection.s + '</option>';
                        }
                    }
                    d.html(html);
                    break;

                case "RADIO":
                    for (var s = 0; s < Classification.s.length; s++) {
                        var Selection = Classification.s[s];
                        // if the selection is not valid disable the control
                        var elem = this.getSelectionElement(v + '_r_' + Classification.s[s].i);
                        parseInt(h.value) == Classification.s[s].i ? elem.checked = true : elem.checked = false;
                        elem.disabled = false;
                        if (SelectedCount > 0 && $.inArray(Classification.s[s].i, validSelections) == -1) {
                            elem.onclick = function() { return false; };
                            elem.disabled = true;
                        } else {
                            elem.onclick = new Function("window['" + v + "'].Select(" + Classification.i + ", " + Selection.i + ", true);");
                        }
                    }
                    break;
            }
        }
    };

    // update fields with new item data
    this.HandleItemInfo = function(o, clicked) {
        if (!o.Success) return;

        var properties = this.ItemProperties;
        for (var x = 0; x < o.ItemProperties.length; x++) {
            var p = o.ItemProperties[x];
            var ip = properties['IP_' + p.N];
            if (ip && (clicked || ip.OnHover)) {
                if (!ip.T) ip.T = $(ip.Target);
                if (ip.T.length > 0) {
                    switch (ip.Type) {
                        case "SINGLE":
                            ip.T.html(p.V);
                            break;

                        case "IMAGE":
                            ip.T.attr('src', p.V).attr('alt', p.Alt);
                            break;

                        case "HREF":
                            ip.T.attr('href', "javascript:void(0);");
                            ip.T.unbind("click").click(new Function("window.location = \"" + p.V + "\";return false;"));
                            break;

                        case "PRINTHREF":
                            ip.T.attr('href', p.V);
                            break;

                        case "SENDWINDOW":
                            ip.T.attr("onclick", "BaseModule.NewWindow('" + p.V + "', 'sendtofriend', 700, 430, 'yes', 'no'); return false;");
                            break;
                    }
                    // if the value is empty hide the target
                    p.V == "" ? ip.T.hide() : ip.T.show();
                }
            }
        }
    };

    this.UpdateAvailability = function() {
        var v = this.options.Variable;

        // string to help lookup the selected item (comma-separated SelectionIds)
        var str = '';
        var conn = '';

        // array with same length as # of Classifications for holding SelectionId associated with each Classification
        var arr = new Array;

        // number of selections made on the page
        var SelectedCount = 0;

        var CurrentItem = null;
        if (this.ClassificationsLength > 0) {
            // loop through Classifications to populate the array
            for (var p = 0; p < this.ClassificationsLength; p++) {
                var Classification = this.options.Classifications[p];
                h = this.getSelectionElement("hdnClassification_" + v + "_" + Classification.i);
                str += conn + h.value;
                if (h.value == "") {
                    // no selection, default to zero
                    arr[arr.length] = 0;
                } else {
                    // add the selection to the array
                    arr[arr.length] = parseInt(h.value);

                    // increment the counter
                    SelectedCount++;
                }
                conn = ',';
            }

            // check for existing item
            CurrentItem = this.Items[v + '_Item_' + str];
        } else if (this.options.Items.length > 0) {
            CurrentItem = this.options.Items[0];
        }

        // if item found, populate the hidden input and lookup the item info
        if (CurrentItem) {
            this.getSelectionElement("hdnItem_" + v).value = CurrentItem.i;

            if ((typeof this.options.ci !== 'undefined' && this.options.ci) || this.options.OnlySelections) return;

            var email = (this.Email ? this.Email : "");

            var ctrl = this.getSelectionElement(this.options.AddToCartBtn).parentNode; // in this case we have a SPAN wrapper (the parent), but typically you'll want to hide the button itself
            ctrl.style.display = "";

            if (this.options.IsQuickView) {
                var vd = this.getSelectionElement(this.options.DetailsContainer);
                if (CurrentItem.q <= 0) {
                    vd.style.display = "";
                    ctrl.style.display = "none";
                    $('#' + this.options.QuantityTextBox).parent().hide();
                } else {
                    vd.style.display = "none";
                    $('#' + this.options.QuantityTextBox).parent().show();
                }
                
            } else {
                var em = this.getSelectionElement(this.options.EmailContainer);
                em.style.display = "none";
                if (this.options.EnableInventory) {
                    if (CurrentItem.q <= 0) {
                        if (CurrentItem.c != 'Backorder') {
                            ctrl.style.display = "none";
                            em.innerHTML = '<div style="margin-bottom:10px;"><strong>Sorry, this item is currently out of stock!</strong><br />Enter your email address below to receive notification when it becomes available.<div style="margin-top:4px;" class="formee"><input type="text" class="text" id="' + v + '_txtEmailMe" maxlength="100" value="' + email + '" onkeypress="var e = event; var code = (e.which ? e.which : e.keyCode); if (code == 13) {window[\'' + v + '\'].EmailMe(); return false; } window[\'' + v + '\'].Email = this.value;" onkeyup="window[\'' + v + '\'].Email = this.value;" /> <span class="btnWrapper btnFullWidth"><input type="button" class="btn" value="Submit" onclick="window[\'' + v + '\'].EmailMe();" /></span></div></div>';
                            em.style.display = "";
                        }
                        else {
                            var bdate = '';
                            if (CurrentItem.b) bdate = '<br />Estimated Ship Date: ' + CurrentItem.b;
                            em.innerHTML = '<div style="margin-bottom:10px;"><strong>This item is currently on backorder.</strong>' + bdate + '</div>';
                            em.style.display = "";
                        }
                    }
                }
            }
        }
    };

    this.Clear = function(p) {
    	var Classification = this.GetClassificationByClassificationId(p);

        // clear the current ItemId
        this.getSelectionElement("hdnItem_" + this.options.Variable).value = "";

        // clear this Classification's current selection
        var h = this.getSelectionElement("hdnClassification_" + this.options.Variable + "_" + Classification.i);
        if (h.value == "") return;
        h.value = "";

        // clear the selection text
        this.getSelectionElement("span_" + this.options.Variable + "_p_" + Classification.i).innerHTML = "";

        if (!this.options.OnlySelections && !this.options.IsQuickView) {
            //reset the add to cart button style
            var ctrl = this.getSelectionElement(this.options.AddToCartBtn).parentNode;
            ctrl.style.display = "";

            // clear the email container
            var em = this.getSelectionElement(this.options.EmailContainer);
            em.innerHTML = ""
            em.style.display = "none";

            // hide the clear link
            var clr = this.getSelectionElement("divClear_" + this.options.Variable + "_" + Classification.i);
            if (clr) clr.style.display = "none";

            switch (Classification.t) {
                case "SWATCH":
                    // loop the selections
                    for (var s = 0; s < Classification.s.length; s++) {
                        var Selection = Classification.s[s];
                        // if the selection is not valid disable the control
                        var elem = this.getSelectionElement(this.options.Variable + '_l_' + Classification.s[s].i);
                        elem.className = '';
                        var tags = elem.getElementsByTagName('IMG');
                        for (var img = 0; img < tags.length; img++) {
                            tags[img].className = '';
                        }
                    }
                    break;

                case "TEXTLINK":
                    // loop the selections
                    for (var s = 0; s < Classification.s.length; s++) {
                        var Selection = Classification.s[s];
                        // if the selection is not valid disable the control
                        var elem = this.getSelectionElement(this.options.Variable + '_l_' + Classification.s[s].i);
                        elem.className = '';
                    }
                    break;

                case "DROPDOWN":
                    break;

                case "RADIO":
                    // loop the selections
                    for (var s = 0; s < Classification.s.length; s++) {
                        var Selection = Classification.s[s];
                        // if the selection is not valid disable the control
                        var elem = this.getSelectionElement(this.options.Variable + '_r_' + Classification.s[s].i);
                        elem.checked = false;
                        elem.disabled = false;
                    }
                    break;
            }
        }
        
    };

    // add the selected item to the shopping cart
    this.AddToCart = function () {
        if (!this.ValidateSelections()) return;

        var id = this.getSelectionElement("hdnItem_" + this.options.Variable).value;

        //Get the quantity
        var Quantity = $('#' + this.options.QuantityTextBox);
        var qty = 1;
        if (Quantity.length > 0) qty = Quantity.val();
        if (!parseInt(qty) || parseInt(qty) < 1) {
            alert("Please enter a valid numeric quantity");
            Quantity.focus();
            return;
        }
        qty = parseInt(qty);

        //Get the recipient
        var drp = $('#' + this.options.RecipientDropDown);
        var txt = $('#' + this.options.RecipientTextBox);

        var rec = 'Myself';
        var specificRecipient = null;
        if (drp.length > 0) rec = drp.val();
        if (rec == 'OtherSpecify' && txt.length > 0) {
            specificRecipient = txt.val();
            if (BaseModule.isEmpty(specificRecipient)) {
                alert('Please enter the recipient name.');
                txt.focus();
                return;
            }
        }
        AddToCart(undefined, id, qty, rec, specificRecipient, this.options);
    };

    // add the selected item to the member wishlist
    this.AddToWishlist = function() {
        if (!this.ValidateSelections()) return;

        var id = this.getSelectionElement("hdnItem_" + this.options.Variable).value;

        //Get the quantity
        var cqty = $('#' + this.options.QuantityTextBox);
        var qty = 1;
        if (cqty.length > 0) qty = cqty.val();
        if (!parseInt(qty) || parseInt(qty) < 1) {
            alert("Please enter a valid numeric quantity");
            cqty.focus();
            return;
        }
        qty = parseInt(qty);

        //Get the recipient
        var drp = $('#' + this.options.RecipientDropDown);
        var txt = $('#' + this.options.RecipientTextBox);

        var rec = 'Myself';
        var specificRecipient = null;
        if (drp.length > 0) rec = drp.val();
        if (rec == 'OtherSpecify' && txt.length > 0) {
            specificRecipient = txt.val();
            if (BaseModule.isEmpty(specificRecipient)) {
                alert('Please enter the recipient name.');
                txt.focus();
                return;
            }
        }

        var data = {
            'F': 'AddToWishlist',
            'ItemId': id,
            'OrderItemId': (this.options.OrderItemId ? this.options.OrderItemId : 0),
            'WishlistItemId': (this.options.WishlistItemId ? this.options.WishlistItemId : 0),
            'Qty': qty,
            'Recipient': rec,
            'SpecificRecipient': specificRecipient,
            'ValueId': (this.options.ValueId ? this.options.ValueId : 0)
        };

        if (!this.ValidateCertAndPopulateRequestData(data)) return;

        $.ajax({
            type: 'POST',
            dataType: 'json',
            data: data,
            url: globalSiteSubDirectory + '/ajax/store/ajax.aspx',
            success: function (o) {
                if (!o.Success) {
                    if (o.Error) alert(o.Error);
                    return;
                }
                window.location = o.Url;
            }
        });
    };

    // validate all the selections have been made
    this.ValidateSelections = function() {
        var id = this.getSelectionElement("hdnItem_" + this.options.Variable).value;
        if (!parseInt(id) || parseInt(id) == 0) {
            var str = "";
            var count = 0;
            var conn = "";
            for (var p = 0; p < this.ClassificationsLength; p++) {
                var Classification = this.options.Classifications[p];
                var h = this.getSelectionElement("hdnClassification_" + this.options.Variable + "_" + Classification.i);
                if (h.value == "") {
                    str += conn + Classification.n;
                    count++;
                    conn = "\n";
                }
            }
            count == 1 ? alert("Please make a selection for attribute \"" + str + "\"") : alert("Please make selections for the following attributes:\n\n" + str);
            return false;
        }
        return true;
    };

    this.EmailMe = function(Cancel, Email) {
        if (!this.ValidateSelections()) return;

        var v = this.options.Variable;
        var c = this.options.EmailContainer;
        var t = this.getSelectionElement(v + "_txtEmailMe");

        if (!Email) Email = t.value;
        var data = {
            'F': 'EmailMe',
            'Email': Email,
            'ItemId': this.getSelectionElement("hdnItem_" + v).value,
            'Cancel': (Cancel ? Cancel : "")
        };

        $.ajax({
            url: globalSiteSubDirectory + '/ajax/store/ajax.aspx',
            data: data,
            dataType: 'json',
            type: 'POST',
            aysnc: false,
            success: function (o) {
                var boldText = '';
                var secondLine = '';
                var makeLink = function (onClick) { return '<a href="#" onclick="' + onClick + ' return false;">Click here</a>'; }

                if (!o.Success) {
                    if (!o.Exists) {
                        alert(o.Error ? o.Error : 'An error occurred. Please try again.');
                        $('#' + t).focus();
                        return;
                    }

                    boldText = 'The email address provided has already been submitted for notification.';
                    secondLine = makeLink('window[\'' + v + '\'].EmailMe(\'Y\', \'' + Email + '\');') + ' to cancel this notification.';
                }
                else {
                    if (Cancel) {
                        boldText = 'Your email address has been removed.';
                        secondLine = makeLink('window[\'' + v + '\'].UpdateAvailability();') + ' to add your email address again.';
                    }
                    else {
                        boldText = 'Thank you, we have received your request.';
                        secondLine = 'You will be notified when this product becomes available.';
                    }
                }

                $('#' + c).html('<div style="margin-bottom:10px;"><b>' + boldText + '</b><br />' + secondLine + '</div>');
            }
        });
    };

    this.HandleKeyPress = function(e) {
        var code = (e.which ? e.which : e.keyCode);
        if (code == 13) {
            this.AddToCart();
            return false;
        }
        return true;
    };
};

function AddToCart(drpSelId,itemId, quantity, rec, specificRecipient, options) {
    var id = itemId;
    if (drpSelId != undefined) {
        if (!ValidateSelections(drpSelId)) return;
        id = $(drpSelId).val();
    }
    
    var qty = 1;
    if (quantity != undefined) qty = quantity;

    var PreCallBack;
    var CallBack;
    var DisableSlider;

    if (options != undefined) {
        PreCallBack = options.AddToCartPreCallBack;
        CallBack = options.AddToCartCallBack;
        DisableSlider = options.DisableSlider;
    }
    var data = {
        'F': 'AddToCart',
        'ItemId': id,
        'OrderItemId': (options ? (options.OrderItemId ? options.OrderItemId : 0) : 0),
        'Qty': qty,
        'Recipient': (rec ? rec: 0),
        'SpecificRecipient': (specificRecipient ? specificRecipient : 0),
        'ValueId': (options ? (options.ValueId ? options.ValueId : 0) : 0 )
    };

    ValidateCertAndPopulateRequestData(data,options);

    $.ajax({
        url: globalSiteSubDirectory + '/ajax/store/ajax.aspx',
        dataType: 'json',
        type: 'POST',
        data: data,
        success: function (o) {
            if (!o.Success) {
                alert((o.Error ? o.Error : 'An error occurred while trying to add the item to your cart.'));
                return;
            }
            if (PreCallBack) PreCallBack(o);

            var html = '';
            if (!o.Details || !o.Details.AddedQuantity || o.Details.AddedQuantity == 0) {
                $("#AddToCartHeader").html('<span class="red">Item was not added to your cart</span>');
                html = '<span class="smaller bold red">' + o.Details.ErrorMessage + '</span>';
            }
            else {
                $("#AddToCartHeader").html("Product Added to Your Cart");
                html += '<div class="itemLink">';
                if (o.Image) html += '	<img class="itemImage" src="' + o.Image + '" />';
                html += '</div>';
                html += '<div class="itemContent">';
                if (o.ItemName) html += '	<div class="itemTitle">' + o.ItemName + '</div>';

                html += '	<div class="item-dialog-details">';

                if (o.Details.Recipient)
                    html += '<div class="smaller"><span class="bold">Ship To:</span> ' + o.Details.Recipient + '</div>';

                if (o.Selections) {
                    html += '		<ul class="prodInfo smaller pp">' + o.Selections + '</ul>';
                }


                if (o.Details.ErrorMessage)
                    html += '			<div style="padding:6px 0 0 0;" class="smaller red">' + o.Details.ErrorMessage + '</div>';
                html += '	<div class="itemPrice">';
                html += '		<span>' + o.Price + '</span>';
                html += '	</div>';
                html += '		</div>';
                html += '	</div>';
                html += '</div>';
            }
            $('#divItemAdded').html(html);
            $('span[id="spanCartTotal"]').html(o.TotalQuantity);


            if (!DisableSlider) showRecentCart();

            if (CallBack) CallBack(o);
        }
    });
}

function ValidateSelections(drpSelId) {
    var $drpSelId = $(drpSelId);
    if (!$drpSelId) {
        alert("An error occurred while trying to add the item to your cart.");
        return false;
    }
    if ($drpSelId.val() == '') {
        alert("Please make a selection for attribute \"" + $(drpSelId).children('option').filter(':selected').text() + "\"");
        return false;
    }
    return true;
}

function ValidateCertAndPopulateRequestData(data, options) {
    if (!options) return true;
    if (typeof options.ci !== 'undefined' && options.ci) {
        var fullError = '';
        var isNotValid = function (e, t, aj, isOptional, additionalValidation) {
            var $e = $('#' + e);
            var v = '';
            if ($e.length > 0) v = $e.val();
            if (BaseModule.isEmpty(v) && !isOptional) {
                fullError += 'Please enter a "' + t + '" for the certificate.\n';
                return true;
            }
            if (typeof additionalValidation === 'function') {
                if (additionalValidation(t, v)) {
                    return true;
                }
            }

            data[aj] = v;
            return false;
        };

        var failed = false;
        failed = isNotValid(options.CertFromName, 'From Name', 'CertFromName', false) || failed;
        failed = isNotValid(options.CertToName, 'To Name', 'CertToName', false) || failed;
        failed = isNotValid(options.CertToEmail, 'Recipient E-mail', 'CertEmail', false, function (t, v) {
            var regexp = /^[A-Za-z0-9']([\.\-]?[a-zA-Z0-9'_])*\@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,5}$/;
            if (!regexp.test(v)) {
                fullError += 'Please enter a valid e-mail address for "' + t + '".\n';
                return true;
            }
            return false;
        }) || failed;
        failed = isNotValid(options.CertType, 'Certificate Type', 'CertType', true) || failed;
        failed = isNotValid(options.CertMessage, 'Certificate Message', 'CertMessage', true) || failed;

        if (failed) {
            alert(fullError);
            return false;
        }
    }
    return true;
};