var horizontal_scroller = new Class({
    Implements: [Options, Events],
    options: {
        slide_holder: '',		// Holder element which holds the content to slide
        slide_holder_parent: '',// parent element holding the slider (to inject controls into)
        content_elements: [],	// Content elements to slide
        slider_w: 0,			// Holder element width
        slider_h: 0,			// Holder element height
        total_content_h: 0,		// Total width of the content in the holder
        content_elements_h: 0,	// width of a content element
        content_elements_w: 0,	// width of a content element
        wrap_div: '',			// Div wrapped around the holder content
        holder_is_wrapper: false, // wrapper around elements, or wrapper is set (<ul>) so needs wrapper around that.
        autoplay: false,		// SLIDE CONTENT AUTOMATICALLY?
        controls: false,		// PREV EN NEXT BUTTONS ?
        next_but: '',			// Slide to left button
        prev_but: '',			// Slide to right button
        slide_per_item: true,	// slide per item, or slide per viewport width
        slidespeed: 500,		// Animation speed,
        scroll_next_speed: 2000,	// Show next items speed,
        active_class: 'active',	// class of the content item which is active i.e. should be visible in the holder viewport
        insert_wrap_before: ''
    },
    initialize: function(options){
        this.setOptions(options);
        this.get_holder_dims(this.options.slide_holder);
        this.sliding_content = false;
    },
	// Get the width of the Holder element
	get_holder_dims: function(content_holder) {
		this.options.slider_w =  content_holder.getStyle('width').toInt();
		this.options.slider_h =  content_holder.getStyle('height').toInt();
		this.options.slide_holder_parent = this.options.slide_holder.getParent();
        this.get_content_slides(this.options.slide_holder, this.options.content_elements);
	},
	// Get the Holder element's children i.e. the content_elements
	// Calculate total height of his content
	get_content_slides: function(content_holder, content_elements) {
		if(content_elements.length==0) {
			this.options.content_elements = content_holder.getChildren();
		}
		var total_content_w = 0;
		var content_slider = this;
		var slider_options = this.options;
		//var elements_by_position = [];
		var element_width, element_height;
		// LOOP THROUGH ELEMENTS, GET WIDTH & HEIGHT, SET IN CORRECT POSITION
		this.options.content_elements.each(function(content_element, index) {
			var element_dims = content_element.getSize();
			var element_margin_left = content_element.getStyle('margin-left').toInt();
			var element_margin_right = content_element.getStyle('margin-right').toInt();
			var element_margin_top = content_element.getStyle('margin-top').toInt();
			var element_margin_bottom = content_element.getStyle('margin-bottom').toInt();
			element_width = element_dims.x.toInt() + element_margin_left +element_margin_right;
			element_height = element_dims.y.toInt() + element_margin_top +element_margin_bottom;

			// Store the left position of each element, in case it needs to be wrapped
			content_element.store('left_position', total_content_w);
			// Add to array of elements by position (for preloading)
			//elements_by_position[total_content_w] = content_element;
			// Add to total content width
			total_content_w = total_content_w + element_width;
			// active element ?
			if(content_element.hasClass(slider_options.active_class)) {
				content_slider.active_element = content_element;
			}
		});
		this.options.content_elements_h = element_height;
		this.options.content_elements_w = element_width;
		//this.elements_by_position = elements_by_position;
		
		if(this.options.slide_per_item==false) {
			this.slide_increment = this.options.slider_w;
			this.elements_in_view = this.options.slider_w / this.options.content_elements_w;
		} else {
			this.slide_increment = this.options.content_elements_w;
			this.elements_in_view = 1;
		}
		this.element_in_view_index = 0;
		this.options.total_content_w = total_content_w;
		// output(this.options.total_content_w+' - '+this.options.slider_w+' this.elements_in_view: '+this.elements_in_view);
		if(this.options.total_content_w>this.options.slider_w) {
			this.wrap_slide_content();
		}
		// this.set_slider_height(element_heights);
	},
	wrap_slide_content: function () {
		this.slider_position = this.options.slide_holder.getCoordinates(this.options.slide_holder_parent); 

		var wrapper_height = this.options.slider_h;
		var wrapper_div;
		if(this.options.holder_is_wrapper==false) {
			wrapper_div = new Element('div', {
			    'class': 'slide_content_wrapper',
			    styles: {
			        position: 'absolute',
			        top: 0, //this.slider_position.top,
			        left: this.slider_position.left,
			        width: this.options.total_content_w
			    }
			});
			this.options.slide_holder.setStyles({
				overflow: 'hidden',
				position: 'relative'
			});
			this.options.wrap_div = wrapper_div;
			if(this.options.insert_wrap_before=='') {
				wrapper_div.inject(this.options.slide_holder);
			} else {
				wrapper_div.inject(this.options.insert_wrap_before, 'after');
			}
			this.options.content_elements.inject(wrapper_div);
		} else {
			wrapper_div = new Element('div', {
			    'class': 'slide_content_wrapper',
			    styles: {
			        position: 'relative',
			        overflow: 'hidden',
			        width: this.options.slider_w,
			        height: this.options.slider_h
			    }
			});
			this.options.slide_holder.setStyles({
				width: this.options.total_content_w,
		        position: 'absolute',
				top: 0,
				left: 0
			}); 
		
			if(this.options.insert_wrap_before=='') {
				wrapper_div.inject(this.options.slide_holder_parent);
			} else {
				wrapper_div.inject(this.options.insert_wrap_before, 'after');
			}
			this.options.slide_holder.inject(wrapper_div);
			
		}
		// output('this.options.wrap_div = '+this.options.wrap_div);
		// MAKE PARENT DIV RELATIVE
		if(this.options.slide_holder_parent.getStyle('position')=='static') {
			this.options.slide_holder_parent.setStyle('position', 'relative');
		}
		this.position_slides();

		if(this.options.controls==true) {
			this.set_prev_next_buttons();
		} 
		if(this.options.autoplay==true) {
			this.set_scroll_timer();
		}
	},
	// Take all content elements and position them absolute, with the right left value, stored earlier
	position_slides: function() {
		this.options.content_elements.each(function(content_element) {
			content_element.setStyles({
				position: 'absolute',
				left: content_element.retrieve('left_position'),
				top: 0
			});
		});
	},
	// Insert previous and next slide buttons
	set_prev_next_buttons: function() {
		// These buttons need to be outside the holder div, since it's overflow is hidden
		// Get the position of the holder div, to position the buttons relative to the holder
		var slider_position = this.slider_position; 
		if(this.options.next_but=='') {
			// Create the next button, this will be visible 
			var next_button = new Element('a', {
			    href: '#slide_right',
			    'class': 'item_slider_control next',
			    html: '&gt;',
			    styles: {
			        display: 'block',
			        top: this.slider_position.top + 10,
			        left: this.slider_position.left + this.options.slider_h + 0
			    },
			    events: {
			        click: function(){
			            return false;
			        }
			    }
			});
			next_button.inject(this.options.slide_holder_parent);
			this.options.next_but = next_button;
		}
        this.options.next_but.addEvent('click', this.slide_content.bind(this));
		if(this.options.prev_but=='') {
			// Create the prev button, this will be invisible, because the slider starts at 0
			var prev_button = new Element('a', {
			    href: '#slide_left',
			    'class': 'item_slider_control prev',
			    html: '&lt;',
			    styles: {
			        display: 'none',
			        top: this.slider_position.top + 10,
			        left: this.slider_position.left - 50
			    },
			    events: {
			        click: function(){
			            return false;
			        }
			    }
			});
			prev_button.inject(this.options.slide_holder_parent);
			this.options.prev_but = prev_button;
		// ALS ER AL IS, ZET OP ONZICHTBAAR
		} else {
			this.options.prev_but.setStyle('display', 'none');
		}
        this.options.prev_but.addEvent('click', this.slide_content.bind(this));
		// INJECT the prev/next buttons to the holder's parent element
		if(typeof this.active_element!='undefined') {
			this.set_active_position();
		}
		// PRELOAD NEXT VISIBLE IMAGES
		this.preload_content_images();
	},
	// Slide the content inside the holder, get the direction by the class of the button
	slide_content: function(event) {
		// Slide only when it's not currently sliding (to prevent messed up positions)
		if(this.sliding_content==false) {
			var cur_content_pos = this.options.wrap_div.getStyle('left').toInt();
			var next_pos = cur_content_pos - this.slide_increment;
			// ALS ER GEKLIKT IS, STOPPEN MET AUTOMATISCH SLIDEN
			if(typeof event!='undefined') {
				this.options.autoplay = false;
				if(typeof this.scroll_delay!='undefined') {
					clearTimeout(this.scroll_delay);
				}
			}
			if((typeof event!='undefined') && (event.target.hasClass('prev'))) {
				next_pos = cur_content_pos + this.slide_increment;
				this.element_in_view_index = this.element_in_view_index - this.elements_in_view;
			} else {
				this.element_in_view_index = this.element_in_view_index + this.elements_in_view;
			}
			// output('this.element_in_view_index = '+this.element_in_view_index);
			// output('this.slide_increment = '+this.slide_increment);
			// output('cur_content_pos = '+cur_content_pos+' | next_pos = '+Math.abs(next_pos)+' en total_w = '+this.options.total_content_w);
			if(Math.abs(next_pos) >= this.options.total_content_w) { next_pos = 0; } 
			// PRELOAD NEXT IMAGES
			this.preload_content_images();
			// SLIDER TWEEN
			var content_slide_FX = new Fx.Tween(this.options.wrap_div, {property: 'left', duration: this.options.slidespeed});
			// Start the slide animation and update the visibility of the prev/next buttons
			var has_controls = this.options.controls;
			var does_autoplay = this.options.autoplay;
			this.sliding_content = true;
			content_slide_FX.start(cur_content_pos,next_pos).chain(function(){ 
				if(has_controls==true) {
					this.update_controls(next_pos); 
				}
				if(does_autoplay==true) {
					//output('set die timer!');
					this.set_scroll_timer(); 
				}
				this.sliding_content = false;
				}.bind(this)
			);
		}
		return false;
	},
	set_scroll_timer: function() {
		if(typeof this.scroll_delay=='undefined') {
			this.scroll_delay = '';
		} else {
			clearTimeout(this.scroll_delay);
		}
		this.scroll_delay = this.slide_content.delay(this.options.scroll_next_speed, this);
	},
	// Set the visibility of the prev/next buttons
	update_controls: function(cur_content_pos) {
		// SHOW PREV -> is visible when the wrap div position is negative
		if(cur_content_pos<0) {
			this.options.prev_but.setStyle('display', 'block');
		}
		// HIDE PREV -> is invisible when the wrap div position is 0
		if(cur_content_pos==0) {
			this.options.prev_but.setStyle('display', 'none');
		}
		// HIDE NEXT -> is invisible when the last content element is visible in the holder's viewport
		if((-1*(cur_content_pos - this.options.slider_w))>=this.options.total_content_w) {
			this.options.next_but.setStyle('display', 'none');
		}
		// SHOW NEXT -> is visible when the last content element is not visible in the holder's viewport
		if(this.options.total_content_w>(-1*(cur_content_pos - this.options.slider_w))) {
			this.options.next_but.setStyle('display', 'block');
		}
	},
	preload_content_images: function() {
		// PRELOAD NEXT UPCOMING 
		var preload_index = this.element_in_view_index + this.elements_in_view;
		if(preload_index<this.options.content_elements.length) {
			for(var i=0; i<this.elements_in_view;i++) {
				var element_to_preload_index = preload_index + i;
				// output('element_to_preload_index = '+element_to_preload_index);
				var element_to_preload = this.options.content_elements[element_to_preload_index];
				if(element_to_preload.getElement('a.image_link')!=null) {
					var elements_img_to_load  = element_to_preload.getElement('a.image_link').getProperty('rel');
					// output('preloooad'+elements_img_to_load);
					if((elements_img_to_load!='') && (elements_img_to_load!=null)) {
						element_to_preload.getElement('a.image_link img').setProperty('src', elements_img_to_load);
						element_to_preload.getElement('a.image_link').setProperty('rel', '');
					}
				}
			}
		}
	}	
});
