/**
 *
 * Copyright (c) 2009 Lauri Borodkin (http://boro.ee)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 */
 
 
jQuery.bChanger = function() {
    
    var in_motion = false;
    var rollback = false;
    
    
    fadeObjects = function(element, settings, data, mark) {

        var mark = mark || false; 
        if(!in_motion) {
            if(
                (settings.direction == 'first' && 
                    ((data.current_obj == 0 && settings.loop) || data.current_obj > 0 || (settings.rollback && settings.autorun))) 
                || 
                (settings.direction == 'last' && 
                    ((data.current_obj == data.objs.length-1 && settings.loop) || data.current_obj < data.objs.length-1 || (settings.rollback && settings.autorun)))
                ||
                    mark
            ) {

                in_motion = true;
                
                jQuery(data.objs[data.current_obj]).fadeOut(settings.fadeOutTime, function() {});
                
                var between_time = settings.timeBetweenFading;
                if (between_time < 0) {
                    between_time = settings.fadeOutTime;
                }
                
                var between = setTimeout(function() {
                    var nextElement = 'none';
                    if(settings.direction == 'first') {
                        data.marks.removeClass('bc-mark-active');
                        jQuery(data.objs[data.current_obj]).css('z-index',data.zindex);
                        if (settings.loop && data.current_obj == 0) {
                            data.current_obj = data.objs.length-1;
                            nextElement = data.objs[data.current_obj];
                        }
                        
                        else if (settings.rollback && data.current_obj == 0) {
                            data.current_obj++;
                            nextElement = data.objs[data.current_obj];
                            settings.direction = 'last';
                            
                        }
                        else if (mark) {
                            data.current_obj = data.marks.index(mark);
                            nextElement = data.objs[data.current_obj];
                        }
                        else {
                            if (settings.rollback && data.current_obj == 1) {
                                rollback = true;
                            }
                            data.current_obj--;
                            nextElement = data.objs[data.current_obj];
                        }

                        jQuery(data.marks[data.current_obj]).addClass('bc-mark-active');
                        jQuery(nextElement).css('z-index',data.zindex+1).fadeIn(settings.fadeOutTime, function() {
                            in_motion = false;
                            
                            if (!settings.rollback && !settings.loop && data.current_obj == 0) {
                                activateEvents(element, settings, data);
                            }
                            if(settings.autorun) {
                                var pause = setTimeout(function() {
                                    
                                    if(rollback && !settings.loop) {
                                         var rollbackPause = setTimeout(function() {
                                             fadeObjects(element, settings, data);
                                             clearTimeout(rollbackPause);
                                             clearTimeout(pause);
                                             rollback = false;
                                        },settings.rollbackPause);
                                        
                                    }
                                    else {
                                        fadeObjects(element, settings, data);
                                        clearTimeout(pause);
                                    }
                                    
                                },settings.pause);
                            }
                        });

                    }
                    else {
                        data.marks.removeClass('bc-mark-active');
                        jQuery(data.objs[data.current_obj]).css('z-index',data.zindex);
                        if (settings.loop && data.current_obj == data.objs.length-1) {
                            data.current_obj = 0;
                            nextElement = data.objs[data.current_obj];
                        }
                        
                        else if (settings.rollback && data.current_obj == data.objs.length-1) {
                            data.current_obj--;
                            nextElement = data.objs[data.current_obj];
                            settings.direction = 'first';
                            
                        }
                        else if (mark) {
                           
                            data.current_obj = data.marks.index(mark);
                            nextElement = data.objs[data.current_obj];
                        }
                        else {
                            if(settings.rollback && data.current_obj == data.objs.length-2) {
                                rollback = true;
                            }
                            data.current_obj++;
                            nextElement = data.objs[data.current_obj];
                        }

                        jQuery(data.marks[data.current_obj]).addClass('bc-mark-active');
                        jQuery(nextElement).css('z-index',data.zindex+1).fadeIn(settings.fadeOutTime, function() {
                            in_motion = false;
                            if (!settings.rollback && !settings.loop && data.current_obj == data.objs.length-1) {
                                activateEvents(element, settings, data);
                            }
                            if(settings.autorun) {
                                var pause = setTimeout(function() {
                                    if(rollback && !settings.loop) {
                                         var rollbackPause = setTimeout(function() {
                                             fadeObjects(element, settings, data);
                                             clearTimeout(rollbackPause);
                                             clearTimeout(pause);
                                             rollback = false;
                                        },settings.rollbackPause);
                                        
                                    }
                                    else {
                                        fadeObjects(element, settings, data);
                                        clearTimeout(pause);
                                    }
                                },settings.pause);
                            }
                        });
                    }
                    clearTimeout(between);
                },between_time);
            }
        }
    };
    activateEvents = function(element, settings, data) {
		data.prev.click(function(event) {
		    if (settings.type == 'fader') {
		        settings.direction = 'first';
		        fadeObjects(element, settings, data); 
	        }
	        else if (settings.type == 'scroller') {
	            if(settings.direction == 'left' || settings.direction == 'right') {
	                settings.direction = 'right';
	            }
	            else {
	                settings.direction = 'down';
	            }
		        scrollObjects(element, settings, data); 
	        }
		});
		
		data.next.click(function(event) {
		    if (settings.type == 'fader') {
		        settings.direction = 'last';
		        fadeObjects(element, settings, data); 
	        }
	        else if (settings.type == 'scroller') {
	            if(settings.direction == 'left' || settings.direction == 'right') {
	                settings.direction = 'left';
	            }
	            else {
	                settings.direction = 'up';
	            }
		        scrollObjects(element, settings, data); 
	        }
		});
		    
		data.marks.click(function(event) {
		    if (settings.type == 'fader') {
		        fadeObjects(element, settings, data, this);
	        }
	        else if (settings.type == 'scroller') {
		        scrollObjects(element, settings, data, this); 
	        }
		});
    };
    
    scrollObjects = function(element, settings, data, mark) {
        var moving_length = 0;
        var moving_time = settings.time;
        var mark = mark || false;
        var step_count = 0;
        if (settings.stepSize == 0) { 
            if(settings.direction == 'right' || settings.direction == 'left') {
                settings.stepSize = data.objs_outer_div.width();
            }
            else {
                settings.stepSize = data.objs_outer_div.height(); }
            } 
        
        if(settings.stepSize > 0 && 
            (
                ((settings.direction == 'left' || settings.direction == 'right') && 
                    settings.stepSize <= data.objs_outer_div.width()) 
                || 
                ((settings.direction == 'up' || settings.direction == 'down') && 
                    settings.stepSize <= data.objs_outer_div.height())
            )
        ) {
            
            if(settings.direction == 'right' || settings.direction == 'left') {
                step_count = Math.floor(data.objs_div.width()/settings.stepSize);
                step_count = (data.objs_div.width() % settings.stepSize == 0) ? step_count-1 : step_count;
            }
            else {
                step_count = Math.floor(data.objs_div.height()/settings.stepSize);
                step_count = (data.objs_div.height() % settings.stepSize == 0) ? step_count-1 : step_count;
            }
            
            moving_length = settings.stepSize;
        }
        
        if(!settings.scrollerHasSpace) {
            if(settings.direction == 'right' || settings.direction == 'left') {
                if(settings.stepSize == data.objs_outer_div.width()) {
                    
                }
                else {
                    step_count = step_count - 1 - Math.ceil((data.objs_div.width()-data.objs_outer_div.width())/moving_length);
                }
                
            }
            else {
                if(settings.stepSize == data.objs_outer_div.height()) {}
                else {
                    step_count = step_count - 1 - Math.ceil((data.objs_div.height()-data.objs_outer_div.height())/moving_length);
                }
            }
            
            
        }
        
        if(!in_motion) {
            if(!settings.loop) {
                if(
                    ((settings.direction == 'right' || settings.direction == 'down') && 
                        (data.current_obj > 0 || settings.rollback && settings.autorun))
                    ||
                    ((settings.direction == 'left' || settings.direction == 'up') && 
                        (data.current_obj < step_count || settings.rollback && settings.autorun))
                    ||
                        mark
                ) {

                    in_motion = true;
                    
                    
                    
                    // Animation type
                        var animation = null;     
                        
                        if((settings.direction == 'left' || settings.direction == 'right') && settings.stepSize == data.objs_outer_div.width() && mark) {
                            var much = data.current_obj - data.marks.index(mark);
                            if(much == 0) {
                                moving_length = 0;
                                moving_time = 0;
                            }
                            else {
                                
                                if (data.current_obj < data.marks.index(mark) && settings.direction == 'right') { settings.direction = 'left'; }
                                else if (data.current_obj > data.marks.index(mark) && settings.direction == 'left') { settings.direction = 'right'; }
                                moving_length = moving_length * Math.abs(much);
                            }
                        }
                        else if((settings.direction == 'up' || settings.direction == 'down') && settings.stepSize == data.objs_outer_div.height() && mark) {
                            var much = data.current_obj - data.marks.index(mark);
                            if(much == 0) {
                                moving_length = 0;
                                moving_time = 0;
                            }
                            else {
                                if (data.current_obj < data.marks.index(mark) && settings.direction == 'down') { settings.direction = 'up'; }
                                else if (data.current_obj > data.marks.index(mark) && settings.direction == 'up') { settings.direction = 'down'; }
                                moving_length = moving_length * Math.abs(much);
                            }
                        }
                        
                        
                        switch (settings.direction) {
                            case 'up':
                                animation = {marginTop: '-='+(moving_length)+'px'};
                                break;
                            case 'down':
                                animation = {marginTop: '+='+(moving_length)+'px'};
                                break;
                            case 'right':
                                animation = {marginLeft: '+='+(moving_length)+'px'};
                                break;
                            default:
                                animation = {marginLeft: '-='+(moving_length)+'px'};
                                break;
                        }
                    
                    
                    jQuery(data.objs_div).animate(animation, moving_time, settings.easing, function() {
                        data.marks.removeClass('bc-mark-active');
                        
                        
                        if(settings.direction == 'left' || settings.direction == 'up') {
                            
                            if(mark) {
                                data.current_obj = data.marks.index(mark);
                                
                            }
                            else if (settings.rollback && data.current_obj == step_count-1) {
                                
                                data.current_obj++;
                                
                                if(settings.direction == 'left') {
                                    settings.direction = 'right';
                                }
                                else {
                                    settings.direction = 'down';
                                }
                                rollback = true;
                            }
                            else {
                                data.current_obj++;
                            }

                            jQuery(data.marks[data.current_obj]).addClass('bc-mark-active');
                            if (!settings.rollback && !settings.loop && data.current_obj == step_count) {
                                activateEvents(element, settings, data);
                            }
                            
                        }
                        else {
                            if(mark) {
                                data.current_obj = data.marks.index(mark);
                            }
                            else if (settings.rollback && data.current_obj == 1) {
                                
                                data.current_obj--;
                                
                                if(settings.direction == 'right') {
                                    settings.direction = 'left';
                                }
                                else {
                                    settings.direction = 'up';
                                }
                                rollback = true;
                            }
                            
                            else {
                                data.current_obj--;
                            }

                            jQuery(data.marks[data.current_obj]).addClass('bc-mark-active');
                            if (!settings.rollback && !settings.loop && data.current_obj == 0) {
                                activateEvents(element, settings, data);
                            }
                        }
                        in_motion = 0;
                        if(settings.autorun) {

                            var pause = setTimeout(function() {
                                if(rollback && !settings.loop) {
                                     var rollbackPause = setTimeout(function() {
                                         scrollObjects(element, settings, data);
                                         clearTimeout(rollbackPause);
                                         clearTimeout(pause);
                                         rollback = false;
                                    },settings.rollbackPause);
                                    
                                }
                                else {
                                    scrollObjects(element, settings, data);
                                    clearTimeout(pause);
                                }
                            },settings.pause);
                        }
                            
                           
                     });

                }
            }
            else {
                //console.log('loopib');
            }
        }
    };
        

	return {
	    init: function(element, settings, data) {
 			
 			if (settings.autorun) { 
                var pause = setTimeout(function() {
                    if(settings.type == 'fader') { fadeObjects(element, settings, data); }
                    else if(settings.type == 'scroller') { scrollObjects(element, settings, data); }
                    else if(settings.type == 'slider') { slideObjects(element, settings, data); }
                    clearTimeout(pause);
                },settings.pause);
 			    
 		    }
 			if (!settings.autorun) { activateEvents(element, settings, data); }
 			
		}
	};
}();

jQuery.fn.bChanger = function(options) {
	this.each(function() {
        
        // Settings
            var settings = jQuery.extend({
                build: true, // Genereerib ise changeri: true,false
                type: 'fader', // Tüübid: scroller, fader, slider
                easing: 'swing', // Liikumise stiil: swing, linear
                pause: 3000, // Animatsioonide vahel olev pausi aeg
                loop: true, // Pidev töötamine: true, false
                autorun: true, // Automaatne käivitamine: true, false
                time: 1000, // Animatsiooni kestvus scrolleri või slaideri korral
                direction: 'last', // Liikumise suund scrolleri või slideri korral: left, right, up, down. Fademise korral: frist, last
                rollback: false, // rollib edasi-tagasi
                rollbackPause: 6000,
                fadeOutTime: 1000,
                fadeInTime: 1000,
                timeBetweenFading: -1, // Fademise vahele jääb aeg -1 kui on võrne fadeout
                sliderBounce: false, // Hüppamine slideri korral
                stepSize: 0, // Ühe sammu pikkus: 0 - samm on võrdne objekti pikkusega 
                scrollerHasSpace: true, // Kui skrollimisel on lõpus tühimiks, kas seda arvestatakse või mitte,
                prev: null,
                next: null,
                marks: null
                }, options);
        
        
        // status attribute for scroller
            var scroller_status = false;
            
            
        // New data object
            var data = new Object();
        
        
        // Generates html if needed
            if (settings.build) {
                data.objs = jQuery(this).children();
    		    jQuery(this).wrapInner('<div class="bc-objs-outer"><div class="bc-objs"></div></div>');
    		    data.objs.css('display','block');
            }
            else {
                data.objs = jQuery(this).find('.bc-obj');
            }
        
        data.objs_outer_div = jQuery(this).find('.bc-objs-outer');
        data.objs_div = jQuery(this).find('.bc-objs');
        data.marks = (settings.marks) ? jQuery(settings.marks) : jQuery(this).find('.bc-mark');
        data.prev = (settings.prev) ? jQuery(settings.prev): jQuery(this).find('.bc-prev');
        data.next = (settings.next) ? jQuery(settings.next) : jQuery(this).find('.bc-next');
        
        data.marks.click(function(event) { event.preventDefault(); });
        data.prev.click(function(event) { event.preventDefault(); });
        data.next.click(function(event) { event.preventDefault(); });

        // Changing containers style
            var outer_div_pos = data.objs_outer_div.css('position');
            if (outer_div_pos != 'relative' && outer_div_pos != 'absolute'){
                data.objs_outer_div.css('position','relative');
            }
            data.objs_outer_div.css('overflow','hidden');
            data.objs_div.css('position','absolute');
            
            
        data.width = jQuery(this).width();
    	data.height = jQuery(this).height();  
        
        
        // Changing containers dimensions
            if (data.objs_outer_div.height() == 0) {
                if(data.height == 0) {
                    data.objs_outer_div.height(jQuery(data.objs[0]).outerHeight());   
                }
                else {
    	            data.objs_outer_div.height(data.height);
                }
            }
            if (data.objs_outer_div.width() == 0) {
                if(data.width == 0) {
                    data.objs_outer_div.width(jQuery(data.objs[0]).outerWidth());   
                }
                else {
    	            data.obj_outer_div.width(data.width);
                }
            }
        
        // changing objects style
            data.zindex = parseInt(data.objs.css('z-index')) || 0;
            
            data.objs.css('position','absolute');
            
            if (settings.type == 'fader') {
                
               if (settings.direction == 'first') {
                    jQuery(data.objs.hide());
                    jQuery(data.objs[data.objs.length-1]).css('z-index',data.zindex+1).show();
                    jQuery(data.marks[data.objs.length-1]).addClass('bc-mark-active');
                    data.current_obj = data.objs.length-1;
                }
                else {
                    jQuery(data.objs.hide());
                    jQuery(data.objs[0]).css('z-index',data.zindex+1).show();
                    jQuery(data.marks[0]).addClass('bc-mark-active');
                    data.current_obj = 0;
                }
                
            }
            
            
            if(settings.type == 'scroller') {
                
                if (settings.direction != 'left' && settings.direction != 'right' && settings.direction != 'up' && settings.direction != 'down') {
                    settings.direction = 'left';
                }
                
                if (settings.direction=='left' || settings.direction == 'up') {
                    jQuery(data.marks[0]).addClass('bc-mark-active');
                    data.current_obj = 0;
                }
                else if (settings.direction=='right' || settings.direction == 'down') {
                    jQuery(data.marks[data.objs.length-1]).addClass('bc-mark-active');
                    data.current_obj = data.objs.length-1;
                }
                      
                
                if(!settings.loop) {
                    var sum = 0;

                    data.objs.each(function() {
                        if (settings.direction == 'left') {
                            jQuery(this).css('left', sum+'px');
                            sum +=jQuery(this).outerWidth();
                        }
                        else if(settings.direction == 'right') {
                            jQuery(this).css('right', sum+'px');
                            sum +=jQuery(this).outerWidth();
                        }
                        else if(settings.direction == 'up') {
                            jQuery(this).css('top', sum+'px');
                            sum +=jQuery(this).outerHeight();
                        }
                        else {
                            jQuery(this).css('bottom', sum+'px');
                            sum +=jQuery(this).outerHeight();
                        }

                    });
                    
                    if (settings.direction=='left' || settings.direction=='right') {
                        
                        data.objs_div.width(sum);
                        data.objs_div.height(data.objs_outer_div.height());
                        if (settings.direction == 'right') {
                            
                            data.objs_div.css('margin-left', -(sum-jQuery(data.objs[data.objs.length-1]).outerWidth()) +'px');
                        }
                        if (data.objs_outer_div.width() < data.objs_div.width()) { scroller_status = true; }
                    }
                    else if(settings.direction == 'up' || settings.direction == 'down') {
                        data.objs_div.width(data.objs_outer_div.width());
                        data.objs_div.height(sum);
                        if (settings.direction == 'down') {
                            data.objs_div.css('margin-top', -(sum-jQuery(data.objs[data.objs.length-1]).outerHeight()) +'px');
                        }
                        if (data.objs_outer_div.height() < data.objs_div.height()) { scroller_status = true; }
                    }
                }
                else {
                    
                    if (settings.direction=='left' || settings.direction=='right') {
                        data.objs.each(function () {
                            jQuery(this).css('top',-jQuery(this).height() +'px');
                        });
                        jQuery(data.objs[0]).css('top','0px');
                    }
                    else if (settings.direction=='up' || settings.direction=='down') {
                        data.objs.each(function () {
                            jQuery(this).css('left',-jQuery(this).width() +'px');
                        });
                        jQuery(data.objs[0]).css('left','0px');
                    }
                }
            }
        
        //  Paneme objectid liikuma
            if (data.objs.length > 1) {
                
                switch (settings.type) {
                    case 'fader':
                        jQuery.bChanger.init(this, settings, data);
                        break;
                    case 'slider':
                        jQuery.bChanger.init(this, settings, data);
                        break;
                    default:
                        if(scroller_status) {
                            jQuery.bChanger.init(this, settings, data);
                        }
                        break;
                }
            }
        
	});
	return this;
};
        
