//  Set up TF namespace
var TF = window.TF || {};
//  Initialize and perform scrolling anchor links
TF.Scroller = function () {
	
	var stepIncrement = 50;	// Number of pixels that each step moves the window
	var stepDelay = 10;	// Number of milliseconds between steps
	var limit = 6 * 1000; // After 6 seconds, scroll is killed
	var running = false;
	
	// Recursive scrolling method -- steps through complete scroll
	function scrollStep(to, dest, down) {
		if(!running || (down && to >= dest) || (!down && to <= dest)) {
			TF.Scroller.killScroll();
			return;
		}
		if((down && to >= (dest - (2 * stepIncrement))) ||
		   (!down && to <= (dest - (2 * stepIncrement)))) {
			stepIncrement = stepIncrement * .55;
		}
		window.scrollTo(0, to);
		// Assign the returned function to a public method.
		TF.Scroller.nextStep = callNext(+to + stepIncrement, dest, down);
		window.setTimeout(TF.Scroller.nextStep, stepDelay);
	}
	
	// Create a closure so that scrollStep can be accessed by window.setTimeout()
	function callNext(to, dest, down) {
		return function() { scrollStep(to, dest, down); };
	}
	
	return {
		nextStep: null,
		killTimeout: null,
		
		// Sets up and calls scrollStep
		diffPgAnchorScroll: function() {
			// for links from diff. page
			// grab query string and split it into parameter key-value pairs
			var QS = window.location.search.substring(1);
			var QSParams = QS.split('&');
			// create separate arrays to hold parameter keys and values
			var QSParamKeys = new Array();
			var QSParamValues = new Array();
			// loop through and split each key/value pair and place into key and value arrays
			for (var p = 0; p < QSParams.length; p++) {
				var paramPosition = QSParams[p].indexOf('=');
				if (paramPosition > 0) {
					var paramKey = QSParams[p].substring(0, paramPosition);
					QSParamKeys[p] = paramKey;
					var paramValue = QSParams[p].substring(paramPosition + 1);
					QSParamValues[p] = paramValue;
				}
			}
			
			// create array of page's anchor links			
			var pgLinksAr = YAHOO.util.Dom.getElementsByClassName('scrollingLink', 'a');
			var pgAnchorLinksAr = new Array();
			for (var l = 0; l < pgLinksAr.length; l++) {
				var pgAnchorLink = pgLinksAr[l].href.replace(/^.*#/, '');
				pgAnchorLinksAr[l] = pgAnchorLink;
			}
			// convert anchor links array to string
			var pgAnchorLinksStr = pgAnchorLinksAr.join();
			
			var diffPgTarget;
			// look for each query string parameter key in anchor links string
			for (var a = 0; a < QSParamKeys.length; a++) {
				diffPgAnchorId = QSParamKeys[a];
				diffPgAnchorIdIndex = pgAnchorLinksStr.indexOf(diffPgAnchorId);
				// if key is present, it's the link target; break out of for loop
				if (diffPgAnchorIdIndex !== -1) {
					diffPgTarget = YAHOO.util.Dom.get(diffPgAnchorId);
					break;
				}
			}

			// if link target doesn't exist, exit function
			if (diffPgTarget === undefined) {
				return;
			// if link target exists, scroll to link target
			} else {
				running = true;
				var yCoord = ((YAHOO.util.Dom.getY(diffPgTarget) - 6) < 0) ? 0 : YAHOO.util.Dom.getY(diffPgTarget) - 6;
				var currentYPosition = (document.all) ? document.body.scrollTop : window.pageYOffset;
				var down = true;
				if(currentYPosition > yCoord) {
					stepIncrement *= -1;
					down = false;
				}
				// stop the scroll once the time limit is reached
				TF.Scroller.killTimeout = window.setTimeout(TF.Scroller.killScroll, limit);
				scrollStep(currentYPosition + stepIncrement, yCoord, down);
			}
		},
		
		// Sets up and calls scrollStep
		samePgAnchorScroll: function(e, obj) {
						
			// for links from same page
			var clickedLink = YAHOO.util.Event.getTarget(e);
			var samePgAnchorId = clickedLink.href.replace(/^.*#/, '');
			var samePgTarget = YAHOO.util.Dom.get(samePgAnchorId);
			
			if(samePgTarget) {
				YAHOO.util.Event.stopEvent(e);
				running = true;
				var yCoord = ((YAHOO.util.Dom.getY(samePgTarget) - 6) < 0) ? 0 : YAHOO.util.Dom.getY(samePgTarget) - 6;
				var currentYPosition = (document.all) ? document.body.scrollTop : window.pageYOffset;
				var down = true;
				if(currentYPosition > yCoord) {
					stepIncrement *= -1;
					down = false;
				}
				// Stop the scroll once the time limit is reached.
				TF.Scroller.killTimeout = window.setTimeout(TF.Scroller.killScroll, limit);
				scrollStep(currentYPosition + stepIncrement, yCoord, down);	
			}
		},
					
		// Kill scroll after timeout to prevent endless loop
		killScroll: function() {
			window.clearTimeout(TF.Scroller.killTimeout);
			running = false;
			stepIncrement = 50;			
		},
		
		// Attach scrolling method to links with class 'scrollingLink'
		init: function() {
			var links = YAHOO.util.Dom.getElementsByClassName('scrollingLink', 'a');
			YAHOO.util.Event.addListener(links, 'click', TF.Scroller.samePgAnchorScroll, TF.Scroller, true);
		}
	}
} ();

YAHOO.util.Event.onDOMReady(TF.Scroller.init, TF.Scroller, true);
YAHOO.util.Event.addListener(window, 'load', TF.Scroller.diffPgAnchorScroll, TF.Scroller, true);