var Carousel=Class.create();
Carousel.prototype = Object.extend(new Base(), {
	id				:null,
	count			:null,
	num_displayed	:5,
	visible_width 	:525,
	item_width 		:125,
	items_width		:null,
	items_overflow	:null,
	slider			:{},
	knob			:{},
	duration		:0.2,		// change back to 0.75
	left_btn		:null,
	right_btn		:null,
	ct_postfix		:"-ct",
	/* constructor */
	initialize:function(id,sid,nid,spos)
	{
		this.id 			= id;
		this.slider			= $(sid);
		this.knob 			= $(nid);
		// control of back and next arrows
		this.left_btn 		= $(this.id+'-left');
		this.right_btn 		= $(this.id+'-right');
		
		// knob and its properties
		if (this.knob) {
			this.knob.width = this.knob.getWidth();
			this.knob.cssNoValue = this.cssNoValue;
			this.knob.x = function(){
				return this.cssNoValue($(this.id).getStyle('left'));
			}
		}
		
		// how  wide is the visible area
		this.visible_width 	= $(this.id).up().getDimensions().width;
		// setup some reused vars		
		this.set_values();
		if(this.count==0)
			return;
		// slider func
		if (this.knob) {
			new Draggable(this.knob.id,{constraint:'horizontal',bound:"outer",onDrag:this.knob_change.bind(this)});
		}
		if(spos)
			this.slide(-1*(Math.floor(spos/this.num_displayed)));
		
	},
	focus:function(spos)
	{
		var currentx = this.cssNoValue($(this.id).getStyle('left'));
		var width = this.items_width;
		var s_amt=0;
		// scroll button on the right was clicked
		if((currentx+spos*this.item_width)<0)
			s_amt=-1*(currentx+(spos*this.item_width));
		else if(currentx+((spos+1)*this.item_width)>this.visible_width)
			s_amt=this.visible_width-(currentx+((spos+1)*this.item_width));
		else if(s_amt==0)
			return;
		// scroll button on the left was clicked
//		else if(true)
//			s_amt = -1*s_amt;
		// where will the items be next (future x)
		var nextx = currentx+s_amt;
		// have to manage these before moving the items
		this.manage_btns(nextx);
		// move the items
		new Effect.MoveBy($(this.id),0,s_amt,{duration:this.duration});
		// move the knob (must pass the nextx b/c of the tween)
		this.position_knob(nextx);
	},
	set_values:function(npos)
	{
		// how many are there
		this.count 			= $(this.id).immediateDescendants().length;
		// the ajax delete takes time so -1 is passed in 
		if(npos!=undefined) {this.count--;}
		
		// update the count, if one exists
		if($(this.id+this.ct_postfix)) { $(this.id+this.ct_postfix).innerHTML = this.count + " items";}
		
		if(this.count<=0){this.manage_btns(0);return;}		
		// how wide is each item
		this.item_width 	= $(this.id).down().getWidth();
		// calculate how many are displayed
		this.num_displayed 	= this.visible_width/this.item_width;
		
		// the rest of vars require items		
		if(this.count==0){this.manage_btns(0);return}
		// how wide the items are
		this.items_width 	= this.count * this.item_width;
		// how much is not visible
		var overflow 		= (this.count-this.num_displayed)*this.item_width;
		this.ratio=(overflow)/this.visible_width;
		// max amt to be scrolled
		this.items_overflow = this.items_width-this.visible_width;	
		// hide the buttons, if necessary
		this.manage_btns(0);
	},
	remove:function()
	{
		this.set_values(-1);
		this.knob_change([-1*this.item_width,0]);
	},
	// handles the side controls
	slide:function(dir)
	{
		var s_amt = dir*this.visible_width;
		var currentx = this.cssNoValue($(this.id).getStyle('left'));
		var width = this.items_width;
		// scroll button on the right was clicked
		if(dir<0)
		{
			// the right most item never moves further than the right border
			var totoff 		= currentx+width;
			var twoofviz	= 2*this.visible_width;
			if(currentx+s_amt+this.items_width<this.visible_width){
				s_amt = this.visible_width-totoff;
			}
		// scroll button on the left was clicked
		}else{
			// don't have to anything s_amt is already set
			if(currentx<0&&currentx>0-this.visible_width)
				s_amt = 0-currentx;
		}
		// where will the items be next (future x)
		var nextx = currentx+s_amt;
		// have to manage these before moving the items
		this.manage_btns(nextx);
		
		// move the items
		new Effect.MoveBy($(this.id),0,s_amt,{duration:this.duration});
		
		// move the knob (must pass the nextx b/c of the tween)
		this.position_knob(nextx);
	},
	position_knob:function(nextx)
	{		
		if (this.knob) {
			// what will the overflow be
			var future_flow			= (nextx + this.items_width) - this.visible_width;
			// flow ratio 
			var flow_ratio 			= 1 - future_flow / this.items_overflow;
			// total draggable area
			var d_area 				= this.visible_width-this.knob.width;
			// adjust based on the ratio (if moving instantly, set the xpos to this value
			var nextx 				= d_area * flow_ratio;
			// find the diff (tweened version)
			var move_to = nextx-this.knob.x();
			// move knob
			new Effect.MoveBy(this.knob,0,move_to,{duration:this.duration});
		}
	},
	manage_btns:function(nextx)
	{
		var width = nextx+this.items_width;
		// handle the right button
		if(width > this.visible_width)
			this.right_btn.show();
		else
			this.right_btn.hide();
		// handle the left
		if(nextx<0)
			this.left_btn.show();
		else
			this.left_btn.hide();
		// manage the knob
		if (this.knob) {
			if(this.count<=this.num_displayed)
				this.knob.up().hide();
			else
				this.knob.up().show();
		}
	},
	// callback handler for when the knob is moved.
	knob_change:function(what)
	{
		var delta		= what.currentDelta();		
		// find the % the knob has been moved
		var px 			= (delta[0]/(this.visible_width-this.knob.width));
		// moving the items backwards
		var inthehole 	= -1*this.items_overflow*px;
		this.slider.setStyle({left:inthehole+'px'});
		// update the buttons
		this.manage_btns(inthehole);
	}
});