var ContentScrollers = {
	
	init : function() {
	
		var content_scrollers = $$('.content_scroller');
		
		content_scrollers.each(function(n) {
		
			new ContentScrollers.HorizontalScroller(n);
			
		});
	}

};

// Transitions

ContentScrollers.Transition = Class.create({
	initialize : function(content_scroller, params) {
		if(!content_scroller || content_scroller.is_moving) { return; }

		this.do_nothing = false;
		
		this.content_scroller = content_scroller;
		
		this.start = content_scroller.position;
		this.end = params.backward != null && params.backward == true ? this.start + content_scroller.item_size : this.start - content_scroller.item_size;
		this.current = this.start;
		this.interval = null;
		this.duration = params.duration != null && params.duration > 0 ? params.duration : 500;
		this.duration_step = 13;
		this.num_of_steps = this.duration / this.duration_step;
		this.increment = (this.end - this.start) / this.num_of_steps;
		
		this.before = params.before ? params.before.bind(content_scroller) : null;
		this.after = params.after ? params.after.bind(content_scroller) : null;

		this.begin();
	},

	begin : function() {
		if(this.do_nothing) { return; }

		this.content_scroller.is_moving = true;

		if (this.before) { this.before(); }
		
		this.interval = setInterval(function() { this.step(this.current + this.increment); }.bind(this), this.duration_step);
	},
	
	finish : function() {
		if(this.do_nothing) { return; }

		this.content_scroller.is_moving = false;

		clearInterval(this.interval);
		this.interval = null;

		this.content_scroller.setPosition(this.end);

		if (this.after) { this.after(); }
	},

	step : function(next_step) { return true; }
});

ContentScrollers.HorizontalTransition = Class.create(ContentScrollers.Transition, {
	initialize : function($super, content_scroller, params) { $super(content_scroller, params); },

	step : function(next_step) {
		this.current = next_step;
		this.content_scroller.items.setStyle({left: next_step + 'px'});

		if(this.increment < 0) {
			if(next_step <= this.end) {
				this.finish();
			}			
		} else {
			if(next_step >= this.end) {
				this.finish();
			}
		}
	}
});

ContentScrollers.VerticalTransition = Class.create(ContentScrollers.Transition, {
	initialize : function($super, content_scroller, params) { $super(content_scroller, params); },

	step : function(next_step) {
		this.current = next_step;
		this.content_scroller.items.setStyle({top: next_step + 'px'});

		if(this.increment < 0) {
			if(next_step <= this.end) {
				this.finish();
			}			
		} else {
			if(next_step >= this.end) {
				this.finish();
			}
		}
	}
});


//Scrollers

ContentScrollers.Scroller = Class.create({
	initialize : function(content_scroller) {

		this.content_scroller = content_scroller;

		this.prev_button = content_scroller.select(".prev_button")[0];
		this.prev_button.is_clickable = true;
		this.prev_button.observe("click", function() { if(this.is_clickable) { content_scroller.scrollBackward(); } });
		
		this.next_button = content_scroller.select(".next_button")[0];
		this.next_button.is_clickable = true;
		this.next_button.observe("click", function() { if(this.is_clickable) { content_scroller.scrollForward(); } });
		
		this.items = content_scroller.select(".content_scroller_items")[0];
		this.num_of_items = this.items.childElements().size();
		this.item_size = this.getItemSize();
		this.total_size_of_items = this.getTotalSizeOfItems();
		this.position = this.getPosition();
		this.transition_duration = 400;

		this.updateButtons();
			
		Object.extend(content_scroller, this);
	},
	
	getPosition : function() { return true; },
	setPosition : function(position) { return true; },
	getItemSize : function() { return true; },
	
	getTotalSizeOfItems : function() {
		if (!this.items) { return 0; }
		
		return this.item_size * this.num_of_items;
	},

	isAtBeginning : function() {
		if (!this.items) { return false; }
		
		return this.position >= 0;		
	},

	isAtEnd : function() {
		if (!this.items) { return false; }
		
		return this.position <= -(this.total_size_of_items - this.window_size);	
	},
	
	scrollBackward : function() { return true; },
	scrollForward : function() { return true; },
	
	updateButtons : function(params) {
		
		var off = params && params.off ? params.off : false;
		var prev_off = params && params.prev_off ? params.prev_off : false;
		var next_off = params && params.next_off ? params.next_off : false;

		this.prev_button.is_clickable = !off & !prev_off & !this.isAtBeginning();
		this.next_button.is_clickable = !off & !next_off & !this.isAtEnd();
		
		prev_button_bg = this.prev_button.getStyle("background-image");
		if (this.prev_button.is_clickable) {
			this.prev_button.setStyle({"backgroundImage" : prev_button_bg.replace(/_off\./gi, '_on.')});
		} else {
			this.prev_button.setStyle({"backgroundImage" : prev_button_bg.replace(/_on\./gi, '_off.')});
		}
		
		next_button_bg = this.next_button.getStyle("background-image");
		if (this.next_button.is_clickable) {
			this.next_button.setStyle({"backgroundImage" : next_button_bg.replace(/_off\./gi, '_on.')});
		} else {
			this.next_button.setStyle({"backgroundImage" : next_button_bg.replace(/_on\./gi, '_off.')});
		}		
	}
});

ContentScrollers.HorizontalScroller = Class.create(ContentScrollers.Scroller, {

	initialize : function($super, content_scroller) { 
	
		this.window = content_scroller.select(".content")[0];
		if (this.window) { this.window_size = this.window.offsetWidth; }
	
		$super(content_scroller);
	},

	getPosition : function() {
		if (!this.items) { return 0; }

		var position = parseInt(this.items.getStyle('left'), 10);
		return isNaN(position) ? 0 : position;
	},
	
	setPosition : function(position) {
		this.items.setStyle({left: position + 'px'});
		this.position = position;		
	},
	
	getItemSize : function() {
		if (!this.items) { return 0; }
		
		var first_item = this.items.firstDescendant();
		var margin_left = parseInt(first_item.getStyle("margin-left"), 10);
		margin_left = isNaN(margin_left) ? 0 : margin_left;
		var margin_right = parseInt(first_item.getStyle("margin-right"), 10);
		margin_right = isNaN(margin_right) ? 0 : margin_right;

		return first_item.offsetWidth + margin_left + margin_right;
	},
	
	scrollBackward : function() {
		if (this.isAtBeginning()) { return; }
		
		new ContentScrollers.HorizontalTransition(this, {
			duration : this.transition_duration,
			backward : true,
			before : function() { this.updateButtons({off : true}); },
			after : function() { this.updateButtons(); }
		});
	},
	
	scrollForward : function() {
		if (this.isAtEnd()) { return; }

		new ContentScrollers.HorizontalTransition(this, {
			duration : this.transition_duration,
			backward : false,
			before : function() { this.updateButtons({off : true}); },
			after : function() { this.updateButtons(); }
		});
	}
});

ContentScrollers.VerticalScroller = Class.create(ContentScrollers.Scroller, {

	initialize : function($super, content_scroller) {
		
		this.window = content_scroller.select(".content")[0];
		if (this.window) { this.window_size = this.window.offsetHeight; }
	
		$super(content_scroller);
	},

	getPosition : function() {
		if (!this.items) { return 0; }
	
		var position = parseInt(this.items.getStyle('top'), 10);
		return isNaN(position) ? 0 : position;
	},
	
	setPosition : function(position) {
		this.items.setStyle({top: position + 'px'});
		this.position = position;
	},
	
	getItemSize : function() {
		if (!this.items) { return 0; }
		
		var first_item = this.items.firstDescendant();
		var margin_top = parseInt(first_item.getStyle("margin-top"), 10);
		margin_top = isNaN(margin_top) ? 0 : margin_top;
		var margin_bottom = parseInt(first_item.getStyle("margin-bottom"), 10);
		margin_bottom = isNaN(margin_bottom) ? 0 : margin_bottom;

		return first_item.offsetHeight + margin_top + margin_bottom;
	},

	scrollBackward : function() {
		if (this.isAtBeginning()) { return; }
		
		new ContentScrollers.VerticalTransition(this, {
			duration : this.transition_duration,
			backward : true,
			before : function() { this.updateButtons({off : true}); },
			after : function() { this.updateButtons(); }
		});
	},
	
	scrollForward : function() {
		if (this.isAtEnd()) { return; }

		new ContentScrollers.VerticalTransition(this, {
			duration : this.transition_duration,
			backward : false,
			before : function() { this.updateButtons({off : true}); },
			after : function() { this.updateButtons(); }
		});
	}
});

document.observe("dom:loaded", ContentScrollers.init);
