var slidit = new Class({
	Implements: [Options],
	options: {
		show: {
			duration: 500,
			transition: Fx.Transitions.Sine.easeOut,
			effect_obj: {
			},
			sizeModificator: {
				x: 0,
				y: 0
			}
		},
		hide: {
			duration: 500,
			transition: Fx.Transitions.Sine.easeOut,
			effect_obj: {
			}
		},
		initStatus: 'show',
		initStyles: ''
	},
	isShown: true,
	slideSize: {x: 0, y: 0},
	initHeight: 0,
	initWidth: 0,
	initOpacity: 0,

	initialize: function(click_el, slide_el, options) {
		
		// 'click'-Elements
		if($type(click_el) == 'element') {
			this.click_el = click_el;
		} else {
			this.click_el = $(click_el);
		}
		
		// 'slide'-Elements
		if($type(slide_el) == 'element') {
			this.slide_el = slide_el;
		} else {
			this.slide_el = $(slide_el);
		}
		
		this.setOptions(options);
		
		this.detectSlideSize();
		this.setShowSize();
		
		// initial status hidden
		if(this.options.initStatus == 'hide') {
			this.isShown = false;
			this.initHeight		= this.options.hide.effect_obj.height;
			this.initWidth		= this.options.hide.effect_obj.width;
			this.initOpacity	= this.options.hide.effect_obj.opacity;
		}
		else {
			this.isShown = true;
			this.initHeight		= this.options.show.effect_obj.height;
			this.initWidth		= this.options.show.effect_obj.width;
			this.initOpacity	= this.options.show.effect_obj.opacity;
		}
		
		
		this.createSlideBox();
		this.slideBox.wraps(this.slide_el);
		
		this.removeHidingStylesFromSlide();
		
		this.checkEffectObject();
		
		this.addEvents();
	},
	
	checkEffectObject: function()
	{
		// Show Effect
		var cnt = 0;
		for (var k in this.options.show.effect_obj)
		{
			cnt++;
		}
		
		if(cnt === 0) {
			this.options.show.effect_obj.height		= this.slideSize.y;
			this.options.show.effect_obj.opacity	= 1;
		}
		
		// Hide Effect
		cnt = 0;
		for (var k in this.options.hide.effect_obj)
		{
			cnt++;
		}
		
		if(cnt === 0) {
			this.options.hide.effect_obj.height		= 0;
			this.options.hide.effect_obj.opacity	= 0;
		}
		
		
	},
	
	/**
	 * creates outer div
	 */
	createSlideBox: function()
	{
		if(this.initHeight === false) {
			this.initHeight = 0;
		}
		if(this.initWidth === false) {
			this.initWidth = 0;
		}
		this.slideBox = new Element('div', {
			'class': 'sliditBox',
			style: this.options.initStyles,
			styles: {
				height: this.initHeight,
				width: this.initWidth,
				opacity: this.initOpacity,
				overflow: 'hidden'
			}
		});
	},
	
	/**
	 * detects slide size
	 */
	detectSlideSize: function()
	{
		var is_hidden = false;
		
		// display if hidden, but make it invisible
		if(this.slide_el.getStyle('display') == 'none') {
			this.slide_el.setStyle('position', 'absolute');
			this.slide_el.setStyle('visibility', 'hidden');
			this.slide_el.setStyle('display', 'block');
			is_hidden = true;
		}
		
		this.slideSize = this.slide_el.getScrollSize();
		this.slideSize.x = this.slideSize.x.toInt() + this.slide_el.getStyle('border-left').toInt() + this.slide_el.getStyle('border-right').toInt();
		this.slideSize.y = this.slideSize.y.toInt() + this.slide_el.getStyle('border-top').toInt() + this.slide_el.getStyle('border-bottom').toInt();
		this.slideSize.x = this.slideSize.x.toInt() + this.slide_el.getStyle('margin-left').toInt() + this.slide_el.getStyle('margin-right').toInt();
		this.slideSize.y = this.slideSize.y.toInt() + this.slide_el.getStyle('margin-top').toInt() + this.slide_el.getStyle('margin-bottom').toInt();
		
		// if it was displayed, hide it again
		if(is_hidden) {
			this.slide_el.setStyle('display', 'none');
			this.slide_el.setStyle('visibility', 'visible');
			this.slide_el.setStyle('position', 'static');
		}
		
		if(this.options.show.sizeModificator.x > 0) {
			this.slideSize.x = this.slideSize.x + this.options.show.sizeModificator.x;
		}
		if(this.options.show.sizeModificator.y > 0) {
			this.slideSize.y = this.slideSize.y + this.options.show.sizeModificator.y;
		}
	},
	
	/**
	 * sets show size to slide size if wished (options.show.effect_obj.width/height = true)
	 */
	setShowSize: function()
	{
		if(this.options.show.effect_obj.width === true) {
			this.options.show.effect_obj.width = this.slideSize.x;
		}
		if(this.options.show.effect_obj.height === true) {
			this.options.show.effect_obj.height = this.slideSize.y;
		}
	},
	
	/**
	 * adds click-Event to click_el
	 */
	addEvents: function()
	{
		this.click_el.addEvent('click', function(e) {
			e.stop();
			this.toggle();
		}.bind(this));
	},
	
	/**
	 * toggles slide
	 */
	toggle: function()
	{
		// slide out
		if(this.isShown) {
			var duration	= this.options.hide.duration;
			var transition	= this.options.hide.transition;
			var effect_obj	= this.options.hide.effect_obj;
			this.isShown = false;
		}
		// slide in
		else {
			var duration	= this.options.show.duration;
			var transition	= this.options.show.transition;
			var effect_obj	= this.options.show.effect_obj;
			this.isShown = true;
		}

		var effect = new Fx.Morph(this.slideBox, {
			duration: duration,
			transition: transition
		});
		
		effect.start(effect_obj);
	},
	
	/**
	 * removes any styles from slide, that hides it
	 */
	removeHidingStylesFromSlide: function()
	{
		if(this.slide_el.getStyle('display') == 'none') {
			this.slide_el.setStyle('display', 'block');
		}
		
		if(this.slide_el.getStyle('visibility') == 'hidden') {
			this.slide_el.setStyle('visibility', 'visible');
		}

		if(this.slide_el.getStyle('height').toInt() == 0) {
			this.slide_el.setStyle('height', this.options.show.effect_obj.height);
		}
		
		if(this.slide_el.getStyle('width').toInt() == 0) {
			this.slide_el.setStyle('width', this.options.show.effect_obj.width);
		}
		
		if(this.slide_el.getStyle('opacity') == 0) {
			this.slide_el.setStyle('opacity', 1);
		}
	}
});
