<!--
//========================================================================
//
// Name:    guess03.js
//
// Version: 1.3.4
//
// Dates:   07-04-05, 07-31-05
//          08-01-05, 08-23-05
//          10-12-05, 10-31-05
//          11-01-05, 11-06-05
// 
// Programmer: K. B. Norton
//
// Mods: 10-07-05 Added seconds to randomizer for each sub-topic 
//                selection, better distribution...
//     : 10-09-05 Can choose any item in learn mode, click and next
//     : 10-11-05 Can enter learn mode after "Done!" and see item images
//     : 10-31-05 Shows first pic in checked list with "dot" after "Done!"
//
// Features:
//
//      1. Can randomly select images from subject/topic group
//      2. Can link to a URL under item's name...
//      3. Can pick first, best example, in image series for "leaning" mode
//      4. Returns to same image or group when in learn mode or when in 
//         play mode and count is > 0, only scrambles once per game, 
//         clear button will start "new" game and scramble sequence.
//         Scrambles on any return to play from an off site url, return
//         image is same as when left though.
//      5. Use "go" buttons to open a URL in a window, *not* leaving page
//      6. Can display list in true numerical order in learn/demo mode
//	7. Can exlcude the first image if in play mode, too much giveaway
//	8. Can open a small image window for comparison to others via "img"
//          and via mywindow01.js script
//
//
// Notes:  Re-writing since older IE's (iMac) don't like the array methods 
//         of shift and pop! So have to use a different approach... am
//         leaving previous code in as an example, which does work OK!
// 
//========================================================================

//----- A few default values
var contentType = 1;            // Default Text=1, images=0
var biggestTerm = 0;            // Field size for largest term/word
var learnmode   = 0;		// Put into learning mode, 1 is yes
var demomode    = 0;		// Demo mode

demoDelay = demoDelay * 1000;	// Convert seconds to milliseconds

//----- Defaults: Check on these vars... better method?
if (myWidth  == null) var myWidth  = 100;
if (myHeight == null) var myHeight = 100;

//----- Move/split the string data into the arrays...
var theItems  = new Array();
var theDimns  = new Array();
var theDesc   = new Array();
var imgWidth  = new Array();
var imgHeight = new Array();
var theImages = new Array();
var i2iMap    = new Array();
var mapCount  = new Array();
var theInfo   = new Array();

var missedItems = new Array();

theItems      = myData.split(",");
theDimns      = myDimns.split(",");
theDesc       = myDesc.split("|");		// Changed to a pipe |
theInfo       = myInfo.split("|");

//----- If dot, then match for image file types...
//----- Is it a text-based or is it an image-based game?
var tvar = theItems[0];
if ( tvar.indexOf(".") + 1 )
{
//----- If ends in .jpg or .gif, must be an image type file... IE?
        if ( tvar.match(/\.(jpg|gif)$/) ) contentType = 0;
}

//----- Data Inits...
var n         = theItems.length;
var upperbnd  = n - 1;           // Upper bound slot in array
var lowerbnd  = 0;               // Lower bound slot
var myURLpath = new String(document.location);          // Create object
var loc       = 0;
var sequence   = new Array(n);
var count     = 0;
var errors    = 0;
var whichItem = 0;
var seq_cnt   = 0;
var lastSeqCnt = 0;
var direction = 0;
var reentered = 0;
var listCnt   = 0;
var lastListCnt = 0;
var mynumber  = 0;
var lastChecked = -1;
var mindx     = 0; 

var modeName  = "";
var timeoutId = "";
var rndPull   = 0;

//----- Set up a date "handle"
var now  = new Date();

//----- Spin thru the pseudo-random number generator for x seconds...
//----- Does this have any real effect?
var rndCnt = Number(now.getSeconds()) + 1;
for ( var r = 1; r < rndCnt; r++ )
{
	rndPull = Math.random();
}


//----- MAIN: Begin processes...
build_seq(n);

if ( contentType > 0)
{
        for (var i = 0; i < n; i++)
        {
                if (theItems[i].length > biggestTerm)
                {
                        biggestTerm = theItems[i].length;
                }
        }

        biggestTerm++;          // Make it one space bigger...
}

if ( contentType < 1 )
{
//----- There is myWidth and myHeight in accompanying data js file...
//----- If images, loadup the prefetch buffer...
        preLoadImages(n);
	
//----- erase.jpg holds a blank, white space for a clear in image area...
        var clearScreen    = new Array();
        clearScreen[0]     = new Image(myWidth, myHeight);

//----- NOTE: Watch path! erase.jpg or similiar must exist at URLs!
//----- Must have something here to clear screen to a blank...
        if ( (loc = myURLpath.lastIndexOf("/")) > 0 )
        {
                myURLpath = myURLpath.substr(0, loc) + "/"+screenWipe;
                clearScreen[0].src = myURLpath;
        }
}

function getMatch()
{
//----- This is run when you click the "Enter" button...
//----- If missed, adds to missedItems array
        var mychecked;

//----- On next selection, clear previous check box
	if ( (leaveNoTrail > 0) && (lastChecked > -1) )
	{
		document.game.done[lastChecked].checked = 0;
	}

//----- See which one has been selected or "checked"
	mychecked = getChecked();

        if ( whichItem == mychecked)
        {
//----- Check the box if OK and mark as done...
                document.game.done[whichItem].checked = 1;
		lastChecked = whichItem;
        }
        else
        {
//----- Move the dot in radio button to the correct choice...
//----- and display this "error" message, increment the error count box
                document.game.choices[whichItem].checked = 1;
                alert("Correct choice is shown...");
		missedItems[errors] = whichItem;
                errors++;
                document.game.errors.value = errors;
        }

//----- Always inc event counter... and display, "policy decision"
//----- An event is a right or wrong answer!
        count++;
        document.game.counter.value = count;
}

function getNext()
{
//----- Select a random choice to display in window...
//----- If reentered is 1, then u return to same image group or image
	var displayList = "";
	var displayLine = "";

	var selected    = 0;
	var k           = 0;
        var holdCnt     = 0;
        var someMissed  = "";

	if ( reentered == 0 )
	{
		whichItem = sequence[seq_cnt];

		listCnt++;
		if ( listCnt > n ) listCnt = 1;

//----- Could expand here for linear listing, in order, 1,2,3, etc...
		if ( (listInOrder > 0) && (learnmode > 0 || demomode > 0) )
		{
			whichItem = listCnt - 1;
		}

//----- Perhaps pop/shift missedItems array for next "missed" for as long as
//----- items in the array and "Done!"
//-----  first test was (missedItems.length > 0)  
		if ( (mindx < missedItems.length) && (document.game.counter.value == "Done!") )
		{
// whichItem = missedItems.shift();
			whichItem = missedItems[mindx++];
			listCnt   = whichItem + 1;
		}
	}

//----- Get next sequence number, like a look-ahead, it's ready for "Next" 
//----- Move up or down for random sequence...
        (direction) ? seq_cnt++ : seq_cnt-- ;

//----- Reset to top of array
        if (seq_cnt > upperbnd) seq_cnt = 0;

//----- Reset to bottom of array
        if (seq_cnt < 0) seq_cnt = upperbnd;

//----- ... now we are done.
//----- NOTE: "count" is set to 0 below if there were "errors" so this block
//-----  only done once, as it should be!
        if (count > upperbnd)
        {
                document.game.counter.value = "Done!";

//----- If this flag, then show the ones missed for review and study...
//-----  second test was (missedItems.length > 0), (mindx < missedItems.length)
		if ( (errorsReview > 0) && (errors > 0) )
		{
//----- Clear all boxes for this display of missed items...
			for (k = 0; k < n; k++) document.game.done[k].checked = 0;

//----- Now show the ones missed by checking them...
//----- NOTE: Some platforms do not like nested index brackets!
			for(k = 0; k < missedItems.length; k++)
			{
				someMissed = missedItems[k];
				if ( someMissed > -1 )
				{
					document.game.done[someMissed].checked = 1;
				}
			}

//----- This allows more selections, as in "Learn" mode, after "Done!"
//-----  "count" determines re-entry into this block, 0 is don't re-enter
			count     = 0;
			learnmode = 1;

			document.game.gamemode[0].checked = 0;
			document.game.gamemode[1].checked = 1;
			document.game.modename.value      = "Learn";

//----- Get this "missed" image and "dot" it too...
//----- If some -1's, they are at top of sort
			missedItems.sort(numberOrder);

//----- Shift out or "find" *first* item, and return...
// whichItem = missedItems.shift();
			mindx     = missedItems.length - errors;
			whichItem = missedItems[mindx++];
		}

//----- Perhaps skip this return and choose a "whichItem" to show...
//----- else if none wrong, no errors, then clear last check mark
	if ( someMissed.length == 0 )
	{
		if ( (leaveNoTrail > 0) && (lastChecked > -1) )
		{
			document.game.done[lastChecked].checked = 0;
		}
		return;
	}

//----- End of Done! block
        }

//----- contentType is either text=1 or images=0...
//----- This is where it, text or image, is displayed.
        if ( contentType )
        {
                document.game.myDisplay.value = theItems[whichItem];
        }
        else
        {
//----- If in learnmode check to see if an intentional selection was made...
//----- This is a "jump" to any item in the choices list
		if ( (learnmode > 0) && ((selected = getChecked()) > -1 ) )
		{
			if ( selected != whichItem ) whichItem = selected;
		}

//----- Could make first one default to the "preferred" learning image?
//----- Write these vars just before the display to dynamically adjust...
		var someChoice = 1;		// Default value
		var mapString  = i2iMap[whichItem];	
		mapCount       = mapString.split(";");

//----- Derive random number from the clock in seconds, now is global
        	var secs = Number(now.getSeconds());
 
		if ( mapCount.length > 1 )
		{
			someChoice = Math.round( (Math.random() + (secs/100)) * (mapCount.length) );
			if ( someChoice > mapCount.length )
			{
				someChoice = someChoice - mapCount.length;
			}
		}

		someChoice = someChoice - 1;
		if (someChoice < 0 ) someChoice = 0;

//----- If in learnmode and flag, then *always* choose first one in series
		if ( (setPriorityFlag > 0) && (learnmode > 0) )
		{
			someChoice = 0;
		}

//----- If in playmode and flag, then *never* show the first one...
//----- ie, can never be "0th" index position, might give away the "answer"
//----- or be an instructional video segment...
		if ( (document.game.modename.value == "Play") && (firstLearnOnly > 0) )
		{
			if ( (mapCount.length > 1) && (someChoice == 0) ) someChoice++;
		}

		myChoice = mapCount[someChoice];

//----- Must be IE 4+ or Netscape 6+ to write these, else read only 
		document.game.myImages.width  = imgWidth[myChoice];
		document.game.myImages.height = imgHeight[myChoice];

               	document.game.myImages.src    = theImages[myChoice];

//----- Correlate item numbers with choice numbers in learn mode
		if ( (learnmode > 0) || (demomode > 0) )
		{
			displayList = whichItem + 1;
			listCnt     = displayList;
		}
		else
		{
			displayList = listCnt;
		}

//----- Store the current item number on page but in the middle using :'s.
//----- This is a work-around below, box only displays first or last 2 chars
//----- depending on whether it is Netscape or IE...
		displayLine = listCnt+"          :"+encrypt(whichItem)+":          "+displayList;

//----- If in demo and hide is true...
		if ( (demomode > 0) && (hideItemNumbers > 0) ) displayLine = "";

//----- Overwriting on a right justify, so for IE try a clear first...
//----- OK, this works fine!!! removes "jitter" in Mac IE
		document.game.currentItem.value = "";
		document.game.currentItem.value = displayLine;
		reentered = 0;
        }

//----- Leaning mode, check each *radio* button as you go...
	if ( (learnmode > 0) || (demomode > 0) )
	{
	        document.game.choices[whichItem].checked = 1;
	}

//----- If this option set, then display this text in these modes...
	if ( showTextInfo > 0 )
	{
		if ( (learnmode > 0) || (demomode > 0) )
		{
			document.game.textinfo.value = theInfo[whichItem];
		}
		else
		{
			document.game.textinfo.value = "";
		}
	}
}

function clearChoices()
{
//----- Clear the last item selected... before the next choosing/scramble
        document.game.choices[whichItem].checked = 0;
}

function write_it()
{
//----- Write in the radio buttons and the descriptions...
        var radioButtons = '<input type="radio" name="choices"> ';
        var checkBoxes   = ' <input type="checkbox" name="done"> ';

        for (var x = 0; x < n; x++)
        {
                document.writeln("<tr><td><b>"+(x+1)+".</b> " + radioButtons + checkBoxes + theDesc[x]);
        }
}

function build_seq(max)
{
//----- Load up this sequencing array...
        for (var j = 0; j < max; j++)
        {
                sequence[j] = j;
        }
}

function clearAll()
{
//----- Clear all check boxes and clear missed items...
//----- Delete all elements in the array too
        for (var k = 0; k < n; k++)
	{
		document.game.done[k].checked = 0;
// missedItems.pop();
		missedItems[k] = -1;
	}

//----- Reset all counters...
        seq_cnt   = 0;
        count     = 0;
        errors    = 0;
        whichItem = 0;
	listCnt   = 0;
	demomode  = 0;
	lastChecked = -1;
        mindx     = 0;

//----- Reset all window field displays...
        document.game.reset();

//----- OK, this is better. It wipes image area to white...
//----- erase.jpg or ltgrey.jpg as the clear
        if ( ! contentType )
        {
                document.game.myImages.src = clearScreen[0].src;
        }

//----- This is the default "state" in "Play" mode
	document.game.gamemode[0].checked = 1;
	togglemode();
}

function scramble()
{
//----- Rearrange an ordered list to a scrambled list...
//----- Do only once at the start of each "session"
        var tmp   = "";
        var cnt   = 0;
        var mid   = 0;

//----- Only scramble once per game... (could make this an option)
//----- Once game is on, or in learnmode, don't scramble anymore...
	if (document.game.counter.value > 0 || learnmode > 0) return;

        mid = Math.round( (n/2) );

        for (var y = 0; y < mid; y++)
        {
                for (var x = 0; x < n; x++)
                {
                        if (sequence[cnt+1])
                        {
                                tmp             = sequence[cnt];
                                sequence[cnt]   = sequence[cnt+1];
                                sequence[cnt+1] = tmp;
                        }
                        else break;
                        cnt = cnt + 2;
                }
//----- Shift left and append first to end...
                tmp = sequence[0];
                for (x = 1; x < n; x++) sequence[x-1] = sequence[x];
                sequence[n-1] = tmp;
        }

//----- Derive random number from the clock in seconds, now is global
        var secs = Number(now.getSeconds());
        seq_cnt  = 2;                   // Assumes at least 2 answers

        if (secs > 9) secs    = Math.round(secs % 10);
        if (secs > 0) seq_cnt = Math.round( (secs/10) * (n - 1) );

//----- Then see if number is odd or even and go by that!
        ( seq_cnt % 2 ) ? direction = 1 : direction = 0;

//----- Initialize the mode here... best spot for this so far
	togglemode();
}

function preLoadImages(max)
{
//----- Load the prefetch buffer... which is the image "cache"
//----- NOTE: By specifying a size, they display *MUCH* faster!
//----- You need to build the i2iMap which maps items to images

        var preBuffer   = new Array();
	var flatItems   = new Array();
	var flatDimns   = new Array();
	var workArray   = new Array();

	var pos         = 0;
	var adjWidth    = 0;
	var adjHeight   = 0;
	var ratio       = 0;
	var imgCount    = 0;
	var mapCounter  = 0;
	var testData    = 0;
	var j           = 0;

	var itemData    = "";
	var buildData   = "";

//----- Replace all ;'s with ,'s flattening out this string
	do
	{
		j = myData.indexOf(';');
		if ( j > 0 )
		{
			myData  = myData.substr(0,j)  + "," + myData.substr(j+1);
		}

		j = myDimns.indexOf(';');
		if ( j < 0 ) break;		
		myDimns = myDimns.substr(0,j) + "," + myDimns.substr(j+1);		
	}
	while ( 1 );

//----- Build "flat" arrays, serializing any multi fields to single fields
//----- So xxx:yyy;xxx:yyy, becomes xxx:yyy,xxx:yyy, etc...

	flatItems = myData.split(",");
	flatDimns = myDimns.split(",");

	imgCount  = flatItems.length;

//----- Get the first data string
	itemData  = theItems[mapCounter];
	workArray = itemData.split(";");
	testData  = workArray.length;

//----- Start of process loop...
//----- max is number of items in the theItems, imgCount is the flat count
        for (var i = 0; i < imgCount; i++)
        {
//----- Get the dimensions of the jpg image 
		pos       = flatDimns[i].indexOf(':');
		adjWidth  = flatDimns[i].substr(0,pos);
		adjHeight = flatDimns[i].substr(pos+1);

//----- Adjust image to fit inside and on the "screen"
//----- NOTE: myWidth and myHeight belong to the screen
		if ( adjHeight >= adjWidth )
		{
//----- If bigger, scale down...
			if ( adjHeight >= myHeight )
			{
				ratio     = myHeight / adjHeight;
				adjHeight = myHeight;
				adjWidth  = Math.round(adjWidth * ratio);
			}
		}
		else
//----- Implied opposite case: width > height
		{
			if ( adjWidth >= myWidth )
			{
				ratio     = myWidth / adjWidth;
				adjWidth  = myWidth;
				adjHeight = Math.round(adjHeight * ratio); 
			}
		}

//----- Store in "correct" sizes... but ...
//----- NOTE: Does NOT seem to like the adjusted values in "new Image"!!!
		imgWidth[i]      = adjWidth;
		imgHeight[i]     = adjHeight;

//----- May or may not work in netscape? IE?
// preBuffer[i] = new Image(imgWidth[i], imgHeight[i]);

                preBuffer[i]     = new Image(myWidth, myHeight);
       	        preBuffer[i].src = flatItems[i];

//----- Store in a master "flat" serialized array... 1 value per index
		theImages[i]     = flatItems[i];

//----- Now build the image map...
//----- There will be n theItems with strings of indices in each "box"
//----- OK, we have something to concatenate...
		if ( testData >= 1 ) buildData = buildData + i + ";";

		testData = testData - 1;	// dec counter
		if ( testData == 0 )		// and test again...
		{
//----- Remove last ";", load map, get next item data, clear...
			buildData = buildData.substr(0, (buildData.length - 1) );
			i2iMap[mapCounter] = buildData;
			mapCounter         = mapCounter + 1;
//----- Test array boundry...
			if ( mapCounter < max )
			{
				itemData  = theItems[mapCounter];
				workArray = itemData.split(";");
				testData  = workArray.length;
				buildData = "";
			}
		}
        } // End of "i" for loop, outer
}

function setDisplayType()
{
//----- Write into the doc so that you have the matching choice..
        var textType  = '<input type="text" readonly name="myDisplay" value="" size="'+ biggestTerm + '">';
	var imageType = '<img name="myImages" width="' + myWidth + '" height="' + myHeight + '">';

        (contentType) ? document.write(textType) : document.write(imageType);
}

function setInputLine(input_name)
{
//----- This is for a field display item.
//----- You could overide this from other local data...
        var defInputSize = "5";

        document.write('<input type="text" readonly value="0" name="' + input_name + '" size="' + defInputSize + '" >');
}

function setMode()
{
//----- Set up the Mode panel with "play" and "learn" as the choices...
	if ( setModeFlag > 0 )
	{
		document.write('<b>Mode:</b>&nbsp;');
		document.write('Play: <input type="radio" name="gamemode" onclick="togglemode();" checked>');
		document.write('&nbsp;Learn: <input type="radio" name="gamemode" onclick="togglemode();">'); 

//----- Set up "Demo" button...
		if ( setDemoFlag > 0 )
		{
			document.write('&nbsp;Demo: <input type="radio" name="gamemode" onclick="togglemode();">'); 
		}

//----- NOTE: The "default" is "Play" so it always wants to restore on a clear
		document.write('&nbsp; <input type="text" name="modename" size="5" value="Play" readonly>');
	}
	else
	{
//----- If not using, then just a space...
		document.write('&nbsp;');
	}
}

function reentry()
{
//----- When re-entering page, test and or set data or flags...
//----- Recover stored data from the page.
//----- NOTE: This code is *always* entered first!
	var pageData  = new Array();
	var bigString = "";
	var pos       = "";
	var missed    = "";
 
	count  = document.game.counter.value;
	missed = document.game.errors.value;

	if ( setModeFlag > 0 )
	{
		modeName = document.game.modename.value;

//----- Need a text field here for storage across pages...
		( modeName.match(/^Learn$/) ) ? learnmode = 1 : learnmode = 0;
	}

//----- A very long string with a number at the front, in the middle,
//----- and in the back. Middle is the encrypted page item numeer.
	bigString = document.game.currentItem.value;
	if ( bigString.length > 0 )
	{
		pos       = bigString.indexOf(" ");
		listCnt   = Number(bigString.substr(0,pos));
		pageData  = bigString.split(":");
		whichItem = decrypt(Number(pageData[1]));
	}

//----- If game has begun, or in learn mode, return to same image *group*
//----- First choice might be wrong, so include a missed flag...
//----- Usually "caught" by count anyway
	(count > 0 || learnmode > 0 || missed > 0) ? reentered = 1 : renetered = 0;
}


function togglemode()
{
//----- Find out if we need to "toggle" buttons
	if ( setModeFlag > 0 )
	{
//----- First option 0 is "play" mode, then 1 is "learn" mode
		if ( document.game.gamemode[0].checked )
		{
			learnmode                    = 0;
			demomode                     = 0;
			clearChoices();		// Clears last whichItem
			document.game.modename.value = "Play";
			if ( timeoutId.length > 0 ) stopShow();

//----- From learn or demo back to play, start again from here...
//----- Re-syncronize from beggining of sequence array
			listCnt                      = 0;
			seq_cnt                      = 0;
		}
		else if (document.game.gamemode[1].checked)
		{
			learnmode                    = 1;
			demomode                     = 0;
			document.game.modename.value = "Learn";
			if ( timeoutId.length > 0 ) stopShow();
			if ( (listInOrder > 0) && (learnmode > 0 || demomode > 0) )
			{
				listCnt = 0;
			}

		}
		else
		{
			demomode                     = 1;
			learnmode                    = 0;
			document.game.modename.value = "Demo";
			if ( (listInOrder > 0) && (learnmode > 0 || demomode > 0) )
			{
				listCnt = 0;
			}

			runDemo();		// Launch from here...
		}

//----- Attempt to hold original sequence, but doesn't, not stored on page!
	reentered = 0;
	}
}

function encrypt(mynumber)
{
//----- Very simple method!
	mynumber++;
	mynumber = mynumber * 2364;
	mynumber = mynumber + 1212;

	return mynumber;
}

function decrypt(mynumber)
{
	mynumber = mynumber - 1212;
	mynumber = mynumber / 2364;
	mynumber--;

	return mynumber;
}

function runDemo()
{
//----- Begin a timed loop through the items showing what they are...
//----- Don't pass in delay value, causes trouble!
//----- Begins on "Demo" radio button and stops on "Play" or "Learn"

	if ( demomode > 0 )
	{
		getNext();
	}
	else return;

//----- Timer here... delay by "x" seconds
//----- NOTE: You need this for iMac IE! 
	timeoutId = setTimeout("runDemo()", demoDelay);

}

function stopShow()
{
//----- Stop the demo or auto "slide" show...
	clearTimeout(timeoutId);
}

function setInfo()
{
//----- Set up the info text line or text box
	if ( showTextInfo > 0 )
	{
		document.write('<input type="text" name="textinfo" size="60" value="" readonly>'); 
	}
	else
	{
		document.write('<br>');
	}
}

function getChecked()
{
//----- Find out which item has been checked and return it...
//----- If nothing checked or selected yet, return -1
	fndChecked = -1;

        for (var i = 0; i < n; i++)
        {
//----- Find out which one has been checked... and exit loop
                if (document.game.choices[i].checked)
                {
                        fndChecked = i;
                        break;
                }
        }

	return fndChecked;
}

//----- Sort numerically as called from something.sort(numberOrder)...
function numberOrder(a, b) { return a - b; }

//----- End of guess03.js
//-->
