brand.search = Class.create({

    // config: Object
    // section data from site.globalnav.config[section]
    config: null,
    
    // isDefaultPanel: Boolean
    // true if search panel is the open/page panel
    isDefaultPanel: false,
    
    // resultsNode: DOM node
    // node container for results html
    resultsNode: null,

    // progressNode: DOM node
    // progress node to show while search is in progress    
    progressNode: null,

    // _hasContent: Boolean
    // false before initial search, true once search has run & there are child widgets to destroy
    _hasContent: false,
    
    // children: Array
    // widget ids for each search result     
    _children: [""],
        
    _defaultState: null,    
    _isSearching: false,
           
    initialize: function(args) {
        //console.log("brand.search.init");
       
        if (!args.config || !args.config.search) return;
        
        for (var arg in args) {
            this[arg] = args[arg];
        } 
        
        this.formField = $(this.config.search.formFieldId);
        var formSubmit = $(this.config.search.formSubmitId);
        if (!this.formField || !formSubmit) return;
        
        this._defaultState = page_data.panel_nav["default"];
      
        var psubnav = $("psubnav_" + this.config.id).widget;
        this.resultsNode = psubnav.resultsNode;
        this.contentResultsNode = psubnav.contentResultsNode;
        this.progressNode = (this.progressNode ? this.progressNode : psubnav.progressNode);
        
        this.formField.observe("keypress", this._onkeypress.bind(this));
        formSubmit.observe("click", this._onclick.bind(this));

        if (this.isDefaultPanel && this._defaultState.query) {
            this.submit({ query: this._defaultState.query });
        }
    },

    _onkeypress: function(event) { 
        if (event.keyCode != Event.KEY_RETURN) {
            return false;
        }                
        this.submit(event);      
    },
    
    _onclick: function(e) {
        this.submit(e);
    },
    
    submit: function(args) {
        if (this._isSearching) { return; }
        var query = (args && args.query) ? args.query : this.formField.value;
       
        // on error: show popover
        if ( !query || query === this._defaultState.searchDefault ) {
            var popid = this.config.search.errorPopup;
            if (popid) {
                brand.overlay.launch({
                    foregroundNode: $(popid),
                    displayInline: true,
                    removeOnHide: false,
                    displayDuration: 5000
                }); 
            }
            
            return false;
        }
         
        // if no error: execute search
        this._execute({ query: query });
    },

    _execute: function(args) {
        this._isSearching = true;
        var psubnav = $("psubnav_" + this.config.id).widget;        
        var defaultId = null;
        //console.log("brand.search._execute: "+this.parentId + " / " + $(this.parentId));
        this.reset();
        
        if (!$(this.parentId)) return; //TESTING
        
        // show progress, hide content
        this._showProgress(true);
        psubnav.resultsMessageNode.innerHTML = "";
        if (psubnav.contentResultsContainer) {
            psubnav.contentResultsContainer.addClassName("hidden");
        }
        // if triggered by form submit vs. panel click
        if (this.panelManagerId) {
            var gset = $(this.parentId).widget; 
            var pnavManager = gset.getChild(this.panelManagerId);
        }
  
        // check if default state        
        if (this.isDefaultPanel) {            
            defaultId = (this._defaultState.item.item ? this._defaultState.item.item.id : null); 
            if (this.panelManagerId) {
                this._showDefault();
            } 
        // search: open sliding panel
        } else if (pnavManager) {
            pnavManager.onTrigger(true);      
            window.parent.scrollTo(0,0); //scroll to top of screen
        }
                
        // ajax request
        var self = this;
        var onLoadArgs = {
            query: args.query,
            psubnav: psubnav,
            defaultId: defaultId
        }
        
        // wait for the panel to open before starting load (avoids animation stutters)
        // Panel.durationOpen = 400
        // TODO: create callback in Panel.js to know when panel has opened instead of using timeout
        var doRequest = function() {
            var c = self.config.content;
            var url = c.url + "?" + c.param + "=" + encodeURIComponent(args.query); 
            //var url = "/js/brand/globalnav/data/" + self.config.id + "_"+ args.query + ".txt";  
            new Ajax.Request(
                url, {
                method: 'get',
                onSuccess:  function(transport) {  
                     self.onLoad(transport.responseText, onLoadArgs)
                }.bind(this) 
             }); 
        }              
        setTimeout(doRequest, 400);
             
    },
    
    onLoad: function(data, args) {
        //console.log("brand.search.onLoad");

        this._isSearching = false;
        var self = this;
        var psubnav = args.psubnav; 
        
        if (typeof data == "string") data = data.evalJSON(true); 
        var detailItems = data.products;
        
        var hasItemInDefaultCategory = false; 
        var contentResults = data.content_results || [];
        var hasResults = (detailItems.length > 0 || contentResults.length > 0); 
        
        // reset previously rendered content/state
        if (this._hasContent) {
            this.reset();
        }
        // headers for results and no results
        //var hdNode = $(this.id + "_hd");
        var hdNode = $("psubnav_search_hd");
        if (hdNode && data.header_img) {
            hdNode.setAttribute("src", data.header_img);
            hdNode.setAttribute("alt", data.header_alt);
        }
        
        // show results count/message
        if (data.results_message) {
            psubnav.resultsMessageNode.innerHTML = data.results_message;
        } else if (!hasResults && data.no_results_message) {
            psubnav.resultsMessageNode.innerHTML = data.no_results_message;
        }
        
        if (!hasResults) {
            this._showProgress(false);
            return false;
        }
        
        // SS note: move this to where "/globalnav/event/getcontent/onload" used to fire?
        generic.events.fire({event:"search:results", msg:{ pageid: "Search", keywords: args.query, count: data.count, cat: "2200"}});
              
        // check if results contain default item 
        if (this.isDefaultPanel) {
           if (this._defaultState.query === args.query) {
                hasItemInDefaultCategory = detailItems.any(function(item){ 
                    return (item.id === args.defaultId);
                });
            }
  
            if (hasItemInDefaultCategory) {
                this.resultsNode.addClassName("panelnav_category_default");
            } else {
                 this.resultsNode.removeClassName("panelnav_category_default");
            }
        }
        
        // output content results, if they exist
        if (data.content_results) { 
             data.content_results.each( function(item, idx) {
                var detailArgs = {
                    idx: idx,
                    item: item
                };
                var detail = self._initContentSearchDetail(detailArgs);
                self._children.push(id);
                psubnav.addSubItem(detail.domNode, self.resultsNode);
                
                if (detail.startup) detail.startup(); 
            });
        }       

        detailItems.each( function(item, idx) {
            //console.log("brand.search.onLoad detailItems "+idx + "/" +  psubnav.id);
            // set if default
            var isdefault = false;
            if (!item.id) item.id = item.sku.path
            
            if (hasItemInDefaultCategory && (item.id === args.defaultId)) {
                isdefault = true;
            }
            var id = "psubitem_" + self.config.id + "_" + item.id;

            var detailArgs = {
                id: id,
                item: item,
                isdefault: isdefault,
                isInDefaultCategory: hasItemInDefaultCategory, 
                parentId: psubnav.id, 
                domParent: $(psubnav.id).widget.resultsNode
            }
           // discontinued search results
            if (self.config.id === "discontinued") {
                var detail = self._initDiscontinuedDetail(detailArgs);
                
            // main search results
            } else {
                var detail = self._initSearchDetail(detailArgs);         
            }

            self._children.push(id);
            
            // place detail node in DOM & start it up:
            if (detail.startup) detail.startup();  
        });
        
        // broadcast that search content has loaded/rendered:
        var pid;
        if (this.config.id === "search") {
            pid = "pnav_search_panel";
        }
        //JSTest dojo.publish("/globalnav/event/getcontent/onload", [{ type: "panel", id: pid, parentId: psubnav.parentId }]);
            
        this._hasContent = true; // nodes exist which will have to be destroyed before next search
        
        // hide progress, show content
        this._showProgress(false);   
    },

    _initSearchDetail: function(args) {
        //console.log("brand.search._initSearchDetail");
        var item = args.item;      
                
        var detailArgs = Object.extend(args, { 
            url: item.uri, 
            product: item,
            hdPath: item.header,
            //hdHeight: item.header_image_height,
            displayName: item.name,
            description: item.short_desc,
            thumbPath: item.thumb,
            hex: (item.shade_result ? item.sku.color[0] : ""),
            shadename: (item.shade_result ? item.sku.shade_name : "") 
        });
        
        if ( item.is_giftcard == 1 )  {
            detailArgs.templatePath = "jsTemplates.globalnav.SearchGiftcard";
            var detail = new brand.globalnav.SearchProductDetail(detailArgs);
        } else if ( item.is_custom_palette == 1 )  {
            detailArgs.templatePath = "jsTemplates.globalnav.SearchCustomPalette";
            var detail = new brand.globalnav.SearchProductDetail(detailArgs);        
        } else if ( item.shade_result || !item.shaded ) {
            var detail = new brand.globalnav.SearchQuickBuyDetail(detailArgs);
        } else {
            try {
                var detail = new brand.globalnav.SearchProductDetail(detailArgs);    
            } catch(err) {
                console.log("brand.search._initSearchDetail error " + err.description);
            }
        }           
            
        return detail;
    },

    _initContentSearchDetail: function(args) {
        // TODO: mac jp version has not been tested.  may be missing necessary args
        var id = "psubitem_" + this.config.id + "_content_" + args.idx;
        var item = args.item;        
        var detail = new brand.globalnav.Detail({
            id: id,
            templatePath: "jsTemplates.globalnav.SearchContentDetail",
            url: item.url,
            description: item.short_desc,
            isdefault: false,
            isInDefaultCategory: false
        });    

        return detail;
    },
    
    _initDiscontinuedDetail: function(args) {
        var item = args.item;   
        var detail = new brand.globalnav.DiscontinuedProductDetail({
            id: args.id,
            url: item.uri,
            displayName: item.name,
            hdPath: item.header,
            thumbPath: item.thumbnail,
            description: item.description,
            sku: item.sku,
            shadedResult: (item.shade_result == 1 ? true : false),            
            isdefault: args.isdefault,
            isInDefaultCategory: args.isInDefaultCategory
        });  
        
        return detail;
    },

    _showProgress: function(/* Boolean */state) {
        // toggle display of progress & content
        var s = this.progressNode.style;
        if (state) {
            s.display = "block";
            this.resultsNode.style.display = "none"; 
        } else {
            s.display = "none";
            this.resultsNode.style.display = "block";
        }
    },
    
    reset: function() {
        //console.log("brand.search.reset");
        this.resultsNode.innerHTML = "";
     
        this._showProgress(true);
        this._hasContent = false;
    },
    
    _showDefault: function() {
        var parent = $("globalnav_container").widget;
        // tell parent set to bring focus back to default
        if (parent.onChildClick && (parent.activeItemId !== "")) {
            parent.onChildClick(this.config.id, true);
        }
    }
    
});
