/*
---
script: Carousel.js
license: MIT-style license.
description: Tab - Minimalistic but extensible tab swapper.
copyright: Copyright (c) 2010 Thierry Bela
authors: [Thierry Bela]

requires:
  core:1.2.3:
  - Class.Extras
  - Element.Event
  - Element.Style
  - Element.Dimensions
  - Array
provides: [Carousel]
...
*/

(function () {

function style(el, style) {

	var mrg = el.getStyle(style);

	return mrg == 'auto' ? 0 : mrg.toInt()
}

var Carousel = this.Carousel = new Class({

		Implements: [Options, Events],
		options: {

		/*
			circular: false,
			onChange: function (index) {

			},
			previous: element1,
			next: element2,
			container: null,
			selector: '',
		*/
			mode: 'horizontal',
			animation: 'Move',
			scroll: 4,
			distance: 1,
			fx: {

				link: 'cancel',
				transition: 'sine:out',
				duration: 500
			}
		},
		plugins: {},
		initialize: function (options) {

			this.addEvent('change', function (current) {

				this.current = current

			}.bind(this)).setOptions(options);

			['previous', 'next'].each(function (val) {

				if($(this.options[val])) $(this.options[val]).addEvent('click', function (e) {

					e.stop();
					this[val]()

				}.bind(this))

			}, this);

			this.elements = $(options.container).getChildren(options.selector);

			this.current = 0;
			this.anim = new this.plugins[this.options.animation](this);

			this.move(this.options.current || 0);
		},

		isVisible: function (index) {

			if($type($(index)) == 'element') index = this.elements.indexOf($(index));

			var length = this.elements.length,
				current = this.current,
				scroll = this.options.scroll;

			if(current <= index && index < current + scroll) return true;

			if(this.options.circular) for(var i = 1; i < scroll; i++) {

				if((i + current)  % length == index) return true;
			}

			return false
		},

		first: function () {

			return this.current
		},

		previous: function (direction) {

			return this.move(this.current - this.options.distance, direction)
		},

		next: function (direction) {

			return this.move(this.current + this.options.distance, direction)
		},

		move: function (index, direction) {

			var elements = this.elements,
				current = this.current,
				length = elements.length,
				scroll = this.options.scroll;

			if($type($(index)) == 'element') index = elements.indexOf($(index));

			//if(this.isVisible(index)) return this;

			if(!this.options.circular) {

				if(index > length - scroll) index = length - scroll
			}

			else {

				if(index < 0) index += length
				index %= Math.max(length, 1);
			}

			if(index < 0 || length <= scroll || index >= length) return this;

			if(direction == undefined) {

				//detect direction. inspired by moostack
				var forward = current < index ? index - current : elements.length - current + index,
					backward = current > index ? current - index : current + elements.length - index;

				direction = Math.abs(forward) <= Math.abs(backward) ? 1 : -1
			}

			this.anim.move(this, index, direction);

			return this
		}
	});

	Carousel.prototype.plugins.Move = new Class({

		initialize: function (carousel) {

			var up = this.up = carousel.options.mode == 'vertical',
				options = this.options = carousel.options,
				elements = this.elements = carousel.elements.map(function (el) {

					return el.setStyles({display: 'block', position: 'absolute'})

				}),
				parent = elements[0].getParent(),
				pos = parent.setStyles({height: parent.offsetHeight, position: 'relative', overflow: 'hidden'}).getStyle('padding' + (this.up ? 'Top' : 'Left'));

				this.property = 'offset' + (up ? 'Top' : 'Left');
				this.margin = 'margin' + (up ? 'Top' : 'Left');

			this.reorder(0, 1).fx = new Fx.Elements(elements, options.fx)
		},

		reorder: function (offset, direction) {

			var options = this.options,
				panels = this.elements,
				ini = pos = style(panels[0].getParent(), 'padding' + (this.up ? 'Top' : 'Left')),
				i,
				index,
				length = panels.length,
				horizontal = options.mode == 'horizontal',
				side = horizontal ? 'offsetWidth' : 'offsetHeight';

			//rtl
			if(direction == -1) {

				for(i = length; i > options.scroll - 1; i--) {

					index = (i + offset + length) % length;
					panel = panels[index];

					if(horizontal) panel.setStyle('left', pos);
					else panel.setStyles({left: 0, top: pos});
					pos -= (panel[side] + style(panel, this.margin));
				}

				pos = ini + panel[side] + style(panel, this.margin);

				for(i = 1; i < options.scroll; i++) {

					index = (i + offset + length) % length;

					panel = panels[index];

					if(horizontal) panel.setStyle('left', pos);
					else panel.setStyles({left: 0, top: pos});
					pos += panel[side] + style(panel, this.margin);
				}

				//ltr
			} else if(direction == 1) for(i = 0; i < length; i++) {

				index = (i + offset + length) % length;
				panel = panels[index];

				if(horizontal) panel.setStyle('left', pos);
				else panel.setStyles({left: 0, top: pos});
				pos += panel[side] + style(panel, this.margin);
			}

			return this
		},

		move: function (carousel, current, direction) {

			var obj = {},
				up = this.up,
				property = this.property,
				offset;

			/*if(this.options.circular) this.reorder(carousel.current, direction)*/;

			offset = carousel.elements[current][property];

			carousel.elements.each(function (el, index) {

				obj[index] = up ? {top: el[property] - offset} : {left: el[property] - offset}
			});

			this.fx.cancel().start(obj).chain(function () { carousel.fireEvent('change', current) })
		}
	})
})();


/*
---
script: Carousel.js
license: MIT-style license.
description: Tab.Extra - Autosliding carousel.
copyright: Copyright (c) 2010 Thierry Bela
authors: [Thierry Bela]

requires:
  core:1.2.3:
  - Class.Extras
  - Element.Event
  - Element.Style
  - Element.Dimensions
  - Array
provides: [Carousel]
...
*/

Carousel.Extra = new Class({

		/*

			options: {

				interval: 10, //interval between 2 executions in seconds
				delay: 10, //delay between the moment a tab is clicked and the auto slide is restarted
				reverse: true //move backward
			},
			reverse: false, //move direction
		*/

			Extends: Carousel,
			Binds: ['update', 'start', 'stop'],
			initialize: function(options) {

				this.parent($merge({interval: 10, delay: 10}, options));

				//handle click on tab. wait 10 seconds before we go
				['previous', 'next'].each(function (val) {

					if($(this.options[val])) $(this.options[val]).addEvent('click', function (e) {

						e.stop();

						if(this.running) this.stop().start.delay(this.options.delay * 1000)

					}.bind(this))

				}, this);

				this.reverse = !!this.options.reverse;
				this.running = false;
				this.timer = new PeriodicalExecuter(this.update, this.options.interval);

				return this
			},

			update: function () { return this[this.reverse ? 'previous' : 'next']() },

			start: function () {

				this.timer.registerCallback();
				this.running = true;
				return this
			},

			stop: function() {

				this.timer.stop();
				this.running = false;
				return this
			}
		});


/*
Script: PeriodicalExecuter.js
	port of the Prototype.js timer to Mootools

	License: MIT-style license.
	Copyright: Copyright (c) 2007 Thierry bela <bntfr at yahoo dot fr>

	License:
		MIT-style license.

	Authors:
		Thierry Bela

	TODO: possibility to stop the timer when the window is idle ?
*/
	var PeriodicalExecuter = new Class({
		// name: 'PeriodicalExecuter',
		initialize: function(callback, frequency) {

			this.callback = callback;
			this.frequency = frequency;
			this.currentlyExecuting = false;

			this.registerCallback()
		},

		registerCallback: function() {

			this.stop();
			//this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
			return this
		},

		execute: function() {

			this.callback(this);
			return this
		},

		stop: function() {

			if (!this.timer) return this;
			clearInterval(this.timer);
			this.timer = null;
			return this
		},

		onTimerEvent: function() {

			if (!this.currentlyExecuting) {

				try {

					this.currentlyExecuting = true;
					this.execute();
				} finally {

					this.currentlyExecuting = false;
				}
			}

			return this
		}
	});
                
		var list = '';
		var arrSize = new Array();
	window.addEvent('domready', function () {
		//tabs
		tabcontents = $$('#slide div');
		if (tabcontents.length) {
			tabcontents.each(function (el, index) {
				var curtabname = el.getFirst('h6').get('text');
				var listLink = '<li><a href="#'+ index +'">'+ curtabname +'</a></li>';
				arrSize[index] = el.getStyle('height');
				list = list + listLink;
				$$('ul.tabs').set('html' ,'<li><a href="#page-p" class="invisible"><</a></li>' + list + '<li><a href="#page-p" class="invisible">></a></li>');
			});
			$$('#slide').setStyle('height' , arrSize[0]);
			var duration = 1000,
				links = $$('ul.tabs li a'),
				tab = new Carousel.Extra({
					container: 'slide',
					scroll: 1,
					circular: false,
					current: 0,
					previous: links.shift(),
					next: links.pop(),
					 mode: 'horizontal',
					onChange: function (index) {
						links.each(function (el, off) {
							el[off == index ? 'addClass' : 'removeClass']('active')
						})
					},
					fx: {
						duration: duration
					}
				});
			links.each(function (el, index) {
				el.addEvent('click', function (e) {
					e.stop();
					tab.move(index);
					$$('#slide').set('tween' , {duration:500});
					
					if(arrSize[index].toInt() > 1000) {
						arrSize[index] = 1000;
					}
					$$('#slide').tween('height' , arrSize[index] ) ;
				})
			});
		}

		$$('#slide div').each(function(el , index){
			//get height of each element
			var startElementHeight = el.getStyle('height').toInt();
                        var myHandler = 1000;
			
			if ( startElementHeight > myHandler) {
				el.setStyle('height', myHandler);//if element gets too big, set height to 1000px´
				el.setStyle('top' , '0px');
				
                                var allowScroll = true;
				//arrows for scrolling 
				var arrowDown = new Array();
				arrowDown[index] = new Element('p' , {'class':'arrowDown', 'styles':{'height':'34px' , 'width':'34px' , 'cursor':'pointer' , 'z-index':'1' , 'position':'absolute', 'top':'738px' , 'left':'482px' , 'background-image':'url(fileadmin/templates/derpunkt.de-2009-demo/img/slide-arrow-down.png)'}}).inject(el , 'top');
				var arrowUp = new Array();
				arrowUp[index] = new Element('p' , {'class':'arrowUp', 'styles':{'height':'34px' , 'width':'34px' , 'cursor':'pointer' , 'visibility':'hidden' , 'z-index':'1' , 'position':'absolute', 'top':'204px' , 'left':'482px' , 'background-image':'url(fileadmin/templates/derpunkt.de-2009-demo/img/slide-arrow-up.png)'}}).inject(arrowDown[index] , 'after');
				
                                var tabsScroll = new Fx.Scroll(document.body , {wheelStops:false});
                                
                                var down = function(){
                                    if(allowScroll == true) {
                                        allowScroll = false;
                                        curElTop = el.getStyle('top').toInt();
                                        if(!curElTop){curElTop = 0};
                                        
                                        el.tween('top', curElTop-myHandler);
                                        
                                        curArrowPosition = arrowDown[index].getStyle('top').toInt();
                                        arrowDown[index].tween('top' , curArrowPosition+myHandler);
                                        
                                        curArrowPosition = arrowUp[index].getStyle('top').toInt();
                                        arrowUp[index].tween('top' , curArrowPosition+myHandler);
                                        
                                        if(curElTop <= 0){
                                            arrowUp[index].setStyle('visibility' , 'visible');
                                        }
                                        if(curElTop < (2*myHandler)-startElementHeight){
                                            arrowDown[index].setStyle('visibility' , 'hidden');
                                            
                                            heightCorrection = true;
                                        }
                                    }
                                }
                                var up = function(){
                                    
                                    if(allowScroll == true){
                                        allowScroll = false;
                                        curElTop = el.getStyle('top').toInt();
                                        
                                        if(!curElTop){curElTop = 0;}
                                        
                                        el.tween('top', curElTop+myHandler);
                                        
                                        var curArrowPosition = arrowDown[index].getStyle('top').toInt();
                                        arrowDown[index].tween('top' , curArrowPosition-myHandler);
                                        
                                        curArrowPosition = arrowUp[index].getStyle('top').toInt();
                                        arrowUp[index].tween('top' , curArrowPosition-myHandler);
                                        
                                        if(curElTop == -myHandler){
                                                arrowUp[index].setStyle('visibility' , 'hidden');
                                        }
                                        if(curElTop >= -startElementHeight){
                                                arrowDown[index].setStyle('visibility' , 'visible');
                                        }
                                        if(curElTop < (2*myHandler)-startElementHeight){
                                                $('slide').tween('height' , myHandler);
                                        }
                                    }
                                }
                                
				$$(el , arrowUp[index] , arrowDown[index]).set('tween' , {duration:1500 , onComplete:function(){
                                    if(allowScroll == false){
                                        allowScroll = true;
                                    }
                                    
                                    if(heightCorrection == true){
                                        heightCorrection = false; //so this condition is true only one time
                                        
                                        var bodyHeight = document.body.getScrollSize().y;
                                        var windowHeight = window.getSize().y;
                                        $('slide').tween('height' , startElementHeight+curElTop-myHandler-10);
                                        tabsScroll.start(0 , bodyHeight-windowHeight-(myHandler-(startElementHeight+curElTop-myHandler))-60 );
                                        
                                    }
                                }})
				
				var reset = $$('ul.tabs li a');
				reset.addEvent('click' , function(){
					el.setStyle('top' , 0);
					arrowDown[index].setStyles({'top':'738px' , 'visibility':'visible'});
					arrowUp[index].setStyles({'top':'204px' , 'visibility':'hidden'});
				});
				
				//scroll down
				scrollDown = arrowDown[index].addEvent('click' , down);
				
				//scroll up
				scrollUp = arrowUp[index].addEvent('click' , up );
			} else {
				el.setStyle('top' , 0);
			}
		});
	})
