MCFC.carousel = function () {
	
	var NAV_ITEMS_PER_PAGE = 3;
	var NAV_ITEM_WIDTH = 159;
	var NAV_ITEM_HEIGHT = 140;
	var NAV_ITEM_BOTTOM_PAD = 1;
	var NAV_ITEM_ANIMATION_SPEED = 500; //ms
	var NAV_ITEM_ANIMATION_DELAY = 150; //ms
	var NAV_ITEM_HOVER_FADE_IN = 0; //ms
	var NAV_ITEM_HOVER_FADE_OUT = 300; //ms
	var NAV_ITEM_CLICK_FADE_IN = 150;
	var NAV_ITEM_CLICK_FADE_OUT = 300;
	
	// index 0 to number of slides -1 which is different from row_index.
	var Slide = function (data, active, index) {
	    
	    var showLikeButton = function()
		{
		    FBIFrame = '<div id=fblike-container style="position:absolute; top:410px; left:20px; border:none; overflow:hidden; width:450px; height:21px;"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fmcfc.co.uk&amp;layout=button_count&amp;show_faces=true&amp;width=200&amp;action=like&amp;font=arial&amp;colorscheme=dark&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:200px; height:21px;" allowTransparency="true"></iframe></div>';
            $('#content-main-feature').html(FBIFrame + $('#content-main-feature').html());
		}
	    
        var awaykit = "New Away Kit";
        var homekit = "New Home Kit";
        if(active && (data.nav.section.search(homekit) == 0 || data.nav.section.search(awaykit) == 0 ))
        {
            showLikeButton();
        }
		var loaded = false;
		var preloading_init = false;
		var content = "";
		var carousel_element = $('#'+MCFC.carousel.data.carousel_element_id);
		
		// if active we've already got the contents in the DOM
		if(active) {
			content = carousel_element.html();
			loaded = preloading_init = true;
		}
		
		// private method for displaying 
		// the content in the  carousel area.
		// TODO: This method should know how to 
		// embed different types of of slides.
		var display = function () {
			//console.log("display");
			// safely remove current SWF if exists
			//MCFC.swf.remove('carousel-swf-container');
			// render the HTML into container
            try {
			    carousel_element.html(content);
            } catch (e) {}
			// redraw the h2swf's 
			if(MCFC.fontsizes){
				MCFC.fontsizes(carousel_element.parent());
			}
			// re init supersleight if needed
            try {
                supersleight.run();
            }catch(err){ }
            
			// redraw rounded corners
			MCFC.custom(carousel_element.parent());
			switch(data.type) {
				case 'html': break;
				case 'swf' :
                    if(data.nav.section.search(awaykit) == 0 || data.nav.section.search(homekit) == 0)
                    {
                        showLikeButton();
                    }
				    var params = $.extend({}, {wmode : 'transparent'}, data.params);
					MCFC.swf.embed(data.swf_url, 'carousel-swf-container', 800, 450, data.flashvars, params, data.attributes);
				break;
			};
		};

		return {
			
			get_index : function () {
				return index;
			},

			load : function (fn, force_reload, preload_image) {
				preloading_init = true;
				var that = this;
				if(!this.get_content() || force_reload) {
					$.get(data.xhr_url, function(data) {
						content = data;
						loaded = true;
						var img = $(data).find('img').get(0);
						if(preload_image && img) {
							that.load_image($(img).attr('src'), function(){
								if(fn) { fn(content); }
							});
						}else{
							if(fn) { fn(content); }
						}
					});
				}else{
					if(fn) { fn(content); }
				}
			},
			
			load_image : function (src, fn) {
				//console.log('Starting preload image: ' + src);
				var img = new Image();
				$(img)
					// on image loaded callback
					.load(function () {
						//console.log('Background image loaded: ' + src);
						fn();
					})
					// If image can't be loaded
					.error(function () {
						//console.log('Error loading background image loaded: ' + src + ' Moving on anyways.' );
						fn();
					})
					// Load the image
					.attr('src', src);
			},

			get_content : function () {
				return loaded ? content : false;
			},
			
			get_nav_node : function (node) {
				return data.nav[node];
			},
			
			show : function () {
				this.load(display);
			},
			
			is_loaded : function () {
				return loaded;
			},
			
			preloading_initiated : function () {
				return preloading_init;
			}
			
		};
	};
	
	
	// navitems are ordered in a classical 147,258,369 layout grid
	// <li><a class="active" href="#"><div><h4>Shop</h4><p>2009/10<br />Replica Kit</p></div></a></li>
	var NavItem = function (slide, row_index, page, active, node, parent_nav_node) {

		var content_html = null;
		var attached_to_dom = false;
		var hover = false;
		var click_listeners = [];
		var that = this;
		
		var set_nav_item_html = function(node) {
			content_html = node;
			// add/remove active flag if exists.
			pub[active ? 'activate' : 'deactivate']();
			// set new copy
			$(node).find('h4').html(slide.get_nav_node('section'));
			$(node).find('a').attr('href', slide.get_nav_node('href'));
			$(node).find('p').html(slide.get_nav_node('label'));
			// position the nav item html in correct y pos
			$(node).css('position', 'absolute');
			$(node).css('top', NAV_ITEM_HEIGHT*row_index+(row_index*NAV_ITEM_BOTTOM_PAD));		
			$(node).find('a').bind('click', pub.click);
			$(node).find('a').bind('mouseenter', $(node).find('a'), pub.mouseenter);
			$(node).find('a').bind('mouseleave', $(node).find('a'), pub.mouseleave);
			// mark attached
			$(node).attr('rel', 'attached');
		};
		
		var pub = {
			
			get_slide : function () {
				return slide;
			},
			
			get_page : function () {
				return page;
			},
			
			get_row_index : function () {
				return row_index;
			},
			
			get_slide_index : function () {
				return this.get_slide().get_index();
			},
			
			set_dom_node : function (node) {
				set_nav_item_html(node);
				attached_to_dom = true;
			},
			
			set_parent_dom_node : function (node) {
				
			},
			
			css : function(attr, val) {
				return $(content_html).css(attr, val);
			},
			
			animate : function(spec, time, fn) {
				$(content_html).animate(spec, time, "swing", fn);
			},
			
			attach_to_dom : function() {
				if(attached_to_dom) { return; }
				$(parent_nav_node).append(content_html);
				attached_to_dom = true;
			},
			
			show : function(direction) {
				this.css('left', NAV_ITEM_WIDTH*direction);
				this.attach_to_dom();
				this.animate({
					left : 0
				}, NAV_ITEM_ANIMATION_SPEED);
			},
			
			hide : function(direction) {
				this.animate({
					left : NAV_ITEM_WIDTH*direction
				}, NAV_ITEM_ANIMATION_SPEED);	
			},
			
			click : function (event) {
				event.data = pub;
				for(k in click_listeners) {
					click_listeners[k](event);
				}
				return false;
			},

			mouseenter : function (event) {
				if(active){ return; }
				pub.css('background-color', '#5cbfeb');
			},

			mouseleave : function (event) {
				if(active){ return; }
				pub.css('background-color', '#3a7895');
			},
			
			add_click_listener : function(fn) {
				click_listeners.push(fn);
			},
			
			activate : function (animate) {
				active = true;
                animate = false;
				var set_background_active = function () {
					$(content_html).addClass('active').css('background-color', '#5cbfeb');
				};
				if(animate) {
					$('a', content_html).animate({
						backgroundColor : '#5cbfeb'
					}, NAV_ITEM_CLICK_FADE_IN, "swing", function(){
						set_background_active();
					});					
				}else{
					$('a', content_html).css('background-color', '#5cbfeb');
					set_background_active();
				}
			},
			
			deactivate : function () {
				active = false;
				$(content_html).removeClass('active').css('background-color', '#3a7895');
				//$('a', content_html).animate({
				//	backgroundColor : '#3a7895'
				//}, NAV_ITEM_CLICK_FADE_OUT, "swing", function(){
                //
				//});

				$('a', content_html).css('background-color', '#3a7895');
				
			}
			
		};
		
		// create the new dom node for the nav item
		set_nav_item_html(node);
		
		return pub;
		
	};	

	
	// will hold instances of slide
	var carousel_nav_manager = function () {

		var nav_items = [];
		var current_slide_index;
		var current_page_number;
		var timer_id;
				
		// bind click events to the pagination links		
		var bind_click_events_to_pagination_links = function () {
			var pagination_counter = 0;
			$('#carousel-pagination-links a').each(function() {
				pagination_counter++;
				// console.log('binding click event to');
				// console.log(this);
				$(this).bind('click', function(p) {
					return function () {
						console.log('clicked on pagination link' + p);
						MCFC.carousel.nav_manager.change_page(p);
						return false;
					};
				}(pagination_counter));
			});
		};
		
		var transition_nav_items = function(nav_items, direction, func) {
			for (var i=0; i < nav_items.length; i++) {
				var delay = i*NAV_ITEM_ANIMATION_DELAY+1;
				window.setTimeout(function(index){
					return function() {
						nav_items[index][func](direction*-1);
					};
				}(i), delay);
			};
		};
		
		return {
			
			add_nav_item : function (item) {
				item.add_click_listener((this.nav_item_click_handler));
				nav_items.push(item);
			},
			
			nav_item_click_handler : function (e) {
				//alert("nav_item_click_handler"+e.data.get_slide_index());
				MCFC.carousel.nav_manager.change_slide(e.data.get_slide_index());
				MCFC.carousel.nav_manager.stop_timer();
			},
			
			deactivate_all_navitems : function (except_this) {
				var items = carousel_nav_manager.get_nav_items();
				for(k in items){
					if(items[k].get_slide_index() != except_this.get_slide_index()){
						items[k].deactivate();
					}
				}
			},
			
			bind_nav_items_to_dom : function (element_id) {
				var current_nav_items = this.get_nav_items_for_page(this.get_current_page_number());
				for (var i=0; i < NAV_ITEMS_PER_PAGE; i++) {
					if(current_nav_items[i]){
						current_nav_items[i].set_dom_node($('#'+element_id+' li')[i]);
					}
				};
				// remove list items that we're not using anymore.
				$('#'+element_id+' li[rel!=attached]').remove();				
				bind_click_events_to_pagination_links();
			},
			
			get_nav_items : function () {
				return nav_items;
			},
			
			get_nav_items_for_page : function (page_number) {
				var items = [];
				for (var i=0; i < this.get_nav_items().length; i++) {
					if(this.get_nav_items()[i].get_page() == page_number){
						items.push(this.get_nav_items()[i]);
					}
				};
				return items;
			},
			
			// slide_index goes from 0 to the end of the array
			// of all slides.
			// This is different to the row_index which is a
			// per page index from 0 to `NAV_ITEMS_PER_PAGE`
			set_current_slide_index : function (index) {
				current_slide_index = parseInt(index);
				if(MCFC.carousel.data.use_url_hashes && index > 0 || MCFC.hash.get()){
					MCFC.hash.set(index);
				}
			},
			
			get_current_slide_index : function () {
				return current_slide_index;
			},
			
			set_current_page_number : function (page_number) {
				this.change_pagination_highlight(current_page_number, page_number);
				current_page_number = page_number;
			},
			
			get_current_page_number : function () {
				return current_page_number;
			},
			
			get_next_page_number : function () {
				return this.total_number_of_pages() > this.get_current_page_number() ? this.get_current_page_number() + 1 : false;
			},
			
			get_previous_page_number : function () {
				return this.get_current_page_number() > 1 ? this.get_current_page_number() - 1 : false; 
			},
			
			change_pagination_highlight : function (from_number, to_number) {
				from_number = from_number === undefined ? 1 : from_number;
				var links = $('#carousel-pagination-links a');
				if(links){
					$(links[from_number-1]).removeClass('active');
					$(links[to_number-1]).addClass('active');
				}
			},
			
			get_page_number_for_slide_index : function(slide_index) {
				return Math.floor(slide_index/NAV_ITEMS_PER_PAGE)+1;
			},
			
			total_number_of_pages : function () {
				return Math.ceil(this.get_nav_items().length/NAV_ITEMS_PER_PAGE);
			},
			
			preload_slides_for_page : function (page_number) {
				var nav_items = this.get_nav_items_for_page(page_number);
				//console.log('preloading slides for page ' + page_number);
				for (var i=0; i < nav_items.length; i++) {
					nav_items[i].get_slide().load(null, null, MCFC.carousel.data.preload_images);
				};
			},
			
			change_page : function (page_number) {
				//console.log('change_page called: ' + page_number);
				
				// make sure we stop the timer as soon as 
				// the user start interacting with the piece.
				this.stop_timer();
				
				// make sure it's not the same as current
				if(page_number == this.get_current_page_number()) {
					return false;
				}
				
				// make sure requested page have slides
				var new_nav_items = this.get_nav_items_for_page(page_number);

				if(!new_nav_items.length) {
					return false;
				}
				
				if(MCFC.carousel.data.preload_slides_for_active_page){
					this.preload_slides_for_page(page_number);
				}
				
				// get current nav items
				var current_nav_items = this.get_nav_items_for_page(this.get_current_page_number());

				// what direction are we paginating?
				var direction = page_number < this.get_current_page_number() ? 1 : -1;
				
				transition_nav_items(new_nav_items, direction, 'show');
				transition_nav_items(current_nav_items, direction*-1, 'hide');				
				this.set_current_page_number(page_number);
			},
			
			change_slide : function (slide_index) {
				console.log('change_slide called: ' + slide_index);
				
				// make sure we're not trying to load same slide again.
				if(slide_index == this.get_current_slide_index()){
					console.warn('Already on slide '+ slide_index);
					return false;
				}
				
				// does the next slide exist?
				var all_nav_items = this.get_nav_items();
				if(!all_nav_items[slide_index]) {
					console.warn('Slide index '+ slide_index + ' does not exist');
					return false;
				}
				
				// goto the page that holds this nav item
				this.change_page(this.get_page_number_for_slide_index(slide_index));
				// activate this navitem
				var new_nav_item = all_nav_items[slide_index];
				this.deactivate_all_navitems(new_nav_item);
			
                var s = new_nav_item.get_slide();	
				s.show();
				new_nav_item.mouseenter();
				new_nav_item.activate(true);
				
				this.set_current_slide_index(slide_index);
				
				return false;
			},
			
			
			/*
			*	TIMER METHODS
			*/
			
			render_timer : function(element_id, milliseconds, autostart) {
				timer_id = element_id;

				var params = {
					wmode: 'transparent'
				};
				
				var attributes = {
					id: timer_id
				};

				var flashvars = {
					debug : 0,
					milliseconds : milliseconds,
					on_time_up : 'MCFC.carousel.nav_manager.time_up',
					on_init : 'MCFC.carousel.nav_manager.timer_init',
					autostart : autostart ? 1:0
				};
				MCFC.swf.embed('/flash/carouseltimer/carouseltimer.swf', timer_id, 20, 20, flashvars, params, attributes);
			},
			
			timer_init : function () {
				
			},
			
			start_timer : function () {
				var timer_object = document.getElementById(timer_id);
				if(timer_object){
					timer_object.start_timer();
				}
			},
			
			stop_timer : function () {
				var timer_object = document.getElementById(timer_id);
				if(timer_object && timer_object.stop_timer){
					timer_object.stop_timer();
				}
			},
			
			time_up : function () {
				// move to next slide and highlight the next navitem in line.
				var current = MCFC.carousel.nav_manager.get_current_slide_index();
				var number_of_items = MCFC.carousel.nav_manager.get_nav_items().length;
				var next = current + 1 == number_of_items ? 0 : current + 1;
				MCFC.carousel.nav_manager.change_slide(next);
				MCFC.carousel.nav_manager.start_timer();
			}		
			
		};
	}();
	
	var hash_changed_callback = function (hash_value) {
		if(hash_value){
			carousel_nav_manager.change_slide(hash_value);
		}
	};
	
	var load_carousel_data = function () {
		// make sure that the data object is present
		if(!MCFC.carousel.data) {
			console.warn("Please define the MCFC.carousel.data object to load the carousel");
			return false;
		}
		
		if(!MCFC.carousel.data.carousel_nav_element_id) {
			console.info("No navigation will be bound to the DOM. carousel_nav_element_id not found.");
			var render_navigation = false;
		}else{
			var render_navigation = true;
			var parent_nav_node = $('#'+MCFC.carousel.data.carousel_nav_element_id);
			var parent_nav_node_clone = $('li:first', parent_nav_node).clone();
		}
		
		// subscribe to hash change events.
		if(MCFC.carousel.data.use_url_hashes){
			MCFC.hash.on_change(hash_changed_callback);
		}
		
		// set starting slide and page.
		//carousel_nav_manager.set_current_slide_index(MCFC.carousel.data.current_slide_index);
		if(MCFC.carousel.data.use_url_hashes && MCFC.hash.get(0) && MCFC.hash.get(0).length <= 2 && parseInt(MCFC.hash.get(0))) {
			//console.log('Gettings current slide from hash: '+MCFC.hash.get(0));
			var current_slide_index = MCFC.hash.get(0);
			var loading_from_hash = true;
		}else{
			var current_slide_index = MCFC.carousel.data.current_slide_index;
		}
		carousel_nav_manager.set_current_page_number(Math.floor(current_slide_index/NAV_ITEMS_PER_PAGE) + 1);
		
		var page = 0;
		var row_index = 0;
		for(var i = 0; i < MCFC.carousel.data.slides.length; i++) {
			if(i%NAV_ITEMS_PER_PAGE==0){ page++; row_index=0; }
			var is_active = current_slide_index==i;
			var mark_slide_as_active = is_active && !loading_from_hash;
			var slide = new Slide(MCFC.carousel.data.slides[i], mark_slide_as_active, i);
			if (render_navigation){
				carousel_nav_manager.add_nav_item(
					new NavItem(slide, row_index, page, is_active, $(parent_nav_node_clone).clone(), parent_nav_node));
			}
			row_index++;
		}
		
		// attache the current already rendered nav items to the objects we just created.
		carousel_nav_manager.bind_nav_items_to_dom(MCFC.carousel.data.carousel_nav_element_id);
		
		// preload the first page of slides
		if(MCFC.carousel.data.preload_slides_for_active_page){
			carousel_nav_manager.preload_slides_for_page(carousel_nav_manager.get_current_page_number());
		}
		
		// attach the slideshow timer to the DOM
		carousel_nav_manager.render_timer('carousel-pagination-timer', MCFC.carousel.data.slideshow_milliseconds, MCFC.carousel.data.slideshow_autostart);
		
		// change to the current slide
		carousel_nav_manager.change_slide(current_slide_index);
		
	};

	MCFC.init.add_on_dom_ready(load_carousel_data);
	
	return {
		nav_manager : carousel_nav_manager
	};
	
}();

