//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//	Gatekeeper Educational Ltd
//	Contents of this file copyright F J Ahearn
//	If you use significant portions of the jscript much as is please leave this notice intact
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

//test only leave commented out
//wint=open("","test");
//wint.document.open("text/plain");
//wint.document.writeln(document.vlinkColor) ;
//document.getElementById("test").innerHTML+="n= "+n+"<br>";
//var testcnt=0;

//Size of main content area as designed (1152*864 screen) and scaling factors
var cw=1152.0;
var ch=747.0;
var wf=1.0;
var hf=1.0;

//interactive parameters
var param=new Array();

//pointers to all elements - firefox cannot use .all
var inps=new Array(); //contains data for params, areas and connecting lines
var divs=new Array(); //containers for both text and images - controls etc
var spans=new Array(); //drag and drop elements

//target areas
var numtgts=0;
var tgts=new Array();

//connecting lines
var numlines;
var numleft;
var lines=new Array();
var numcon=4; //max number of junctions allowed for

//the area markers and lines
var outline; //selected area marker
var dline;   //dynamic line
var fmark;   //fixed dynamic line marker ie the arrow origin
var dmark;   //moverable dynamic line marker ie the arrow head
var line0;   //the basic element for creating connecting lines

//global line angle for transfer to arrow head angle
var sintheta;
var costheta;
var quad;

//arrow head on connecting lines
var aangle=30; //angle to main line in degrees
var alen=20; //length in pixels along line
var cmargin;
var asin;  //multipliers for acos and asin factors of main line
var acos;

//the coordinates of active areas - store both right and width etc for speed in over checks
var xas0=new Array();
var yas0=new Array();
var xas1=new Array();
var yas1=new Array();
var was=new Array();
var has=new Array();
//ditto unscaled for firefox, we need these to grab from original unscaled image
var xa0=new Array();
var ya0=new Array();
var wa=new Array();
var ha=new Array();

//flyback and dragdrop flags
var moving=false; 		//flyback is still moving last item
var xp=new Array(); //xp twice??
var yp=new Array();
var step; var steps;

//selections and dragdrop flags
//area selections, -1 means not selected otherwise 0 to n
var nsel=-1; 		//area mouse is over during move
var nseldown=-1; 	//area selected on mousedown
var nselup=-1; 		//area selected on mouseup
var dragging=false; 		//Drag and drop in progress flag

//coords at centre of 1st selected item
var xfirst=0;
var yfirst=0;

//coords of last mouse position during drag
var xold=0;
var yold=0;

//mouse up position
var xup;
var yup;

//offsets for both dynamic line markers
var xoff;
var yoff;

//which browser?
var ie=false;

//canvas
var img = new Image(); 
var canvas;   //canvas object
var ctx;      //context
var ctop;     //top of canvas
var nl=-1; //last area highlighted -1 is no highlight

//connecting lines coordinates - these have to be continually redrawn in firefox so store to save time
var xcl = new Array();	    	//coordinates of joins	
var ycl = new Array();
var colcl  = new Array();   	//colour
var statcl  = new Array();  	//status already drawn?
var ncl = new Array(); 		//number connections in line

//Initial tasks on open

//Resize on opening
//this is alternative to <body onresize= which also works in firefox
window.onresize = new Function("window.location.href=window.location.href;");
window.onload = init;
function init()
{

//get browser
if (navigator.appName=="Microsoft Internet Explorer") ie=true;

//get interactive parameters
getparams();

//get pointers to all elements - firefox does not recognise .all
inps = document.getElementsByTagName("INPUT");
spans = document.getElementsByTagName("SPAN");
divs = document.getElementsByTagName("DIV");

//drag&drop targets - start at 1 as the 1st input is params
numtgts = param[0];
for (m=1,n=0;n<numtgts;m++,n++) tgts[n]=inps[m];

//connecting lines - should follow targets
numlines = param[1];  numleft=numlines;
//numleft=2; //for test of ending only comment out

//the area markers and lines for ie
outline = document.getElementById("outline"); 
dline = document.getElementById("dline");
fmark = document.getElementById("fmark");
dmark = document.getElementById("dmark");
line0 = document.getElementById('line0');
		
//allow for marker sizes by preavaluating the offsets
//it is assumed that fixed and draggeable markers are same size, used for both
with (dmark.style) {xoff=0.5*pos(width); yoff=0.5*pos(height); }

//preevaluate arrow head constants
aangle = aangle * Math.PI / 180.0;
acos = Math.cos(aangle);
asin = Math.sin(aangle);
cmargin=alen*asin+2;

//rescale all used elements
resize();

//get connecting line coordinates
getconn();

//hide either canvas or background image according to browser
if (ie)
{
  document.getElementById('canvasdiv').style.visibility="hidden";
  document.getElementById('imagediv').style.visibility="visible";
}

//for firefox etc set up the canvas
else
{
  document.getElementById('imagediv').style.visibility="hidden";
  canvas = document.getElementById('canvas');
  ctop = pos(document.getElementById('canvasdiv').style.top);
  ctx = canvas.getContext('2d');

  //get the image
  //note directly pointing at existing background image seems to cause scale problem for some reason
  img.src = document.getElementById('backimage').src;  
  ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
}  

//show number lines to do
document.getElementById("number").innerHTML=numleft +" lines left";

//start drag and drop
document.onmousemove = OnMouseMove;

//Shows all lines for test - comment out normally
//for (t=1*numtgts+1; t<inps.length; t++) connect(inps[t].id);
}


//Get parameters for interactive from a hidden control
//standard function
function getparams()
{
  str = document.getElementById("params").value;
  n = 0; p1=0;
  do
  {
	p2 = str.indexOf(",",p1);
        if (p2>0) param[n] = str.substring(p1,p2);
        n++; 
        p1=p2+1
  }
  while (p2>0 && p2<str.length);
}


//rescale all elements to screen
//standard function apart from last part about animation limits
function resize()
{

//get design size from the background image in case user has changed it
with (document.getElementById("imagediv").style) {w=width; h=height;}
cw = pos(w); ch=pos(h);

//ensure that canvas is same
with (document.getElementById("canvasdiv").style) {width=w; height=h;}
with (document.getElementById("canvas")) {width=cw; height=ch;}

//Size according to actual required width at given screen res
ws = document.body.clientWidth; hs = Math.floor(ch * ws / cw);
if (hs>document.body.clientHeight)
{	
  hs=document.body.clientHeight;
  ws = Math.floor(cw * hs / ch);
}
wf=ws / cw; hf=wf;  lf = 0.5 * (document.body.clientWidth - ws);

//god knows why this is needed - scale/offset have to be primed ?????
x = rescale('1px',1);
x = offset('1px',1);

//get numeric dimensions of active areas from hidden inputs, note px will be present even if not in HTML
//we need width/height and 2nd position for speed in processing
for (n=0; n<tgts.length; n++) 
{  
  with (tgts[n].style)
  {  
    //store unscaled for firefox original image sections
    xa0[n] = pos(left);
    ya0[n] = pos(top);
    wa[n] = pos(width);
    ha[n] = pos(height);

    //scaled for ie and firefox as drawn
    xas0[n] = Math.floor(pos(left) * wf) + lf;
    yas0[n] = Math.floor(pos(top) * hf);
    was[n] = Math.floor(pos(width) * wf);
    has[n] = Math.floor(pos(height) * hf);
    xas1[n] = xas0[n] + was[n] - 1;
    yas1[n] = yas0[n] + has[n] - 1;
  }
}

//rescale captions, help buttons etc that may be visible
for (n=0; n<divs.length; n++) 
{  
  with (divs[n].style)
  {  
    left = Math.floor(pos(left) * wf + lf) + 'px';
    top = rescale(top,hf);
    width = rescale(width,wf);
    height = rescale(height,hf);
    fontSize = rescale(fontSize,hf);
  }
}

//canvas for firefox only this is inside a div that has already been moved above, just set area to match
//note for future ref - ensure no scroll bars (see HTML body) or get odd results with clientwidth changing during resize above
with (document.getElementById("canvas")) {width = ws; height = hs;}
}

//get scaled coordinates of the connecting line junctions
function getconn()
{

//create 2 dim arrays for line coords
for (n=0; n<numlines; n++)
{
   xcl[n]=new Array(numcon); 
   ycl[n]=new Array(numcon);
}

//for each input
cl=0;
for (n=0; n<inps.length; n++) 
{  

  //if a connecting line descriptor
  if (inps[n].lang!="")
  {
     with (inps[n])
     {  
  	//colour held in name
     	colcl[cl]=name;

        //init status to not drawn
	statcl[cl]  = false;

     	//number of sectors of the line from len = nsector + 9*(nsector+1)
     	//value is form NNNN,NNNN-NNNN,NNNN-NNNN,NNNN etc
	ncl[cl] = (value.length-9) / 10;

     	//store xy coordinates for this connecting line
     	//value is form NNNN,NNNN-NNNN,NNNN-NNNN,NNNN etc
     	for (s=0,m=0; s<value.length; s+=10,m++)
     	{ 
           xcl[cl][m] = Math.round(wf * value.substring(s,s+4));
	   if (ie) xcl[cl][m] += lf;
           ycl[cl][m] = Math.round(hf * value.substring(s+5,s+9));
     	}
     }
     cl+=1;
  }
}
}

//general routines for scaling & offsetting of position and dimensions
//firefox does not have posLeft, posWidth etc
//standard functions

//take val as Npx, mult by numeric sc and return Mpx
function rescale(val,sc)
{
    num = 1.0 * parseInt(val,10);
    return Math.round(sc * num) + "px";
}
//take val as Npx, add numeric off and return Mpx
function offset(val,off)
{
  num = parseInt(val,10); 
  return (1*num + 1*off) + "px";
}
//take val as Npx, return N
function pos(val)
{
    return parseInt(val,10);
}


//drag and drop

//mouse move
function OnMouseMove(e)
{
  //if finished do nowt
  if (numleft<=0)
  {
	moving=true;
        return;
  }

  //get event and target for ie or firefox
  if (e==null) {e = window.event; x=e.clientX; y=e.clientY;}
  else         {x=e.pageX; y=e.pageY;}
  //document.getElementById("test2").innerHTML=x+" "+y; //test only

  //If moving during flyback do nothing else
  if (moving) return;

  //see which active area it is over if any
  nsel = -1;
  for (n=0; n<numtgts; n++) 
  {  
      //If cursor within drop area note drop item
      if (x>=xas0[n])
        if (x<=xas1[n])
           if (y>=yas0[n])
             if (y<=yas1[n])
             {
                nsel = n;
                break;
             }
  }


  //if over any area show outline and allow drag if not already allowed (dragging starts on mousedown)
  if (nsel>=0)
  { 

     //internet explorer outline set by bordered span
     if (ie)
       	with (outline.style) { left=xas0[n]+'px'; top=yas0[n]+'px'; width=was[n]+'px'; height=has[n]+'px'; visibility = "visible";}

     //firefox uses canvas
     else
     {

        //ensure any previous election removed, can go too fast between adjacent boxes
        //note rectangle set previously is inside box, does not include the line so make clear area a bit bigger
        if (nl>=0)
        {
            xs=xa0[nl]-20; ys=ya0[nl]-20; ws=1*wa[nl]+40; hs=1*ha[nl]+40;
            xt=Math.floor(xs*wf); yt=Math.floor(ys*hf); wt=Math.floor(ws*wf); ht=Math.floor(hs*hf); 
            ctx.drawImage(img,xs,ys,ws,hs,xt,yt,wt,ht);
        }
      
        //draw new rectangle
  	ctx.strokeRect(xas0[nsel]-lf,yas0[nsel],was[nsel],has[nsel]);
	redrawcl();
        nl=nsel;
     }

     //if already selected different item show link that will be made otherwise just show name at top left
     if (dragging && nsel!=nseldown)
        document.getElementById("caption").innerHTML=tgts[nsel].name + " eats " + tgts[nseldown].name + "?";
     else
     	document.getElementById("caption").innerHTML=tgts[nsel].name;

     //allow drag if not already allowed (dragging starts on mousedown)
     if (!dragging) document.onmousedown = OnMouseDown;  
  }

  //if not over area hide area marker in similar ways
  else
  {
     if (ie)
     	outline.style.visibility = "hidden";
     else
     {
        //note rectangle set previously is inside box, does not include the line so make clear area a bit bigger
        if (nl>=0)
        {
            xs=xa0[nl]-20; ys=ya0[nl]-20; ws=1*wa[nl]+40; hs=1*ha[nl]+40;
            xt=Math.floor(xs*wf); yt=Math.floor(ys*hf); wt=Math.floor(ws*wf); ht=Math.floor(hs*hf); 
            ctx.drawImage(img,xs,ys,ws,hs,xt,yt,wt,ht);
	    redrawcl();
            nl=-1;
        }
      }

     //hide caption
     document.getElementById("caption").innerHTML="";
  }

  //If dragging move line marker with mouse
  if (dragging)
  {
    //if Int explorer make lines out of elements
    if (ie)
    {
    	with (dmark.style) {left = (x-xoff)+'px';  top = (y-yoff)+'px';}
  
    	//move one end of the dynamic marker line ditto
    	with (document.getElementById("dline").style)
    	{
  		drawline(dline,xfirst, yfirst,x-xfirst,y-yfirst);
        	drawdhead();
    	}
    }

    //firefox use canvas to draw a line
    //note the mouse x is lf (left pos of canvas) more than canvas x
    else
    {
	drawlineff(xfirst-lf, yfirst, x-lf, y, xold, yold, nsel);
        drawdheadff(xfirst-lf, yfirst, x-lf, y);
        redrawcl();
    }
  }

  // cancel out any text selections - this is essential or won't work
  //has to go in mouse move too for this one as going outside original item?
  document.body.focus();
  document.onselectstart = function () { return false; };
  return false;
}


//mouse down - start drag
function OnMouseDown(e)
{

   //If flying back after a wrong match or not over an area do nothing else
   if (moving || nsel<0) return;

   //note which area it's over on down if any
   nseldown=1*nsel;

   //get event and target for ie or firefox
   if (e==null) {e = window.event; x=e.clientX; y=e.clientY;}
   else         {x=e.pageX; y=e.pageY;}

   //note the centre of selected area
   xfirst =  xas0[nsel]+0.5*was[nsel]; yfirst = yas0[nsel]+0.5*has[nsel];

   //if internet explorer we have to set up elements to make a line with
   if (ie)
   {

   	//put the fixed marker on the centre of selected area and make visible
   	with (fmark.style)
   	{
        	left = xfirst-0.5*pos(width)+'px'; top=yfirst-0.5*pos(height) +'px'; 
        	visibility = "visible";
   	}
  
   	//put the dynamic marker on the mouse position and make visible
   	with (dmark.style)
   	{
        	xd = x-xoff; yd=y-yoff; 
        	left = xd+'px'; top=yd +'px'; 
        	visibility = "visible";
   	}
  
   	//center the arrow item center vertical bottom aligned
   	dragline = document.getElementById("dline");
   	with (dline.style)
   	{
       		left = (xfirst - 0.5 * pos(width)) + 'px';
       		top = (yfirst - pos(height)) + 'px';	
       		visibility = "visible";
        }
   }
  
   //Start drag and drop of marker and enable selection
   dragging=true; 
   document.onmouseup = OnMouseUp;

   // cancel out any text selections - this is essential or won't work
   document.body.focus();
   document.onselectstart = function () { return false; };
   return false;
}


//mouse up - end drag
function OnMouseUp(e)
{
   //If flying back after a wrong answer do nothing else
   if (moving) return;

   //note which area it's over on up if any
   nselup=1*nsel;

   //get event and target for ie or firefox
   if (e==null) {e = window.event; xup=e.clientX; yup=e.clientY;}
   else         {xup=e.pageX; yup=e.pageY;}

   //if not in defined area do a fly back
   if (nselup<0) 
   {
       //Prevent further choice until animation finished
       moving = true;

       //stop drag and drop and wait for next selection
       dragging=false; 
       document.onmouseup = null;
       document.onmousedown = null;

       //Put the dragged item back
       flyback();
  }

  //if mouse up while over 1st selected element do nothing except hide arrow and reenable selection
  else
  {    
       if (nselup==nseldown) 
       {
           fmark.style.visibility="hidden";
           dmark.style.visibility="hidden";
           dline.style.visibility="hidden";
	   dragging=false; 
           document.onmouseup = null;
           document.onmousedown = null;
	   if (!ie)
           {
		clearlineff(xfirst,yfirst,xup,yup);
                redrawcl();
           }
       }

       //if both original and new areas are valid check if matched
       else
       {
           match();
       }
  }
}


//Matching

//Match items
function match()
{

  //if  eats 1st item draw a connecting line between the centres
  //The value of 2nd item is string of form nn,nn,nn. .. where each nn is the id of something it eats
  //so look for id of previously selected item in this item value
  if (tgts[nselup].value.indexOf(tgts[nseldown].id)>=0)
  {
  
      //firefox - redraw rectangle round item	
      if (!ie)
      {
 	ctx.strokeRect(xas0[nselup]-lf,yas0[nselup],was[nselup],has[nselup]);

	//this clear of first area needed if firefox has tabs not sure why exactly
        xs=xa0[nseldown]-20; ys=ya0[nseldown]-20; ws=1*wa[nseldown]+40; hs=1*ha[nseldown]+40;
        xt=Math.floor(xs*wf); yt=Math.floor(ys*hf); wt=Math.floor(ws*wf); ht=Math.floor(hs*hf); 
        ctx.drawImage(img,xs,ys,ws,hs,xt,yt,wt,ht);

        //clear dynamic line
        clearlineff(xfirst,yfirst,xup,yup);
      }

      //draw connection	
      connect(tgts[nseldown].id+tgts[nselup].id);  

      //if finished do end - hide dynamic lines and markers and show result
      if (numleft<=0)
      {
         if (ie)
	 {	
           fmark.style.visibility="hidden";
           dmark.style.visibility="hidden";
           dline.style.visibility="hidden";
           outline.style.visibility="hidden";
         }
         else
         {
           xs=xa0[nselup]-20; ys=ya0[nselup]-20; ws=1*wa[nselup]+40; hs=1*ha[nselup]+40;
           xt=Math.floor(xs*wf); yt=Math.floor(ys*hf); wt=Math.floor(ws*wf); ht=Math.floor(hs*hf); 
           ctx.drawImage(img,xs,ys,ws,hs,xt,yt,wt,ht);
	   redrawcl();
	 }
         document.getElementById("caption").innerHTML="ALL DONE!";
      }

      //otherwise remove arrow markers and reenable new selection
      else
      {  
         fmark.style.visibility="hidden";
         dmark.style.visibility="hidden";
         dline.style.visibility="hidden";
         dragging=false; 
         document.onmouseup = null;
         document.onmousedown = null;      
      }
  }

  //otherwise do a fly back
  else   
  {	
       //Prevent further choice until animation finished
       moving = true;

       //stop drag and drop and wait for next selection
       dragging=false; 
       document.onmouseup = null;
       document.onmousedown = null;

       //Put the dragged item back
       flyback();
  }
}


//dynamic and connnecting line draw

//draw line from selected item to cursor - internet explorer
function drawline(o,x,y,dx,dy)
{
    //abs distance mouse cursor from centre point
    hyp=Math.sqrt(dx*dx+dy*dy);
    if (hyp<0.001) hyp=0.001;
    sintheta=dx/hyp;
    costheta=-dy/hyp;

    //set size and position of the line
    //position of dragged end depends on quadrant
    with (o.style)
    {
	height=hyp+'px';
	if (dx>=0)
	{
           if (dy<0) {left=x+'px'; top=(y+dy)+'px';}
   	   else      {left=x+'px'; top=y+'px';}
        }
        else
	{
	  if (dy>=0) {left=(x+dx)+'px'; top=y+'px';}
   	  else       {left=(x+dx)+'px'; top=(y+dy)+'px';}
        }
    }

    //set rotation
    with (o.filters.item(0))
    {
      M11 = costheta;
      M12 = -sintheta;
      M21 = sintheta;
      M22 = costheta;
    }
}
//draw an arrow head at orientation of dynamic line - internet explorer
function drawdhead()
{
   dmark.filters.item(0).M11=costheta;
   dmark.filters.item(0).M12=-sintheta;
   dmark.filters.item(0).M21=sintheta;
   dmark.filters.item(0).M22=costheta;
}

//draw a line with firefox
function drawlineff(x0,y0,x1,y1,x2,y2,na)
{
  	//clear line from last time by putting a bit of image over it, allow a small overlap for arrow head
        clearlineff(x0,y0,x2,y2);

	//redraw any marked area erased
  	if (na>=0) ctx.strokeRect(xas0[na]-lf,yas0[na],was[na],has[na]);

  	//make new line
  	ctx.beginPath();
  	ctx.moveTo(x0,y0);
  	ctx.lineTo(x1,y1);
  	ctx.stroke();

        //store coords to clear next time
        xold=x1; yold=y1;
}

//clear line from last time by putting a bit of image over it, allow a small overlap for arrow head - firefox
function clearlineff(x0,y0,x2,y2)
{
  	//clear line from last time by putting a bit of image over it, allow a small overlap for arrow head
	dx=x2-x0; dy=y2-y0;
        dp=cmargin; dl=2*dp;
  	if (dx>0)  {xc = x0-dp; w=dx+dl; if (xc<0) xc=0;}
  	else	   {xc = x2-dp; w=dl-dx; if (xc<0) xc=0;}
  	if (dy>0)  {yc = y0-dp; h=dy+dl; if (yc<0) yc=0;}
  	else	   {yc = y2-dp; h=dl-dy; if (yc<0) yc=0;}
        ctx.drawImage(img,xc/wf,yc/hf,w/wf,h/hf,xc,yc,w,h);
}

//draw arrow head with firefox
function drawdheadff(x0,y0,x1,y1)
{
dx0=x1-x0; dy0=y1-y0;
hyp=Math.sqrt(dx0*dx0+dy0*dy0);
if (hyp<0.001) hyp=0.001;
t=alen/hyp; dx0=dx0*t; dy0=dy0*t;
k1=dy0*acos; k2=dx0*asin; k3=dx0*acos; k4=dy0*asin;
x2=x1-k3-k4;
y2=y1-k1+k2;
x3=x1-k3+k4;
y3=y1-k1-k2;

//make new line
ctx.beginPath();
ctx.moveTo(x2,y2);
ctx.lineTo(x1,y1);
ctx.lineTo(x3,y3);
ctx.stroke();
}

//draw connection line between food web related items
// a connecting line is made up of one or more connected straight lines
function connect(lineid) 
{

  //the hidden input describing connecting line
  with (document.getElementById(lineid))
  {
     //if this line drawn already nothing else
     if (name=="x") return;

     //index into pre-extracted coords
     nline = 1*lang;

     //mark line as used
     statcl[nline] = true;
     name="x";  
  }

  //internet explorer
  if (ie)
  {
     //for each straight portion of the line  
     for (n=0;n<ncl[nline];n++)
     {

       //set up a narrow span as a line
       var newline = document.createElement('span');

       //set required colour etc
       with (newline.style)
       {
         backgroundColor=colcl[nline];
         left="10px"; top="10px"; height="2px"; 	//initialise these but none actually matter as draw resizes
         width="2px"; 				//this sets line thickness
         zIndex=line0.style.zIndex;
         filter=dmark.style.filter;		//for some reason a filter on 'template' line0 stops code working
         visibility="visible";
       }
       line0.appendChild(newline);

       //draw line sector from start to end
       drawline(newline,xcl[nline][n],ycl[nline][n],xcl[nline][n+1]-xcl[nline][n],ycl[nline][n+1]-ycl[nline][n]);
     }

     //put arrow head on
     n=ncl[nline];
     drawhead(xcl[nline][n],ycl[nline][n],colcl[nline]);
  }

  //firefox - we have to redraw all the connection lines so far
  else
  {
	redrawcl();
  }

  //show connections still to be made
  numleft--;
  document.getElementById("number").innerHTML=numleft +" lines left";
}

//fast redraw drawn connection lines for firefox
function redrawcl() 
{
  //for each connection 
  for (n=0;n<numlines;n++)
  {	

       //if a line has already been drawn redraw it
       if (statcl[n])	
       {
	  ctx.strokeStyle = colcl[n];
	  ctx.beginPath();
  	  ctx.moveTo(xcl[n][0],ycl[n][0]);
 	  for (c=1;c<=ncl[n];c++)
  	  {
  		ctx.lineTo(xcl[n][c],ycl[n][c]);
	  }
 	  ctx.stroke(); 
          i1=ncl[n]-1; i2=ncl[n];
          drawdheadff(xcl[n][i1], ycl[n][i1], xcl[n][i2], ycl[n][i2]);
       }

  }
  ctx.strokeStyle = "black";
}

//draw an arrow head on end of connecting lines - this is 2 lines done in same way as above
function drawhead(x,y,col)
{

  //for -1 and +1, ie on both sides of the main line and symmetric about it
  for (n=-1;n<=1;n+=2)
  {

    //create a new line
    var newline = document.createElement('span');
    with (newline.style)
    {
        backgroundColor=col;
        left=x+'px'; top=y+'px'; 
        width="2px"; 
        zIndex=line0.style.zIndex; filter=dmark.style.filter; visibility="visible";
    }
    line0.appendChild(newline);

    //angle of rotation
    newsin = acos*sintheta + n * asin*costheta; dx=-alen*newsin;
    newcos = acos*costheta - n * asin*sintheta; dy=alen*newcos;

    //set size and position of the line
    //position depends on quadrant
    with (newline.style)
    {
        height=alen+'px';
        x=pos(left); y=pos(top);
	if (dx>=0)
	{
           if (dy<0) {left=x+'px'; top=(y+dy)+'px';}
   	   else      {left=x+'px'; top=y+'px';}
        }
        else
	{
	  if (dy>=0) {left=(x+dx)+'px'; top=y+'px';}
   	  else       {left=(x+dx)+'px'; top=(y+dy)+'px';}
        }
    }

    //set IE rotation filters
    with (newline.filters.item(0))
    {
      M11 = newcos;
      M12 = -newsin;
      M21 = newsin;
      M22 = newcos;
    }
  }
}

//flyback

//Return an incorrect item to previous position
function flyback()
{
  //set up position array with 1st pos as current last as previous and rest between two points
  dx=xup-xfirst; 
  dy=yup-yfirst;

  //Set number steps according to pixel distance approx 4 steps if straight up about 200 pixels
  dist = Math.sqrt(dx*dx + dy*dy);
  steps=Math.round(0.02 * dist);

  //Do a straight path
  if (ie)
  	with (dmark.style) {x=pos(left); y=pos(top);}
  else
       x=xup; y=yup;
  for (n=0;n<=steps;n++)
  {
    xp[n]=Math.floor(x-(n*dx)/steps); yp[n]=Math.floor(y-(n*dy)/steps);
  }

  //Move back along path
  step=0;
  dopath();
}
//Animate along path
function dopath()
{

//if internet explorer 
if (ie)
{
   //Drag item
   with (dmark.style)
   {
     left=xp[step] - xoff +'px'; 
     top=yp[step] - yoff +'px';
     drawline(dline,xfirst,yfirst,xp[step]-xfirst, yp[step]-yfirst);
     drawdhead();
   }
}
else
{
     x=xp[step]; y=yp[step];
     drawlineff(xfirst-lf, yfirst, x-lf, y, xold, yold, nselup);
     drawdheadff(xfirst-lf, yfirst, x-lf, y);
     redrawcl();
}

//If another step in path do next after delay 
if (++step<=steps) 
{   
  setTimeout("dopath()",50);
}

//De-Animate at end allow choice and hide arrow head 
else
{
  moving = false;

  if (ie)
  {  
	fmark.style.visibility="hidden";
  	dmark.style.visibility="hidden";
  	dline.style.visibility="hidden";
  }
  else
  {
        n=step-1;
  	x=xp[n]-lf-20; y=yp[n]-20; w=40; h=40;
        ctx.drawImage(img,x/wf,y/hf,w/wf,h/hf,x,y,w,h);
	redrawcl();
  }
}
}

//help
function showhelp() 
{
str = "Move the cursor over a plant or animal so that is outlined and then click and drag to create an arrow.\n\n" +
      "Drop the arrow head over an animal you think commonly eats your first selection.\n\n" +
      "Get it right and a connecting line is drawn, otherwise the arrow flies back."
window.alert(str);
}


