// Copyright (C) 2008 Robert W. Clarke Consulting, all rights reserved.// do not remove this copyright notice// Global vars ----------------------------------------------------------------------------------var ary_colors = new Array();ary_colors['correct'] = "00FF00"; // greenary_colors['wrong'] = "FF0000"; // redary_colors['noclick'] = "FFFFFF"; // whiteary_colors['active'] = "FFCC33"; // yellow	var ary_state_status;var ary_state_order;var switch_interval = new Array();switch_interval['easy'] = 2000;switch_interval['difficult'] = 1500;var interval_switchstate;var score_increment = new Array();score_increment['easy'] = 23;score_increment['difficult'] = 52;var game_level;var game_status = "init";var game_time = 0;var interval_gametime;// System --------------------------------------------------------------------------------------function initGame(){ // called when page first loads	document.forms.gamecontrol.time.value = 0;	document.forms.gamecontrol.score.value = 0;	document.forms.gamecontrol.ss.value = "START";	document.forms.gamecontrol.state.value = "Click on START button";	document.forms.gamecontrol.correct.value = 0;	document.forms.gamecontrol.incorrect.value = 0;	disableLevelSelection(false);	document.forms.gamecontrol.level[0].checked = true;	game_status = "ready";}// Game Control ----------------------------------------------------------------------------------function setRandomStateOrder(){ // called by newGame()	ary_state_order = new Array();	var sc;	for(sc in ary_state_name){ // fill up the unclicked states		ary_state_order.push(sc);	}	ary_state_order = shuffleArray(ary_state_order); // make random}function resetStateStatus(){ // called by newGame()	ary_state_status = new Array();	var sc;	for(sc in ary_state_name){		ary_state_status[sc] = new Array();		ary_state_status[sc]['color'] = ary_colors['noclick'];		ary_state_status[sc]['latch'] = false;		ary_state_status[sc]['score'] = 0;	}}function disableLevelSelection(directive){ // called by newGame()	// disables the radio buttons	document.forms.gamecontrol.level[0].disabled = directive;	document.forms.gamecontrol.level[1].disabled = directive;}function startGame(){ // called by the START button		// set the game level, either easy or difficult	game_level = getSelectedRadioValue(document.forms.gamecontrol.level);	disableLevelSelection(true);		// set game time	game_time = 0;	updateTime();	interval_gametime = setInterval("updateTime()",1000);		// reset the controls	document.forms.gamecontrol.ss.value = "STOP";			// reset arrays	resetStateStatus();	setRandomStateOrder();	document.forms.gamecontrol.state.value = ary_state_name[ary_state_order[0]];	// update the map, activates the states	updateMap();		updateScore();		game_status = "run"; // allows map clicks		interval_switchstate = setInterval("nextState()",switch_interval[game_level]);}function nextState(){ // called by interval interval_switchstate and when user clicks on a state	flushUnclickedStates();	// check if there are still states left to click	if(ary_state_order.length == 0){		stopGame();		return;	}		document.forms.gamecontrol.state.value = ary_state_name[ary_state_order[0]];		updateMap();}function flushUnclickedStates(){	if(ary_state_order.length == 0){return;}		var counter = ary_state_order.length + 1;	var sc;	while(counter > 0){		if(ary_state_order.length == 0){break;}		if(ary_state_status[ary_state_order[0]]['latch']){ // latched			ary_state_order.shift(); // remove it		} else { // circulate the array			sc = ary_state_order.shift();			ary_state_order.push(sc);		}		counter --;	}}function updateScore(){	// update the game score fields		var correct_clicks = 0;	var incorrect_clicks = 0;	var game_score = 0;	var sc;	for(sc in ary_state_name){		if(ary_state_status[sc]['score'] > 0){			correct_clicks ++;			game_score += score_increment[game_level];		}		if(ary_state_status[sc]['score'] < 0){			incorrect_clicks ++;			// game_score -= score_increment[game_level];		}	}	if(game_score < 0){game_score = 0;}	document.forms.gamecontrol.score.value = game_score	document.forms.gamecontrol.correct.value = correct_clicks;	document.forms.gamecontrol.incorrect.value = incorrect_clicks;}function updateTime(){ // called by interval_gametime	game_time ++;	document.forms.gamecontrol.time.value = game_time;}function stopGame(){ // called by the stop button or if there are no more states left	clearInterval(interval_gametime); // stop the one second interval	clearInterval(interval_switchstate);		game_status = "idle"; // prevents further clicks on map		updateMap();	disableLevelSelection(false);	document.forms.gamecontrol.state.value = "Game over, click START for new game";	document.forms.gamecontrol.ss.value = "START";}function gameControl(btn_obj){ // called from the game START / STOP button	if(btn_obj.value == "START"){		startGame();		btn_obj.value = "STOP";		return;	} 		if(btn_obj.value == "STOP"){		stopGame();		btn_obj.value = "START";		return;	}}// General funcitons -------------------------------------------------------------------------------function shuffleArray(ary){	var numbers = "_";	var n;	var ary_shuffled = new Array();	while(ary_shuffled.length < ary.length){		n = randomNumber(0,ary.length-1);		if(numbers.indexOf("_" + n + "_") < 0){ // not already picked			numbers += n + "_";			ary_shuffled.push(ary[n]);		}	}	return ary_shuffled;}function randomNumber(nmin,nmax){	return nmin + Math.floor(Math.random() * (nmax - nmin + 1));}function getSelectedRadioValue(radio_obj){	var i;	for(i=0;i<radio_obj.length;i++){		if(radio_obj[i].checked){			return radio_obj[i].value;		}	}}// Selection --------------------------------------------------------------------------------------function selectState(sc){ // called by map when user clicks on a state		// map clicks only apply if game is running	if(game_status != "run"){ return; }		ary_state_status[sc]['latch'] = true;		// accept the click	if(sc == ary_state_order[0]){ // hit		ary_state_status[sc]['score'] = 1;		ary_state_status[sc]['color'] = ary_colors['correct'];	} else { // miss		ary_state_status[sc]['score'] = -1;		ary_state_status[sc]['color'] = ary_colors['wrong'];	}		updateScore();			// nextState(); // also updates the map	updateMap();}// Map XML --------------------------------------------------------------------------------------function updateMap(){ // called by selectState function every time user clicks on a state	// this function generates the xml to configure the map based the array of selected statesvar state_code, xml_state, re, state_color, state_action;	var xml_state_tmpl = '<state id="_ID_" ncolor="_COLOR_" rcolor="_COLOR_" action="_ACTION_" />';		// start the xml	var xml = '<?xml version="1.0" encoding="iso-8859-1" ?><MT1022>'; // start the xml	xml += '<global state_initials="off" state_name="off" action_target="_self" />';		for(state_code in ary_state_name){ // loop through each state		xml_state = xml_state_tmpl; // set to state template xml				// set the ID		re = /_ID_/g;		xml_state = xml_state.replace(re,state_code); // replace id		// set state color and action		state_color = ary_state_status[state_code]['color'];		state_action = "";		if(!ary_state_status[state_code]['latch']){ // never been clicked			state_action = "javascript:selectState('"+state_code+"')";			if(state_code == ary_state_order[0]){ // the active state				state_color = ary_colors['active'];			}		}						re = /_COLOR_/g;		xml_state = xml_state.replace(re,state_color);				re = /_ACTION_/g;		xml_state = xml_state.replace(re,state_action);				xml += xml_state; // append xml	}		xml += '</MT1022>'; // finish xml		// update the map	sendXML(xml);}function sendXML(xml){	// this function sends the xml to the map	// the map receives the xml and configures itself automatically	if(window.maptron){		window.document["maptron"].SetVariable("jxml", xml);	}	if(document.maptron){		document.maptron.SetVariable("jxml", xml);	}}// Data --------------------------------------------------------------------------------------// make array for state namesvar ary_state_name = new Array();ary_state_name['AL']="Alabama";ary_state_name['AK']="Alaska";ary_state_name['AZ']="Arizona";ary_state_name['AR']="Arkansas";ary_state_name['CA']="California";ary_state_name['CO']="Colorado";ary_state_name['CT']="Connecticut";ary_state_name['DE']="Delaware";ary_state_name['FL']="Florida";ary_state_name['GA']="Georgia";ary_state_name['HI']="Hawaii";ary_state_name['ID']="Idaho";ary_state_name['IL']="Illinois";ary_state_name['IN']="Indiana";ary_state_name['IA']="Iowa";ary_state_name['KS']="Kansas";ary_state_name['KY']="Kentucky";ary_state_name['LA']="Louisiana";ary_state_name['ME']="Maine";ary_state_name['MD']="Maryland";ary_state_name['MA']="Massachusetts";ary_state_name['MI']="Michigan";ary_state_name['MN']="Minnesota";ary_state_name['MS']="Mississippi";ary_state_name['MO']="Missouri";ary_state_name['MT']="Montana";ary_state_name['NE']="Nebraska";ary_state_name['NV']="Nevada";ary_state_name['NH']="New Hampshire";ary_state_name['NJ']="New Jersey";ary_state_name['NM']="New Mexico";ary_state_name['NY']="New York";ary_state_name['NC']="North Carolina";ary_state_name['ND']="North Dakota";ary_state_name['OH']="Ohio";ary_state_name['OK']="Oklahoma";ary_state_name['OR']="Oregon";ary_state_name['PA']="Pennsylvania";ary_state_name['RI']="Rhode Island";ary_state_name['SC']="South Carolina";ary_state_name['SD']="South Dakota";ary_state_name['TN']="Tennessee";ary_state_name['TX']="Texas";ary_state_name['UT']="Utah";ary_state_name['VT']="Vermont";ary_state_name['VA']="Virginia";ary_state_name['WA']="Washington";ary_state_name['WV']="West Virginia";ary_state_name['WI']="Wisconsin";ary_state_name['WY']="Wyoming";