/************* SLIDE PANEL *****************/

function startSlide( aDir, aBtn, aCallBack )
{
	if (( appParams.state == "sliding" )
		|| ( aDir == 0 ))
		return;
	
	var panelWidth = 100*( domGlobals.clipper.offsetWidth )
			  		    /( domGlobals.slipper.offsetWidth );
	
	appParams.anim.slider.button    = aBtn;
	appParams.anim.slider.fromPanel =          appParams.currentPanel;
	appParams.anim.slider.toPanel   = 1*aDir + appParams.currentPanel;

	startMultiAnim
	(
		"slider",
		20,
		"cube",
		new Array
		(
			new multiAnimTarget( domGlobals.slipper, "marginLeft", -100*appParams.anim.slider.fromPanel, -100*appParams.anim.slider.toPanel, "%" )
		),
		"postSlide();"+aCallBack
	);
}

function postSlide()
{
	appParams.currentPanel = appParams.anim.slider.toPanel;
	if ( appParams.anim.slider.button )
		appParams.anim.slider.button.className = replaceAll( appParams.anim.slider.button.className, "-onn", "-off" );
	
	setSlipperForPanel( appParams.currentPanel );

	appParams.state = "normal";
}

function setSlipperForPanel( aPanel ) { domGlobals.slipper.style.marginLeft = (-100*aPanel) + "%"; }

/************* SHOW/HIDE INFO PANEL *************/

function setInfoState( aState ) { domGlobals.info.state = aState; }
function toggleInfo()
{
	setInfoState( !domGlobals.info.state );
	prepInfoAnim(  domGlobals.info.state );
			
	startMultiAnim
	(
		"informer",
		10,
		"cube",
		new Array( new multiAnimTarget( domGlobals.info.panel, "top", ( domGlobals.info.state ? 100 : 0 ), ( domGlobals.info.state ? 0 : 100 ), "%" ) ),
		"postInfoAnim()"
	);
}
function prepInfoAnim( aInfoState ) {
	for ( var aIdx = 0; aIdx < domGlobals.info.showBtns.length; aIdx++ )
		setStateForElement(  aInfoState, domGlobals.info.showBtns[aIdx] );
	setStateForElement( !aInfoState, domGlobals.info.hideBtn );
}
function postInfoAnim() {}

/************** SHOW/HIDE POPUP TEXT ***************/

var textState = false;


function reflowText()
{
	if ( textState )
	{
		var maxTextHeight = maxTextHeightForOrientation( appParams.orientation );
		document.getElementById("pop-text-scrollbox").style.maxHeight = maxTextHeight + "px";
		document.getElementById("pop-text-scrollbox").style.height    = maxTextHeight + "px";
	}
}

function maxTextHeightForOrientation( aOrient )
{
	return ( aOrient == "portrait" ? 480 - 41 - 44 : 320 - 41 - 32 ) 
		- document.getElementById("pop-title").offsetHeight;
}

function setTextState( aState ) { textState = aState; }
function toggleText()
{
	setTextState( !textState );
	prepTextAnim(  textState );

	document.getElementById("pop-scrollnote").style.display = "none";
	
	var maxTextHeight   = maxTextHeightForOrientation( appParams.orientation );
	var textStartHeight = document.getElementById("pop-text-scrollbox").offsetHeight;
	var textEndHeight   = ( textState ? maxTextHeight : 0 );
	
	if ( document.getElementById("pop-text").offsetHeight > maxTextHeight )
		document.getElementById("pop-scrollnote").style.display = "block";

	document.getElementById("pop-text-scrollbox").style.maxHeight = maxTextHeight + "px";
	
	startMultiAnim(
		"actor",
		10,
		"cube",
		new Array(
			new multiAnimTarget( document.getElementById("pop-text-scrollbox"), "height", ""+textStartHeight, ""+textEndHeight, "px" ),
			new multiAnimTarget( document.getElementById("tbbtn-read"), "opacity", ""+(textState ? 1.0 : 0.0 ), "" + (textState ? 0.0 : 1.0 ), "" ),
			new multiAnimTarget( document.getElementById("tbbtn-hide"), "opacity", ""+(textState ? 0.0 : 1.0 ), "" + (textState ? 1.0 : 0.0 ), "" ),
			new multiAnimTarget( document.getElementById("pop-text-scrollbox"), "scrollTop", "current", "0", "" )
//			new multiAnimTarget( document.getElementById("scrollNotice"), "opacity", "current", ( willNeedToScroll ? 1.0 : 0.0 ), "" )
		),
		"postTextAnim()"
	);
}


function prepTextAnim( aTextState )
{
	setStateForElement(  aTextState, document.getElementById("tbbtn-read") );
	setStateForElement( !aTextState, document.getElementById("tbbtn-hide") );
}
function postTextAnim()
{
	setStateForElement( false, document.getElementById("tbbtn-read") );
	setStateForElement( false, document.getElementById("tbbtn-hide") );
}

/************** MULTI-ANIMATION ENGINE **************/

function multiAnimObject( aType )
{
	this.type       = aType;
	this.running    = false;
	this.timeout    = null;
	this.counter    = 0;
	this.maxCounter = 0;
	this.easeType   = "line";
	this.elems      = null;
	this.props      = null;
	this.startVals  = null;
	this.endVals    = null;
	this.valUnits   = null;
	this.callback   = null;
	this.button     = null;
	this.fromPanel  = null;
	this.toPanel    = null;
	
	this.step       = function() { stepMultiAnim( this ); };

	return this;
}

function multiAnimTarget( aElement, aProp, aStartVal, aEndVal, aValUnit )
{
	if ( aStartVal == "current" )
	{
		if ( aProp == "scrollTop" )
			aStartVal = aElement.scrollTop;
		else
		{
			aStartVal = aElement.style[aProp];
			
			if (( aProp == "top" ) || ( aProp == "bottom" ) || ( aProp == "left" ) || ( aProp == "right" ))	
				aStartVal = parseFloat( aStartVal );
		}
	}
	
	this.elem     = aElement;
	this.prop     = aProp;
	this.startVal = aStartVal;
	this.endVal   = aEndVal;
	this.valUnit  = aValUnit;

	return this;	
}

function startMultiAnim( aMAnimType, aCount, aEaseType, aTargets, aCallBack )
{
	var aMAnim = appParams.anim[aMAnimType];
	
	aMAnim.running    = true;
	aMAnim.counter    = -1;
	aMAnim.maxCounter = aCount;
	aMAnim.easeType   = aEaseType;
	aMAnim.targets    = aTargets;
	aMAnim.callback   = aCallBack;
	
	aMAnim.timeout    = setTimeout( "appParams.anim."+aMAnimType+".step()", 0 );
}

function stepMultiAnim( aMAnim )
{
	aMAnim.counter += 1;
	aMAnim.progress = animProgressForCountMaxType( aMAnim.counter, aMAnim.maxCounter, aMAnim.easeType );
	
	rUpdateMultiAnimTargetAtIndexForProgress( aMAnim, 0, aMAnim.progress );
	
	if ( aMAnim.counter < aMAnim.maxCounter )
		aMAnim.timeout = setTimeout( "appParams.anim."+aMAnim.type+".step()", 0 );
	else
	{
		aMAnim.running = false;
		aMAnim.timeout = setTimeout( aMAnim.callback, 0 );
	}		
}
function animProgressForCountMaxType( aCount, aMax, aEaseType )
{
	var theResult = ( aMax == 0 ? 0 : aCount / aMax );
	
	switch( aEaseType )
	{
		case "trig": theResult = ( 1 - Math.cos( Math.PI * theResult ) )/2.0; break;
		case "cube":
		{
			if ( theResult > 0.5 )
			{
				theResult = ( 1.0 - theResult );
				theResult = 1.0 - 4*theResult*theResult*theResult;
			}
			else
				theResult = 4*theResult*theResult*theResult;
		}
		break;
	}

	return theResult;
}
function rUpdateMultiAnimTargetAtIndexForProgress( aMAnim, aIdx, aProgress )
{
	if ( aIdx < aMAnim.targets.length )
	{
		var theTarget  = aMAnim.targets[aIdx];
		var thePropVal = easeFromStartEndProgress( 1*theTarget.startVal, 1*theTarget.endVal, aProgress )
						+ theTarget.valUnit;
	
		switch ( theTarget.prop )
		{
			case "scrollTop": theTarget.elem.scrollTop             = thePropVal; break;
			default:          theTarget.elem.style[theTarget.prop] = thePropVal; break;
		}
		
		rUpdateMultiAnimTargetAtIndexForProgress( aMAnim, 1+aIdx, aProgress );
	}	
}

function easeFromStartEndProgress( aStart, aEnd, aProgress ) { return 1*aStart + ( 1*aEnd - 1*aStart )*aProgress; }


/***********
UI UTILITIES
***********/

function setStateForElement( aState, aElement )
{
	var bState = ( aState ? "-off" : "-onn" );
	aState = ( aState ? "-onn" : "-off" );
	
	aElement.className = replaceAll( aElement.className, bState, aState );
}

function updateProgressIndicator( aId, aPercent )
{
	aPercent += 100 * Math.min( 3000, ( new Date() ).getTime() - imageLoadTimeStamp ) / 3000.0 / imagesToLoad.length;
	aPercent = Math.min( aPercent, 100 );
	
	document.getElementById(aId).style.width = ( aPercent + "%" );
}

/****************
GENERIC UTILITIES
****************/

function replaceAll( aSrcStr, aFindStr, aReplaceStr ) { return aSrcStr.replace( new RegExp( aFindStr, "g" ), aReplaceStr ); }

function dateFromYYYYMMDD( aYYYYMMDD )
{
	var theY = 1*aYYYYMMDD.substring( 0, 4 );
	var theM = 1*aYYYYMMDD.substring( 4, 6 );
	var theD = 1*aYYYYMMDD.substring( 6, 8 );
	
	var theMonths = new Array( "Zer", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" );
	
	return theD + " " + theMonths[theM];
}

function ordinalString( aNum ) {
	return new Array( "Zeroth", "First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth" )[aNum];
}

function capitalizeString( aStr )
{
	var theResult = '';
	
	aStr = aStr.split(' ');
	for ( var aIdx = 0; aIdx < aStr.length; aIdx++ )
		theResult += aStr[aIdx].substring(0,1).toUpperCase() + aStr[aIdx].substring(1, aStr[aIdx].length) + ' ';
		
	return theResult;
}

function goToForm( aURL ) { window.open( aURL ); }
function goToSite( aSiteDotCom ) {
	
	switch ( aSiteDotCom )
	{
		case "www.astrology.com": aSiteDotCom += ASTROLOGY_OMNITURE_CODE; break;
		case "www.ivillage.com":  aSiteDotCom +=  IVILLAGE_OMNITURE_CODE; break;
		
		case "www.tricochet.com":
		case "www.daylateanddollarshort.com":
		case "www.iconicon.net":
			aSiteDotCom += DLDS_SENDER_CODE;
			break;
	}
	
	aSiteDotCom  = "http://"+aSiteDotCom;
	
	window.open( aSiteDotCom );
}



/*********************************************
Apple/iPhone-Related Methods
*********************************************/
function hideAddressBar()
{
	setTimeout( "window.scrollTo(0, 1)", 10 );
}

function changeOrientation()
{
	if (( window.orientation == undefined ) || ( window.orientation % 180 == 0 ))
		setOrientation("portrait");
	else
		setOrientation("landscape");
}

function setOrientation( aOrient )
{
	appParams.orientation = aOrient;
	
	body.setAttribute( "orient", aOrient );
	
	hideAddressBar();
	postSetOrientation();	
}
//function postSetOrientation() {} /** FOR CUSTOMIZED BEHAVIOR **/

function  widthForOrientation( aOrient ) { return ( aOrient == "portrait" ? 320 : 480 ); }
function heightForOrientation( aOrient ) { return ( aOrient == "portrait" ? 416 : 268 ); }

function resizeWindowForOrientation( aOrient )
{
	resizeInnerTo( widthForOrientation( aOrient ), heightForOrientation( aOrient ) );
}

function resizeInnerTo(w,h)
{
	var inW = top.innerWidth;
	var inH = top.innerHeight;
	
	top.resizeBy( w - inW, h - inH );
}
