/*
Required Files: 
	prototype.js
	scriptaculous.js?load=effects
*/

var ContentScrollers = {
	init : function() {
	
		var horizontal_content_scrollers = $$('.content_scroller, .content_scroller.horizontal');
		
		horizontal_content_scrollers.each(function(n) {
			new ContentScrollers.HorizontalScroller(n);
		});
		
		var vertical_content_scrollers = $$('.content_scroller.vertical');
		
		vertical_content_scrollers.each(function(n) {
			new ContentScrollers.VerticalScroller(n);	
		});
	}
};

//Scrollers

ContentScrollers.Scroller = Class.create({
	initialize : function(content_scroller) {

		this.content_scroller = content_scroller;

		// set up previous button
		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(); } });
		
		// set up next button
		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.hasItems() ? this.items.childElements().size() : 0;
		this.item_size = this.hasItems() ? this.getItemSize() : 0;
		this.total_size_of_items = this.hasItems() ? this.getTotalSizeOfItems() : 0;
		this.position = this.hasItems() ? this.getPosition() : 0;
		this.transition_duration = this.getTransitionDuration();

		this.updateButtons();
		
		// add content_scroller div with the functionality of this object
		Object.extend(content_scroller, this);
	},
	
	hasItems : function() {
		return this.items !== undefined && this.items !== null && this.items.childElements().size() > 0;
	},
	
	getPosition : function() { return true; },
	setPosition : function(position) { return true; },
	getItemSize : function() { return true; },
	
	getTransitionDuration : function() {
	
		var potential_durations = (/\bduration[0-9]+\b/i).exec(this.content_scroller.className);
		var duration = 400;
		
		if (potential_durations != null) {
			duration = parseInt(potential_durations[0].substr(8), 10);  //8 is the length of the word "duration"
		}
	
		return duration / 1000;
	},
	
	getTotalSizeOfItems : function() {
		if (!this.items) { return 0; }
		
		return this.item_size * this.num_of_items;
	},

	isAtBeginning : function() {
		if (!this.items) { return true; }
		
		return this.position >= 0;		
	},

	isAtEnd : function() {
		if (!this.items) { return true; }
		
		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; }
		
		var new_position = this.position + this.item_size;
				
		new Effect.Move(this.items, {
			x : new_position,
			y : 0,
			mode : 'absolute',
			duration : this.transition_duration,
			beforeStart : function() { this.updateButtons({off : true}); }.bind(this),
			afterFinish : function() { this.setPosition(new_position); this.updateButtons(); }.bind(this)
		});
	},
	
	scrollForward : function() {
		if (this.isAtEnd()) { return; }

		var new_position = this.position - this.item_size;
		
		new Effect.Move(this.items, {
			x : new_position,
			y : 0,
			mode : 'absolute',
			duration : this.transition_duration,
			beforeStart : function() { this.updateButtons({off : true}); }.bind(this),
			afterFinish : function() { this.setPosition(new_position); this.updateButtons(); }.bind(this)
		});
	}
});

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; }
		
		var new_position = this.position + this.item_size;
		
		new Effect.Move(this.items, {
			x : 0,
			y : new_position,
			mode : 'absolute',
			duration : this.transition_duration,
			beforeStart : function() { this.updateButtons({off : true}); }.bind(this),
			afterFinish : function() { this.setPosition(new_position); this.updateButtons(); }.bind(this)
		});
	},
	
	scrollForward : function() {
		if (this.isAtEnd()) { return; }

		var new_position = this.position - this.item_size;
		
		new Effect.Move(this.items, {
			x : 0,
			y : new_position,
			mode : 'absolute',
			duration : this.transition_duration,
			beforeStart : function() { this.updateButtons({off : true}); }.bind(this),
			afterFinish : function() { this.setPosition(new_position); this.updateButtons(); }.bind(this)
		});
	}
});

document.observe("dom:loaded", ContentScrollers.init);
