function init() 
         {
         document.onmousedown = mouseDown;
         document.onmousemove = mouseMove;
         document.onmouseup = mouseUp;
         if(navigator.appName == 'Netscape') 
            document.captureEvents(Event.MOUSEDOWN | Event.MOUSEMOVE | Event.MOUSEUP);         
         initPuzzle();
         }

function mouseDown(e) 
         {
	     if ((navigator.appName == 'Netscape' && e.which!=1) || (navigator.appName == 'Microsoft Internet Explorer' && event.button!=1)) return true;
	     var x = (navigator.appName == 'Netscape')? e.pageX : event.x+document.body.scrollLeft;
	     var y = (navigator.appName == 'Netscape')? e.pageY : event.y+document.body.scrollTop;
	     if (navigator.appName == 'Netscape' && e.target!=document) routeEvent(e);
	
	     ClickedLayer = -1;
         	              
		 //If the puzzle is not solved, check if a piece was clicked on.	     	     
		 for(var layer = 0; layer < Layers.length; layer++)
		    {                       
	         if(Selected(x, y, Layers[layer].id))
	           {
                if(ClickedLayer == -1)
                  {       
	              Layers[layer].ClickedX = x - GetX(Layers[layer].id);
	              Layers[layer].ClickedY = y - GetY(Layers[layer].id);
	              ClickedLayer = layer;
                  }
                else
                  if(GetZ(Layers[layer].id) > GetZ(Layers[ClickedLayer].id))
                    {
                    Layers[layer].ClickedX = x - GetX(Layers[layer].id);
	                Layers[layer].ClickedY = y - GetY(Layers[layer].id);
                    ClickedLayer = layer;
                    }
			   }                         
	        }
            
         if(ClickedLayer != -1)
           {
           PickUp(ClickedLayer);
           if(Layers[ClickedLayer].Word != -1)
             {
             for(var index = 0; index < Layers.length; index++)
                {
                if(Layers[index].Word == Layers[ClickedLayer].Word)
                  PickUp(index);
                }
             }
           }
                           
         if(ClickedLayer == -1) return true; 
         else return false;
}

function mouseMove(e) 
         {
	     var x = (navigator.appName == 'Netscape')? e.pageX : event.x+document.body.scrollLeft;
	     var y = (navigator.appName == 'Netscape')? e.pageY : event.y+document.body.scrollTop;
	     if (navigator.appName == 'Netscape' && e.target!=document) routeEvent(e);
						
		 //If a piece of the puzzle (word or letter) is selected,
		 //make it follow the mouse cursor.
                           
	     if(ClickedLayer != -1)
           {
           if(Layers[ClickedLayer].Word == -1)
	         {	       		   
		     Move(x - Layers[ClickedLayer].ClickedX, 
		          y - Layers[ClickedLayer].ClickedY, 
			      Layers[ClickedLayer].id);		     
	         }
           else
             {
             for(var layer = 0; layer < Layers.length; layer++)
                {
                if(Layers[layer].Word == Layers[ClickedLayer].Word)
                  {
                  if(Layers[layer].Letter == 0)
                    {
                    Words[Layers[layer].Word].x = GetX(Layers[layer].id);
                    Words[Layers[layer].Word].y = GetY(Layers[layer].id);
                    }
                  
                  //Align the letters of a solved word horizontally.
                  if(Words[Layers[ClickedLayer].Word].Direction == 0)
                    {
                    Move(x - Layers[ClickedLayer].ClickedX + 
                             Layers[layer].Letter * GetW(Layers[0].id) -
                             Layers[ClickedLayer].Letter * GetW(Layers[0].id), 
		                 y - Layers[ClickedLayer].ClickedY, 
			             Layers[layer].id);
                    }
                  //Align the letters of a solved word vertically.
                  if(Words[Layers[ClickedLayer].Word].Direction == 1)
                    {
                    Move(x - Layers[ClickedLayer].ClickedX, 
		                 y - Layers[ClickedLayer].ClickedY +
                             Layers[layer].Letter * GetH(Layers[0].id) -
                             Layers[ClickedLayer].Letter * GetH(Layers[0].id), 
			             Layers[layer].id);
                    }
                  }
                }
             }
           }

         var HoveredLayer = -1;
           
         for(var layer = 0; layer < Layers.length - 3; layer++)
		    {                       
	         if(Selected(x, y, Layers[layer].id))
                HoveredLayer = layer;
            }                                             		 
         
         if(ClickedLayer == -1 && HoveredLayer == -1) return true; 
         else return false;
}

function mouseUp(e) 
         {
	     var x = (navigator.appName == 'Netscape')? e.pageX : event.x+document.body.scrollLeft;
	     var y = (navigator.appName == 'Netscape')? e.pageY : event.y+document.body.scrollTop;
	     if (navigator.appName == 'Netscape' && e.target!=document) routeEvent(e);			         	         
           
         ClickedLayer = -1;	         
		 
		 var BigTol = 25;
		 var SmallTol = 15;         		 
		                         
         //Are the letters in the right order?
		 for(var Word_Counter = 0; Word_Counter < Words.length; Word_Counter++)
            {                        
            //Are the letters in the right order? (horizontally)            
            if(Words[Word_Counter].Solved == false)
              {
              Words[Word_Counter].Solved = true;              
              for(var Letter_Counter = 0; Letter_Counter < Words[Word_Counter].Letters.length - 1 && Words[Word_Counter].Solved == true; Letter_Counter++)
                 {               
                 Words[Word_Counter].Solved = false;
                 for(var Layers1_Counter = 0; Layers1_Counter < Words[Word_Counter].Letters[Letter_Counter].length; Layers1_Counter++)
                    {                    
                    for(var Layers2_Counter = 0; Layers2_Counter < Words[Word_Counter].Letters[Letter_Counter + 1].length; Layers2_Counter++)
                       {
                       if(GetX(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].id) + 
                          GetW(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].id) - SmallTol <
                          GetX(Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].id) &&
                          GetX(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].id) + 
                          GetW(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].id) + BigTol >
                          GetX(Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].id) &&                          
                          GetY(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].id) - SmallTol <
                          GetY(Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].id) &&
                          GetY(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].id) + BigTol >
                          GetY(Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].id) &&
						  Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].Word == -1)
                         {
                          if(Letter_Counter == 0)
                            {
                            Words[Word_Counter].x = GetX(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].id);
                            Words[Word_Counter].y = GetY(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].id);               
                         
                            if((Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].Word == -1 ||
                                Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].Word == Word_Counter))
                               {
                                Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].Word = Word_Counter;
                                Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].Letter = Letter_Counter;
                               }
							}
                            
						  /*if(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].Word != -1 &&
                             Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].Word != Word_Counter)
                            {
                            Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].OverlappedWord = Word_Counter;
                            Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].OverlappedLetter = Letter_Counter;
                            Words[Word_Counter].x = GetX(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].id) -
                                                    GetW(Layers[0].id) * Letter_Counter;
                            Words[Word_Counter].y = GetY(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].id);
                            }*/	
						  						  
                          if(Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].Word == -1 &&
						     Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].Word == Word_Counter
						     /*(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].Word == Word_Counter ||
							  Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].OverlappedWord == Word_Counter)*/)
                            {                                                      
                            Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].Word = Word_Counter;
                            Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].Letter = Letter_Counter + 1;
                            }                                                      
                            
                          /*if(Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].Word != -1 &&
                             Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].Word != Word_Counter)
                            {
                            Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].OverlappedWord = Word_Counter;
                            Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].OverlappedLetter = Letter_Counter + 1;
                            Words[Word_Counter].x = GetX(Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].id) -
                                                    GetW(Layers[0].id) * (Letter_Counter + 1);
                            Words[Word_Counter].y = GetY(Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].id);
                            }*/
						                            
                          Words[Word_Counter].Solved = true;                          
						  break;
                         }
                       } 					   
					if(Words[Word_Counter].Solved == true) break;                   
                    }
                 }
              if(Words[Word_Counter].Solved == true) 
                {
                 Words[Word_Counter].Direction = 0;                 
                 WordReward(Word_Counter);
                }                              
              }
            
            //Are the letters in the right order? (vertically)            
            if(Words[Word_Counter].Solved == false)
              {
              Words[Word_Counter].Solved = true;              
              for(var Letter_Counter = 0; Letter_Counter < Words[Word_Counter].Letters.length - 1 && Words[Word_Counter].Solved == true; Letter_Counter++)
                 {               
                 Words[Word_Counter].Solved = false;
                 for(var Layers1_Counter = 0; Layers1_Counter < Words[Word_Counter].Letters[Letter_Counter].length; Layers1_Counter++)
                    {                    
                    for(var Layers2_Counter = 0; Layers2_Counter < Words[Word_Counter].Letters[Letter_Counter + 1].length; Layers2_Counter++)
                       {
                       if(GetY(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].id) + 
                          GetH(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].id) - SmallTol <
                          GetY(Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].id) &&
                          GetY(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].id) + 
                          GetH(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].id) + BigTol >
                          GetY(Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].id) &&                          
                          GetX(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].id) - SmallTol <
                          GetX(Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].id) &&
                          GetX(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].id) + BigTol >
                          GetX(Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].id) &&
						  Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].Word == -1)
                         {
                          if(Letter_Counter == 0)
                            {
                            Words[Word_Counter].x = GetX(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].id);
                            Words[Word_Counter].y = GetY(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].id);
                            
							if((Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].Word == -1 ||
                                Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].Word == Word_Counter))
                              {                                                      
                              Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].Word = Word_Counter;
                              Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].Letter = Letter_Counter;
                              }

                            }
                            
						  /*if(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].Word != -1 &&
                             Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].Word != Word_Counter)
                            {
                            Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].OverlappedWord = Word_Counter;
                            Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].OverlappedLetter = Letter_Counter;
                            Words[Word_Counter].x = GetX(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].id);
                            Words[Word_Counter].y = GetY(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].id) -
                                                    GetH(Layers[0].id) * Letter_Counter;
                            }*/
							                                                   
                          if(Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].Word == -1 &&
						     Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].Word == Word_Counter
                             /*(Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].Word == Word_Counter ||
							  Words[Word_Counter].Letters[Letter_Counter][Layers1_Counter].OverlappedWord == Word_Counter)*/)
                            {                                                      
                            Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].Word = Word_Counter;
                            Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].Letter = Letter_Counter + 1;
                            }
                                                      
                            
                          /*if(Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].Word != -1 &&
                             Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].Word != Word_Counter)
                            {
                            Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].OverlappedWord = Word_Counter;
                            Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].OverlappedLetter = Letter_Counter + 1;
                            Words[Word_Counter].x = GetX(Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].id);
                            Words[Word_Counter].y = GetY(Words[Word_Counter].Letters[Letter_Counter + 1][Layers2_Counter].id) -
                                                    GetH(Layers[0].id) * (Letter_Counter + 1);                                                                              
                            }*/
                          
                          Words[Word_Counter].Solved = true;
                          break;
                         }
                       }
                    if(Words[Word_Counter].Solved == true) break;
                    }
                 }
              if(Words[Word_Counter].Solved == true) 
                {
                 Words[Word_Counter].Direction = 1;                 
                 WordReward(Word_Counter);
                }                              
              }            
              
            //Is the word really solved? If not, unlock the pieces that are in place.
            if(Words[Word_Counter].Solved == false)
              {
              for(var layer = 0; layer < Layers.length; layer++)
                 {
                  if(Layers[layer].Word == Word_Counter)
                    {
                     Layers[layer].Word = -1;
                     Layers[layer].Letter = -1;                     
                    }
                 }
              } 
            }                      
         
         //Was a piece of a solved word used to solve another?
         //If so, go fetch an available corresponding piece.
         /*for(var Layers1_Counter = 0; Layers1_Counter < Layers.length; Layers1_Counter++)
            {
            if(Layers[Layers1_Counter].OverlappedWord != -1)
              {
              for(var Layers2_Counter = 0; Layers2_Counter < Words[Layers[Layers1_Counter].OverlappedWord].Letters[Layers[Layers1_Counter].OverlappedLetter].length; Layers2_Counter++)
                 {
                 if(Words[Layers[Layers1_Counter].OverlappedWord].Letters[Layers[Layers1_Counter].OverlappedLetter][Layers2_Counter].Word == -1 &&
                    Words[Layers[Layers1_Counter].OverlappedWord].Solved == true)
                   {
                   PickUp(Layers2_Counter);
                   Words[Layers[Layers1_Counter].OverlappedWord].Letters[Layers[Layers1_Counter].OverlappedLetter][Layers2_Counter].Word = Layers[Layers1_Counter].OverlappedWord;
                   Words[Layers[Layers1_Counter].OverlappedWord].Letters[Layers[Layers1_Counter].OverlappedLetter][Layers2_Counter].Letter = Layers[Layers1_Counter].OverlappedLetter;                                      
                   
                   for(var Layers3_Counter = 0; Layers3_Counter < Layers.length; Layers3_Counter++)
                      {
                      if(Words[Layers[Layers1_Counter].OverlappedWord].Letters[Layers[Layers1_Counter].OverlappedLetter][Layers2_Counter].Word == Layers[Layers3_Counter].Word &&
                         Words[Layers[Layers1_Counter].OverlappedWord].Letters[Layers[Layers1_Counter].OverlappedLetter][Layers2_Counter].Letter == Layers[Layers3_Counter].Letter)
                        {
                        PickUp(Layers3_Counter);
                        }                         
                      }
                   break;                   
                   }                                  
                 }
              Layers[Layers1_Counter].OverlappedWord = -1;
              Layers[Layers1_Counter].OverlappedLetter = -1;
              }
            }*/
                                               
         for(var Layers_Counter = 0; Layers_Counter < Layers.length; Layers_Counter++)
            {
            if(Layers[Layers_Counter].Word != -1)
              {			  
               //Align the pieces of solved words. (horizontally)
               if(Words[Layers[Layers_Counter].Word].Direction == 0)
                 {                  
                  Slide(Words[Layers[Layers_Counter].Word].x + 
                       Layers[Layers_Counter].Letter * GetW(Layers[0].id),
                       Words[Layers[Layers_Counter].Word].y,
                       10,
                       'Layers[' + Layers_Counter + '].id');
                 }
               //Align the pieces of solved words. (vertically)
               else
                 {                  
                  Slide(Words[Layers[Layers_Counter].Word].x,
                       Words[Layers[Layers_Counter].Word].y + 
                       Layers[Layers_Counter].Letter * GetH(Layers[0].id),
                       10, 
                       'Layers[' + Layers_Counter + '].id');
                 }
              }
            }
            
         //Is the puzzle solved?
         var SolvedPuzzle = true;
         for(var Word_Counter = 0; Word_Counter < Words.length; Word_Counter++)     
            {
            if(Words[Word_Counter].Solved == false)
              SolvedPuzzle = false;
            }
            
         if(SolvedPuzzle == true)
            PuzzleReward();
		                   
         if(ClickedLayer == -1) return true; 
         else {ClickedLayer = -1; return false;}
}
