var m_clCaveTree;             // full tree
var m_iUniqueIDMaster = 0;    // used while initiatization to provide a unique ID to all caves.
var m_clSubCaveNodes;         // array of all sub-cave-nodes of the currently selected node
var m_clAllCaveNodes;         // array of all cave-nodes
var m_iSorting = 0;           // 0: Mission Sequence, 1: Alphabetically, 2: Score, 3: Length
var m_clCurrentRootNode;      // Currently selected node
var m_iaImages = new Array();
var m_iCurrentImageToLoad = 0;
 
  /**
   * Shows or hides an element.
   * Returns the affected element.
   **/
  function enableCavelet(strElementName, bEnable)
  {
    var clDoc;
    clDoc = document.getElementById(strElementName);

    if (bEnable == false)
    {
      clDoc.style.display = "none";
    }
    else
    {
      clDoc.style.display = "block";
    }

    return clDoc;
  }

  function isCaveletOpen(strElementName)
  {
    if (document.getElementById(strElementName).style.display == "none")
    {
      return false;
    }
    else
    {
      return true;
    }
  }

  function toggleCavelet(strElementName)
  {
    if (isCaveletOpen(strElementName) == false)
    {
      enableCavelet(strElementName, true);
    }
    else
    {
      enableCavelet(strElementName, false);
    }
  }

  /**
   * This method walks through the tree, searching for 
   * given unique ID, returning it - or null if not found.
   */
  function findNodeByID(clTreeNode, iUniqueID)
  {
    if (iUniqueID == clTreeNode.uniqueID)
    {
      return clTreeNode;
    }
        
    if (clTreeNode.subs != null)
    {
     for (iIndex in clTreeNode.subs)
     {
      clReturn = findNodeByID(clTreeNode.subs[iIndex], iUniqueID);
      if (clReturn != null)
      {
        return clReturn;
      }
     }
    } 
  }

  function initiateImageLoading()
  {
    iIndex = m_iaImages[m_iCurrentImageToLoad++];
    clMinistripElement = document.getElementById("MID"+m_clMissionIDs[iIndex].MID);
    if (clMinistripElement != null)
    {
      clImage = new Image(1,1);
      clImage.onload =  function() 
      {  
        m_strLoadPercentage = (m_iCurrentImageToLoad/(m_iaImages.length)*100).toFixed(2) + "%";
        updateStatistics();
        clMinistripElement.src = m_clMissionIDs[iIndex].IMG; 
        if (m_iCurrentImageToLoad < m_iaImages.length)
        {
          setTimeout('initiateImageLoading()',0);
        }
      };
      clImage.src=m_clMissionIDs[iIndex].IMG;
    }
  }

  function createMenuBarThreaded(clRootNode)
  {
    var strMenuBar = "";
    var clCurrentNode;
	
    // Writing currently selected RootNode to cookie to be able to restore last filterstate after user comes back from somewhere

				writeCookie("FilterNode",clRootNode.uniqueID);
			    
				m_clCurrentRootNode = clRootNode;

    // Step 001: Hiding CaveletDIV

    enableCavelet('Disclaimer',false);
    enableCavelet('Content',false);
    
    // Step 002: Walking down the tree to create
    //           the links to the current Node

    clCurrentNode = clRootNode;

    while (clCurrentNode = clCurrentNode.parentNode)
    {
      strMenuBar = getLink(clCurrentNode,true) + " "+ strMenuBar;
      //console.log("down to "+clCurrentNode.name);
    }

    // Step 003: The current one

    strMenuBar += " "+getLink(clRootNode,true);

    document.getElementById("Gurke").innerHTML = strMenuBar + "<span class='text_mini_yellow'> [ IN BEARBEITUNG ]</span>";

    new caveseekers.executor(this,1,'createMenuBar',clRootNode);
  }

  /**
   * Creates the MenuBar - somehow
   */
  function createMenuBar(clRootNode)
  {
    var strMenuBar = "";
    var clCurrentNode;
    m_clCurrentRootNode = clRootNode;
  
    // Step 001: Walking down the tree to create
    //           the links to the current Node
    
    clCurrentNode = clRootNode;
    
    while (clCurrentNode = clCurrentNode.parentNode)
    {
      strMenuBar = getLink(clCurrentNode,true) + " "+ strMenuBar;
      //console.log("down to "+clCurrentNode.name);
    }

    // Step 002: The current one

    strMenuBar += " "+getLink(clRootNode,true)+ " ";

    // Step 003: Walking up the tree to create
    //       the nodes below the current node

    clSubsY = clRootNode["subs"];

    for (iIndexX in clSubsY )
    {
      if (clSubsY[iIndexX].type != "CAVE")
      {
        strMenuBar += getLink(clSubsY[iIndexX],false)+" ";
      }
    }

    // STATUS: Now we need to search ALL caves below the rootnode
    //         once again recursively. creating an array of these cave nodes
    //         for later use
    
    m_clSubCaveNodes = new Array();
    
    gatherCaveNodes(clRootNode);
    
    // STATUS: m_clSubCaveNodes now contains all caves below the currently
    //         selected node.
  
    // STATUS: Here we can do some kind of additional sorting to
    //         our selected caves. first tryp: alphabetically  
    
    // Step 001: Sorting
    
    if (m_iSorting == 0)
    {
    
      // Step 001.2: Mission Date
    
      m_clSubCaveNodes.sort(missionSort);
    }
    else if (m_iSorting == 1)
    {
  
     // Step 001.1: Alphabetically
  
     m_clSubCaveNodes.sort(dateSort);
    }
    else if (m_iSorting == 2)
    {
  
     // Step 001.2: Score
  
     m_clSubCaveNodes.sort(scoreSort);
    }
    else if (m_iSorting == 3)
    {
  
     // Step 001.2: Length
  
     m_clSubCaveNodes.sort(lengthSort);
    }

    // STATUS: Es reicht leider nicht, alle Cavelets einzuschalten, die eingeschaltet werden müssen.
    //         Nein, es müssen alle anderen vorher auch ausgeschaltet werden. Wie geht den?
  
    var strCaveletCode = "";
    var clContentDoc = document.getElementById("Content");

    for (iIndex in m_clAllCaveNodes)
    {
      clCavelet = enableCavelet("CID"+m_clAllCaveNodes[iIndex].caveID,false);
    }
    for (iIndex in m_clSubCaveNodes)
    {
      clCavelet = enableCavelet("CID"+m_clSubCaveNodes[iIndex].caveID,true);
      clContentDoc.appendChild(clCavelet);
    }
  
    document.getElementById("Gurke").innerHTML = strMenuBar;
    m_strHitCount = "SELEKTIERTE HOHLRÄUME: <span class='text_mini_red'>"+m_clSubCaveNodes.length+"</span>";
    updateStatistics();
    document.getElementById("CaveList").innerHTML = getSorter();
    enableCavelet('Content',true);
    enableCavelet('Disclaimer',true);
  }
  
  function dateSort(clNodeA,clNodeB) 
  {
   	if (clNodeA.name > clNodeB.name)
    {
      return 1;
    }
    
    if (clNodeA.name < clNodeB.name)
    {
      return -1;
    }
    
    return 0;
  }
  
  function missionSort(clNodeA,clNodeB) 
  {
    if (parseInt(clNodeA.mission) < parseInt(clNodeB.mission))
    {
      return 1;
    }
    
    if (parseInt(clNodeA.mission) > parseInt(clNodeB.mission))
    {
      return -1;
    }
    
    return 0;
  }

  function scoreSort(clNodeA,clNodeB) 
  {
   
    if (parseInt(clNodeA.score) < parseInt(clNodeB.score))
    {
      return 1;
    }
	
    if (parseInt(clNodeA.score) > parseInt(clNodeB.score))
    {
      return -1;
    }
   
    return 0;
  }

  function lengthSort(clNodeA,clNodeB) 
  {
    if (parseInt(clNodeA.length) < parseInt(clNodeB.length))
    {
      return 1;
    }
	
    if (parseInt(clNodeA.length) > parseInt(clNodeB.length))
    {
      return -1;
    }
    
    return 0;
  }
  
var m_strHitCount;
var m_strLoadPercentage = "";

		function updateStatistics()
		{
		    document.getElementById("HitCounter").innerHTML = m_strHitCount+ " GELADENE VORSCHAUBILDER: <span class='text_mini_red'>"+m_strLoadPercentage+"</span>";
		}

  function initiateSortThreaded(iSort)
  {
    enableCavelet('Disclaimer',false);
    enableCavelet('Content',false);
    
    m_iSorting = iSort;

 			// Writing currently selected sortation to cookie to be able to restore last filterstate after user comes back from somewhere
		
	 		writeCookie("Sortation",iSort);

    document.getElementById("CaveList").innerHTML = "<span class='text_mini_yellow'>SORTIERUNG:</span> " +getSorter()+ "<span class='text_mini_yellow'> [ IN BEARBEITUNG ]</span>";

    new caveseekers.executor(this,1,'initiateSort',iSort);
  }

  function initiateSort(iSort)
  {
    m_iSorting = iSort;
    createMenuBar(m_clCurrentRootNode);
  }

  /**
  Creates the Sort-Bar.
  */

  function getSorter()
  {
    var strOutput="";
    var strName;
    var strClass;

    for (var i = 0; i < 4; i++)
    {
      switch(i)
      {
	      case 0:
	        strName = "MISSION";
			      strSortText = "Da das Datum geheim zu sein hat, wird nach Missionsnummer sortiert.";
	      break;
	      case 1:
	        strName = "ALPHABET";
			      strSortText = "Nach Alphabet sortieren. Wir hoffen, dass das alphabet auch nach der nächsten Rechschreibreform noch gültig ist.";
	      break;
	      case 2:
	        strName = "PUNKTZAHL";
			      strSortText = "Nach der - zugegebenermaßen - subjektiven Bewertung der Löcher sortieren.";
	      break;
	      case 3:
	        strName = "LÄNGE";
		       strSortText = "Nach der Länge der Löcher sortieren";
	      break;  
	    }
    
	    if (i == m_iSorting)
	    {
	      strClass = "link_mini_red";
	    }
	    else
	    {
	      strClass = "link_mini";
	    }
	    
	    strOutput += "<a href='#' class='"+strClass+"' title='"+strSortText+"' onclick='initiateSortThreaded("+i+");'>"+strName+"</a> ";  
	    }
    return strOutput;
  }
 
  function getLink(clNode, bHighlighted)
  {
   var strNodeName;
  // var bImageAvailable = false;
   
   if (clNode == null)
   {
     return;
   }
   
   if (clNode.name == "ROOT")
   {
    strNodeName = "ERDBALL";
//    bImageAvailable = true;
   }
   else
   {
    strNodeName = clNode.name;
   }
   
   if (bHighlighted == true)
   {
    strClass = "link_mini_red";
   }
   else
   {
    strClass = "link_mini";
   }

   strNodeName = strNodeName.toUpperCase();

//   if (clNode.type == "COUNTRY")
//   {
//   	bImageAvailable = true;
//   }
	 
//	 if (bImageAvailable == true)
//	 {
//     return "<img src='images/flags/"+strNodeName+".png' width='10' height='10'> <a href='#' class='"+strClass+"' onclick='createMenuBarThreaded(findNodeByID(m_clCaveTree,"+clNode.uniqueID+"));'>"+strNodeName+"</a>";
//	 }
//   else
// 	 {
     return "<a href='#' class='"+strClass+"' onclick='createMenuBarThreaded(findNodeByID(m_clCaveTree,"+clNode.uniqueID+"));'>"+strNodeName+"</a>";
//   }

  }

  function initializeTree(clTreeNode, clParentTreeNode)
  {
    m_clAllCaveNodes = new Array();
    initializeTreeRecurser(clTreeNode, clParentTreeNode);
  }

  /**
   * This method walks through the tree and applies some initialization to its nodes:
   *
   * 1. a unique ID
   * 2. a pointer to its parent
   *
   */
  function initializeTreeRecurser(clTreeNode, clParentTreeNode)
  {
  
    // Step 001: Applying new attributes
    
    clTreeNode.uniqueID = m_iUniqueIDMaster++;
    clTreeNode.parentNode = clParentTreeNode;
    if (clTreeNode.type == "CAVE")
    {
      m_clAllCaveNodes.push(clTreeNode);
    }
    
    // Step 002: Checking out subnodes
    
    if (clTreeNode.subs != null)
    {
     for (iIndex in clTreeNode.subs)
     {
      initializeTreeRecurser(clTreeNode.subs[iIndex], clTreeNode);
     }
    } 
  }

  function gatherCaveNodes(clRootNode)
  {

    // Step 001: Applying new attributes
    
    if (clRootNode.type == "CAVE")
    {
      m_clSubCaveNodes.push(clRootNode);
    }

    // Step 002: Checking out subnodes
    
    if (clRootNode.subs != null)
    {
     for (iIndex in clRootNode.subs)
     {
      gatherCaveNodes(clRootNode.subs[iIndex]);
     }
    } 
  }
  
  function writeCookie(strName, strValue)
  {
  	 var clCookie = strName+"="+unescape(strValue);
	   document.cookie = clCookie;
  }
  
  function readCookie(name) 
  {
    var i = document.cookie.indexOf(name + "=");
    var c = "";
    if (i > -1) 
    {
      var ende = document.cookie.indexOf("; ",i+name.length+1);
      if (ende == -1) 
      {
       ende = document.cookie.length;
      }
      c = document.cookie.substring(i+name.length+1, ende);
    }
    return unescape(c);
  }
