/*
 * JavaScript for the Digital UK Postcode Checker
 * 
 * collapsable sections code
 */

var collapsableSections = function(){
  
    // array of collapsable sections
	var collapsableSections = [];
		
	// array of collapsable headings
	var collapsableHeadings = [];
	
	// array of collapsable section heights
	var collapsableSectionHeights = [];
	
	// array containing the number of channels per section
	var channelsPerSection = [];
	
	// array to contain the current animation state of each heading
	var currentlyAnimating = [];
	
	// boolean : animate the transition?
	var animate = true;
	
	// boolean : has this script been initialised already?
	var initialised = false;
	
	
	/*
	 * initialisation function
	 * options {object} a set of parameters to tell the script what elements to work with
	 * allows this to be generically applied across the site without worrying too much about DOM structure
	 */
	function init(options) {
	    
	    // error check, don't initialise if not properly specified
	    if (!options.collapsableSections || !options.collapsableHeadings) {
	        return false;
	    }
	    
	    // error check, don't initialise if named sections aren't found 
	    if ($(options.collapsableSections).length < 1 || $(options.collapsableHeadings).length < 1) {
	        return false;
	    }
	    
	    // error check, make sure it doesn't get intitialised twice
	    if (initialised === true) {
	        return false;
	    }
	    
	    // get all collapsable content
	    collapsableSections = $(options.collapsableSections);
	    collapsableHeadings = $(options.collapsableHeadings);

        // set the global variable - animate?
        animate = options.animate;

        // intialise all collapsable content
        initHeadings();
        initSections();
        
        // condition : if an expand all container is set, display link 
        if (!!options.expandAll) {
            initExpandAll(options.expandAll);
        }
        
        // set the status of the script, to avoid conflicts
        initialised = true;
	}
	
	
	
	/*
	 * function to initalise all sections
	 */
	 function initSections() {
	     
     	// hide all collapsable table content on dom load
     	collapsableSections.each(function(counter){
     		collapsableSectionHeights[counter] = $(this).height();
     		channelsPerSection[counter] = $(this).find("tr").length;
     		//$(this).css({ overflow:"hidden" });
 			
 			// set initial visible state of each section, based on whether it should start open or not
     		if (!$(this).hasClass("open")) {
         		$(this).css({ display:"none" });
         	}
     	});
	 }
	
	
	
	/*
 	 * function to initalise all headings
 	 */
 	 function initHeadings() {
 	     
    	// set an animation default property (not animating)
    	collapsableHeadings.each(function(counter){
    		currentlyAnimating[counter] = false;
    		this.counter = counter;
    		
    		// condition : show initial state of each heading, based on whether the section starts open or not
    		if ($(collapsableSections[counter]).hasClass('open')) {
    		    $(this).addClass("open");
    		} else {
    		    $(this).addClass("collapsed");
    		}
    	});
    	
    	// set hover styles, for IE6
    	collapsableHeadings.hover(
    		function(){ 
    			$(this).addClass("hover");
    		},
    		function(){
    			$(this).removeClass("hover");
    		}
    	);
    	
    	
    	// set the link display of each collapsable heading, collapsed by default, & bind event listeners for clicks on each table heading
    	collapsableHeadings.click(function(e) {

    	    // condition : detect whether the click was for a link within the heading
    	    if (e.target.nodeName != 'A' && e.target.className != "popup") {
    	        
        		// get the number of the current heading in the array
        		var counter = this.counter;
        		
        		// condition : if the current heading isn't currently collapsing
        		if (currentlyAnimating[counter] === false) {

        			currentlyAnimating[counter] = true;

        			// get the selected heading element
        			var collapsableHeading = $(this);

        			// find the relating collapsable section, from the original array
        			var collapsableIndex = collapsableHeadings.index(this);
        			var collapsableSection = $(collapsableSections[collapsableIndex]);

        			// calculate the section height, to show/hide
        			var oldHeight = collapsableSectionHeights[collapsableIndex];

        			// set the animation time, from how many channels are contained in the collapsable section
        			var animationTime = channelsPerSection[counter]*50;

        			// set a minimum & maximum animation time
        			animationTime = (animationTime < 500) ? 500 : animationTime;
        			animationTime = (animationTime > 3000) ? 3000 : animationTime;
        			
        			// condition : if this the content is currently collapsed, open it
        			if(collapsableHeading.hasClass("collapsed")) {
        				collapsableHeading.removeClass("collapsed").removeClass("hover").addClass("open");
        				if (animate === false) {
                            collapsableSection.css({
            					display:"block",
            					height:'auto'
            				}).addClass('open');
            				currentlyAnimating[counter] = false;
            			} else {
            				collapsableSection.css({
            					display:"block",
            					height:"0px"
            				}).animate({
            					height:oldHeight+"px"
            				},animationTime,function(){
            					currentlyAnimating[counter] = false;
            					collapsableSection.css({height:'auto'}).addClass('open');
            				});
            			}

        			// if the content is currently open, collapse it
        			} else if (collapsableHeading.hasClass("open")) {
        				collapsableHeading.removeClass("open").addClass("collapsed");
        				if (animate === false) {
        				    collapsableSection.css({
        						display:"none",
        						height:"0"
        					});
        					currentlyAnimating[counter] = false;
        				} else {   
            				collapsableSection.animate({
            					height:"0"
            				},animationTime,function(){
            					collapsableSection.css({
            						display:"none",
            						height:oldHeight+"px"
            					});
            					currentlyAnimating[counter] = false;
            				});
            			}
        			}
        		}
    		}
    	});
    }
    
    
    
	
	/*
	 * function to add an optional expand-all link somewhere on the page
	 * options {object} a set of parameters containing the expand all link text, and where in the page it should go
	 */
	function initExpandAll(options) {
	    
	    // create a link to expand all collapsable content
    	var expandAllLink = $(options.linkText);
    	$(options.linkLocation).append(expandAllLink);
    	$(expandAllLink).click(function(e){

    		e.preventDefault();

    		// condition: select all collapsable content, and open if not already
    		collapsableHeadings.each(function(counter){

    			// get the selected heading element
    			var collapsableHeading = $(this);

    			// find the relating collapsable section, from the original array
    			var collapsableIndex = collapsableHeadings.index(this);
    			var collapsableSection = $(collapsableSections[collapsableIndex]);

    			// get the number of the current heading in the array
    			var counter = this.counter;

    			// condition : if the current heading isn't currently collapsing
    			if (currentlyAnimating[counter] === false && collapsableHeading.hasClass('collapsed')) {

    				currentlyAnimating[counter] = true;

    				// calculate the section height, to show/hide
    				var oldHeight = collapsableSectionHeights[collapsableIndex];

    				// condition : safari doesn't include table padding in it's height calculations
    				if($.browser.safari) {
    					//oldHeight += (channelsPerSection[counter]*12);
    				}

    				// set the animation time, from how many channels are contained in the collapsable section
    				var animationTime = channelsPerSection[counter]*50;

    				// set a minimum & maximum animation time
    				animationTime = (animationTime < 500) ? 500 : animationTime;
    				animationTime = (animationTime > 3000) ? 3000 : animationTime;

    				// condition : if this the content is currently collapsed, open it
    				if(collapsableHeading.hasClass("collapsed")) {
    					collapsableHeading.removeClass("collapsed").addClass("open");
    					if (animate === false) {
    					    collapsableSection.css({
    					        height : 'auto',
    					        display : 'block'
    					    }).addClass('open');
    						currentlyAnimating[counter] = false;
    					} else {
    					    collapsableSection.css({
        						display:"block",
        						height:"0px"
        					}).animate({
        						height:oldHeight+"px"
        					},animationTime,function(){
                                collapsableSection.css({height:'auto'}).addClass('open');
        						currentlyAnimating[counter] = false;
        					});
    					}
    				}
    			}
    		});
    	});
	}
	

    /*
      * RETURN - expose any methods and variables
      */
      return {
          init: init
      };

}();



/*
 * initialise any collapsable sections!
 */
$(document).ready(function(){ 

    // add collapsable area for main postcode checker
    var postcodeCheckOptions = {
        collapsableSections : ".postcode #channels_available .collapsable",
        collapsableHeadings : ".postcode #channels_available h3",
        expandAll : {
            linkText : "<a href='#'>Click on a genre below to display available channels or click here to expand all.</a>",
            linkLocation : "#expand_all_link_area"
        },
        animate : true
    };
    collapsableSections.init(postcodeCheckOptions);


    // add collapsable areas for postcode checker - trade view (regions)
    var postcodeCheckTradeViewRegionsOptions = {
        collapsableSections : ".postcode.tradeview.region #collapsable_content .collapsable",
        collapsableHeadings : ".postcode.tradeview.region #collapsable_content h3",
        expandAll : {
            linkText : "<p id='expand_all'><a href='#'>Expand all</a></p>",
            linkLocation : ".collapsable_controls:first"
        },
        animate : false
    };
    collapsableSections.init(postcodeCheckTradeViewRegionsOptions);
    

    // add collapsable areas for postcode checker - trade view (postcode)
    var postcodeCheckTradeViewOptions = {
        collapsableSections : ".postcode.tradeview #collapsable_content .collapsable",
        collapsableHeadings : ".postcode.tradeview #collapsable_content h3",
        animate : true
    };
    collapsableSections.init(postcodeCheckTradeViewOptions);

});