/**
 * @fileoverview  toco3_teaserrotation
 *
 * @package  toco3_teaserrotation
 * @author   Murat Purc <murat@purc.de>
 * @author   Christian Ehret <ce@toco3.com>
 * @licence  GNU General Public License v2, 
 *           http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * @requires Prototype JavaScript framework and script.aculo.us
 */


/**
 * Class toco3_teaserrotation
 *
 * @class
 */
var toco3_teaserrotation = Class.create({

	/**
	 * Slidebox element
	 *
	 * @type  {String}
	 */
	_slideBox: null,

	/**
	 * Width of slidebox
	 *
	 * @type  {Integer}
	 */
	_width: 0,

	/**
	 * Height of slidebox
	 *
	 * @type  {Integer}
	 */
	_height: null,

	/**
	 * List of slidebox items
	 *
	 * @type  {Array}
	 */
    _items: null,

	/**
	 * Spacer between two slides
	 *
	 * @type  {Integer}
	 */
    _spacer: 0,

	/**
	 * Duration of effect
	 *
	 * @type  {Float}
	 */
    _duration: 1,

	/**
	 * Position of current slide item
	 *
	 * @type  {Integer}
	 */
    _pos: 0,


	/**
	 * Interval for slideshow
	 *
	 * @type  {Integer}
	 */
    _interval: 5,

	/**
	 * List of available slide directions
	 *
	 * @type  {Array}
	 */
    _availableDirections: ["random", "lefttop-rightbottom", "left-right", "leftbottom-righttop", "top-bottom", "bottom-top", "righttop-leftbottom", "right-left", "rightbottom-lefttop", "cross-fade"],

	/**
	 * Current slide direction
	 *
	 * @type  {String}
	 */
    _direction: "left-right",

	/**
	 * Periodical executer used for slideshow
	 *
	 * @type  {PeriodicalExecuter}
	 */
    _pe: null,

	/**
	 * Flag about current running animation
	 *
	 * @type  {Boolean}
	 */
    _animating: false,

    _nextelement: null,
    _prevelement: null,

	/**
	 * Constructor
	 *
	 * @param  {String}  element  ID of slide box element
	 * @param  {Object}  options  Options as json object, as follows:
     *                            - options.autostart = Flag to autostart a slideshow
     *                            - options.stopOnMouseover = Flag to stop current running slideshow on mouseover
     *                            - options.startOnMouseout = Flag to start slideshow on mouseout
     *                            - options.itemsClass = Classname of slidebox items
     *                            - options.startPos = Start position of item
     *                            - options.spacer = Spacer in pixel between two slides
     *                            - options.interval = Intervall in seconds for slideshow
     *                            - options.duration = Duration of slide effect
     *                            - options.useItemsSizes = Flag to calculate slide box dimensions using items
     *                            - options.width = Width of slidebox in pixel
     *                            - options.height = Height of slidebox in pixel
     *                            - options.direction = Slide direction, one of this._availableDirections items
     *							  - options.autosize = Automatically resize paging buttons
	 */
	initialize: function(element, options) {
		if (typeof(options) == "undefined") {
		    throw("mpSlideBox.initialize: Missing options parameter");
            return;
        } else if (!$(element)) {
		    throw("mpSlideBox.initialize: Couldn't find slide box element having id '" + element + "'");
            return;
        } else if (typeof(options.itemsClass) == "undefined") {
		    throw("mpSlideBox.initialize: Missing option for class name of slide box items");
            return;
        }

        // slide box
        this._slideBox = element;
        
        // next element
        this._nextelement = options.nextelement;
        
        // prev element 
        this._prevelement = options.prevelement;
        
        // stop on mouseover
        if (typeof(options.stopOnMouseover) !== "undefined" && options.stopOnMouseover == true) {
            $(this._slideBox).observe("mouseover", this.stop.bind(this));
            $(this._nextelement).observe("mouseover", this.stop.bind(this));
            $(this._prevelement).observe("mouseover", this.stop.bind(this));
        }
        // start on mouseout
        if (typeof(options.startOnMouseout) !== "undefined" && options.startOnMouseout == true) {
            $(this._slideBox).observe("mouseout", this.start.bind(this));
            $(this._nextelement).observe("mouseout", this.start.bind(this));
            $(this._prevelement).observe("mouseout", this.start.bind(this));
        }

        // set slide box items
        this._items = $(this._slideBox).select("." + options.itemsClass);
        if (!this._items) {
            return;
        }

        // start position
        if (typeof(options.startPos) !== "undefined") {
            if (parseInt(options.startPos) >= 0 && parseInt(options.startPos) < this._items.length) {
                this._pos = parseInt(options.startPos);
            }
        }
        if ($(this._slideBox+'-'+this._pos)) {
        	$(this._slideBox+'-'+this._pos).addClassName('active');
        }
        // space between two slides
        if (typeof(options.spacer) !== "undefined" && parseInt(options.spacer) > 0) {
            this._spacer = parseInt(options.spacer);
        }

        // periodical executer intervall
        if (typeof(options.interval) !== "undefined" && parseInt(options.interval) > 0) {
            this._interval = parseInt(options.interval);
        }

        // duration of effect
        if (typeof(options.duration) !== "undefined" && parseFloat(options.duration) > 0) {
            this._duration = parseFloat(options.duration);
        }

        // initialize dimensions of box
        this._initializeDimensions(options);
        $(this._slideBox).setStyle({width: this._width + "px", height: this._height + "px", minHeight: this._height + "px"});

        if (typeof(options.autosize) !== "undefined" && options.autosize == true) {
          $(this._nextelement).setStyle({height: this._height + "px", minHeight: this._height + "px"});
          $(this._prevelement).setStyle({height: this._height + "px", minHeight: this._height + "px"});
        } 
        
        // initialize slide box items
        this._items.each(function(item, i){
            item.setStyle({position: "absolute", top: "0px", left: "0px", width: this._width + "px", height: this._height + "px"});
            if (i !== this._pos) {
                item.setStyle({display: "none",left: "-" + this._width + "px"});
            }
        }.bind(this));

        // set direction
        if (typeof(options.direction) !== "undefined") {
            this._availableDirections.each(function(item){
                if (item == options.direction) {
                    this._direction = options.direction;
                }
            }.bind(this));
        }

        if (typeof(options.autostart) !== "undefined" && options.autostart == true) {
            this.start();
        }
	},


    /**
     * Starts the periodical sliding of slide box items
     */
    start: function(){
        if (this._animating) {
            return;
        }
        this.stop();
        this._pe = new PeriodicalExecuter(this.next.bind(this), this._interval);
    },


    /**
     * Stops the periodical sliding of slide box items
     */
    stop: function(){
        //console.log('this._pe', this._pe);
        if (this._pe !== null) {
            this._pe.stop();
        }
    },


    /**
     * Displays the previous slide box item
     */
    previous: function(){
        if (this._animating) {
            return;
        }
        var currentPos = this._pos--;
        if (this._pos < 0) {
            this._pos = this._items.length - 1;
        }
        this._move(this._newSrollOptions(currentPos, this._pos, true));
    },


    /**
     * Displays the next slide box item
     */
    next: function(){
        if (this._animating) {
            return;
        }
        var currentPos = this._pos++;
        if (this._pos == this._items.length) {
            this._pos = 0;
        }
        this._move(this._newSrollOptions(currentPos, this._pos, false));
    },


    /**
     * Displays the slide box item by passed position
     *
     * @param  {Interger}  position  Position of item to show
     */
    showByPos: function(position){
        if (this._animating) {
            return;
        }
        if (position < 1 || position >= this._items.length) {
            return;
        }
        var currentPos = this._pos;
        this._pos = position--;

        this._move(this._newSrollOptions(currentPos, this._pos, false));
    },


    /**
     * Displays the slide box item by passed position
     *
     * @param  {Interger}  position  Position of item to show
     */
    goToPos: function(position){
        if (this._animating) {
            return;
        }
        if (position < 0 || position >= this._items.length) {
            return;
        }
        var currentPos = this._pos;
		var setreverse = false;
		if (position < currentPos) {
			setreverse = true;
		}
		this._pos = position--;
        this._move(this._newSrollOptions(currentPos, this._pos, setreverse));
		this.stop();
    },

    /**
     * Sets width and height of slide box by analyzing passed options
     *
     * @param  {Object}  options  Slide box options
     */
    _initializeDimensions: function(options) {
        // adapt to existing slide box item dimensions?
        var bUseItemsSizes = (typeof(options.useItemsSizes) !== "undefined" && options.useItemsSizes == true) ? true : false;
        if (bUseItemsSizes) {
            // loop thru each slide box  and set max dimensions
            this._items.each(function(item, i){
                if (this._width < item.getWidth()) {
                    this._width = item.getWidth();
                }
                if (this._height < item.getHeight()) {
                    this._height = item.getHeight();
                }
            }.bind(this));
        } else {
            // slide box width
            if (typeof(options.width) !== "undefined") {
                this._width = parseInt(options.width);
            } else {
                this._width = $(this._slideBox).getWidth();
            }

            // slide box height
            if (typeof(options.height) !== "undefined") {
                this._height = parseInt(options.height);
            } else {
                this._height = $(this._slideBox).getHeight();
            }
        }
    },


    /**
     * Returns the direction for next slide, @see this._availableDirections
     *
     * @returns  {String}  The direction identifier
     */
    _getDirection: function(){
        if (this._direction !== "random") {
            return this._direction;
        } else {
            var pos = 1 + parseInt((this._availableDirections.length - 1) * Math.random());
            //console.log('_getDirection() direction', this._availableDirections[pos]);
            return this._availableDirections[pos];
        }
    },


    /**
     * Returns the scroll options struct for the next slide
     *
     * @param  {Integer}  curPos   Current slide item position
     * @param  {Integer}  nextPos  Next slide item position
     * @param  {Boolean}  reverse  Flag to reverse 
     *
     */
    _newSrollOptions: function(curPos, nextPos, reverse){
        var height = this._height + this._spacer;
        var width  = this._width + this._spacer;
        if (reverse == true) {
            height = - height;
            width  = - width;
        }

        // base scroll options
        var opt = {
            cur: {
                pos: curPos, x: 0, y: 0
            },
            next: {
                pos: nextPos, x1: 0, y1: 0, x2: 0, y2: 0
            }
        };

        // set current box options
        var dir = this._getDirection();
        if (dir == "lefttop-rightbottom") {
            opt.cur.x = height;
            opt.cur.y = width;
        } else if (dir == "left-right") {
            opt.cur.x = 0;
            opt.cur.y = width;
        } else if (dir == "leftbottom-righttop") {
            opt.cur.x = - height;
            opt.cur.y = width;
        } else if (dir == "top-bottom") {
            opt.cur.x = height;
            opt.cur.y = 0;
        } else if (dir == "bottom-top") {
            opt.cur.x = - height;
            opt.cur.y = 0;
        } else if (dir == "righttop-leftbottom") {
            opt.cur.x = height;
            opt.cur.y = - width;
        } else if (dir == "right-left") {
            opt.cur.x = 0;
            opt.cur.y = - width;
        } else if (dir == "rightbottom-lefttop") {
            opt.cur.x = - height;
            opt.cur.y = - width;
        }

        // set next box options
        dir = this._getDirection();
        if (dir == "lefttop-rightbottom") {
            opt.next.x1 = - height;
            opt.next.y1 = - width;
            opt.next.x2 = height;
            opt.next.y2 = width;
        } else if (dir == "left-right") {
            opt.next.x1 = 0;
            opt.next.y1 = - width;
            opt.next.x2 = 0;
            opt.next.y2 = width;
        } else if (dir == "leftbottom-righttop") {
            opt.next.x1 = height;
            opt.next.y1 = - width;
            opt.next.x2 = - height;
            opt.next.y2 = width;
        } else if (dir == "top-bottom") {
            opt.next.x1 = - height;
            opt.next.y1 = 0;
            opt.next.x2 = height;
            opt.next.y2 = 0;
        } else if (dir == "bottom-top") {
            opt.next.x1 = height;
            opt.next.y1 = 0;
            opt.next.x2 = - height;
            opt.next.y2 = 0;
        } else if (dir == "righttop-leftbottom") {
            opt.next.x1 = - height;
            opt.next.y1 = width;
            opt.next.x2 = height;
            opt.next.y2 = - width;
        } else if (dir == "right-left") {
            opt.next.x1 = 0;
            opt.next.y1 = width;
            opt.next.x2 = 0;
            opt.next.y2 = - width;
        } else if (dir == "rightbottom-lefttop") {
            opt.next.x1 = height;
            opt.next.y1 = width;
            opt.next.x2 = - height;
            opt.next.y2 = - width;
        }

        return opt;
    },


    _move: function(opt) {

        /*change class of tab!! */    
        /*
        for(var i = 0; i < this._items.length; i++) {
        	$(this._slideBox+'-'+i).removeClassName('active');
        }*/
        if (this._direction == "cross-fade") {
        	if ($(this._slideBox+'-'+opt.cur.pos)) {
	    	  $(this._slideBox+'-'+opt.cur.pos).removeClassName('active');
        	}
	    	this._animating = true;
	        new Effect.Fade($(this._items[opt.cur.pos]), {
	            duration:   this._duration,
	            from: 1,
	            to: 0,
	            beforeStart: function(){
        		
	        }	            
	        });
	        
	        $(this._items[opt.next.pos]).setStyle({top: opt.next.x1 + "px", left: opt.next.y1 + "px"});
	        
	        if ($(this._slideBox+'-'+opt.next.pos)) {
	        	$(this._slideBox+'-'+opt.next.pos).addClassName('active');
	        }
	        new Effect.Appear($(this._items[opt.next.pos]), {
	            duration:   this._duration,
	            from: 0,
	            to: 1,
	            afterFinish: function(){
                this._animating = false;
                
            }.bind(this)	            
	        });
        	
        } else {
            if ($(this._slideBox+'-'+opt.cur.pos)) {
            	$(this._slideBox+'-'+opt.cur.pos).removeClassName('active');
            }
	    	this._animating = true;
	        new Effect.MoveBy($(this._items[opt.cur.pos]), opt.cur.x, opt.cur.y, {
	            duration:   this._duration,
	            transition: Effect.Transitions.sinoidal,
	            beforeStart: function(){
	        		
	        }
	        });
	        
	        $(this._items[opt.next.pos]).setStyle({top: opt.next.x1 + "px", left: opt.next.y1 + "px"});
	        if ($(this._slideBox+'-'+opt.next.pos)) {
	        	$(this._slideBox+'-'+opt.next.pos).addClassName('active');
	        }
	        new Effect.MoveBy($(this._items[opt.next.pos]), opt.next.x2, opt.next.y2, {
	            duration:   this._duration,
	            transition: Effect.Transitions.sinoidal,
	            afterFinish: function(){
	                this._animating = false;
	                
	            }.bind(this)
	        });
	    }
    }
});


if (!("console" in window) || !("firebug" in console)) {
(function(){
	window.console = {
		log:   function(){},
		debug: function(){},
		info:  function(){},
		warn:  function(){},
		error: function(){}
	}
})();
}
