{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf430
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\paperw11900\paperh16840\margl1440\margr1440\vieww9000\viewh8400\viewkind0
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural

\f0\fs24 \cf0 /* \
next step. want the object to create it's own scrollbars and position them correctly. also want object to resize the scrollbars\
to accomodate width of container.\
*/\
\
/* ScrollingDiv 0.1\
* by Peter Swan - pdswan-at-gmail.com\
* Liscensed under Creative Commons: http://creativecommons.org/licenses/by-nc-sa/3.0/\
* Please include original header in derivative work\
*\
* The ScrollingDiv class uses the prototype (http://prototypejs.org/) and scriptaculous (http://script.aculo.us/) \
* libraries to create cross browser custom scrollbars for div elements.\
*\
* Setting overflow: auto or overflow: scroll on the parent element will give default OS\
* scrollbars in the case that javascript is not enabled.\
*\
* ScrollingDiv( <element to scroll>, <parent element>, <clip width>, <clip height>, <vertical scrollbar>, <horizontal scrollbar>)\
*	- instantiates new scrolling div element.\
*	- element to scroll will scroll within the parent element with using clip width and clip height to create the\
*	  clipping window (defaults to parentElement.width, parentElement.height)\
*\
* ScrollingDiv.bindButtons( <up button element>, <down button element>, <left button element>, <right button element>, delta)\
*	- on click of <up button element <element to scroll> will scroll up by delta = \{x | 0 <= x <= 1\}\
*\
* ScrollingDiv.resetContentDim()\
*	- can theoretically be used to reset the width and height of the scrolling element in the case of an asynchronous\
*	  update to the content.\
*\
* This class has been tested on the following browsers:\
* Firefox 2.0.0.3 (PC)\
* Opera 8.54\
* IE 6.0.2900\
* Safari\
* Firefox\
*/\
\
var DEBUG = 1;\
function debugMessage(msg)\{\
	if( DEBUG && window.console)\{\
		console.log(msg);\
	\}\
\}\
\
/* This is a small extension to the Control.Slider to allow for it to support and correctly treat\
   tracks and handles with percentage based width/heights. */\
Control.PercentageSlider = Class.create( Control.Slider, \{\
		initialize: function( $super, handle, track, options)\{\
			$super( handle, track, options);\
			debugMessage('init: ' + this.maximumOffset() + ', ' + this.minimumOffset() + ', ' + $(track).offsetWidth);\
			Event.observe( window, 'resize', this.onResize.bind(this));\
		\},\
		\
		onResize: function(e)\{\
			debugMessage('caught Slider resize event!' + this.maximumOffset() + ', ' + this.minimumOffset());\
			this.trackLength = this.maximumOffset() - this.minimumOffset();\
\
			this.handleLength = this.isVertical() ? \
			(this.handles[0].offsetHeight != 0 ? \
				this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) : \
			(this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth : \
				this.handles[0].style.width.replace(/px$/,""));\
			\
			this.handles.each( function(h, i)\{\
					this.setValue( this.values[i], i);\
			\}.bind(this));\
		\}\
\});\
\
var ScrollingDiv = Class.create();\
ScrollingDiv.prototype = \{\
	initialize: function( e, vs, hs)\{\
		this.scrollElement = $(e);\
		this.hs = hs;\
		this.vs = vs;\
		\
		this.ubtn = null;\
		this.dbtn = null;\
		this.lbtn = null;\
		this.rbtn = null;\
		this.delta = 0;\
		\
		// Get content width and height\
		this.resetContentDim();\
		this.scrollElement.scrollLeft = this.scrollElement.scrollTop = 0;\
		Event.observe(window, 'resize', function()\{\
				debugMessage('caught resize event!');\
				this.resetContentDim();\
		\}.bind(this));\
		\
		/* If there is a horizontal scrollbar set up\
		onslide and onchange functions\
		*/\
		if( this.hs )\{\
			this.hs = hs;\
			this.hs.options.onChange = this.hs.options.onSlide = this.scrollHorizontal.bind(this);\
		\}\
		\
		if( this.vs )\{\
			this.vs = vs\
			this.vs.options.onChange = this.vs.options.onSlide = this.scrollVertical.bind(this);\
		\}\
		\
		/* Functions to manage a periodical executer that\
		manages up/down/left/right button functionality\
		*/\
		this.startUp = function()\{\
			this.stop();\
			this.vs.setValueBy(-this.delta);\
			this.btnPe = new PeriodicalExecuter(\
				function()\{\
					this.vs.setValueBy(-this.delta);\
				\}.bind(this), 0.1);\
		\};\
		this.startDown = function()\{\
			this.stop();\
			this.vs.setValueBy(this.delta);\
			this.btnPe = new PeriodicalExecuter(\
				function()\{\
					this.vs.setValueBy(this.delta);\
				\}.bind(this), 0.1);\
		\};\
		this.startLeft = function()\{\
			this.stop();\
			this.hs.setValueBy(-this.delta);\
			this.btnPe = new PeriodicalExecuter(\
				function()\{\
					this.hs.setValueBy(-this.delta);\
				\}.bind(this), 0.1);\
		\};\
		this.startRight = function()\{\
			this.stop();\
			this.hs.setValueBy(this.delta);\
			this.btnPe = new PeriodicalExecuter(\
				function()\{\
					this.hs.setValueBy(this.delta);\
				\}.bind(this), 0.1);\
		\};\
		this.stop = function()\{\
			if( this.btnPe )\{\
				this.btnPe.stop();\
				delete this.btnPe;\
			\}\
		\};\
	\},\
	\
	scrollHorizontal: function(v)\{\
		/*var left = Math.round((v / this.hs.maximum) * (this.clipWidth - this.contentWidth));\
		this.scrollElement.setStyle(\{left: left + 'px'\});*/\
		var left = Math.round((v / this.hs.maximum) * -(this.clipWidth - this.contentWidth));\
		this.scrollElement.scrollLeft = left;\
	\},\
	\
	scrollVertical: function(v)\{\
		/*var top = Math.round((v / this.vs.maximum) * (this.clipHeight - this.contentHeight));\
		this.scrollElement.setStyle(\{top: top + 'px'\});*/\
		var top = Math.round((v / this.vs.maximum) * -(this.clipHeight - this.contentHeight));\
		this.scrollElement.scrollTop = top;\
	\},\
	\
	/* Get dimensions of content element, if dimensions are less than\
	the clipping dimensions, disable the scrollbars */\
	resetContentDim: function()\{\
		this.scrollElement.setStyle(\{'overflow': 'auto'\});\
		this.contentWidth = this.scrollElement.scrollWidth;\
		this.contentHeight = this.scrollElement.scrollHeight;\
		this.scrollElement.setStyle(\{'overflow': 'hidden'\});\
		this.clipWidth = this.scrollElement.getWidth();\
		this.clipHeight = this.scrollElement.getHeight();\
		\
		debugMessage('clip dimensions: ' + this.clipWidth + ', ' + this.clipHeight);\
		debugMessage('content dimensions: ' + this.contentWidth + ', ' + this.contentHeight);\
		\
		if( this.vs )\{\
			if( this.contentHeight <= this.clipHeight )\{\
				this.vs.setDisabled();\
				this.vs.track.setStyle(\{visibility: 'hidden'\});\
				if( this.ubtn )\{\
					this.ubtn.setStyle(\{visibility: 'hidden'\});\
				\}\
				if( this.dbtn )\{\
					this.dbtn.setStyle(\{visibility: 'hidden'\});\
				\}\
			\}else\{\
				this.vs.setEnabled();\
				this.vs.track.setStyle(\{visibility: 'visible'\});\
				if( this.ubtn )\{\
					this.ubtn.setStyle(\{visibility: 'visible'\});\
				\}\
				if( this.dbtn )\{\
					this.dbtn.setStyle(\{visibility: 'visible'\});\
				\}\
			\}\
		\}\
		if( this.hs )\{\
			if( this.contentWidth <= this.clipWidth )\{\
				this.hs.setDisabled();\
				this.hs.track.setStyle(\{visibility: 'hidden'\});\
				if( this.lbtn )\{\
					this.lbtn.setStyle(\{visibility: 'hidden'\});\
				\}\
				if( this.rbtn )\{\
					this.rbtn.setStyle(\{visibility: 'hidden'\});\
				\}\
			\}else\{\
				this.hs.setEnabled();\
				this.hs.track.setStyle(\{visibility: 'visible'\});\
				if( this.lbtn )\{\
					this.lbtn.setStyle(\{visibility: 'visible'\});\
				\}\
				if( this.rbtn )\{\
					this.rbtn.setStyle(\{visibility: 'visible'\});\
				\}\
			\}\
		\}\
	\},\
	\
	/* Takes elements that will act as up/down/left/right buttons as well\
	as a delta value which controls rate of scrolling */\
	bindButtons: function( ubtn, dbtn, lbtn, rbtn, delta)\{\
		this.ubtn = $(ubtn);\
		this.dbtn = $(dbtn);\
		this.lbtn = $(lbtn);\
		this.rbtn = $(rbtn);\
		this.delta = delta;\
		\
		if( this.ubtn )\{\
			if( this.vs )\{\
				Event.observe( this.ubtn, 'mousedown', this.startUp.bind(this));\
				Event.observe( this.ubtn, 'mouseout', this.stop.bind(this));\
				Event.observe( document, 'mouseup', this.stop.bind(this));\
			\}\
		\}\
		if( this.dbtn )\{\
			if( this.vs )\{\
				Event.observe( this.dbtn, 'mousedown', this.startDown.bind(this));\
				Event.observe( this.dbtn, 'mouseout', this.stop.bind(this));\
				Event.observe( document, 'mouseup', this.stop.bind(this));\
			\}\
		\}\
		if( this.lbtn )\{\
			if( this.hs )\{\
				Event.observe( this.lbtn, 'mousedown', this.startLeft.bind(this));\
				Event.observe( this.lbtn, 'mouseout', this.stop.bind(this));\
				Event.observe( document, 'mouseup', this.stop.bind(this));\
			\}\
		\}\
		if( this.rbtn )\{\
			if( this.hs )\{\
				Event.observe( this.rbtn, 'mousedown', this.startRight.bind(this));\
				Event.observe( this.rbtn, 'mouseout', this.stop.bind(this));\
				Event.observe( document, 'mouseup', this.stop.bind(this));\
			\}\
		\}\
		this.resetContentDim();\
	\}\
\};\
\
function createScrollingDiv( elm )\{\
	elm = $(elm);\
	if( elm )\{\
		debugMessage('elm: ' + elm.inspect());\
		var content = elm.down('.content');\
		if( content )\{\
			debugMessage('content: ' + content.inspect());\
			var vs_contain = elm.down('.vertical_scroll_bar');\
			var hs_contain = elm.down('.horizontal_scroll_bar');\
			var vs_components = \{\};\
			var hs_components = \{\};\
			var vs;\
			var hs;\
			if( vs_contain )\{\
				vs_components = getScrollControls(vs_contain);\
			\}\
			if( hs_contain )\{\
				hs_components = getScrollControls(hs_contain);\
			\}\
			if( vs_components.track && vs_components.handle )\{\
				vs = new Control.PercentageSlider( vs_components.handle, vs_components.track, \{axis: 'vertical'\});\
			\}\
			if( hs_components.track && hs_components.handle )\{\
				hs = new Control.PercentageSlider( hs_components.handle, hs_components.track, \{axis: 'horizontal'\});\
			\}\
			if( (!hs && !vs))\{\
				return null;\
			\}else\{\
				var temp = new ScrollingDiv( content, vs, hs);\
				temp.bindButtons( vs_components.up_button, vs_components.down_button, hs_components.left_button, hs_components.right_button, 0.05);\
				return temp;\
			\}\
		\}else\{\
			return null;\
		\}\
	\}else\{\
		return null;\
	\}\
\}\
\
function getScrollControls( elm )\{\
	var ret = \{\
		down_button: null,\
		up_button: null,\
		right_button: null,\
		left_button: null,\
		track: null,\
		handle: null\
	\};\
	elm = $(elm);\
	if( elm )\{\
		ret.down_button = elm.down('.down_button');\
		ret.up_button = elm.down('.up_button');\
		ret.right_button = elm.down('.right_button');\
		ret.left_button = elm.down('.left_button');\
		ret.track = elm.down('.track');\
		ret.handle = elm.down('.handle');\
	\}\
	return ret;\
\}\
\
\
/* when the dom is loaded, start creating custom scrollers */\
Event.observe(document, 'dom:loaded', function()\{\
		$$('.scrolling_div').each( function( element )\{\
				createScrollingDiv(element);\
		\});\
\});\
}