Effect.MoveOffsetLeft = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      x:    0,
      y:    0
    }, arguments[1] || { });
    this.start(options);
  },
  setup: function() {
    this.originalLeft = parseFloat(this.element.getStyle('marginLeft') || '0');
    this.originalTop  = parseFloat(this.element.getStyle('marginTop')  || '0');
  },
  update: function(position) {
	this.element.setStyle({
      marginLeft: (this.options.x  * position + this.originalLeft).round() + 'px',
      marginTop:  (this.options.y  * position + this.originalTop).round()  + 'px'
    });
  }
});
/**
 * @author Bjørge Næss
 * @copyright Bjørge Næss (c) 2008
 *
 */
var TextSlider = Class.create({

	initialize: function(element, options) {

		element = $(element);

		this.options = Object.extend({
			'alignMiddle': false,
			'centerOnClick': false,
			'loop': false
		},options)
		if (element.tagName.toLowerCase() == 'ul') {
			// Then, create the wrapper
			this.element=new Element('div', {'class': 'textslider'})
			// and wrap the ul
			element.wrap(this.element)
			this.ulEl = element;
		}
		else {
			this.element = element
			this.element.addClassName('textslider')
			this.ulEl = this.element.down('ul');
			if (!this.ulEl) return alert('No UL element contained in given element: '+element.id)
		}
		if (this.options.previousButton) {
			this.previousButton = $(this.options.previousButton)
			this.previousButton.observe('click', this.previous.bind(this))
			this.previousButton.addClassName('disabled')
		}
		if (this.options.nextButton) {
			this.nextButton = $(this.options.nextButton)
			this.nextButton.observe('click', this.next.bind(this))
			this.nextButton.addClassName('disabled')
		}
		this.firstElement = this.ulEl.down('li')
		this.lastElement = this.firstElement.siblings().last()

		this.currentElement = null

		if (!this.firstElement) return false;

		if (this.options.centerOnClick) this.ulEl.observe('click', this.centerOnClick.bindAsEventListener(this))
		this.ulEl.observe('click', this.addpos.bindAsEventListener(this))

		Event.observe(window, 'load', this.init.bind(this))

	},
	addpos: function(e) {
		var el = e.findElement('a')
		if (!el) return
		var url = StringUrlSegment.setHashSegment(el.href, 'left', this.getLeft())
		document.location.href = url
		Event.stop(e)
	},
	init: function() {
		this.viewport = this.element.getDimensions()
		if (this.options.alignMiddle) this.alignMiddle()
		var l = parseInt(UrlSegment.getHashSegment('left'))
		if (l) this.setLeft(l)
		var id = parseInt(UrlSegment.getHashSegment('cat'))
		if (id) this.setSelectedId(id)
		this.updateButtonsStyle()
		setInterval(this._hashChangeCheck.bind(this), 200)
	},
	centerOnClick: function(event) {
		var liEl = event.findElement('li')
		this.moveTo(liEl)
	},
	setLeft: function(left) {
		this.ulEl.style.marginLeft=left+'px'
	},
	getLeft: function() {
		return parseInt(this.ulEl.style.marginLeft) || 0
	},
	moveTo: function(liEl) {

		// Fix for IE7
		this.viewport = this.element.getDimensions()

		var current = this.element.down('.current')
		if (current) current.removeClassName('current')

		if (!this.viewport.width || this.getWidth() <= this.viewport.width) return this.setCurrent(liEl)

		var it = this.firstElement
		var element_left = 0;
		while (it && it != liEl) {
			element_left += it.getWidth()
			it = it.next('li')
		}

		var element_center = liEl.getWidth() / 2
		var viewport_center = this.viewport.width / 2
		var new_left = (element_left*-1) + (viewport_center - element_center)
		//if (new_pos < 0) new_pos = 0
		//
		if (new_left > 0) new_left = 0
		if (this.getWidth() + new_left < this.viewport.width) new_left = this.viewport.width - this.getWidth()

		var steps = new_left - this.getLeft()

		new Effect.MoveOffsetLeft(this.ulEl, {
			x: steps, y: 0,
			transition: Effect.Transitions.sinoidal,
			afterFinish: this.updateButtonsStyle.bind(this)
		}); /**/
		this.setCurrent(liEl)
	},
	setCurrent: function(liEl) {
		liEl.addClassName('current')
		this.currentElement = liEl
		UrlSegment.setHashSegment('cat', liEl.id.substring(4))
	},
	getWidth: function() {
		var list = this.ulEl.select('li');
		var width = 0
		for (var i = 0; i < list.length; i++) {
			width += Element.getWidth(list[i])
		}
		return width;
	},
	setSelectedId: function(id) {
		var liEl = $('cat_'+id)
		if (liEl) this.moveTo(liEl)
	},
	_hashChangeCheck: function(init) {

		var el_id = UrlSegment.getHashSegment('cat')

		if (!el_id || this.last_el_id == el_id) return

		this.last_el_id = el_id
		var current = this.ulEl.select('li').find(function(liEl){
			return liEl.id=='cat_'+el_id
		})
		if (current && current != this.currentElement) {
			this.moveTo(current)
		}
	},
	getCenterElement: function() {
		var center = this.viewport.width / 2

		var list = this.ulEl.select('li');

		var left = parseInt(this.ulEl.style.marginLeft) || 0

		var element;

		for (var i = 0; i < list.length; i++) {
			element = list[i]
			left += element.getWidth()
			if (left >= center) break
		}

		return element

	},
	updateButtonsStyle: function() {
		var next = this.getNextOutside()
		var prev = this.getPreviousOutside()
		if (next) {
			this.nextButton.removeClassName('disabled')
			if (Object.isFunction(this.nextButton.enable)) this.nextButton.enable()
		}
		else {
			this.nextButton.addClassName('disabled')
			if (Object.isFunction(this.nextButton.disable)) this.nextButton.disable()
		}

		if (prev) {
			this.previousButton.removeClassName('disabled')
			if (Object.isFunction(this.previousButton.enable)) this.previousButton.enable()
		} else {
			this.previousButton.addClassName('disabled')
			if (Object.isFunction(this.previousButton.disable)) this.previousButton.disable()
		}
	},
	getNextOutside: function() {
		var liEl = (this.currentElement) ? this.currentElement : this.firstElement
		liEl = liEl.next('li')
		while (liEl) {
			if (!this.inViewport(liEl)) return liEl
			liEl = liEl.next('li')
		}
		return null
	},
	getPreviousOutside: function() {
		var liEl = (this.currentElement) ? this.currentElement : this.firstElement
		liEl = liEl.previous('li')
		while (liEl) {
			if (!this.inViewport(liEl)) return liEl
			liEl = liEl.previous('li')
		}
		return null
	},
	inViewport: function(liEl) {
		var current = this.firstElement
		var el_start = 0;
		while (current && current != liEl) {
			el_start += current.getWidth()
			current = current.next('li')
		}

		var vp_start = parseInt(this.ulEl.style.marginLeft)*-1 || 0
		var vp_end = vp_start + this.viewport.width

		var el_end = el_start + liEl.getWidth()

		//console.log([el_start, '-', el_end], ' / ', [vp_start,'-', vp_end])

		return el_start >= vp_start && el_end <= vp_end

	},
	first: function() {
		//this.moveTo(this.firstElement)
	},
	next: function (event) {
		var next = this.getNextOutside()

		if (!next && !this.loop) return

		this.currentElement = next ? next : this.firstElement
		this.moveTo(this.currentElement)
	},
	previous: function(event) {
		var prev = this.getPreviousOutside()

		if (!prev && !this.loop) return

		this.currentElement = prev ? prev : this.lastElement
		this.moveTo(this.currentElement)
	},
	alignMiddle: function() {

		var list = this.ulEl.select('li');

		// Get height of highest image
		var maxheight = list.collect(function(li) {return li.getHeight()}).max()

		// Adjust heights
		for (var i = 0; i < list.length; i++) {
		   var liEl = list[i]
			var top = (maxheight - liEl.getHeight()) / 2
			liEl.style.marginTop = top + 'px'
		}
		this.element.style.height = maxheight+'px'

		// Align in center
		var wdiff = this.viewport.width - this.getWidth()
		if (wdiff > 0) {
			this.ulEl.style.marginLeft = (wdiff/2)+'px'
		}
	}
});
