// summary:
//      Classes for elements needed to construct a panel:
//      Panel, PanelNavSet, PanelNav

  
brand.globalnav.PanelNavSet = Class.create(Widget,  
{
    // summary:
    //      Parent controller for multiple PanelNavs & PanelSubNavs associated with
    //      a single Panel (1 to many relationship)
    //      (Ex: Shop Products section only has 1 panel for all its subsections)
        
    isContainer: true,

    // parentId: String
    // parent object id 
    parentId: null,
    
    // isPanelSet: Boolean
    // referenced by PanelNav children to indicate that PanelNav's parent is a PanelNavSet (rather than globalnav container)
    isPanelSet: true,

    // panelId: String
    // Panel to slide in/out    
    panelId: "",
    
    // activeItemId: String
    // currently active/open NavItem
    activeItemId: "",
    
    initialize: function($super, properties) {
    	//console.log("PanelNavSet.initialize "+properties.id);   
    	$super(properties);
    },

    postCreate: function() {
        //console.log("brand.globalnav.PanelNavSet.postCreate " + this.id);  
        this.panelId = this._addPanel();
    },
    
    setActiveItem: function(/* String */itemId) {
        //console.log("PanelNavSet.setActiveItem: setting active to = "+itemId + " / notify parent "+this.parentId);
        this.activeItemId = itemId;
        this.parent.activeSubItemId = itemId; // tell Accordion
    },
    
    onChildClick: function(/* String */itemId) {
        //console.log("PanelNavSet.onChildClick triggered from item: "+itemId+" to parent: "+this.id+" activeItem id = "+this.activeItemId);
        if (this.activeItemId && (this.activeItemId !== itemId)) {
            this.hideItem(this.activeItemId); 
        }
    },
    
    _addPanel: function() {
        // summary
        //      Add 1 Panel element that contains multiple PanelNavs in this set
        //
        //console.log("PanelNavSet._addPanel "+this.id);
        var panel = new site.layout.Panel({
            id: this.id+"_panel",
            parentId: this.id 
        });
        return panel.id 
    },
    
    // fade in & toggle methods: only used w/ a PanelNavSet (iow when a PanelNav has siblings)
    fadeInSubNav: function(id) {
       var node = $(id); 
        
        // TODO: ?? clean up relationship of toggleSiblings & panelNav.show/hideItem & open/close?
        // TODO: if panel is already open, we have to start w/ fade in, but if the panel isn't open, we can just do: s.display = ""; before the panel slides out 
        node.hide(); // hide it before opacity is set
        node.setOpacity(0); 
        node.show(); // ok to display now
        
        new Effect.Opacity (
	node, {
	   duration    : 0.33, 
	   transition  : Effect.Transitions.linear, 
	   from        : 0,
	   to          : 1 
       });

    },
    
    hideItem: function(/* String */itemId) {
        //console.log("PanelNavSet.hideItem "+itemId);
        var item = $(itemId).widget;
        /**JSTEST if (item.hdImg) {
            item.hdImg.changeSrc("off");
        }**/
        if (item.hdNode) item.hdNode.removeClassName("sprite-on");
        this.toggleSubNav(item.subId, 0);
        item._setActive(false);
    },
    
    toggleSubNav: function(id, state) { 
        //console.log("PanelNavSet.toggleSubNav "+id+" / " + state);
        $(id).style.display = (state == 1) ? "" : "none"; 
    }
});


brand.globalnav.panelManager = Class.create (Widget, 
{
    // summary:
    //      Handles events from trigger to effect the panel associated with this item

    // hasPanelSiblings: Boolean
    // is this PanelNav part of a PanelNavSet   
    hasPanelSiblings: false,
    
    // panelId: String
    // Panel to slide in/out
    panelId: "",

    // parent: Object
    // parent widget 
    parent: null,
    
    // subId: String
    // id of associated PanelSubNav
    // fades in/out only if it is part of a PanelNavSet
    subId: "",
    
    // sectionId: String
    // brand.globalnav.config section id
    sectionId: "",

    // item: Object (optional)
    // brand.globalnav.config item-level
    item: null,
    
    initialize: function($super, args) {
        //console.log("panelManager.init "+args.id + "/"+args.parentId);
        this.id = args.id;
        this.item = args.item;
        try {
        	this.parent = $(args.parentId).widget;
          this.hasPanelSiblings = (!!this.parent.isPanelSet);  //false? 
        } catch(e) {
        	console.log("panelManager.init E "+args.id + "/"+args.parentId+" doesn't exist as a dom obj");
        }
        $super(args); 
    },

    startup: function() {
        // used only for panelManager (PanelNav as extension of panelManager is stored as dijit instead)
        this.panelId = this._addPanel(this.parent); 
        //this.parent.addChild(this); //search and other children of Global Set without panels
    },
    
    addSubNav: function(/* Widget */subNavItem) {
        // summary
        //      Captures PanelSubNav item as a sub item (subId) associated w/ this PanelNav
        //      Adds PanelSubNav item as DOM & widget child of the Panel for this PanelNav
        //      Hides PanelSubNav's with siblings (part of a PanelNavSet)
        //console.log("PanelMgr.addSubNav "+subNavItem.id + " / "+this.panelId + " / "+$(subNavItem.id));
        this.subId = subNavItem.id;
        //$(this.panelId).widget.addChild(subNavItem);  
        
        if (this.hasPanelSiblings && $(this.subId) ) {
                $(this.subId).style.display = "none";
            
        }   
    },
    
    _addPanel: function(/* Widget */parent) {
        // summary
        //      If PanelNav instance is part of a set, get its Panel instance already created by PanelNavSet
        //      Else PanelNav instance gets a Panel of its own
       
        //console.log("panelManager._addPanel "+this.id + "_panel / " + this.id + " / " + this.parentId);
        var id; 
        if (this.hasPanelSiblings) {
        	  //console.log("panelManager._addPanel hasPanelSiblings: "+this.id);
            id = parent.panelId;
        } else {
        	 //console.log("panelManager._addPanel **no siblings**: "+this.id); 
            panel = new site.layout.Panel({
                id: this.id + "_panel",
                parentId: this.id, 
                domParent: "panel_container"
            });
            id = panel.id;
        }
        return id;
    },
    
    _setActive: function(/* Boolean */state) {   
        //console.log("PanelManager._setActive");
        this.isActive = state;
        if (state == true) {
            this.parent.setActiveItem(this.id);
        } else if (this.parent.activeItemId === this.id) {
            this.parent.setActiveItem("");
        }
        //console.log("panelnav link: _setActive: state = "+state+" this.id = "+this.id+" parentid = "+this.parent.id);
    },
    
    _onClick: function(e) {
        // summary:
        //      Click handler for PanelNav button (in template)

        //console.log("panelManager._onClick() this.id: "+this.id+ " / this.subId: "+this.subId);
   
        if (!this.isActive) {
            var psubnav = $(this.subId).widget;
            if (!psubnav.hasLoaded || !psubnav.cache) {
                // wait for the panel to open before starting load (avoids animation stutters)
                // Panel.durationOpen = 400
                var si = this.sectionId; 
                var d = this.item;
                var di = this.itemId;
                var g = function() { 
                   params = { psubnav: psubnav, sectionId: si, item: d, itemId: di };
                   globalSet.gnav.getPanelContent(params);
                   generic.events.fire({event:"panelnav:click", msg:params}); 
                }               
                setTimeout(g, 400);
            }
        }
        
        this.onTrigger(false);
    },

    onTrigger: function(stayOpen) {
        // summary:
        //      Handler for any "trigger" event (i.e. button click or search submission)
        //      stayOpen keeps panel from closing if it is already active (ex: search)
        
        //console.log("PanelMgr.onTrigger "+this.id + " / parent "+this.parentId + " / subnav " + this.subId);
       
        $(this.parentId).widget.onChildClick(this.id); // parent is either GlobalSet or PanelNavSet
        if (this.hdNode) this.hdNode.addClassName("sprite-on")
         
        var psubnav = $(this.subId).widget; // psubnav (base class: PanelSubNav)
        // toggle state
        if (this.isActive) {
            if  (!stayOpen) {
                this.hideItem();
            }
        } else {
            psubnav.onParentClick();
            this.showPanel();
            if (!psubnav.hasLoaded || !psubnav.cache) {             
                if (!psubnav.hasLoaded && psubnav.progressNode) {
                    psubnav.progressNode.style.display = "block"; // show progress   
                }               
            }
        }
    },
    
    close: function() {
        // summary:
        //      Called from parent Accordion
        //      note: "close" used as generic name (matches Accordion method name)
        
        this.hideItem();
    },
    
    showPanel: function() {
        // summary:
        //      For single PanelNav: Panel slides out
        //      For PanelNavs w/ siblings: PanelSubNav fades in
        
        //console.log("brand.globalnav.PanelManager.showPanel"); 
        var panel = $(this.panelId).widget;
        
        if (this.hasPanelSiblings) {
            var parentSet = this.parent;            
            if (panel.isOpen) {
                //console.log("PanelManager.showPanel parentSet.fadeInSubNav")
                parentSet.fadeInSubNav(this.subId);
            } else {
                //console.log("PanelManager.showPanel parentSet.toggleSubNav") 
                parentSet.toggleSubNav(this.subId, 1);
                panel.open();
            }
        } else {
            panel.open();
        }
        
        this._setActive(true); 
        generic.events.fire({event:"panelnav:show", msg:{ type:"panel", id: this.panelId, itemId: this.itemId, subId: this.subId, sectionId: this.sectionId, displayName: this.displayName, parentId: this.parentId }}); 
    },
    
    hideItem: function() {
        // summary:
        //      For single PanelNav: Panel slides in
        //      For PanelNavs w/ siblings: PanelSubNav fades in
        //console.log("PanelManager.hideItem"); 
        var panel = $(this.panelId).widget;
        panel.close();
        if (this.hasPanelSiblings) {
            this.parent.toggleSubNav(this.subId, 0);
        }
        this._setActive(false);
        
       generic.events.fire({event:"panelnav:hide", msg: { type: "panel", id: this.panelId, itemId: this.itemId, subId: this.subId }} );
    }   
});


brand.globalnav.PanelNav = Class.create( brand.globalnav.panelManager, 
{
    // summary:
    //      Creates the trigger header in the left nav
    //      Handles events from trigger to effect the panel associated with this item
    //      Can be an child of a PanelNavSet (hasPanelSiblings = true),
    //      or a child of a single Panel if it is not part of a set (1 to 1 relationship)
    //      (Ex: My Mac section has 1 Panel with 1 PanelNav & 1 PanelSubNav)

    //templatePath: "/js/brand/globalnav/templates/PanelNav.html",
    templatePath: "jsTemplates.globalnav.PanelNav",
   
    // hasLoaded: Boolean
    // have template nodes loaded in DOM
    // declarative instance = true
    hasLoaded: false,
    
    // parentId: String
    // parent object id 
    parentId: "",
    
    // displayName: String
    displayName: "",
    
    // hdPath: String
    // header img src
    hdPath: "",
    
    // img: generic.Img object
    hdImg: {},
    
    // isActive: Boolean
    // is this PanelNav active/visible    
    isActive: false,

    // itemId: String (optional)
    // brand.globalnav.config item-level id  
    itemId: "",
    
    initialize: function($super, properties) { 
    	//console.log("PanelNav.init "+properties.id + "/"+properties.parentId + "/"+properties.domParent); 
    	$super(properties);
    },
    postCreate: function() {
        //console.log("PanelNav.postCreate "+this.id+" to parent "+this.parentId);    
    
        if (!this.parent) { 
            //console.log("PARENT NOT FOUND w/ dijit.byId");
            //this.parent = this.getParent();
        }

        /**declarative instance**/
        if (this.hasLoaded) {     
            //this.parent.addChild(this.id);  
            this.startup();
        } 

        if (this.itemId === "") {
            try {
                this.itemId = this.item.id;
            }
            catch (err) { }
        }
        
    },
    
    startup: function() {
        // summary
        //      Called from postCreate if declarative instance
        //      Called explictly if programmatic instance (Accordion has to wait for header to be placed in DOM)
        //      Sets header img rollover
         //console.log("PanelNav.startup "+this.parent.id);
         this.panelId = this._addPanel(this.parent); //moved from PanelMgr's initialize
         //JSTEST this.hdNode = $(this.id + "_hd");
         
        //JSTEST this.hdImg = new generic.img(hdNode, ["off","on","sel"]);
    },

    showPanel: function($super, args) {
        // summary:
        //      Extends panelManager.showPanel
        //console.log("PanelNav.showPanel "+this.id);
        $super(args);
        
        //JSTEST: fix me
        /**
        if (this.hasPanelSiblings) {
            if (this.hdImg) {
                this.hdImg.changeSrc("sel"); // gnav category img
            }
        } else {
            if (this.hdImg) {
                this.hdImg.changeSrc("on"); // gnav section img
            }
        }**/
        /**
        if (this.hasPanelSiblings) { 
            if (this.hdNode) {
                this.hdNode.addClassName("sprite-on"); // gnav category img
            }
        } else {  
            if (this.hdNode) {
               this.hdNode.addClassName("sprite-on"); // gnav section img
            }
        }**/
    },
    
    hideItem: function($super, args) {
        // summary:
        //      Extends panelManager.hideItem
        
        $super(args);
        
       if (this.hdNode) {
           this.hdNode.removeClassName("sprite-on");
        }
    }/**,
    
    _onMouseOver: function(e) { 
        if (this.hdImg) {
            if (!this.isActive) { this.hdImg.changeSrc("on") };
        }
    },
    
    _onMouseOut: function(e) {
        if (this.hdImg) {
            if (!this.isActive) { this.hdImg.changeSrc("off") };
        }
    }**/
});

site.layout = {};//JSTEST temp
site.layout.Panel = Class.create(Widget, 
{
    // summary:
    //      Creates visual representation of sliding panel element with close button
    //      Can contain a single PanelSubNav or multiple navs as part of a PanelNavSet 
    //templatePath: "/js/brand/globalnav/templates/Panel.html",        
    templatePath: "jsTemplates.globalnav.Panel",  
    
    // isOpen: Boolean
    // Panel open/closed state
    isOpen: false,
    
    // parentId: String
    // pointer to PanelNav or PanelSet that spawned me
    parentId: "",
    domParent: "panel_container",
    
    // panel animation properties 
    closedpx: -96,
    openpx: 192,
    durationOpen: 0.4,
    durationClose: 0.3,
    
    initialize: function($super, properties) {
    	this.setProperties(properties);	 
    	//console.log("site.layout.Panel.initialize "+this.id+ " / "+this.parentId + " / "+this.domParent); 
    	$super();	
    },
    postCreate: function() {
        // place panel in panel container 
        //console.log("site.layout.Panel.postCreate"); 
        //$("panel_container").innerHTML += this.domNode;
    },
    
    _onClickClose: function() {
    // summary:
    //      Handler for close button on panel
    //      If this is a set, get active PanelNav via PanelNavSet
    //      Else, talk to PanelNav directly
        //console.log("site.layout.Panel._onClickClose()"); 
        var parent = $(this.parentId).widget;
        
        // otherwise, look for parent instance stored by GlobalSet
        if (!parent) {
            try {
                var gset = $(globalNavSetId);
                parent = gset.getChild(this.parentId);
            }
            catch(err){};
        }
            
        if (parent.isPanelSet) { 
            var activeItem = $(parent.activeItemId).widget;
            activeItem.hideItem();
        } else {
            parent.hideItem();
        }
    },
    
    open: function() {
        //console.log("site.layout.Panel.open "+this.id);
        var node = $(this.id);
        node.addClassName("panel_active");
        this._slide(1, node);
        this.isOpen = true;
    },
    
    close: function() { 
        //console.log("site.layout.Panel.close "+this.id);
        var node = $(this.id);
        node.removeClassName("panel_active");
        this._slide(0, node);
        this.isOpen = false;
    },
    
    _slide: function(state, node) { 
        //console.log("site.layout.Panel.open._slide: "+node.id + " to "+this.openpx);
        var duration, start, end, onEnd;
        if (state == 1) {
            node.style.display = "block";
            node.style.left = this.closedpx + "px";
            end = this.openpx;
            duration = this.durationOpen;
        } else {
            end = this.closedpx;
            duration = this.durationClose; 
        }
      
        new Effect.Move(node, { 
      	  duration: duration,
        	  x: end, 
        	  y: 0, 
        	  mode: 'absolute'
        });
    }
});