
// don't use stuff in this class; it's private. see below.
//
EFX = {
	
	opacitySpeed : "normal",	// "normal", "fast"
	expandSpeed : "normal",
	onComplete : null,
	
	// 0-1
	setOpacity : function(e, o) {
		var sty = e.style;
		if ( Math.abs(o) < 0.08) o = 0;
		if ( Math.abs(o-1) < 0.08) o = 1;
		if (o == 0 && sty.visibility != "hidden") sty.visibility = "hidden";
		else if (sty.visibility != "visible") sty.visibility = "visible";
		sty.filter = "alpha(opacity=" + o*100 + ")";
		sty.opacity = o;
	},

	setHeight : function(e,ht) {
		var sty = e.style;
		if ( ht > 0) {
			sty.display = 'block';
			sty.overflow = 'hidden';
		} else {
			sty.display = 'none';
		}
		sty.height = Math.floor(ht) + 'px';
	},
	
	doneHeight : function(e) {
		if ( e.shootFor > 0)
			e.style.overflow = "visible";	// allow floating layers to show now
	},

	// inputs: [current time] [start position] [total distance to move] [total time to take]
	//
	easeOutQuad : function(t, b, c, d) { return -c *(t/=d)*(t-2) + b; },
	easeInQuad : function (t, b, c, d) { return c*(t/=d)*t + b; },

	// this function handles one frame of motion, then resets itself to run again
	//
	offsetValue : function( eltId, func, easingFunc) {
		var e = $(eltId);

		func( e, easingFunc(e.curStep, e.startAt, e.travelDistance, e.steps) );

		if ( ++e.curStep < e.steps) {
			var f = 'EFX.offsetValue("' + eltId + '",' + e.funcName + ',' + e.easingFunc + ');';
			setTimeout(f, e.stepDelay);
		}
		else {
			func( e, e.shootFor);
			// ugh... we need to set the final height to AUTO. otherwise, any
			// expanding boxes INSIDE this one won't force the parent to grow
			// (because it has a fixed height!)
			if ( func == EFX.setHeight) {
				if ( e.shootFor > 0)
					e.style.height="auto";
			}
			if ( e.completeFunc)	// internal completion function
				e.completeFunc(e);
			if ( EFX.onComplete)	// external
				EFX.onComplete();
		}
	},

	toggleOpacity : function(eltId) {
		var e = $(eltId),
			sty = e.style,
			o = sty.opacity, fnc;

		if ( typeof o == 'undefined' || o.length == 0) {
			// test for what's real & true... display:none / visibility:hidden (must be set inline; not in style sheet)
			if ( sty.display == 'none') {
				EFX.setOpacity(e,0);
				sty.display = 'block';
				o = 0;
			}
			else if ( sty.visibility == 'hidden')
				o = 0;
			else
				o = 1;
		}

		e.stepDelay = 20;	// could be parameterized when needed
		e.steps = (EFX.opacitySpeed == "fast" ? (o>0 ? 10 : 10) : (o>0 ? 16 : 28));
		e.curStep = 0;
		e.startAt = parseInt(o);	// assume 0 or 1 to start...
		e.shootFor = (o>0 ? 0 : 1);
		e.funcName = 'EFX.setOpacity';
		e.travelDistance = (e.shootFor - e.startAt);
		e.easingFunc = 'EFX.easeOutQuad';

		fnc = 'EFX.offsetValue("'+eltId+'",'+e.funcName+','+e.easingFunc+')';
		setTimeout(fnc,e.stepDelay);
	},

	// returns a width/height pair
	getOriginalSize : function(e) {
		if (e.calcSizes) return e.calcSizes;	// caching means the contents can't change!
		if (e.style.display != 'none')
			sizes = {width: e.offsetWidth, height: e.scrollHeight};
		else {
			// from prototype:getDimensions
			// all wid/ht properties give 0 if display=none,
			// so enable the element temporarily
			//
			var sty = e.style,
				origVis = sty.visibility,
				origPos = sty.position,
				origHt = sty.height;
			sty.visibility = 'hidden';
			sty.position = 'absolute';
			sty.height = 'auto';
			sty.display = '';
			var origWid = e.offsetWidth, // clientWidth,
				origHt = e.scrollHeight; // clientHeight;
			sty.display = 'none';
			sty.position = origPos;
			sty.visibility = origVis;
			sty.height = origHt;
			sizes = {width: origWid, height: origHt};
		}
		e.calcSizes = sizes;
		return sizes;
	},

	toggleExpand : function(eltId) {
		var e = $(eltId), sizes,
			ht = this.getOriginalSize(e).height;

		e.stepDelay = 15;
		e.curStep = 0;
		if ( e.style.display == 'none') {	// open up
			e.startAt = 0;
			e.shootFor = ht;
			e.steps = (EFX.expandSpeed == "fast" ? 14 : 20);
		} else {
			e.startAt = ht;
			e.shootFor = 0;
			e.steps = (EFX.expandSpeed == "fast" ? 9 : 16);
		}
		e.easingFunc = 'EFX.easeOutQuad';
		e.funcName = 'EFX.setHeight';
		e.travelDistance = (e.shootFor - e.startAt);
		e.completeFunc = EFX.doneHeight;

		fnc = 'EFX.offsetValue("'+eltId+'",'+e.funcName+','+e.easingFunc+')';
		setTimeout(fnc,e.stepDelay);
	}
};

//--------------

	function setupOnePopFade( anc) {
		toggleFadeFunction = function(e) {
			EFX.toggleOpacity(this.id+'Pop');
			cancelEvent(e,false);
			return false;
		};
		addEvent(anc,'click',toggleFadeFunction,true);
	}

	function setupOnePopExpand( anc) {
		toggleExpandFunction = function(e) {
			EFX.toggleExpand(this.id+'Pop');
			cancelEvent(e,false);
			return false;
		};
		addEvent(anc,'click',toggleExpandFunction,true);
	}

// note: for popExpand, the toggled div cannot have padding. it must also have DISPLAY:NONE set inline
registerAnchorType( {cls:"popExpand", apply:setupOnePopExpand} );

// for popFade: padding is fine. the toggled div must have VIS:HIDDEN inline (and have layout)
registerAnchorType( {cls:"popFade", apply:setupOnePopFade} );
