/* Smooth scrolling
	 Changes links that link to other parts of this page to scroll
	 smoothly to those links rather than jump to them directly, which
	 can be a little disorienting.

	 sil, http://www.kryogenix.org/
	 http://www.peterbe.com/Smooth-anchor-scrolling-Javascript
	 
	 Modifiers: Luke Morgan <luke@lmorgan.co.uk>

	 v1.0 2003-11-11
	 v1.1 2005-06-16 wrap it up in an object
	 v1.2 2008-08-28 LM - Modified to add a function that performs scroll immediately
		to the element with specified ID.
*/

var ss = {
	fixAllLinks: function() {
		// Get a list of all links in the page
		var allLinks = document.getElementsByTagName('a');
		// Walk through the list
		for (var i=0;i<allLinks.length;i++) {
			var lnk = allLinks[i];
			if ((lnk.href && lnk.href.indexOf('#') != -1) && 
					( (lnk.pathname == location.pathname) ||
			('/'+lnk.pathname == location.pathname) ) && 
					(lnk.search == location.search)) {
				// If the link is internal to the page (begins in #)
				// then attach the smoothScroll function as an onclick
				// event handler
				ss.addEvent(lnk,'click',ss.smoothScroll);
			}
		}
	},

	smoothScroll: function(e) {
		// This is an event handler; get the clicked on element,
		// in a cross-browser fashion
		if (window.event) {
			target = window.event.srcElement;
		} else if (e) {
			target = e.target;
		} else return;

		// Make sure that the target is an element, not a text node
		// within an element
		if (target.nodeType == 3) {
			target = target.parentNode;
		}

		// Paranoia; check this is an A tag
		if (target.nodeName.toLowerCase() != 'a') return;

		// Find the <a name> tag corresponding to this href
		// First strip off the hash (first character)
		anchor = target.hash.substr(1);
		// Now loop all A tags until we find one with that name
		var allLinks = document.getElementsByTagName('a');
		var allDivs = document.getElementsByTagName('div');
		var all = [allLinks, allDivs];
		var destinationLink = null;
		for (var j=0; j<all.length; j++) {
			for (var i=0;i<all[j].length;i++) {
				var lnk = all[j][i];
				if (lnk.name && (lnk.name == anchor)) {
					destinationLink = lnk;
					break;
				} else if (lnk.id && (lnk.id == anchor)){
					destinationLink = lnk;
					break;
				}
			}
		}
		/*
		var allLinks = document.getElementsByTagName('a');
		var destinationLink = null;
		for (var i=0;i<allLinks.length;i++) {
			var lnk = allLinks[i];
			if (lnk.name && (lnk.name == anchor)) {
				destinationLink = lnk;
				break;
			}
		}
		*/

		// If we didn't find a destination, give up and let the browser do
		// its thing
		if (!destinationLink) return true;

		// Find the destination's position
		var destx = destinationLink.offsetLeft; 
		var desty = destinationLink.offsetTop;
		var thisNode = destinationLink;
		while (thisNode.offsetParent && 
					(thisNode.offsetParent != document.body)) {
			thisNode = thisNode.offsetParent;
			destx += thisNode.offsetLeft;
			desty += thisNode.offsetTop;
		}

		// Stop any current scrolling
		clearInterval(ss.INTERVAL);

		cypos = ss.getCurrentYPos();

		ss_stepsize = parseInt((desty-cypos)/ss.STEPS);
		ss.INTERVAL = setInterval('ss.scrollWindow('+ss_stepsize+','+desty+',"'+anchor+'")',10);

		// And stop the actual click happening
		if (window.event) {
			window.event.cancelBubble = true;
			window.event.returnValue = false;
		}
		if (e && e.preventDefault && e.stopPropagation) {
			e.preventDefault();
			e.stopPropagation();
		}
	}, // end smoothScroll
	
	///////////////////////////////////
	// Immediate smooth scroll to tag
	scrollToTagNow: function(tagID, anchor) {
		var destinationLink = document.getElementById(tagID);
		
		if(!destinationLink) return;
		// Find the destination's position
		var destx = destinationLink.offsetLeft; 
		var desty = destinationLink.offsetTop;
		var thisNode = destinationLink;
		while (thisNode.offsetParent && 
					(thisNode.offsetParent != document.body)) {
			thisNode = thisNode.offsetParent;
			destx += thisNode.offsetLeft;
			desty += thisNode.offsetTop;
		}

		// Stop any current scrolling
		clearInterval(ss.INTERVAL);

		cypos = ss.getCurrentYPos();

		ss_stepsize = parseInt((desty-cypos)/ss.STEPS);
		//alert('original Dest: ' + desty);
		//alert('documentHeight: ' + ss.getDocumentHeight());
		//alert('documentHeight: ' + ss.getViewportHeight());		
		
		if( desty > (ss.getDocumentHeight()-ss.getViewportHeight())) {
			desty = ss.getDocumentHeight()-ss.getViewportHeight();
		}
		ss.INTERVAL = setInterval('ss.scrollWindow('+ss_stepsize+','+desty+',"'+anchor+'")',10);

	}, // end scrollToTagNow
	
	scrollWindow: function(scramount,dest,anchor) {
		wascypos = ss.getCurrentYPos();
		isAbove = (wascypos < dest);
		//window.scrollTo(0,wascypos + scramount); 
		window.scrollTo(0, parseInt(wascypos + (dest-wascypos)/10 + 1));
		iscypos = ss.getCurrentYPos();
		isAboveNow = (iscypos < dest);
		if ((isAbove != isAboveNow) || (wascypos == iscypos)) {
			// if we've just scrolled past the destination, or
			// we haven't moved from the last scroll (i.e., we're at the
			// bottom of the page) then scroll exactly to the link
			window.scrollTo(0,dest);
			// cancel the repeating timer
			clearInterval(ss.INTERVAL);
			// and jump to the link directly so the URL's right
			location.hash = anchor;
		}
	},

	getCurrentYPos: function() {
		if (document.body && document.body.scrollTop)
			return document.body.scrollTop;
		if (document.documentElement && document.documentElement.scrollTop)
			return document.documentElement.scrollTop;
		if (window.pageYOffset)
			return window.pageYOffset;
		return 0;
	},

	addEvent: function(elm, evType, fn, useCapture) {
		// addEvent and removeEvent
		// cross-browser event handling for IE5+,  NS6 and Mozilla
		// By Scott Andrew
		if (elm.addEventListener){
			elm.addEventListener(evType, fn, useCapture);
			return true;
		} else if (elm.attachEvent){
			var r = elm.attachEvent("on"+evType, fn);
			return r;
		} else {
			alert("Handler could not be removed");
		}
	} ,
	
	// Extract from http://www.JavascriptToolbox.com
	// Copyright (c)2005-2007 Matt Kruse (javascripttoolbox.com)
	// Get the height of the entire document
	// --------------------------------------------------------------------
	// Determine if a reference is defined
	getDocumentHeight: function() {
		var body = null;
		if (document.body) {
			body = document.body;
		}
		else if (document.getElementsByTagName) {
			var bodies = document.getElementsByTagName("BODY");
			if (bodies!=null && bodies.length>0) {
				body = bodies[0];
			}
		}
    
		var innerHeight = (ss.defined(self.innerHeight)&&!isNaN(self.innerHeight))?self.innerHeight:0;
		if (document.documentElement && (!document.compatMode || document.compatMode=="CSS1Compat")) {
			var topMargin = parseInt(ss.getStyle(body,'marginTop'),10) || 0;
			var bottomMargin = parseInt(ss.getStyle(body,'marginBottom'), 10) || 0;
		  return Math.max(body.offsetHeight + topMargin + bottomMargin, document.documentElement.clientHeight, document.documentElement.scrollHeight, ss.zero(self.innerHeight));
		}
		return Math.max(body.scrollHeight, body.clientHeight, ss.zero(self.innerHeight));
	},
	defined: function(o) {
	  return (typeof(o)!="undefined");
	},
	zero: function(n) {
		return (!ss.defined(n) || isNaN(n))?0:n;
	},	
	// Get the currently-applied style of an object
	getStyle: function(o, property) {
	if (o==null) { return null; }
	var val = null;
	var camelProperty = ss.hyphen2camel(property);
	// Handle "float" property as a special case
	if (property=="float") {
	  val = ss.getStyle(o,"cssFloat");
	  if (val==null) { 
		val = ss.getStyle(o,"styleFloat"); 
	  }
	}
	else if (o.currentStyle && ss.defined(o.currentStyle[camelProperty])) {
	  val = o.currentStyle[camelProperty];
	}
	else if (window.getComputedStyle) {
	  val = window.getComputedStyle(o,null).getPropertyValue(property);
	}
	else if (o.style && ss.defined(o.style[camelProperty])) {
	  val = o.style[camelProperty];
	}
	// For color values, make the value consistent across browsers
	// Convert rgb() colors back to hex for consistency
	if (/^\s*rgb\s*\(/.test(val)) {
	  val = ss.rgb2hex(val);
	}
	// Lowercase all #hex values
	if (/^#/.test(val)) {
	  val = val.toLowerCase();
	}
	return val;
	},
	// Convert an RGB string in the form "rgb (255, 255, 255)" to "#ffffff"
	rgb2hex: function(rgbString) {
		if (typeof(rgbString)!="string" || !ss.defined(rgbString.match)) { return null; }
		var result = rgbString.match(/^\s*rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*/);
		if (result==null) { return rgbString; }
		var rgb = +result[1] << 16 | +result[2] << 8 | +result[3];
		var hex = "";
		var digits = "0123456789abcdef";
		while(rgb!=0) { 
			hex = digits.charAt(rgb&0xf)+hex; 
			rgb>>>=4; 
		} 
		while(hex.length<6) { hex='0'+hex; }
		return "#" + hex;
	},
	// Convert hyphen style names like border-width to camel case like borderWidth
	hyphen2camel: function(property) {
		if (!ss.defined(property) || property==null) { return null; }
		if (property.indexOf("-")<0) { return property; }
		var str = "";
		var c = null;
		var l = property.length;
		for (var i=0; i<l; i++) {
			c = property.charAt(i);
			str += (c!="-")?c:property.charAt(++i).toUpperCase();
		}
		return str;
	},
	
	
	// extract from http://andylangton.co.uk/articles/javascript/get-viewport-size-javascript/
	getViewportHeight: function() {
		// the more standards compliant browsers (mozilla/netscape/opera/IE7) use window.innerWidth and window.innerHeight
		if (typeof window.innerWidth != 'undefined') {
			return viewportheight = window.innerHeight
		}
		// IE6 in standards compliant mode (i.e. with a valid doctype as the first line in the document)
		else if (typeof document.documentElement != 'undefined'
			&& typeof document.documentElement.clientWidth !=
			'undefined' && document.documentElement.clientWidth != 0) {
		   
		   return document.documentElement.clientHeight
		}
		// older versions of IE
		else {
		   return document.getElementsByTagName('body')[0].clientHeight
		}
	}

}

ss.STEPS = 25;

// don't smooth scroll all links by default.
//ss.addEvent(window,"load",ss.fixAllLinks);