/**
 * Main JS
 * Turbulent Media - juin 2010
 * @author frederic GINIOUX
 */
 
 
heap.api.cite = {};

heap.api.setup({
  object: heap.api.cite,
  api_class:'cite_api',
  url: heap.urlmap.cite_api_json,
  methods: ['getProductionsList']
});

$(document).ready(function(e){
	var citeMenu = new Cite.menu('#menu', {openActive: true, duration: 600});
	$('.cleanfield').cleanfield();
	positionLogo();
	$(window).resize(function() {
		positionLogo();
	});
});

var Cite = {
	tools: {
		stopEvent: function(evt){
			if(window.event){ //IE
				evt = window.event;
				evt.returnValue = false;
			}
			
			try {
				evt.cancelBubble = true;
				if(evt.preventDefault) evt.preventDefault();
				if(evt.stopPropagation) evt.stopPropagation();
				if(evt.stopped) evt.stopped = true;
			} catch(e) {
				/* console.log(e.message); */
			}		
			return evt;
		}		
	}, 
	
	menu: function(container, options){
		this.defaultOptions = {openActive: false, duration: 500, easing: 'easeInOutCubic'};
		this.options = jQuery.extend({}, this.defaultOptions, options);
		this.container = $(container);
		return this.init();
	}
};

$.extend(Cite.menu.prototype, {
	init: function(){
		var links = $('a.first', this.container);
		links.each(function(i, elt){
			var parent = $(elt).parents('li:first');
			if(!$('.submenu', parent).is('div')) return;
			$(elt).bind('click', function(e){
				Cite.tools.stopEvent(e);
				this.closeAll().open(arguments[0]);				
				return false;
			}.bind(this, $('.submenu', parent)));
		}.bind(this));
		
		if(this.options.openActive){ //Ouverture du sous-menu contenant un item actif
			var parent = $('a.active', this.container).parents('.submenu:eq(0)');
			if(parent.is('div')) this.closeAll().open(parent);			
		}		
		return this;
	}, 
	
	open: function(elt){
		if($(elt).height() == 0){
			var height = $('div:eq(0)', elt).innerHeight();
			var params = {
	  		duration: this.options.duration,
	  		easing: this.options.easing,
		  	complete: function(){ 
					$(this).addClass('overflow');
		  	}
		  };
			$(elt).stop(true, true).animate({height: height}, params);
		}		
		return this;
	}, 
	
	closeAll: function(){
		var elts = $('.submenu.overflow', this.container);
		var params = {
			duration: this.options.duration,
			easing: this.options.easing
		};
		elts.removeClass('overflow').stop(true, true).animate({height: 0}, params);
		return this;
	}
});

/* Block HTML cliquable -----*/
Cite.callToAction = function(container, htmlElts){
	this.container = $(container);
	this.url = this.getUrl();
	this.elts = this.getElts(htmlElts);
	return this.init();
};

$.extend(Cite.callToAction.prototype, {
	init: function(){
		for(var i = 0; i < this.elts.length; i++){
			this.callToAction(this.elts[i]);			
		}
		return this;
	}, 
	
	getElts: function(elts){
		var _return = new Array();
		for(var i = 0; i < elts.length; i++){
			var elt = $(elts[i], this.container);
			if(elt.is(elts[i])){
				_return.push(elt);
			}
		}
		return _return;
	}, 
	
	getUrl: function(){
		var url = null;
		$('a', this.container).each(function(i, elt){
			if($(elt).attr('href')){
				url = $(elt).attr('href');
				return;
			}
		});
		return url;
	},
	
	callToAction: function(elt){
		$(elt).bind('click', function(e){
			Cite.tools.stopEvent(e);
			var link = $('a:eq(0)', this.container);
			if(this.url){
				if(link.attr('target') == '_blank') window.open(this.url);
				else window.location.href = this.url;
			}			
			return false;			
		}.bind(this));		
	}
});

/**
 * Caroussel Widget
 */
Cite.Caroussel = function(container, options){
 	this.defaultOptions = {duration: 500, easing: 'easeInOutSine', speed: 'slow', display: 3, itemCssClass: '', scrollerCssClass: '', vertical: false};
	this.options = jQuery.extend({}, this.defaultOptions, options);
	this.container = $(container);
	this.scroller = new Object();
	this.items = new Array();
	this.btns = jQuery('.btn', this.container);
	this.index = 0;
	this.isInProcess = false;
	this.interval = null;
	return this.initialize();	
};
 
$.extend(Cite.Caroussel.prototype, {
 	/**
 	 * Initialise l'instance de l'objet 
 	 * Recupere tous les éléments et les enregistre dans le tableau this.items
 	 * Initialise l'objet scroller du caroussel
 	 * Enregistre les gestionnaires d'évènements sur les boutons de défilement
 	 * @return {Object} l'instance courante
 	 */
	initialize: function(){
		$(this.options.itemCssClass, this.container).each(function(i, elt){
			this.items.push(new Cite.CarousselElt(elt, {}));
		}.bind(this));
		
		this.initScroller();
		
		this.btns.each(function(i, elt){
			var $btn = jQuery(elt);
			$btn.bindAsEventListener('click', function(e){
				Cite.tools.stopEvent(e);
				var $btn = arguments[1] || null;
				if(!$btn || $btn.hasClass('.disabled')) return false;
				($btn.hasClass('prev'))? this.moveTo('prev') : this.moveTo('next');
				return false;
			}, this, $btn);
		}.bind(this));
		
		if(this.options.autoPlay)
		{
			this.clearAutoPlayInterval().setAutoPlayInterval();
			
			$(this.container).bind('mouseenter', function(e){
				this.clearAutoPlayInterval();			
			}.bind(this)).bind('mouseleave', function(e){
				this.setAutoPlayInterval();				
			}.bind(this));
		}
		
		return this.setBtnsAvailability();
	},
	
	clearAutoPlayInterval: function()
	{
		if(this.interval)
		{
			window.clearInterval(this.interval);
			this.interval = null;
		}
		return this;
	},
	
	setAutoPlayInterval: function()
	{
		this.interval = window.setInterval(function(){
			if(this.index == this.items.length - 1)
			{
				this.options.sliderElt.slider('value', 0);
			}
			else this.moveTo('next');
		}.bind(this), this.options.delay);
		return this;
	},
	
	/**
	 * Déplace le caroussel vers la droite ou la gauche
	 * @param {String} direction : prev || next
	 * @return {Object} l'instance courante
	 */
	moveTo: function(direction){
		if(this.isInProcess) return;
		this.isInProcess = true;
		var distance = (direction == 'prev')? this.getPrev() : this.getNext();
		$(this).trigger('move', [distance, direction, true]);
		if(!this.options.vertical) this.scroller.moveTo(distance, direction);
		else this.scroller.moveTo(distance, direction, true);
		return this;
	},
	
	/**
	 * 
	 */
	jumpTo: function(index){
		if(index == this.index) return;
		var direction = (index < this.index)? 'prev' : 'next';
		var distance = (!this.options.vertical)? index * -1 *	this.items[0].getWidth() : index * -1 *	this.items[0].getHeight();
		this.isInProcess = true;
		var that = this;
		/* Gestion init. scrolling */
		var args = (arguments[1])? [distance, direction, true] : [distance, direction];
		$(this).trigger('move', args);
		
		$(this.scroller).trigger('startMove', [direction]);
		var params = (this.options.vertical)? {top: distance} : {left: distance};
		this.scroller.container.stop().animate(params, {easing: this.scroller.options.easing, duration: this.scroller.options.duration, complete: function(){
			$(this).trigger('stopMove');
			that.isInProcess = false;
			that.index = index;
			that.setBtnsAvailability();
			$(this).trigger('endProcess');						
		}.bind(this.scroller)});
		return this;
	},
	
	/**
	 * Retourne l'index suivant pour un deplacement
	 * @return {Number} valeur de l'index suivant
	 */
	getNext: function(){
		var leftScroll = this.options.display - (this.index+1+this.options.display);
		return (!this.options.vertical)? this.items[0].getWidth() * leftScroll : this.items[0].getHeight() * leftScroll;
	},
	
	/**
	 * Retourne l'index précédent pour un deplacement
	 * @return {Number} valeur de l'index précédent
	 */
	getPrev: function(){
		var leftScroll = this.options.display - (this.index-1+this.options.display);
		return (!this.options.vertical)? this.items[0].getWidth() * leftScroll : this.items[0].getHeight() * leftScroll;
	},
	
	/**
	 * Fonction de callback appellée lors d'un déplacement vers l'avant
	 * @return {Object} l'instance courante
	 */
	goNextCallback: function(){
		this.isInProcess = false;
		this.index++;
		return this.setBtnsAvailability();
	},
	
	/**
	 * Fonction de callback appellée lors d'un déplacement vers l'arrière
	 * @return {Object} l'instance courante
	 */
	goPrevCallback: function(){
		this.isInProcess = false;
		this.index--;
		return this.setBtnsAvailability();
	},
	
	/**
	 * Creer une instance de classe Cite.CarousselScroller
	 * Declare les callback pour les évènements de fin de déplacement
	 * @return {Object} l'instance courante
	 */
	initScroller: function(){
		var params = {};
		if(this.items.length) params = {length: this.items.length, itemWidth: this.items[0].getWidth(), duration: this.options.duration, easing: this.options.easing};
		
		if(this.options.vertical){
			params['vertical'] = true;
			params['itemHeight'] = this.items[0].getHeight();
		}
		this.scroller = new Cite.CarousselScroller($(this.options.scrollerCssClass + ':eq(0)', this.container), params);
		
		$(this.scroller).bind('stopMoveNext', function(e){
			this.goNextCallback();
		}.bind(this)).bind('stopMovePrev', function(e){
			this.goPrevCallback();
		}.bind(this));
		
		return this;
	},	
	
	/**
	 * Vérifie la disponibilité des boutons du caroussel
	 * @return {Object} l'instance courante
	 */
	setBtnsAvailability: function(){
		var $nextBtn = $prevBtn = null;
		this.btns.each(function(i, elt){
			var $btn = $(elt);
			if($btn.hasClass('prev')) $prevBtn = $btn;
			else $nextBtn = $btn;
		});
		
		if($prevBtn){
			if(this.index <= 0){
				this.index = 0;
				$prevBtn.addClass('disabled');
			} else $prevBtn.removeClass('disabled');
		}
		
		if($nextBtn){
			if((this.index+this.options.display) >= this.items.length){
				$nextBtn.addClass('disabled');
			}	else $nextBtn.removeClass('disabled');
		}		
		
		$(this).trigger('endProcess');		
		return this;
	}
});
 
/**
	* Caroussel Widget Liste des éléments
  * @param {HTML elt} container : HTML elt.
  * @param {Object} options : objet contenant les options custom de l'élément
  * @methods
  * 	initialize();
  * 	getWidth();
  *		setWidth();
  *		moveTo();
  * @return {Object} l'instance courante
  */
Cite.CarousselScroller = function(container, options){
 	this.defaultOptions = {duration: 350, easing: 'easeInOutSine', speed: 'slow', length: 0, itemWidth: 400, itemHeight: 400, vertical: false};
	this.options = $.extend({}, this.defaultOptions, options);
	this.container = $(container);
	return this.initialize();
};
 
$.extend(Cite.CarousselScroller.prototype, {
 	initialize: function(){
		return this.setWidth();
	},
	
	/**
	 * Ajuste la taille du container des éléments
	 * @return {Object} l'instance courante
	 */
	setWidth: function(){
		var _width = this.options.length * this.options.itemWidth;
		if(_width > 0) this.container.css({width: _width});
		return this;
	},
	
	setHeight: function(){
		var _height = this.options.length * this.options.itemHeight;
		if(_height > 0) this.container.css({height: _height});
		return this;
	},
	
	/**
	 * Retourne la largeur courante du container des éléments
	 * @return largeur du container HTML en pixels
	 */
	getWidth: function(){
		return this.container.innerWidth();
	},
	
	getHeight: function(){
		return this.container.innerHeight();
	},
	
	/**
	 * Deplace le container des éléments
	 * A la fin du mouvement de deplacement lancement un trigger sur l'evenement stopMove
	 * A utiliser pour une fonction optionnelle de callback
	 * @param {Number} dist
	 * @return {Object} l'instance courante
	 */
	moveTo: function(dist, direction){
		$(this).trigger('startMove', [direction]);
		var params = (arguments[2])? {top: dist}: {left: dist};
		this.container.stop().animate(params, {duration: this.options.duration, easing: this.options.easing, complete: function(){
			(direction == 'prev')? $(this).trigger('stopMovePrev') : $(this).trigger('stopMoveNext');
			$(this).trigger('stopMove');
		}.bind(this)});
		return this;	
	}
});
 
/**
  * Caroussel Widget Elément
  * @params container : HTML elt.
  * @options Hash contenant les options custom de l'élément
  * @methods
  * 	initialize();
  * 	getWidth();
  * @return {Object} l'instance courante
	*/
 Cite.CarousselElt = function(container, options){
 	this.defaultOptions = {duration: 350, easing: 'easeInOutSine', speed: 'slow', vertical: false};
	this.options = $.extend({}, this.defaultOptions, options);
	this.container = $(container);
	this.isActive = (this.container.hasClass('.active'))? true : false;
	return this.initialize();
};
 
$.extend(Cite.CarousselElt.prototype, {
 	initialize: function(){
		return this;
	}, 
	
	/**
	 * Trouve la largeur d'un élément
	 * @return largeur du container de l'élément HTML en pixels
	 */
	getWidth: function(){
		var width = 0;
		var $parent = this.container.parents('li:eq(0)');
		if($parent.is('li')){
			width = $parent.innerWidth();			
		}
		else width = this.container.outerWidth(true);
		return width;
	}, 
	
	/**
	 * Trouve la hauteur d'un élément
	 * @return hauteur du container de l'élément HTML en pixels
	 */
	getHeight: function(){
		var height = 0;
		var $parent = this.container.parents('li:eq(0)');
		if($parent.is('li')){
			height = $parent.innerHeight();			
		}
		else height = this.container.outerHeight(true);
		return height;
	}
});


/**
  * Ajax search management
  * @params 
  * @options 
  * @methods
  * 	
  * 	
  * @return 
	*/
var triggerFolioObj = new Object();
Cite.folio = {
	sp: {},
	so: {},  
	process: false,
		
	get: function(type, rel){
		this.setParams(['so'], [this.getParams(type, rel)]);
		this.process = true;
		
    var sparams = { searchParams: this.sp, searchOptions: this.so };
    
		heap.api.cite.getProductionsList(function(r){
      //console.log(r.toSource());
		 	if(r.type == heap.SUCCESS){
		 		$(window['triggerFolioObj']).trigger('success');
		 		if(type == 'filters'){
			 		$('.filters a').each(function(i, elt){
			 			var elt = $(elt);
			 			elt.removeClass('active');
			 			if(elt.attr('rel') == rel) elt.addClass('active');	
			 		});
			 	}
			 	this.setActivePage().update(r.data.html);
		 	}
		 	else $(window['triggerFolioObj']).trigger('error');
		}.bind(this),sparams);
		
		return this;		
	},
	
	setActivePage: function(){
		var i = this.so.page;
		$('.pager li a').each(function(j, page){
			var p = $(page);
		 	if(j == (i-1)) p.addClass('active');
		 	else {
		 		p.removeClass('active');
		 	}
		});
		return this;
	},
	
	update: function(html){
		if(this.container.is('div')){
			this.container.html(html);
			this.process = false;
			$(window['triggerFolioObj']).trigger('update');
		}
		return this;	
	},
		
	getParams: function(type, rel){
		var params = {};
		switch(type){
			case 'filters': 
				var rels = rel.split('||');
				$.extend(params, {page: 1, sort: rels[0], sortOrder: rels[1]});
			break;
			case 'pages': 
				$.extend(params, {page: rel});
			break;
		}
		return params;
	},
	
	setParams: function(names, values){
		for(var i = 0; i < names.length; i++){
			if(!this.hasOwnProperty(names[i])) continue;
			else {
				$.extend(this[names[i]], values[i]);				
			}
		}
		return this;
	},
		
	init: function(so, sp, container){
		this.setParams(['so', 'sp'], [so, sp]);
		this.container = $(container);
		var filters = $('.filters a');
		filters.each(function(i, elt){
			var elt = $(elt);
			elt.bind('click', function(evt){
				Cite.tools.stopEvent(evt);
				if($(this).hasClass('active') || Cite.folio.process) return;
				Cite.folio.get('filters', $(this).attr('rel'));
				return false;
			});			
		});
		
		var pages = $('.pager li a');
		pages.each(function(i, elt){
			var elt = $(elt);
			elt.bind('click', function(evt){
				Cite.tools.stopEvent(evt);
				if($(this).hasClass('active') || Cite.folio.process) return;
				Cite.folio.get('pages', $(this).attr('rel'));
				return false;
			});			
		});
	}
};
var positionLogo = function(){
	var logo = $('#global_wrap #content #header a');
	var w = $(this).width();
	if(w < 1175){
		if(!logo.hasClass('fixed')){
			logo.addClass('fixed');
		}
	}else{
		if(logo.hasClass('fixed')){
			logo.removeClass('fixed');
		}
	}
}
