// JQUERY JBBC PLUGIN
// PLUGIN TO REPLICATE THE BBC NEWS TICKER ON THE BBC HOMEPAGE
// VERSION 0.0.4
// AUTHOR: ROB CHARLWOOD
// DATE: 25/11/2009
// GENERAL GPL LICENCSE
// TESTED IN IE6+, FIREFOX*, SAFARI*, OPERA*, CHROME (* ON MAC WHERE APPROPRIATE)

// CREATE PLUGIN
(function($) {

	// DEFINE JBBC OBJECT AND DEFAULT OPTIONS
	$.jBBC = {
		defaults: {
		
		  // DIMENSIONS
		  jbbc_width: '300',
		  image_height: '173',
		  image_width: '145',
		  
		  // BACKGROUND STYLES
		  bg_color: '#FFFFFF',
		  bg_img: '',
		  border_color: '#BBC3C7',
		  
		  // UL STYLES
		  list_color: '#FFFFFF',
		  list_img: '',
		  list_hover_img: '',
		  list_hover_color: '#88A9BD',
		  
		  // LINK STYLES
		  link_color: '#3B3F3E',
		  link_hover_color: '#FFFFFF',
		  link_open: '_self',
		  
		  // CALLBACK OPTIONS
		  jbbc_callback: false,
		  jbbc_callback_data: false
		}
	};
	
	// EXTEND JQUERY WITH THE PLUGIN
	$.fn.extend({
		jBBC:function(config) {
			
			// USE DEFAULTS OR VALUES PROVIDED BY DEVELOPER
			var config = $.extend({}, $.jBBC.defaults, config);
			
			// ADD SOME VALUES TO CONFIG
			config.Container = $('<div id="jbbc"></div>');
			config.imageHolder = $('<div id="jbbc_image_holder"></div>');
			config.listHolder = $('<div id="jbbc_list_holder"></div>');
			config.newList = $('<ul id="jbbc_list"></ul>');
			config.clearIt = $('<div style="clear:both;"></div>');
			
			// ATTEMPT TO SELECT THE CHILDREN OF THE SUPPLIED LIST
			if($(this).children('li').length !== 0){
			
			    // HIDE ORIGINAL LIST
			    $(this).hide();
                
                // GRAB THE IMAGE DATA WE NEED FROM THE LIST
                $(this).children().each(function(i){
                
                    // GRAB TITLE
                    config.itemTitle = $("a", this).attr("title");
                    
                    // GRAB LIST OBJECT
                    config.listItem = $(this);
                    
                    // GRAB LINK
                    config.link = $("a", this).attr("href");
                    
                    // GRAB IMAGE NAME
                    config.imageName = $("a", this).attr("rel");
                    
                    // CREATE IMAGE NODE              
                    config.image = (i == 0) ? $('<div class="image"><a href="' + config.link + '" hreflang="en-gb"><img src="' + config.imageName + '" title="' + config.itemTitle + '" alt="' + config.itemTitle + '"/></a></div>') : $('<div class="image_hide"><a href="' + config.link + '" hreflang="en-gb"><img src="' + config.imageName + '" title="' + config.itemTitle + '" alt="' + config.itemTitle + '"/></a></div>');
                    
                    // APPLY NEW WINDOW IF NECCESSARY
                    if(config.link_open == "new"){
                        config.image.find('a').attr("target", "_blank");
                        config.listItem.find('a').attr("target", "_blank");
                    }
                    
                    // APPEND TO IMAGE HOLDER
                    config.image.appendTo(config.imageHolder);
                    
                    // APPEND THE LIST ITEM TO THE NEW LIST
                    config.listItem.appendTo(config.newList);
                });
                
                // APPLY USER DEFINED STYLES TO ELEMENTS
                config.Container.css("width",config.jbbc_width)
                                .css("height",config.image_height)
                                .css("background-color",config.bg_color);
                config.imageHolder.css("width", config.image_width);
                config.listHolder.css("width", config.jbbc_width - config.image_width);
                config.newList.css("height", config.image_height);
                
                // IF A BG IMAGE IS DEFINED, APPLY IT
                if (config.bg_img !== ''){
                    
                    // APPLY IT, POSITION IT AND REPEAT IT
                    config.Container.css("background-image", 'url("' + config.bg_img + '")')
                                    .css("background-position", "top left")
                                    .css("background-repeat","repeat");
                }
                                           
                // WORK OUT AMOUNT OF PADDING TO APPLY ALONG WITH A HEIGHT FOR THE LIST ITEMS
                var liTotalHeight = Math.floor((config.image_height / 4));
                var liPaddingTopBottom = Math.floor((liTotalHeight / 6));
                var liPaddingleftRight = Math.floor((liPaddingTopBottom));
                
                // CHECK FOR IE AS WE NEED TO SPECIFY A PHYSIAL HEIGHT AS IT DOES NOT TAKE THE AMOUNT OF PADDING INTO ACCOUNT WHEN RENDERING
                if($.browser.msie){
                    var liHeight = liTotalHeight ;
                }else{
                    var liHeight = liTotalHeight - Math.floor((liPaddingTopBottom * 2 ));
                }
                
                // APPLY THE PADDING AND HEIGHT
                config.newList.find('li a').css("width", config.jbbc_width - config.image_width)
                                           .css("background-color", config.list_color)
                                           .css("color", config.link_color)
                                           .css("border-bottom-color",config.border_color)
                                           .css("padding-top", liPaddingTopBottom)
                                           .css("padding-bottom", liPaddingTopBottom)
                                           .css("padding-left",liPaddingleftRight)
                                           .css("padding-right",liPaddingleftRight)
                                           .css("height",liHeight);
                
                // IF A LIST ITEM BG IMAGE IS DEFINED, APPLY IT
                if (config.list_img !== ''){
                    
                    // APPLY IT, POSITION IT AND REPEAT IT
                    config.newList.find('li a').css("background-image", 'url("' + config.list_img + '")')
                                               .css("background-position", "top left")
                                               .css("background-repeat","repeat");
                }
                
                // REMOVE THE BOTTOM BORDER FROM THE LAST LIST ELEMENT
                config.newList.find('li a:last').css("border-bottom","0");
                
                // ADD BOTH THE IMAGE HOLDER AND NEW LIST INTO THE RELEVANT PARENT AND THEN ATTACH THE NEW BUILD ON AFTER THE CURRENT OBJECT
                config.newList.prependTo(config.listHolder);
                config.imageHolder.prependTo(config.Container);
                config.listHolder.appendTo(config.Container);
                config.clearIt.appendTo(config.Container);
                config.Container.insertAfter($(this));
                
                // LISTEN FOR ROLL OUT AS WE NEED TO REMOVE THE ANY BACKGROUND IMAGE FROM THE LIST ITEM IF ONE WAS SPECIFIED
                config.newList.find('a').mouseout(function() {
			     
			       // IF A LIST ITEM BG IMAGE IS DEFINED, APPLY IT
                   if (config.list_img !== ''){
                    
                        // APPLY IT, POSITION IT AND REPEAT IT
                        $(this).css("background-image", 'url("' + config.list_img + '")')
                                                   .css("background-position", "top left")
                                                   .css("background-repeat","repeat");
                    }
	            });
                                
                // LISTEN FOR ROLLOVERS
                config.newList.find('a').hover(function (e) {
                
                    // GRAB CURRENTLY HOVERED ELEMENT
				    var elementID = e.target;
				    
                    // APPLY NORMAL STATE TO ALL BUTTONS
				    config.newList.find('li a').css("width", config.jbbc_width - config.image_width)
                                           .css("background-color", config.list_color)
                                           .css("color", config.link_color)
                                           .css("border-bottom-color",config.border_color);
				    
				    
		            // UPDATE THIS LINK WITH HOVER STYLES
                    $(this).css("width", config.jbbc_width - config.image_width)
                           .css("background-color", config.list_hover_color)
                           .css("color", config.link_hover_color)
                           .css("border-bottom-color",config.border_color);
                    
                    // IF A LIST ITEM HOVER BG IMAGE IS DEFINED, APPLY IT
                    if (config.list_hover_img !== ''){
                        
                        // APPLY IT, POSITION IT AND REPEAT IT
                        $(this).css("background-image", 'url("' + config.list_hover_img + '")')
                               .css("background-position", "top left")
                               .css("background-repeat","repeat");
                    }

                    // LOOP THROUGH IMAGES AND HIDE ALL
                    config.imageHolder.children('div').each(function(i){
                        
                        // GRAB THE CURRENT LOOPED ELEMENT SRC
                        var image = $(this).find('img').attr("src");
                        
                        // DUE TO THE WAY IE PICKS UP SRC'S AS FULL URLS WE NEED TO CHECK FOR ABSOLUTE OR RELATIVE URLS
                        if(elementID.rel.match("http://") == "http://" || elementID.rel.match("https://") == "https://"){
                            config.relative = false;
                        }else{
                            config.relative = true;
                        }

                        // IF IE AND RELATIVE URLS THEN REMOVE HOST FROM IMAGE SRC
                        /*****THIS IF LINE MAY BREAK YOU IN IE *********/
                        ell = $(elementID).attr('rel');					
                        if($.browser.msie){
                                                    image = image.split('/');
                                                    image = image[image.length - 1];
                                                    ell = ell.split('/');
                                                    ell = ell[ell.length - 1];
                                          }
                        
						
                        // CHECK TO SEE IF IT MATCHES WITH THE SELECTED LIST ITEM
                        if(image == ell){
                            // IF SO DISPLAY THE IMAGE
                            $(this).removeClass("image_hide").addClass("image");
                                        
                        }else{
                        
                            // OTHERWISE HIDE IT
                            $(this).removeClass("image").addClass("image_hide");
                        }
                    });                    
			         
			         // PREVENT DEFAULT
			         e.preventDefault();
			     });
			     
                // METHOD ONCLICK
                config.newList.find('a').click(function(e){
                
                    // CHECK FOR CALL BACK METHOD
                    if(config.jbbc_callback !== false){

                        // EXECUTE THE CALLBACK METHOD DEPENDING ON CALL BACK DATA
                        (config.callback_data == false) ? config.jbbc_callback() : config.jbbc_callback(config.jbbc_callback_data); 
                        
                        // PREVENT THE LINK FROM BEING FOLLOWED
                        e.preventDefault();                        
                    }
                });
                
                // METHOD ONCLICK
                config.imageHolder.children('div').click(function(e){
                
                    // CHECK FOR CALL BACK METHOD
                    if(config.jbbc_callback !== false){

                        // EXECUTE THE CALLBACK METHOD DEPENDING ON CALL BACK DATA
                        (config.callback_data == false) ? config.jbbc_callback() : config.jbbc_callback(config.jbbc_callback_data); 
                        
                        // PREVENT THE LINK FROM BEING FOLLOWED
                        e.preventDefault();                        
                    }
                });
                                
			}else{
			     
			     // NO CHILDREN SO MAY AS WELL REMOVE THE LIST
			     $(this).remove();
			}
			
			// RETURN THE JQUERY OBJECT FOR CHAINING
			return this;
		}
    
    // END OF CONSTRUCTOR METHOD
	});

// END OF PLUGIN	
})(jQuery);
