var tx_ohspecial_pi1 = {};

// Teaser: Teasing elements of a defined source
tx_ohspecial_pi1.Teaser = Class.create({
	// constant:
	duration: 1,

	// dynamic (set by plugin):
	slider: null,
	container: null,
	movement: {},
	delay: 1000,
	direction: 'rightleft',
	ident: '',
	pointer: 0,
	element: {},
	imagesLength: 0,
	currentImage: null,

	useTimeoutInterval: false,

	/**
	 * Initializes a new instance (called automatically like a constructor)
	 */
	initialize: function(options) {
		this.delay = options.delay*1000;
		this.direction = options.direction;
		this.ident = options.ident;
		this.element = options.element;
		this.imagesLength = this.element.images.length;

		var container = $(this.ident+'-image');
		var dimensions = container.getDimensions();
		this.evaluateDirection(dimensions);

		container.setStyle({
			width: dimensions.width+'px',
			height: dimensions.height+'px',
			overflow: 'hidden',
			position: 'relative'
		});
		this.slider = container.down('div.slider').setStyle({
			left: -this.movement.offset.left+'px',
			top: -this.movement.offset.top+'px',
			width: dimensions.width*this.movement.factor.width+'px',
			height: dimensions.height*this.movement.factor.height+'px',
			position: 'relative'
		});
		this.container = container.down('div.slider');
		this.container.down('a', 0).addClassName('current');

		// However, window.setTimeout produces errors in events and bindings on Firefox 2. Thus, we simulate the behaviour:
		if (Prototype.Browser.Gecko) {
			this.useTimeoutInterval = true;
		}

		setTimeout(this.initializeAnimation.bind(this), 10);
	},

	initializeAnimation: function() {
		// Insert the follow-up image:
		this.insertNextImage();
		// Adjust positioning of the first image (make it absolute):
		this.container.down('a.current').setStyle(this.movement.stylesFirst);

		if (this.useTimeoutInterval) {
			window.setTimeout(this.update.bind(this), this.delay);
		} else {
			window.setInterval(this.update.bind(this), this.delay);
		}
	},

	evaluateDirection: function(dimensions) {
		this.movement = {
			width: 0, height: 0,
			offset: { left: 0, top: 0 },
			factor: { width: 1, height: 1 },
			insertion: 'bottom',
			imagesOrder: [0, 1],
			stylesNext: {},
			stylesFirst: {}
		};

		switch(this.direction) {
			case 'topdown':
				this.movement.height = dimensions.height;
				this.movement.offset.top = dimensions.height;
				this.movement.factor.height = 2;
				this.movement.insertion = 'top';
				this.movement.imagesOrder = [1, 0];
				this.movement.stylesNext = { top: 0 };
				this.movement.stylesFirst = { top: this.movement.height+'px' };
				break;
			case 'bottomup':
				this.movement.height = -dimensions.height;
				this.movement.factor.height = 2;
				this.movement.stylesNext = { top: -this.movement.height+'px' };
				this.movement.stylesFirst = { top: 0 };
				break;
			case 'leftright':
				this.movement.width = dimensions.width;
				this.movement.offset.left = dimensions.width;
				this.movement.factor.width = 2;
				this.movement.insertion = 'top';
				this.movement.imagesOrder = [1, 0];
				this.movement.stylesNext = { left: 0 };
				this.movement.stylesFirst = { left: this.movement.width+'px' };
				break;
			default:
			case 'rightleft':
				this.movement.width = -dimensions.width;
				this.movement.factor.width = 2;
				this.movement.stylesNext = { left: -this.movement.width+'px' };
				this.movement.stylesFirst = { left: 0 };
				break;
		}
		// All animated elements are positioned absolutely to prevent flickering on removing elements from DOM:
		this.movement.stylesNext.position = 'absolute';
		this.movement.stylesFirst.position = 'absolute';
	},

	/**
	 * Updates the pointer and calls the rendering at each iteration
	 */
	update: function() {
		var offset = 0, start = new Date().getUTCMilliseconds();

		if (++this.pointer >= this.imagesLength) {
			this.pointer = 0;
		}
		this.currentImage = this.element.images[this.pointer];
		this.render();

		if (this.useTimeoutInterval) {
			offset = new Date().getUTCMilliseconds() - start;
			window.setTimeout(this.update.bind(this), this.delay - offset);
		}
	},

	insertNextImage: function() {
		var nextPointer = this.pointer+1;
		var insertion, options = {};
		options[this.movement.insertion] = this.element.images[nextPointer < this.imagesLength ? nextPointer : 0];

		this.container.insert(options);
		insertion = Element.select(this.container, 'img');
		insertion = (this.movement.insertion == 'bottom' ? insertion.last() : insertion.first());

		if (this.element.link) {
			// Wrap image with anchor and set styles for absolute positioning:
			insertion
				.wrap('a', { href: this.element.link, className: 'next' })
				.setStyle(this.movement.stylesNext);
		}
	},

	/**
	 * Renders the new content and updates it in DOM
	 */
	render: function() {
		this.updateImageByEffect('image');
	},

	updateImageByEffect: function(field) {
		var currentImage, nextImage, teaser = this;

		currentImage = this.container.down('a.current', 0)
			.addClassName('remove')
			.removeClassName('current');
		nextImage = this.container.down('a.next', 0)
			.addClassName('current')
			.removeClassName('next');

		new Effect.Parallel([
			new Effect.Move(currentImage, { x: this.movement.width, y: this.movement.height, duration: this.duration }),
			new Effect.Move(nextImage, { x: this.movement.width, y: this.movement.height, duration: this.duration })
		], {
			duration: this.duration,
			afterFinish: this.removeCurrentImage.bind(this)
		});
	},

	removeCurrentImage: function() {
		Element.select(this.container, 'a.remove').each(function(element) {
			try {
				if (element.parentNode) {
					element.remove();
				}
			} catch(e) {
				element.hide();
			}
		});

		this.insertNextImage();
	}
});

tx_ohspecial_pi1.WidgetBox = Class.create({
	
	initialize: function(options) {
		this.container = $(options.container);		
		var accordion = new tx_ohspecial_pi1.Accordion(options);
		$(options.container).select('.' + options.classNames.toggle)[0].addClassName(options.classNames.toggleActive);
		$(options.container).select('.' + options.classNames.content)[0].addClassName(options.classNames.contentActive);
	}	
});

// accordion.js v2.0
//
// Copyright (c) 2007 stickmanlabs
// Author: Kevin P Miller | http://www.stickmanlabs.com
//
// Accordion is freely distributable under the terms of an MIT-style license.
//
// I don't care what you think about the file size...
//   Be a pro:
//	    http://www.thinkvitamin.com/features/webapps/serving-javascript-fast
//      http://rakaz.nl/item/make_your_pages_load_faster_by_combining_and_compressing_javascript_and_css_files
//


/*-----------------------------------------------------------------------------------------------*/

if (typeof Effect == 'undefined')
	throw("accordion.js requires including script.aculo.us' effects.js library!");

tx_ohspecial_pi1.Accordion = Class.create({

	//
	//  Setup the Variables
	//
	showAccordion : null,
	currentAccordion : null,
	duration : null,
	effects : [],
	animating : false,
	isInitialised: false,

	//
	//  Initialize the accordions
	//
	initialize: function(options) {
		if (!$(options.container)) {
			throw(options.container+" doesn't exist!");
			return false;
		}
			
		if($(options.container).select('div.force_open').length) {
		
			// show all accordions	
			var accordions = $(options.container).select('div.dropdown_content');
			
			for (var index = 0; index < accordions.length; ++index) {
				$(accordions[index]).setStyle({
				  height: 'auto',
				  display: 'block'
				});
			}
			return false;
		}
		
		this.options = Object.extend({
			resizeSpeed : 8,
			classNames : {
				toggle : 'accordion_toggle',
				toggleActive : 'accordion_toggle_active',
				content : 'accordion_content',
				contentActive : 'accordion_content_active'
			},
			defaultSize : {
				height : null,
				width : null
			},
			direction : 'vertical',
			onEvent : 'click',
			allowFullClose: true
		}, options || {});

		this.duration = ((11-this.options.resizeSpeed)*0.15);

		var accordions = $$('#'+options.container+' .'+this.options.classNames.toggle);
		accordions.each(function(accordion, index) {
			
			// Added to prevent flash
			if(this.options.allowFullClose || index != 0) {
				$(accordion.next(0)).setStyle({
					height: '0px'
				});
			}

			Event.observe(accordion, this.options.onEvent, this.activate.bind(this, accordion), false);
			if (this.options.onEvent == 'click') {
				accordion.onclick = function() {return false;};
			}

			if (this.options.direction == 'horizontal') {
				var options = $H({width: '0px'});
			} else {
				var options = $H({height: '0px'});
			}

			options.display = 'none';
			this.currentAccordion = $(accordion.next(0));
			if(this.options.allowFullClose || index != 0) {
				this.currentAccordion.setStyle(options);
			} else {
				this.showAccordion = this.currentAccordion;
			}
		}.bind(this));
	},

	//
	//  Activate an accordion
	//
	activate : function(accordion) {
		if (this.animating) {
			return false;
		}

		this.effects = [];

		this.currentAccordion = $(accordion.next(0));
		this.currentAccordion.setStyle({
			display: 'block'
		});

		this.currentAccordion.previous(0).addClassName(this.options.classNames.toggleActive);
		this.currentAccordion.addClassName(this.options.classNames.contentActive);

		if (this.options.direction == 'horizontal') {
			this.scaling = $H({
				scaleX: true,
				scaleY: false
			});
		} else {
			this.scaling = $H({
				scaleX: false,
				scaleY: true
			});
		}

		if (this.currentAccordion == this.showAccordion) {
			if(this.options.allowFullClose) {
				this.deactivate();
			}
		} else {
			this._handleAccordion();
		}
		
		// Addon for oh_form:
		// To get the correct form field offset we need a late init
		if(window.tx_ohform && !this.isInitialised) {
			tmpSetting = tx_ohform.settings;
			window.tx_ohform.init(tmpSetting);
			this.isInitialised = true;
		}
		
	},
	//
	// Deactivate an active accordion
	//
	deactivate : function() {
		if (this.animating) {
			return false;
		}		
		var options = $H({
			duration: this.duration,
			scaleContent: false,
			transition: Effect.Transitions.sinoidal,
			queue: {
				position: 'end',
				scope: 'accordionAnimation'
			},
			scaleMode: {
				originalHeight: this.options.defaultSize.height ? this.options.defaultSize.height : this.currentAccordion.scrollHeight,
				originalWidth: this.options.defaultSize.width ? this.options.defaultSize.width : this.currentAccordion.scrollWidth
			},
			beforeStart: function() {
				this.animating = true;
			},			
			afterFinish: function() {
				if(this.showAccordion) {
					this.showAccordion.setStyle({
						height: 'auto',
						display: 'none'
					});
					this.showAccordion.removeClassName(this.options.classNames.contentActive);
				}
				this.showAccordion = null;
				this.animating = false;
			}.bind(this)
		});

		// edited for Prototype 1.6+
		//options.merge(this.scaling);
		options = $H(options).merge(this.scaling).toObject();

		this.showAccordion.previous(0).removeClassName(this.options.classNames.toggleActive);

		new Effect.Scale(this.showAccordion, 0, options);
	},

	//
	// Handle the open/close actions of the accordion
	//
	_handleAccordion : function() {
		var options = $H({
			sync: true,
			scaleFrom: 0,
			scaleContent: false,
			transition: Effect.Transitions.sinoidal,
			scaleMode: {
				originalHeight: this.options.defaultSize.height ? this.options.defaultSize.height : this.currentAccordion.scrollHeight,
				originalWidth: this.options.defaultSize.width ? this.options.defaultSize.width : this.currentAccordion.scrollWidth
			}
		});

		// edited for Prototype 1.6+
		//options.merge(this.scaling);
		options = $H(options).merge(this.scaling).toObject();

		this.effects.push(
			new Effect.Scale(this.currentAccordion, 100, options)
		);

		if (this.showAccordion) {
			this.showAccordion.previous(0).removeClassName(this.options.classNames.toggleActive);
			this.showAccordion.removeClassName(this.options.classNames.contentActive);

			options = $H({
				sync: true,
				scaleContent: false,
				transition: Effect.Transitions.sinoidal
			});

			// edited for Prototype 1.6+
			//options.merge(this.scaling);
			options = $H(options).merge(this.scaling).toObject();

			this.effects.push(
				new Effect.Scale(this.showAccordion, 0, options)
			);
		}

		new Effect.Parallel(this.effects, {
			duration: this.duration,
			queue: {
				position: 'end',
				scope: 'accordionAnimation'
			},
			beforeStart: function() {
				this.animating = true;
				if (this.currentAccordion) {
					this.currentAccordion.setStyle({
						height: '0px'
					});
				}
			}.bind(this),
			afterFinish: function() {
				if (this.showAccordion) {
					this.showAccordion.setStyle({
						display: 'none'
					});
				}
				$(this.currentAccordion).setStyle({
					height: 'auto'
				});
				this.showAccordion = this.currentAccordion;
				this.animating = false;
			}.bind(this)
		});
	}
});
