/*----------------------------------------------------------------------------------------------------------------------------------------------	jQuery News Rotator */

(function ($) {



    $.fn.Rotator = function (options) {

        var o = jQuery.extend({//Default values
            type: 'slideshow',				//type of rotation for elements: 'slideshow','event-triggered'
			interval: 3000,					//interval between slides
            items_query: '.items',			//jQuery selector string for the parent of items
            item_query: '.item',			//jQuery selector string for the items array
            orientation: 'horizontal',		//orientation for the slideshow. At moment only horizontal
			order: 'ascending',				//order of slideshow 'ascending' 'descending'
			horizontal_height: true,		//flag to indicate whether the height is to be adjusted or not
			items_displayed: 1,				//Number of items displayed at a time
            current_class: 'current',		//class of current element
            duration: 1000,					//duration of slideshow
            easing: "linear",
			buttons: null,
			button_active_class: 'carrousel-current',
			buttons_event: 'click',				//animation effect for slideshow
			start_pos: 0,					//start position of slideshow P.S. starts from index 0
			button_next: null,
			button_previous: null,
            beforeStart: function() { },	//before starting the script
            beforeSlide: function() { },	//before starting each animation effect
            afterSlide: function() { },		//after each animation
			onClick: function(){}

        }, options);

        function ascending()//checks if the order of the slideshow is ascending
		{
			if(o.order.match(/asc/gi) != null)return true;
			return null;	
		}
		
		function descending()//checks if the order of the slideshow is descending
		{
			if(o.order.match(/desc/gi) != null)return true;
			return null;	
		}

        function horizontal()//checks if the orientation of the slideshow is landscape/horizontal
        {
            if (o.orientation.toLowerCase().match(/horizontal/gi) != null) return true;
            return false;
        }
		
		function vertical()//checks if the orientation of the slideshow is landscape/horizontal
        {
            if (o.orientation.toLowerCase().indexOf(/vertical/gi) != null) return true;
            return false;
        }
		
		function curPos(obj)
		{
			var	pos = 0;//Set position to zero
			$(obj).find(o.item_query).each(function($key,$value){//Loop through each item
				if($(this).hasClass(o.current_class))pos = $key;
			});
			return pos;
		}
		
		function nextPos(obj)//Get position of next item
		{
			var pos = (curPos(obj) + o.items_displayed);
			return ($(obj).find(o.item_query).length == pos) ? 0 : pos;	
		}
		
		function previousPos(obj)//Get position of previous item
		{
			var pos = (curPos(obj) - o.items_displayed);
			var oItemLength = $(obj).find(o.item_query).length;
			
			if(pos < 0)
			{
				return ((oItemLength % o.items_displayed) == 0) ? oItemLength - o.items_displayed : (oItemLength - (oItemLength % o.items_displayed));
			} else {
				return pos;	
			}
		}

		/*
        function next(obj) {
            if (typeof $(obj).find('.' + o.current_class).next()[0] != 'undefined') {
                return $(obj).find('.' + o.current_class).next();
            } else {
                return $(obj).find(o.item_query + ':first');
            }
        }

        function previous(obj) {
            if (typeof $(obj).find('.' + o.current_class).previous()[0] != 'undefined') {
                return $(obj).find('.' + o.current_class).previous();
            } else {
                return $(obj).find(o.item_query + ':last');
            }
        }
		*/
		
		function activateButtons(obj)
		{
			if(!o.buttons)return;
			if(typeof o.buttons != 'string' && o.buttons.constructor.toString().match(/Array/) == null)throw new Error('NewsRotator expects the object literal argument \'buttons\' to be of jQuery selector string type or an array of jQuery selector string types');	
			if(typeof o.buttons == 'string')o.buttons = [o.buttons];
			for(var i = 0; i < o.buttons.length; i++)
			{
				if(typeof o.buttons[i] != 'string')throw new Error('NewsRotator expects the object literal argument \'buttons\' to be an array of jQuery selector string types');
				if($(o.buttons[i]).length != $(obj).find(o.item_query).length)throw new Error('NewsRotator expects the o.buttons jQuery selector string to reference the same number of elements as items');			
			}
			
			o.buttons_event = (o.buttons_event.match(/click/gi) != null) ? 'click' : o.buttons_event;
			o.buttons_event = (o.buttons_event.match(/mouseover/gi) != null) ? 'mouseover' : o.buttons_event;
			
			for(var i = 0; i < o.buttons.length; i++)
			{
				
				$(o.buttons[i]).bind(o.buttons_event,{anchors:o.buttons[i],obj:obj},function($e){
					if(o.buttons_event == 'click')$e.preventDefault();
					var sText = $(this).text();
					var oAnchor = this;
					var pos = 0;
					$($e.data.anchors).each(function($key,$value){
						if($(oAnchor)[0] == $(this)[0])pos = $key;
					});
					o.onClick();
					move($e.data.obj,pos);//move to element
				}).eq(0).addClass(o.button_active_class);
			}
		}
		
		function refreshButtons(obj)
		{
			if(!o.buttons)return;
			
			for(var i = 0; i < o.buttons.length; i++)
			{
				$(o.buttons[i]).removeClass(o.button_active_class).eq(curPos(obj)).addClass(o.button_active_class);//Remove current class from soon to be previous and add current class to soon to be current
			}
			
		}
		
		function activatePreviousButton(obj)
		{
			if(!o.button_previous)return;
			$(o.button_previous).bind('click',{obj:obj},function($e){
				$e.preventDefault();
				move($e.data.obj,previousPos($e.data.obj));
			});	
		}
		
		function activateNextButton(obj)
		{
			if(!o.button_next)return;
			$(o.button_next).bind('click',{obj:obj},function($e){
				$e.preventDefault();
				move($e.data.obj,nextPos($e.data.obj));
				
			});	
		}
	
		
		function move(obj,x)//moves to item with position 'x' 
		{
			
			if(obj.sliding)return;
			obj.sliding = true;
			
			if(o.type == 'slideshow')//If type of rotation is slideshow
			{
				$(this).find(o.items_query).stop();//stop current animation
				clearInterval(obj.oInterval);//clear current interval
				obj.oInterval = null;//set interval variable to null
			}
			
			//Remove class of previous to be item and add class of current to be item
            $(obj).find(o.item_query).removeClass('current').eq(x).addClass('current');
			
			if(horizontal())//If horizontal
			{
				if(o.horizontal_height)
				{
					$(obj).stop().animate({
						height: $(obj).find('.' + o.current_class).innerHeight()
					}, o.duration, o.easing).find(o.items_query).stop().animate({//Start animation of items parent
						'margin-left': (-(x * ($(obj).find('.' + o.current_class).innerWidth()))) + 'px',//set negative margin to items parent in order to move it to current item
						height: $(obj).find('.' + o.current_class).innerHeight()
					}, o.duration, o.easing, function () {//Once the animation is finished
						obj.sliding = null;
						refreshButtons(obj);
						o.afterSlide(); //Call function which is run after the slide is finished
						if(o.type == 'slideshow')slide(obj);//If type of rotation is slideshow
					});
				} else {
					$(obj).find(o.items_query).animate({//Start animation of items parent
						marginLeft: -(x * ($(obj).find('.' + o.current_class).innerWidth()))//set negative margin to items parent in order to move it to current item
					}, o.duration, o.easing, function () {//Once the animation is finished
						obj.sliding = null;
						refreshButtons(obj);
						o.afterSlide(); //Call function which is run after the slide is finished
						if(o.type == 'slideshow')slide(obj);//If type of rotation is slideshow
					});	
				}
				
			} else {//If vertical
				$(obj).find(o.items_query).animate({//Start animation of items parent
					marginTop: -(x * ($(obj).find('.' + o.current_class).innerHeight()))//set negative margin to items parent in order to move it to current item
				}, o.duration, o.easing, function () {//Once the animation is finished
					obj.sliding = null;
					refreshButtons(obj);
					o.afterSlide(); //Call function which is run after the slide is finished
					if(o.type == 'slideshow')slide(obj);//If type of rotation is slideshow
				
				});	
			}
			
			
        }
		
		function slide(obj)
		{
			obj.oInterval = setInterval(function () {//Set interval for slideshow
				
				o.beforeSlide();//before the slideshow
				if(ascending())
				{
					var x = nextPos(obj);//Get index of next item
				} else {
					var x = previousPos(obj);	
				}
				move(obj,x);
			}, o.interval);	
		}
		
		function setStartPos(obj)
		{
			if(o.start_pos >= $(obj).find(o.item_query).length)o.start_pos = 0;
			 
			if(o.start_pos != 0 && o.items_displayed > 1)o.start_pos = Math.floor(o.start_pos / o.items_displayed) * o.items_displayed;
			 
			$(obj).find(o.item_query).eq(o.start_pos).addClass(o.current_class);
			
			if(horizontal())//If horizontal
			{
				$(obj).css({
					height:	$(obj).find('.' + o.current_class).innerHeight()	
				}).find(o.items_query).css({//Start animation for parent of items
					marginLeft: -(o.start_pos * ($(obj).find('.' + o.current_class).innerWidth())),
					height:	$(obj).find('.' + o.current_class).innerHeight()
				});
				
			} else {//If vertical
				$(obj).find(o.items_query).css({//Start animation for parent of items
						marginTop: -(o.start_pos * ($(obj).find('.' + o.current_class).innerHeight()))	
				});	
			}
			
			refreshButtons(obj);
		}
		

        return this.each(function () {

//---------------------------------------------------------------------------------------------------------------------	START - prepare elements 
            
			//Set up each item
			$(this).find(o.item_query).css({
				margin: 0
			});
			
			
			
			if (horizontal())
			{
				//Set up the news rotator
				$(this).css({
					position: 'relative',
					'z-index': 1,
					overflow: 'hidden',
					height:$(this).find(o.item_query).innerHeight(),
					width: Math.round($(this).find(o.item_query).innerWidth() * o.items_displayed)
				});
				
				$(this).find(o.item_query).css({
					display: 'block'
				});
				
				//Set up the items holder
				$(this).find(o.items_query).css({
					height: $(this).find(o.item_query).innerHeight(),
					width: ($(this).find(o.item_query).innerWidth() * $(this).find(o.item_query).length),
					position: 'relative',
					overflow: 'hidden'
				});
				
				$(this).find(o.item_query).css('float', 'left');
				
			} else {
				
				//Set up the news rotator
				$(this).css({
					position: 'relative',
					'z-index': 1,
					overflow: 'hidden',
					height:$(this).find(o.item_query).innerHeight(),
					width:$(this).find(o.item_query).innerWidth()
				});
				
				$(this).find(o.item_query).css({
					display: 'block'
				});
				
				
				//Set up the items holder
				$(this).find(o.items_query).css({
					height: ($(this).find(o.item_query).innerHeight() * $(this).find(o.item_query).length),
					width: $(this).find(o.item_query).innerWidth(),
					position: 'relative',
					overflow: 'hidden'
				});	
			}
			
			

            
			
//---------------------------------------------------------------------------------------------------------------------	END - prepare elements

            o.beforeStart();	//before startint the rotator script

            if(o.type == 'slideshow')slide(this);//If type of rotation is slideshow
			
			activateButtons(this);
			activatePreviousButton(this);
			activateNextButton(this);
			
			setStartPos(this);
        });


    };

})(jQuery);



