/*
 * BILDER SLIDE GALLERY v1.1.5
 * by Sebastian Schilbe
 * PROTOTYPE / SCRIPTACULOUS
 *
 * SYNTAX
 * new Gallery( id, {options} );
 *
 * OPTIONS
 * left			<string>	id Button left						Default: null		Example: "btn_left"
 * right		<string>	id Button right						Default: null		Example: "btn_right"
 * scrollOne	<bool>		per element or per page scroll		Default: 0			Example: 1
 * duration		<int>		effect duration in sec				Default: 1			Example: 1.5 | 3
 * transition	<function>	transitions function				Default: Effect.Transitions.sinoidal	Example: Effect.Transitions.spring
 * index        <object>    Object with infos about index       Default: {}         Example: {id:'index'}
 * index.id     <string>    ID Index Container					Default: null		Example: 'index'
 * index.active <string>	Class or Img for active Element		Default: null		Example: 'class_active' | '<img src="active.png" />'
 * index.default<string>	Class or Img for inactive Element	Default: null		Example: 'class_inactive' | '<img src="inactive.png" />'
 *
 * METHODS
 * goto			<int>		page or element to show				Default: 0			Example: 1 | 2 | "next" | "first" | "last" | "previous"
 *
 * RELEASE NOTES
 * 1.1.5
 * Bug fixes for small picture collections. 
 * 1.1.4 (2008/12/30)
 * Index added
 * 1.1.3
 * Buttons fading when not needed
 * per Page scrolls last page is only last element
 */
var Gallery = Class.create({
    initialize: function(id, options){
        //User Parameters
        this.btn_r = options.left || null;
        this.btn_l = options.right || null;
        this.index = options.index || null;
		this.regler = options.regler;
		//this.index.default = options.index.default || null;
        this.scrollOne = options.scrollOne || 0; //Per Element oder per Seite scrollen?
        this.g = { //Id im g Object
            id: id
        }
        //Intern Parameters
        this.effectoptions = {};
        this.effectoptions = (options.duration) ? $H({
            duration: options.duration
        }) : this.effectoptions;
        this.effectoptions = (options.transition) ? this.effectoptions.update({
            transition: options.transition
        }) : this.effectoptions;
        
        this.css = new Template('##{id} > *'); //CSS Template String für $$ Funktion
        this.items = $$(this.css.evaluate(this.g)).length -
        parseInt($$(this.css.evaluate(this.g)).reverse().collect(function(n){
            return n.getWidth()
        }).inject(0, function(n, m, c){
            return (n + m <= $(id).getWidth()) ? n + m : (n.toString().startsWith('#')) ? n : "#" + (c-1);
        }).substr(1)); //Anzahl der Elemente abzüglich Elemente der letzten Seite  
//        this.items = $$(this.css.evaluate(this.g)).length;
        this.itemsWidth = $$(this.css.evaluate(this.g)).collect(function(n){ //Gesamtbreite aller Elemente
            return n.getWidth()
        }).inject(0, function(n, m){
            return n + m;
        });
        this.objectShown = 0; //Aktuell sichtbares/angewähltes Element 
        //Intern Functions
        this._wrap(); //Fügt einen DIV Container hinzu und legt die Elemente dort rein. CSS Template wird abgeändert
        if (this.btn_l) {
            $(this.btn_l).observe('click', this._move.bindAsEventListener(this, "next"));
        }
        if (this.btn_r) {
            $(this.btn_r).observe('click', this._move.bindAsEventListener(this, "previous"));
        }
        this.goto(0);
    },
    _wrap: function(){
        $(this.g.id).setStyle('overflow:hidden');
        var wrapperDiv = document.createElement('div');
        $$(this.css.evaluate(this.g)).invoke('wrap', wrapperDiv, {
            style: 'position:absolute;width:' + this.itemsWidth + 'px'
        });
        this.css.template = '##{id} > div > *'; //Template muss wegen WRAP geändert werden
    },
/*    _drawIndex: function(){
		if($(this.index.id).down()) $(this.index.id).down().remove();
        var wrapperDiv = document.createElement('div'), index = this.index, objectShown = this.objectShown;
        $(wrapperDiv).setStyle('margin:auto; text-align:center');
        $(this.index.id).insert({
            top: wrapperDiv
        });
        $R(1, this.items).each(function(n){
            $(wrapperDiv).insert({
                bottom: (index.default)?(index.default.match(/<img/))?index.default:'<span class="'+index.default+'">'+n+'</span>':'<span>'+n+'</span> '
            });
        });
		$$('#'+index.id+' div > *').each(bindIndex.bind(this));
		function bindIndex(el,n) {
			$(el).observe('click',this.goto.bind(this, n));
		}
		$$('#'+index.id+' div > *')[objectShown].insert({after:(index.active)?(index.active.match(/<img/))?index.active:'<span class="'+index.active+'">'+(objectShown+1)+'</span>':'<strong>'+(objectShown+1)+'</strong> '}).remove();
    },*/
    _move: function(e, wert){
        this.goto(wert);
    },
	_registerMove: function(e, wert) {
		//In regelmäßigen Abständen soll goto ausgelöst werden
		this._move.bind(this, wert);
		this.regular = setInterval(this._move.bind(this, wert), 1000);
	},
	_unregisterMove: function(e, wert) {
		//In regelmäßigen Abständen soll goto ausgelöst werden
		clearInterval(this.regular);
	},	
	getWidth: function() {
		return this.itemsWidth;
	},	
    goto: function(i){
        switch (i) {
            case "last":
                i = this.items - 1;
                break;
            case "first":
                i = 0;
                break;
            case "next":
                i = this.objectShown + 1;
                break;
            case "previous":
                i = this.objectShown - 1;
                break;
        }
        if (i >= this.items) 
            i = this.items - 1;
        if (this.scrollOne) { //Per Element scrollen
            if (i < 0) 
                return;
            var biggestPos = -this.itemsWidth + $(this.g.id).getWidth();
            if (i >= this.items - 1) 
                var newPos = biggestPos;
            else {
                var newPos = -1 *
                ($A($$(this.css.evaluate(this.g)).collect(function(n){
                    return n.getWidth()
                }).inGroupsOf(i+1, 0)[0]).inject(0, function(n, m){
                    return n + m;
                }) - $$(this.css.evaluate(this.g))[0].getWidth());
            }
            if (newPos < biggestPos) 
                newPos = biggestPos;
            var options = $H({
                x: newPos,
                y: 0,
                mode: 'absolute'
            });
            options.update(this.effectoptions);
            new Effect.Move($(this.g.id).down(), options.toObject(), {queue: 'end'});
            this.objectShown = i;
        }
        else { //Per Seite scrollen
            var newPos = $(this.g.id).getWidth() * -i;
            if (newPos < -this.itemsWidth || newPos > 0) {
                return;
            }
            var options = $H({
                x: newPos,
                y: 0,
                mode: 'absolute'
            });
            options.update(this.effectoptions);
            new Effect.Move($(this.g.id).down(), options.toObject(), {queue: 'end'});
            this.objectShown = i;
        }
        if (this.objectShown <= 0) {
//            $(this.btn_r).fade();
        }
        else {
//            $(this.btn_r).appear();
        }
        if (this.objectShown >= this.items - 1) {
//            $(this.btn_l).fade();
        }
        else {
//            $(this.btn_l).appear();
        }
		this.regler.setValue( this.objectShown/(this.items-1)  );
        if (this.index) 
            this._drawIndex();

    }
});

