var WxProductSearch= Class.create({
    initialize: function(wContainer, wUrl) {
        this.loadingIndicator= new Element('span', { 'class': 'loading_1' });
        this.loadingIndicator.innerHTML= 'Loading...';

        this.url= wUrl;

        this.container= $(wContainer);
        this.container.insert({'top': this.loadingIndicator.hide()});

        this.searchPropertiesPane= this.container.up('form').down('#search_product_properties_pane');
        this.searchPropertiesPaneClose= this.searchPropertiesPane.down('.popup_close');
        this.searchPropertiesPaneContainer= this.searchPropertiesPane.down('.product_properties');

        this.searchPropertiesPopup= new WxPopup('search_product', '#search_product_properties_anchor', {
            autoOpen: false,
            callbackFindPopup: function() { return this.searchPropertiesPane; }.bind(this),
            callbackInsertPopup: function() {}
        } );

        this.searchPropertiesPopup.documentLoaded();

        this.searchOptionsPopup= new WxPopup('search_product', '#search_product_options_anchor', {
            offsetX: 5,
            callbackFindPopup: function() { return this.container.up('form').down('#search_product_options_pane'); }.bind(this),
            callbackInsertPopup: function() {}
        } );

        this.searchOptionsPopup.documentLoaded();

        this.selection= null;

        this.onAjaxSuccess= this._onAjaxSuccess.bind(this);
        this.onAjaxComplete= this._onAjaxComplete.bind(this);
        this.onChange= this._onChange.bind(this);

        this.tTreeSelect= new Template('<p>\n<select id="#{id}" name="#{id}"><option value="-">&nbsp;</option></select>\n</p>');
        this.tTreeOption= new Template('<option value="#{value}" #{selected}>#{text}</option>');
        this.tTreeOptgroup= new Template('<optgroup label="#{label}">#{html}</optgroup>');

        this.tPropertySelect= new Template('<p>#{title}<br />\n<select id="#{id}_0" name="#{id}_0" class="range" #{disabled}>#{options_range}</select>\n<select id="#{id}_1" name="#{id}_1" class="value">#{options_value}</select>\n</p>');
        this.tPropertyOption= new Template('<option value="#{value}" #{selected}>#{text}</option>');

        this.documentLoaded= this._documentLoaded.bind(this);
        this.documentUnloaded= this._documentUnloaded.bind(this);

        this.documentLoaded();

        Event.observe(window, 'unload', this.documentUnloaded);
    },

    _documentLoaded: function() {
        this.container.select('select').each(function(select) {
            this.attachEvents(select);
        }, this);

        this.searchPropertiesPaneClose.observe('click', this.searchPropertiesPopup.hidePopup);

        if (this.searchPropertiesPaneContainer.visible()) {
            this.searchPropertiesPopup.showAnchors(false);
        }
    },

    _documentUnloaded: function() {
        this.container.select('select').each(function(select) {
            this.detachEvents(select);
        }, this);

        this.searchPropertiesPaneClose.stopObserving();

        this.searchPropertiesPopup.documentUnloaded();
        this.searchOptionsPopup.documentUnloaded();
    },

    attachEvents: function(select) {
        $(select).observe('change', this.onChange);
    },

    detachEvents: function(select) {
        $(select).stopObserving('change');
    },

    //
    // Properties Popup
    //

    createSelect: function(selectId, selectContent) {
        var html= this.tTreeSelect.evaluate({'id': selectId});

        this.container.insert(html);

        var select= this.container.down('#' + selectId);

        this.buildSelect(select, selectContent);
        this.attachEvents(select);
    },

// this.tTreeOptgroup= new Template('<optgroup label="#{label}">#{html}</optgroup>');

    buildSelect: function(select, selectContent) {
        var html= '';
        var htmlOptgroup= null;
        var htmlOptgroupLabel= null;

        for (var i= 0, len= selectContent.length; i < len; i++) {
            if (selectContent[i][1] == '-') {
                if (htmlOptgroupLabel != null) {
                    html += this.tTreeOptgroup.evaluate({'label': htmlOptgroupLabel, 'html': htmlOptgroup});
                }

                htmlOptgroupLabel= selectContent[i][0];
                htmlOptgroup= '';
            } else {
                var htmlOption= this.tTreeOption.evaluate({
                    'value': selectContent[i][1],
                    'text': selectContent[i][0],
                    'selected': (selectContent[i][2] == '1' ? 'selected="selected"' : null)
                });

                if (htmlOptgroupLabel != null) {
                    htmlOptgroup += htmlOption;
                } else {
                    html += htmlOption;
                }
            }
        }

        if (htmlOptgroupLabel != null) {
            html += this.tTreeOptgroup.evaluate({'label': htmlOptgroupLabel, 'html': htmlOptgroup});
        }

        select.update(html);
    },

/*
        for (var i= 0, len= selectContent.length; i ... len; i++) {
            if (selectContent[i][1] == '-') {
                optgroup= new Element('optgroup');
                optgroup.label= selectContent[i][0];

                select.appendChild(optgroup);
            } else {
                var option= new Option();

                option.text= selectContent[i][0];
                option.value= selectContent[i][1];

                if (optgroup == null) {
                    select.appendChild(option);
                } else {
                    optgroup.appendChild(option);
                }

                if (selectContent[i][2] == '1') {
                    option.selected= true;
                }
            }
        }
*/

    buildSearchTree: function(searchTree) {
        var selects= this.container.select('select');

        for (var i= 0, len= searchTree.length; i < len; i++) {
            var wOptions= searchTree[i].wOptions;
            if (wOptions.length == 0) {
                continue;
            }

            var searchId= 'search_product_' + i;

            if (i < selects.length) {
                this.buildSelect(selects[i], wOptions);
            } else {
                this.createSelect(searchId, wOptions);
            }
        }

        for (var j= selects.length - 1, len2= searchTree.length; j >= len2; j--) {
            this.detachEvents(selects[j]);

            selects[j].up('p').remove();
        }

        this.searchPropertiesPopup.positionPopup();
    },

    buildSearchProperty: function(searchPropertyId, searchProperty) {
        if (searchPropertyId == 'search_product_property_') {
            this.searchPropertiesPopup.hideAnchors();

            this.searchPropertiesPaneContainer.update('').hide();
            this.searchPropertiesPaneContainer.id= 'search_product_property_';

            return ;
        }

        if (this.searchPropertiesPaneContainer.id == searchPropertyId) {
            return ;
        }
/*
        var p= [];

        for (var i= 0, len= searchProperty.length; i < len; i++) {
            var property= searchProperty[i];

            var id_0= 'property_' + property.pId + '_0';
            var id_1= 'property_' + property.pId + '_1';

            var o_0= new Array();
            var o_1= new Array();

            if (property.pRange == '0') {
                o_0.push(Builder.node('option', {value: '0', selected: 'selected', disabled: 'disabled'}, '='));
            } else {
                o_0.push(Builder.node('option', {value: '0', selected: 'selected'}, '='));
                o_0.push(Builder.node('option', {value: '1'}, '>='));
                o_0.push(Builder.node('option', {value: '2'}, '<='));
            }

            for (var j= 0, len2= property.pValues.length; j < len2; j++) {
                if (property.pValues[j][2] == '1') {
                    o_1.push(Builder.node('option', {value: property.pValues[j][1], selected: 'selected'}, property.pValues[j][0]));
                } else {
                    o_1.push(Builder.node('option', {value: property.pValues[j][1]}, property.pValues[j][0]));
                }
            }

            p.push(Builder.node('p', [
                Builder._text(property.pName),
                Builder.node('br'),
                Builder.node('select', {id: id_0, name: id_0, className: 'range'}, o_0),
                Builder.node('select', {id: id_1, name: id_1, className: 'value'}, o_1)
            ]));
        }

        var element= Builder.node('div', {id: searchPropertyId, className: 'product_properties'}, p);

        this.searchPropertiesPaneContainer.replace(element);
        this.searchPropertiesPaneContainer= $(searchPropertyId);
        this.searchPropertiesPaneContainer.show();

        this.searchPropertiesPopup.showAnchors(true);
*/
        var html= '';

        for (var i= 0, len= searchProperty.length; i < len; i++) {
            var property= searchProperty[i];

            var htmlDisabled= null;
            var htmlOptionsRange= null;
            var htmlOptionsValue= null;

            if (property.pRange == '0') {
                htmlOptionsRange= this.tPropertyOption.evaluate({
                    'text': '=',
                    'value': '0',
                    'selected': 'selected="selected"'
                });

                htmlDisabled= 'disabled="disabled"';
            } else {
                htmlOptionsRange= '';

                htmlOptionsRange += this.tPropertyOption.evaluate({'text': '=', 'value': '0', 'selected': 'selected="selected"'});
                htmlOptionsRange += this.tPropertyOption.evaluate({'text': '>=', 'value': '1', 'selected': null});
                htmlOptionsRange += this.tPropertyOption.evaluate({'text': '<=', 'value': '2', 'selected': null });

                if (property.pRange == '2') {
                    htmlOptionsRange += this.tPropertyOption.evaluate({'text': '~=', 'value': '3', 'selected': null});
                }
            }

            htmlOptionsValue= '';

            for (var j= 0, len2= property.pValues.length; j < len2; j++) {
                htmlOptionsValue += this.tPropertyOption.evaluate({
                    'text': property.pValues[j][0],
                    'value': property.pValues[j][1],
                    'selected': (property.pValues[j][2] == '1' ? 'selected="selected"' : null)
                });
            }

            html += this.tPropertySelect.evaluate({
                'title': property.pName,
                'id': 'property_' + property.pId,
                'disabled': htmlDisabled,
                'options_range': htmlOptionsRange,
                'options_value': htmlOptionsValue
            });
        }

        this.searchPropertiesPaneContainer.update(html).show();
        this.searchPropertiesPaneContainer.id= searchPropertyId;

        this.searchPropertiesPopup.showAnchors(true);
/*
            var selectRange= new Element('select', {'class': 'range'});
            var selectValue= new Element('select', {'class': 'value'});

            var selectRangeId= 'property_' + productProperty.pId + '_0';
            var selectValueId= 'property_' + productProperty.pId + '_1';

            selectRange.id= selectRangeId;
            selectRange.name= selectRangeId;

            selectValue.id= selectValueId;
            selectValue.name= selectValueId;

            if (productProperty.pRange == '0') {
                var option= new Option();

                option.text= '=';
                option.value= '0';
                option.selected= true;

                selectRange.appendChild(option);
                selectRange.disabled= true;
            } else {
                option= new Option();
                option.text= '=';
                option.value= '0';
                option.selected= true;

                selectRange.appendChild(option);

                option= new Option();
                option.text= '>=';
                option.value= '1';

                selectRange.appendChild(option);

                option= new Option();
                option.text= ...
                option.value= '2';

                selectRange.appendChild(option);
            }

            option= new Option();
            option.value= '0';
            option.selected= true;

            selectValue.appendChild(option);

            for (var j= 0, len2= productProperty.pValues.length; j ... len2; j++) {
                option= new Option();
                option.text= productProperty.pValues[j][0];
                option.value= productProperty.pValues[j][1];

                selectValue.appendChild(option);
            }

            var p= new Element('p');

            p.insert(productProperty.pName);
            p.insert(new Element('br'));
            p.insert(selectRange);
            p.insert(selectValue);

            this.searchPropertiesPaneContainer.insert(p);
        }

        this.searchPropertiesPaneContainer.id= searchProperty.groupId;
*/
    },

    _onAjaxSuccess: function(transport) {
        if (! transport.responseText.blank()) {
            var response= transport.responseText.evalJSON();

            this.buildSearchTree(response.searchTree);
            this.buildSearchProperty(response.searchPropertyId, response.searchProperty);
        }
    },

    _onAjaxComplete: function() {
        this.loadingIndicator.hide();
        this.selection= null;
    },

    _onChange: function(event) {
        var element= event.findElement();
        var selects= this.container.select('select');

        if (this.selection != null) {
            for (var i= 0, len= selects.length; i < len; i++) {
                if (selects[i] == element) {
                    element.selectedIndex= this.selection[i];
                    break;
                }
            }

            return ;
        }

        this.loadingIndicator.show();
        this.selection= this.container.select('select').pluck('selectedIndex');

        var parameters;

        parameters= {};
        parameters['search_product_property']= this.searchPropertiesPaneContainer.id;

        for (i= 0, len= selects.length; i < len; i++) {
            parameters[selects[i].id]= selects[i].options[selects[i].selectedIndex].value;

            if (selects[i] == element) {
                break;
            }
        }

        new Ajax.Request(this.url, {
            parameters: Object.toQueryString(parameters),
            onCreate: WxAjax.overrideMimeType,
            onSuccess: this.onAjaxSuccess,
            onComplete: this.onAjaxComplete
        } );
    }
});
