///	<summary>Class BaseScroller
///	Serves as an abstract class to render a scroller whose behavior is to shift the content a set number of pixels for a jump effect.
///	</summary>
///	Created by TCW and EBS (11/2005)
///	Updated by EBS (5/2006) to remove setting of visibility in favor of class names that can be styled
///	(Commented out sections would allow arrow HTML to be automatically generated by the scroller)
///	Updated by EBS (6/2006) to remove formatCssSelector() method, rewrite it to be comprehensive
///	and work in Safari, and move it to the StyleHelper.js file, since it's generic style-oriented functionality
/// <param name="viewId">html id of the viewable area</param>
/// <param name="itemId">html id of the area that is to be scrolled</param>
/// <param name="leftArrowId">html id of the left arrow</param>
/// <param name="rightArrowId">html id of the right arrow</param>

/*function BaseScroller(viewId, itemId, leftArrowId, rightArrowId, forwardText, backwardText) {*/

function BaseScroller(viewId, itemId, leftArrowId, rightArrowId) {

			// ===================
			// protected variables
			// ===================
	
			// Html element references
	this._scrollerView = null;
	this._scrollerItem = null;
	this._backwardArrow = null;
	this._forwardArrow = null;
			// Html ids
	this._viewId = (viewId != null) ? viewId : "scroll-view";	// same as id (#) name
	this._itemId = (itemId != null) ? itemId : "scroll-item";	// same as id (#) name
	this._backwardArrowId = (leftArrowId != null) ? leftArrowId : "scroll-left-arrow";
	this._forwardArrowId = (rightArrowId != null) ? rightArrowId : "scroll-right-arrow";
			// Text (can be overridden in XML file with <forwardText> and <backwardText> nodes
			// with appropriate codebehind to read these xml nodes before calling Scroller()
	/*this._forwardText = (forwardText != null) ? forwardText : "Forward";
	this._backwardText = (backwardText != null) ? backwardText : "Back";*/
			// Css property ids (in the case that the css selector is not simply the element id but uses a path, or if there are multiple scrollers on the same page)
	this._viewCssSelector = null;
	this._itemCssSelector = null;
	
	this._increment = 0;	// amount (in px) to scroll by for each click
	this._itemCount = 0;	// number of items to scroll (used as a multiplier of the increment)
	this._initialPosition = 0; // Initial "jump" position for the control
	this._cssPath = "style.css";	// indicates the title of the external stylesheet so we can access these properties, initially only for Safari	
	
			// ===========
			// Constructor
			// ===========
	
			// ==========
			// Properties
			// ==========
	
	///	<summary>Sets the value representing how much the item html moves on scroll.</summary>
	this.SetIncrement = function(value) {
		this._increment = value;
	}
	///	<summary>Sets the value representing how many items are in the scroller, used in scroll calculation.</summary>
	this.SetItemCount = function(value) {
		this._itemCount = value;
	}
	///	<summary>Sets the value representing the path to the css file necessary to find a stylesheet object reference.</summary>
	this.SetCssPath= function(value) {
		this._cssPath = value;
	}
	///	<summary>Sets the value representing the viewable area's style selector, necessary for cross-browser scripting.
	/// There should be no reason to override this; it is created by the class based on the string passed into the constructor
	/// (or the default string) for the view id.</summary>
	this.SetViewCssSelector= function(value) {
		this._viewCssSelector = value;
	}
	///	<summary>Sets the value representing the item area's style selector, necessary for cross-browser scripting.</summary>
	this.SetItemCssSelector= function(value) {
		this._itemCssSelector = value;
	}
	/// <summary>Sets the initial jump position for the control. The number stored here will call the scrollForward method that many times.</summary>
	this.SetInitialPosition= function(value) {
		this._initialPosition = value;
	}
	
			// ==============
			// Public methods
			// ==============
	
	///	<summary>Final method - Moves the scroller viewable area by changing the position of the item elements' style.left property</summary>
	this.Scroll = function(direction) {
				// Scroll only if there are items remaining outside the clip viewing area
				/* Forward */
		if (direction > 0) {
			if (this.canScrollForward()) {
				this.scrollForward();
			}							/* Reverse */
		} else {
			if (this.canScrollBackward()) {
				this.scrollBackward();
			}
		}
		
		this.updateControls(0, this.canScrollBackward());
		this.updateControls(1, this.canScrollForward());
	}
	
	
			// =================
			// Protected methods
			// =================
	
	///	<summary>Moves the item area forward the specified number of times</summary>
	this.jumpForward = function(numTimes) {
		for (var i = 0; i < numTimes; i++) {
			this.scrollForward();
		}
	}
	
	///	<summary>Moves the item area backward the specified number of times</summary>
	this.jumpBackward = function(numTimes) {
		for (var i = 0; i < numTimes; i++) {
			this.scrollBackward();
		}
	}
	
	///	<summary>Abstract method - moves the item area forward</summary>
	this.scrollForward = function() {}
	
	///	<summary>Abstract method - moves the item area backward</summary>
	this.scrollBackward = function() {}
	
	///	<summary>Abstract method - indicates if there is remaining html to scroll forward</summary>
	this.canScrollForward = function() {}
	
	///	<summary>Abstract method - indicates if there is remaining html to scroll forward</summary>
	this.canScrollBackward = function() {}
	
	///	<summary>Abstract method - Initializes items from the stylesheet so we can reference them by their style.* properties later in the script</summary>
	this.ReadStyleSheetProperties = function() {}
		
	///	<summary>Arrows will disappear when at scroller bounds</summary>
	this.updateControls = function(direction, visible) {
		
		var controlClass = (visible) ? "scroll-active" : "scroll-inactive";
		
		var arrow = (direction > 0) ? this._forwardArrow : this._backwardArrow;
		
		if (arrow != null) {
			arrow.className = controlClass;
		}
	}
	/*
	/// <summary>Arrows must be rendered to the page if the scroller exists</summary>
	this.renderControls = function() {
		// builds the controls and finds the parent node (scroll-frame by default)
		var backwardHtml = this.buildControl(this._backwardArrowId, this._backwardText);
		var forwardHtml = this.buildControl(this._forwardArrowId, this._forwardText);
		var parent = this._scrollerView.parentNode;
		// render the controls to the DOM
		parent.insertBefore(backwardHtml, this._scrollerView);
		parent.appendChild(forwardHtml);
	}

	/// <summary> Renders one arrow control</summary>
	this.buildControl = function(theId, theText) {
		var div = document.createElement('div');
		div.id = theId;
		var text = document.createTextNode(theText);
		div.appendChild(text);
		return div;
	}*/

	///	<summary>Add the necessary event listeners required for scroller use.</summary>
	this.addListeners = function () {
		if (document.getElementById) {
			var scroller = this;
			
			EventHelper.AddEvent(this._forwardArrow, 'click', scrollRightInitPtr = function() {scroller.Scroll(1);}, false);
			EventHelper.AddEvent(this._backwardArrow, 'click', scrollLeftInitPtr = function() {scroller.Scroll(0);}, false);
		}
	}
}

///	<summary>Set up routine, declared here so we can call it in inheriting classes</summary>
BaseScroller.prototype.Init = function(){
			// Don't do anything unless the scroller actually exists on the page
	if (document.getElementById(this._viewId) != null) {
				// These html object references need to be set here to help ensure that the elements will exist on
				// the page when the reference is attempted
		this._scrollerView = document.getElementById(this._viewId);
		this._scrollerItem = document.getElementById(this._itemId);
		
		// render the arrow controls
		/*this.renderControls(this._backwardArrowId, this._forwardArrowId);*/
		
		this._backwardArrow = document.getElementById(this._backwardArrowId);
		this._forwardArrow = document.getElementById(this._forwardArrowId);
			   // set the selector string
		this._viewCssSelector = (this._viewCssSelector == null) ? StyleHelper.FormatCssSelector('#'+this._viewId) : StyleHelper.FormatCssSelector(this._viewCssSelector);
		this._itemCssSelector = (this._itemCssSelector == null) ? StyleHelper.FormatCssSelector('#'+this._itemId) : StyleHelper.FormatCssSelector(this._itemCssSelector);
				// Set view properties if javascript is enabled to override accessibility styles for non-javascript
		this._scrollerView.style.overflow = "hidden";
		this._scrollerView.style.visibility = "visible";
		
		this.ReadStyleSheetProperties();		// called here so that the arrow test will have the necessary properties set

		this.jumpForward(this._initialPosition);
		this.updateControls(0, this.canScrollBackward());
		this.updateControls(1, this.canScrollForward());

		this.addListeners();
	}
}
