// WDR: Pulled the tab logic into its own class.
// This "may" be appropriate to put in global.js or another general location...
TabbedContent = Class.create({
    
    initialize: function(args) {

		// These id's are generated within the tab context.
    	// mainContainerID is a div that holds the whole thing.
    	// tabContainerID is a UL that holds only the clickable tabs across the top.
    	// contentContainerID is the div that holds each tab's content div.
    	this.mainContainerID = "tabs_container";
    	this.tabContainerID = "tab-label-container";
    	this.contentContainerID = "tabs-content";

		// I'm using wrapperContainerID instead of the containerSelector + tabsContainerSelector.
		// This must already exist on the page, and will be filled in with the tabs.
    	this.wrapperContainerID = "product-details";
    	
    	this.contentClass = ""; //"tab-content";
    	this.contentStyle = "";
    	this.activeClassName = "current";
    	this.tabs = null;
    	
        Object.extend(this, args || {});
		
		this.createContainer();
    },
    
    createContainer: function() {
    	var html = '<div id="'+this.mainContainerID+'">' +
    					'<ul id="'+this.tabContainerID+'" class="tabs clearfix"></ul>' +
    					'<div class="dotted-y-r">' +
    						'<div class="dotted-y-l tab-content" id="'+this.contentContainerID+'">' +
        					'</div>' +
    					'</div>' +
					'</div>' +
					'';
		
		this.initContainer(html);
    },
    
    initContainer: function(html) {
        var tabsContainerNode = $(this.wrapperContainerID);
        if ( tabsContainerNode ) {
        	tabsContainerNode.update(html);
        }

        this.tabs = new Control.Tabs ( this.tabContainerID, { 
        							   setClassOnContainer: true, 
        							   activeClassName: this.activeClassName,
                                       setActiveTabOnClick: this.setActiveTab.bind(this)
        							   } );
        
    },
    
	createTab: function (args) {
		// Check optional args.
		// In most cases, you won't need tabContainerID or contentContainerID here,
		// but you may want a tab-specific style
		if ( !args.tabContainerID ) args.tabContainerID = this.tabContainerID;
		if ( !args.contentContainerID ) args.contentContainerID = this.contentContainerID;
		if ( !args.contentClass ) args.contentClass = this.contentClass;
		if ( !args.contentStyle ) args.contentStyle = this.contentStyle;
		
		// Note: args.tabID and args.tabLabel are required!
		
        var lnk = new Element('a', {href: '#' + args.tabID}).update(args.tabLabel);
        var li = new Element('li').update(lnk);
        
        // id should be unique so this is better written
        // $(this.wrapperContainerID).down('#' + args.tabContainerID).insert(li);
        $(args.tabContainerID).insert(li);
 
       // NOTE: you can build out a tabHdrContentModule or tabContentModule but not both (in a single call). slider ties them together, but these are actually two different tab sets
        if (args.tabHdrContentModule) {
            var tabID = args.tabID
            tabID += tabID .match(/_hdr/) ? '' : '_hdr';
            var hdrContentDiv = new Element('div', {
                "class" : args.contentClass,
                "id"    : tabID,
                "style" : args.contentStyle 
                });
            args.hdrTabID = tabID;
            hdrContentDiv.update(args.content);
            $('slider_container').parentNode.insertBefore(hdrContentDiv,$('slider_container'));
        } else {
             var contentDiv = new Element('div', {
                "class" : args.contentClass,
                "id"    : args.tabID,
                "style" : args.contentStyle 
                });
             contentDiv.update(args.content);
            $(args.contentContainerID).insert(contentDiv);  
        }
        // ids should be unique anyway - better written as
        // $(this.wrapperContainerID).down('#' + args.contentContainerID).insert(contentDiv);
       // $(args.contentContainerID).insert(contentDiv);
        
        this.tabs.addTab(lnk);
        this.setActiveTab(args.tabID);
        
        return contentDiv;
    },
    
    getTabContainer: function(tabID) {
        var containerNode = $(this.wrapperContainerID).down('#' + tabID);
        return containerNode;
    },
    
    updateTab: function(tabID,html) {
        var containerNode = $(this.wrapperContainerID).down('#' + tabID);
    	if ( containerNode ) {
    		containerNode.update ( html );
    	}
    },
    
    setActiveTab: function(tabID) {
    	this.tabs.setActiveTab(tabID);

        // attempt to move the footer to the appropriate spot for this tab
        if(typeof moveFooterOnPage == 'function')
            moveFooterOnPage();
    },
    
    fixTabHeight: function(tabID) {
    	// Note - this will only work on an active tab...
        var containerNode = $(this.wrapperContainerID).down('#' + tabID);
        containerNode.fixContentHeight();
    }
    
    //TODO: We should derive this class from the Control.Tabs class rather than wrapping
    // the instance.  Then we can override the setActiveTab() method and call fixTabHeight()
    // whenever a tab is activated.
    
});


TabbedProductContent = Class.create(TabbedContent, {
	
	createProductTab: function (args) {
		// First, create the tab using base method
		this.createTab(args);
		
		// Flag to indicate if there is content in the top half
		// (may be product-only tab)
		this.hasContent = false;
		
		// If we have content, use that
		// Else assume we need to load the product info
		if ( args.tabContentModule || args.tabHdrContentModule) {
			this._loadContentInfo(args);
		} else {
			this._loadProductInfo(args);
		}
		
		// Load product multibox, if any
		var isCol = parseInt(args.tabMultiColumn);
		if ( isCol > 0 ) {
			this._loadProductMBoxColumns(args);
		} else {
			this._loadProductMBox(args);
		}
    },
    
    // Load product info section, which consists of a heading, an image, and text.
    _loadProductInfo: function(args) {
		
		var infoDiv = new Element('div', {
				"class" : "tab-product-info"
				});
		
		if ( args.tabHeading ) {
			infoDiv.insert( new Element('h1').update(args.tabHeading) );
			this.hasContent = true;
		}
		
		if ( args.tabImage ) {
			infoDiv.insert( new Element('img', {
					"src" : args.tabImage,
					"style" : "float: left; margin: 5px;"
					}) );
			this.hasContent = true;
		}
		
		if ( args.tabText ) {
			infoDiv.insert( new Element('div').update(args.tabText) );
			this.hasContent = true;
		}
		
		if ( this.hasContent ) {
			infoDiv.insert( new Element('br', { "style":"clear: both;"}) );
		}

        // ids should be unique anyway - better written as:
        // var containerNode = $(this.wrapperContainerID).down('#' + args.tabID);
        var containerNode = $(args.tabID);
        containerNode.insert(infoDiv);
    },
    
    // Load content module
    _loadContentInfo: function(args) {
        // better as 
        // var containerNode = $(this.wrapperContainerID).down('#' + args.tabID);
       var containerNode = args.tabHdrContentModule ? $(args.hdrTabID) : $(args.tabID);
        
		var infoDiv = new Element('div', {
				"class" : "tab-product-info",
				"style" : "position: relative;"
				});

    	
    	if ( !this.onContentLoaded )
    		this.onContentLoaded = [];
		this.onContentLoaded[args.tabID] = args.onContentLoaded || function(){};
		this.hasContent = true;
		
        containerNode.insert(infoDiv);
        var content = args.tabHdrContentModule ? args.tabHdrContentModule : args.tabContentModule;
        new Ajax.Updater ( infoDiv, content, { 
        	evalScripts: true,
        	onComplete: this._ajaxCallback.bind(this,args.tabID) 
        } );
		
		
    },
    
    fixContentHeight: function(tabID) {
        //var containerNode = $(this.wrapperContainerID).down('#' + tabID);
        var containerNode = $(tabID);
        var infoDiv = containerNode.down('.tab-product-info');
        
        // The "fix" only works if the tab is active.
        // Save current active tab so we can reset if needed.
        var active = this.tabs.activeLink;
        if ( active && active.key != tabID ) {
    		this.tabs.setActiveTab(tabID);
    	}
    	
        infoDiv.fixContentHeight();
        
        if ( active && active.key != tabID ) {
        	this.tabs.setActiveTab(active);
        }
    },
    
    _ajaxCallback: function(tabID) {
    	this.fixContentHeight(tabID);
    	this.onContentLoaded[tabID]();
    },
    
    // This loads product data into a multibox on the bottom half of the tab
    // (below either the product info or content module section).
    // We only load if some kind of product data is requested.
    _loadProductMBox: function(args) {
    	
        // Are there products to load here?
        if ( args.tabProducts || args.tabCategories || args.tabSkus ) {
        	
            // better as:
        	// var containerNode = $(this.wrapperContainerID).down('#' + args.tabID);
            var containerNode = $(args.tabID);

			// Create a unique id for the mbox section
        	var prodDivID = this.wrapperContainerID+'-'+args.tabID+'-'+'product-mbox';
        	
        	// Only need the border if there is content in the top half
        	var wrapperClass = ( this.hasContent ? "tab-product-mbox-topborder" : "tab-product-mbox-noborder" );
        	
        	// Need a wrapper around the actual product div so we can handle the borders
        	var prodWrapper = new Element('div', {
        			"id" : prodDivID + '-wrapper',
        			"class" : wrapperClass
        			});
        			
        	// Make the product div
        	prodWrapper.insert( new Element('div', {
					"id"    : prodDivID,
					"class" : "tab-product-mbox browse-products clearfix"
					}) );
        	
        	// Insert the div onto the page
			containerNode.insert( prodWrapper );
			
			// How many products per row?
			var ppr = parseInt(args.tabProdsPerRow);
			var prodsPerRow = ( ppr > 0 ? ppr : 3 );
			
			// Generate an mbox
        	var mbObj = new ProductMultiBox({
				containerId: prodDivID,
				productsPerRow: prodsPerRow,
				mode: 1
				});
			
			// Split the product id list into an array and stuff each id into the mbox
			if ( args.tabProducts ) {
				$A(String(args.tabProducts).split(",")).each( function(el) {
						mbObj.addProduct(String(el).strip());
						});
			}
			
			if ( args.tabCategories ) {
				$A(String(args.tabCategories).split(",")).each( function(el) {
						mbObj.addCategory(el);
						});
			}
			
			if ( args.tabSkus ) {
				$A(String(args.tabSkus).split(",")).each( function(el) {
						mbObj.addSku(el);
						});
			}
			
			// Fill in the mbox data
			mbObj.loadMultiBox();
        }

    },

    // This loads product data into a multibox on the bottom half of the tab
    // (below either the product info or content module section).
    // This version will load categories (only) in vertical columns rather than rows,
    // one category per column.
    _loadProductMBoxColumns: function(args) {
    	
        // Are there products to load here?
        if ( args.tabCategories ) {
        	
            // better as:
        	// var containerNode = $(this.wrapperContainerID).down('#' + args.tabID);
            var containerNode = $(args.tabID);

			// Create a unique id for the mbox section
        	var prodDivID = this.wrapperContainerID+'-'+args.tabID+'-'+'product-mbox';
        	
        	// Only need the border if there is content in the top half
        	var wrapperClass = ( this.hasContent ? "tab-product-mbox-topborder" : "tab-product-mbox-noborder" );
        	
        	// Need a wrapper around the actual product div so we can handle the borders
        	var prodWrapper = new Element('div', {
        			"id" : prodDivID + '-wrapper',
        			"class" : wrapperClass
        			});
        			
        	// Insert the div onto the page
			containerNode.insert( prodWrapper );

			// Use a big number for "per row" to force all the li's to be in one ul.
			var prodsPerRow = 100;
			var catIds = $A(String(args.tabCategories).split(","));
			var catCnt = catIds.size();
			
			// Loop thru the cats and make a column for each one.
			catIds.each( function(catId,index) {
				
				var strClass = "tab-product-mbox browse-products column-mode clearfix";
				if ( index % 2 ) { strClass += " even"; }
				if ( index == catCnt-1 ) { strClass += " last"; }

	        	// Make the product div
	        	prodWrapper.insert( new Element('div', {
						"id"    : prodDivID + '-' + catId,
						"class" : strClass
						}) );
			

				// Generate an mbox
	        	var mbObj = new ProductMultiBox({
					containerId: prodDivID + '-' + catId,
					productsPerRow: prodsPerRow,
					mode: 1
					});
			
				mbObj.addCategory(catId);

				// Fill in the mbox data
				mbObj.loadMultiBox();
			});
			
			// Clear the whole thing.
			prodWrapper.insert( new Element('div', {
				"style" : "clear: both"
			}));
        }

    }
    
});

// Use this class IFF you have created the html MANUALLY
// and you just want to wrap it with the class object.
TabbedContentWrapper = Class.create({
    
    initialize: function(args) {
    	this.wrapperContainerID = "product-details";
    	this.tabContainerID = 'tab-label-container';
    	this.activeClassName = 'current';
    	
        Object.extend(this, args || {});
        
        this.tabs = new Control.Tabs ( this.tabContainerID, { 
        							   setClassOnContainer: true, 
        							   activeClassName: this.activeClassName
        							   } );
	},
		
    updateTab: function(tabID,html) {
        // better as 
        // var containerNode = $(this.wrapperContainerID).down('#' + tabID);
        var containerNode = $(tabID);
    	if ( containerNode ) {
    		containerNode.update ( html );
    	}
    },
    
    setActiveTab: function(tabID) {
    	this.tabs.setActiveTab(tabID);
    },
    
    fixContentHeight: function(tabID) {
        
        // The "fix" only works if the tab is active.
        // Save current active tab so we can reset if needed.
        var active = this.tabs.activeLink;
        if ( active && active.key != tabID ) {
    		this.tabs.setActiveTab(tabID);
    	}
    	
        // better as
        // var containerNode = $(this.wrapperContainerID).down('#' + tabID);
        var containerNode = $(tabID);
        
        containerNode.childElements().each(function(el){
        	if ( el.tagName == 'DIV' ) {
        		el.fixContentHeight();
        	}
        });
        
        if ( active && active.key != tabID ) {
        	this.tabs.setActiveTab(active);
        }
    }

});

