var slidesign = new Class({
	initialize: function(options){
		this.options= $extend(
			{
				baseID:	"slidesign",
				fxduration:	1000,	// number of milliseconds for transition
				numSlides: 5,	// number of slide in view port (special first counts)
				showArrows: true,
				showArrowsIn: 0.55,
				showArrowsOut: 0.0,
				slideHeight: 300,
				slideshowDelay: 4000, // how long to pause on slide. MUST BE LONGER THAN fxduration
				slideWidth: 200,
				specialFirst: false,
				stickFirst:	false,
				transition:	Fx.Transitions.Sine.easeOut
			}, options || {}
		);
		
		this.moving = false;
		this.running = false;
		this.finishing = false;
		this.left = 0;
		
		this.base = $(this.options.baseID);
		this.base.setStyles({'width':this.options.slideWidth*this.options.numSlides,'height':this.options.slideHeight});
		this.divs = this.base.getChildren('div');
		this.clearClass(this.divs,this.options.specialFirst);
		
		this.divs.setStyles({'width':this.options.slideWidth,'height':this.options.slideHeight});
		if(this.options.stickFirst){
			this.specialFirst = this.divs.shift();
			this.left=this.options.slideWidth;
			this.options.numSlides--;
		}
		
		this.outer = new Element('div',{
			'id':'slideSignOuter',
			'styles':{'width':this.options.slideWidth*this.options.numSlides,'height':this.options.slideHeight},
			'events':{
				'mouseleave':function(){this.hideArrows();}.bind(this),
				'mouseenter':function(){this.showArrows();}.bind(this)
			}
		}).inject(this.base);
		this.inner = new Element('div',{'id':'slideSignInner','styles':{'width':this.options.slideWidth*(this.divs.length*3),'height':this.options.slideHeight}}).inject(this.outer);
		
		this.inner.adopt(this.divs);
		this.current = (this.divs.length/2).toInt();
		this.divs.each(function(d,i){
			if(i<this.current){
				var clone = d.clone().inject(this.inner);
			}else{
				var clone = d.clone().inject(this.divs[0],'before');
			}
		},this);
		this.divs = this.inner.getChildren('div');
		this.divs[this.current].addClass(this.options.specialFirst);
		l = 0 - (this.options.slideWidth * this.current);
		this.inner.setStyles({'left':l});
		
		this.createArrows();
		
		this.addEffects();
		
		this.startShow();
		
	},
	
	createArrows: function(){
		if(this.options.showArrows){
			this.rightArrow = new Element('div',{
				'id':'rightArrow',
				'class':'slideArrows',
				'styles':{'right':0,'height':this.options.slideHeight,'opacity':this.options.showArrowsOut},
				'events':{
					'click':function(){this.clickRight();}.bind(this),
					'mouseleave':function(){this.hideArrows();}.bind(this),
					'mouseenter':function(){this.showArrows();}.bind(this)
				}
			}).inject(this.base);
			this.leftArrow = new Element('div',{
				'id':'leftArrow',
				'class':'slideArrows',
				'styles':{'left':this.left,'height':this.options.slideHeight,'opacity':this.options.showArrowsOut},
				'events':{
					'click':function(){this.clickLeft();}.bind(this),
					'mouseleave':function(){this.hideArrows();}.bind(this),
					'mouseenter':function(){this.showArrows();}.bind(this)
				}
			}).inject(this.base);
			
			this.rightArrowEffect = new Fx.Morph(this.rightArrow, {duration: this.options.fxduration, transition: Fx.Transitions.Sine.easeInOut, link: 'chain'});
			this.leftArrowEffect = new Fx.Morph(this.leftArrow, {duration: this.options.fxduration, transition: Fx.Transitions.Sine.easeInOut, link: 'chain'});
		}
	},
	
	addEffects: function(){
		this.divs.each(function(d,i){
			d.setProperty('id','slideNum'+i);
			d.effect = new Fx.Morph(d, {duration: this.options.fxduration, transition: this.options.transition});
		},this);
	},
	
	startShow: function(){
		$clear(this.running);
		this.running = this.moveLeft.periodical(this.options.slideshowDelay,this);
	},
	
	moveLeft: function(){
		this.moving = true;
		$clear(this.cleanup);
		this.divs[0].effect.start({width:0});
		this.clearClass(this.divs,this.options.specialFirst);
		this.finishing = this.moveLeftFinish.delay(this.options.fxduration+20,this);
	},
	
	moveLeftFinish: function(){
		this.inner.grab(this.divs[0]);
		this.cleanupMove(false);
		this.cleanup = this.cleanupMove.periodical(10,this,true);
		this.moving = false;
	},
	
	moveRight: function(){
		this.moving = true;
		$clear(this.cleanup);
		this.divs[this.current-1].addClass(this.options.specialFirst);
		this.divs[0].effect.start({width:this.options.slideWidth*2});
		this.clearClass(this.divs,this.options.specialFirst);
		this.finishing = this.moveRightFinish.delay(this.options.fxduration+20,this);
	},
	
	moveRightFinish: function(){
		this.inner.grab(this.divs.getLast(),'top');
		this.cleanupMove(false);
		this.cleanup = this.cleanupMove.periodical(10,this,true);
		this.moving = false;
	},
	
	clearClass: function(ds,c){
		if(c) ds.removeClass(c);
	},
	
	cleanupMove: function(a){
		this.divs = this.inner.getChildren('div');
		e=0;
		this.divs.each(function(d){
			if(d.getSize().x!=this.options.slideWidth) e++
		},this);
		if(e){
			this.clearClass(this.divs,this.options.specialFirst);
			this.divs.setStyles({'width':this.options.slideWidth});
			this.divs[this.current].addClass(this.options.specialFirst);
		}
	},
	
	showArrows: function(){
		if(this.options.showArrows){
			$clear(this.running);
			this.rightArrowEffect.cancel();
			this.leftArrowEffect.cancel();
			this.rightArrowEffect.start({'opacity': this.options.showArrowsIn});
			this.leftArrowEffect.start({'opacity': this.options.showArrowsIn});
		}
	},
	
	hideArrows: function(){
		if(this.options.showArrows){
			this.rightArrowEffect.start({'opacity': this.options.showArrowsOut});
			this.leftArrowEffect.start({'opacity': this.options.showArrowsOut});
			this.startShow();
		}
	},
	
	clickRight: function(){
		if(!this.moving){
			this.moveLeft();
		}
		return false;
	},
	
	clickLeft: function(){
		if(!this.moving){
			this.moveRight();
		}
		return false;
	},
	
	scrollSizeWithMargins: function(e){
		d = e.getScrollSize();
		m = e.getStyles('marginTop','marginRight','marginBottom','marginLeft');
		x = d.x.toInt();
		y = d.y.toInt();
		t = m.marginTop.toInt();
		r = m.marginRight.toInt();
		b = m.marginBottom.toInt();
		l = m.marginLeft.toInt();
		return {'x':x+r+l,'y':y+t+b};
	}

});
