/*
Copyright _ 2005, Apple Computer, Inc.  All rights reserved.
NOTE:  Use of this source code is subject to the terms of the Software
License Agreement for Mac OS X, which accompanies the code.  Your use
of this source code signifies your agreement to such license terms and
conditions.  Except as expressly granted in the Software License Agreement
for Mac OS X, no other copyright, patent, or other intellectual property
license or right is granted, either expressly or by implication, by Apple.
*/

/* 
All the code not by Apple, Copyright 2005, Guy Drieghe D.

This version: 1.1 -- 21 July 2005 -- Antwerp, Belgium

*/



/* Timer initialisation and other timer stuff */
/* -- used for the auto-flipback things       */

var secs;
var timerID = null;
var timerRunning = false;
var delay = 1000;

// initialise the timing variable for the auto-flipback
var tijd = 3;		
//document.getElementById("autoflip").options[5].selected='true';

function InitializeTimer(tijd)
{
    secs = tijd;
    StopTheClock();
    StartTheTimer();
}

function StopTheClock()
{
    if(timerRunning)
        clearTimeout(timerID);
    timerRunning = false;
}

function StartTheTimer()
{
    if (secs==0)
    {
        StopTheClock();
        
        var prefShown = document.getElementById("prefs");
        // make sure the card doesn't flip back when the prefs are visible -- damn, that was fun !
        if (prefShown.style.display != 'block') { 
        	hideCard();		// hide the back card, after 'secs' seconds -- the infamous auto-flipback feature
        }
    }
    else
    {
        self.status = secs;
        secs = secs - 1;
        timerRunning = true;
        timerID = self.setTimeout("StartTheTimer()", delay);
    }
}

/* ------------------------------------------------------------------------ */
/* Let's keep things tidy and cycles down when we leave the Dashboard Layer */

if (window.widget) {
	widget.onhide = onhide;
}

function onhide () {
	secs = 0;						//relax the time when the widget is not shown
	StartTheTimer();				//stop the timer which flips back the card, so the card flips back - hehe
	prefs.style.display="none";		//make sure the prefs back is not shown
	back.style.display="none";		//make sure the card back is not shown, just for good measure
}



/* Define the dynamic text variables for the front and prefs-back ----------- */
/* 1 = 4th version, 2 = 3rd, etc...   --------------------------------------- */

var revision1 = 'Fourth Again Revised and More Universal Edition<br>&copy; 1975, 1978, 1979 Brian Eno and Peter Schmidt<br>&copy; Christmas 1996 Brian Eno, Peter Norton, Pae White';
var revision2 = 'Third Again Revised Edition<br>&copy; 1975, 1978, 1979 Brian Eno and Peter Schmidt';
var revision3 = 'Second Revised Edition<br>&copy; 1975, 1978 Brian Eno and Peter Schmidt';
var revision4 = 'First Edition, printed January 1975<br>&copy; 1975 Brian Eno and Peter Schmidt';

var edition1 = "Cuarta Edicion";
var edition2 = "Tercera Edicion";
var edition3 = "Segunda Edicion";
var edition4 = "Primera Edicion Original";

// ------------------------- //


/* set the version popup according to the prefs (last chosen option)...
  'welke' & 'hoelang' are the parameters send through by the setup() function to retrieve the prefs */
function setPop(welke) {
	document.getElementById("vers").options[welke].selected='true';
}

function setPop2(hoelang) {
	document.getElementById("autoflip").options[hoelang].selected='true';
}

function prefsKey(key) { 
	return widget.identifier + "-" + key;
}


// the random number generator
// part of this code by Johnny Larocque -- min/max addition by myself (as if that was difficult, ha!)

function rndm(minn, maxn) {
	rnd.today=new Date();
	rnd.seed=rnd.today.getTime();
	
	function rnd() {
		rnd.seed = (rnd.seed*9301+49297) % 233280;
		return rnd.seed/(233280.0);
	};
	
	function rand(number) {
		return Math.ceil(rnd()*number);
	};
	random_num = rand(((maxn+1)-minn))+(minn-1); /* generates a random number between minn and maxn */
	return random_num;
}


var num;	// too lazy to put this where the other initial variables are...


/* ************************************************************************************ */
/* ******************** the main core of the program: randomizing the cards *********** */
/* ************************************************************************************ */
function rotate() {

	var currPop = document.getElementById("vers").options.selectedIndex;

	currPop = currPop + 1;	//indices in the popup start at 0, so we add 1 to make life easier
	
	// select the right range in the aphorisms array
	switch(currPop) {	// which edition did we choose ?
		case 1:
			num = rndm(1,100);  // Fourth Edition
			break;
		case 2:
			num = rndm(101,222);  // Third Edition
			break;
		case 3:
			num = rndm(223,350);  // Second Edition
			break;
		case 4:
			num = rndm(351,463);  // First Edition
			break;
	}
}


/***********************************/
// SAVING AND RETRIEVING PREFERENCES
/***********************************/

// setup() is run when the body loads.  It checks to see if there is a preference for this widget
// and if so, applies the preference to the widget.

function setup()
{
	if(window.widget)  	//we need to be running in the Dashboard Layer here !
	{ 
		//onhide(); 	//forgot why this is here, but we don't seem to need it
		
		/* retrieve prefs */
    	var obliquePref = widget.preferenceForKey("obliquePref");  		//prefs for version
    	var obliqueTime = widget.preferenceForKey("obliqueTime");  		//prefs for autoflip time
    	
    	if (obliquePref && obliquePref.length > 0) 	// if the prefs are not empty, restore them //
    												// we need to check on only one of the pref keys //
    	{ 
    		/* write back the info texts, derived from "obliquePref" pref (which is simply a number from 1 to 4.
    		   Call the setPop() function to write back the position of the popup */
    	
    		/* first let's handle the "version popup" */
    		switch (obliquePref) {
				case '1':
					document.getElementById("revision").innerHTML = revision1;	//write the dynamic texts to the front
					document.getElementById("edition").innerHTML = edition1;
					document.getElementById("vers").options[0].selected='true';	//set the version popup to where it is stored in the prefs
					break;
				case '2':
					document.getElementById("revision").innerHTML = revision2;
					document.getElementById("edition").innerHTML = edition2;
					document.getElementById("vers").options[1].selected='true';
					break;
				case '3':
					document.getElementById("revision").innerHTML = revision3;
					document.getElementById("edition").innerHTML = edition3;
					document.getElementById("vers").options[2].selected='true';
					break;
				case '4':
					document.getElementById("revision").innerHTML = revision4;
					document.getElementById("edition").innerHTML = edition4;
					document.getElementById("vers").options[3].selected='true';
					break;
				default:
					document.getElementById("revision").innerHTML = revision1;	//default to the fourth edition
					document.getElementById("edition").innerHTML = edition1;
					document.getElementById("vers").options[0].selected='true';
			}
			
			/* now let's handle the auto-flipback timing */
			switch (obliqueTime) {
				case '30':
					document.getElementById("autoflip").options[0].selected='true';
					break;
				case '20':
					document.getElementById("autoflip").options[1].selected='true';
					break;
				case '10':
					document.getElementById("autoflip").options[2].selected='true';
					break;
				case '5':
					document.getElementById("autoflip").options[3].selected='true';
					break;
				case '4':
					document.getElementById("autoflip").options[4].selected='true';
					break;
				case '3':
					document.getElementById("autoflip").options[5].selected='true';
					break;
				default:		// in ehm, case something goes wrong, set default to 3 seconds
					document.getElementById("autoflip").options[5].selected='true';
					break;
			}
			
        } 
        else   // if that would fail, set texts and popup to their default values
        {
        	document.getElementById("revision").innerHTML = revision1;
			document.getElementById("edition").innerHTML = edition1;
        	document.getElementById("vers").options[0].selected='true';		// set default deck to 4th edition
        	document.getElementById("autoflip").options[5].selected='true';	// set default auto-flip time to 3"
        }
	}
}





// changeVersion() is called whenever a menu item is chosen in the widget's preferences.  It queries the
// menu to find out which option was chosen, applies the change to the widget, and saves the preference.

function changeVersion(elem)
{	
	var versie = elem.options[elem.selectedIndex].value;
	/* when changing the popup, write the "current version" value to the prefs (a number from 1 to 4) */
	
	switch (versie) {		// which option was chosen ?
		case '1':
			document.getElementById("revision").innerHTML = revision1;	// change text underneath the pulldown
			document.getElementById("edition").innerHTML = edition1;	// change the indicator text on the front
			if(window.widget)
			{
				widget.setPreferenceForKey("1", "obliquePref");			// write the prefs
			}
			break;
		case '2':
			document.getElementById("revision").innerHTML = revision2;
			document.getElementById("edition").innerHTML = edition2;
			if(window.widget)
			{
				widget.setPreferenceForKey("2", "obliquePref");
			}
			break;
		case '3':
			document.getElementById("revision").innerHTML = revision3;
			document.getElementById("edition").innerHTML = edition3;
			if(window.widget)
			{
				widget.setPreferenceForKey("3", "obliquePref");
			}
			break;
		case '4':
			document.getElementById("revision").innerHTML = revision4;
			document.getElementById("edition").innerHTML = edition4;
			if(window.widget)
			{
				widget.setPreferenceForKey("4", "obliquePref");
			}
			break;
		default:
			if(window.widget)
			{
				widget.setPreferenceForKey("1", "obliquePref");
			}
	}
}


function changeTime()
{	
	var pop = document.getElementById("autoflip");					// get the pulldown menu
	var tijd = pop.options[pop.selectedIndex].value;				// get the values from that pd menu
	
	switch (tijd) {													// which option was chosen ?
		case '30':
			InitializeTimer(30);									// set the nž of seconds to auto-flipback
			if(window.widget)
			{
				widget.setPreferenceForKey("30", "obliqueTime");	// ...and write the prefs
			}
			break;
		case '20':
			InitializeTimer(20);
			if(window.widget)
			{
				widget.setPreferenceForKey("20", "obliqueTime");
			}
			break;
		case '10':
			InitializeTimer(10);
			if(window.widget)
			{
				widget.setPreferenceForKey("10", "obliqueTime");
			}
			break;
		case '5':
			InitializeTimer(5);
			if(window.widget)
			{
				widget.setPreferenceForKey("5", "obliqueTime");
			}
			break;
		case '4':
			InitializeTimer(4);
			if(window.widget)
			{
				widget.setPreferenceForKey("4", "obliqueTime");
			}
			break;
		case '3':
			InitializeTimer(3);
			if(window.widget)
			{
				widget.setPreferenceForKey("3", "obliqueTime");
			}
			break;
		default:
			InitializeTimer(3);			// set the default time for auto-flipback to 3 seconds
			if(window.widget)
			{
				widget.setPreferenceForKey("3", "obliqueTime");
			}
			break;
	}
}



/*********************************/
// HIDING AND SHOWING BACK
/*********************************/
function showCard()
{
	var front = document.getElementById("front");
	var back = document.getElementById("back");
	var prefs = document.getElementById("prefs");
	
	
	if (window.widget)
		widget.prepareForTransition("ToBack");		// freezes the widget so that you can change it without the user noticing
	
	
	front.style.display="none";		// hide the front
	prefs.style.display="none";		// hide the pref back
	back.style.display="block";		// show the card back
	
	
	if (window.widget)
		setTimeout ('widget.performTransition();', 0); // and flip the widget over	

	document.getElementById('fliprollie').style.display = 'none';  // clean up the front side - hide the button behind the draw button
	
	changeTime();  // call the function to check for the pulldown which sets the timer to flip back the card automatically
	
	rotate();
	
	document.getElementById("aphorism").innerHTML = quote[num];
	
}

function hideCard()
{
	var front = document.getElementById("front");
	var back = document.getElementById("back");
	
	if (window.widget)
		widget.prepareForTransition("ToFront");		// freezes the widget and prepares it for the flip back to the front
	
	back.style.display="none";			// hide the back
	front.style.display="block";		// show the front
	
	if (window.widget)
		setTimeout ('widget.performTransition();', 0);		// and flip the widget back to the front
		
		
}




/*********************************/
// HIDING AND SHOWING PREFERENCES
/*********************************/

// showPrefs() is called when the preferences flipper is clicked upon.  It freezes the front of the widget,
// hides the front div, unhides the back div, and then flips the widget over.

function showPrefs()
{
	var front = document.getElementById("front");
	var prefs = document.getElementById("prefs");
	
	if (window.widget)
		widget.prepareForTransition("ToBack");		// freezes the widget so that you can change it without the user noticing
	
	front.style.display="none";		// hide the front
	prefs.style.display="block";		// show the back
	
	if (window.widget)
		setTimeout ('widget.performTransition();', 0);		// and flip the widget over	

	document.getElementById('fliprollie').style.display = 'none';  // clean up the front side - hide the button behind the draw button

}


// hidePrefs() is called by the done button on the back side of the widget.  It performs the opposite transition
// as showPrefs() does.

function hidePrefs()
{
	var front = document.getElementById("front");
	var prefs = document.getElementById("prefs");
	
	if (window.widget)
		widget.prepareForTransition("ToFront");		// freezes the widget and prepares it for the flip back to the front
	
	prefs.style.display="none";			// hide the back
	front.style.display="block";		// show the front
	
	if (window.widget)
		setTimeout ('widget.performTransition();', 0);		// and flip the widget back to the front
}


// PREFERENCE BUTTON ANIMATION (- the pref flipper fade in/out)

var flipShown = false;		// a flag used to signify if the flipper is currently shown or not.


// A structure that holds information that is needed for the animation to run.
var animation = {duration:0, starttime:0, to:1.0, now:0.0, from:0.0, firstElement:null, timer:null};


// mousemove() is the event handle assigned to the onmousemove property on the front div of the widget. 
// It is triggered whenever a mouse is moved within the bounds of your widget.  It prepares the
// preference flipper fade and then calls animate() to performs the animation.

function mousemove (event)
{
	if (!flipShown)			// if the preferences flipper is not already showing...
	{
		if (animation.timer != null)			// reset the animation timer value, in case a value was left behind
		{
			clearInterval (animation.timer);
			animation.timer  = null;
		}
		
		var starttime = (new Date).getTime() - 13; 		// set it back one frame
		
		animation.duration = 500;												// animation time, in ms
		animation.starttime = starttime;										// specify the start time
		animation.firstElement = document.getElementById ('flip');				// specify the element to fade
		animation.timer = setInterval ("animate();", 13);						// set the animation function
		animation.from = animation.now;											// beginning opacity (not ness. 0)
		animation.to = 1.0;														// final opacity
		animate();																// begin animation
		flipShown = true;														// mark the flipper as animated
	}
}

// mouseexit() is the opposite of mousemove() in that it preps the preferences flipper
// to disappear.  It adds the appropriate values to the animation data structure and sets the animation in motion.

function mouseexit (event)
{
	if (flipShown)
	{
		// fade in the flip widget
		if (animation.timer != null)
		{
			clearInterval (animation.timer);
			animation.timer  = null;
		}
		
		var starttime = (new Date).getTime() - 13;
		
		animation.duration = 500;
		animation.starttime = starttime;
		animation.firstElement = document.getElementById ('flip');
		animation.timer = setInterval ("animate();", 13);
		animation.from = animation.now;
		animation.to = 0.0;
		animate();
		flipShown = false;
	}
}


// animate() performs the fade animation for the preferences flipper. It uses the opacity CSS property to simulate a fade.

function animate()
{
	var T;
	var ease;
	var time = (new Date).getTime();
		
	
	T = limit_3(time-animation.starttime, 0, animation.duration);
	
	if (T >= animation.duration)
	{
		clearInterval (animation.timer);
		animation.timer = null;
		animation.now = animation.to;
	}
	else
	{
		ease = 0.5 - (0.5 * Math.cos(Math.PI * T / animation.duration));
		animation.now = computeNextFloat (animation.from, animation.to, ease);
	}
	
	animation.firstElement.style.opacity = animation.now;
}


// these functions are utilities used by animate()

function limit_3 (a, b, c)
{
    return a < b ? b : (a > c ? c : a);
}

function computeNextFloat (from, to, ease)
{
    return from + (to - from) * ease;
}

// these functions are called when the info button itself receives onmouseover and onmouseout events

function enterflip(event)
{
	document.getElementById('fliprollie').style.display = 'block';
}

function exitflip(event)
{
	document.getElementById('fliprollie').style.display = 'none';
}


