/**
 * Carusel Class
 * Created By Sebastian Romero - Javier Morales
 * Feb - 5 / 2009 
 * Modified by Javier Morales JSON
 * Feb - 9 / 2009

 * var carusel = new Carusel(data.placements[0].items, document.getElementById("container"));
 * var carusel = new Carusel(""./data/home_page.json"", document.getElementById("container"));
 * carusel.onLoad = function(){alert("ja!")}
 * carusel.onError = function(errorCode){alert(errorCode);}	
 */
/**
 * 
 * @param {String} Path of the json Service
 * @param {HTMLObject} Where the Carousel will be place
 * @param {Boolean} If is looping carousel
 * @param {Boolean} Debug Mode
 * @param {HTMLObject} Holder for Pager
 * @param {Array} Array of feed paths for Tabs
 */
 function Carusel(data, conteiner, isLooping, debug, pagingHolder, feeds){
 	/**
 	 * Public Variables 
 	 */
	this.onLoad = null;
	this.onError = null;
	/**
	 * Private Variable
	 */
	var service = (data)?data:null;
	var htm_container = (conteiner)?conteiner:null;
	var boo_isLooping = (isLooping)?isLooping:false;
	var arr_itemsData;
	var itemInfo = new Object();
	var num_currentPosition = 0;
	var num_initialPos = 0;
	var num_finalPos = 0;
	var num_initialMargin = 5;
	var num_itemClick = 0;
	var num_direction = 1;
	var scope = this;
	var imgLoader;
	var marginAdjust = (document.all)?0:0;
	var handlersSize = 23 * 2; //Default size of the handlers (arrows) 
	var useLogger = debug;
	var currentPosition = 0;
	var fullItemWidth = 180;
	var numVisibleItems = 4;
	var pager = pagingHolder;
	var pages = 0;
	var maxMoves = 0;
	var isLoaded = false;
	var arr_feeds = feeds;
	
	/**
	 * Constants 
	 */
	var STR_WRAPPER_CONTENT = "baseWrapper";
	var STR_MOVE_LEFTCLASS = "move_left";
	var STR_MOVE_RIGHTCLASS = "move_right";
	var DATA_URL = "./data/home_page.json";
	var STR_FEEDERROR = "Error Code 1";
	var NUM_MARGIN = 10;
	
	/**
	 * Public methods
	 */
	this.initialize = function(){
		void carousel();
	};
	
	/**
	 * Loads the data returned by DATA_URL
	 */
	this.loadData = function(data, status){
		if (data.placements && data.placements.length>0)
		{
			data = data.placements[0];
		}
		if(data.strategy)
			setTitle(data.strategy);
		if(data.items && data.items.length>0){
			arr_itemsData = data.items;
			if(!isLoaded)
				buildItemsOnContainer();
		} else 
			hideCarouse();
	};	
	
	this.onCarouselResize = function(){
		changeMarginToElements();
	};
	
	
	/**
	 * Private methods
	 */
	 
	var carousel = function(){
		imgLoader = displayLoader();
		if(typeof(service) == "string"){
			$.getJSON((service)?service:DATA_URL, scope.loadData);
		} else {
			if(service!=null)
				scope.loadData(service);
			else
				hideCarouse();
		}
	};
	 
	
	var emptyCarausel = function(){
		$(htm_container).find(".item").remove();
		$(".loaderImage", htm_container).css("display", "");
		$(".baseWrapper", htm_container).css("width", 200);
		$(".baseWrapper", htm_container).css("left", 0);
		currentPosition = 0;
		isLoaded = false;
		arr_itemsData = new Array();
	};
	
	
	var getNodeIndex = function(node){
		var nodeIndex = 0;
		if(node){
			try {
				for (var i = 0; i<	node.parentNode.getElementsByTagName("li").length; i++){
					if(node.parentNode.getElementsByTagName("li")[i] === node){
						nodeIndex = i;
						break;
					}
				}
			} catch(e){
			}
		}
		return nodeIndex;
	};
	 
	/*
	Add Events to Tabs 
	Created by Sebastian Romero
	*/
	var addEventsToTabs = function(){
		var scope = this;
		$("#" + htm_container.id + "_tabs a").click(function(){
			 $(this).parents("ul").find("li").removeClass("selected");
			 if(!$(this).parents("li").hasClass("selected")){
				service = arr_feeds[getNodeIndex(this.parentNode)];
				$(this).parents("li").addClass("selected");
				void emptyCarausel();
				void carousel();
			 }
		});
	}
	 
	 
	var hideCarouse = function(){
		htm_container.style.display = "none";
		setTitle("");
		setTimeout(executeErrorHandler, 300);
	};
	
	var setTitle = function(title){
		$("h2", htm_container).html(title);
	};
	
	var buildItemsOnContainer = function(){
		var item, contentWrapper, finalWidth;
		isLoaded = true;
		contentWrapper = getContentWrapper();
		if(arr_itemsData.length == 0){
			hideCarouse();
			return;
		}
		for(var i = 0; i<arr_itemsData.length; i++) {
			item = itemElement(arr_itemsData[i]);
			finalWidth = 178 * Number(i);
			if(contentWrapper)
				contentWrapper.appendChild(item);
		}
		//This has to be reviewed. Items should not be presented more than once at the same moment
		//regardless of the size of the carousel.
		if(isLooping){
			for(var u = 0; u<2; u++){
				for(i in arr_itemsData) {
					item = itemElement(arr_itemsData[i]);
					finalWidth = 178 * Number(i);
					if(contentWrapper)
						contentWrapper.appendChild(item);
				}
			}
			num_itemClick = arr_itemsData.length*-1;
		}
		itemInfo.width = item.clientWidth;
		itemInfo.height = item.clientHeight;
		if(contentWrapper){
			finalWidth += (itemInfo.width + num_initialMargin);
			contentWrapper.style.width = finalWidth + "px";

			//contentWrapper.style.marginLeft = "25px";
			contentWrapper.parentNode.className = "rail";
			num_initialPos = 0;
			void hideLoader();	
			void addNavigationEvents();
			void getMaxHeight(getNumberOfItems());
			setTimeout(executeLoadHandler, 300);
			setTimeout(changeMarginToElements, 500);
			void changeMarginToElements();
			void addEventsToTabs();
		}
	};
	
	/**
	 * AddEvents to the Navigation Buttons, The Container shoul include STR_MOVE_LEFTCLASS and STR_MOVE_RIGHTCLASS
	 * difined on the HTML.
	 */
	var addNavigationEvents = function(){
		var a_leftNav, a_rigthNav;
		var size=0;
		if (htm_container) {
			var arr_aLinks = htm_container.getElementsByTagName("a");
			links : for(var i = 0; i<arr_aLinks.length; i++){
				//Handler for Right
				if(arr_aLinks[i].className == STR_MOVE_RIGHTCLASS){
					a_rigthNav = arr_aLinks[i] 
					a_rigthNav.onclick = gotoRight;
					size+=a_rigthNav.offsetWidth;
				}
				//Handler for Left
				if(arr_aLinks[i].className == STR_MOVE_LEFTCLASS){
					a_leftNav = arr_aLinks[i]; 
					a_leftNav.onclick = gotoLeft;
					size+=a_leftNav.offsetWidth;
				}
			}
			handlersSize = size; 
			log("Calculated handlers size: "+size+"px");
		}
	};
	
	/**
	 * 
	 * @param {Boolean} direction 
	 */
	var doAnimateWrapper = function (direction){
		var contentWrapper = getContentWrapper();
		var totalItems = $(".item",contentWrapper).length;
		maxMoves = numVisibleItems - totalItems;
		var newPosition;
		num_direction = (direction)?1:-1;
		newPosition = currentPosition + num_direction;
		if (contentWrapper) {
			log("Max moves: "+ maxMoves)
			log("currentPosition: "+ currentPosition);
			log("Direction: " + num_direction);
			if ((maxMoves <= newPosition || newPosition>currentPosition) && (currentPosition+num_direction) <= 0)
			{
				currentPosition+=num_direction;
				moveToPosition();
			}
			else if(pager)
			{				
				if (direction)
				{
					
					currentPosition = maxMoves;
					moveToPosition();
				}
				else
				{
					goToPage(1);
				}
			}
		}
	};
	
	var moveToPosition = function (avoidAnimation)
	{
		var contentWrapper = getContentWrapper();
		log("Moving");		
		if(avoidAnimation)
		{
			$(contentWrapper).css("left",(currentPosition * fullItemWidth) + "px");
		}
		else
		{
			$(contentWrapper).animate({
				left: (currentPosition * fullItemWidth) + "px"
			}, "low");
		}
		if(pager)
		{
			renderPager();
		}
	};

	
	/**
	 * 
	 * @param {Boolean} direction 
	 */
	var doLoopingAnimateWrapper = function (direction){
		var contentWrapper = getContentWrapper();
		var top_pos, num_init, secundPos, finalPos, finalDis;
		num_direction = (direction)?1:-1;		
		if (contentWrapper) {
			num_currentPosition += ((Number(itemInfo.width) + (num_initialMargin + marginAdjust)) * num_direction );
			top_pos = ((contentWrapper.offsetWidth - 100) - contentWrapper.parentNode.offsetWidth) * -1;
			num_init = ((Number(itemInfo.width) + (num_initialMargin + marginAdjust)) * -1 );
			secundPos = ((Number(itemInfo.width) + (num_initialMargin + marginAdjust)) * -1 )* arr_itemsData.length;
			finalPos = (((Number(itemInfo.width) + (num_initialMargin + marginAdjust)) * -1 )* ((arr_itemsData.length*3))) + contentWrapper.parentNode.offsetWidth - (num_initialMargin + marginAdjust);
			finalDis = (((Number(itemInfo.width) + (num_initialMargin + marginAdjust)) * -1 )* arr_itemsData.length)+ contentWrapper.parentNode.offsetWidth;
			if(num_currentPosition >= num_init){
				num_itemClick =  (arr_itemsData.length) + (num_direction * -1);
				num_currentPosition = secundPos;
				contentWrapper.style.left = secundPos + "px";
				doLoopingAnimateWrapper(direction);
				return;
			}
			if(num_currentPosition <= finalPos){
				num_itemClick = Math.floor(contentWrapper.offsetWidth/num_currentPosition);
				num_currentPosition = finalDis;
				contentWrapper.style.left = finalDis + "px";
				doLoopingAnimateWrapper(direction);
				return;
			}
			
			//if ((num_currentPosition <= num_initialPos) && num_currentPosition >= top_pos) {
			num_itemClick = num_itemClick + (num_direction * -1);
			$("." + contentWrapper.className, htm_container).animate({
				left: num_currentPosition + "px"
			}, "low");
		}
	};
	
	/**
	 * 
	 */
	var hideLoader = function(){
		var wrapper = getContentWrapper();
		wrapper.style.textAlign = "left";
		if(imgLoader){
			imgLoader.style.display = "none";
		}
	}
	
	/**
	 * 
	 */
	var displayLoader = function(){
		if(htm_container){
			for(var i = 0; i<htm_container.getElementsByTagName("img").length; i++){
				if(htm_container.getElementsByTagName("img")[i].className == "loaderImage"){
					imgLoader = htm_container.getElementsByTagName("img")[i];
					break;
				}
			}
		}
		if(imgLoader){
			var wrapper = getContentWrapper();
			imgLoader.style.display ="";
			wrapper.style.textAlign = "center";
			wrapper.appendChild(imgLoader);
		}
		return imgLoader;
	}
	
	/**
	 * Returns the Main Content
	 */
	var getContentWrapper = function(){
		var contentWrapper; 
		if(htm_container){
			content : for (var i = 0; i<htm_container.getElementsByTagName("div").length; i++){
				if(htm_container.getElementsByTagName("div")[i].className == STR_WRAPPER_CONTENT){
					contentWrapper = htm_container.getElementsByTagName("div")[i];
					break content; 
				}
			}
		}
		return contentWrapper;
	};
	
	/**
	* Returns an array with the currently available items in the given wrapper
	*/
	var getNumberOfItems = function(wrapper){ 
		return $("div.item", wrapper);
	};
	/**
	 * Calculates the max height of the items and then make it the height of every other item
	 */
	var getMaxHeight = function(items){
		var max_height = 180;
		for (var i=0; i<items.length; i++){
			if(items[i].offsetHeight > max_height){
				max_height = items[i].offsetHeight;
			}
		}
		items.css("height", max_height + "px");
		return max_height;
	};
	
	/**
	 * 
	 */
	var changeMarginToElements = function(){
		
		try {		
			log("****************CALCULATING NEW MARGINS - BEGIN********************");
			var ie6Padding = 100;//document.all && !document.XMLHttpRequest?10:0; 
			var contentWrapper = getContentWrapper();
			var items = $("div.item",htm_container);
			var minItemWidth = itemInfo.width + NUM_MARGIN; //Item width with min margin
			log("Item width: " + minItemWidth);				
			var targetWidth = contentWrapper.parentNode.parentNode.offsetWidth - handlersSize; //Size of the viewport
			log("Target width: " + targetWidth);
			var contentWrapper = getContentWrapper(); //Item content wrapper
			numVisibleItems = Math.floor(targetWidth/minItemWidth); //Items to show in the current viewport size
			numVisibleItems = items.length < numVisibleItems ? items.length : numVisibleItems; //Checks if there are less items in the carousel than can be show
			log("visible items: " + numVisibleItems);
			var itemMargin = Math.floor((targetWidth - (numVisibleItems * itemInfo.width)) / (numVisibleItems*2)); //New value for left and right margin
			log("Margins: "+itemMargin);
			var newLeft = currentPosition * (itemInfo.width+itemMargin*2);
			log("Left: "+newLeft)
			fullItemWidth = itemInfo.width + itemMargin * 2;
			
			items.css("margin-left",itemMargin+"px");
			items.css("margin-right",itemMargin+"px");
		
			$(contentWrapper.parentNode).css("width",((targetWidth-2+Math.floor(handlersSize/2)) - 25)+"px");
			$(contentWrapper).css("width",(fullItemWidth*items.length+ie6Padding)+"px");
			$(contentWrapper).css("position","relative");
			
			moveToPosition(true);			

			renderPager();
			
			log("*****************CALCULATING NEW MARGINS - END*********************");
		} catch(e){
			return;
		}
		
	};
	
	var renderPager = function(){
		var classes;
		var tag;
		var selectedPage;
		var isPageBegin;
		var totalItems = $("div.item",htm_container).length;
		if (pager)
		{			
			log("***RENDERING PAGER - BEGIN***");
			$("*",pager).remove();
			pages = Math.ceil(totalItems/numVisibleItems);		
			log("Pages: "+pages);
			if(pages>1)
			{
				selectedPage = Math.abs(currentPosition / numVisibleItems) + 1;
				log("Selected page: "+selectedPage);
				isPageBegin =  (currentPosition % numVisibleItems) == 0;
				log("Is page begin: "+isPageBegin);
				for (var i=1;i<=pages;i++)
				{
					classes = "";
					tag = "a";
					if(i==1)
					{
						classes += " first";
					}
					if (i==selectedPage && isPageBegin)
					{
						tag="span";
					}
					if(i==pages)
					{
						classes += " last";
					}
					log("Appending: ");
					$(pager).append(createPagerElement(tag, classes, i));
				}
			}
			log("****RENDERING PAGER - END****");
		}
	};
	
	var createPagerElement = function (tag, classes, page){
		var element = document.createElement(tag);
		element.className = classes;
		element.innerHTML = page;
		if(tag=="a")
		{
			element.href="javascript:;";
		}
		$(element).click(
				function()
				{
					goToPage(page);
				});	
		log(element);
		return element;
	};
	
	var goToPage = function(page){
		currentPosition = -1 * numVisibleItems * (page - 1);
		moveToPosition();
	};
	
	var itemElement = function(itemData){
		var html_element = document.createElement("div");
		html_element.className = (itemData.type)?itemData.type:"item normal ticketnew ";
		html_element.innerHTML = "<h4><a href=\""+((itemData.url)?itemData.url:"javascript:;")+"\">" + (itemData.name.length > 40 ? itemData.name.substr(0,40) + "..." : itemData.name) + "</a></h4> ";
		html_element.innerHTML += "<p class=\"placeimage\"><a href=\""+((itemData.url)?itemData.url:"javascript:;")+"\"><img src=\"" + itemData.image + "&qlt=75" + "\" alt=\""+itemData.name+
									"\" style=\"margin-left:20px;\" /></a></p>";
		html_element.innerHTML += "<div class=\"saveStory\">"+itemData.attr_savestory+"</div>";
		html_element.innerHTML += "<a class=\"view_more_btn\" href=\"" + ((itemData.url)?itemData.url:"javascript:;") + "\"></a> ";
		return html_element;
	};
	
	var gotoRight = function(){
		if(!boo_isLooping)
			doAnimateWrapper(false);
		else 
			doLoopingAnimateWrapper(false);
	};
	var gotoLeft = function(){
		if(!boo_isLooping)
			doAnimateWrapper(true);
		else 
			doLoopingAnimateWrapper(true);
			
	};
	
	var executeLoadHandler = function(){
		if(scope.onLoad)
			scope.onLoad();
	};
	var executeErrorHandler = function(){
		if(this.onError)
			this.onError(STR_FEEDERROR);
	};
	var log = function(message){
		if (useLogger)
		{
			try
			{
				console.log(message);
			}
			catch(exp){alert(message);}
		}
	};
	this.initialize();
 }

