// ---------------------------------------- extending prototype ---------------------------------------

/*
 ref:		Element
 note:		a prototype extended element.
 note:		Use $('xxx') syntax instead of new Element('xxx')
 returns:	Element
 type:		Class
 arg:		String|Object element
 example:	<script type="text/javascript">
			var y = $('xxx')
		</script>   
*/
Element.addMethods({
	
	/*
	 ref:		Element.animate
	 note:		Shortcut for creating and running an animation object on an extended element
	 returns:	Element
	 expando:	Element.dfNew.animate
	 delegate:	DfNew.Animate
	 type:		Method
	 arg:		Object pars
	 example:	<script type="text/javascript">
				$('xxx').animate({
					opacity: 0.5,
					height: 50
				});
			</script>
	*/
	animate: function(element,pars){
		element = $(element);
		DfNew.Namespace.create('dfNew.animate',element).animate = new DfNew.Animate(element).run(pars);	
		return element;
	},
	
	/*
	 ref:		Element.toggleAnimation
	 note:		Shortcut for creating and setting an animation object with toggle event listeners on an extended element
	 returns:	Element
	 expando:	Element.dfNew.toggleAnimation
	 delegate:	DfNew.Animate.toggleBy
	 type:		Method
	 arg:		Object pars
	 arg:		String action choices are click and hover
	 example:	<script type="text/javascript">
				$('xxx').toggleAnimation('click', {
					opacity: 0.5,
					height: 50
				});
			</script>
	*/
	toggleAnimation: function(element, action, pars){
		element = $(element);
		DfNew.Animate.toggleBy( element , action , pars )
		return element;
	},
	
	/*
	 ref:		Element.dragable
	 note:		Shortcut for creating and setting a drag object on an extended element
	 returns:	Element
	 expando:	Element.dfNew.drag
	 delegate:	DfNew.Drag
	 type:		Method
	 arg:		Object pars
	 example:	<script type="text/javascript">
				$('xxx').drag();
			</script>
	*/
	dragable: function(element,pars){
		element = $(element);
		DfNew.Namespace.create('dfNew', element).drag = new DfNew.Drag(element).set(pars);
		return element;
	},
	
	/*
	 ref:		Element.resizable
	 note:		Shortcut for creating and setting a resize object on an extended element
	 returns:	Element
	 expando:	Element.dfNew.resize
	 delegate:	DfNew.Resize
	 type:		Method
	 arg:		Object pars
	 example:	<script type="text/javascript">
				$('xxx').resize();
			</script>
	*/
	resizable: function(element,pars){
		element = $(element);
		DfNew.Namespace.create('dfNew', element).resize = new DfNew.Resize(element).set(pars);
		return element;
	},
	
	/*
	 ref:		Element.ui
	 note:		Shortcut for creating and setting a DfNew.Ui object on an extended element
	 returns:	Element
	 delegate:	DfNew.Ui
	 expando:	Element.dfNew.ui
	 type:		Method
	 arg:		Object pars
	 example:	<script type="text/javascript">
				$('xxx').ui({
					animate: {
						width: 600
					},
					drag: {}
				});
			</script>
	*/
	ui: function(element,pars){
		element = $(element);
		DfNew.Namespace.create('dfNew', element).ui = new DfNew.Ui(element).set(pars);
		return element;
	},
	
	/*
	 ref:		Element.createNS
	 note:		Shortcut for creating a namespace object
	 returns:	Object
	 delegate:	DfNew.Namespace.create
	 type:		Method
	 arg:		String namespace
	 example:	<script type="text/javascript">
				$('xxx').createNS('xxx.yyy.zzz')
			</script>
	*/
	createNS: function(element,namespace){
		return DfNew.Namespace.create(namespace,$(element));
	},
	
	/*
	 ref:		Element.center
	 note:		Centers the element relative to its parent.
	 returns:	Element
	 type:		Method
	 hint:		Element must be positioned Absolute
	 hint:		Parent must be positioned Absolute or Relative
	 example:	<script type="text/javascript">
				$('xxx').center()
			</script>
	*/
	center: function(element){
		element = $(element);
		holder = element.up()
		
		var hHeight
		var hWidth 
		if (holder == document.body) {
			hHeight = document.viewport.getHeight()/2
			hWidth = document.viewport.getWidth()/2
		}else{
			hHeight = holder.getHeight()/2
			hWidth = holder.getWidth()/2
		}
		
		element.style.left = hWidth-(element.getWidth()/2) + 'px'
		element.style.top = hHeight-(element.getHeight()/2) + 'px'
		
		return element
	}
});

/*
 ref:		String
 returns:	String
 type:		Class
 arg:		String string
*/			  
Object.extend(String.prototype,{
	
	/*
	 ref:		String.uId
	 note:		Created a Unique string based on a timestamp and random number
	 returns:	String
	 type:		Method
	 example:	<script type="text/javascript">
				var xxx = ''.uId()
			</script>
	*/
	uId: function(){
		return this + "u" + new Date().getTime() + parseInt(10000*Math.random());
	},
	
	/*
	 ref:		String.exe
	 note:		Evaluates a String using eval
	 note:		Wraps the string in an array and returns the zero index
	 returns:	Object
	 type:		Method
	 example:	<script type="text/javascript">
				var xxx = '{"a":"b"}'.exe()
			</script>
	*/
	exe: function(){
		return(eval('[' + this + ']')[0]);
	},
	
	/*
	 ref:		String.trim
	 note:		trims whitespace from the beginning and end of a string
	 returns:	String
	 type:		Method
	 example:	<script type="text/javascript">
				var xxx = '  vvv '.trim()
			</script>
	*/
	trim: function(){
		return this.replace(/^[\s]+ |[\s]+$/g,'');	
	}
	
});

/*
 ref:		Array
 returns:	Array
 type:		Class
*/
Object.extend(Array.prototype,{
	/*
	 ref:		Array.sum
	 note:		sums elements in an array
	 returns:	Number
	 type:		Method
	 example:	<script type="text/javascript">
				var xxx = [2,4,5].sum()
			</script>
	*/
	sum:function(){
		var s = 0;
		for(var i=0; i<this.length; i++){
			s += this[i];
		}
		return s;
	}
});

/*
 ref:		Hash
 note:		a prototype extended object
 note:		Use $H(obj) syntax instead of new Hash(obj)
 arg:		Object obj
 returns:	Hash
 type:		Class
 example:	<script type="text/javascript">
			var xxx = $H({a:'aa'; b:'bb'})
		</script>
*/
Object.extend(Hash.prototype,{
	
	/*
	 ref:		Hash.arrayAndHash
	 note:		Extends a hash to have an array counterpart
	 note:		The Array is the values of the Hash
	 returns:	Hash&Array
	 type:		Method
	 example:	<script type="text/javascript">
				var xxx = $H({a:'aa'; b:'bb'}).arrayAndHash()
				
				alert(xxx.a)
				
				alert(xxx[0])
			</script>
	*/
	arrayAndHash: function(){
		var r = this.values()
		for(p in this){
			r[p] = this[p]
		}
		return r
	}
});

/*
 ref:		Number
 returns:	Number
 type:		Class
*/
Object.extend(Number.prototype, {
	
	/*
	 ref:		Number.suff
	 note:		returns the number given plus the suffix from that number as a string
	 returns:	String
	 type:		Method
	 example:	<script type="text/javascript">
				var xxx = 6.suff()
			</script>
	*/
	suff: function(){
		var str = this.toString()
		var count = parseInt(str.length -1)
		if(this == 0)return this
		if((str[count]>3 && str[count]<10) || str[count-1]==1 && count != 0 )return this + "th"
		if(str[count] == 1)return this + "st"
		if(str[count] == 2)return this + "nd"
		if(str[count] == 3)return this + "rd"
			return this + "th"
	},
	
	/*
	 ref:		Number.round
	 note:		returns the number given plus the suffix from that number as a string
	 note:		provides a decimal places argument to prototypes round method
	 override:
	 returns:	String
	 arg:		Number places optional argument for the decimal places to round the number to
	 type:		Method
	 example:	<script type="text/javascript">
				var xxx = (6.4567).round(2)
			</script>
	*/
	round: function(places){
		if(places){
			return Math.round((this+1-1)*(Math.pow(10,places)))/Math.pow(10,places);
		} else {
			return Math.round()
		}
	},
	
	/*
	 ref:		Number.dollars
	 note:		returns the number given as an American Currency String
	 returns:	String
	 type:		Method
	 example:	<script type="text/javascript">
				var xxx = (6.4567).dollars()
			</script>
	*/
	dollars: function(){
		var num = this.round(2)
		num = num.toString()
		var dec = num.indexOf(new String('.'))
		if(dec == -1){
			num = num.concat(new String('.00'))   
		}else if(((num.length-1) - dec) == 1){
			num = num.concat(new String('0'))
		}
		return '$'+num
	}
	
});

/*
 ref:		DfNew
 note:		Base Static Class or Namespace for the API
 returns:	Object
 type:		Static Class
*/
var DfNew = {}

/*
 ref:		DfNew.version
 note:		version of the API
 type:		Static Parameter
 returns:	String
 example:	<script type="text/javascript">
			alert(DfNew.VERSION)
		</script>
*/
DfNew.version = "1.3.6";

/*
 ref:		DfNew.classPath
 returns:	String
 note:		location where importModule looks for files
 type:		Static Parameter
 example:	<script type="text/javascript">
			DfNew.classPath = '/js/df/';
		</script>
*/
DfNew.classPath = '../js/df/';

/*
 ref:		DfNew.importModule
 note:		load javascript files through inline as the page loads, n waits for n-1 to load
 type:		Static Method
 arg:		*String arguments the filename of the javascript file without the extention or path.
		Uses DfNew.ClassPath for the path. Multiple arguments allowed
 example:	<script type="text/javascript">
			DfNew.importModule("DfNew.Navigation", "DfNew.Tip" )
		</script>
*/
DfNew.importModule = function () {
	for (var i = 0; i < arguments.length; i++) {
		if(DfNew.Namespace.exists(arguments[i])){
		}else{
			document.write('<script type="text/javascript" src="' + DfNew.classPath + arguments[i] + '.js"></script>');
		}
	}
};

/*
 ref:		DfNew.loadJS
 type:		Static Method
 arg:		*String arguments the filename of the javascript file with the extention and path.
		Multiple arguments allowed
 note:		load javascript files through inline as the page loads, n waits for n-1 to load
 example:	<script type="text/javascript">
			DfNew.loadJS('/js/df/DfNew.Tip.js', '/js/df/DfNew.Navigation.js')
		</script> 
*/
DfNew.loadJS = function () {
	for (var i = 0; i < arguments.length; i++) {
		document.write('<script type="text/javascript" src="'+ arguments[i] +'"></script>');
	}
};

/*
 ref:		DfNew.loadImage
 note:		loads image file
 note:		intended to be used as a preloader
 arg:		*String arguments the filename of the image file with the extention and path.
		Multiple arguments allowed
 type:		Static Method
 example:	<script type="text/javascript">
			DfNew.loadImage('/images/x.jpg', '/images/y.jpg', '/images/y.jpg')
		</script>
*/
DfNew.loadImage = function () {
	for (var i = 0; i < arguments.length; i++) {
		new Image().src = arguments[i];
	}
};
	
/*
 ref:		DfNew.browser
 type:		Static Method
 note:		Browser Detection
 returns:	{
			mac : (0|1),
			safari : (0|1),
			firefoxMac : (0|1),
			pc : (0|1),
			ie : (0|1),
			ie6 : (0|1),
			ie7 : (0|1),
			netscape : (0|1),
			firefox : (0|1)
		}
 example:	<script type="text/javascript">
			if(DfNew.browser().ie6 ){
				alert('hack away');
			}
		</script>
*/
DfNew.browser = function () {
	var obj = {
		mac : 0,
		safari : 0,
		firefoxMac : 0,
		pc : 0,
		ie : 0,
		ie6 : 0,
		ie7 : 0,
		netscape : 0,
		firefox : 0
	};
	
	var ua = navigator.userAgent.toLowerCase();
	
	if (ua.indexOf("macintosh") !== -1) {
		obj.mac = 1;
		if (ua.indexOf("safari") !== -1) {
			obj.safari = 1;
		}
		else if (ua.indexOf("firefox") !== -1) {
			obj.firefoxMac = 1;
		}
	} else {
		obj.pc = 1; 
		if (ua.indexOf("msie") !== -1) {
			obj.ie = 1;
			if (ua.indexOf("msie 6") !== -1 || ua.indexOf("msie 5") !== -1) {
				obj.ie6 = 1;
			}
			else if (ua.indexOf("msie 7") !== -1) {
				obj.ie7 = 1;
			}
		}
		else if (ua.indexOf("netscape") !== -1) {
			obj.netscape = 1;
		}
		else if (ua.indexOf("firefox") !== -1) {
			obj.firefox = 1;
		}
	}
	return obj;
};	
	
/*
 ref:		DfNew.e
 note:		creates an element and appends it to another
 returns:	Element
 type:		Static Method
 example:	<script type="text/javascript">
			DfNew.e('div', document.body, {innerHTML: 'new element', className: 'new'} )
		</script>
*/
DfNew.e = function(tag,elm,para){
	var obj = document.createElement(tag);
	if(para){
		Object.extend(obj,para);
	}
	elm.appendChild($(obj));
	return $(obj);
};

/*
 ref:		DfNew.Namespace
 returns:	Object
 note:		This is the class to use to create or determine if a namespace exists
 type:		Static Class
*/
DfNew.Namespace = {
	_ary: null,
	_obj: null,
	_exists: false,
	
	/*
	 ref:		DfNew.Namespace.create
	 note:		create or retrieve a namespace
	 note:		returns last Object in the namespace string
	 note:		namespaces are created from blank objects if they don't already exist
	 type:		Static Method
	 arg:		String str the complete namespace as a string
	 arg:		Object scope the object to append the namespace objects to. This argument is
			optional. It defaults to window
	 returns:	Object
	 example:	<script type="text/javascript">
				var ns = DfNew.Namespace.create('DfNew.xxx.yyy.zzz', window)
			</script>
	 example:	<script type="text/javascript">
				var ns = DfNew.Namespace.create('DfNew.xxx.yyy.zzz', $('xxx'))
			</script>
	*/
	create: function (str, scope) {
		DfNew.Namespace._ary = str.split('.');
		
		if (!scope) {
		    scope = window;
		}
		
		if (!scope[DfNew.Namespace._ary[0]]) {
		    scope[DfNew.Namespace._ary[0]] = {};
		}
		
		DfNew.Namespace._obj = scope[DfNew.Namespace._ary[0]];
		
		if (DfNew.Namespace._ary[1]) {
		    DfNew.Namespace._next(1);
		}
		
		return DfNew.Namespace._obj;
	},
	
	/*
	 ref:		DfNew.Namespace.exists
	 note:		checks for the existance of a namespace
	 type:		Static Method
	 returns:	Boolean
	 arg:		String str the complete namespace as a string
	 arg:		Object scope of the namespace object. This argument is
			optional. It defaults to window
	 example:	<script type="text/javascript">
				if(DfNew.Namespace.exists('DfNew.xxx.yyy.zzz')
			</script>
	*/
	exists: function (str, scope) {
		DfNew.Namespace._ary = str.split('.');
		DfNew.Namespace._exists = false;
		
		if (!scope) {
		    scope = window;
		}
		
		if (!scope[DfNew.Namespace._ary[0]]) {
		    scope[DfNew.Namespace._ary[0]] = {};
		}
		
		DfNew.Namespace._obj = scope[DfNew.Namespace._ary[0]];
		
		if (DfNew.Namespace._ary[1]) {
		    DfNew.Namespace._exists = true;
		    DfNew.Namespace._checkNext(1);
		} else {
		    DfNew.Namespace._exists = false;
		}
		
		return DfNew.Namespace._exists;
	},
	
	_next: function (i) {
		if (!DfNew.Namespace._obj[DfNew.Namespace._ary[i]]) {
		    DfNew.Namespace._obj[DfNew.Namespace._ary[i]] = {};
		}
		
		DfNew.Namespace._obj = DfNew.Namespace._obj[DfNew.Namespace._ary[i]];
		
		if (DfNew.Namespace._ary[i + 1]) {
		    DfNew.Namespace._next(i + 1);
		}
	},
	
	_checkNext: function (i) {
		if (DfNew.Namespace._obj[DfNew.Namespace._ary[i]]) {
			DfNew.Namespace._obj = DfNew.Namespace._obj[DfNew.Namespace._ary[i]];
			if (DfNew.Namespace._ary[i + 1]) {
				DfNew.Namespace._checkNext(i + 1);
			} else {
				DfNew.Namespace._exists = true;
			}
		} else {
			DfNew.Namespace._exists = false;
		}
	}
}

/*
 ref:		DfNew.Event
 note:		Creates a custom event Object
 note:		Intended to by used on non dom based objects
 returns:	DfNew.Event
 type:		Class
 example:	<script type="text/javascript">
			var e = new DfNew.Event()
		</script>
*/
DfNew.Event = Class.create({
	initialize: function() {
		
		this.events = {};
		
		return this;	
	},
	
	/*
	 ref:		DfNew.Event.registerEvent
	 note:		registers a new event type.
	 returns:	DfNew.Event
	 type:		Method
	 arg:		*String name the name of the custom event
	 example:	<script type="text/javascript">
				var e = new DfNew.Event().register(':set', ':get', ':delete')
			</script>
	*/
	registerEvent: function () {
	    for (var i = 0; i < arguments.length; i++ ) {
		this.events[arguments[i]] = [];
	    }
	    return this;
	},
	
	/*
	 ref:		DfNew.Event.unregisterEvent
	 note:		unregisters a new event type.
	 note:		this will also remove all observers
	 returns:	DfNew.Event
	 type:		Method
	 arg:		*String name the name of the custom event
	 example:	<script type="text/javascript">
				var e = new DfNew.Event().unregister(':set', ':get', ':delete')
			</script>
	*/
	unregisterEvent: function () {
	    for (var i = 0; i < arguments.length; i++ ) {
		if (this.events[arguments[i]]) {
			delete this.events[arguments[i]];
		}
	    }
	    return this;
	},
	
	/*
	 ref:		DfNew.Event.observe
	 note:		registers observer functions on an event type.
	 note:		the event types are scoped to the object that initialized the event object
	 returns:	DfNew.Event
	 type:		Method
	 arg:		String onx the name of the custom event to listen for
	 arg:		Function fn the function that runs on dispatch of the event
	 example:	<script type="text/javascript">
				var e = new DfNew.Event().register(':set', ':get', ':delete')
				
				e.observe(':set', function(e){
					alert(e.memo)
				})
			</script>
	 example:	<script type="text/javascript">
				var event = new DfNew.Event().register(':set', ':get', ':delete')
				
				var DfNew.Test = class.Create({
					initialize: function(){
						event.observe(':set', this.meth1.bind(this))
					},
					
					meth1: function(e){
						alert(e.memo)
						alert(this)
					}
				});
				
			</script>
	*/
	observe: function (onx, fn) {
		if (this.events[onx]) {
		} else {
			this.registerEvent(onx);
		}
		this.events[onx].push(fn);
		return this;
	},
	
	/*
	 ref:		DfNew.Event.stopObserving
	 note:		unregisters observer functions on an event type.
	 note:		the event types are scoped to the object that initialized the event object
	 note:		parameter references to binded functions make unobserving posiable
	 returns:	DfNew.Event
	 type:		Method
	 arg:		String onx the name of the custom event
	 arg:		Function fn the function that is to be removed
	 example:	<script type="text/javascript">
				var event = new DfNew.Event().register(':set', ':get', ':delete')
				
				var DfNew.Test = class.Create({
					initialize: function(){
						this._meth1 = this.meth1.bind(this)
						
						event.observe(':set', this._meth1)
						
						event.stopObserving(':set', this._meth1)
					},
					
					meth1: function(e){
						alert(e.memo)
						alert(this)
					}
				});
				
			</script>
	*/
	stopObserving: function (onx ,fn) {
		for (var i = 0; i < this.events[onx].length; i += 1) {
			if (this.events[onx][i] === fn) {
				this.events[onx].splice(i, 1);
			}
		}
		return this;
	},

	/*
	 ref:		DfNew.Event.fire
	 note:		fires custom events.
	 returns:	DfNew.Event
	 type:		Method
	 arg:		String onx the name of the custom event
	 arg:		Object memo object to send to the listener functions
	 example:	<script type="text/javascript">
				var event = new DfNew.Event().register(':set', ':get', ':delete')
				
				var DfNew.Test = class.Create({
					initialize: function(){
						this._meth1 = this.meth1.bind(this)
						event.observe(':set', this._meth1)
					},
					
					meth1: function(e){
						alert(e.memo)
						alert(this)
					}
				});
				
				var test = new DfNew.Test()
				
				event.fire(':set')
				
			</script>
	*/
	fire: function (onx, memo) {
		if(this.events[onx]){
			for (var i = 0; i < this.events[onx].length; i += 1) {
				this.events[onx][i]({target: this, memo: memo});
			}
		}
		return this;
	}
});

/*
 ref:		DfNew.Base
 note:		Base class for instance based classes that take a parameters object
 type:		Class
 returns:	DfNew.Base
 extends:	DfNew.Event
 example:	<script type="text/javascript">
			var base = new DfNew.Base()
		</script>
*/
DfNew.Base = Class.create( DfNew.Event, {
	initialize: function($super) {
		$super()
		
		this.pars = {};
		
		return this;	
	},
	
	/*
	 ref:		DfNew.Base.setPars
	 note:		Overrides and or adds parameters to the parameters object
	 type:		Method
	 returns:	DfNew.Base
	 arg:		Object pars the parameters object
	 example:	<script type="text/javascript">
				var base = new DfNew.Base().setPars({xxx:"yyy"})
			</script>
	*/
	setPars: function(pars){
		if(pars){
			Object.extend( this.pars, pars);
		}
		return this;
	}
});

/*
 ref:		DfNew.Ui
 type:		Class
 note:		Base class for instance based classes that are build on a ui object
 event:		this.element :set fires when the set method is complete
 event:		this.element :show fires when the elements is told to show itself
 event:		this.element :shown fires when the element is finished its show process
 event:		this.element :hide fires when the elements is told to hide itself
 event:		this.element :hidden fires when the element is finished its hide process
 arg:		String|Element element an extended dom node or dom node id string
 extends:	DfNew.Base
 example:	<script type="text/javascript">
			var element = new DfNew.Ui('xxx')
		</script>
*/
DfNew.Ui = Class.create(DfNew.Base, {
	initialize: function($super, element) {
		
		$super(element)
		
		this.setPars({
			
			/*
			 ref:		DfNew.Ui.pars.showClassName
			 type:		Parameter
			 returns:	String
			 default:	df_element_show
			 note:		classname to assign during the show process of the element
			*/
			showClassName: 'df_element_show',
			
			/*
			 ref:		DfNew.Ui.pars.hideClassName
			 type:		Parameter
			 returns:	String
			 default:	df_element_hide
			 note:		classname to assign during the hide process of the element
			*/
			hideClassName: 'df_element_hide',
			
			/*
			 ref:		DfNew.Ui.pars.animate
			 type:		Parameter
			 returns:	Boolean|DfNew.Animate.pars
			 default:	false
			 note:		pars object you want to initialize DfNew.Animate with
			 example:	<script type="text/javascript">
						var el = new DfNew.Ui($('el')).set({
							animate: {
								opacity:0.35,
								time: 250
							}
						});
					</script>
			*/
			animate: false,
			
			/*
			 ref:		DfNew.Ui.pars.drag
			 type:		Parameter
			 returns:	Boolean|DfNew.Drag.pars
			 default:	false
			 note:		pars object you want to initialize DfNew.Drag with
			 example:	<script type="text/javascript">
						var el = new DfNew.Ui($('el')).set({
							animate: {
								opacity:0.35,
								time: 250
							},
							drag: {}
						});
					</script>
			*/
			drag: false,
			
			/*
			 ref:		DfNew.Ui.pars.resize
			 type:		Parameter
			 returns:	Boolean|DfNew.Resize.pars
			 default:	false
			 note:		pars object you want to initialize DfNew.Drag with
			 example:	<script type="text/javascript">
						var el = new DfNew.Ui($('el')).set({
							animate: {
								opacity:0.35,
								time: 250
							},
							resize:{}
						});
					</script>
			*/
			resize: false,
			
			/*
			 ref:		DfNew.Ui.pars.resize
			 type:		Parameter
			 returns:	Boolean|DfNew.Scroll.pars
			 default:	false
			 note:		pars object you want to initialize DfNew.Scroll with
			 example:	<script type="text/javascript">
						var el = new DfNew.Ui($('el')).set({
							animate: {
								opacity:0.35,
								time: 250
							},
							scroll:{}
						});
					</script>
			*/
			scroll: false,
			
			/*
			 ref:		DfNew.Ui.pars.iframe
			 type:		Parameter
			 returns:	Boolean
			 default:	false
			 note:		if set to true an iframe will be prepended to the element on show
					of the element.
			 note:		It will be hiddden on hide of the element
			*/
			iframe: false,
			
			/*
			 ref:		DfNew.Ui.pars.onSet
			 type:		Parameter
			 returns:	Function
			 default:	false
			 note:		anonymous function 
			 note:		sends class instance as the only argument
			*/
			onSet: false,
			
			/*
			 ref:		DfNew.Ui.pars.onHide
			 type:		Parameter
			 returns:	Function
			 default:	false
			 note:		anonymous function 
			 note:		sends class instance as the only argument 
			*/
			onHide: false,
			
			/*
			 ref:		DfNew.Ui.pars.onShow
			 type:		Parameter
			 returns:	Function
			 default:	false
			 note:		anonymous function 
			 note:		sends class instance as the only argument 
			*/
			onShow: false,
			
			/*
			 ref:		DfNew.Ui.pars.onHidden
			 type:		Parameter
			 returns:	Function
			 default:	false
			 note:		anonymous function 
			 note:		sends class instance as the only argument
			*/
			onHidden: false,
			
			/*
			 ref:		DfNew.Ui.pars.onShown
			 type:		Parameter
			 returns:	Function
			 default:	false
			 note:		anonymous function 
			 note:		sends class instance as the only argument
			*/
			onShown: false
		});
		
		this.element = $(element);
		
		this.togglePanes = []
		
		this.status = false
		this.displayStatus = false
		
		this._animationCompleteEvent = this.animationCompleteEvent.bindAsEventListener(this)
		
		return this;
	},
	
	/*
	 ref:		DfNew.Ui.set
	 type:		Method
	 note:		sets the instance to use the given parameters
	 note:		required the set the ui object into action
	 note:		the second part of the constructor
	 fire:		this.element :set
	 arg:		DfNew.Ui.pars pars
	 returns:	DfNew.Ui
	 example:	<script type="text/javascript">
				var element = new DfNew.Ui('xxx').set(
					animate: {
						opacity: .6,
						ease: DfNew.Transitions.cubicOut
					},
					drag: {}
				)
			</script>
	*/
	set: function(pars){
		
		this.setPars(pars);
		
		if(this.pars.animate){
			this.animate = new DfNew.Animate(this.getElement());
			Object.extend(this.animate.pars, this.pars.animate);
			
			this.animate.getElement().observe(':complete', this._animationCompleteEvent);
			
		} else {
			this.animate = false
		}
		
		if(this.pars.drag){
			this.drag = new DfNew.Drag(this.getElement());
			Object.extend(this.drag.pars, this.pars.drag);
			this.drag.set(this.drag.pars).enable()
		}else {
			this.drag = false
		}
		
		if(this.pars.resize){
			this.resize = new DfNew.Resize(this.getElement());
			Object.extend(this.resize.pars, this.pars.resize);
			this.resize.set(this.resize.pars).enable()
		}else {
			this.resize = false
		}
		
		if(this.pars.scroll){
			this.scroll = new DfNew.Scroll(this.getElement());
			Object.extend(this.scroll.pars, this.pars.scroll);
			this.scroll.set(this.scroll.pars)
		}else {
			this.scroll = false
		}
		
		this.element.fire(':set')
		
		if(this.pars.onSet){
			this.pars.onSet(this)
		}
		
		return this
	},

	/*
	 ref:		DfNew.Ui.getElement
	 type:		Method
	 note:		gets the native element that was used to create the instance of DfNew.Ui
	 returns:	Element
	 example:	<script type="text/javascript">
				var element = new DfNew.Ui('xxx').set()
				var nativeNode = element.getElement()
			</script>
	*/
	getElement: function() {
		return this.element;
	},

	/*
	 ref:		DfNew.Ui.getPointerX
	 type:		Method
	 note:		gets the mouse X position relative to the element 
	 returns:	Number
	 example:	<script type="text/javascript">
				var element = new DfNew.Ui('xxx').set()
				
				element.getElement().observe('mousemove', function(e){
					alert(element.getPointerX())
				});
			</script>
	*/
	getPointerX: function(e) {
		return Event.pointerX(e) - this.getElement().cumulativeOffset().left 
	},

	/*
	 ref:		DfNew.Ui.getPointerY
	 type:		Method
	 note:		gets the mouse Y position relative to the element 
	 returns:	Number
	 example:	<script type="text/javascript">
				var element = new DfNew.Ui('xxx').set()
				
				element.getElement().observe('mousemove', function(e){
					alert(element.getPointerY())
				});
			</script>
	*/
	getPointerY: function(e) {
		return Event.pointerY(e) - this.getElement().cumulativeOffset().top 
	},
	
	/*
	 ref:		DfNew.Ui.togglePane
	 type:		Method
	 delegate:	DfNew.TogglePane
	 arg:		Element|String element
	 arg:		DfNew.TogglePane.pars pars appends this as the controller par
	 note:		Creates an instance of DfNew.TogglePane with this as the controller
	 returns:	DfNew.TogglePane
	 example:	<script type="text/javascript">
				var element = new DfNew.Ui('xxx').set()
				
				var tp = element.togglePane($('yyy'), {
					animate: {
						height: 40,
						width:40
					},
					toggleShowDelay: 100
				});
			</script>
	*/
	togglePane: function(element, pars){
		Object.extend(pars, {controller: this})
		var togglePane = new DfNew.TogglePane(element).set(pars)
		this.togglePanes.push(togglePane)
		return togglePane;
	},
	
	animationCompleteEvent: function(e){
		e.stop()
		if(e.memo.pointer == 0){
			this._finishHide(e)
		}
		else if(e.memo.pointer == 1) {
			this._finishShow(e)
		}
	},
	
	/*
	 ref:		DfNew.Ui.show
	 type:		Method
	 note:		Shows the element by running its animation and assigning showClassName parameter
	 note:		show sets this.status = true and then calls this.showByStatus
	 returns:	DfNew.Ui
	 example:	<script type="text/javascript">
				var element = new DfNew.Ui('xxx').set(
					animate: {
						opacity: .75
					}
				).show()
			</script>
	 example:	<script type="text/javascript">
				var element = new DfNew.Ui('xxx').set(
					showClassName: 'displayNow'
				).show()
			</script>
	*/
	show: function(e){
		this.status = true
		this.showByStatus(e)
		return this
	},
	
	/*
	 ref:		DfNew.Ui.showByStatus
	 type:		Method
	 note:		Shows the element by running its animation and assigning showClassName parameter
	 note:		showByStatus checks to make sure that this.status is true and
			this.displayStatus is false and then calls this.showActions
	 returns:	DfNew.Ui
	*/
	showByStatus: function(e){
		if( this.status && !this.displayStatus ){
			this.showActions(e)
		}
		return this;
	},
	
	/*
	 ref:		DfNew.Ui.showActions
	 type:		Method
	 note:		Shows the element by running its animation and assigning showClassName parameter
	 note:		Shows the element only if it is not already being shown
	 fire:		this.element :show
	 fire:		this.element :shown
	 returns:	DfNew.Ui
	 example:	<script type="text/javascript">
				var element = new DfNew.Ui('xxx').set(
					animate: {
						opacity: .75
					}
				).showActions()
			</script>
	 example:	<script type="text/javascript">
				var element = new DfNew.Ui('xxx').set(
					showClassName: 'displayNow'
				).showActions()
			</script>
	*/
	showActions: function(e){
		this.status = true
		
		if(!this.displayStatus ){
			
			this.displayStatus = true
			
			this.element.fire(':show');
			
			if(this.pars.onShow){
				this.pars.onShow(this)
			}
				
			if(this.pars.showClassName) {
				this.getElement().addClassName(this.pars.showClassName)
			}
			
			if(this.pars.hideClassName){
				this.getElement().removeClassName(this.pars.hideClassName)
			}
			
			if (this.animate) {
				if (this.animate.getHistoryCount() == 0) {
					this.animate.run();	
				} else {
					this.animate.last();
				}
			} else {
				this._finishShow(e)
			}
		}
		return this
	},
	
	_finishShow: function(e){
		
		if((DfNew.browser()).ie6 && this.pars.iframe){
			this.showIframe();
		}
		
		this.element.fire(':shown');
		
		if(this.pars.onShown){
			this.pars.onShown(this)
		}
	},
	
	/*
	 ref:		DfNew.Ui.hide
	 type:		Method
	 note:		Hides the element by reverting its animation and assigning hideClassName parameter
	 note:		hide sets this.status = false and then calls this.hideByStatus
	 returns:	DfNew.Ui
	 example:	<script type="text/javascript">
				var element = new DfNew.Ui('xxx').set(
					animate: {
						opacity: .75
					}
				).show()
				
				element.getElement().observe('click', element.hide)
			</script>
	 example:	<script type="text/javascript">
				var element = new DfNew.Ui('xxx').set(
					showClassName: 'displayNow'
				).show()
				
				element.getElement().observe('click', element.hide)
			</script>
	*/
	hide: function(e){
		this.status = false
		this.hideByStatus(e)
	},
	
	/*
	 ref:		DfNew.Ui.hideByStatus
	 type:		Method
	 note:		Hides the element by reverting its animation and assigning hideClassName parameter
	 note:		checks to make sure that this.status is false and
			this.displayStatus is true and then calls this.hideActions
	 returns:	DfNew.Ui
	*/
	hideByStatus: function(e){
		if(!this.status && this.displayStatus){
			this.hideActions(e)
		}
		return this 
	},
	
	/*
	 ref:		DfNew.Ui.hideActions
	 type:		Method
	 note:		Hides the element by reverting its animation and assigning hideClassName parameter
	 note:		hideActions only runs if this.displayStatus is true
	 fire:		this.element :hide
	 fire:		this.element :hidden
	 returns:	DfNew.Ui
	 example:	<script type="text/javascript">
				var element = new DfNew.Ui('xxx').set(
					animate: {
						opacity: .75
					}
				).show()
				
				element.getElement().observe('click', element.hideActions)
			</script>
	 example:	<script type="text/javascript">
				var element = new DfNew.Ui('xxx').set(
					showClassName: 'displayNow'
				).show()
				
				element.getElement().observe('click', element.hideActions)
			</script>
	*/
	hideActions: function(e){
		this.status = false
		
		if(this.displayStatus ){
			
			this.displayStatus = false
			
			this.element.fire(':hide');
			
			if(this.pars.onHide){
				this.pars.onHide(this)
			}
			
			if( this.animate && this.animate.getHistoryCount() > 0){
				this.animate.first();
			}else{
				this._finishHide(e)
			}
		}
		return this
	},
	
	_finishHide: function(e){
			
		if(this.pars.hideClassName) {
			this.getElement().addClassName(this.pars.hideClassName)
			
		}
		if(this.pars.showClassName){
			this.getElement().removeClassName(this.pars.showClassName)
		}
		
		if((DfNew.browser()).ie6 && this.pars.iframe){
			this.hideIframe();
		}
		
		this.element.fire(':hidden');
		
		if(this.pars.onHidden){
			this.pars.onHidden(this)
		}
	},
	
	/*
	 ref:		DfNew.Ui.showIframe
	 type:		Method
	 note:		creates or displays blocking iframe for ie6
	 note:		attempts to size and position the frame to the element
	 note:		prepends the iframe to the element
	 note:		called by this.showActions
	 returns:	DfNew.Ui
	*/
	showIframe: function(){
		if(this.iframe){
			this.iframe.style.display = "block";
		}else{
			var html = '<iframe class="ie6BlockerFrame" style="display:block; left:'+ this.element.getStyle('left') +'; position:absolute; top:'+ this.element.getStyle('top') +'; filter:progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0);" scrolling="no" src="javascript:void(0);" frameborder="0" height="'+ parseInt( this.element.offsetHeight) +'px" width="'+ parseInt( this.element.offsetWidth) +'px"></iframe>'
			this.element.insert({before: html});
			this.iframe = this.element.previous('iframe')
		}
		return this
	},

	/*
	 ref:		DfNew.Ui.hideIframe
	 type:		Method
	 note:		hides the iframe
	 note:		called by this.hideActions
	 returns:	DfNew.Ui
	*/
	hideIframe: function(){
		if(this.iframe){
			this.iframe.style.display = "none";
		}
		return this
	}
});

/*
 ref:		DfNew.UiCollection
 type:		Class
 returns:	DfNew.UiCollection
 extends:	DfNew.Ui
 arg:		String|Element element an extended dom node or dom node id string
 note:		Base class for instance based classes that are collections of ui objects
*/
DfNew.UiCollection = Class.create(DfNew.Ui, {
	initialize: function($super, element){
		$super(element)
		
		this.setPars({
			/*
			 ref:		DfNew.UiCollection.pars.collection
			 type:		Parameter
			 returns:	DfNew.UiCollection
			 note:		passed to collection items as a reference back to the collection
			*/
			collection: this
		});
		
		this.items = [];
		
		return this
	},
	
	/*
	 ref:		DfNew.UiCollection.set
	 type:		Method
	 arg:		DfNew.Ui.pars pars
	 returns:	DfNew.UiCollection
	 note:		builds the collection of DfNew.Ui and sets the parameters object
	*/
	set: function($super, pars){
		$super(pars);
		
		this.buildItems();
		
		return this;
	},

	/*
	 ref:		DfNew.UiCollection.getItems
	 type:		Method
	 returns:	Array
	 note:		gets all the items of the collection
	*/
	getItems: function () {
		return this.items;
	},

	/*
	 ref:		DfNew.UiCollection.getItem
	 type:		Method
	 returns:	DfNew.Ui
	 arg:		Number i index of the items array to return
	 note:		gets an item of the collection
	*/
	getItem: function (i) {
		return this.items[i];
	},

	/*
	 ref:		DfNew.UiCollection.showOnlyItem
	 type:		Method
	 returns:	DfNew.Ui
	 arg:		Number|DfNew.Ui type index of the items array or ui instance to display
	 note:		shows an ui instance of the collection
	 note:		all other ui instances with be hidden
	*/
	showOnlyItem: function (type) { //index or instance
		var openItems = this.getShownItems()
		for(var i=0; i < openItems.length; i++){
			openItems[i].hide();
		}
		return this.showItem(type)
	},

	/*
	 ref:		DfNew.UiCollection.getShownItems
	 type:		Method
	 returns:	Array
	 note:		gets an array of all items in the collection that have this.displayStatus set to true
	*/
	getShownItems: function () {
		var items = []
		for(var i=0; i<this.items.length; i++){
			if(this.items[i].displayStatus){
				items.push(this.items[i]);
			}
		}
		return items
	},

	/*
	 ref:		DfNew.UiCollection.getHiddenItems
	 type:		Method
	 returns:	Array
	 note:		gets an array of all items in the collection that have this.displayStatus set to false
	*/
	getHiddenItems: function () {
		var items = []
		for(var i=0; i<this.items.length; i++){
			if(!this.items[i].displayStatus){
				items.push(this.items[i]);
			}
		}
		return items
	},
	
	/*
	 ref:		DfNew.UiCollection.getInstanceItemIndex
	 type:		Method
	 returns:	Number
	 arg:		DfNew.Ui
	 note:		gets the index in the collection for an item instance
	*/
	getInstanceItemIndex: function(ins){
		var index = false
		loopy:
		for(var i=0; i<this.items.length; i++){
			if( this.items[i] === ins){
				index = i
				break loopy
			}
		}
		return index
	},
	
	/*
	 ref:		DfNew.UiCollection.showItem
	 type:		Method
	 returns:	DfNew.Ui
	 arg:		DfNew.Ui|Number type index of the items array or ui instance to display
	 note:		shows an item in the collection
	*/
	showItem: function (type) { //index or instance
		if(type.constructor == Number){
			return this.items[type].show();
		}else{
			return type.show();
		}
	},
	
	/*
	 ref:		DfNew.UiCollection.showItems
	 type:		Method
	 returns:	DfNew.UiCollection
	 note:		shows all the items of the collection
	*/
	showItems: function () {
		for(var i=0; i<this.items.length; i++){
			if( !this.items[i].displayStatus){
				this.items[i].show();
			}
		}
		return this
	},
	
	/*
	 ref:		DfNew.UiCollection.hideItem
	 type:		Method
	 returns:	DfNew.Ui
	 arg:		Number index index of the items array to hide
	 note:		hides an item of the collection
	*/
	hideItem: function (index) {
		return this.items[index].hide();
	},
	
	/*
	 ref:		DfNew.UiCollection.hideItems
	 type:		Method
	 returns:	DfNew.UiCollection
	 note:		hides all the items of the collection
	*/
	hideItems: function(){
		for(var i=0; i<this.items.length; i++){
			if( this.items[i].displayStatus){
				this.items[i].hide();
			}
		}
		return this;
	},
	
	/*
	 ref:		DfNew.UiCollection.toggleItem
	 type:		Method
	 returns:	DfNew.UiCollection
	 arg:		Number index index of the items array to toggle
	 note:		toggles show or hide of an item of the collection
	*/
	toggleItem: function (index) {
		
		if(this.getItem(index).displayStatus){
			this.hideItem(index)
		}else{
			this.showItem(index)
		}
		return this
	},
	
	/*
	 ref:		DfNew.UiCollection.toggleItems
	 type:		Method
	 returns:	DfNew.UiCollection
	 note:		toggles the display of all items in the collection
	*/
	toggleItems: function () {
		for(var i=0; i<this.items.length; i++){
			if(this.items[i].displayStatus){
				this.items[i].hide()
			}else{
				this.items[i].show()
			}
		}
		return this
	},
	
	/*
	 ref:		DfNew.UiCollection.buildItems
	 type:		Method
	 returns:	DfNew.UiCollection
	 note:		method used to build the items of the collection
	 note:		intended to be overridden
	 example:	<script type="text/javascript">
				var myCollection = Class.create(DfNew.UiCollection, {
					buildItems: function(){
						var elem = this.element.select('div.includeMe');
		
						for(var i=0; i<elem.length; i++){
							this.items.push( new DfNew.Ui( $(elem[i]) ).set(this.pars) );	
						}	
					}
				});
				
				var myIns = new myCollection($('xxx')).set({
					animate: {
						height: 200
					}
				});
			</script>
	*/
	buildItems: function(){
		
		var elem = this.element.immediateDescendants();
		
		for(var i=0; i<elem.length; i++){
			this.items.push( new DfNew.Ui( $(elem[i]) ).set(this.pars) );	
		}
	}
});

/*
 ref:		DfNew.TogglePane
 extends:	DfNew.Ui
 returns:	DfNew.TogglePane
 demo:		../demos/toggleElements.html simple example showing how easy it is to control elements
		through events and animation
 type:		Class
 arg:		string|Element element an extended dom node or dom node id string
 note:		Base class for instance based classes that panes contolled visually by another ui object
 example:	<script type="text/javascript">
			var xxx = new DfNew.TogglePane('yyy').set({
				controller: new DfNew.Ui('zzz').set(),
				animate: {
					width: 500,
					time: 1500
				}
			});
		</script>
*/
DfNew.TogglePane = Class.create(DfNew.Ui, {
	initialize: function($super, element) {
		$super(element)
		
		this.setPars({
			/*
			 ref:		DfNew.TogglePane.pars.toggleShowDelay
			 type:		Parameter
			 returns:	Number
			 default:	250
			 note:		milliseconds to pause before showing element
			 hint:		Only available for hover event type
			 example:	<script type="text/javascript">
						var xxx = new DfNew.TogglePane('yyy').set({
							controller: new DfNew.Ui('zzz').set(),
							animate: {
								width: 500,
								time: 1500
							},
							toggleShowDelay: 1500
						});
					</script>
			*/
			toggleShowDelay: 250,
			
			/*
			 ref:		DfNew.TogglePane.pars.toggleHideDelay
			 type:		Parameter
			 default:	250
			 returns:	Number
			 note:		milliseconds to pause before hiding element
			 hint:		Only available for hover event type
			 example:	<script type="text/javascript">
						var xxx = new DfNew.TogglePane('yyy').set({
							controller: new DfNew.Ui('zzz').set(),
							animate: {
								width: 500,
								time: 1500
							},
							toggleHideDelay: 1500
						});
					</script>
			*/
			toggleHideDelay: 250,
			
			/*
			 ref:		DfNew.TogglePane.pars.activeControllerClassName
			 type:		Parameter
			 returns:	String
			 default:	activeController
			 note:		class assigned to the controller element on show of the toggle element
			*/
			activeControllerClassName: 'activeController',
			
			/*
			 ref:		DfNew.TogglePane.pars.treatAsMenu
			 type:		Parameter
			 default:	true
			 returns:	Boolean
			 hint:		only available for hover event type
			 note:		allows you to move your mouse onto the toggle element and keep it displayed
			 note:		used for ui types like tips and dropnavs
			*/
			treatAsMenu: true,
			
			/*
			 ref:		DfNew.TogglePane.pars.controller
			 type:		Parameter
			 default:	false
			 returns:	DfNew.Ui
			 hint:		this parameter must be set
			 note:		the controlling ui element for the showing and hiding of the
					toggle element
			*/
			controller: false,
			
			/*
			 ref:		DfNew.TogglePane.pars.eventType
			 type:		Parameter
			 default:	hover
			 choice:	hover
			 choice:	click
			 returns:	String
			 hint:		this parameter must be set
			 note:		the event type that triggers showing and hiding the toggle element
			*/
			eventType: 'hover' //hover|click
		});
		
		this._controllerClickObserver = this.controllerClickObserver.bindAsEventListener(this)
		this._controllerHoverOverObserver = this.controllerHoverOverObserver.bindAsEventListener(this)
		this._controllerHoverOutObserver = this.controllerHoverOutObserver.bindAsEventListener(this)
		this._paneHoverOverObserver = this.paneHoverOverObserver.bindAsEventListener(this)
		this._paneHoverOutObserver = this.paneHoverOutObserver.bindAsEventListener(this)
		
		return this;
	},
	
	/*
	 ref:		DfNew.TogglePane.set
	 type:		Method
	 arg:		DfNew.TogglePane.pars pars
	 returns:	DfNew.TogglePane
	 note:		sets the event handlers on the controller and toggle element
	*/
	set: function($super, pars) {
		$super(pars)
		
		this.eventType()
		
		this.element.observe(':show', this.addActiveTitleState.bind(this));
		
		this.element.observe(':hidden', this.removeActiveTitleState.bind(this));
		
		return this;
	},
	
	/*
	 ref:		DfNew.TogglePane.eventType
	 type:		Method
	 returns:	DfNew.TogglePane
	 arg:		DfNew.TogglePane.pars.eventType type can be click, hover, false
	 note:		sets or changes the event type handlers
	*/
	eventType: function(type) {
		if(type === this.pars.eventType){
			return this
		} else {
			if(type === false){
				this.pars.eventType = false
			} else if( type ) {
				this.pars.eventType = type
			}
			
			if (this.pars.eventType == 'hover') {
				this.removeClickEvent()
				this.addHoverEvent()
			}
			else if (this.pars.eventType == 'click') {
				this.removeHoverEvent()
				this.addClickEvent()
			}
			else if (this.pars.eventType === false) {
				this.removeHoverEvent()
				this.removeClickEvent()
			}
			return this	
		}
	},
	
	/*
	 ref:		DfNew.TogglePane.addHoverEvent
	 type:		Method
	 note:		sets up the event handlers for hover
	 note:		not intended to use used directly
	 note:		intended to be overriden
	*/
	addHoverEvent: function(){
		this.pars.controller.getElement().observe(
			'mouseover',
			this._controllerHoverOverObserver
		);
		
		this.pars.controller.getElement().observe(
			'mouseout',
			this._controllerHoverOutObserver
		);
		
		if (this.pars.treatAsMenu) {
			this.getElement().observe(
				'mouseover',
				this._paneHoverOverObserver
			);
			
			this.getElement().observe(
				'mouseout',
				this._paneHoverOutObserver
			);
		}
	},
	
	/*
	 ref:		DfNew.TogglePane.removeHoverEvent
	 type:		Method
	 note:		removes the event handlers for hover
	 note:		not intended to use used directly
	 note:		intended to be overriden
	*/
	removeHoverEvent: function(){
		this.pars.controller.getElement().stopObserving(
			'mouseover',
			this._controllerHoverOverObserver
		);
		
		this.pars.controller.getElement().stopObserving(
			'mouseout',
			this._controllerHoverOutObserver
		);
		
		if (this.pars.treatAsMenu) {
			this.getElement().stopObserving(
				'mouseover',
				this._paneHoverOverObserver
			);
			
			this.getElement().stopObserving(
				'mouseout',
				this._paneHoverOutObserver
			);
		}	
	},
	
	/*
	 ref:		DfNew.TogglePane.addClickEvent
	 type:		Method
	 note:		sets up the event handlers for click
	 note:		not intended to use used directly
	 note:		intended to be overriden
	*/
	addClickEvent: function(){
		this.pars.controller.getElement().observe(
			'click',
			this._controllerClickObserver
		);
	},
	
	/*
	 ref:		DfNew.TogglePane.removeClickEvent
	 type:		Method
	 note:		removes the event handlers for click
	 note:		not intended to use used directly
	 note:		intended to be overriden
	*/
	removeClickEvent: function(){
		this.pars.controller.getElement().stopObserving(
			'click',
			this._controllerClickObserver
		);
	},
	
	/*
	 ref:		DfNew.TogglePane.controllerClickObserver
	 type:		Method
	 note:		adds the event handlers for click on the controller element
	 note:		called as part of addClickEvent
	 note:		not intended to use used directly
	 note:		intended to be overriden
	*/
	controllerClickObserver: function(e){
		Event.stop(e);
		if(this.status && this.displayStatus){
			this.hideClickObserver(e)
		}
		else if (!this.status && !this.displayStatus) {
			this.showClickObserver(e)
		}
	},
	
	/*
	 ref:		DfNew.TogglePane.hideClickObserver
	 type:		Method
	 note:		adds the event handlers for click on the element
	 note:		called as part of controllerClickObserver
	 note:		not intended to use used directly
	 note:		intended to be overriden
	*/
	hideClickObserver: function(e){
		this.hide(e)
	},
	
	/*
	 ref:		DfNew.TogglePane.showClickObserver
	 type:		Method
	 note:		adds the event handlers for click on the element
	 note:		called as part of controllerClickObserver
	 note:		not intended to use used directly
	 note:		intended to be overriden
	*/
	showClickObserver: function(e){
		this.show(e)
	},
	
	/*
	 ref:		DfNew.TogglePane.controllerHoverOverObserver
	 type:		Method
	 note:		adds the event handlers for hover on the controller element
	 note:		called as part of addHoverEvent
	 note:		not intended to use used directly
	 note:		intended to be overriden
	*/
	controllerHoverOverObserver: function(e){
		Event.stop(e);
		this.status = true
		setTimeout( this.showByStatus.bind(this), this.pars.toggleShowDelay)
	},
	
	/*
	 ref:		DfNew.TogglePane.controllerHoverOutObserver
	 type:		Method
	 note:		adds the event handlers for hover on the controller element
	 note:		called as part of addHoverEvent
	 note:		not intended to use used directly
	 note:		intended to be overriden
	*/
	controllerHoverOutObserver: function(e){
		Event.stop(e);
		this.status = false
		setTimeout( this.hideByStatus.bind(this), this.pars.toggleHideDelay)
	},
	
	/*
	 ref:		DfNew.TogglePane.paneHoverOverObserver
	 type:		Method
	 note:		adds the event handlers for hover on the toggle element
	 note:		called as part of addHoverEvent
	 note:		not intended to use used directly
	 note:		intended to be overriden
	*/
	paneHoverOverObserver: function(e){
		Event.stop(e);
		this.status = true
	},
	
	/*
	 ref:		DfNew.TogglePane.paneHoverOutObserver
	 type:		Method
	 note:		adds the event handlers for hover on the toggle element
	 note:		called as part of addHoverEvent
	 note:		not intended to use used directly
	 note:		intended to be overriden
	*/
	paneHoverOutObserver: function(e){
		Event.stop(e);
		this.status = false
		setTimeout( this.hideByStatus.bind(this), this.pars.toggleHideDelay)
	},
	
	/*
	 ref:		DfNew.TogglePane.removeActiveTitleState
	 type:		Method
	 returns:	DfNew.TogglePane
	 note:		removes the activeControllerClassName parameter to the controller element on hide
	*/
	removeActiveTitleState: function(e){
		Event.stop(e)
		if( this.pars.activeControllerClassName){
			this.pars.controller.element.removeClassName( this.pars.activeControllerClassName );
		}
		return this
	},
	
	/*
	 ref:		DfNew.TogglePane.addActiveTitleState
	 type:		Method
	 returns:	DfNew.TogglePane
	 note:		adds the activeControllerClassName parameter to the controller element on show
	*/
	addActiveTitleState: function(e){
		Event.stop(e)
		if( this.pars.activeControllerClassName){
			this.pars.controller.element.addClassName( this.pars.activeControllerClassName );
		}
		return this
	}
});

/*
 ref:		DfNew.Cookie
 extends:	DfNew.Base
 returns:	DfNew.Cookie
 demo:		../demos/cookie.html create, show, modify, delete cookies 
 note:		Makes document.cookie object easy to work with
 type:		Class
 event:		this :get
 event:		this :set
 event:		this :delete
*/
DfNew.Cookie = Class.create(DfNew.Base, {
	initialize: function($super, element) {
		$super(element)
		
		this.setPars({
			
			/*
			 ref:		DfNew.Cookie.pars.name
			 type:		Parameter
			 returns:	String
			 default:	dfNew
			 note:		the name of the cookie
			*/
			name: 'dfNew',
			
			/*
			 ref:		DfNew.Cookie.pars.path
			 type:		Parameter
			 returns:	Boolean|String
			 default:	false
			 note:		the path of the cookie
			*/
			path: false,
			
			/*
			 ref:		DfNew.Cookie.pars.domain
			 type:		Parameter
			 returns:	Boolean|String
			 default:	false
			 note:		the domain of the cookie
			*/
			domain:false,
			
			/*
			 ref:		DfNew.Cookie.pars.expires
			 type:		Parameter
			 returns:	Boolean|String
			 default:	false
			 note:		the expiration date of the cookie
			*/
			expires:false,
			
			/*
			 ref:		DfNew.Cookie.pars.data
			 type:		Parameter
			 returns:	Boolean|String|Object|Array|Number
			 default:	false
			 note:		the date of the cookie
			*/
			data: false,
			
			/*
			 ref:		DfNew.Cookie.pars.onSet
			 type:		Parameter
			 returns:	Function
			 default:	false
			 note:		anonymous function 
			 note:		sends class instance as the only argument
			*/
			onSet: false,
			
			/*
			 ref:		DfNew.Cookie.pars.onGet
			 type:		Parameter
			 returns:	Function
			 default:	false
			 note:		anonymous function 
			 note:		sends class instance as the only argument
			*/
			onGet: false,
			
			/*
			 ref:		DfNew.Cookie.pars.onDelete
			 type:		Parameter
			 returns:	Function
			 default:	false
			 note:		anonymous function 
			 note:		sends class instance as the only argument
			*/
			onDelete: false
		});
		
		return this;
	},
	
	/*
	 ref:		DfNew.Cookie.setCookie
	 type:		Method
	 returns:	DfNew.Cookie
	 arg:		DfNew.Cookie.pars pars
	 fire:		this :set sends cookie as a memo
	 note:		writes the cookie
	*/
	setCookie: function(pars) {
		
		this.setPars(pars);
		
		var serial = false;
		
		if (this.pars.data.constructor == Array || this.pars.data.constructor == Object) {
			serial = escape(Object.toJSON(this.pars.data));
		} else {
			serial = escape(this.pars.data);
		}
		
		var value = this.pars.name + '=' + serial + ';'
		if (this.pars.expires) {
			value += ' expires=' + this.pars.expires + ';'
		}
		if (this.pars.path) {
			value += ' path=' + this.pars.path + ';'
		}
		if (this.pars.domain) {
			value += ' domain=' + this.pars.domain + ';'
		}
		document.cookie = value;
		
		this.fire(':set', {cookie: this} );
		
		if(this.pars.onSet){
			this.pars.onSet(this)
		}
		
		return this;
	},
	
	/*
	 ref:		DfNew.Cookie.deleteCookie
	 type:		Method
	 returns:	DfNew.Cookie
	 fire:		this :delete sends cookie as a memo
	 note:		deletes the cookie
	*/
	deleteCookie: function(){
		var cookie_date = new Date ( );
		cookie_date.setTime( cookie_date.getTime() - 1 );
		document.cookie = this.pars.name + "=; expires=" + cookie_date.toGMTString();
		
		this.fire(':delete', {cookie: this} );
		
		if(this.pars.onDelete){
			this.pars.onDelete(this)
		}
		
		return this;
	},
	
	/*
	 ref:		DfNew.Cookie.getCookie
	 type:		Method
	 returns:	DfNew.Cookie
	 fire:		this :get sends cookie as a memo
	 note:		returns the cookie data
	*/
	getCookie: function(){
		var result = document.cookie.match ( this.pars.name + '=(.*?)(;|$)' );
		
		if( result ){
			
			this.fire(':get', {cookie: this} );
			
			if(this.pars.onGet){
				this.pars.onGet(this)
			}
			
			if (result[1].constructor == Array || result[1].constructor == Object) {
				return unescape(Object.toJSON(result[1]));
			} else {
				return unescape(result[1]);
			}
		}else{
			return undefined;
		}
	}
});


/*
 ref:		DfNew.Scroll
 extends:	DfNew.Ui
 type:		Class
 returns:	DfNew.Scroll
 arg:		String|Element element an extended dom node or dom node id string
 event:		this.element :mousewheel
*/
DfNew.Scroll = Class.create(DfNew.Ui, {
	initialize: function($super, element) {
		$super(element)
	},
	
	/*
	 ref:		DfNew.Scroll.set
	 type:		Method
	 returns:	DfNew.Scroll
	 arg:		DfNew.Ui.pars pars
	 fire:		this.element :mousewheel calls mouseWheelDelta based on dom event listeners
	*/
	set: function($super, pars){
		$super(pars)
		
		this.setPars({
			/*
			 ref:		DfNew.Scroll.pars.onMousewheel
			 type:		Parameter
			 returns:	Function
			 default:	false
			 note:		anonymous function 
			 note:		sends class instance as the first argument
			 note:		sends event as the second argument
			*/
			onMousewheel: false
		})
		
		Event.observe( this.element, "mousewheel", function(e){
			this.element.fire(':mousewheel',{delta:this.mouseWheelDelta(e)});
			
			if(this.pars.onMousewheel){
				this.pars.onMousewheel(this, e)
			}
		}.bind(this));
		
		Event.observe( this.element, "DOMMouseScroll", function(e){
			this.element.fire(':mousewheel',{delta:this.mouseWheelDelta(e)});
			
			if(this.pars.onMousewheel){
				this.pars.onMousewheel(this, e)
			}
		}.bind(this));
		
		return this;
	},
	
	/*
	 ref:		DfNew.Scroll.set
	 type:		Method
	 note:		attempts to create some consistancy for reading mousewheel interations
	 note:		not intended to be called directly
	*/
	mouseWheelDelta: function(e){
		var delta = 0;
		
		if (e.wheelDelta){
	
			delta = e.wheelDelta/120;
	
			if (window.opera){
				delta = -delta;
			}
		}
		else if(e.detail){
			delta = -e.detail/3;
		}
		return delta;
	}

});

// ---------------------------------------- animation classes ---------------------------------------

//Author: Robert Penner, <http://www.robertpenner.com/easing/>
//License: Easing Equations v1.5, (c) 2003 Robert Penner, all rights reserved. Open Source BSD License.

/*
 ref:		DfNew.Transitions
 type:		Static Class
 returns:	Object
 note:		adds a ton of Robert Penner's Easings equations
 example:	<script type="text/javascript">
			$('xxx').animate({
				padding: 600,
				ease: DfNew.Transitions.cubicOut
			})
		</script>
*/
DfNew.Transitions = {
	
	/*
	 ref:		DfNew.Transitions.linear
	 type:		Static Method
	 returns:	Number
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 note:		the default easing for DfNew.Animate
	*/
	linear: function(t, b, c, d){
		return c*t/d + b;
	},
	
	/*
	 ref:		DfNew.Transitions.quadIn
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	quadIn: function(t, b, c, d){
		return c*(t/=d)*t + b;
	},
	
	/*
	 ref:		DfNew.Transitions.quadOut
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	quadOut: function(t, b, c, d){
		return -c *(t/=d)*(t-2) + b;
	},

	/*
	 ref:		DfNew.Transitions.quadInOut
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	quadInOut: function(t, b, c, d){
		if ((t/=d/2) < 1) return c/2*t*t + b;
		return -c/2 * ((--t)*(t-2) - 1) + b;
	},

	/*
	 ref:		DfNew.Transitions.cubicIn
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	cubicIn: function(t, b, c, d){
		return c*(t/=d)*t*t + b;
	},

	/*
	 ref:		DfNew.Transitions.cubicOut
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	cubicOut: function(t, b, c, d){
		return c*((t=t/d-1)*t*t + 1) + b;
	},

	/*
	 ref:		DfNew.Transitions.cubicInOut
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	cubicInOut: function(t, b, c, d){
		if ((t/=d/2) < 1) return c/2*t*t*t + b;
		return c/2*((t-=2)*t*t + 2) + b;
	},

	/*
	 ref:		DfNew.Transitions.quartIn
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	quartIn: function(t, b, c, d){
		return c*(t/=d)*t*t*t + b;
	},

	/*
	 ref:		DfNew.Transitions.quartOut
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	quartOut: function(t, b, c, d){
		return -c * ((t=t/d-1)*t*t*t - 1) + b;
	},

	/*
	 ref:		DfNew.Transitions.quartInOut
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	quartInOut: function(t, b, c, d){
		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
		return -c/2 * ((t-=2)*t*t*t - 2) + b;
	},

	/*
	 ref:		DfNew.Transitions.quintIn
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	quintIn: function(t, b, c, d){
		return c*(t/=d)*t*t*t*t + b;
	},

	/*
	 ref:		DfNew.Transitions.quintOut
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	quintOut: function(t, b, c, d){
		return c*((t=t/d-1)*t*t*t*t + 1) + b;
	},

	/*
	 ref:		DfNew.Transitions.quintInOut
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	quintInOut: function(t, b, c, d){
		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
		return c/2*((t-=2)*t*t*t*t + 2) + b;
	},

	/*
	 ref:		DfNew.Transitions.sineIn
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	sineIn: function(t, b, c, d){
		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
	},

	/*
	 ref:		DfNew.Transitions.sineOut
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	sineOut: function(t, b, c, d){
		return c * Math.sin(t/d * (Math.PI/2)) + b;
	},

	/*
	 ref:		DfNew.Transitions.sineInOut
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	sineInOut: function(t, b, c, d){
		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
	},

	/*
	 ref:		DfNew.Transitions.expoIn
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	expoIn: function(t, b, c, d){
		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
	},

	/*
	 ref:		DfNew.Transitions.expoOut
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	expoOut: function(t, b, c, d){
		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
	},

	/*
	 ref:		DfNew.Transitions.expoInOut
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	expoInOut: function(t, b, c, d){
		if (t==0) return b;
		if (t==d) return b+c;
		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
	},

	/*
	 ref:		DfNew.Transitions.circIn
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	circIn: function(t, b, c, d){
		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
	},

	/*
	 ref:		DfNew.Transitions.circOut
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	circOut: function(t, b, c, d){
		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
	},

	/*
	 ref:		DfNew.Transitions.circInOut
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	circInOut: function(t, b, c, d){
		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
	},

	/*
	 ref:		DfNew.Transitions.elasticIn
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 arg:		Number a factor optional
	 arg:		Number p factor optional
	 returns:	Number
	*/
	elasticIn: function(t, b, c, d, a, p){
		if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; if (!a) a = 1;
		if (a < Math.abs(c)){ a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin(c/a);
		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	},

	/*
	 ref:		DfNew.Transitions.elasticOut
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 arg:		Number a factor optional
	 arg:		Number p factor optional
	 arg:		Number a factor optional
	 arg:		Number p factor optional
	 returns:	Number
	*/
	elasticOut: function(t, b, c, d, a, p){
		if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; if (!a) a = 1;
		if (a < Math.abs(c)){ a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin(c/a);
		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
	},

	/*
	 ref:		DfNew.Transitions.elasticInOut
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 arg:		Number a factor optional
	 arg:		Number p factor optional
	 returns:	Number
	*/
	elasticInOut: function(t, b, c, d, a, p){
		if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); if (!a) a = 1;
		if (a < Math.abs(c)){ a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin(c/a);
		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
	},

	/*
	 ref:		DfNew.Transitions.backIn
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 arg:		Number s factor optional
	 returns:	Number
	*/
	backIn: function(t, b, c, d, s){
		if (!s) s = 1.70158;
		return c*(t/=d)*t*((s+1)*t - s) + b;
	},

	/*
	 ref:		DfNew.Transitions.backOut
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 arg:		Number s factor optional
	 returns:	Number
	*/
	backOut: function(t, b, c, d, s){
		if (!s) s = 1.70158;
		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
	},

	/*
	 ref:		DfNew.Transitions.backInOut
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 arg:		Number s factor optional
	 returns:	Number
	*/
	backInOut: function(t, b, c, d, s){
		if (!s) s = 1.70158;
		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
	},

	/*
	 ref:		DfNew.Transitions.bounceIn
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	bounceIn: function(t, b, c, d){
		return c - DfNew.Transitions.bounceOut (d-t, 0, c, d) + b;
	},

	/*
	 ref:		DfNew.Transitions.bounceOut
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	bounceOut: function(t, b, c, d){
		if ((t/=d) < (1/2.75)){
			return c*(7.5625*t*t) + b;
		} else if (t < (2/2.75)){
			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
		} else if (t < (2.5/2.75)){
			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
		} else {
			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
		}
	},

	/*
	 ref:		DfNew.Transitions.bounceInOut
	 type:		Static Method
	 arg:		Number t current iteration
	 arg:		Number b current value
	 arg:		Number c total value delta
	 arg:		Number d total iterations
	 returns:	Number
	*/
	bounceInOut: function(t, b, c, d){
		if (t < d/2) return DfNew.Transitions.bounceIn(t*2, 0, c, d) * .5 + b;
		return DfNew.Transitions.bounceOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
	}

};

/*
 ref:		DfNew.Animate
 extends:	DfNew.Ui
 note:		give an element a convenient way to change its visual properties in a stepping way
 type:		Class
 arg:		String|Element element an extended dom node or dom node id string
 hint:		Element must be positioned Absolute or relative if animating top or left
 hint:		Animation parameters map to and change css styles
 hint:		no color keywords allowed
 demo:		../demos/animate_move.html interactive demo allows you to choose easing, duration, and pause between each iteration. Also
		tracks the animation history and allows you to revert to previous animation steps.
 demo:		../demos/animate_selectors.html interactive demo allows you to choose any selectors and values
		to animate
 event:		this.element :complete
 event:		this.element :iteration
*/
DfNew.Animate = Class.create(DfNew.Ui, {
	initialize: function($super, element) {
		
		$super(element)
		
		this.setPars({
			
			/*
			 ref:		DfNew.Animate.pars.time
			 type:		Parameter
			 returns:	Number|Boolean
			 choice:	false
			 choice:	Number
			 default:	250
			 note:		time in milliseconds to run the complete animation
			 hint:		use time and pase together or pause and skip
			 hint:		easing is only available when using time and pause
			*/
			time: 250,
			
			/*
			 ref:		DfNew.Animate.pars.pause
			 type:		Parameter
			 returns:	Number
			 default:	40
			 note:		time in milliseconds waint between each iteration
			 hint:		use time and pase together or pause and skip
			 hint:		easing is only available when using time and pause
			*/
			pause: 40,
			
			/*
			 ref:		DfNew.Animate.pars.skip
			 type:		Parameter
			 returns:	Number|Boolean
			 choice:	false
			 choice:	Number
			 default:	false
			 note:		pixels to skip between each iteration
			 hint:		use time and pase together or pause and skip
			 hint:		easing is only available when using time and pause
			*/
			skip:false,
			
			/*
			 ref:		DfNew.Animate.pars.ease
			 type:		Parameter
			 returns:	Function
			 default:	DfNew.Transitions.linear
			*/
			ease: DfNew.Transitions.linear,
			
			/*
			 ref:		DfNew.Animate.pars.width
			 type:		Parameter
			 returns:	Number|Boolean
			 default:	false
			 note:		animates the css property of width
			*/
			width: false,
			
			/*
			 ref:		DfNew.Animate.pars.height
			 type:		Parameter
			 returns:	Number|Boolean
			 default:	false
			 note:		animates the css property of height
			*/
			height: false,
			
			/*
			 ref:		DfNew.Animate.pars.color
			 type:		Parameter
			 returns:	Boolean|String
			 choice:	false
			 choice:	hex as a string like '#ffffff'
			 choice:	rgb as a string like 'rgb(255,255,255)'
			 default:	false
			 note:		animates the css property of color
			*/
			color: false,
			
			/*
			 ref:		DfNew.Animate.pars.backgroundColor
			 type:		Parameter
			 returns:	Boolean|String
			 choice:	false
			 choice:	hex as a string like '#ffffff'
			 choice:	rgb as a string like 'rgb(255,255,255)'
			 default:	false
			 note:		animates the css property of background-color
			*/
			backgroundColor: false,
			
			/*
			 ref:		DfNew.Animate.pars.backgroundPosition
			 type:		Parameter
			 returns:	Boolean|String
			 choice:	false
			 choice:	String like '1px 4px'
			 default:	false
			 note:		animates the css property of background-position
			*/
			backgroundPosition: false,
			
			/*
			 ref:		DfNew.Animate.pars.left
			 type:		Parameter
			 returns:	Boolean|Number
			 default:	false
			 note:		animates the css property of left
			*/
			left: false,
			
			/*
			 ref:		DfNew.Animate.pars.top
			 type:		Parameter
			 returns:	Boolean|Number
			 default:	false
			 note:		animates the css property of top
			*/
			top: false,
			
			/*
			 ref:		DfNew.Animate.pars.opacity
			 type:		Parameter
			 returns:	Boolean|Number
			 choice:	false
			 choice:	decimal 0.0001 - 0.9999
			 hint:		use values between 0.0001 - 0.9999
			 hint:		prototype does not like cap case. in css use filter:alpha(opacity=50)
			 default:	false
			 note:		animates the css property of opacity
			*/
			opacity: false,
			
			/*
			 ref:		DfNew.Animate.pars.fontSize
			 type:		Parameter
			 returns:	Boolean|Number
			 default:	false
			 note:		animates the css property of font-size
			*/
			fontSize: false,
			
			/*
			 ref:		DfNew.Animate.pars.lineHeight
			 type:		Parameter
			 returns:	Boolean|Number
			 default:	false
			 note:		animates the css property of line-height
			*/
			lineHeight: false,
			
			/*
			 ref:		DfNew.Animate.pars.letterSpacing
			 type:		Parameter
			 returns:	Boolean|Number
			 default:	false
			 note:		animates the css property of letter-spacing
			*/
			letterSpacing: false,
			
			/*
			 ref:		DfNew.Animate.pars.paddingLeft
			 type:		Parameter
			 returns:	Boolean|Number
			 default:	false
			 note:		animates the css property of padding-left
			*/
			paddingLeft: false,
			
			/*
			 ref:		DfNew.Animate.pars.paddingRight
			 type:		Parameter
			 returns:	Boolean|Number
			 default:	false
			 note:		animates the css property of padding-right
			*/
			paddingRight: false,
			
			/*
			 ref:		DfNew.Animate.pars.paddingTop
			 type:		Parameter
			 returns:	Boolean|Number
			 default:	false
			 note:		animates the css property of padding-top
			*/
			paddingTop: false,
			
			/*
			 ref:		DfNew.Animate.pars.paddingBottom
			 type:		Parameter
			 returns:	Boolean|Number
			 default:	false
			 note:		animates the css property of padding-bottom
			*/
			paddingBottom: false,
			
			/*
			 ref:		DfNew.Animate.pars.marginLeft
			 type:		Parameter
			 returns:	Boolean|Number
			 default:	false
			 note:		animates the css property of margin-left
			*/
			marginLeft: false,
			
			/*
			 ref:		DfNew.Animate.pars.marginRight
			 type:		Parameter
			 returns:	Boolean|Number
			 default:	false
			 note:		animates the css property of margin-right
			*/
			marginRight: false,
			
			/*
			 ref:		DfNew.Animate.pars.marginTop
			 type:		Parameter
			 returns:	Boolean|Number
			 default:	false
			 note:		animates the css property of margin-top
			*/
			marginTop: false,
			
			/*
			 ref:		DfNew.Animate.pars.marginBottom
			 type:		Parameter
			 returns:	Boolean|Number
			 default:	false
			 note:		animates the css property of margin-bottom
			*/
			marginBottom: false,
			
			/*
			 ref:		DfNew.Animate.pars.onComplete
			 type:		Parameter
			 returns:	Function
			 default:	false
			 note:		anonymous function 
			 note:		sends class instance as the only argument
			*/
			onComplete: false,
			
			/*
			 ref:		DfNew.Animate.pars.onIteration
			 type:		Parameter
			 returns:	Function
			 default:	false
			 note:		anonymous function 
			 note:		sends class instance as the only argument
			*/
			onIteration: false,
			
			selectors: []
		});
		
		this.possibleSelectors = [
			'width','height','color','left','top','fontSize', 'lineHeight', 'letterSpacing',
			'paddingLeft','paddingRight','paddingTop','paddingBottom',
			'marginLeft','marginRight','marginTop','marginBottom',
			'opacity','backgroundColor', 'backgroundPosition'
		];
		
		this.running = false;
		this.iterations = false;
		this.currentIteration = false;
		this.animators = [];
		this.coords = [];
		this.history = [];
		this.hpointer = 0;
		
		return this;	
	},
	
	/*
	 ref:		DfNew.Animate.run
	 type:		Method
	 returns:	DfNew.Animate
	 arg:		DfNew.Animate.pars pars
	 arg:		Boolean fromHistory run the animation at the current pointer
	 note:		runs the animation based on the pars sent in or a step from the history
	*/
	run: function(pars,fromHistory){
		this.setPars(pars);
		
		//load with initial state of element
		if( this.history.length == 0 ){
			this.loadInitialState();
			this.hpointer = 0;
		}
		
		//load record in history array
		if( !fromHistory ){
			this.loadState();
			this.hpointer = this.history.length -1
		}
		
		//create an array of selector to animate
		this.createAnimators();
		
		
		if( this.animators.length == 0 && !fromHistory ){
			this.history.pop()
			this.hpointer--
		}
		
		//determine the iterations the animation will take
		this.setIterations();
		
		//create an array of interation steps, how the selectors are set for each iteration
		this.createCoordHash();
		
		//run though the coords array with the set pause value
		if( this.coords.length > 0 ){
			this.running = true;
			this.stepThroughAnimation();
		}
		return this;
	},
	
	/*
	 ref:		DfNew.Animate.getPossibleSelectors
	 type:		Method
	 returns:	Array
	 note:		gets all the available css selectors that can be animated
	*/
	getPossibleSelectors: function(){
		return this.possibleSelectors
	},
	
	/*
	 ref:		DfNew.Animate.getHistoryCount
	 type:		Method
	 returns:	Number
	 note:		gets the total number of animation steps ran on this instance
	*/
	getHistoryCount: function(){
		return this.history.length;
	},
	
	/*
	 ref:		DfNew.Animate.clear
	 type:		Method
	 returns:	DfNew.Animate
	 note:		stops the animation
	 note:		clears all memory of the instance
	*/
	clear: function(){
		this.running = false;
		this.animators = [];
		this.history = [];
		this.hpointer = 0;
		this.iterations = false;
		this.currentIteration = false;
		this.coords = [];
		return this;
	},
	
	/*
	 ref:		DfNew.Animate.terminate
	 type:		Method
	 returns:	DfNew.Animate
	 note:		stops the animation
	 note:		clears all memory of the current animation that is running 
	*/
	terminate: function(){
		running = false;
		coords = [];
		iterations = false;
		currentIteration = false;
		animators = [];
		return this;
	},
	
	/*
	 ref:		DfNew.Animate.pause
	 type:		Method
	 returns:	DfNew.Animate
	 note:		pauses the animation
	*/
	pause: function(ms){
		this.running = false;
		
		if (ms) {
			setTimeout(this.resume.bind(this), ms);
		}
		
		return this;
	},

	/*
	 ref:		DfNew.Animate.resume
	 type:		Method
	 returns:	DfNew.Animate
	 note:		resumes the animation
	*/
	resume: function(){
		this.running = true;
		this.stepThroughAnimation()
		return this
	},
	
	/*
	 ref:		DfNew.Animate.back
	 type:		Method
	 returns:	DfNew.Animate
	 arg:		DfNew.Animate.pars you can override or add any pars to the history before the
			animation is carried out
	 note:		runs the previous animation in the history 
	*/
	back: function(pars){
		if(this.hpointer > 0){
			this.hpointer--;	
			if(pars){
				Object.extend( this.history[ this.hpointer ], pars );
			}
			this.run(false, true);
		}
	},
	
	/*
	 ref:		DfNew.Animate.next
	 type:		Method
	 returns:	DfNew.Animate
	 arg:		DfNew.Animate.pars you can override or add any pars to the history before the
			animation is carried out
	 note:		runs the next animation in the history 
	*/
	next: function(pars){
		if( (this.hpointer + 1) < this.history.length ){
			this.hpointer++;	
			if(pars){
				Object.extend( this.history[ this.hpointer ], pars );
			}
			this.run(false, true);
		}
	},
	
	/*
	 ref:		DfNew.Animate.first
	 type:		Method
	 returns:	DfNew.Animate
	 arg:		DfNew.Animate.pars you can override or add any pars to the history before the
			animation is carried out
	 note:		animates back to its original css properties 
	*/
	first: function(pars){
		this.hpointer = 0;
		if(pars){
			Object.extend( this.history[ this.hpointer ], pars );
		}
		this.run(false, true);
	},
	
	/*
	 ref:		DfNew.Animate.last
	 type:		Method
	 returns:	DfNew.Animate
	 arg:		DfNew.Animate.pars you can override or add any pars to the history before the
			animation is carried out
	 note:		animates to the last index in the history
	*/
	last: function(pars){
		this.hpointer = this.history.length-1;
		if(pars){
			Object.extend( this.history[ this.hpointer ], pars );
		}
		this.run(false, true);
	},
	
	/*
	 ref:		DfNew.Animate.index
	 type:		Method
	 returns:	DfNew.Animate
	 arg:		Number index a specific index in the history to animate to
	 arg:		DfNew.Animate.pars you can override or add any pars to the history before the
			animation is carried out
	 note:		animates to a specific index in the history
	*/
	index: function(index, pars){
		this.hpointer = index-1;
		if(pars){
			Object.extend( this.history[ this.hpointer ], pars );
		}
		this.run(false, true);
	},
	
	/*
	 ref:		DfNew.Animate.toggle
	 type:		Method
	 returns:	DfNew.Animate
	 arg:		Number index a specific index in the history to animate to
	 arg:		DfNew.Animate.pars you can override or add any pars to the history before the
			animation is carried out
	 note:		toggles the history between 1 and 0
	 note:		runs the animation for the first time if not run yet
	 hint:		the static method of DfNew.Animate.toggleBy works well for common observers
			like click or hover
	 example:	<script type="text/javascript">
				var el = new DfNew.Animate($('xxx')).setPars({
					opacity: .5
				})
				
				el.getElement().observe('click', function(e){
					this.toggle()
				}.bind(el))
			</script>
	*/
	toggle: function(pars){
		if( this.history.length == 0 ){
			this.run(pars);	
		}
		else if( this.hpointer == 1 ){
			this.first(pars);
		}
		else if( this.hpointer == 0 ){
			this.last(pars);
		}
	},
    
	loadInitialState: function(){
		
		this.createSelectors();
		
		var copy = Object.clone( this.pars );
		
		var obj = {}
		for( var i=0; i<copy.selectors.length; i++ ){
			
			var val = this.element.getStyle(copy.selectors[i]);
			
			if(val != undefined){
				obj[copy.selectors[i]] = val ;  
			}else{
				obj[copy.selectors[i]] = false;  
			}
		}
		
		this.history.push( Object.extend(copy,obj) );
	},
	
	loadState: function(){
		this.createSelectors();
		this.history.push( Object.extend( {}, this.pars ) );
	},
	
	createSelectors: function(){
		this.pars.selectors.length == 0
		this.possibleSelectors.each(function(v){
			if( this.pars[v] !== false ){
				this.pars.selectors.push(v)
			}
		}.bind(this));
	},
	
	createAnimators: function(){
		this.animators = [];
		
		for(var i=0; i<this.history[this.hpointer].selectors.length; i++){
			var elem = this.history[this.hpointer].selectors[i];
			
			if(this.history[this.hpointer][elem] !== false){
				
				var rawTargetValue = this.history[this.hpointer][elem]
				
				//execute value function
				if(rawTargetValue.constructor == Function){
					rawTargetValue = rawTargetValue(this);
				}
				
				var val = this.element.getStyle(elem);
				
			var currentValue = this.getCurrentValue(elem,val);
				
				var targetValue = this.getCurrentValue(elem,rawTargetValue);
				
				var units = this.getUnits(rawTargetValue);
				if(!units){
					units = this.getUnits(val);
				}
				
				var delta = this.getDelta(targetValue,currentValue);
				
				if(delta){
					this.animators.push({selector:elem,delta:delta,current:currentValue,units:units});
				}
			}
		}
	},
	
	setIterations: function(){
		var p = this.history[this.hpointer];
		if(p.pause && p.time){
			this.iterations = Math.ceil(p.time/p.pause);
		}
		else if(p.skip && p.pause){
			this.iterations = Math.ceil( this.getMaxAbsVal() / p.skip);
		}
		this.currentIteration = 0;
	},
	
	createCoordHash: function(){
		this.coords = [];
		if( this.animators.length > 0 ){
			for(var i=0; i<this.iterations; i++){
				this.coords.push( this.buildAnimateStep(i) );
			}
		}
	},
	
	//recursive function that steps through the coords array based on pause value
	stepThroughAnimation: function(){
		if( this.running ){
			if( this.iterations > this.currentIteration){
				this.element.setStyle( this.coords[this.currentIteration] );
				this.currentIteration++;
				
				this.element.fire(':iteration', { iteration: this.currentIteration, iterations: this.iterations } );
				
				if( this.history[this.hpointer].onIteration){
					this.history[this.hpointer].onIteration(this);
				}
				
				setTimeout( this.stepThroughAnimation.bind(this), this.history[this.hpointer].pause);
			}else{
				this.running = false;
				
				this.element.fire(':complete', {pointer: this.hpointer});
				
				if( this.history[this.hpointer].onComplete){
					this.history[this.hpointer].onComplete(this);
				}
			}
		}
	},
	
	getMaxAbsVal: function(){
		var ary = [];
		for(var i=0; i<this.animators.length; i++){
			var val = this.animators[i].delta;
			if(val.constructor == Array){
				for(var j=0; j<val.length; j++){
					ary.push( Math.abs(val[j]) );
				}
			}else{
				ary.push( Math.abs(val) );
			}
		}
		return ary.max();
	},
	
	buildAnimateStep: function(rec){
		var obj = {}
		
		for(var i=0; i<this.animators.length; i++){
			var elem = this.animators[i];
			
			var val = this.getInteratedValue(elem,rec);
			
			if(rec == (this.iterations-1)){
				
				var rawTargetValue = this.history[this.hpointer][elem.selector]
				//execute value function
				if(rawTargetValue.constructor == Function){
				     rawTargetValue = rawTargetValue(this);
				}
				
				val = this.getCurrentValue( elem.selector, rawTargetValue );
			}
			obj[elem.selector] = this.setDisplayValue( elem.selector, val, elem.units );
		}
		return obj;
	},
	
	getInteratedValue: function(elem,rec){
			
		var ease = false;
		if( this.history[this.hpointer].ease.constructor == Function){
			ease = this.history[this.hpointer].ease
		}else{
			ease = this.history[this.hpointer].ease[elem.selector]
		}
		
		var val = false;
		if(elem.delta.constructor == Array){
			val = [];
			
			for(var i=0; i<elem.delta.length; i++){
				if( this.history[this.hpointer].pause && this.history[this.hpointer].time){
					val.push( this.getEasedValueForTime(elem.current[i], rec+1, elem.delta[i], ease ) );
				}
				else if( this.history[this.hpointer].pause && this.history[this.hpointer].skip){
					
					val.push( this.plotSkipValue( elem.current[i], elem.delta[i], rec ));
				}
			}
		}else{
			if( this.history[this.hpointer].pause && this.history[this.hpointer].time){
				val = this.getEasedValueForTime( elem.current, rec+1, elem.delta, ease )
			}
			else if(this.history[this.hpointer].pause && this.history[this.hpointer].skip){
				val = this.plotSkipValue(elem.current,elem.delta,rec);
			}
			
		}
		return val;
	},
	
	getEasedValueForTime: function(currentValue, interationStep, delta, ease ){
		return ease(interationStep, currentValue, delta, this.iterations )
	},
	
	plotSkipValue: function(current,delta,rec){
		if(delta > 0){
			var plot = current + ((rec+1) * ( this.history[this.hpointer].skip));
			
			if(plot <= current + delta){
				plot = plot;
			}else{
				plot = current + delta;
			}
		}else if(delta < 0){
			var plot = current - ((rec+1) * ( this.history[this.hpointer].skip));
			
			if(plot >= current + delta){
				plot = plot;
			}else{
				plot = current + delta;
			}
		}else{
			var plot = 0;
		}
		return plot;
	},
	
	//takes two numeric values or two numeric arrays and returns the difference of the numbers or an array of the differences of each number in the array
	getDelta: function(targetValue,currentValue){
		var res = false;
		var keepIt = false;
		if(targetValue.constructor == Array | currentValue.constructor == Array){
			res = [];
			for(var i=0; i<targetValue.length; i++){
				var delta = targetValue[i] - currentValue[i]
				if(delta){
					keepIt = true;
				}
				res.push(delta);
			}
			if(!keepIt){
				res = false;	
			}
		}else{
			res = targetValue - currentValue;
		}
		return res;
	},
	
	//takes a raw value and returns the unit measurement of that value
	getUnits: function(val){
		var str = false;
		if(/px$/.test(val)){
			str = 'px';	
		}else if(/%$/.test(val)){
			str = '%';	
		}else if(/em$/.test(val)){
			str = 'em';	
		}
		return str;
	},
	
	//(NEEDS SOME WORK on UNITS) takes a selector, a number or an array of numbers, and a unit and returns the presentation ready value of the number(s)
	setDisplayValue: function(elem,val,units){
		if(
			elem == 'width' | elem == 'height' | elem == 'top' | elem == 'left' | elem == 'fontSize'| elem == 'lineHeight'| elem == 'letterSpacing'
			| elem == 'paddingLeft' | elem == 'paddingRight' | elem == 'paddingTop' | elem == 'paddingBottom'
			| elem == 'marginLeft' | elem == 'marginRight' | elem == 'margingTop' | elem == 'marginBottom'
		   ){
			val = parseInt(val);
		}else if(elem == 'opacity'){
			val = val/100;
		}
		else if(elem == 'color' | elem == 'backgroundColor' ){
			val = this.hexFromArray(val);
		}
		else if(elem == 'backgroundPosition'){
			val = this.toBackgroundPositionString(val);
		}
		
		if(units && elem != 'backgroundPosition'){
			val += units;
		}
		
		return val;
	},
	
	//(NEEDS SOME WORK on UNITS) takes a numbers array [1,1] and returns the presentation value 1px 1px
	toBackgroundPositionString: function(val){
		str = '';
		for(var i=0; i<val.length; i++){
			str += Math.round(val[i]) + 'px ';
		}
		return str;
	},
	
	//takes a numbers array [255,255,255] and returns the presentation value #ffffff
	hexFromArray: function(val){
		var str = '#';
		for(var i=0; i<val.length; i++){
			str += parseInt(val[i]).toColorPart();
		}
		return str;
	},
	
	// takes a selector and a mixed raw value and returns the value(s) as a number or an array of numbers
	getCurrentValue: function(elem,val){
		if(
			elem == 'width' | elem == 'height' | elem == 'top' | elem == 'left' | elem == 'fontSize' | elem == 'lineHeight'| elem == 'letterSpacing'
			| elem == 'paddingLeft' | elem == 'paddingRight' | elem == 'paddingTop' | elem == 'paddingBottom'
			| elem == 'marginLeft' | elem == 'marginRight' | elem == 'marginTop' | elem == 'marginBottom'
		   ){
			val = parseInt(val);
		}
		else if(elem == 'opacity'){
			val = parseInt(val * 100);
		}
		else if(elem == 'color' | elem == 'backgroundColor' ){
			val = this.toColorArray(val);
		}
		else if(elem == 'backgroundPosition'){
			val = this.toBackgroundPositionArray(val);
		}
		
		return val;
	},
	
	//(NEEDS SOME WORK) takes background position info in the form of 1px 1px and converts it to [1,1]
	toBackgroundPositionArray: function(val){
		val = val.split(' ');
		for(var i=0; i<val.length; i++){
			val[i] = parseInt(val[i])
		}
		return val
	},
	
	//(NEEDS SOME WORK) takes color info in the form of #ffffff or rgb(255,255,255) and conterts it to [255,255,255] 
	toColorArray: function(val){
		if(/^#/.test(val)){
			val = val.replace(/^#/g,'').replace(/(..)/g,"$1,").replace(/,$/g,'').split(',');
			for(var i=0; i<val.length; i++){
				if(val[i].constructor == String){
					val[i] = parseInt(val[i],16);	
				}
				val[i] = Number(val[i])
			}
			
		}else if(/^rgb/.test(val)){
			val = val.replace(/^rgb\(|\)$/g,'').split(',');
			for(var i=0; i<val.length; i++){
				val[i] = Number(val[i])
			}
		}
		return val
	}
});

/*
 ref:		DfNew.Animate.toggleBy
 note:		This is a factory method for creating an instance of DfNew.Animate complete with listeners for
		toggling an animation object.
 type:		Static Method
 returns:	DfNew.Animate
 arg:		String|Element element
 arg:		String action choose between click and hover
 arg:		DfNew.Animate.pars pars
 example:	<script type="text/javascript">
			var animate = DfNew.Animate.toggleBy($('xxx'), 'click', {
				opacity: .65
			})
		</script>
*/
DfNew.Animate.toggleBy = function(element, action, pars){
	var animate = new DfNew.Animate(element);
	Object.extend( animate.pars, pars );
	if(action == 'click'){
		ele.observe('click', function(e){
			animate.toggle()
		}.bind(animate));
		
	}else if(action == 'hover'){
		ele.observe('mouseover', function(e){
			animate.toggle()
		}.bind(animate));
		
		ele.observe('mouseout', function(e){
			animate.toggle()
		}.bind(animate));
	}
	return animate;
}

/*
 ref:		DfNew.Drag
 extends:	DfNew.Ui
 returns:	DfNew.Drag
 note:		Makes an element dragable
 hint:		Element must be positioned Absolute,
 type:		Class
 arg:		String|Element element an extended dom node or dom node id string
 event:		this.element :start
 event:		this.element :stop
 event:		this.element :drag
 event:		this.element :dragX
 event:		this.element :dragY
 event:		this.element :enable
 event:		this.element :disable
*/
DfNew.Drag = Class.create(DfNew.Ui, {
	initialize: function($super, element){
		$super(element)
		
		this.setPars({
			/*
			 ref:		DfNew.Drag.pars.dirX
			 type:		Parameter
			 returns:	object|Boolean
			 choice:	true
			 choice:	false
			 choice:	hash with values for min and or max {min:,max:}
			 default:	false
			 note:		rules for draging left and right
			*/
			dirX: true, 
			
			/*
			 ref:		DfNew.Drag.pars.dirY
			 type:		Parameter
			 returns:	object|Boolean
			 choice:	true
			 choice:	false
			 choice:	hash with values for min and or max {min:,max:}
			 default:	false
			 note:		rules for draging up and down
			*/
			dirY: true,
			
			/*
			 ref:		DfNew.Drag.pars.onStart
			 type:		Parameter
			 returns:	Function
			 default:	false
			 note:		anonymous function 
			 note:		sends class instance as the only argument
			*/
			onStart: false,
			
			/*
			 ref:		DfNew.Drag.pars.onDrag
			 type:		Parameter
			 returns:	Function
			 default:	false
			 note:		anonymous function 
			 note:		sends class instance as the only argument
			*/
			onDrag: false,
			
			/*
			 ref:		DfNew.Drag.pars.onDragX
			 type:		Parameter
			 returns:	Function
			 default:	false
			 note:		anonymous function 
			 note:		sends class instance as the only argument
			*/
			onDragX: false,
			
			/*
			 ref:		DfNew.Drag.pars.onDragY
			 type:		Parameter
			 returns:	Function
			 default:	false
			 note:		anonymous function 
			 note:		sends class instance as the only argument
			*/
			onDragY: false,
			
			/*
			 ref:		DfNew.Drag.pars.onStop
			 type:		Parameter
			 returns:	Function
			 default:	false
			 note:		anonymous function 
			 note:		sends class instance as the only argument
			*/
			onStop: false,
			
			/*
			 ref:		DfNew.Drag.pars.onEnable
			 type:		Parameter
			 returns:	Function
			 default:	false
			 note:		anonymous function 
			 note:		sends class instance as the only argument
			*/
			onEnable: false,
			
			/*
			 ref:		DfNew.Drag.pars.onDisable
			 type:		Parameter
			 returns:	Function
			 default:	false
			 note:		anonymous function 
			 note:		sends class instance as the only argument
			*/
			onDisable: false,
			
			/*
			 ref:		DfNew.Drag.pars.dragElement
			 type:		Parameter
			 returns:	Array
			 default:	false
			 note:		accepts string CSS selector like 'div.dragable'
			*/
			dragElement: false
		});
		
		this._offsetX
		this._offsetY
		this._curX
		this._curY
		
		this._followIt = this.followIt.bindAsEventListener(this)
		this._startIt = this.startIt.bindAsEventListener(this)
		this._stopIt = this.stopIt.bindAsEventListener(this)
		
		return this
	},
	
	/*
	 ref:		DfNew.Drag.enable
	 type:		Method
	 returns:	DfNew.Drag
	 arg:		DfNew.Drag.pars pars
	 fire:		this.element :enable
	 note:		enables the element to be dragable
	*/
	enable: function(pars){
		this.setPars(pars)
		
		this.element.fire(':enable');
			
		if(this.pars.onEnable){
			this.pars.onEnable(this)
		}
		
		if(this.pars.dragElement){
			this.element.select(this.pars.dragElement).each(function(v){
				Event.observe(v,'mousedown', this._startIt);
			}.bind(this));
		}else{
			Event.observe(this.element,'mousedown', this._startIt);
		}
		
		return this
	},
	
	/*
	 ref:		DfNew.Drag.disable
	 type:		Method
	 returns:	DfNew.Drag
	 arg:		DfNew.Drag.pars pars
	 fire:		this.element :disable
	 note:		disable the element from being dragged
	*/
	disable: function(pars){
		this.setPars(pars)
		
		this.element.fire(':disable');
			
		if(this.pars.onDisable){
			this.pars.onDisable(this)
		}
		
		if(this.pars.dragElement){
			this.element.select(this.pars.dragElement).each(function(v){
				Event.stopObserving(v,'mousedown', this._startIt);
			}.bind(this));
		}else{
			Event.stopObserving(this.element,'mousedown', this._startIt);
		}
		
		return this
	},
	
	/*
	 ref:		DfNew.Drag.startIt
	 type:		Method
	 returns:	DfNew.Drag
	 arg:		DfNew.Drag.pars pars
	 fire:		this.element :start
	 note:		not intended to be called directly
	*/
	startIt: function(e){
		Event.stop(e); 
		
		Event.observe(document.body,'mousemove', this._followIt);
		Event.observe(document.body,'mouseup', this._stopIt);
		
		this._offsetX = this.offsetX(e)
		this._offsetY = this.offsetY(e)
		
		this.element.fire(':start')
		
		if(this.pars.onStart){
			this.pars.onStart(this)
		}
		
		return this
	},
	
	offsetX: function(e){
		return Event.pointerX(e) - this.getElement().positionedOffset().left
	},
	
	offsetY: function(e){
		return Event.pointerY(e) - this.getElement().positionedOffset().top
	},
	
	/*
	 ref:		DfNew.Drag.stopIt
	 type:		Method
	 returns:	DfNew.Drag
	 fire:		this.element :stop
	 note:		not intended to be called directly
	*/
	stopIt: function(e){
		Event.stop(e); 
		Event.stopObserving(document.body,'mousemove', this._followIt)
		Event.stopObserving(document.body,'mouseup',this._stopIt)
		
		if(this.pars.onStop){
			this.pars.onStop(this)
		}
		this.element.fire(':stop')
		
		return this
	},
	
	/*
	 ref:		DfNew.Drag.followIt
	 type:		Method
	 returns:	DfNew.Drag
	 fire:		this.element :drag
	 note:		not intended to be called directly
	*/
	followIt: function(e) {
		Event.stop(e); 
		
		if(this.pars.dirX){
			this.dirX(e)
		}
		
		if(this.pars.dirY){
			this.dirY(e)
		}
		
		if(this.pars.onDrag) {
			this.pars.onDrag(this)
		}
		this.element.fire(':drag')
		
		return this
	},
	
	/*
	 ref:		DfNew.Drag.dirX
	 type:		Method
	 returns:	DfNew.Drag
	 fire:		this.element :dragX
	 note:		not intended to be called directly
	*/
	dirX: function(e){
		this._curX = Event.pointerX(e) - this._offsetX
		
		if(this.pars.dirX.min || this.pars.dirX.min == 0){
			this.minDirX(e)
		}
		
		if(this.pars.dirX.max || this.pars.dirX.max == 0){
			this.maxDirX(e)
		}
		
		this.element.style.left = this._curX + 'px'
		
		if(this.pars.onDragX){
			this.pars.onDragX(this)
		}
		this.element.fire(':dragX')
	},
	
	minDirX: function(e){
		if(this._curX < this.pars.dirX.min){
			this._curX = this.pars.dirX.min
		}
	},
	
	maxDirX: function(e){
		if(this._curX > this.pars.dirX.max){
			this._curX = this.pars.dirX.max
		}
	},
	
	/*
	 ref:		DfNew.Drag.dirY
	 type:		Method
	 returns:	DfNew.Drag
	 fire:		this.element :dragY
	 note:		not intended to be called directly
	*/
	dirY: function(e){
		this._curY = Event.pointerY(e) - this._offsetY
		
		if(this.pars.dirY.min || this.pars.dirY.min == 0){
			this.minDirY(e)
		}
		
		if(this.pars.dirY.max || this.pars.dirY.max == 0){
			this.maxDirY(e)
		}
		
		this.element.style.top = this._curY + 'px'
		
		if(this.pars.onDragY){
			this.pars.onDragY(this)
		}
		this.element.fire(':dragY')
	},
	
	minDirY: function(e){
		if(this._curY < this.pars.dirY.min){
			this._curY = this.pars.dirY.min
		}
	},
	
	maxDirY: function(e){
		if(this._curY > this.pars.dirY.max){
			this._curY = this.pars.dirY.max
		}
	}
});

/*
 ref:		DfNew.Resize
 type:		Class
 extends:	DfNew.Drag
 returns:	DfNew.Resize
 event:		this.element :size
 event:		this.element :sizeHeight
 event:		this.element :sizeWidth
 arg:		string|Element element an extended dom node or dom node id string
*/
DfNew.Resize = Class.create(DfNew.Drag, {
	initialize: function($super, element) {
		$super(element)
		
		delete this.pars.dragElement
		
		this.setPars({
			
			/*
			 ref:		DfNew.Resize.pars.hitDepth
			 type:		Parameter
			 returns:	Number
			 default:	20
			 note:		padding inside the element that triggers resizing
			*/
			hitDepth: 20,
			
			/*
			 ref:		DfNew.Resize.pars.dirH
			 type:		Parameter
			 returns:	Boolean
			 default:	true
			 note:		can resize height
			*/
			dirH: true,
			
			/*
			 ref:		DfNew.Resize.pars.dirT
			 type:		Parameter
			 returns:	Boolean
			 default:	true
			 note:		can resize top
			*/
			dirT: true,
			
			/*
			 ref:		DfNew.Resize.pars.dirB
			 type:		Parameter
			 returns:	Boolean
			 default:	true
			 note:		can resize bottom
			*/
			dirB: true,
			
			/*
			 ref:		DfNew.Resize.pars.dirW
			 type:		Parameter
			 returns:	Boolean
			 default:	true
			 note:		can resize width
			*/
			dirW: true,
			
			/*
			 ref:		DfNew.Resize.pars.dirL
			 type:		Parameter
			 returns:	Boolean
			 default:	true
			 note:		can resize left side
			*/
			dirL: true,
			
			/*
			 ref:		DfNew.Resize.pars.dirR
			 type:		Parameter
			 returns:	Boolean
			 default:	true
			 note:		can resize right side
			*/
			dirR: true,
			
			/*
			 ref:		DfNew.Resize.pars.onSizeHeight
			 type:		Parameter
			 returns:	Function
			 default:	false
			 note:		anonymous function 
			 note:		sends class instance as the only argument
			*/
			onSizeHeight: false,
			
			/*
			 ref:		DfNew.Resize.pars.onSizeWidth
			 type:		Parameter
			 returns:	Function
			 default:	false
			 note:		anonymous function 
			 note:		sends class instance as the only argument
			*/
			onSizeWidth: false,
			
			/*
			 ref:		DfNew.Resize.pars.onSize
			 type:		Parameter
			 returns:	Function
			 default:	false
			 note:		anonymous function 
			 note:		sends class instance as the only argument
			*/
			onSize: false
		});
		
		this._curH
		this._curW
		this._pointerX
		this._pointerY
		this._sizeHeight = false
		this._sizeWidth = false
		this._startH
		this._startW
		this._startL
		this._startT
		
		return this
	},
	
	/*
	 ref:		DfNew.Resize.enable
	 override:
	 type:		Method
	 returns:	DfNew.Resize
	 fire:		this.element :enable
	*/
	enable: function(pars){
		this.setPars(pars)
		
		this.element.fire(':enable');
			
		if(this.pars.onEnable){
			this.pars.onEnable(this)
		}
		
		Event.observe(this.element,'mousedown', this._startIt);
		
		return this
	},
	
	/*
	 ref:		DfNew.Resize.disable
	 override:
	 returns:	DfNew.Resize
	 type:		Method
	 fire:		this.element :disable
	*/
	disable: function(pars){
		this.setPars(pars)
		
		this.element.fire(':disable');
			
		if(this.pars.onDisable){
			this.pars.onDisable(this)
		}
		
		Event.stopObserving(this.element,'mousedown', this._startIt);
		
		return this
	},
	
	/*
	 ref:		DfNew.Resize.followIt
	 override:
	 returns:	DfNew.Resize
	 fire:		this.element :start
	 type:		Method
	 note:		not intended to be called directly
	*/
	startIt: function(e){
		Event.stop(e); 
		
		this._offsetX = this.offsetX(e)
		this._offsetY = this.offsetY(e)
		
		this._pointerX = this.getPointerX(e)
		this._pointerY = this.getPointerY(e)
		
		this._startH = this.element.getHeight()
		this._startW = this.element.getWidth()
		
		this._startL = parseInt(this.element.getStyle('left'))
		this._startT = parseInt(this.element.getStyle('top'))
		
		this._curX = Event.pointerX(e) - this._offsetX
		this._curY = Event.pointerY(e) - this._offsetY
		
		if(this._pointerY <= this.pars.hitDepth){
			this._sizeHeight = 'top'
		}else if (this._pointerY >= this.element.getHeight() - this.pars.hitDepth) {
			this._sizeHeight = 'bottom'
		} else {
			this._sizeHeight = false
		}
		
		if(this._pointerX <= this.pars.hitDepth){
			this._sizeWidth = 'left'
		} else if (this._pointerX >= this.element.getWidth() - this.pars.hitDepth){
			this._sizeWidth = 'right'
		} else {
			this._sizeWidth = false
		}
		
		if(this._sizeHeight || this._sizeWidth){
			Event.observe(document.body,'mousemove', this._followIt);
			Event.observe(document.body,'mouseup', this._stopIt);
		}
		
		if(this.pars.onStart){
			this.pars.onStart(this)
		}
		
		this.element.fire(':start')
		
		return this
	},
	
	/*
	 ref:		DfNew.Resize.followIt
	 override:
	 returns:	DfNew.Resize
	 type:		Method
	 fire:		this.element :size
	 note:		not intended to be called directly
	*/
	followIt: function($super, e) {
		Event.stop(e); 
		
		if(this.pars.dirH && this._sizeHeight ){
			if(this._sizeHeight == 'top' && this.pars.dirT){
				this.dirY(e)
			}
			this.dirH(e)
		}
		
		if(this.pars.dirW && this._sizeWidth){
			if(this._sizeWidth == 'left' && this.pars.dirL){
				this.dirX(e)
			}
			this.dirW(e)
		}
		
		this.element.fire(':size')
		
		return this
	},
	
	/*
	 ref:		DfNew.Resize.dirH
	 type:		Method
	 fire:		this.element :sizeHeight
	 note:		not intended to be called directly
	*/
	dirH: function(e){
		if(this._sizeHeight == 'top' && this.pars.dirT){
			this._curH = this._startH + (this._startT - this._curY)
		} else if (this._sizeHeight == 'bottom' && this.pars.dirB){
			this._curH = this.getPointerY(e) + (this._startH - this._pointerY)
		}
		
		this.element.style.height = this._curH + 'px'
		
		if(this.pars.onSizeHeight){
			this.pars.onSizeHeight(this)
		}
		this.element.fire(':sizeHeight')
	},
	
	/*
	 ref:		DfNew.Resize.dirW
	 type:		Method
	 fire:		this.element :sizeHeight
	 note:		not intended to be called directly
	*/
	dirW: function(e){
		if(this._sizeWidth == 'left' && this.pars.dirL){
			this._curW = this._startW + (this._startL - this._curX)
		} else if (this._sizeWidth == 'right' && this.pars.dirR){
			this._curW = this.getPointerX(e) + (this._startW - this._pointerX)
		}
		
		this.element.style.width = this._curW + 'px'
		
		if(this.pars.onSizeWidth){
			this.pars.onSizeWidth(this)
		}
		this.element.fire(':sizeWidth')
	}
});	
