/**
 * sliderSelect
 * @author Avery Brooks
 * @requires jQuery
 * @requires jQuery.dimensions
 * @param objID (target UL)
 * @param parentID (container DIV)
 */
function sliderSelect(target, container, sliderName) {

	//
	//
	// Movement Functions
	//
	//

	/*
	 * slideToComplex()
	 */
	this.slideToComplex = function(value) {

		if (!value || value == "undefined") {
			value = this.currentIndex;
		}

		var REAL_WIDTH  = 0;
		var CHILD_COUNT = 0;
		var TARGET_CHILD = value;

		$(this.contentObj).children("li").each(
			function() {
				REAL_WIDTH += $(this).width();
				CHILD_COUNT ++;
			}
		);

		var MIDDLE_CHILD = Math.floor(CHILD_COUNT / 2);

		var leftTarget = 25;
		var rightTarget = $(this.refObj).width() - 25 - $(this.contentObj).children("li:nth-child(" + CHILD_COUNT + ")").width();

		if (TARGET_CHILD == 1) {
			WEIGHT2 = 0;
			WEIGHT1 = 1;
		} else if (TARGET_CHILD == CHILD_COUNT) {
			WEIGHT2 = 1;
			WEIGHT1 = 0;
		} else {
			var WEIGHT2 = TARGET_CHILD / CHILD_COUNT;
			var WEIGHT1 = 1 - WEIGHT2;
		}

		var target = WEIGHT1 * leftTarget + WEIGHT2 * rightTarget;

		// Find contentObj left
		var startLeft = $(this.contentObj).position().left;

		// Find targetObj offset
		var childOffset = $(this.contentObj).children("li:nth-child("+TARGET_CHILD+")").position().left;

		// ChildLeft inside reference obj
		var childLeftInRef = startLeft + childOffset;

		var moveAmount = target - childLeftInRef;		

		this.lastIndex = this.currentIndex;
		this.currentIndex = TARGET_CHILD;

		// alert("I am " + this.currentIndex + " of " + CHILD_COUNT + ".");

		this.scrollBy(moveAmount);
		return;

	}

	/*
	 * slideToCenter()
	 */
	this.slideToCenter = function(value) {

		if (!value || value == "undefined") {
			value = this.currentIndex;
		}

		// Find real center
		var target = 0;
			target += ($(this.refObj).width() / 2);
			target -= ($(this.contentObj).children("li:nth-child("+value+")").width() / 2);

		// Find contentObj left
		var startLeft = $(this.contentObj).position().left;

		// Find targetObj offset
		var childOffset = $(this.contentObj).children("li:nth-child("+value+")").position().left;

		// ChildLeft inside reference obj
		var childLeftInRef = startLeft + childOffset;

		var moveAmount = target - childLeftInRef;		

		this.lastIndex = this.currentIndex;
		this.currentIndex = value;

		this.scrollBy(moveAmount);
		return;

	}

	/**
	 * scrollTo()
	 */
	this.slideTo = function(value) {

		if (!value) {
			return false;
		}

		var offset = 0;
		var scrollAmount = 0;
		var parentWidth  = $(this.refObj).width();

		value = parseInt(value);

		this.lastIndex = this.currentIndex;

		if (value > this.currentIndex) {
			while (this.currentIndex < value) {
				scrollAmount -= $(this.contentObj).children("li:nth-child("+this.currentIndex+")").width();
				this.currentIndex ++;
			}
		} else if (value < this.currentIndex) {
			while (this.currentIndex > value) {
				// we're moving 'back' by one at a time so subtract first
				this.currentIndex --;
				scrollAmount += $(this.contentObj).children("li:nth-child("+this.currentIndex+")").width();
			}
		} else if (value == this.currentIndex) {
			// This dude isn't going anyplace
		}

		this.scrollBy(scrollAmount);

		return true;
	}
	
	/**
	 * scrollBy()
	 */
	this.scrollBy = function(value) {

		if (!value || value == 0) {
			return false;
		}
		
		var direction  = "+=";
		var duration   = this.getDuration();
		var easing     = this.getEasing();
		var slideview  = $(this.contentObj);
	
		if (value > 0) {
			direction = "+=";
		}
	
		if (value < 0) {
			value *= -1;
			direction = "-=";
		}

		value = direction + value + "px";

		// PRESCROLL event
		if (this.lastIndex != this.currentIndex) {
			try {
				setTimeout(this.preScrollFunct + "('" + this.lastIndex + "')", 3);
			} catch(e) {}
		}

		// Remove next/prev buttons for fast clickers
		this.clearPrev();
		this.clearNext();

		slideview.animate(
			{left: value},
			duration,
			easing
		);

		// EVENT COMPLETE callback
		if (this.lastIndex != this.currentIndex) {
			try {
				setTimeout(this.postScrollFunct + "('" + this.currentIndex + "')", duration);
			} catch(e) {}
		}

		// Re-init next/prev buttons
		setTimeout(this.myName + ".setPrev()",duration);
		setTimeout(this.myName + ".setNext()",duration);

		return true;
	}

	/**
	 * show a particular element, letting the object select which method to use
	 */
	this.showElement = function(value) {

		if (!value) {
			value = this.selectedIndex;
		}

		if (this.align === "left") {
			this.slideTo(value);
		} else if (this.align === "center") {
			this.slideToCenter(value);
		} else if (this.align === "complex") {
			this.slideToComplex(value);
		} else {
			// if we are here, there is a problem with alignment setup
		}	

		return;
	}

	/**
	 * showPrev()
	 */
	this.showPrev = function() {
		if (this.currentIndex == 1) {
			return false;
		}
		return this.showElement(this.currentIndex - 1);
	}

	/**
	 * showNext()
	 */
	this.showNext = function() {

		if (this.currentIndex >= ($(this.contentObj).children().length)) {
			return false;
		}
		return this.showElement(this.currentIndex + 1);
	}

	/**
	 * debug()
	 */
	this.debug = function(Party) {
		$('#Footer').append('<p>'+ Party +'</p>');
	}

	/**
	 * continuous scrolling functions
	 */
	this.startScrollPrev = function() {
		this.repeatEvent(this.myName + '.showPrev()', this.getDuration);
	}

	this.startScrollNext = function() {
		this.repeatEvent(this.myName + '.showNext()', this.getDuration);
	}

	this.stopScrollPrev = function() {
		this.stopEvent(this.myName + '.showPrev()');
	}

	this.stopScrollNext = function() {
		this.stopEvent(this.myName + '.showNext()');
	}

	/**
	 * delayed event handling
	 */
	this.delayEvent = function(functionName, delayTime) {
		try {
			clearTimeout(this.delayTimers[functionName]);
		} catch(e) {
			// alert(e);
		}
		try {
			this.delayTimers[functionName] = setTimeout(functionName, delayTime);
		} catch(e) {
			// alert(e);
		}
	}

	this.repeatEvent = function(functionName, delayTime) {
		try {
			clearInterval(this.delayTimers[functionName]);
		} catch(e) {
			// alert(e);
		}
		try {
			this.delayTimers[functionName] = setInterval(functionName, delayTime);
		} catch(e) {
			// alert(e);
		}
	}

	this.stopEvent = function(functionName) {
		try {
			clearInterval(this.delayTimers[functionName]);
		} catch(e) {
			alert(e);
		}	
	}

	//
	//
	// Utilies (these should be "prototyped" so they don't use up extra memory if we reuse the object ...
	//
	//

	// Try and fix size of the parent container
	this.calculateAndSetFullWidth = function() {
		var REAL_WIDTH  = 0;
		var CHILD_COUNT = 0;
		$(this.contentObj).children("li").each(
			function() {
				var last = REAL_WIDTH;
				$(this).children("img").each(
					function() {
						REAL_WIDTH += parseInt($(this).attr("width"));
						REAL_WIDTH += parseInt($(this).css("margin-right"));
						REAL_WIDTH += parseInt($(this).css("margin-left"));
						REAL_WIDTH += 5;
					}
				);
				CHILD_COUNT ++;
			}
		);
		$(this.contentObj).width(REAL_WIDTH);
		return;
	}


	/**
	 * Find literal list offset (px)
	 */
	this.getObjectOffset = function(value) {
		value.children().each(function(){
			// alert($(this).width());
		});
	}

	/**
	 * isID()
	 */
	this.isID = function(target) {

		if (!target)
		return false;

		if (target.substr(0,1) == "#") {
			target = target.substr(1,target.length);
		}

		if (document.getElementById(target)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * trimID()
	 */
	this.trimID = function(value) {
		if (value.substr(0,1) == "#") {
			value = value.substr(1,value.length);
		}
		return value;
	}

	//
	//
	// SETTERS
	//
	//

	/**
	 * addItem -- does this need to be more complex?
	 */
	this.addItem = function(content) {

		if (content == null || content == "undefined") {
			return false;
		}

		var slideview  = $(this.contentObj);
		var htmlcontent = "<li>" + content + "</li>";	

		slideview.append(htmlcontent);


		return true;
	}

	/**
	 * setCallback()
	 * Set the name of a function to handle the end of a scroll.
	 * Will be passed the selected index when fired.
	 */
	this.setCallback = function(callback) {
		this.postScrollFunct = callback;
	}

	/**
	 * setPrescroll()
	 * Set the name of a function to handle the end of a scroll.
	 * Will be passed the selected index when fired.
	 */
	this.setPrescroll = function(prescroll) {
		this.preScrollFunct = prescroll;
	}

	/**
	 * setScrollType()
	 * click or mouseover
	 *
	 */
	this.setScrollType = function(value) {
		if (value.toLowerCase() === "click") {
			this.scrollType = "click";
		} else if (value.toLowerCase() === "mouseover") {
			this.scrollType = "mouseover";
		} else {
			return false;
		}
		return true;
	}
	

	/**
	 * setAlign()
	 * where to line up the selected index?  left/center supported
	 * 
	 */
	this.setAlign = function(value) {

		if (value.toLowerCase() === "complex") {
			this.align = "complex";		
		} else if (value.toLowerCase() === "center") {
			this.align = "center";
		} else if (value.toLowerCase() === "left") {
			this.align = "left";
		} else {
			return false;
		}
		
		return true;		
	}

	/**
	 * setNext()
	 * Binds click to "next object"
	 */
	this.setNext = function(target) {
		if (target != null) {
			this.nextButton = document.getElementById(this.trimID(target));
			$(this.nextButton).css("cursor","pointer");
		}

		if (this.scrollType == "mouseover") {
			$(this.nextButton).bind("mouseover",this,function(e){
				e.data.repeatEvent(e.data.myName +".showNext()",e.data.holdDuration);
				e.data.showNext();
			});
			$(this.nextButton).bind("mouseout",this,function(e){
				e.data.stopEvent(e.data.myName +".showNext()");
				e.data.stopScrollNext();
			});
		} else if (this.scrollType == "click") {
			$(this.nextButton).bind("click",this,function(e){
				e.data.showNext();
			});
		}

		return;
	}

	/**
	 * setPrev()
	 * Binds click to "previous object"
	 */
	this.setPrev = function(target) {

		if (target != null) {
			this.prevButton = document.getElementById(this.trimID(target));
			$(this.prevButton).css("cursor","pointer");
		}

		// $(this.prevButton).css("cursor","pointer");

		if (this.scrollType == "mouseover") {
			$(this.prevButton).bind("mouseover",this,function(e){
				e.data.repeatEvent(e.data.myName +".showPrev()",e.data.holdDuration);
				e.data.showPrev();
			});
			$(this.prevButton).bind("mouseout",this,function(e){
				e.data.stopEvent(e.data.myName +".showPrev");
				e.data.stopScrollPrev();
			});
		} else if (this.scrollType == "click") {
			$(this.prevButton).bind("click",this,function(e){
				e.data.showPrev();
			});
		}

		return;
	}

	this.clearPrev = function() {
		$(this.prevButton).unbind(this.scrollType);
		return;
	}

	this.clearNext = function() {
		$(this.nextButton).unbind(this.scrollType);
		return;
	}

	/**
	 * central place to get duration of slide so we can make it based on width later if we need to
	 */
	this.getDuration = function() {
		return this.duration;
	}

	this.getEasing = function() {
		if (this.scrollType == "click") {
			return "swing";
		} else {
			return "linear";
		}
	}

	//
	//
	// "CONSTRUCTOR"
	// (sort of)
	//	
	//

	this.myName          = "";

	this.contentObj       = "";
	this.refObj           = "";

	this.currentID        = "";
	this.currentIndex     = 1;
	this.prevButton       = null;
	this.nextButton       = null;

	this.align            = "left"; // left, center, complex
	this.preScrollFunct   = null;
	this.postScrollFunct  = null;

	this.duration         = 250;
	
	this.holdDuration	  = 850;

	this.scrollType       = "mouseover"; // mouseover / click

	this.delayTimers      = Array();

	// Init ...

	if (sliderName != null && sliderName != "undefined") {
		this.myName = sliderName;
	}

	if (this.isID(target)) {

		target = this.trimID(target);

		this.contentObj = document.getElementById(target);
		this.currentID  = target; // ?

		container = this.trimID(container);
		this.refObj = document.getElementById(container);

	} else if (typeof(target) == "") {
		// HTMLObj
		// (other option ... if you pass a refeernce to the object, find the ID)
	}


	// Try and fix size
	this.calculateAndSetFullWidth();




} // End of object
