/*
 ---
 script: Loop.js
 description: Runs a class method on a periodical
 license: MIT-style license.
 authors: Ryan Florence <http://ryanflorence.com>
 docs: http://moodocs.net/rpflo/mootools-rpflo/Loop
 requires:
 - core:1.2.4/'*'
 provides: [Loop]
 ...
 */
var Loop = new Class({

    loopCount: 0,
    isStopped: true,
    isLooping: false,
    loopMethod: $empty,
    
    setLoop: function(fn, delay){
        if (this.isLooping) 
            this.stopLoop();
        this.loopMethod = fn;
        this.loopDelay = delay || 3000;
        return this;
    },
    
    stopLoop: function(){
        this.isStopped = true;
        this.isLooping = false;
        $clear(this.periodical);
        return this;
    },
    
    startLoop: function(delay){
        if (this.isStopped) {
            var delay = (delay) ? delay : this.loopDelay;
            this.isStopped = false;
            this.isLooping = true;
            this.periodical = this.looper.periodical(delay, this);
        };
        return this;
    },
    
    resetLoop: function(){
        this.loopCount = 0;
        return this;
    },
    
    looper: function(){
        this.loopCount++;
        this.loopMethod(this.loopCount);
        return this;
    }
    
});

/*
 ---
 script: SlideShow.js
 description: The ultimate, class-based, slideshow class. Use any element, not just images. so it's prefect for galleries, newstickers, whatever.  Comes with packaged transitions but is ridiculously easy to extend and create your own transitions
 license: MIT-style license.
 authors: Ryan Florence
 docs: http://moodocs.net/rpflo/mootools-rpflo/SlideShow
 provides: [SlideShow]
 ...
 */
var SlideShow = new Class({

    Implements: [Options, Events, Loop],
    
    options: {
		delay: 7000,
		maxheight: 'auto'
    },
    
    initialize: function(element, tabs, options){
        this.setOptions(options);
        this.setLoop(this.showNext, this.options.delay);
        this.element = document.id(element);
        this.elementTabs = document.id(tabs);
        this.slides = this.element.getChildren();
        
        if (this.elementTabs) {
            this.tabs = this.elementTabs.getChildren();
            this.currentTab = this.tabs[0];

			this.history = HistoryManager.register(	
				this.elementTabs.id,
				[0],
				function(args) { this.showSlide(args[0]); }.bind(this),
				false,
				false);			
        }
        this.current = this.slides[0];
		//if (this.history) this.history.setValue(0,1);
        
        this.maxheight = 0;
        this.setup();
		
	},
    
    setup: function(){
        this.slides.each(function(slide, index){
            this.storeTransition(slide).reset(slide);
            slide.setStyle('display', 'block');
            slide.setStyle('width', slide.offsetwidth);
			
            this.maxheight = Math.max(this.maxheight, slide.offsetHeight);
            if (index != 0) {
                slide.setStyle('display', 'none');
			}
            slide.store('ssIndex', index+1);
        }, this);
		this.maxheight= parseInt(this.options.maxheight == 'auto'?this.maxheight:this.options.maxheight);
	
		if (this.options.maxheight != '') {
			this.element.setStyle('height', this.maxheight);
		}
		this.elementSize = this.element.getComputedSize();
		
		
        this.slides.each(function(slide, index){
            var slideSize = slide.getDimensions({computeSize: true});
			if (this.options.maxheight!='') {
				var h=this.maxheight-(slideSize['totalHeight']-slideSize['height']);
				slide.setStyle('height', h);
				slide.store('maxheight',h);
			} else {
				if (index==0)
					this.element.setStyle('height',slideSize['totalHeight']);
				slide.store('maxheight',slideSize['totalHeight']);
			}
			slide.setStyle('width', this.elementSize['width']-(slideSize['totalWidth']-slideSize['width']));
        }, this);
        if (this.elementTabs) {
            this.tabs.each(function(tab, index){
				if (index ==0)
		            tab.addClass('active');

                tab.addEvent('click', this.onClick.bindWithEvent(this, [index+1]));
            }, this);
        }
    },
    onClick: function(evt, index){
        this.showSlide(index);
        return false;
    },
    storeTransition: function(slide){
        var classes = slide.get('class');
        var transitionRegex = /transition:[a-zA-Z]+/;
        var durationRegex = /duration:[0-9]+/;
        var transition = classes.match(transitionRegex)[0].split(':')[1];
        var duration = classes.match(durationRegex)[0].split(':')[1];
        slide.store('ssTransition', transition);
        slide.store('ssDuration', duration);
        return this;
    },
    
    getTransition: function(slide){
        return slide.retrieve('ssTransition');
    },
    
    getDuration: function(slide){
        return slide.retrieve('ssDuration');
    },
    
    getIndex: function(slide){
        return slide.retrieve('ssIndex');
    },
    
    show: function(slide){
        var transition = this.getTransition(slide);
        var duration = this.getDuration(slide);
        var index = this.getIndex(slide);
        
        var previous = this.current.setStyle('z-index', 1);
        var next = this.reset(slide);
        this.transitions[transition](previous, next, duration, this);
		if (this.options.maxheight == '') {
			this.element.tween('height', next.retrieve('maxheight'));
		}
        if (this.elementTabs) {
            var previousTab = this.currentTab;
            var nextTab = this.tabs[index-1];
            previousTab.removeClass('active');
            nextTab.addClass('active');
            this.currentTab = nextTab;
        }
        (function(){
            previous.setStyle('display', 'none');
        }).bind(this).delay(duration);
		if (this.options.maxheight != '') {
		}
        this.current = next;
        return this;
    },
    
    reset: function(slide){
        return slide.setStyles({
            'position': 'absolute',
            'z-index': 0,
            'display': 'block',
            'left': 0,
			'overflow': 'hidden',
            'top': 0
        }).fade('show');
        return this;
    },
    
    nextSlide: function(){
        var next = this.current.getNext();
        return (next) ? next : this.slides[0];
    },
    
    previousSlide: function(){
        var previous = this.current.getPrevious();
        return (previous) ? previous : this.slides.getLast();
    },
    
    showNext: function(){
        this.show(this.nextSlide());
        return this;
    },
    
    showPrevious: function(){
        this.show(this.previousSlide());
        return this;
    },
    
    showSlide: function(index){
		if (this.history) this.history.setValue(0, index);
        index = Math.max(0, Math.min(index, this.slides.length));
        if (this.getIndex(this.current) != index) {
            this.show(this.slides[index-1]);
        }
    }
    
});

SlideShow.adders = {

    transitions: {},
    
    add: function(className, fn){
        this.transitions[className] = fn;
        this.implement({
            transitions: this.transitions
        });
    },
    
    addAllThese: function(transitions){
        $A(transitions).each(function(transition){
            this.add(transition[0], transition[1]);
        }, this);
    }
    
}

$extend(SlideShow, SlideShow.adders);
SlideShow.implement(SlideShow.adders);

SlideShow.add('fade', function(previous, next, duration, instance){
	previous.set('tween', {
        duration: duration
    }).fade('out');
    return this;
});

SlideShow.addAllThese([['crossFade', function(previous, next, duration, instance){
    previous.set('tween', {
        duration: duration
    }).fade('out');
    next.set('tween', {
        duration: duration
    }).fade('in');
    return this;
}
], ['pushLeft', function(previous, next, duration, instance){
    var distance = instance.element.getStyle('width').toInt();
    next.setStyle('left', distance);
    [next, previous].each(function(slide){
        var to = slide.getStyle('left').toInt() - distance;
        slide.set('tween', {
            duration: duration
        }).tween('left', to);
    });
    return this;
}
], ['pushRight', function(previous, next, duration, instance){
    var distance = instance.element.getStyle('width').toInt();
    next.setStyle('left', -distance);
    [next, previous].each(function(slide){
        var to = slide.getStyle('left').toInt() + distance;
        slide.set('tween', {
            duration: duration
        }).tween('left', to);
    });
    return this;
}
], ['pushDown', function(previous, next, duration, instance){
    var distance = instance.element.getStyle('height').toInt();
    next.setStyle('top', -distance);
    [next, previous].each(function(slide){
        var to = slide.getStyle('top').toInt() + distance;
        slide.set('tween', {
            duration: duration
        }).tween('top', to);
    });
    return this;
}
], ['pushUp', function(previous, next, duration, instance){
    var distance = instance.element.getStyle('height').toInt();
    next.setStyle('top', distance);
    [next, previous].each(function(slide){
        var to = slide.getStyle('top').toInt() - distance;
        slide.set('tween', {
            duration: duration
        }).tween('top', to);
    });
    return this;
}
], ['blindLeft', function(previous, next, duration, instance){
    var distance = instance.element.getStyle('width').toInt();
    next.setStyles({
        'left': distance,
        'z-index': 1
    }).set('tween', {
        duration: duration
    }).tween('left', 0);
    return this;
}
], ['blindRight', function(previous, next, duration, instance){
    var distance = instance.element.getStyle('width').toInt();
    next.setStyles({
        'left': -distance,
        'z-index': 1
    }).set('tween', {
        duration: duration
    }).tween('left', 0);
    return this;
}
], ['blindUp', function(previous, next, duration, instance){
    var distance = instance.element.getStyle('height').toInt();
    next.setStyles({
        'top': distance,
        'z-index': 1
    }).set('tween', {
        duration: duration
    }).tween('top', 0);
    return this;
}
], ['blindDown', function(previous, next, duration, instance){
    var distance = instance.element.getStyle('height').toInt();
    next.setStyles({
        'top': -distance,
        'z-index': 1
    }).set('tween', {
        duration: duration
    }).tween('top', 0);
    return this;
}
], ['blindDownFade', function(previous, next, duration, instance){
    this.blindDown(previous, next, duration, instance).fade(previous, next, duration, instance);
}
], ['blindUpFade', function(previous, next, duration, instance){
    this.blindUp(previous, next, duration, instance).fade(previous, next, duration, instance);
}
], ['blindLeftFade', function(previous, next, duration, instance){
    this.blindLeft(previous, next, duration, instance).fade(previous, next, duration, instance);
}
], ['blindRightFade', function(previous, next, duration, instance){
    this.blindRight(previous, next, duration, instance).fade(previous, next, duration, instance);
}
]]);

