/*
	name			: ClassBehaviours, the javascript framework based on class-name parsing
	update			: 9.11.9
	author			: Maurice van Creij
	dependencies	: jquery.classbehaviours.js
	info			: http://www.classbehaviours.com/

    This file is part of jQuery.classBehaviours.

    ClassBehaviours is a javascript framework based on class-name parsing.
    Copyright (C) 2008  Maurice van Creij

    ClassBehaviours is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    ClassBehaviours is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with ClassBehaviours. If not, see http://www.gnu.org/licenses/gpl.html.
*/

	// create the jQuery object if it doesn't already exist
	if(typeof(jQuery)=='undefined') jQuery = function(){};

	// create the root classbehaviours object if it doesn't already exist
	if(typeof(jQuery.classBehaviours)=='undefined') jQuery.classBehaviours = function(){};

	// create the handlers child object if it doesn't already exist
	if(typeof(jQuery.classBehaviours.handlers)=='undefined') jQuery.classBehaviours.handlers = function(){}

	// scroll a list of options
	jQuery.classBehaviours.handlers.scrollList = {
		// properties
		name: 'scrollList',
		list: null,
		focus: null,
		speed: 10,
		distance: 0,
		// methods
		start: function(node){
			// prepare the refered list
			id = jQuery.classBehaviours.utilities.getClassParameter(node, 'id', 'scrollList0');
			this.prepareList(id);
			// add the right event handler to the button
			node.onclick = (jQuery.classBehaviours.utilities.getClassParameter(node, 'scrollDirection', 'forward')=='backward') ? this.startBackward : this.startForward ;
			// set canvas event handlers
			document.getElementById(id).onmouseover = this.cancel;
			document.getElementById(id).onmouseout = this.cancel;
		},
		// events
		cancelSubmit: function(){
			return false;
		},
		startBackward: function(that){
			var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
			var sl = jQuery.classBehaviours.handlers.scrollList;
			// reset all scrolling
			id = sl.reset(objNode);
			// start the scrolling
			sl.scrollBackward(id);
			// cancel the click
			return false;
		},
		startForward: function(that){
			var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
			var sl = jQuery.classBehaviours.handlers.scrollList;
			// reset all scrolling
			id = sl.reset(objNode);
			// start the scrolling
			sl.scrollForward(id);
			// cancel the click
			return false;
		},
		// methods
		idle: function(id){
			jQuery.classBehaviours.handlers.scrollList.speed = 20;
			jQuery.classBehaviours.handlers.scrollList.scrollForward(id);
		},
		prepareList: function(id) {
			var scroller = document.getElementById(id);
			var sl = jQuery.classBehaviours.handlers.scrollList;
			// if this list has not been prepared before
			if(scroller.className.indexOf('trippled')<0){
				// copy the content twice
				scrollList = scroller.getElementsByTagName('UL')[0];
				scrollList.innerHTML += scrollList.innerHTML + scrollList.innerHTML;
				jQuery.classBehaviours.parser.parseNode(scrollList);
				// set the scroller halfway
				var contentWidth = scrollList.offsetWidth;
				var contentWidth = 0;
				var contentElements = scrollList.getElementsByTagName('LI')
				for(var a=0; a<contentElements.length; a++){
					contentWidth += contentElements[a].offsetWidth;
				}
				scrollList.style.marginLeft = '-' + Math.round(contentWidth/3) + 'px';
				// mark the list as prepared
				scroller.className += ' trippled';
				// start the idle scrolling
				//sl.idleTimer = setTimeout('jQuery.classBehaviours.handlers.scrollList.idle("'+id+'")', 800000);
			}
		},
		reset: function(that){
			var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
			var sl = jQuery.classBehaviours.handlers.scrollList;
			// clear the idle timer
			//clearTimeout(sl.idleTimer);
			// stop the scrolling
			clearTimeout(sl.timeout);
			// reset the speed
			sl.speed = 20;
			// get the target id+`+3
			id = jQuery.classBehaviours.utilities.getClassParameter(objNode, 'id', 'scrollList0');
			// pass the id back
			return id;
		},
		cancel: function(that){
			var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
			var sl = jQuery.classBehaviours.handlers.scrollList;
			// clear the idle timer
			//clearTimeout(sl.idleTimer);
			// stop the scrolling
			clearTimeout(sl.timeout);
			// reset the distance
			sl.distance = 0;
			// release the focus
			sl.focus = null;
			// wait for a while, then start idle scrolling
			id = (objNode.nodeName=='BUTTON') ? jQuery.classBehaviours.utilities.getClassParameter(objNode, 'id', 'scrollList0') : objNode.id ;
			//sl.idleTimer = setTimeout('jQuery.classBehaviours.handlers.scrollList.idle("'+id+'")', 8000);
		},
		scrollBackward: function(id){
			var sl = jQuery.classBehaviours.handlers.scrollList;
			// how wide is the container
			var container = document.getElementById(id);
			var borderWidth = container.offsetWidth;
			// how wide is the content
			var content = container.getElementsByTagName('UL')[0];
			var contentWidth = 0;
			var contentElements = content.getElementsByTagName('LI')
			for(var a=0; a<contentElements.length; a++){
				contentWidth += contentElements[a].offsetWidth;
			}
			// where is the content
			var contentScrolled = (content.style.marginLeft) ? parseInt(content.style.marginLeft) : 0 ;
			// if a page worth of scrolling has passed
			sl.distance += sl.speed;
			if(sl.distance >= borderWidth){
				// adjust the last step
				sl.speed -= sl.distance - borderWidth;
				// stop scrolling
				sl.cancel(document.getElementById(id));
			}
			// else move a next step
			else{
				// next step
				sl.timeout = setTimeout('jQuery.classBehaviours.handlers.scrollList.scrollBackward("' + id + '")', 25);
			}
			// if the content can still move
			loopPoint = 0
			resetPoint = -1 * Math.round(contentWidth/3);
			if(contentScrolled<loopPoint){
				// move it
				content.style.marginLeft = (contentScrolled + sl.speed) + 'px';
			}
			// reset it back to the starting position
			else{
				content.style.marginLeft = (contentScrolled + resetPoint + sl.speed) + 'px';
			}
		},
		scrollForward: function(id){
			var sl = jQuery.classBehaviours.handlers.scrollList;
			// how wide is the container
			var container = document.getElementById(id);
			var borderWidth = container.offsetWidth;
			// how wide is the content
			var content = container.getElementsByTagName('UL')[0];
			var contentWidth = 0;
			var contentElements = container.getElementsByTagName('LI')
			for(var a=0; a<contentElements.length; a++){
				contentWidth += contentElements[a].offsetWidth;
			}
			// where is the content
			var contentScrolled = (content.style.marginLeft) ? parseInt(content.style.marginLeft) : 0 ;
			// if a page worth of scrolling has passed
			sl.distance += sl.speed;
			if(sl.distance >= borderWidth){
				// adjust the last step
				sl.speed -= sl.distance - borderWidth; // I don't know why the 4 was needed, sorry.
				// stop scrolling
				sl.cancel(document.getElementById(id));
			}
			// else order a next step
			else{
				// next step
				sl.timeout = setTimeout('jQuery.classBehaviours.handlers.scrollList.scrollForward("' + id + '")', 25);
			}
			// if the content can still move
			loopPoint = -2 * Math.round(contentWidth/3);
			resetPoint = -1 * Math.round(contentWidth/3);
			if(contentScrolled > loopPoint){
				// move it
				content.style.marginLeft = (contentScrolled - sl.speed) + 'px';
			}
			// else reset it back to the starting position
			else{
				content.style.marginLeft = (contentScrolled - resetPoint - sl.speed) + 'px';
			}
		}
	}

	// add this addon to the jQuery object
	if(typeof(jQuery.fn)!='undefined'){
		// extend jQuery with this method
		jQuery.fn.scrollList = function(){
			return this.each(
				function(){
					jQuery.classBehaviours.handlers.scrollList.start(this);
				}
			);
		};
		// set the event handler for this jQuery method
		$(document).ready(
			function(){
				$(".scrollList").scrollList();
			}
		);
	}

