// $Id: forbesjcarousel.js

ForbesJCarousel = function(id_placeholder, data_url, params) {
  this.id_placeholder = id_placeholder;
  this.data_url = data_url;
  this.params = params;
  this.cache = [];
  this.cacheFirst = 0;
  this.total = undefined;
  this.dataLoading = false;
  
  this.init();
};

/**
 * Static members & constants
 */
ForbesJCarousel.CACHE_SIZE = 40;
ForbesJCarousel.CACHE_LOAD_SIZE = 12;
ForbesJCarousel.CACHE_UNDERLOAD_SIZE = 6;

/**
 * Methods
 */
ForbesJCarousel.prototype.init = function () {
	this.cacheReset();
	
	if(typeof(this.params.initCallback) === "string") {
		this.params.initCallback = eval("fn = " + this.params.initCallback);
	}
	
	if(typeof(this.params.renderItemCallback) === "string") {
		this.params.renderItemCallback = eval("fn = " + this.params.renderItemCallback);
	}
	
	this.params.scroll = this.params.scroll ? parseInt(this.params.scroll) : 1;
	
	var t = this;
	var jcarouselParams = {
		scroll: this.params.scroll,
		itemLoadCallback: function(carousel, state) { 
  		t.itemLoadCallback(carousel, state);
  	},
  	itemVisibleOutCallback: {
  		onAfterAnimation: function(carousel, item, i, state, evt) {
  		  /*if(i == carousel.first-1) {
  		    alert('first');
  		    carousel.remove(i-1);
  		  }  
  		    
  		  if(i == carousel.last+1) {
  		    alert('last');
  		    carousel.remove(i+1);
  		  }*/
  		}
  	}
  };
		
	if(typeof(this.params.initCallback) === "function") jcarouselParams.initCallback = this.params.initCallback;
	
  if(this.params.start) jcarouselParams.start = parseInt(this.params.start);
	if(this.params.vertical) jcarouselParams.vertical = true;
	
  $('#' + this.id_placeholder).jcarousel(jcarouselParams);
};

ForbesJCarousel.prototype.cacheReset = function () {
	this.cache = [];
	this.cacheFirst = 0;
};


ForbesJCarousel.prototype.itemLoadCallback = function(carousel, state) {
  var carouselFirst = this.positionNormalize(carousel.first-this.params.scroll);
  var carouselLast = this.positionNormalize(carousel.last+this.params.scroll);
	if (carousel.has(carouselFirst, carouselLast)) return;

	var first, last;
	
	if(this.cacheHas(carouselFirst, carouselFirst) ) {
		this.render(carousel);
		
		if(this.dataLoading) return;
		
		first = this.positionNormalize(carousel.last + 1);
		last = this.positionNormalize(carousel.last + ForbesJCarousel.CACHE_UNDERLOAD_SIZE);
		
		if(this.cacheHas(first, last )) {
			first = this.positionNormalize(carousel.first - ForbesJCarousel.CACHE_UNDERLOAD_SIZE);
			last = this.positionNormalize(carousel.first - 1 );
			if(this.cacheHas(first, last )) {
				return;
			} else {
				first = this.cacheFirst - ForbesJCarousel.CACHE_LOAD_SIZE;
				last = this.cacheFirst - 1;
			}
		} else {
			first = this.cacheFirst + this.cache.length;
			last = this.cacheFirst + this.cache.length - 1 + ForbesJCarousel.CACHE_LOAD_SIZE;
		}
		
	} else {
		this.cacheReset();
		first = carousel.first - ForbesJCarousel.CACHE_LOAD_SIZE;
		last = carousel.last + ForbesJCarousel.CACHE_LOAD_SIZE;
	}

	first = this.positionNormalize(first);
	last = this.positionNormalize(last);

	
	var t = this;
	this.dataLoading = true;
  jQuery.getJSON(
		this.data_url, { first:  first,  last: last },
    function(data) {
			t.dataLoading = false;
    	t.cacheSet(data, carousel);
    	t.render(carousel);
    }
  );
};

ForbesJCarousel.prototype.render = function(carousel) {
  var carouselFirst = this.positionNormalize(carousel.first-this.params.scroll);
  var carouselLast = this.positionNormalize(carousel.last+this.params.scroll);
  
	for(var i = carouselFirst; i <= carouselLast; i++) {
	  if (carousel.has(i, i)) continue;
		if(this.cacheGetByNum(i)) {
			var item = carousel.add(i, this.cacheGetByNum(i));
			
			if(typeof(this.params.renderItemCallback) === "function") {
				this.params.renderItemCallback(this, item, i);
			}
		}
	}
};

ForbesJCarousel.prototype.getItemHTML = function(item) {
	return item;
};



ForbesJCarousel.prototype.cacheSet = function(data, carousel) {
	if(!(data.items instanceof Array) ) return;
	if(data.total) { 
		carousel.size(data.total);
		this.total = data.total;
	}
	
	
	var dataFirst = data.first;
	if(this.cacheFirst < dataFirst) {
		if(this.cacheFirst == 0) {
			this.cacheFirst = dataFirst;
			this.cache.push(data.items.shift());
			dataFirst++;
		}
		
		if( dataFirst == this.cacheFirst + this.cache.length) {
			while(data.items.length) this.cache.push(data.items.shift());
		}
		
		while(this.cache.length > ForbesJCarousel.CACHE_SIZE) {
			this.cache.shift();
			this.cacheFirst++;
		}
	} else {
		if( dataFirst + data.items.length == this.cacheFirst) {
			while(data.items.length) this.cache.unshift(data.items.pop());
		};
		this.cacheFirst = data.first;
		
		while(this.cache.length > ForbesJCarousel.CACHE_SIZE) {
			this.cache.pop();
		}
	}

};

ForbesJCarousel.prototype.cacheGetByNum = function(num) {
	return this.cache[num - this.cacheFirst];
};

ForbesJCarousel.prototype.positionNormalize = function(num) {
	if(num < 1) num = 1;
	if(this.total !== undefined && num > this.total) num = this.total;
	return num;
};

ForbesJCarousel.prototype.cacheHas = function(first, last) {
	return (first >= this.cacheFirst && last <= this.cacheFirst + this.cache.length-1);
};


jQuery.extend(ForbesJCarousel, {
	items: [],
	add: function(id_placeholder, data_url, params) {
		this.items.push(new ForbesJCarousel(id_placeholder, data_url, params));
	}
});

FBJCarouselHelper = function() {
};

FBJCarouselHelper.mainpersonsBlockRenderItemCallback = function (fbCarousel, item, i) {
	var imgSelector = $('IMG.imagecache', item).eq(0); 
	imgSelector.mouseover(function() {
		if( $(this).hasClass("selected") ) return;
		$('#' + fbCarousel.id_placeholder + ' LI IMG').removeClass("selected");
		$(this).addClass("selected");
		var html = $('<div>').append( $('.text_container', item).eq(0).clone() ).html();
		$('#placeholder-mainpersons').html(html);
		$('#placeholder-mainpersons .text_container').show();
	});
	
	if(i == 1 && fbCarousel.initBlock == undefined && imgSelector.length) {
		imgSelector.trigger('mouseover', imgSelector.get(0));
		fbCarousel.initBlock = true;
	}
};

FBJCarouselHelper.interviewBlockRenderItemCallback = function (fbCarousel, item, i) {
	var imgSelector = $('IMG.imagecache', item).eq(0); 
	imgSelector.mouseover(function() {
		if( $(this).hasClass("selected") ) return;
		$('#' + fbCarousel.id_placeholder + ' LI IMG').removeClass("selected");
		$(this).addClass("selected");
		var html = $('<div>').append( $('.text_container', item).eq(0).clone() ).html();
		$('#placeholder-interview').html(html);
		$('#placeholder-interview .text_container').show();
	});
	
	if(i == 1 && fbCarousel.initBlock == undefined && imgSelector.length) {
		imgSelector.trigger('mouseover', imgSelector.get(0));
		fbCarousel.initBlock = true;
	}
};


