/*:: Script Information ::Title       : expandable and collasible menu with state stored by cookieAuthor      : livibetterCreated date: 04/28/2006Updated date: 22:34 10/26/2006Version     : 0.2.1.2Credit      : cookies.js by RoBorg			  lb_common.js 0.1			  lb_html.js 0.1License     : GNU Lesser General Public LicenseCopyright   : 2006 livibetter:: Contact Information ::eMail		: web@livibetter.comMSN			: livibetter@gmail.comWebsite		: http://www.livibetter.com*/c.setExpires(new Date(new Date().getTime() + 604800000));/*	Class: clb_menu_method		Describe how the menu would be collapsed or expanded	Parameters:		duration:			number				in millisecond.				0 means instantly collapsed or expanded			Default 1000ms		stepsSizing:			number				how many sizing steps in duration.				0 means instant sizing.			Default=10		stepsFading :			number				how many fading steps in duration.				0 means instant fading.			Default=10*/function clb_menu_method(duration, stepsSizing, stepsFading){	// Set duration of sizing and fading	this.duration = (typeof duration=="number")?duration:1000;	// Set steps of sizing if there is a value and duration != 0, or no sizing	this.stepsSizing = (this.duration==0)?0:((typeof stepsSizing=="number")?stepsSizing:10);	// Set interval for sizing	this.intervalSizing = (this.stepsSizing>0)?(this.duration / this.stepsSizing):0;	// Set steps of fading, same as how sizing	this.stepsFading = (this.duration==0)?0:((typeof stepsFading=="number")?stepsFading:10);	// Set interval for fading	this.intervalFading = (this.stepsFading>0)?(this.duration / this.stepsFading):0;	}/*	Class: clb_menu*/function clb_menu(Object, bCollapse, methodCollapsing, sizeCollapsed, sizeExpanded, rangeOpacity, methodCookie, fOnDone){	if(typeof Object!="object") return;	this.scan = scan;	this.toggle = toggle;	this.sizing = sizing;	this.fading = fading;	this.checkDone = checkDone;	/*		Initial		Parameters:			undefined, null:				Default lb_menu object.			Object:				object					A Div needs lb_menu functionality.			bCollapse:				boolean					Is this menu collapse at first time(can't find data in cookie)?				Default false			methodCollapsing:				clb_menu_method					Default Collapsing Method			sizeCollapsed:				clb_size					Collapsed Size of menu				Default 0, 0			sizeExpanded:				clb_size					Expanded Size of menu				Default offsetWidth, offset Height of Object			rangeOpacity:				clb_range					Define how to change opacity.				Default 0 to 100;			methodCookie:				undefined, null					only default method				clb_menu_method					Collapsing Method for cookie say collapse. If this is not set, the default method will be used.			fOnDone:				undefined, null					no callback function is needed				function					After menu collapsed or expanded, it invokes fOnDone(this), which this is current menu object.	*/	if(arguments.length>0){		// *****************		// Initial variables		this.target = Object;		// Assign this menu to target Object		Object.menu = this;		// Set style for Object 		this.target.style.overflow = "hidden"		// Set default method		this.methodDefault = methodCollapsing;		// Set collapsed size		if(sizeCollapsed == null)			this.sizeCollapsed = new clb_size(0,0);		else			this.sizeCollapsed = sizeCollapsed;		// Set expanded size		if(sizeExpanded == null)			this.sizeExpanded = new clb_size(this.target.offsetWidth, this.target.offsetHeight);		else			this.sizeExpanded = sizeExpanded;		// Set opacity range		if(rangeOpacity == null)			this.rangeOpacity = new clb_range(0, 100);		else			this.rangeOpacity = rangeOpacity;		// Set callback functions		if(typeof fOnDone == "function")			this.onDone = fOnDone;		// Set initial state		this.state = "Expanded";		// ***********************		// Check cookies for state		statePrev = c.getValue("lb_menu_" + this.target.id);		switch(statePrev){			case "Collapsed":				bCollapse = true;	// contunue at next case			case undefined:				// It is the first time				if(bCollapse == true)					// Collapse at first time, same as collapsing by cookie					if(methodCookie!=null)						this.toggle("collapse", methodCookie);					else						this.toggle("collapse"); // Use default method										break;			default:				// Expanded, do nothing				// NOTE: assuming sizeExpanded equals offsetWidth, offsetHeight always.			}		}	/*		Method: scan		Paraments:	*/	function scan(){		// TODO: Not implemented yet.		}	/*		Method: toogle		Paraments:			method:				undefined, null:					Using default method and toggle				sToggle:					"expand"						Do expand					"collapse"						Do expand					"toggle", null, undefined						Do toggle				clb_menu_method:					overrides method for toogling	*/	function toggle(sToggle, method){		// Check state		if(this.state=='Expanding' || this.state=='Collapsing') return;		if(this.state=='Expanded' && sToggle=='expand') return;		if(this.state=='Collapsed' && sToggle=='collapse') return;		// Use default or override		this.methodCurrent = (method==null)?this.methodDefault:method;		// Set count for callback function.		this.countdown = 2;				// ****************		// Starting		this.methodCurrent.countSizing = 0;		this.methodCurrent.countFading = 0;		this.state = (this.state=='Expanded')?'Collapsing':'Expanding';		setTimeout("document.getElementById('"+this.target.id+"').menu.sizing()", Math.round(this.methodCurrent.intervalSizing));		setTimeout("document.getElementById('"+this.target.id+"').menu.fading()", Math.round(this.methodCurrent.intervalFading));		}	/*		Method: sizing				for collapsing or expanding		Parameters:	*/	function sizing(sID){		var bExpanding = this.state=="Expanding";		this.methodCurrent.countSizing++;		if(this.methodCurrent.countSizing>=this.methodCurrent.stepsSizing){			// End of sizing			if(bExpanding){				this.target.style.width  = this.sizeExpanded.width + 'px';				this.target.style.height = this.sizeExpanded.height + 'px';				}			else{				this.target.style.width  = this.sizeCollapsed.width + 'px';				this.target.style.height = this.sizeCollapsed.height + 'px';				}			this.checkDone();			}		else{			// In progress			var intervalWidth  = (this.sizeExpanded.width  - this.sizeCollapsed.width )/this.methodCurrent.stepsSizing*this.methodCurrent.countSizing*(bExpanding*2 - 1);			var intervalHeight = (this.sizeExpanded.height - this.sizeCollapsed.height)/this.methodCurrent.stepsSizing*this.methodCurrent.countSizing*(bExpanding*2 - 1);			this.target.style.width  = (((bExpanding)?this.sizeCollapsed.width :this.sizeExpanded.width ) + intervalWidth ) + "px";			this.target.style.height = (((bExpanding)?this.sizeCollapsed.height:this.sizeExpanded.height) + intervalHeight) + "px";			// Keep sizing			setTimeout("document.getElementById('"+this.target.id+"').menu.sizing()", Math.round(this.methodCurrent.intervalSizing));			}		}	/*		Method: fading				for fading in or out		Parameters:	*/	function fading(){		var bExpanding = this.state=="Expanding";		this.methodCurrent.countFading++;		if(this.methodCurrent.countFading>=this.methodCurrent.stepsFading){			// End of fading			lb_html_setOpacity(this.target, (bExpanding)?this.rangeOpacity.to:this.rangeOpacity.from);			this.checkDone();			}		else{			// In progress			var interval = (this.rangeOpacity.to - this.rangeOpacity.from)/this.methodCurrent.stepsFading*this.methodCurrent.countFading*(bExpanding*2 - 1);			lb_html_setOpacity(this.target, ((bExpanding)?this.rangeOpacity.from:this.rangeOpacity.to) + interval);			// Keep fading			setTimeout("document.getElementById('"+this.target.id+"').menu.fading()", Math.round(this.methodCurrent.intervalFading));			}		}	/*		Method: checkDone				Changing state and check both sizing and fading are done. If both are done, then call invoke onDone.		Parameters:	*/	function checkDone(){		this.countdown--;		if(this.countdown==0){			this.state = (this.state=="Expanding")?"Expanded":"Collapsed";			c.setValue("lb_menu_" + this.target.id, this.state);			if(typeof this.onDone == "function")				this.onDone(this);	// Invoke event			}		}	}