﻿/// <reference path="../Plugins/jquery-1.3.2-vsdoc.js" />
Type.registerNamespace("Controls");


/// <summary>
/// V1.1 enables/disables attributes accordning to available variants
/// Depends:
/// jquery-1.4.js
///                       ui.core.js
/// ExtendJquery.js
/// MicrosoftAjax.js
/// </summary>
Controls.VariantFilter = function() {
}
Controls.VariantFilter.prototype =
{
    _init: function() {
        $(this.element).show();
        if (this.options.noVariantsElement != null) {
            $(this.options.noVariantsElement).hide();
        }

        var callback = this._onAttributeClick;
        var pThis = this;
        var delegate = Function.createDelegate(pThis, callback);
        $(this.options.attributeElement, this.element).each(function() {
            if ($(this).is('input')) {
                //$(this).click(delegate);
                $(this).click($.createEventDelegate(pThis, callback));
            }
            else if ($(this).is('select')) {

                var selectElement = this;
                $(this).bind("change", function(event) {
                    if ($(this).data("oldValue") != $(this).val()) {
                        $(this).data("oldValue", $(this).val());
                        delegate(selectElement, event);
                    }
                }).each(function() { $(this).data("oldValue", $(this).val()) });
                //$(this).change($.createEventDelegate(pThis, callback));
            }
        });

        if (this.options.variantJson != null) {
            for (i = 0; i < this.options.variantJson.length; i++) {
                var item = this.options.variantJson[i];
                // Set avaiable attributes accoring to selected variant
                if (item.ID == $(this.options.attributeDropDown).val()) {
                    this.SetAvailableAttributesInGUI(item.AttributeValues, true, this.options.autoEnable);
                    return;
                }
            }
        }
    },
    _onAttributeClick: function(element, event) {
        return this._doClick(element, true);
    },
    _doClick: function(element, automaticEvent) {
        var attributeChecked = false;
        var selectedAttrId = $(element).val();
        if ($(element).is('input')) {
            attributeChecked = $(element).attr('checked');
        } else if ($(element).is('select')) {
            attributeChecked = parseIntForced(selectedAttrId) > 0;
        }

        var attributes = this.GetSelectedAttributes();
        var availableVariants = this.GetAvailableVariants(attributes);
        var availableAttributes = this.GetAvailableAttributes(availableVariants);

        if (availableVariants.length == 0) {
            if (this.options.noVariantsElement != null) {
                $(this.options.noVariantsElement).show();
            }
            var disabledOptionClass = this.options.disabledOptionClass;
            // No variants available in this attribute combo. Deselect all but last.
            $(this.options.attributeElement, this.element).each(function(i) {
                if ($(this).is('input') && $(this).attr('id')) {
                    $(this).attr('checked', false);
                }
                else if ($(this).is('select')) {
                    $(this).children('option').each(function(i) {
                        $(this).removeClass(disabledOptionClass);
                        $(this).attr('selected', i == 0);
                    });
                }
            });
            if ($(element).is('input')) {
                $(element).attr('checked', true);
                this._doClick(element, false);
            }
            else if ($(element).is('select')) {
                $(element).val(selectedAttrId);
                this._doClick(element, false);
                $(element).change();
            }
        }
        else if (availableVariants.length == 1 && attributeChecked) {
            if (this.options.noVariantsElement != null) {
                $(this.options.noVariantsElement).hide();
            }
            // Only 1 variant avaiable. Select this if last click was a check.
            this.SetAvailableAttributesInGUI(availableAttributes, this.options.autoComplete, false);
            if (this.options.autoComplete || attributes.length == availableAttributes.length) {
                if (this.options.autoEnable) {
                    this.SetAvailableAttributesInGUI(availableAttributes, true, true);
                }
                this.SelectVariant(availableVariants[0].ID);
            }
            else if (this.options.autoDeselect) {
                this.SelectVariant(null);
            }

        }
        else {
            if (this.options.autoDeselect) {
                this.SelectVariant(null);
            }
            if (automaticEvent && this.options.noVariantsElement != null) {
                $(this.options.noVariantsElement).hide();
            }
            // Multiple variants available. Show which variants are available.
            this.SetAvailableAttributesInGUI(availableAttributes, false, false);
        }

        // trigger refresh of all attribute checkboxes. Needed for hover plugin.
        $(this.options.attributeElement, this.element).trigger('refresh');
    },
    /*
    * Select a specific variant in the drop down
    */
    SelectVariant: function(id) {
        if (this.options.variantJson != null) {
            if (id == null) {
                id = $(this.options.attributeDropDown).find("option:first").val();
            }
            if ($(this.options.attributeDropDown).val() != id) {
                $(this.options.attributeDropDown).val(id);
                $(this.options.attributeDropDown).change();
            }
        }
    },
    /* 
    * Get all selected attributes
    */
    GetSelectedAttributes: function() {
        var array = [];
        $(this.options.attributeElement, this.element).each(function(index) {

            if ($(this).is('input') && $(this).attr('checked')) {
                array.push(parseIntForced($(this).attr('id')));
            }
            if ($(this).is('select') && parseIntForced($(this).val()) != 0) {
                array.push(parseIntForced($(this).val()));
            }
        });
        return array;
    },
    /* 
    * Set available attributes accoring to attribute selection and available variants
    */
    SetAvailableAttributesInGUI: function(attributes, autoCheck, enableAll) {
        $.log("Setting available attributes.");
        var callback = this._onAttributeClick;
        var pThis = this;
        var delegate = Function.createDelegate(pThis, callback);
        var disableOption = this.options.disableOptions;
        var disabledOptionClass = this.options.disabledOptionClass;
        $(this.options.attributeElement).each(function(i) {
            if ($(this).is('input')) {
                if (!enableAll && Array.indexOf(attributes, parseIntForced($(this).attr('id'))) < 0) {
                    $.log('Disable input ' + $(this).html());
                    if (disableOption) {
                        $(this).attr('disabled', true);
                    }
                    $(this).addClass(disabledOptionClass);
                    $(this).attr('checked', false);
                }
                else {
                    $.log('Enable input' + $(this).html());
                    $(this).attr('disabled', false);
                    $(this).removeClass(disabledOptionClass);
                    if (autoCheck && !enableAll)
                        $(this).attr('checked', true);
                    else if (enableAll && Array.indexOf(attributes, parseIntForced($(this).attr('id'))) >= 0)
                        $(this).attr('checked', true);

                }
            }
            if ($(this).is('select')) {
                $(this).unbind('change');
                $(this).children().each(function() {
                    if (!enableAll && Array.indexOf(attributes, parseIntForced($(this).val())) < 0) {
                        // Current option is unavailable
                        if (parseIntForced($(this).val()) > 0) {
                            $.log('Disable select ' + $(this).html());
                            $(this).addClass(disabledOptionClass);
                            $(this).attr('selected', false);
                            if (disableOption) {
                                $(this).attr('disabled', true);
                            }
                            $.log('Disabled select ' + $(this).html());
                        }
                    }
                    else {
                        // Current option as avaialable
                        $.log('Enable select ' + $(this).html());
                        $(this).attr('disabled', false);
                        $(this).removeClass(disabledOptionClass);
                        if (autoCheck && !enableAll) {
                            $(this).attr('selected', true);
                        }
                        else if (enableAll && Array.indexOf(attributes, parseIntForced($(this).val())) >= 0) {
                            $(this).attr('selected', true);
                        }
                    }
                });
                // Hack for IE and Opera. Must replace html for correct render of select element
                var val = $(this).val();
                $(this).html($(this).html());
                $(this).val(val);
                var selectElement = this;
                $(this).bind("change", function(event) {
                    if ($(this).data("oldValue") != $(this).val()) {
                        $(this).data("oldValue", $(this).val());
                        delegate(selectElement, event);
                    }
                }).each(function() { $(this).data("oldValue", $(this).val()) });
            }
        });
    },
    /*
    * Get all attributes for the specified variants
    */
    GetAvailableAttributes: function(variants) {
        var attributes = [];
        for (i = 0; i < variants.length; i++) {
            var item = variants[i];
            for (j = 0; j < item.AttributeValues.length; j++) {
                var value = item.AttributeValues[j];
                if (Array.indexOf(attributes, value) < 0)
                    attributes.push(value);
            }
        }
        $.log("Available attributes: " + attributes.join(", "));
        return attributes;
    },
    /*
    * Get all available variants as Json array
    */
    GetAvailableVariants: function(attributes) {
        var variantsAsJson = [];
        var variantsAsID = [];
        if (this.options.variantJson == null)
            return res;
        for (var i = 0; i < this.options.variantJson.length; i++) {
            var variant = this.options.variantJson[i];
            var addThis = true;
            for (j = 0; j < attributes.length; j++) {
                var attributeValue = attributes[j];
                if (Array.indexOf(variant.AttributeValues, attributeValue) < 0) {
                    addThis = false;
                }
            }
            if (addThis) {
                variantsAsJson.push(variant);
                variantsAsID.push(variant.ID);
            }
        }
        $.log("Available variants: " + variantsAsID.join(", "));
        return variantsAsJson;

    },

    defaults: {
        attributeElement: ".variantAttribute",
        attributeDropDown: "#variantsDropDown",
        noVariantsElement: null,
        disabledOptionClass: "Disabled",
        disableOptions: false,
        variantJson: null,
        autoEnable: true,
        autoComplete: false,
        autoDeselect: true

    }
}

Controls.VariantFilter.registerClass('Controls.VariantFilter', null, Sys.IDisposable);
$.registerAsWidget(Controls.VariantFilter);

function parseIntForced(sText) {
    var ValidChars = "0123456789.";
    var retString = "";
    for (i = 0; i < sText.length; i++) {
        if (ValidChars.indexOf(sText.charAt(i)) >= 0)
            retString += sText.charAt(i);
    }
    return parseInt(retString);
}





