// Global Variables

var GG_fileLocation="../../scripts/SpellingRhymes/";
var GG_xmlFilename=GG_fileLocation+"XMLSpellingRhymes.xml";
var GG_xmlDoc=null;                                           // shows whether we got the XML file
var GG_xml=new Array();                                       // data read in from XML file

var GG_currentPoem=0;
var GG_URLparts=new Array;

var GG_screenZone=new Array();

var GG_objPoem=new Array();
var GG_objWord=new Array();
var GG_objTarget=new Array();

var GG_debugLog="";

var GG_allMatched=false;

var GG_lefteyex=50;   GG_lefteyey=-135;
var GG_righteyex=73;  GG_righteyey=-134;
var GG_mouthx=30; GG_mouthy=-100;

var GG_leftx=51;  GG_lefty=47;
var GG_rightx=78; GG_righty=49;

var GG_pageId=null;
var GG_faceId=null;
var GG_mouthId=null;
var GG_leftEyeId=null;
var GG_rightEyeId=null;

var GG_selectedWord=null;
var GG_selectedTarget=null;
var GG_mismatchedTarget=null;
var GG_mismatchedWord=null;

var GG_whatHappened="";

// Images

var faceImage=new Image();
faceImage.src=GG_fileLocation+"face/smaller empty face trans shadow.png";

var anEyeImage=new Image();
anEyeImage.src=GG_fileLocation+"face/an eye.png";

var grinImage=new Image();
grinImage.src=GG_fileLocation+"face/grin.png";

var laughImage=new Image();
laughImage.src=GG_fileLocation+"face/laugh.png";

var smileImage=new Image();
smileImage.src=GG_fileLocation+"face/smile.png";

var hmmImage=new Image();
hmmImage.src=GG_fileLocation+"face/hmm.png";

var uhImage=new Image();
uhImage.src=GG_fileLocation+"face/uh.png";

var oohImage=new Image();
oohImage.src=GG_fileLocation+"face/ooh.png";

var frownImage=new Image();
frownImage.src=GG_fileLocation+"face/frown.png";

// code

readXML();

if (GG_xml.length>0)
  {
  GG_currentPoem=whichPoem();

  GG_objPoem=getPoems();
  document.write(stylesheetHTML());
  document.write(screenAreasHTML());
  GG_screenZone=getScreenZones();

  showPoem(GG_currentPoem);
  }
else
  {
  document.write('page failed to load');
  }

// *****************************************************
// Read XML File
// *****************************************************

function readXML() 
  {
  writeLog('readXML()');

  GG_xmlDoc=null;

// check Browser

  if (window.ActiveXObject)
    {
    // code for IE
    GG_xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
    }
  else if (document.implementation.createDocument)
    {
    // code for Mozilla, Firefox, Opera, etc.
    GG_xmlDoc=document.implementation.createDocument("","",null);
    }
  else
    {
    alert('Your browser cannot handle this script');
    }

// If its OK, then load the XML

  if (GG_xmlDoc!=null) 
    {
    GG_xmlDoc.async=false;
    GG_xmlDoc.load(GG_xmlFilename);

    GG_xml=GG_xmlDoc.getElementsByTagName("item");
    }
  }

// ***************************
// which poem to show first?
// ***************************

function whichPoem()
  {
  writeLog('whichPoem(), document.URL: '+document.URL);

  var whichPoem=0;
  var poemParameter=0;

  GG_URLparts=document.URL.split('?');
  
  if (GG_URLparts.length>1)
    {
    poemParameter=parseInt(GG_URLparts[1]);

    writeLog('whichPoem()--> GG_URLparts: '+GG_URLparts[0]+', '+GG_URLparts[1]);

    if (poemParameter!=NaN)
      {
      if (poemParameter>0 && poemParameter<GG_xml.length)
        {
        whichPoem=poemParameter;
        }
      }
    }
  
  if (whichPoem==0)
    {
    whichPoem=Math.floor((GG_xml.length-1)*Math.random())+1;
//    window.location.href=GG_URLparts[0]+'?'+whichPoem;
    }

  return (whichPoem);
  }

// ********************
// stylesheet
// ********************

function stylesheetHTML()
  {
  writeLog('stylesheetHTML()');

  stylesheet="";
 
  stylesheet+='<style type="text/css" >';

  stylesheet+='span.debugging { font-weight:bold; color:gray; font-family:monospace; font-size:small; }';

  stylesheet+='table          { border-spacing=0; padding:0; margin:0; }';
  stylesheet+='thead          { border-spacing=0; padding:0; margin:0; }';
  stylesheet+='tbody          { border-spacing=0; padding:0; margin:0; }';
  stylesheet+='tr             { vertical-align:top; }';

  stylesheet+='td.col1        { width:50%; }';
  stylesheet+='td.col2        { width:50%; }';

  stylesheet+='td.box0        { vertical-align:middle; ';
  stylesheet+='                 font-family: "Tempus Sans ITC", Helvetica, Arial, sans-serif; ';
  stylesheet+='                 font-size: 140%;}';
  stylesheet+='td.box1        { padding:1em; }';
  stylesheet+='td.box2        { padding:1em; }';
  stylesheet+='td.box3        { height:2.5em; vertical-align:bottom; }';
  stylesheet+='td.box4        { vertical-align:top; }';
  stylesheet+='td.box5        { vertical-align:top; }';

  stylesheet+='table.speech   { border:thick solid black; height:5em; width:auto; ';
  stylesheet+='                 background-color:#bfe2f9; vertical-align:middle; position:relative; }';

  stylesheet+='tbody.faceTable { border-spacing=0; padding:0; margin:0; border:0 none transparent; }';

  stylesheet+='strong         { font-weight:bold; }';
  stylesheet+='strong.red     { color:red; }';
  stylesheet+='strong.black   { color:black; }';
  stylesheet+='strong.blue    { color:blue; }';
  stylesheet+='strong.green   { color:green; }';
  stylesheet+='strong.purple  { color:purple; }';
  stylesheet+='strong.amber   { color:#F1A629; }';
  stylesheet+='strong.hidden  { display:none; }';
  stylesheet+='strong.blank   { visibility:hidden; }';

  stylesheet+='img.lefteye    { position:relative; left:'+GG_lefteyex+'px;  top:'+GG_lefteyey+'px;  }';
  stylesheet+='img.righteye   { position:relative; left:'+GG_righteyex+'px; top:'+GG_righteyey+'px; }';
  stylesheet+='img.mouth      { position:relative; left:'+GG_mouthx+'px;    top:'+GG_mouthy+'px;    }';

  stylesheet+='</style>';

  return(stylesheet);
  }

// ****************************
// write HTML for screen layout
// ****************************

function screenAreasHTML() 
  {
  writeLog('screenAreasHTML() ');

  screenAreas="";
 
  screenAreas+="<table>";
  screenAreas+="<thead>";
  screenAreas+="<tr>";
  screenAreas+="<td id='rhymeTitle' class='box0' > </td>";
  screenAreas+="<td id='wordsArea'  class='box3' > </td>";
  screenAreas+="</tr>";
  screenAreas+="</thead>";

  screenAreas+="<tbody>";
  screenAreas+="<tr>";
  screenAreas+="<td class='col1' >";

  screenAreas+="<table>";
  screenAreas+="<thead>";
  screenAreas+="<tr>";
  screenAreas+="<td id='rhymeText' class='box1' > </td>";
  screenAreas+="</tr>";
  screenAreas+="</thead>";
  screenAreas+="<tbody>";
  screenAreas+="<tr>";
  screenAreas+="<td id='changeMenu' class='box2' > </td>";
  screenAreas+="</tr>";
  screenAreas+="</tbody>";
  screenAreas+="</table>";

  screenAreas+="</td>";
  screenAreas+="<td class='col2' >";

  screenAreas+="<table>";
  screenAreas+="<tbody class='faceTable' >";
  screenAreas+="<tr>";
  screenAreas+="<td id='speechArea' class='box4' > </td>";
  screenAreas+="</tr><tr>";
  screenAreas+="<td id='faceSpace'  class='box5' > </td>";
  screenAreas+="</tr>";
  screenAreas+="</tbody>";
  screenAreas+="</table>";

  screenAreas+="</td>";
  screenAreas+="</tr>";
  screenAreas+="</tbody>";
  screenAreas+="</table>";

  screenAreas+="<br /><span id='msgArea' class='debugging'> </span>";

  return(screenAreas);
  }

// *******************
// get screen zone ids
// *******************

function getScreenZones()
  {
  writeLog('getScreenZones()');

  var screenZones=new Array();

  screenZones[0]=document.getElementById('rhymeTitle');
  screenZones[1]=document.getElementById('rhymeText');
  screenZones[2]=document.getElementById('changeMenu');
  screenZones[3]=document.getElementById('wordsArea');
  screenZones[4]=document.getElementById('speechArea');
  screenZones[5]=document.getElementById('faceSpace');
  screenZones[6]=document.getElementById('msgArea');

  return(screenZones);
  }

// *************************************
// get Poems
// *************************************

function getPoems()
  {
  writeLog('getPoems()');

  var objPoem=new Array();

  for (var i=1; i<GG_xml.length; i++)
    {
    objPoem[i]=new poemObj();
    objPoem[i].title=GG_xml[i].getElementsByTagName("title")[0].childNodes[0].nodeValue.replace(/\n/g,"");
    objPoem[i].type=GG_xml[i].getElementsByTagName("type")[0].childNodes[0].nodeValue.replace(/\n/g,"");
    objPoem[i].HTML="";
    objPoem[i].targets=new Array();
    objPoem[i].targetIds=new Array();

    getPoemHTML(i,objPoem[i]);
    }

  return(objPoem);
  }

// **************************************
// Poem object function
// **************************************

function poemObj(pTitle,pType,pHTML,pTargets,pTargetIds)
  {
  this.title      =pTitle;       // poem title e.g. 'Shy Sky'
  this.type       =pType;        // poem type e.g. '..y'
  this.HTML       =pHTML;        // HTML of the text of the poem
  this.targets    =pTargets;     // highlighted words in the poem
  this.targetIds  =pTargetIds;   // Ids of highlighted words 
  }

// *****************************************************
// Highlight and create ids for words in the poem
// *****************************************************

function getPoemHTML(poem,object)
  {
  var splitPoem=new Array();

  var textHTML="";
  var itemTarget="";
  var itemId="";

  var itemIds=new Array();
  var itemText=new Array();
  var targetCount=0;

  var poemText="";

// get the poem text, cut off the first newline character, change the rest to <br />

  poemText=GG_xml[poem].getElementsByTagName("poem")[0].childNodes[0].nodeValue;

  if (poemText.charAt(0)=='\n')
    {
    poemText=poemText.slice(1);
    }

  poemText=poemText.replace(/\n/g, "<br />");

// target words are in the format #~target#
// split the text into an array at the # characters
// target words will then be in array elements beginning with ~

  splitPoem=poemText.split(/#/g);

  for (var n=0; n<splitPoem.length; n++)
    {
    if (splitPoem[n].charAt(0)=="~")
      {
      itemId='poem'+poem+'target'+n;
      itemTarget=splitPoem[n].slice(1);

      textHTML+="<strong id='"+itemId+"' ";
      textHTML+="onmouseover='targetHover("+targetCount+")' ";
      textHTML+="onmouseout='targetUnhover("+targetCount+")' ";
      textHTML+=">"+itemTarget+"</strong>";

      itemText[targetCount]=itemTarget;
      itemIds[targetCount]=itemId;
      targetCount+=1;
      }
    else
      {
      textHTML+=splitPoem[n];
      }
    }

  object.HTML=textHTML;
  object.targets=itemText;
  object.targetIds=itemIds;
  }

// *****************************************************
// Show the individual poem
// *****************************************************

function showPoem(poemIndex)
  {
  writeLog('showPoem('+poemIndex+')');

  GG_currentPoem=poemIndex;

  var newWordList="";
  newWordList=randomWords(GG_objPoem[poemIndex].targets);

  GG_objWord=createWordObjects(newWordList);
  GG_objTarget=createTargetObjects(poemIndex);

  // Populate the screen

  GG_screenZone[0].innerHTML=GG_objPoem[poemIndex].title+" ("+GG_objPoem[poemIndex].type+")";
  GG_screenZone[1].innerHTML=GG_objPoem[poemIndex].HTML;

  GG_screenZone[2].innerHTML=FF_rhymesMenu(poemIndex);

  GG_screenZone[3].innerHTML=wordListHTML(GG_objWord);
  GG_screenZone[5].innerHTML=faceHTML();

  GG_faceId=document.getElementById('face');
  GG_mouthId=document.getElementById('mouth');
  GG_leftEyeId=document.getElementById('lefteye');
  GG_rightEyeId=document.getElementById('righteye');

  expressStatus('start');
  populateObjects();
  }

// ***************************
// create random list of words
// ***************************

function randomWords(targetList)
  {
  writeLog('randomWords()');

  var indexList=new Array();
  var randomList=new Array();
  var randomWord=0;
  var next=0;
  var duplicate=false;
  var howMany=0;

  for (var i=0; i<targetList.length; i++)
   {
   if (next==0)
     {
     indexList[next]=i;
     next=next+1;
     }
   else
     {
     duplicate=false;
     for (var k=0; k<i; k++)
       {
       if (targetList[i]==targetList[k])
         {
         duplicate=true;
         k=i;
         }
       }
     if (!duplicate)
       {
       indexList[next]=i;
       next=next+1;
       }
     }
   }

  howMany=(indexList.length<5)? indexList.length : 5;

  for (var j=0; j<howMany; j++)
    {
    randomWord=Math.floor(indexList.length*Math.random());
    randomList[j]=targetList[indexList[randomWord]];
    indexList.splice(randomWord,1);
    }

  return(randomList);
  }

// **************************************
// Text object function
// **************************************

function textObj(pId,pElement,pComma,pCommaId,pText,pStatus)
  {
  this.id         =pId;          // id atribute
  this.element    =pElement;     // from getElementById
  this.comma      =pComma;       // from getElementById for the separating text
  this.commaId    =pCommaId;     // id of comma
  this.text       =pText;        // actual text of this word
  this.status     =pStatus;      // 'unselected','hover','mismatched','matched'
  }

// *********************
// create word objects
// *********************

function createWordObjects(wordList)
  {
  var objects=new Array();

  for (var i=0; i<wordList.length; i++)
    {
    objects[i]=new textObj();
    objects[i].id='word'+i;
    objects[i].commaId='comma'+i;
    objects[i].text=wordList[i];

    objects[i].element=null;
    objects[i].comma=null;
   
    objects[i].status='unselected';
    }
  return(objects);
  }

// *********************
// create target objects
// *********************

function createTargetObjects(poem)
  {
  var objects=new Array();

  for (var j=0; j<GG_objPoem[poem].targets.length; j++)
    {
    objects[j]=new textObj();
    objects[j].id=GG_objPoem[poem].targetIds[j];
    objects[j].text=GG_objPoem[poem].targets[j];

    objects[j].element=null;
    objects[j].status='unselected';
    }
  return(objects);
  }

// *****************************************************
// create rhymes list menu
// *****************************************************

function FF_rhymesMenu(thisOne)
  {
  writeLog('FF_rhymesMenu('+thisOne+')');

  var menuHTML="";

  menuHTML+="<h3>Choose a new rhyme:</h3><br />";

  menuHTML+="<form>";
  menuHTML+="<select id='rhymesMenu' onchange='changeRhyme(0)'>";

  for (var i=1; i<GG_xml.length; i++)
    {
    menuHTML+="<option ";
    if (thisOne==i)
      {
      menuHTML+="selected='selected' ";
      }
    menuHTML+="value='"+i+"' >";
    menuHTML+=GG_objPoem[i].title+" ("+GG_objPoem[i].type+")";
    menuHTML+="</option>";
    }

  menuHTML+="</select>";
  menuHTML+="</form>";

  return(menuHTML);
  }

// *****************************************************
// create word list
// *****************************************************

function wordListHTML(words)
  {
  writeLog('wordListHTML([words])');

  var wordListHTML="";

  for (var i=0; i<words.length; i++)
    {
    wordListHTML+="<strong id='"+words[i].commaId+"' >";
    wordListHTML+=', ';
    wordListHTML+="</strong>";
    wordListHTML+="<strong id='"+words[i].id+"' ";
    wordListHTML+="onmouseover='wordHover("+i+")' ";
    wordListHTML+="onmouseout='wordUnhover("+i+")' ";
    wordListHTML+=">";
    wordListHTML+=words[i].text;
    wordListHTML+="</strong>";
    }

  return(wordListHTML);
  }

// *****************************************************
// Create HTML for face
// *****************************************************

function faceHTML()
  {
  writeLog('faceHTML()');

  var face=""

  face+="<img id='face'  src='"+faceImage.src+"' /><br />";
  face+="<img id='lefteye'  src='"+anEyeImage.src+"'  class='lefteye'  />";
  face+="<img id='righteye' src='"+anEyeImage.src+"'  class='righteye' /><br />";
  face+="<img id='mouth' src='"+laughImage.src+"' class='mouth' />";

  return(face);
  }

// **************
// express status
// **************

function expressStatus(newWhatHappened,index,target)
  {
  writeLog('expressStatus('+newWhatHappened+','+index+','+target+'), GG_whatHappened: '+GG_whatHappened);

  var speechHTML="";

  if (GG_whatHappened==null)
    {
    whatHappened=newWhatHappened;
    }  
  else
    {
    if (GG_whatHappened=='match' || GG_whatHappened=='mismatch')
      {
      if (newWhatHappened=='hover' || newWhatHappened=='selected')
        {
        GG_whatHappened=newWhatHappened;
        }
      } 
    else
      {
      if (newWhatHappened!="")
        {
        GG_whatHappened=newWhatHappened;
        }
      }
    }  

  if (GG_allMatched)
    {
    speechHTML+="You matched them all! Good job!<br />";
    speechHTML+="<strong><a href='javascript:changeRhyme(1)' >Click here for next rhyme</a></strong>";
    setFace('grin');
    }
  else
    {
    switch (GG_whatHappened)
      {
      case ('start'):
        speechHTML+="Hi! Find the words above in the rhyme. <br />Click on a word to pick it up";
        setFace('laugh');
        break;
      case ('hover'):
        speechHTML+="Click on <strong>"+GG_objWord[index].text+"</strong> to pick it up";
        setFace('uh');
        break;
      case ('selected'):
        speechHTML+="You picked up: <strong>"+GG_objWord[index].text+"</strong>! <br />Now click where it is in the rhyme";
        setFace('smile');
        break;
      case ('target acquired'):
        speechHTML+="You picked up: <strong>"+GG_objWord[index].text+"</strong>! <br />Click to see if it matches";
        setFace('ooh');
        break;
      case ('mismatch'):
        speechHTML+="Oops! <strong>"+GG_objWord[index].text+"</strong> and <strong>"+GG_objTarget[target].text+"</strong>, didn't match";
        setFace('frown');
        break;
      case ('match'):
        speechHTML+="Hooray! You matched: <strong>"+GG_objWord[index].text+"</strong>!";
        setFace('laugh');
        break;
      default:
        speechHTML+="Click on one of the words above to pick it up";
        setFace('hmm');
      }
    }

  GG_screenZone[4].innerHTML="<table class='speech'><tbody><tr><td>"+speechHTML+"</td></tr></tbody></table>";
  }

// ******************
// set the face image
// ******************

function setFace(status)
  {
  writeLog('setFace('+status+')');

  switch (status)
    {
    case ('grin'):
      GG_mouthId.src=grinImage.src;
      break;
    case ('laugh'):
      GG_mouthId.src=laughImage.src;
      break;
    case ('smile'):
      GG_mouthId.src=smileImage.src;
      break;
    case ('hmm'):
      GG_mouthId.src=hmmImage.src;
      break;
    case ('uh'):
      GG_mouthId.src=uhImage.src;
      break;
    case ('ooh'):
      GG_mouthId.src=oohImage.src;
      break;
    case ('frown'):
      GG_mouthId.src=frownImage.src;
      break;
    default:
      GG_mouthId.src=smileImage.src;
      break;
    } 
  }

// **************
// populate objects
// **************

function populateObjects()
  {
  writeLog('populateObjects()');

  for (var i=0; i<GG_objWord.length; i++)
    {
    GG_objWord[i].element=document.getElementById(GG_objWord[i].id);
    GG_objWord[i].comma=document.getElementById(GG_objWord[i].commaId);

    styleWord(i);
    }

// remove the first comma

  GG_objWord[0].comma.className="hidden";
  GG_objWord[0].comma.innerHTML="";

  for (var j=0; j<GG_objTarget.length; j++)
    {
    GG_objTarget[j].element=document.getElementById(GG_objTarget[j].id);
    styleTarget(j);
    }

  document.onmousedown=mouseClick;
  document.onmousemove=trackMouse;
  }

// **************
// style word
// **************

function styleWord(index)
  {
  switch (GG_objWord[index].status)
    {
    case ('matched'):
      GG_objWord[index].element.className='hidden';
      GG_objWord[index].element.innerHTML='';

      GG_objWord[index].comma.className='hidden';
      GG_objWord[index].comma.innerHTML='';
      break;
    case ('mismatched'):
      GG_objWord[index].element.className='red';
      break;
    case ('hover'):
        GG_objWord[index].element.className='blue';
      break;
    case ('selected'):
      GG_objWord[index].element.className='blank';
      break;
    default:
      GG_objWord[index].element.className='black';
    }
  }

// **************
// style target
// **************

function styleTarget(index)
  {
  switch (GG_objTarget[index].status)
    {
    case ('matched'):
      GG_objTarget[index].element.className='green';
      GG_objTarget[index].element.onmouseover=null;
      GG_objTarget[index].element.onmouseout=null;
      break;
    case ('mismatched'):
      GG_objTarget[index].element.className='red';
      break;
    case ('hover'):
      GG_objTarget[index].element.className='blue';
      break;
    case ('selected'):
      GG_objTarget[index].element.className='purple';
      break;
    default:
      GG_objTarget[index].element.className='black';
    }
  }

// **************
// on mouse click 
// **************

function mouseClick(e)
  {
  writeLog('mouseClick(), GG_selectedWord: '+GG_selectedWord);

  if (e==null) 
    { 
    e=window.event;
    }

  var sender=(typeof(window.event)!= "undefined") ? e.srcElement : e.target;
  
  if (sender.id!=null)
    {
    if (GG_selectedWord==null)
      {
      examineWords(sender.id);
      }
    else
      {
      examineTargets(sender.id);
      }
    }
  }

// ******************
// track mouse
// *****************

function trackMouse(e)
  {
  var facePosn=null;
  var mouseX=0; mouseY=0;
  var x=0; y=0; 
  var dx=0; dy=0; dr=0;
 
  if (!e) 
    {
    e = window.event;
    }

  if (e.pageX || e.pageY) 	
    {
    mouseX = e.pageX;
    mouseY = e.pageY;
    }
  else if (e.clientX || e.clientY) 	
    {
    mouseX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
    mouseY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
    }

  facePosn=absolutePosition(GG_faceId);

// left eye

  x=facePosn.x + GG_leftx;
  y=facePosn.y + GG_lefty;
  dx=mouseX-x; 
  dy=mouseY-y; 

  dr=Math.sqrt((dx*dx)+(dy*dy));

  if (dr<5)
    {
    x=GG_lefteyex;
    y=GG_lefteyey;
    }
  else
    {
    x=Math.floor(dx*4/dr)+GG_lefteyex;
    y=Math.floor(dy*4/dr)+GG_lefteyey;
    }

  GG_leftEyeId.style.left=x+"px";
  GG_leftEyeId.style.top=y+"px";

// right eye

  x=facePosn.x + GG_rightx;
  y=facePosn.y + GG_righty;
  dx=mouseX-x; 
  dy=mouseY-y; 

  dr=Math.sqrt((dx*dx)+(dy*dy));

  if (dr<5)
    {
    x=GG_righteyex;
    y=GG_righteyey;
    }
  else
    {
    x=Math.floor(dx*4/dr)+GG_righteyex;
    y=Math.floor(dy*4/dr)+GG_righteyey;
    }

  GG_rightEyeId.style.left=x+"px";
  GG_rightEyeId.style.top=y+"px";
  }

// ***************************************
// get the absolute position of an element
// ***************************************

function absolutePosition(elm) 
  {
  var posObj = {'x': elm.offsetLeft, 'y': elm.offsetTop};

  if(elm.offsetParent) 
    {
    var temp_pos = absolutePosition(elm.offsetParent);
    posObj.x += temp_pos.x;
    posObj.y += temp_pos.y;
    }

  return (posObj);
  }

// **************
// on mouse hover
// **************

function wordHover(index)
  {
  if (GG_selectedWord==null)
    {
    writeLog('wordHover('+index+'), GG_selectedWord: '+GG_selectedWord);

    wordStatus(index,'hover');
    styleWord(index);
    expressStatus('hover',index);
    }
  }

function wordUnhover(index)
  {
  if (GG_selectedWord==null)
    {
    writeLog('wordUnhover('+index+'), GG_selectedWord: '+GG_selectedWord);

    wordStatus(index,'unhover');
    styleWord(index);
    expressStatus('unhover',index);   
    }
  }

// **************
// on mouse hover
// **************

function targetHover(index)
  {
  if (GG_selectedWord!=null)
    {
    writeLog('targetHover('+index+')');

    targetStatus(index,'hover');
    styleTarget(index);
    expressStatus('target acquired',GG_selectedWord);
    }
  }

function targetUnhover(index)
  {
  if (GG_selectedWord!=null)
    {
    writeLog('targetUnhover('+index+')');

    targetStatus(index,'unhover');
    styleTarget(index);
    expressStatus('selected',GG_selectedWord);
    }
  }

// *******************
// change rhyme
// *******************

function changeRhyme(action)
  {
  var nextPoem=0;

  if (action==0)
    {
    nextPoem=document.getElementById("rhymesMenu").value;
    }
  else
    {
    nextPoem=GG_currentPoem+1;
    if (nextPoem>=GG_xml.length)
      {
      nextPoem=1;
      }
    }
  window.location.href=GG_URLparts[0]+'?'+nextPoem;
  }

// **************************************
// return index for selected word
// **************************************

function getIndex(id,textObject)
  {
  writeLog('getIndex('+id+',[obj])');

  var objectIndex=null;

  if (id!=null)
    {
    for (var k=0; k<textObject.length; k++)
      {
      if (textObject[k].id==id && textObject[k].status!='matched')
        {
        objectIndex=k;
        }    
      }
    }
  writeLog('getIndex()--> objectIndex: '+objectIndex);
  return (objectIndex);
  }

// *******************************
// stop highlighting last mismatch
// *******************************

function unmismatch()
  {
  writeLog('unmismatch()');

  if (GG_mismatchedTarget!=null)
    {
    targetStatus(GG_mismatchedTarget,'unselected');
    styleTarget(GG_mismatchedTarget);
    GG_mismatchedTarget=null;
    }

  if (GG_mismatchedWord!=null)
    {
    wordStatus(GG_mismatchedWord,'unselected');
    styleWord(GG_mismatchedWord);
    GG_mismatchedWord=null;
    }
  }

// ***********************************
// look to see which word was selected
// ***********************************

function examineWords(id)
  {
  writeLog('examineWords('+id+')');

  var selectedWord=null;

  selectedWord=getIndex(id,GG_objWord);

  if (selectedWord!=null)
    {
    GG_selectedWord=selectedWord;
    wordStatus(GG_selectedWord,'selected');
    expressStatus('selected',GG_selectedWord); 
    }

  writeLog('examineWords()--> selectedWord: '+selectedWord);
  }

// *************************************
// look to see which target was selected
// *************************************

function examineTargets(id)
  {
  writeLog('examineTargets('+id+')');

  var selectedTarget=null;

  selectedTarget=getIndex(id,GG_objTarget);

  if (selectedTarget!=null)
    {
    checkMatch(GG_selectedWord,selectedTarget);
    }
  else
    {
    wordStatus(GG_selectedWord,'unselected');
    GG_selectedWord=null;
    expressStatus('unselected'); 
    }

  writeLog('examineTargets()--> selectedTarget: '+selectedTarget);
  }

// **************************************
// check if word and target match
// **************************************

function checkMatch(wordIndex,targetIndex)
  {
  writeLog('checkMatch('+wordIndex+', '+targetIndex+')');

  if (wordIndex!=null)
    {
    if (GG_objWord[wordIndex].text.toLowerCase()==GG_objTarget[targetIndex].text.toLowerCase())
      {
      highlightIdenticalTargets(GG_objWord[wordIndex].text);
      wordStatus(wordIndex,'matched');
      expressStatus('match',wordIndex);   
      }
    else
      {
      GG_mismatchedTarget=targetIndex;
      targetStatus(targetIndex,'mismatched');

      GG_mismatchedWord=wordIndex;
      wordStatus(wordIndex,'mismatched');

      expressStatus('mismatch',wordIndex,targetIndex);   
      }

    GG_selectedWord=null;
    styleWord(wordIndex);
    styleTarget(targetIndex);
    }
  }

// *************************
// set the status of a word
// *************************

function wordStatus(wordIndex,statusValue)
  {
  writeLog('wordStatus('+wordIndex+', '+statusValue+')');

  GG_objWord[wordIndex].status=statusValue;

  switch (statusValue)
    {
    case ('selected'):
      unmismatch();
      GG_objWord[wordIndex].status='selected';
      break;
    case ('hover'):
      unmismatch();
      GG_objWord[wordIndex].status='hover';
      break;
    default:
      break;
    }
  styleWord(wordIndex);
  reworkWordlist()
  }

// ***************************
// set the status of a traget
// ***************************

function targetStatus(targetIndex,statusValue)
  {
  writeLog('targetStatus('+targetIndex+', '+statusValue+')');

  GG_objTarget[targetIndex].status=statusValue;

  styleTarget(targetIndex);
  }

// *******************************************
// highlight any targets with the same text in
// *******************************************

function highlightIdenticalTargets(text)
  {
  writeLog('highlightIdenticalTargets('+text+')');

  for (var n=0; n<GG_objTarget.length; n++)
    {
    if (GG_objTarget[n].text==text)
      {
      targetStatus(n,'matched');
      styleTarget(n);
      }
    }
  }

// ***************************************
// remove unnecessary commas from wordlist
// and check if all have been matched
// ***************************************

function reworkWordlist()
  {
  writeLog('reworkWordlist()');

  var first=true;

  GG_allMatched=true;
  for (var n=0; n<GG_objWord.length; n++)
    {
    if (GG_objWord[n].status!='matched')
      {
      GG_allMatched=false;

      if (first)  // turn off the preceding comma for the first unmatched word
        {
        GG_objWord[n].comma.className="hidden";
        first=false;
        }
      else
        {
        GG_objWord[n].comma.className="black";
        }
      }
    }
  }

// *********************
// debugging information
// *********************

function writeLog(message) 
  {
/*
  var programVersion='26';

  GG_debugLog+="<br />"+programVersion+": "+message;

  if (GG_screenZone[6]!=null)
    {
    GG_screenZone[6].innerHTML=GG_debugLog;
    }
*/
  }

// the end
