Fx.ExtendedSlide = Fx.Base.extend({

	options: {
		mode: 'vertical',
		direction: 'normal'
	},

	initialize: function(element, options){
		this.parent($(element), options);
		this.options.mode = options.mode;
		this.options.direction = options.direction;
		this.element = $(element);
		
		
		this.wrapper = new Element('div', {'styles': {'margin':  this.element.getStyle('margin'),
													  'position': this.element.getStyle('position'),
													  'overflow': 'hidden',
													  'padding': 0,
													  'visibility': 'hidden',
													  'left': this.element.getStyle('left'),
													  'top': this.element.getStyle('top')}}).injectAfter(this.element).adopt(this.element);
		this.element.setStyle('margin', 0);
		this.element.setStyle('position', 'static');
		this.element.setStyle('left', 'auto');
		this.element.setStyle('top', 'auto');
		
		this.now = [];
		this.open = true;
		this.addEvent('onComplete', function(){
			this.open = (this.now[0] === 0);
		}, true);
		if (window.webkit419) this.addEvent('onComplete', function(){
			if (this.open) this.element.remove().inject(this.wrapper);
		}, true);
	},

	setNow: function(){
		for (var i = 0; i < 2; i++) this.now[i] = this.compute(this.from[i], this.to[i]);
	},

	vertical: function(){
		this.margin = 'margin-top';
		this.layout = 'height';
		this.offset = this.element.offsetHeight;
	},

	horizontal: function(){
		this.margin = 'margin-left';
		this.layout = 'width';
		this.offset = this.element.offsetWidth;
	},

	normal: function(){
		this.offset_margin = -this.offset;
		this.offset_layout = 0;
	},

	reverse: function(){
		this.offset_margin = this.offset;
		this.offset_layout = this.offset;
	},

	/*
	Property: slideIn
		Slides the elements in view horizontally or vertically.

	Arguments:
		mode - (optional, string) 'horizontal' or 'vertical'; defaults to options.mode.
	*/

	slideIn: function(mode){
		this[mode || this.options.mode]();
		this.open = true;
		return this.start([this.element.getStyle(this.margin).toInt(), this.wrapper.getStyle(this.layout).toInt()], [0, this.offset]);
	},

	/*
	Property: slideOut
		Sides the elements out of view horizontally or vertically.

	Arguments:
		mode - (optional, string) 'horizontal' or 'vertical'; defaults to options.mode.
	*/

	slideOut: function(mode,dir){
		this[mode || this.options.mode]();
		this[dir || this.options.direction]();
		this.open = false;
		return this.start([this.element.getStyle(this.margin).toInt(), this.wrapper.getStyle(this.layout).toInt()], [this.offset_margin, this.offset_layout]);
		//return this.start('margin': [0, this.element.getStyle(this.margin).toInt()], 'height': [this.wrapper.getStyle(this.layout).toInt() ,0]);
	},

	/*
	Property: hide
		Hides the element without a transition.

	Arguments:
		mode - (optional, string) 'horizontal' or 'vertical'; defaults to options.mode.
	*/

	hide: function(mode,dir){
		this[mode || this.options.mode]();
		//this[dir || this.options.direction]();
		this.open = false;
		
		if(this.options.direction == 'reverse')
			return this.set([this.offset, this.offset]);
		
		return this.set([-this.offset, 0]);
	},

	/*
	Property: show
		Shows the element without a transition.

	Arguments:
		mode - (optional, string) 'horizontal' or 'vertical'; defaults to options.mode.
	*/

	show: function(mode){
		this[mode || this.options.mode]();
		this.open = true;
		
		return this.set([0, this.offset]);
	},

	/*
	Property: toggle
		Slides in or Out the element, depending on its state

	Arguments:
		mode - (optional, string) 'horizontal' or 'vertical'; defaults to options.mode.

	*/

	toggle: function(mode){	
		if (this.open)
			return this.slideOut(mode);
		
		return this.slideIn(mode);
	},

	increase: function(){
		this.element.setStyle(this.margin, this.now[0] + this.options.unit);
		this.wrapper.setStyle(this.layout, this.now[1] + this.options.unit);
	}

});
