/**
 * @author Sebastian Romero, Laura Martinez 
 * @update Andres Garcia: Fixes
 * @date June 10th 2009 / June 12th 2009
 * All Functionality related with the Carousel Component
 * @param {Jquery, HTMLObject} element
 * @example 
 * 		var carousel;	
 * 		$(".rich_relevance").each(function(index, element){
 * 			carousel = new Carousel($(element));
 * 		});
 * @return Object;
 */

function Carousel(element){
	
	 /**
	 * Public Properties
	 */
	 this.carousel = $(element);
	 this.direction;
	 this.title = this.carousel.find("h3").text();
	 /**
	  * 
	  * @param {String} value
	  */
	 this.setDirection = function(value){
	 	this.carousel.removeClass(this.direction);
	 	properties.direction(value);
		this.carousel.addClass(value);
		this.direction = value;
	 	if (!this.carousel.hasClass("ready-" + value)) 
	 		void setUpCarousel();
	 };
	 
	 
	 /**
	  * 
	  * @param {String} value
	  */
	 this.setTitle = function(value){
	 	this.title = value;
		this.carousel.find("h3").html(value + "<span></span>");
	 };
	 
	 /**
	  * this removes the laoder
	  */
	 this.removeLoading = function(){
	 	$("#loading_carousel").remove();
	 };
	 
	 /**
	  * Clears the carousel
	  * TODO:Initialize the Object again
	  */
	 this.clear = function(){
	 	$(".product_rich_relevance").remove();
	 };
	
	
	/**
	 * Private Properties 
	 */
	var numberItems;
	var itemPosition = 0;
	var posY;
	var currentPos = 0;
	var cntWidth;
	var itemWidth;
	var maxItems = 5;
	var minItems = 4;
	var itemPadding = 20;
	var car;
	var itemsUsed = maxItems;
	var boo_animate = true;
	var canAnimate = true;
	var ItemsCompleteData;
	var scope = this;
	var fixedItemWidth = 0;
	var obj_pos;
	
	var setUpCarousel = function(){
	
		if(scope.direction === "horizontal"){
			numberItems = scope.carousel.find(".product_rich_relevance").size();
			//scope.carousel.find(".product_rich_relevance").find("a:first").addClass("titleLink"); /Laura: does not work as expected/
			car = scope.carousel.find(".wrapper_accordion_rich_relevance");
			scope.carousel.find("a.right_btn_accordeon").click(function(){moveRight()});
			scope.carousel.find("a.left_btn_accordeon").click(function(){moveLeft()});
			posY = car.position().left;
			//scope.carousel.addClass("ready-" + scope.direction);
		}
		
		if(scope.direction === "vertical"){
						
			var num_totalHeight = 0;
			var NUM_TOTAL_VERTICAL_ITEMS = 4 //Can be placed as a parameter
			var imgHeight = 100;
			
			scope.carousel.find("div.product_rich_relevance").each(
				function(index, element){
					if(index < NUM_TOTAL_VERTICAL_ITEMS){					
						num_totalHeight += imgHeight + parseInt($(this).children("a.CarLink").height()) + parseInt($(this).children("p.CarPart").height()) + parseInt($(this).children("p.price_rich_relevance").height()) + 30 + 16; //Padding top and bottom: 15 + 15
					}		
				}
			);
			
			//$(".vertical h3").css({"height":"35px"});
			scope.carousel.css("height", num_totalHeight + scope.carousel.find("h3").height() + 20 +"px");
		}
	 };
	 
	 
	 var findClassValue = function(pattern, e){
	 	var found = null;
	 	var classes = scope.carousel.attr("class").split(" ");
		values : for (var i = 0; i < classes.length; i++) {
			if (classes[i].match(pattern)) {
				found = classes[i].replace(pattern, "");
				break values;
			}
		}
		return found;
	 };
	 
	 var properties = {
	 	/**
	 	 * 
	 	 * @param {String} value
	 	 */
		 direction: function(value){
	 		 
	 		 scope.direction = scope.carousel.hasClass("vertical") ? "vertical" : "horizontal";
	 		 
	 		 //Andres Garcia: This is not neccesary... see the line above
			//scope["direction"] = (findClassValue("vertical"))?"vertical":"horizontal"
 		 },
		 height : function(){
 			 
 			//if(findClassValue("height")){ // Same as above
		 	 if (scope.carousel.hasClass("height")) {
			 	//if(findClassValue("height_", true))
			 	if(scope.carousel.hasClass("height_"))
			 		scope.carousel.css("height", parseInt(findClassValue("height_", true)));
			 }
		 }
	 };
	 
	 var moveRight = function(){
		itemWidth = scope.carousel.find(".wrapper_accordion_rich_relevance div.product_rich_relevance").width();	
		var module = numberItems%itemsUsed;
		posY = $(car).position().left;
		if(canAnimate){			
			if (currentPos<(numberItems - itemsUsed)){
				canAnimate = false;
				if (currentPos == ((numberItems-itemsUsed) - module)){
					if(boo_animate){
						$(car).animate({"left": posY - ((itemWidth + itemPadding) * (numberItems%itemsUsed))}, 1500, function(){canAnimate = true;});
					} else {
						$(car).css({"left": posY - ((itemWidth + itemPadding) * (numberItems%itemsUsed))});
						canAnimate = true;
					}
					//parseItems2(currentPos+itemsUsed, currentPos+(itemsUsed*2));
					currentPos+=module;
				} else {
					if(boo_animate) {
						$(car).animate({"left": posY - ((itemWidth + itemPadding) * itemsUsed)}, 1500, function(){canAnimate = true;});
					} else {
						$(car).css({"left": posY - ((itemWidth + itemPadding) * itemsUsed)});
						canAnimate = true;
					}
					currentPos+=itemsUsed;
				}
			}
		}
	};
	
	var moveLeft = function() {
		itemWidth = scope.carousel.find(".wrapper_accordion_rich_relevance div.product_rich_relevance").width();
		var posMod= currentPos%itemsUsed;
		var module = numberItems%itemsUsed;
		posY = $(car).position().left;
		if(canAnimate) {	
			if (currentPos > 0) {
				canAnimate = false;
				if (currentPos == module) {
					if(boo_animate) {
						$(car).animate({"left": posY + ((itemWidth + itemPadding) * (numberItems%itemsUsed))}, 1500, function(){canAnimate = true;});
					} else {
						$(car).css({"left": posY + ((itemWidth + itemPadding) * (numberItems%itemsUsed))});
						canAnimate = true;
					}
					currentPos-=module;	
				} else {	
					if(boo_animate) {
						$(car).animate({"left": posY + ((itemWidth + itemPadding) * itemsUsed)}, 1500, function(){canAnimate = true;});
					} else {
						$(car).css({"left": posY + ((itemWidth + itemPadding) * itemsUsed)});
						canAnimate = true;
					}
					currentPos-=itemsUsed;	
				}
			}
		}
	};
	
	var fixWidth = function(firstTime) {
		
			var minWidthMax = 170*maxItems;
			var minWidthMin = 170*minItems;
			
			cntWidth = scope.carousel.width() - (($(".left_btn_accordeon").width())*2);
	
			if (numberItems <= maxItems)
			{
				fixedItemWidth = Math.floor(cntWidth/numberItems);
				scope.carousel.find(".wrapper_accordion_rich_relevance div.product_rich_relevance").css("width",(fixedItemWidth-itemPadding+1));
				itemsUsed = numberItems;
			}
			else
			{		
				if(cntWidth>minWidthMax) {
					fixedItemWidth = Math.floor(cntWidth/maxItems);
					scope.carousel.find(".wrapper_accordion_rich_relevance div.product_rich_relevance").css("width",(fixedItemWidth-itemPadding+1));
					itemsUsed = maxItems;
		
				} else {
					if(cntWidth>400) {
						fixedItemWidth = Math.floor(cntWidth/minItems);
						scope.carousel.find(".wrapper_accordion_rich_relevance div.product_rich_relevance").css("width",(fixedItemWidth-itemPadding+1))
						itemsUsed = minItems;
					}
					
				}
			}
			
			
			//Andres Garcia: Please verify the result in obj_pos since it is always NaN (whichever browser) 
			if (firstTime){
				obj_pos = (-(currentPos * fixedItemWidth));
				if(!isNaN(obj_pos))
					$(car).css("left", obj_pos);
			}else{
				obj_pos = (-(currentPos * fixedItemWidth)-itemsUsed + 3);
				if(!isNaN(obj_pos))
					$(car).css("left", obj_pos);
				
			}

		

	};
	
	
	
	/**
	 * Removes the Loader on Component
	 */
	var removeLoader = function(){
		$(element).find(".loading").remove();
	}();
	
	var initialize = function(){
	 	for (var rule in properties) {
			(rule === "vertical" || rule === "horizontal")?rule = "direction" : rule = rule;
	 		if(properties.hasOwnProperty(rule)){
	 			try{properties[rule]();} catch(e){alert(e)}
	 		}
	 	}
		void setUpCarousel();
		fixWidth(true);
		$(window).resize(function(){
			fixWidth(false);
		});
	 }();
	 
	 
	return this;
}

/**
 * 
 * @param {Array} rr
 */
var initCarousels = function(rr){ 
	var carousel;
	//Andres Garcia: Modified to prevent non data feed js error
	$(".rich_relevance").each(function(index, element){
		if (rr.placements){
			if (rr.placements[index]) {
				$(".rich_relevance.horizontal").css("display", "block");
				RichRelevance.fillCarousel($(element), rr.placements[index]);
				document["carousel_" + index] = new Carousel($(element));
				document["carousel_" + index].removeLoading();
			} else {
				$(element).hide();
			}
		}else{
			$(element).hide();
		}
		
	});
};

/**
 * 
 * @param {JqueryObject} element
 * This function returns the instance of the carousel with object
 * @How to use
 * getCarouselInstance($("#carousel_1")).setTitle = "Changed";
 */
var getCarouselInstance = function(element){
	var carousel = null;
	carousels : for (var i = 0; i<$(".rich_relevance").size(); i++){
		if (document["carousel_" + i].carousel.get(i) === element.get(0)) {
			carousel = document["carousel_" + i];
			break carousels;
		}
	}
	return carousel;
};
/**
 * 
 * @param {JqueryObject} carousel
 * @param {Json} data
 */
var updateCarousel = function(carousel, data){
	var carouselObject = getCarouselInstance(carousel);
	if(carouselObject){
		carouselObject.clear();
		RichRelevance.fillCarousel(carousel, data);
	}
};

$(function(){
	//This initializes the carousel using json_template.js
	//initCarousels(rr_recs__);
});

