
//$(document).ready(function() { // This will run it PRIOR to any images loading, which obviously screws up our height calculations
window.onload = function(){ // this will collide with other window.onload functions


	/**
	 * Convenience function from PHP
	 */
	var_dump = function(curVar){
		console.log(curVar);
	}



	/**
	 * Get only the number in a string
	 * 
	 */
	numbersOnly = function(mixedString){
		
		var tmpString = mixedString.replace(/[a-zA-Z-_]/gim, '');
		
		if (tmpString == 0){ 
		
			tmpString = '0'; // otherwise nothing gets returned when it's zero 
			
		}
		
		return tmpString;
		
	}



		/**
		 * GENERIC NOTES : TO BE ROLLED INTO THE OTHERS
		 * 
		 * 
		 * - Make js/css/html editor/runner run in an iframe
		 * - Templates can have 'chunks' so a 'data' -> 'details' template could use 'chunk' for files, content, etc. 
		 * - global template in each 'theme' folder -> things like header, etc. this css should load last since it is GLOBAL
		 * - notifications table, queried every 5 minutes or so? system updates, etc. with a balloon or ? popup on every users desktop
		 * 
		 * - STRATACODE automatic, animatable plugins and effects - just apply a class name 
		 * 
		 * 		.initScroll(quest page scrolls up a few pixel effect) .fadeIn .fadeInSlow .fadeInDelayed .hoverTitle .callout .tooltip .fadeAway .drawer
		 * 		.menu .menuWide .spinner .swap(?) .tabs .accordian .stylebar 
		 * 
		 * 		.fg .mg .bg .fgAlwaysTop
		 * 
		 * 
		 * - abstract the 'get parents' php function into a class that 
		 * can work with any table that uses that particular data structure
		 * - content/asset locking or 'freezing'
		 * - prebuilt templates and template snippets
		 * 
		 */
		////////////////
		// NOTE :: Use jQuery's 'script' loading function (see in ajax? section) to HIDE scripts from casual 'code lifter'
		////////////////



		
		/**
		 * STRATA Scrollbar	(stylebar)	
		 * 
		 * 
		 * GOALS:
		 * 
		 * - Calculate percentage of total height that the viewable
		 *   window is.
		 * - This percentage is how large (in percentage) that the
		 *   gripper is compared to the available scroll bar height.
		 * - Each movement should be the same no matter how tall the
		 *   content is.
		 * - Standardize the delta of mouse wheel movement between
		 *   browsers.
		 * - We need to calculate the height of the scroll bar available
		 *   as a percentage of the total viewable area so that...
		 * - One delta tick should move the gripper it's scale factor
		 *   (as mentioned on previous goal) down/up, while it moves the
		 *   content scrollAmount up/down
		 * 
		 * 
		 * 
		 * //FIXME 
		 * These will need to be indexed like the menu above 
		 * if we want more than one scroll bar on the page.
		 * However, they need to be set once, or the box 
		 * size keeps changing (rounding errors by the browser?)
		 * 
		 * //FIXME 
		 * We can make degrade gracefully for browsers
		 * WITHOUT javascript, if the container starts 
		 * out with a value of scroll instead of hidden 
		 * and jQuery changes it!
		 * 
		 * //FIXME
		 * Listen for resize and react, or make it 
		 * flow correctly on resize
		 * 
		 * 
		 * //NOTE ON BROWSERS RENDERING
		 * At the time of this writing (May 6th, 2009), Firefox
		 * version 3.0.9 appears to be the only browser that allows
		 * floating point calculations in their rendering of elements.
		 * All of the other browsers tested, round to the nearest Int.
		 * If you don't know about this, it can cause serious errors in
		 * your animation calculations.
		 *
		 * And, much of the Math.round and other calculations wouldn't 
		 * be necessary without browser rounding problems
		 * 
		 * This whole thing would be very simple if we did not have
		 * a scrollAmount, however, without this,
		 * the taller the content, the less it scrolls,
		 * etc.
		 *
		 */
		
		/**
		 * Using the 'this' keyword correctly:
		 * 
		 *function func(){
		 *	this.test = 'hi there';
		 *}
		 *func.prototype.talk = function(){
		 *	alert(this.test);
		 *}
		 *var me = new func();
		 *me.talk();
		 */
		
		
		
		
		/**
		 * Updated todo
		 * 
		 * 
		 * x- buttons shouldn't be looking for a class, it should be a var with an assigned id (i.e. scrollUpBtn1, scrollUpBtn2, etc.)
		 * x- Scrollable behavior added by scroll class (how to define primary scroll area?)
		 * x- global event delegation (mousewheel, keyboard) is based on mouseover for sub scrollable areas?
		 * - the scroll instance shouldn't even be created if there is no need for the scroll bar (i.e. content is too short)
		 * x- scrollable class options: .scrollablePrimary .scrollable .scrollableLeft (for left scrollbar)
		 * x- do we really need THREE containers?
		 *		- textContainer - basically the div that the scrollable lives in, right? could be the container that .scrollable is added to?
		 * 		- stylebarContainer - the absolutely positioned container inside the original container - also, see stylebar
		 * 		- stylebar - the actual scroll bar code (when content is long enough) is included AFTER this container (in otherwords as a sibling inside stylebarContainer)
		 */
		


	/**
	 * !Globals 
	 * 
	 * - Can't these be properties of a base object?
	 * 	 UPDATE:	NO - because the event delegators are global
	 * 
	 * 
	 * div element
	 * number of scrollbars
	 */ 
	var currentScroller = ''; // index number of the currently active scroller
	var sseScrollNum = 0; // counter - number of scroll bars for indexNumber
	var scrollObjs = new Array();




	/**
	 *
	 * SSE Scroll Base Object
	 *
	 * NOTE: For whatever reason, I was having a hard time setting properties after instantiation,
	 * so they are passed into to the constructor here. :o/
	 */
	sseScroll = function(containerEl, scrollContainerEl, scrollEl, leftRight, scrollNum){
		
		
		/**
		 * 
		 * stylebar is actually the div containing the scrolling text
		 */
		this.sbWidth = 7; //21;
		
		this.sbButtonHeight = 15; //35;	// fixme this may be causeing problems, as stuff broke after it was changed to 'this'
		
		this.sbPadding = 0; //10; //the distance between the scroll bar and the text content
		
		/**
		 * //FIXME
		 * Things get really wonky at really tall
		 * content levels
		 */
		this.sbMinHeight = 1; // don't let it disappear with massive amounts of content
		
		/**
		 * Set which side of the text container
		 * to show the scroll bar on
		 * 
		 * //FIXME 
		 * Should we be using a float? Do we need
		 * the outer textContainer? What if we 
		 * want the scroll bar outside of the text 
		 * container?
		 */
		this.sbLeftRight = leftRight; //s'right';
		
		/**
		 * For adding button id's etc.
		 */
		this.indexNumber = scrollNum; //0;
		
		/**
		 * The div's
		 */
		this.tc = $(containerEl); //$('.textContainer');
		
		this.scc = $('#' + scrollContainerEl); //scc ends up as the primary container for text and scroll bar
		
		this.sc = $('#' + scrollEl); // sc ends up being the actual text container
		
		//alert (scrollContainerEl + '  type of:' + typeof scrollContainerEl);
		
		this.tmpContainerHeight = this.tc.height();
		
		this.tmpContainerWidth = this.tc.width();
		
		this.tmpContainerTop = this.scc.position().top;
		
		// this is unnecessary, as it won't resize if in CSS it is originally set to overflow: hidden
		//this.tc.css({visibility: 'hidden'}); // now that everything is loaded, show the content container (hidden in CSS to avoid resizing the container)
		
		
		this.scc.css({position: "absolute", top: '0px', left: '0px', width: this.tmpContainerWidth, height: this.tmpContainerHeight, overflow: "hidden"});
		
		
		// sb on right 
		if (this.sbLeftRight == 'right'){
			
			this.sc.css({position: "absolute", top: '0px', left: this.sbPadding + 'px', width: (this.tmpContainerWidth - this.sbWidth - (this.sbPadding * 2) ) + 'px'});
			//console.log('right');
			this.sbLeftRightOpposite = 'left';
		}
		// sb on left
		else {
			
			this.sc.css( {position: "absolute", top: '0px', left: (this.sbPadding + this.sbWidth) + 'px', width: (this.tmpContainerWidth - this.sbWidth - (this.sbPadding * 2) ) + 'px' } );
			//console.log('left');
			this.sbLeftRightOpposite = 'right';
		}
		
		/**
		 * Give us room for the content fade on the bottom
		 * 
		 * marginBottom margin-bottom padding, etc. didn't work...
		 * so we'll just add to the height a bit?
		 */
		//this.sc.css( { 'margin-bottom': '30px' } );
		this.sc.css( { 'height': 20 + this.sc.height() + 'px' } );
		
		this.tmpRealHeight = this.sc.height(); //this is going to be calculated each time :o\
		this.tmpRealWidth = this.sc.width();
		this.tmpRealTop = this.sc.position().top;

		
		/**
		 * Check whether or not we should be scrolling,
		 * 
		 * If not, there is no reason to waste the memory/cpu
		 * with these vars/calcs
		 */
		if (this.tmpRealHeight > this.tmpContainerHeight){
			
			this.shouldScroll = true;

			
			/**
			 * Scroll amount is multiplied by delta
			 * (default of 3) for each event.
			 * 
			 * Should be used only on content, not the gripper?
			 * 
			 * Without this (i.e. using delta only),
			 * the amount of each scroll changes based
			 * on the amount of content
			 */
			this.scrollAmount = '15';

			
			/**
			 * Normalize the mousewheel delta
			 */
			this.deltaMultiplier = '';
			if(jQuery.browser['safari'] == true){ this.deltaMultiplier = 1; }
			if(jQuery.browser['msie'] == true){ this.deltaMultiplier = 3; }
			if(jQuery.browser['mozilla'] == true){ this.deltaMultiplier = 3; }
			if(jQuery.browser['opera'] == true){ this.deltaMultiplier = 3; }

			
			/**
			 * Set the delta for keyboard event and scroll
			 * button clicks
			 * 
			 * defaults to 3
			 */
			this.keyDelta = 3;

			
			/**
			 * Amount of height left over for the gripper
			 * assumes that the buttons are inside the same
			 * container.
			 */
			this.sbAvailHeightPreGrip = this.tmpContainerHeight - (this.sbButtonHeight * 2);

			
			/**
			 * Content Scaling Factor
			 * 
			 */
			this.cScalingFactor = this.tmpContainerHeight / this.tmpRealHeight;

			
			/**
			 * Content Lowest Top
			 * 
			 */
			this.cLowestTop = this.tmpContainerHeight - this.tmpRealHeight;

			
			/**
			 * Calculated Gripper Height
			 * 
			 */		
			this.gripHeight = Math.floor(this.sbAvailHeightPreGrip * this.cScalingFactor);


			/**
			 * Amount of height left over for the gripper
			 * assumes that the buttons are inside the same
			 * container.
			 */
			this.sbAvailHeight = this.sbAvailHeightPreGrip - this.gripHeight;

			
			/**
			 * percentageJump
			 *
			 * How much we will move with each delta
			 * in terms of percentage
			 */
			this.percentageJump = this.scrollAmount / this.tmpRealHeight;


			/**
			 * Grip Jump
			 */
			this.gripJump = this.sbAvailHeight * this.percentageJump;

			
			/**
			 * Scaling Factor
			 * 
			 * 
			 * UPDATE: Scroll Amount scaling factor
			 *
			 * I DON'T THINK THIS IS EVEN BEING USED ANYMORE ----- //FIXME Clean up any vars that aren't being used
			 */
			this.sbHeightScale = this.gripHeight / this.sbAvailHeight;
			
			//var scalingFactor = scrollAmount * sbHeightScale;
			this.scalingFactor = Math.floor(this.scrollAmount * this.cScalingFactor);

			
			/**
			 * Unrounded Absolute middle of Gripper
			 *
			 */
			this.gripAbsMiddle =  this.gripHeight/2;

			
			/**
			 * Relative Lowest Top
			 */
			//var gripLowestTop = sbAvailHeight + this.sbButtonHeight;
			//var gripLowestTop = sbAvailHeight - gripHeight;
			this.gripLowestTop = this.tmpContainerHeight - this.sbButtonHeight - this.gripHeight;  // WHAT IS GOING ON HERE?????
			
			/**
			 * Relative Highest Top
			 */
			this.gripHighestTop = this.sbButtonHeight;
			
			
			if (this.gripHeight < this.sbMinHeight) { this.gripHeight = this.sbMinHeight };
			
			// DO NOT USE CSS BORDERS ON THE SCROLL BAR!
			// they cause massive problems with calculation
			// removed /beta
			this.scrollBar = '<div id="btnScrollBg' + this.indexNumber + '" style="position: absolute; width: ' + this.sbWidth + 'px; height: ' + this.tmpContainerHeight + 'px; ' + this.sbLeftRight + ': 0px; border: 0; margin: 0; padding: 0;">' +
				'<div style="position: absolute; left: 0px; top: ' + this.sbButtonHeight + 'px; z-index: 0; height: ' + this.sbAvailHeightPreGrip + '">' + '<img src="http://www.cbd-alpha.com/Quest/themes/default/assets/images/scroll_bar.png" style="width: 7px; height: ' + this.sbAvailHeightPreGrip + 'px"></div>' +
				'<img id="btnScrollUp' + this.indexNumber + '" src="http://www.cbd-alpha.com/Quest/themes/default/assets/images/scroll_up.gif">' +
				'<img id="btnScrollBar' + this.indexNumber + '" src="http://www.cbd-alpha.com/Quest/themes/default/assets/images/scroll_grabber.png" height="' + this.gripHeight + 'px" width="' + this.sbWidth + 'px;" style="z-index: 3; position: absolute; ' + this.sbLeftRight + ': 0px; top: ' + this.sbButtonHeight + 'px;" >' +
				'<img id="btnScrollDown' + this.indexNumber + '" src="http://www.cbd-alpha.com/Quest/themes/default/assets/images/scroll_down.gif" style="position: absolute; left: 0px; bottom: 0px;"></div>' +
				'<div style="z-index: 10; position: absolute; bottom: 0px; ' + this.sbLeftRightOpposite + ': 0px; width: ' + this.tmpRealWidth + 'px; height: 20px;" class="icon_content_fade">&nbsp;</div>';
				
		
			//$("div.stylebar").after(this.scrollBar);
			this.sc.after(this.scrollBar);
			
			this.sb = $('#btnScrollBar' + this.indexNumber);

			this.sbg = $("#btnScrollBg" + this.indexNumber);
			
			//this is needed in absolute position
			this.sbgOffsetTop = this.sbg.offset().top;
			// the initial top of the gripper
			this.sbTop = this.sb.position().top; // in relative x/y
			
			/**
			 * Give us a place to store our last
			 * gripperTop, so we can calculate a
			 * real offset when dragging.
			 * 
			 * starts the same as sbTop
			 */
			this.gripLastTop = this.sbTop;
					
			// in pageX/Y
			this.absGripperTopConstrain = this.sbgOffsetTop + this.sbButtonHeight;
			this.absGripperBotConstrain = this.sbgOffsetTop + this.tmpContainerHeight - this.sbButtonHeight - this.gripHeight; //- this.sbButtonHeight; // * 2; // - sbgTop - gripHeight ;
			
			
			/*
			sseStatus.update('scc Top - CALLLED this.tmpContainerTop', this.tmpContainerTop);
			//sseStatus.update('scrollAmount', scrollAmount);
			//sseStatus.update('numberOfScrolls', numberOfScrolls);
			//sseStatus.update('scaledNumberOfScrolls', scaledNumberOfScrolls);
			sseStatus.update('tmpContainerHeight', tmpContainerHeight);
			sseStatus.update('this.tmpRealHeight', this.tmpRealHeight);
			sseStatus.update('this.tmpRealTop', this.tmpRealTop);
			sseStatus.update('scalingFactor', scalingFactor);
			sseStatus.update('cScalingFactor', cScalingFactor);
			sseStatus.update('gripLowestTop', gripLowestTop);
			sseStatus.update('sbAvailHeight', sbAvailHeight);
			sseStatus.update('gripHeight', gripHeight);
			sseStatus.update('sbgOffsetTop', sbgOffsetTop);
			sseStatus.update('absGripperTopConstrain', absGripperTopConstrain);
			sseStatus.update('absGripperBotConstrain (grip bottom)', absGripperBotConstrain);
			sseStatus.update('sbHeightScale', sbHeightScale);
			sseStatus.update('percentageJump', percentageJump);
			sseStatus.update('gripJump', gripJump);
			 */
		} // end scroll check if



		/**
		 * for event delegation, we'll set the currently active scroll bar on hover
		 */
		
		//$(el).hover(
		//this.tc.hover(
		//$(containerEl).hover(
		$('#' + scrollContainerEl).hover(
			
			function(){
					
				//alert('over : ' + $(el).attr('id') );
				
				currentScroller = numbersOnly( $(this).attr('id') ); //containerEl; //self.tc; //el; //this.divName;
				
			},
			
			function(){
				
				currentScroller = ''; // this could be set to the default scroller here to make the whole page active
				
			}
		);





		
		/**
		 * 
		 * 
		 * 
		 * 
		 * Event Handlers
		 * 
		 * 
		 * 
		 * 
		 */

		
		var self = this; //sick that 'var' is the key here!!!!

		
		
		
		/**
		 * Initiate up button click scroll action
		 * 
		 */
		$("#btnScrollUp" + this.indexNumber).click(function(e){
			
			self.goUp(e, self.keyDelta);
			
			return false; // prevent the scrollBg click event from firing
			
		});
		
		
		
		
		/**
		 * Initiate down button click scroll action
		 * 
		 */
		$("#btnScrollDown" + this.indexNumber).click(function(e){
			
			self.goDown(e, -self.keyDelta);
			
			return false;
			
		});
		
		
		
		
		/**
		 * Scroll BG Click
		 * 
		 */
		$("#btnScrollBg" + this.indexNumber).click(function(e){
			
			self.clickCoord = e.pageY;
			
			self.absGripNewTop = self.clickCoord - self.gripAbsMiddle;
			
			// sanity check
			if (self.absGripNewTop < self.absGripperTopConstrain){
				
				self.absGripNewTop = self.absGripperTopConstrain;
				
			}
			
			else if (self.absGripNewTop > self.absGripperBotConstrain){
				
				self.absGripNewTop = self.absGripperBotConstrain;
			
			}
			
			else {
				
				//
				
			}
		
			self.gripNewTop = self.absGripNewTop - self.sbgOffsetTop;
		
			self.gripNewPercent = ((self.gripNewTop - self.sbButtonHeight) / self.sbAvailHeight);
			
			self.sb.css({"top" : self.gripNewTop});
			
			self.scTo = Math.round(self.cLowestTop * self.gripNewPercent);
		
			self.sc.animate ({ "top": self.scTo}, {queue: true, duration: 1000, easing: 'easeOutCubic'}); //, "fast"); //easeOutCirc
			
			/**
			 * Reset self here for calculating 
			 * delta next time
			 */
			self.gripLastTop = self.sb.position().top;
			
		});	
		
		
		
		
		
		
		
		/**
		 * Initiate drag on the bsb
		 * 
		 */
		//sseStatus.html(absGripperTopConstrain);
		
		// don't load this unless we're scrolling!
		if (this.shouldScroll){
			
			this.sb.draggable({ 
				
				axis: 'y',
				
				containment: [null, self.absGripperTopConstrain, null, self.absGripperBotConstrain],
				
				// Mouse move distance before drag start officially begins.
				// We'll handle that thank you very much! 
				// Not setting this here (it defaults at 1) was causing all kinds of math problems
				distance: 0, 
				
				start: function(){
					
					//sbCounter = 0;
				},
				
				drag: function(){
					
					/**
					 * Fix dragging up
					 */
					if (self.gripLastTop - self.sb.position().top < 0){
						
						// dragging down
						self.sbDelta = self.gripLastTop - self.sb.position().top;
					
					}
					
					else if (self.gripLastTop - self.sb.position().top > 0){
						
						// dragging up
						self.sbDelta = self.gripLastTop + self.sb.position().top;
						
					}
					
					else {
						
						// drag @ 0
						self.sbDelta = 0;
						
					}
					
					self.gripNewPercent = ((self.sb.position().top - self.sbButtonHeight) / self.sbAvailHeight);
			
					self.scTo = Math.round(self.cLowestTop * self.gripNewPercent);
					
					self.sc.stop(true, true);
			
					self.sc.animate ({ "top": self.scTo }, {queue: true, duration: 1000, easing: 'easeOutCubic'});
					
				},
				
				stop: function(){
					
					self.gripLastTop = self.sb.position().top;
			
				}
				
				
			});
		
		}
		



		/**
		 * Initiate Mousewheel Scroll Action
		 * 
		 * @param {Object} event
		 * @param {Object} delta
		 */
		this.scc.mousewheel(function(event, delta) {

				// up wheel, scrolling info down
				if (delta > 0){
					
					//standardize browsers
					//delta = 1;
					delta = delta * self.deltaMultiplier;
					
					self.goUp(event, delta);

				}
				
				// down wheel, scrolling info up
				else if (delta < 0){
					
					//standardize browsers
					//delta = -1;
					delta = delta * self.deltaMultiplier;
					
					self.goDown(event, delta);
			
				}
				
				return self.bubbleScroll();
		
			});

		

			






	}; // end sseScroll	










		
		



		
	/**
	 * Scroll Up (info down)
	 * 
	 * 
	 */
	sseScroll.prototype.goUp = function(event, delta){
		
		// If this is in the main routine like before, 
		// the return false's will stop the ani at the top and bottom abruptly
		// -UPDATE:
		// However, when it is run in the 'if' clauses, if the queue builds
		// up beyond the constraints, it will 'bounce' past, then into position.
		this.sc.stop(true, true); 
		
		this.newContentTop = this.sc.position().top + delta * this.scrollAmount;
		//console.log(this.newContentTop);
		
		// prevent overflow off the bottom
		if ( (this.shouldScroll) && (this.newContentTop < '0') ){

			this.scTo = this.sc.position().top + (delta * this.scrollAmount);

			this.gripTo = Math.floor( this.sbAvailHeight * (this.scTo / this.cLowestTop) );

			this.newGripTop = this.gripTo + this.sbButtonHeight;
			
			/**
			 * Update the gripper
			 */
			this.sb.css({"top" : this.newGripTop + 'px'});

			/**
			 * Update the content
			 */
			this.sc.animate ({ "top": this.scTo}, {queue: true, duration: 1000, easing: 'easeOutCubic'}); //, "fast"); //easeOutCirc

		}

		// if we will be beyond the bottom on the next click, send us to the bottom
		else if (this.sc.position().top < 0){
			
			this.sb.css({"top" : this.sbButtonHeight});
			
			this.scTo = '0';
			
			this.sc.animate ({ "top": this.scTo}, {queue: true, duration: 1000, easing: 'easeOutCubic'}); //, "fast"); //easeOutCirc

		}
		
		else {
			// we're done
			return false;
		}
		
	}






	/**
	 * Scroll Down (info up)
	 * 
	 *
	 * 
	 * @param event
	 * @param delta A negative offset given by the mousewheel event
	 */
	sseScroll.prototype.goDown = function(event, delta){

		this.sc.stop(true, true); 
		
		this.newContentTop = this.sc.position().top + delta * this.scrollAmount;
		//console.log(this.newContentTop);

		// prevent overflow off the bottom
		if ( (this.shouldScroll) && (this.newContentTop > this.cLowestTop) ){

			this.scTo = this.sc.position().top + (delta * this.scrollAmount);

			this.gripTo = Math.floor( this.sbAvailHeight * (this.scTo / this.cLowestTop) );

			this.newGripTop = this.gripTo + this.sbButtonHeight;
			
			/**
			 * Update the gripper
			 */
			this.sb.css({"top" : this.newGripTop + 'px'});

			/**
			 * Update the content
			 */
			this.sc.animate ({ "top": this.scTo}, {queue: true, duration: 1000, easing: 'easeOutCubic'}); //, "fast"); //easeOutCirc

		}

		// if we will be beyond the bottom on the next click, send us to the bottom
		else if (this.sc.position().top > this.cLowestTop){
			
			this.sb.css({"top" : this.gripLowestTop});
			
			this.scTo = this.cLowestTop;
			
			this.sc.animate ({ "top": this.scTo}, {queue: true, duration: 1000, easing: 'easeOutCubic'}); //, "fast"); //easeOutCirc

		}
		
		else {
			// we're done
			return false;
		}

				
	}








	/**
	 * Prevent the scroll wheel from bubbling
	 * 
	 * 
	 * TODO
	 * -Once we've reached the bottom of our content,
	 * the page should resume scrolling normally
	 */
	sseScroll.prototype.bubbleScroll = function(){
		
		if (this.shouldScroll){
			
			return false; // we'll control the scrolling behavior, so we prevent the default event action of entire page scrolling

		}
		
	}




		












	/*
	// instantiate a scroll bar
	// do it here, so global event functions which call this var can use it 
	var curScroll = new sseScroll();



	//global count of number of scrollbars
	var sseScrollNum = 0;

	$(".scrollable").each(function(){
		// add a new sseScroll object
		
		++sseScrollNum;
	});

	$(".scrollablePrimary").each(function(){
		// add a new sseScroll object
		
		++sseScrollNum;
	});

	$(".scrollableLeft").each(function(){
		// add a new sseScroll object
		
		++sseScrollNum;
	});
	*/





	/**
	 * !Global
	 * 
	 * Setup
	 * 
	 */
	setupScroll = function(el, leftRight){
		
		el.style.overflow = 'hidden'; //done in the object
		
		var oldHtml = $(el).html();
		
		var parentHeight = $(el).innerHeight();
		
		var parentWidth = $(el).width();
		
		var newScrollId = 'stylebarContainer' + sseScrollNum;
		
		var newSubScrollId = 'stylebar' + sseScrollNum;
		
		var newHtml = '<div style="width:' + parentWidth + 'px; height:' + parentHeight + 'px;" id="' + newScrollId + '">' + 
						'<div id="' + newSubScrollId + '">' + oldHtml + '</div></div>';
		
		$(el).html(newHtml);
		
		
		//var newEl = $(curScroll); // not sure why this doesn't work	
		
		//var scrollEl = document.getElementById(newScrollId);
		var scrollEl = newScrollId;
		
		//var scrollSubEl = document.getElementById(newSubScrollId);
		var scrollSubEl = newSubScrollId;
		
		
		scrollObjs[sseScrollNum] = new sseScroll(el, scrollEl, scrollSubEl, leftRight, sseScrollNum); //(scrollEl);
		
		//scrollObjs[sseScrollNum].sbLeftRight = leftRight;
		
		//scrollObjs[sseScrollNum].indexNumber = sseScrollNum;
		
		//alert(scrollObjs[sseScrollNum].sbLeftRight);
		
		
		++sseScrollNum;
		
	}









	/**
	 * !Global
	 * 
	 * Auto find scrollable divs 
	 * 
	 * User Note :
	 * - if you don't need to auto default to one scroll bar, you don't need to use the primary class
	 */
	// primary gets setup first so it gets numbered first (in case we want to default to it)
	$("div.scrollablePrimary").each(function(){
		setupScroll(this, 'right');
	});

	$("div.scrollablePrimaryLeft").each(function(){
		setupScroll(this, 'left');
	});

	$("div.scrollable").each(function(){
		setupScroll(this, 'right');
	});

	$("div.scrollableLeft").each(function(){
		setupScroll(this, 'left');
	});







		
		



	/**
	 * 
	 * 
	 * 
	 * 
	 * 
	 * Global events
	 * Events that will need to be redefined based on which scroll area is active.
	 * 
	 * 
	 * 
	 * 
	 * 
	 */



		

		
		/**
		 * !Global
		 * 
		 * Initiate keyboard bindings
		 * 
		 * 40 = down arrow, 38 = up
		 * 
		 */
		$(document).keydown(function(e){
			
			if (e.which == 40){
				
				if (sseScrollNum > 0 && currentScroller != ''){
					
					//curScroll.goDown(e, -curScroll.keyDelta);
					
					
					//$(currentScroller).html("down"); // FIXME check that current div != '' first
					
					//var currentActive = $(currentScroller).attr('id');
					//var currentActive = currentScroller.attr('id');
					
					//alert(currentScroller);
					//alert(currentActive);
					
					//alert(numbersOnly('thisissomething42'));
					//alert(numbersOnly(currentScroller));
					
					
					//var currentNum = numbersOnly(currentActive);
					//var currentNum = numbersOnly(currentScroller);
					//alert(currentNum);
					
					//scrollObjs[currentNum].goDown(e, -scrollObjs[currentNum].keyDelta);
					scrollObjs[currentScroller].goDown(e, -scrollObjs[currentScroller].keyDelta);
					
					return false;
					
				}
				
				else{
					
					//use scrollable0 if it exists? -- as a default?
					
					return true;
					
				}
				
			}
			
			else if (e.which == 38){
				
				if (sseScrollNum > 0 && currentScroller != ''){
					
					//curScroll.goUp(e, curScroll.keyDelta);
					
					
					//$(currentScroller).html("up"); // FIXME check that current div != '' first
					
					
					//var currentActive = $(currentScroller).attr('id');
					
					//var currentNum = numbersOnly(currentActive);
					//var currentNum = numbersOnly(currentScroller);
					
					//scrollObjs[currentNum].goUp(e, scrollObjs[currentNum].keyDelta);
					scrollObjs[currentScroller].goUp(e, scrollObjs[currentScroller].keyDelta);
					
					return false;
					
				}
				
				else {
					
					return true;
				
				}
				
			}
			
			// UMM....can't TYPE anywhere inside a scrollable container when it's set to false!
			//return false; // hmm..this will disable the default behavior - bind to the mouseover event for the container only?
			return true;
			
		});
		
		
		







	/**
	 * 
	 * 
	 * 
	 * END  of sseScroll Functions
	 * 
	 * 
	 * 
	 * 
	 */



		
		
		
	/**
	 * 
	 * 
	 * 
	 * BEGIN Auto SSE Effects/Behaviors
	 * that require images to be loaded prior to
	 * their being loaded
	 * 
	 * 
	 * 
	 */
		
		
		
		
		
		/**
		 * Auto ROLL Images - roll dir (default)
		 * 
		 * PROBLEM: We have to wait for loading to see if an image
		 * is valid. This obviously slows things down. So we will separate
		 * out auto roll images which live in the same directory, and those
		 * that live in a /roll subdirectory with the same filename into
		 * two different behaviors.
		 * 
		 * This will be the default, as it encourages better
		 * practices - a seperate directory for rollover images
		 * as well as making it easier to make a gallery of a certain
		 * directory
		 * 
		 * FIXME None of these work if there is a period in the name (like an IP address!) - maybe break on the last period only?
		 * 
		 */
		var oldSrc; // this is a dirty global FIXME
		
		$('.auto_roll').hover(
			
			function(){

				var curImg = $(this).attr("src");
				
				oldSrc = curImg;
				
				// check in both a subdirectory named 'roll' for
				// a file of the same name, and in the current directory
				// for a file with the same name plus 'ROLL' prior to the 
				// extension
				
				var imgSplit, newImage;
				
				//curImg = curImg.replace(/\.[png|jpg|jpeg|gif]*/gi, 'REPLACED'); // WORKS - REPLACES EXTENSION
				
				imgSplit = curImg.match(/\/+[A-Za-z0-9_-]*\.[png|jpg|jpeg|gif]*/gi); // WORKS - REPLACES THE IMAGE NAME AND EXT 
				
				curPath = curImg.replace(/\/+[A-Za-z0-9_-]*\.[png|jpg|jpeg|gif]*/gi, ''); // No trailing slash
				
				imgSplit = imgSplit[0].replace("/", "");
				
				newImage = new Image(); 
				
				newImage.src = curPath + '/' + imgSplit;
							
				// look in the roll sub dir with same name as orig, if the original wasn't loaded
					
				newImage.src = curPath + '/roll/' + imgSplit;

				// must not have a rollover image
				//if (!(newImage.width > 1) ){
				//	return false; // will this get us out? - nope
				//}
				
				//alert(newImage.src);	//curPath); //newImage.src);
				//console.log('roll dir: ' + newImage.src);
				//console.log('roll dir: ' + newImage.naturalWidth);
				//console.log('roll dir: ' + newImage.complete);
				
				$(this).attr("src", newImage.src);
				
				

			},
			
			function(){
				
				$(this).attr("src", oldSrc);
				
			}
			
		);



		
		/**
		 * Auto Roll Images - from the same directory with ROLL.ext
		 * as file name
		 * 
		 * FIXME None of these work if there is a period in the name (like an IP address!)
		 * 
		 */
		var oldSrcSame; // this is a dirty global FIXME
		
		$('.auto_roll_samedir').hover(
			
			function(){

				var curImg = $(this).attr("src");
				
				oldSrcSame = curImg;
				
				// check in both a subdirectory named 'roll' for
				// a file of the same name, and in the current directory
				// for a file with the same name plus 'ROLL' prior to the 
				// extension
				
				var imgSplit, newImage;
				
				//curImg = curImg.replace(/\.[png|jpg|jpeg|gif]*/gi, 'REPLACED'); // WORKS - REPLACES EXTENSION
				
				imgSplit = curImg.match(/\/+[A-Za-z0-9_-]*\.[png|jpg|jpeg|gif]*/gi); // WORKS - REPLACES THE IMAGE NAME AND EXT 
				
				curPath = curImg.replace(/\/+[A-Za-z0-9_-]*\.[png|jpg|jpeg|gif]*/gi, ''); // No trailing slash
				
				if($.browser.msie && $.browser.version.substr(0,1)<8){
					/**
					 * IE7 fixes
					 */
					curPath = curPath.replace("http:", "http:" + imgSplit[0]);
					
					//Old line, followed by new (for IE7 only)
					//imgSplit = imgSplit[0].replace("/", "");
					imgSplit = imgSplit[1].replace("/", "");
					
					/**
					 * END IE7 fixes
					 */
				}
				
				else {
					
					// Everyone who's not IE7
					imgSplit = imgSplit[0].replace("/", "");
					
				}
				
				imgSplit = imgSplit.replace(".", "ROLL.");
				
				
				newImage = new Image(); 
				
				newImage.src = curPath + '/' + imgSplit;
				
				//console.log(newImage.src);
				//console.log(newImage.naturalWidth);
				//console.log(newImage.complete);
				
				$(this).attr("src", newImage.src);
				
				

			},
			
			function(){
				
				$(this).attr("src", oldSrcSame);
				
			}
			
		);	
		
		

		
		
		/**
		 * Auto Roll All Images in a container - from the same 
		 * directory with ROLL.ext as file name
		 * 
		 * FIXME None of these work if there is a period in the name (like an IP address!)
		 * 
		 */
		var oldSrcSameAll = new Array(); // this is a dirty global FIXME
		
		$('.auto_roll_samedir_all').hover(
			
			function(){
				
				// find allows us to find the element regardless of it's depth from the parent
				$(this).find('img').each(function(i){
					
					var curImg = $(this).attr("src");
					
					oldSrcSameAll[i] = curImg;
					
					// check in both a subdirectory named 'roll' for
					// a file of the same name, and in the current directory
					// for a file with the same name plus 'ROLL' prior to the 
					// extension
					
					var imgSplit, newImage;
					
					//curImg = curImg.replace(/\.[png|jpg|jpeg|gif]*/gi, 'REPLACED'); // WORKS - REPLACES EXTENSION
					
					imgSplit = curImg.match(/\/+[A-Za-z0-9_-]*\.[png|jpg|jpeg|gif]*/gi); // WORKS - REPLACES THE IMAGE NAME AND EXT 
					
					curPath = curImg.replace(/\/+[A-Za-z0-9_-]*\.[png|jpg|jpeg|gif]*/gi, ''); // No trailing slash
					
					
					
					
					if($.browser.msie && $.browser.version.substr(0,1)<8){
						/**
						 * IE7 fixes
						 */
						curPath = curPath.replace("http:", "http:" + imgSplit[0]);
						
						//Old line, followed by new (for IE7 only)
						//imgSplit = imgSplit[0].replace("/", "");
						imgSplit = imgSplit[1].replace("/", "");
						
						/**
						 * END IE7 fixes
						 */
					}
					
					else {
						
						// Everyone who's not IE7
						imgSplit = imgSplit[0].replace("/", "");
						
					}
					
					
					imgSplit = imgSplit.replace(".", "ROLL.");
					
					
					newImage = new Image(); 
					
					newImage.src = curPath + '/' + imgSplit;
					
					//console.log(newImage.src);
					//console.log(newImage.naturalWidth);
					//console.log(newImage.complete);
					
					$(this).attr("src", newImage.src);
					
				})

			},
			
			function(){

				$(this).find('img').each(function(i){
				
					$(this).attr("src", oldSrcSameAll[i]);
				
				})
				
			}
			
		);		
		
		

		
		
		
		/**
		 * Auto Roll All Images in a container - from a 
		 * directory named /roll/ with same filename
		 * 
		 * 
		 * FIXME None of these work if there is a period in the name (like an IP address!)
		 * 
		 */
		var oldSrcAll = new Array(); // this is a dirty global FIXME
		
		$('.auto_roll_all').hover(
			
			function(){
				
				// find allows us to find the element regardless of it's depth from the parent
				$(this).find('img').each(function(i){
					
					var curImg = $(this).attr("src");
					
					oldSrcAll[i] = curImg;
					
					// check in both a subdirectory named 'roll' for
					// a file of the same name, and in the current directory
					// for a file with the same name plus 'ROLL' prior to the 
					// extension
					
					var imgSplit, newImage;
					
					imgSplit = curImg.match(/\/+[A-Za-z0-9_-]*\.[png|jpg|jpeg|gif]*/gi); // WORKS - REPLACES THE IMAGE NAME AND EXT 
					
					curPath = curImg.replace(/\/+[A-Za-z0-9_-]*\.[png|jpg|jpeg|gif]*/gi, ''); // No trailing slash
					
					if($.browser.msie && $.browser.version.substr(0,1)<8){
						/**
						 * IE7 fixes
						 */
						curPath = curPath.replace("http:", "http:" + imgSplit[0]);
						
						//Old line, followed by new (for IE7 only)
						//imgSplit = imgSplit[0].replace("/", "");
						imgSplit = imgSplit[1].replace("/", "");
						
						/**
						 * END IE7 fixes
						 */
					}
					
					else {
						
						// Everyone who's not IE7
						imgSplit = imgSplit[0].replace("/", "");
						
					}
					
					newImage = new Image(); 
					
					newImage.src = curPath + '/' + imgSplit;
								
					// look in the roll sub dir with same name as orig, if the original wasn't loaded
						
					newImage.src = curPath + '/roll/' + imgSplit;

					
					//console.log(newImage.src);
					//console.log(newImage.naturalWidth);
					//console.log(newImage.complete);
					
					$(this).attr("src", newImage.src);
					
				})

			},
			
			function(){

				$(this).find('img').each(function(i){
				
					$(this).attr("src", oldSrcAll[i]);
				
				})
				
			}
			
		);			
		
		

		
		

		
		/**
		 * Auto Roll CSS Images - from the same directory with ROLL.ext
		 * as file name
		 * 
		 */
		var oldSrcCssSame; // this is a dirty global FIXME
		//$('.auto_roll_css_samedir').css({'backgroundColor', 'blue'});
		//$('.auto_roll_css_samedir').css( { "background-image" : "url('" } );
		//$('div.auto_roll_css_samedir').addClass('icon_callout_lgROLL');
		
		//$('div.auto_roll_css_samedir').hover(
		// This won't always be in a div (in an 'a' on quicklinks)...so ....
		$('.auto_roll_css_samedir').hover(
			
			function(){

				var curImg = $(this).css("background-image");
				
				oldSrcCssSame = curImg;
				//alert(oldSrcCssSame);

				//alert(curImg);
				
				// get rid of quotes and url
				var curImg = curImg.replace(/"/g,"");
				var curImg = curImg.replace(/url\(|\)$/ig, "");
				
				//alert(curImg);
				
				// check in both a subdirectory named 'roll' for
				// a file of the same name, and in the current directory
				// for a file with the same name plus 'ROLL' prior to the 
				// extension
				

				////curImg = curImg.replace(/\.[png|jpg|jpeg|gif]*/gi, 'REPLACED'); // WORKS - REPLACES EXTENSION
				
				/**
				 * Since there are obvious browser differences in implementation
				 * of Regexes, and we only need to change the stuff right before the extension
				 * here, we will simplify
				 */
				//var imgSplit, newImage;

				// these both need a dot in the options to make sure they also match on an ip address
				//imgSplit = curImg.match(/(\/)+([A-Za-z0-9_-])*(\.[png|jpg|jpeg|gif])*/gi); // WORKS - REPLACES THE IMAGE NAME AND EXT 
				//curPath = curImg.replace(/(\/)+([A-Za-z0-9_-])*(\.[png|jpg|jpeg|gif])*/gi, ''); // No trailing slash
				
				//alert(curPath);
				
				//imgSplit = imgSplit[0].replace("/", "");
				
				//imgSplit = imgSplit.replace(".", "ROLL.");
				
				
				
				newImage = new Image(); 
				
				//newImage.src = curPath + '/' + imgSplit;
				
				var extRegex = /\.([png|jpg|jpeg|gif]*)$/gi;
				newImage.src = curImg.replace(extRegex, 'ROLL.$1');
				
				var newCssImage = 'url(' + newImage.src + ')';
				
				//alert(newCssImage);
				
				$(this).css("background-image", newCssImage );
				

			},
			
			function(){
				
				//$(this).css("background-image", 'url(' + oldSrcSame + ')' );
				$(this).css("background-image", oldSrcCssSame);
				
			}
			
		);			
	
				
				
				
				

		//alert('is window load still attached?');
				
				
		


//}); // end document.ready
}; // end window.onload








/**
 * Automatically load sub page callouts
 * 
 * This can not live inside any document ready
 * or window onload type function
 */
function autoLoadCallout(pageName){
	
	var pageClass = pageName.toLowerCase();
	
	var pageName = pageClass.replace(/ /g, "_");
	
	pageClass = pageName + "_callout";

	
	var currentCallout = $('.' + pageClass); //.css({"backgroundColor" : "#fff"});
	
	// change the arrow
	currentCallout
		.removeClass("auto_roll_css_samedir icon_callout_lg sseTooltip")
		.addClass("icon_large_arrow_rROLL")
		.unbind();
	
	var currentPos = currentCallout.offset();
	var currentWidth = currentCallout.width();
	var tipTop = currentPos.top; // + 1;// + 28;
	var tipLeft = currentPos.left; // + currentWidth + 14;
	var tipText = currentCallout.attr('rel');
	$(document.body).append('<div class="callout_active" style="left: ' + tipLeft + 'px; top: ' + tipTop + 'px;">' + tipText + '</div>');
	//var calloutWidth = $('.callout').css('width');
	//$('.callout').css( { opacity: '0.0', width: '0px', visibility: 'visible' } );
	$('.callout_active').css( { opacity: '0.0', 'clip': 'rect(0px, 0px, 50px, 0px)', visibility: 'visible' } );
	//$('.callout').animate( {opacity: '.7', width: calloutWidth}, 800 );
	$('.callout_active').animate( {opacity: '.75', 'clip': 'rect(0px, 250px, 50px, 0px)' }, 900 );
	
	
	/**
	 * Load up and animate the feature overlay
	 * 
	 */
	 $('#' + pageName)
	 	//.removeClass("feature_overlay")
		.css( { opacity: '0.0', visibility: 'visible' } )
		.animate( {opacity: '1.0' }, 900 );
}












