
/**************************************
ÈJonas Raoni Soares Silva
Èhttp://www.joninhas.ath.cx
**************************************/

String.prototype.capitalize = function(){ //v1.0
    return this.replace(/\w+/g, function(a){
        return a.charAt(0).toUpperCase() + a.substr(1);
    });
};


// Initialize variables to hold tag search terms
var searchTagIds = new Array();
var notSearchTagIds = new Array();
var recentSearchTagIds = new Array();
var currentSelection = new Array();
var searchStates = new Array();

function submitTheForm(theFormName) {
   var theForm = document.getElementById(theFormName);
   theFormula(theForm);
   return false;
}

function checkElement(theIncludes, theExcludes, theMineral) {
   var theElements = theMineral[7].split(/\s/);
   if(theIncludes.length < 1 && theExcludes.length < 1) {
      return true;
   }
   
   if(!runElementCheck(theIncludes,theExcludes, theElements)) {
      // check End Member Elements
      var theElements = theMineral[18].split(/\s/);
      if(runElementCheck(theIncludes,theExcludes, theElements)) {
         return true;
      }
      else {
         return false;
      }
   }
   else {
      return true;
   }
}

function runElementCheck(theIncludes, theExcludes, theElements) {

   var addStatus = false;
   if(theExcludes.in_array('all')) {
      // Exclude all elements other than Includes
      if(theIncludes.length < 1) {
         addStatus = false;
      }
      else {
         for(var i=0;i<theElements.length;i++) {
            if(theIncludes.in_array(theElements[i])) {
               addStatus = true;
            }
            else {
               addStatus = false;
               break;
            }
         }
         if(addStatus) {
            for(var i=0;i<theIncludes.length;i++) {
               if(theElements.in_array(theIncludes[i])) {
                  addStatus = true;
               }
               else {
                  addStatus = false;
                  break;
               }
            }
         }
      }
   } 
   else {
      // Process includes and excludes
      if(theIncludes.length < 1) {
         addStatus = true;
      }
      else {
         for(var i=0;i<theIncludes.length;i++) {
            if(theElements.in_array(theIncludes[i])) {
               addStatus = true;
            }
            else {
               addStatus = false;
               break;
            }
         }
      }
      if(addStatus) {
         if(theExcludes.length < 1) {
            addStatus = true;
         }
         else {
            for(var i=0;i<theExcludes.length;i++) {
               if(theElements.in_array(theExcludes[i])) {
                  addStatus = false;
                  break;
               }
            }
         }
      }
   }
   return addStatus;
}

function fillTagSearchP(theFormName) {
   var searchTagsDiv = document.getElementById(theFormName + '_search_tags_display');
   
   // Check if IMA Only is checked
   var ima_only = false;
   if($(theFormName).ima_only.checked) {
      ima_only = true; 
   }

   var theSearchText = new StringBuffer;
   theSearchText.append('<ul class="search_tags_display">');
   var theSearchTextKeys = new Array;
   var theSearchTextLI = new Array;
// alert(searchTagIds[theFormName]);
   for(var i=0;i<searchTagIds[theFormName].length;i++) {
      var localTagData = master_tag_data[searchTagIds[theFormName][i]].split(/\|\|/);
      var extraTagData = "";
      if(localTagData[6].match(/1\d{5}/)) {
         // We have a parent data requirement
         var parentTagData = master_tag_data[localTagData[6]].split(/\|\|/);
         extraTagData = parentTagData[1].replace(/\sRecord/,'').capitalize() + ": ";
      }
      theSearchTextKeys.push(extraTagData+localTagData[1].capitalize() + '-' + searchTagIds[theFormName][i]);
      theSearchTextLI.push('<li><a href="javascript: tagNodeSelect(\'0-'+searchTagIds[theFormName][i]+'\');" class="selected_tag"><img border="0" src="'+baseurl+'/images/icons/complete_tsk.gif" align="absmiddle" />'+extraTagData+localTagData[1].capitalize()+'</a></li>');
   }
   for(var i=0;i<notSearchTagIds[theFormName].length;i++) {
      var localTagData = master_tag_data[notSearchTagIds[theFormName][i]].split(/\|\|/);
      var extraTagData = "";
      if(localTagData[6].match(/1\d{5}/)) {
         // We have a parent data requirement
         var parentTagData = master_tag_data[localTagData[6]].split(/\|\|/);
         extraTagData = parentTagData[1].replace(/\sRecord/,'').capitalize() + ": ";
      }

      if(ima_only && localTagData[0] != '88'&& localTagData[0] != '64' && localTagData[0] != '4') {
         // 88 = questionable mineral species  64 = not an ima approved mineral   4 = not a mineral
         theSearchTextKeys.push(extraTagData+localTagData[1].capitalize() + '-' + notSearchTagIds[theFormName][i]);
         theSearchTextLI.push('<li><a href="javascript: tagNodeSelect(\'0-'+notSearchTagIds[theFormName][i]+'\');" class="not_selected_tag"><img border="0" src="'+baseurl+'/images/icons/delete_obj.gif" align="absmiddle" />'+extraTagData+localTagData[1].capitalize()+'</a></li>');
      }
      else if(!ima_only) {
         theSearchTextKeys.push(extraTagData+localTagData[1].capitalize());
         theSearchTextLI.push('<li><a href="javascript: tagNodeSelect(\'0-'+notSearchTagIds[theFormName][i]+'\');" class="not_selected_tag"><img border="0" src="'+baseurl+'/images/icons/delete_obj.gif" align="absmiddle" />'+extraTagData+localTagData[1].capitalize()+'</a></li>');
      }
   }
   for(var i=0;i<recentSearchTagIds[theFormName].length;i++) {
      if(recentSearchTagIds[theFormName][i]) {
         var localTagData = master_tag_data[recentSearchTagIds[theFormName][i]].split(/\|\|/);
         var extraTagData = "";
         if(localTagData[6].match(/1\d{5}/)) {
            // We have a parent data requirement
            var parentTagData = master_tag_data[localTagData[6]].split(/\|\|/);
            extraTagData = parentTagData[1].replace(/\sRecord/,'').capitalize() + ": ";
         }
         theSearchTextKeys.push(extraTagData+localTagData[1].capitalize() + '-' + recentSearchTagIds[theFormName][i]);
         theSearchTextLI.push('<li><a href="javascript: tagNodeSelect(\'0-'+recentSearchTagIds[theFormName][i]+'\');" class="blank_tag">'+extraTagData+localTagData[1].capitalize()+'</a></li>');
      }
   }

   // Build list
   var theSearchTextKeysTmp = theSearchTextKeys.slice();
   theSearchTextKeys.sort();
   for(i=0;i<theSearchTextKeys.length;i++) {
      var index = 0;
      for(j=0;j<theSearchTextKeysTmp.length;j++) {
         if(theSearchTextKeysTmp[j] == theSearchTextKeys[i]) {
            index = j;
            break;
         }
      }
      theSearchText.append(theSearchTextLI[index]);
   }

   theSearchText.append('</ul>');
   var text = theSearchText.toString();
   searchTagsDiv.innerHTML = text;
}

function clearSearchTag(theFormName, tagId) {
   // Check if tag exists in an array
   var tmpArray = new Array();
   if(notSearchTagIds[theFormName].in_array(tagId)) {
      for(i=0;i<notSearchTagIds[theFormName].length;i++) {
         if(notSearchTagIds[theFormName][i] != tagId) {
            tmpArray.push(notSearchTagIds[theFormName][i]);
         }
      }
      notSearchTagIds[theFormName] = tmpArray;
   }
            
   var tmpArray = new Array();
   if(searchTagIds[theFormName].in_array(tagId)) {
      for(i=0;i<searchTagIds[theFormName].length;i++) {
         if(searchTagIds[theFormName][i] != tagId) {
            tmpArray.push(searchTagIds[theFormName][i]);
         }
      }
      searchTagIds[theFormName] = tmpArray;
   }

   var tmpArray = new Array();
   if(recentSearchTagIds[theFormName].in_array(tagId)) {
      for(i=0;i<recentSearchTagIds[theFormName].length;i++) {
         if(recentSearchTagIds[theFormName][i] != tagId) {
            tmpArray.push(recentSearchTagIds[theFormName][i]);
         }
      }
      recentSearchTagIds[theFormName] = tmpArray;
   }

   /*  DIAGNOSTIC CODE 
   var out = '';
   /*  DIAGNOSTIC CODE 
   var out = '';
   for(i=0;i<notSearchTagIds[theFormName].length;i++) {
      out +=  "NOT = " +  notSearchTagIds[theFormName] + '\n'; 
   }
   for(i=0;i<searchTagIds[theFormName].length;i++) {
      out +=  "TRUE = " +  searchTagIds[theFormName] + '\n'; 
   }
   alert(out); */
}

function sortByTags(theFormName, tagId, tagSortType) {

   // Check if arrays are initialized
   if(!searchTagIds[theFormName]){
      searchTagIds[theFormName] = new Array;
   }
   if(!notSearchTagIds[theFormName]){
      notSearchTagIds[theFormName] = new Array;
   }
   if(!recentSearchTagIds[theFormName]){
      recentSearchTagIds[theFormName] = new Array;
   }

   // Check if IMA Only is checked
   var ima_only = false;
   if($(theFormName).ima_only.checked) {
      ima_only = true; 
   }
      // 88 = questionable mineral species  64 = not an ima approved mineral   4 = not a mineral

   if(ima_only) {
      // 64 = not an ima approved mineral
      notSearchTagIds[theFormName].push('64');
      // 88 = questionable mineral species  64 = not an ima approved mineral   4 = not a mineral
      notSearchTagIds[theFormName].push('88');
      // 4 = not a mineral
      // notSearchTagIds[theFormName].push('4');
   }
   
   // If Tag Name is TEXT - build array of ids for TEXT

   // Otherwise check if parent Text is selected

   // clear existing tag reference

   if(tagId != '') {
      clearSearchTag(theFormName, tagId);
      if(tagSortType  == "true" && !notSearchTagIds[theFormName].in_array(tagId)) {
         notSearchTagIds[theFormName].push(tagId);
      }
      else if(tagSortType  == "false" && !searchTagIds[theFormName].in_array(tagId)) {
         searchTagIds[theFormName].push(tagId);
      }
      else {
         recentSearchTagIds[theFormName].push(tagId);
      }
         
   }

   fillTagSearchP(theFormName);
   

   if(!theForm) {
      var theForm = document.getElementById(theFormName);
   }
   incl = theForm.txt_chemistry_incl.value;
   excl = theForm.txt_chemistry_excl.value;
   processElements(theFormName, incl, excl);

}

function getParent(tagId) {
   if(master_tag_data[tagId]) {
      var parentTagData = master_tag_data[tagId].split(/\|\|/);
      var parentId = parentTagData[6];
      if(parentId > 0) {
         return parentId;
      }
   }
   return false;
}

function checkTag(theFormName, mineral) {
   var theTags = mineral[8].split(/\s/);

   var tagFound = true;
   for(var j=0; j<searchTagIds[theFormName].length; j++) {
      //  Tag searches are implicit AND  Check if parent tag is in array
      if(!theTags.in_array(searchTagIds[theFormName][j])) { 
         return false;
      }
   }
   for(var j=0; j<notSearchTagIds[theFormName].length; j++) {
      //  Tag searches are implicit AND 
      if(theTags.in_array(notSearchTagIds[theFormName][j])) { 
         return false;
      }
   }
   return true;
}

var txtSearchArray = new Array;
function processElements(theFormName, incl, excl) {
   txtSearchArray = new Array;
   // Set Up Search Array

   if(!searchTagIds[theFormName]){
      searchTagIds[theFormName] = new Array;
   }
   if(!notSearchTagIds[theFormName]){
      notSearchTagIds[theFormName] = new Array;
   }
   var theNumberDiv = document.getElementById('result_' + theFormName);

   var theDiv = document.getElementById(theFormName + '_mineral_select_div')

   var theIncludes = new Array();
   var theExcludes = new Array();
   if(incl != '') {
      theIncludes = incl.split(/,/);
   }
   if(excl != '') {
      theExcludes = excl.split(/,/);
   }

   var theText = new StringBuffer;
   theText.append('<select id="mineral_select" name="mineral_select" size="16" style="width: 24em"  onchange="theFormula(this.form);">');
   var theCount = 0;
   for(var i in mineral_keys) {
      if(mineral_keys[i] != "" && i.match(/^[0-9]+$/)) {
         if(mineral_data_array[i].split) {
            var min_data = mineral_data_array[i].split(/\|\|/);
            // Check if tags are present
            var addMineral = true;
            if(searchTagIds[theFormName].length > 0 || notSearchTagIds[theFormName].length > 0) {
               if(! checkTag(theFormName, min_data)) {
                  addMineral = false;
               }
            }
            if(addMineral) {
               if(! checkElement(theIncludes,theExcludes,min_data)) { 
                  addMineral = false;
               }
            }
      
            if(addMineral) {
               if(theCount == 0) {
                  theText.append('<option value="'+ i + '" selected="selected">' + mineral_keys[i] + '</option>');
               }
               else {
                  theText.append('<option value="'+ i + '">' + mineral_keys[i] + '</option>');
               }
               // Set up txtSearch 
               var startLetter = mineral_keys[i].substr(0,1).toLowerCase();
               var cleanName = mineral_keys[i].replace(/[\'\"\-\(\)\_\s\]\[\{\}\|\+\=\*]/g,'').toLowerCase() + '__' + theCount;
               if(!txtSearchArray[startLetter]) {
                  txtSearchArray[startLetter] = new Array;
               }
               txtSearchArray[startLetter].push(cleanName);
               theCount++;
            }
         }
         else {
            alert('Split failed. ['+i+']');
         }
      }
   }   
   

   // theText += '</select>';
   theText.append('</select>');
   // theBox.value = theText;
   theDiv.innerHTML = theText.toString();
   theNumberDiv.innerHTML = theCount;
   theForm = document.getElementById(theFormName);
   if(theForm.mineral_select.options.length > 0 && currentSelection[theForm.id] != theForm.mineral_select[theForm.mineral_select.selectedIndex].value) {
      // Check if old selection is in array
      if(newIndex = hiLoSearchSelectBox(theForm, currentSelection[theForm.id], theCount)) {
         theForm.mineral_select[newIndex].selected = true;
      }
      else {
         // If not, select First Item
         theForm.mineral_select[0].selected = true;
      }
      // Display Formula + Tags for current selection
      theFormula(theForm);
   }
   else {
      theFormula(theForm);
   }
}

function StringBuffer() { 
   this.buffer = new Array(); 
 } 

 StringBuffer.prototype.append = function append(string) { 
   this.buffer.push(string); 
   return this; 
 }; 

 StringBuffer.prototype.toString = function toString() { 
   return this.buffer.join(""); 
 }; 


var tagTreeForm = new Array;
var tagTree = new Array;
function fillSelectBox(theFormName) {
   
   // Set form/tree link
   tagTreeForm.push(theFormName);

   sortByTags(theFormName,'');
   theFormula(theForm);
   // fillGlobalTagSelectBox(theForm);
}

var tmpFormName = "";
function clearAll(theFormName) {
   showOverlay();
   tmpFormName = theFormName
   setTimeout("performClear()","50");
}

function performClear() {
   var theFormName = tmpFormName;
   // Clear Chemistry
   clearElements('periodic_table_1', 'form_periodic_table_1');

   // Clear Tags
   searchTagIds[theFormName] = new Array();
   notSearchTagIds[theFormName] = new Array();
   recentSearchTagIds[theFormName] = new Array();
   searchStates = new Array();

   // fillGlobalTagSelectBox(document.getElementById(theFormName));
   sortByTags(theFormName,'');
   removeOverlay();
}

function clearTags(theFormName) {
   searchTagIds[theFormName] = new Array();
   notSearchTagIds[theFormName] = new Array();
   recentSearchTagIds[theFormName] = new Array();
   searchStates = new Array();

   // fillGlobalTagSelectBox(document.getElementById(theFormName));
   sortByTags(theFormName,'');
}

function clearTagsPT(theFormName) {
   searchTagIds[theFormName] = new Array();
   fillTagSearchP(theFormName);
   theForm = document.getElementById(theFormName);
   incl = theForm.txt_chemistry_incl.value;
   excl = theForm.txt_chemistry_excl.value;
   processElements(theFormName, incl, excl);
}

current_pos=0;

function tagNodeSelect(tagNodeId) {
   // Retrieve Tree ID for Form

   var treeIdData = tagNodeId.split(/\-/);
   var treeId = treeIdData[0];
   var itemId = treeIdData[1];

   /*   Hardcode 2 trees per page 
   var treeId2 = '-1';
   var theFormName = tagTreeForm[treeId];
   if(theFormName.match(/_global_tag_select/)) { 
      theFormName = theFormName.replace(/_global_tag_select/,'');
   }
   else {
      // Set system to synchronize colors
      theFormName2 = theFormName + "_global_tag_select";
      if(!tagTreeForm.in_array(theFormName2)) {
         tagTreeForm.push(theFormName2);
         fillGlobalTagSelectBox(document.getElementById(theFormName2));
      }
      else {
         // Retrieve Tree ID for Form
         var treeId2 = 0;
         for(var i=0;i<tagTreeForm.length;i++) {
            if(tagTreeForm[i] == theFormName2) {
               treeId2 = i;
            }
         }
      }
   } */ 
      /*
      if(tagTree[i].getUserData(i + '-' + itemId, 'tagId').match(/[a-zA-Z]/)) {
         return false;
      } 
      */
   // Initialize Tree

   // Check tag format
   
   var theFormName = '';
   for(i=0;i<tagTree.length;i++) {
      var theFormName = tagTreeForm[i];
      if(theFormName.match(/_global_tag_select/)) { 
         theFormName = theFormName.replace(/_global_tag_select/,'');
      }
   }

   var searchState = '0';
   if(searchStates[itemId]) {
      searchState = searchStates[itemId];
   }
   /* for(i=0;i<tagTree.length;i++) {
      searchState = tagTree[treeId].getUserData(i + '-' + itemId,'searchState');
   } */
   switch (searchState) {
      case '0':
         for(i=0;i<tagTree.length;i++) {
            tagTree[i].setItemStyle(i + '-' + itemId,'selected_tag');
         }
         searchStates[itemId] = '1';
         sortByTags(theFormName, itemId,'false');
      break;

      case '1':
         for(i=0;i<tagTree.length;i++) {
            tagTree[i].setItemStyle(i + '-' + itemId,'not_selected_tag');
         }
         searchStates[itemId] = '-1';
         sortByTags(theFormName, itemId,'true');
      break;

      case '-1':
         for(i=0;i<tagTree.length;i++) {
            tagTree[i].setItemStyle(i + '-' + itemId,'blank_tag');
         }
         searchStates[itemId] = '0';
         sortByTags(theFormName, itemId,'recent');
      break;
   }
}

function setTagUserData(theFormName, currentNode, tagId, treeId) {
   if(notSearchTagIds[theFormName] && notSearchTagIds[theFormName].in_array(tagId)) {
      // tagTree[treeId].setItemStyle(currentNode,'not_selected_tag');
      tagTree[treeId].setUserData(currentNode,'searchState', '-1');
   }
   else if(searchTagIds[theFormName] && searchTagIds[theFormName].in_array(tagId)) {
      // tagTree[treeId].setItemStyle(currentNode,'selected_tag');
      tagTree[treeId].setUserData(currentNode,'searchState', '1');
   }
   else {
      // tagTree[treeId].setItemStyle(currentNode,'blank_tag');
      tagTree[treeId].setUserData(currentNode,'searchState', '0');
   }
}

function loadTags() {
   
   theFormName = "form_periodic_table_1_global_tag_select";
   if($(theFormName).innerHTML.match(/please wait/)) {
      fillGlobalTagSelectBox($("form_periodic_table_1"));
   }
   else {
   }
}

function fillGlobalTagSelectBox(theForm) {
   
   theFormName = theForm.id + "_global_tag_select";
   if(!tagTreeForm.in_array(theFormName)) {
      tagTreeForm.push(theFormName);
   }

   // Check if IMA Only is checked
   var ima_only = false;
   if(theForm.ima_only.checked) {
      ima_only = true; 
   }

   // Sort the tags 
   var mineral_tag_ids = new Array();
   for(var i=0; i<master_tag_data.length; i++) {
      if(master_tag_data[i]) {
         var tmp_mineral_data = master_tag_data[i].split(/\|\|/);
         // 88 = questionable mineral species  64 = not an ima approved mineral   4 = not a mineral
         if(ima_only && tmp_mineral_data[0] != '64' && tmp_mineral_data[0] != '88' && tmp_mineral_data[0] !='4') {
            mineral_tag_ids.push(tmp_mineral_data[0]);
         }
         else if(!ima_only) {
            mineral_tag_ids.push(tmp_mineral_data[0]);
         }
      }
   }

   generateTheTags(theForm, 'SEARCH TAGS', mineral_tag_ids, theFormName, true, false, returnFalse, tagNodeSelect, returnFalse);

}

function returnFalse() {
   return false;
}

function processTreeLevel(levelId, tagNameArray, tagParentArray, parentIdArray, treeId, theForm) {

   // alert(dump(tagNameArray));
   // alert(dump(tagParentArray));
   // Determine which tags are at current level
   var tagsNamesLevel = new Array();
   var tagsNamesLevelByName = new Array();
   var tagsDisplayNames = new Array();
   for(var x in tagParentArray) {
      if(isInteger(tagParentArray[x]) && tagParentArray[x] == levelId) {
         tagsNamesLevel.push(tagNameArray[x].toLowerCase());
         tagsNamesLevelByName[tagNameArray[x].toLowerCase()] = x;
         tagsDisplayNames[tagNameArray[x].toLowerCase()] = tagNameArray[x];
      }
   }
   // Sort tags for this level
   tagsNamesLevel.sort();

   if(levelId > 0) {
      var parentId = treeId + '-' + levelId;
   }
   else {
      var parentId = treeId + '-' + 'TAGS';
   }
   for(var i=0;i<tagsNamesLevel.length;i++) {
      // Create node
      var tagId = tagsNamesLevelByName[tagsNamesLevel[i]];
      var nodeId = treeId + '-' + tagId;
      // Determine Display Name
      var tagDisplayName = tagsDisplayNames[tagsNamesLevel[i]];
      if(!tagDisplayName.match(/[A-Z]/)) {
         // No capitalization present
         tagDisplayName = tagDisplayName.capitalize();
      }
         
      if(tagTree[treeId].insertNewChild(parentId,nodeId,'<a id="tag_href_'+nodeId+'" href="javascript:tagNodeSelect(\''+ nodeId + '\');">' + tagDisplayName + '</a>',0,0,0,0,"")) {
         // tagTree[treeId].setUserData(nodeId,'tagId', tagId);
         tagTree[treeId].setUserData(nodeId,'tagId', tagId);
         tagTree[treeId].setUserData(nodeId,'theFormName', theForm.id);
         setTagUserData(theForm.id, nodeId, tagId, treeId);
      }

      // Determine if this name is a level
      for(var y in parentIdArray) {
         if(parentIdArray[y] == tagsNamesLevelByName[tagsNamesLevel[i]]) {
            processTreeLevel(parentIdArray[y], tagNameArray, tagParentArray, parentIdArray, treeId, theForm);
         }
      }
   }
}

function generateTheTags(theForm, treeName, mineral_tags, treeDiv, collapse, edit_mode, dragDropHandler, singleClickHandler, doubleClickHandler)
{

   // Build array of parents + child id
   var tagNameArray = new Array();
   // Build array of child + names
   var tagParentArray = new Array();
   // Build array of parent ids
   var parentIdArray = new Array();
   for(var i=0; i<mineral_tags.length; i++) {
      if(master_tag_data[mineral_tags[i]]) {
         var tmp_mineral_data = master_tag_data[mineral_tags[i]].split(/\|\|/);
         tagParentArray[tmp_mineral_data[0]] = tmp_mineral_data[6];
         // Check if tag name is Display or Regular
         if(tmp_mineral_data[5] != "" && tmp_mineral_data[5] != " ") {
            tagNameArray[tmp_mineral_data[0]] = tmp_mineral_data[5];
         }
         else {
            tagNameArray[tmp_mineral_data[0]] = tmp_mineral_data[1];
         }
         parentIdArray.push(tmp_mineral_data[6]);
      }
   }
   // Make array unique
   parentIdArray = unique(parentIdArray);
   // Add parent data 
   for(var x in parentIdArray) {
      if(isInteger(parentIdArray[x]) && parentIdArray[x] != "0" && !mineral_tags.in_array(parentIdArray[x])) {
         if(master_tag_data[parentIdArray[x]]) {
            var tmp_mineral_data = master_tag_data[parentIdArray[x]].split(/\|\|/);
            tagParentArray[tmp_mineral_data[0]] = tmp_mineral_data[6];
            tagNameArray[tmp_mineral_data[0]] = tmp_mineral_data[1];
            parentIdArray.push(tmp_mineral_data[6]);
         }
         else {
            alert("An error occurred processing the tags.");
            exit();
         }
      }
   }

   // Initialize tree

   // Retrieve Tree ID for Form
   var treeId = 0;
   for(var i=0;i<tagTreeForm.length;i++) {
      if(tagTreeForm[i] == treeDiv) {
         treeId = i;
      }
   }

   // Clear the tag div
   // if(document.getElementById(tagTreeForm[treeId])) { alert('valid'); }
   document.getElementById(treeDiv).innerHTML = '';
   tagTree[treeId] = new dhtmlXTreeObject(document.getElementById(treeDiv),"","",treeId);
   tagTree[treeId].setImagePath("../libs/dhtmlxTree/imgs/");
   tagTree[treeId].enableCheckBoxes(false);
   // tagTree[treeId].enableDragAndDrop(true);
   // tagTree[treeId].setDragHandler(dragDropHandler);
   tagTree[treeId].enableTreeImages(false);
   // tagTree[treeId].setOnClickHandler(singleClickHandler);
   // tagTree[treeId].setOnDblClickHandler(doubleClickHandler);

   // Create Root Level Tag
   if(tagTree[treeId].insertNewChild(treeId,treeId + '-' + "TAGS",treeName,0,0,0,0,'')) {
      tagTree[treeId].setUserData(treeId + '-' + 'TAGS','tagId','0');
   }

   // tagTree[treeId].closeAllItems(0);
   // Process tree levels (start 0)
   processTreeLevel('0', tagNameArray, tagParentArray, parentIdArray, treeId, theForm);
   if(edit_mode) {
      if(tagTree[treeId].insertNewChild(treeId,"NEW",'Add new tag',0,0,0,0,'')) {
         tagTree[treeId].setUserData('NEW','tagId','0');
      }
   }
   if(collapse) {
      // Close all tree nodes
      tagTree[treeId].closeAllItems();
      // Except the top level one
      tagTree[treeId].openItem(treeId + '-' + "TAGS");
   }
}

function dumpTagTree() {
  document.getElementById('debug').innerHTML =    dump(tagTree);
}

function theComments(theForm)
{

   if(!document.getElementById(theForm.name + '_comments')) {
      return false;
   }

   theCommentsDiv = document.getElementById(theForm.name + '_comments');
   theCommentsDiv.innerHTML = '';

   // Mineral Data should be selected index
   var mineral_data = mineral_data_array[theForm.mineral_select.options[theForm.mineral_select.selectedIndex].value].split(/\|\|/);

   // Populate Chemistry Fields
   var theText = new StringBuffer();
   theText.append('<table align="center">');
   theText.append('<tr><td valign="top"><b>Status Notes:</b></td></tr>');
   theText.append('<tr><td valign="top" class="ml_chemistry">');
   theText.append(mineral_data[19]);
   theText.append('</td</tr>');
   theText.append('<tr><td valign="top" class="ml_chemistry">');
   var commentTextArray = mineral_data[17].split(/\:\:\:/);
   for(var i=0; i< commentTextArray.length; i++) {
      var comment_text = Base64.decode(commentTextArray[i]);
      // comment_text = comment_text.replace(/\+/g,' ');
      comment_text = comment_text.replace(/\r\n/g,'<br />'); // Deal with possible windows return char
      comment_text = comment_text.replace(/\n\r/g,'<br />'); // Deal with possible windows return char
      comment_text = comment_text.replace(/[\n|\r]/g,'<br />'); // Substutite for regular return chars
      theText.append(comment_text);
      theText.append('<br /><br />');
   }
   theText.append('</td></tr>');
   theText.append('</table>');

   // Write the Formula contents to page
   theCommentsDiv.innerHTML = theText.toString();
   
}


function theFormula(theForm)
{

   theFormulaDiv = document.getElementById(theForm.name + '_ideal_formula');
   theFormulaDiv.innerHTML = '';
   theNameDiv = document.getElementById(theForm.name + '_ideal_name');
   theNameDiv.innerHTML = '';

   // Set the current selection for FORM so the proper selection can be maintained
   if(theForm.mineral_select.options.length == 0) {
      document.getElementById(theForm.name + "_tags").innerHTML = "";
      document.getElementById(theForm.name + "_comments").innerHTML = "";
      theForm.google.disabled = true;
      theForm.mindat.disabled = true;
      theForm.webmin.disabled = true;
      theForm.amcsd.disabled = true;
      theForm.hom.disabled = true;
      theForm.ref.disabled = true;
      theForm.rruff.disabled = true;
      if(theForm.admin) {
         theForm.admin.disabled = true;
      }
      // Clear Selected Mineral Area
      return false;
   }

   currentSelection[theForm.id] = theForm.mineral_select[theForm.mineral_select.selectedIndex].value;
   // alert(currentSelection[theForm.id]);



   // Mineral Data should be selected index
   mineral_data = mineral_data_array[theForm.mineral_select.options[theForm.mineral_select.selectedIndex].value].split(/\|\|/);
   // alert(mineral_data);

   // Disable buttons According to Selection
   theForm.google.disabled = false;
   theForm.mindat.disabled = false;
   theForm.webmin.disabled = false;
   if(theForm.admin) {
      theForm.admin.disabled = false;
   }
   if(!mineral_data[4].match(/[a-zA-Z]/)) {
      // Disable HOM
      theForm.hom.disabled = true;
   }
   else {
      theForm.hom.disabled = false;
   } 

   if(mineral_data[6] < 1) {
      // Disable AMCSD
      theForm.amcsd.disabled = true;
   }
   else {
      theForm.amcsd.disabled = false;
   }
   
   // Check if exists in RRUFF DB
   if(!mineral_data[10].match(/[0-9]/)) {
      // Disable RRUFF
      theForm.rruff.disabled = true;
   }
   else {
      theForm.rruff.disabled = false;
   }

   // Check if exists in Reference Section
   if(!mineral_data[9].match(/[0-9]/)) {
      // Disable REF
      theForm.ref.disabled = true;
   }
   else {
      theForm.ref.disabled = false;
   }




   // Populate Chemistry Fields
   var text = '<table align="center">';
   if(theForm.display_ideal.checked) {
      text += '<tr><td>RRUFF:</td><td class="ml_chemistry">' + mineral_data[2]  + '</td></tr>';
   }
   if(theForm.display_ima.checked) {
      text += '<tr><td>IMA:</td><td class="ml_chemistry">' + mineral_data[3] + '</td></tr>';
   }
   if(theForm.display_hom.checked) {
      text += '<tr><td>HOM:</td><td class="ml_chemistry">' + mineral_data[4]  + '</td></tr>';
   }
   if(theForm.display_fleischer.checked) {
      text += '<tr><td>Fleischer:</td><td class="ml_chemistry">' + mineral_data[5]  + '</td></tr>';
   }
   text += '</table>';

   // Write the Formula contents to page
   theFormulaDiv.innerHTML = text;

   // Write the Mineral Name to the page
   theNameDiv.innerHTML = '<center>'+mineral_data[1]+'</center>';
   // Disable Buttons according to selection criteria


   // Populate the tag array
   var theFormName = theForm.id + "_tags";
   var mineral_tags = hiLoSearch(theForm, true);
   var tagTreeName = "Tags (" + mineral_data[1] + ")";
   // function theTags(theForm, treeName, mineral_tags, treeDiv, collapse, edit_mode, dragDropHandler, singleClickHandler, doubleClickHandler)
   generateTheTags(theForm, tagTreeName, mineral_tags, theFormName, false, false, returnFalse, tagNodeSelect, returnFalse);
   
   // Populate the comments area
   theComments(theForm);
}

function display() /* For AMCSD */
{
   var min_name=theForm.a.options[theForm.a.selectedIndex].value;
   var min_disp_name='';
   j=0;
   for(i=0;i<min_name.length;i++)
   {
      min_disp_name += min_name.charAt(i);   
   }

   document.theForm1.Mineral.value=min_disp_name;
   return true;
}

function displaywebmin(theForm)
{
   min_name = theForm.mineral_select.options[theForm.mineral_select.selectedIndex].innerHTML;
   var flag=0;
   for(i=0;i<min_name.length;i++) {
      if(min_name.charCodeAt(i)>123) {
         flag=1;
         break;
      }
   }
   /* flag indicates whether the outer html text contains special characters or not if it contains special characters then orginal value is taken else outer html is taken*/
   if(flag==0)
   {
      /* alert(min_name);*/
      window.open("http://www.webmineral.com/data/"+min_name+".shtml");
   }
   else
   {
      /*alert(theForm.a.options[theForm.a.selectedIndex].value); */
      window.open("http://www.webmineral.com/data/"+theForm.a.options[theForm.a.selectedIndex].value+".shtml");

   }

}

function displaymindat(theForm)
{
  window.open("http://www.mindat.org/search.php?name="+theForm.mineral_select.options[theForm.mineral_select.selectedIndex].innerHTML);
}

function displayHOM(theForm)
{
   var mineralName = theForm.mineral_select.options[theForm.mineral_select.selectedIndex].innerHTML.toLowerCase()+'.pdf';
   window.open("http://rruff.geo.arizona.edu/doclib/hom/"+ mineralName.replace(/[\s|\-|\(|\)]/g,''));
}

function google_open(theForm)
{
   var min_name=theForm.mineral_select.options[theForm.mineral_select.selectedIndex].innerHTML;
   var min_disp_name='';
   j=0;
   for(i=0;i<min_name.length;i++)
   {
      if(min_name.charAt(i) != ' ')
      {
         min_disp_name += min_name.charAt(i);
      }
      else
      {  
         min_disp_name += '%20';
      }
   }

   window.open("http://www.google.com/search?ie=UTF-8&oe=UTF-8&q="+min_disp_name+"&btnG=Google+Search+PDFs&domains=rruff.geo.arizona.edu%2Fdoclib%2F&sitesearch=rruff.geo.arizona.edu%2Fdoclib%2F");
}

function displayAmcsd(theForm)
{
   var min_name=theForm.mineral_select.options[theForm.mineral_select.selectedIndex].innerHTML;
   var min_disp_name='';
   j=0;
   for(i=0;i<min_name.length;i++)
   {
      min_disp_name += min_name.charAt(i);
      
   }
   window.open("http://rruff.geo.arizona.edu/AMS/result.php?mineral="+encodeURIComponent(min_disp_name.toLowerCase()));
   
}

function displayrruff(theForm)
{
   var mineral_id = theForm.mineral_select.options[theForm.mineral_select.selectedIndex].value;
   for(var i in mineral_keys) {
      if(mineral_keys[i] != "" && i.match(/^[0-9]+$/)) {
         if(mineral_data_array[i].split) {
            var min_data = mineral_data_array[i].split(/\|\|/);
            // Check if tags are present
            window.open(baseurl + "/constructor.php?r=sample_search&txt_mineral="+mineral_data[20]);
            break;
         }
      }
   }
}

function exportToRruff(theForm)
{
   
   var inputs = $('export_to_rruff_form').getInputs();

   var inputText = new StringBuffer;
   for(var i=0; i<theForm.mineral_select.options.length; i++) {
      var mineral_id = theForm.mineral_select.options[i].value;
      
      inputText.append(mineral_id);
      inputText.append(',');
   }

   // alert(inputText);exit();
   $('export_to_rruff_form').mineral_ids.value = inputText.toString();
   $('export_to_rruff_form').r.value = 'sample_search';
   if($(theForm).chemistry_mode) {
      if($(theForm).chemistry_mode.checked) {
         $('export_to_rruff_form').chemistry_mode.value = 'true';
         $('export_to_rruff_form').chemistry_mode.checked = 'checked';
         $('export_to_rruff_form').tracking_mode.value = 'false';
         $('export_to_rruff_form').tracking_mode.checked = '';
      }
      if($(theForm).tracking_mode.checked) {
         $('export_to_rruff_form').tracking_mode.value = 'true';
         $('export_to_rruff_form').tracking_mode.checked = 'checked';
         $('export_to_rruff_form').chemistry_mode.value = 'false';
         $('export_to_rruff_form').chemistry_mode.checked = '';
      }
      if(!$(theForm).chemistry_mode.checked && !$(theForm).tracking_mode.checked) {
         $('export_to_rruff_form').chemistry_mode.value = 'false';
         $('export_to_rruff_form').chemistry_mode.checked = '';
         $('export_to_rruff_form').tracking_mode.value = 'false';
         $('export_to_rruff_form').tracking_mode.checked = '';
      }
   }
   var windowName = 'win_'  + Math.floor(Math.random()*1000);
   window.open('',windowName);
   $('export_to_rruff_form').target = windowName;
   $('export_to_rruff_form').method = 'POST';
   $('export_to_rruff_form').action = baseurl + '/constructor.php';
   // Submit form to new window
   $('export_to_rruff_form').submit();
}

function displayMinAdmin(theForm)
{
   /*
   var min_name=theForm.mineral_select.options[theForm.mineral_select.selectedIndex].value;

   var stop = 0;
   for(var i=0;i<mineral_keys.length;i++) {
      if(mineral_keys[i] == min_name) {
         stop = 1;
         break;
      }
      if(stop) {
         break;
      }
   }

   var min_data = mineral_data_array[i].split(/\|/);
   */

   // Mineral Data should be selected index
   mineral_id = theForm.mineral_select.options[theForm.mineral_select.selectedIndex].value;

   window.open(baseurl + "/index.php/r=mineral_addupdate/mineral_id=" + mineral_id);
   
}

function displayrruffref(theForm)
{
   var min_name=theForm.mineral_select.options[theForm.mineral_select.selectedIndex].innerHTML;
   var min_disp_name='';
   j=0;
   for(i=0;i<min_name.length;i++)
   {
      min_disp_name += min_name.charAt(i);
      
   }
   window.open(baseurl + "/rruff_1.0/reference_search.php?txt_mineral="+min_disp_name+"&rruff_action=sbmt_reference_search");
   
}

var mainDiv;
var exportWindow;
function loadChildWindow() {
   if(mainDiv = exportWindow.document.getElementById('main')) {
      mainDiv.innerHTML = '<p style="text-align: right"><a href="javascript: window.close()">[ Click to Close ]</a></p>';
      mainDiv.innerHTML += '<center><b>Export Data<b></center><p style="text-align: left; font-size: 1em;">You can export your mineral list in the formats listed below. When finished, click the link in the top right-hand corner to close this popup window. </p><p>&nbsp;</p><div id="form_list">Please Wait</div>';
      createExportForm();
   }
   else {
      setTimeout("loadChildWindow();",'250');
   }
}

var exportForm;
function exportData(theForm)
{

   exportForm = theForm
   // theForm.export.value = 'PLEASE WAIT';

   // Open window
   if(exportWindow = window.open(baseurl + '/mineral_list/blank.html','exportWindow','status=0,toolbar=0,scrollbars=1,height=400,width=400')) {
   // if(exportWindow = window.open('http://rruff.info/mineral_list/blank.html','exportWindow','')) {
      exportWindow.focus();
      setTimeout("loadChildWindow();",'50');
   }
}

function createExportForm() {
   var theForm = exportForm;
   // Create form with data and submit
   formDiv = exportWindow.document.getElementById('form_list');


   var theFormText = new StringBuffer;
   theFormText.append('<form name="exportForm" id="exportForm" action="' + baseurl + '/index.php" method="post">');
   theFormText.append('<input type="hidden" name="r" value="search_download">');
   theFormText.append('<input type="hidden" name="pipe_delimit_export" value="search_download">');
   var selectLength = theForm.mineral_select.options.length;

   for (i=0;i<selectLength;i++) {
      var min_data = mineral_data_array[theForm.mineral_select.options[i].value].split(/\|\|/);
      theFormText.append('<input type="hidden" name="export_data[' + min_data[0] + ']" value="'+ min_data[0]);
      // Populate Chemistry Fields
      if(theForm.display_ideal.checked) {
         theFormText.append('|||' + min_data[12]);
      }
      else {
         theFormText.append('|||');
      }
      if(theForm.display_ima.checked) {
         theFormText.append('|||' + min_data[13]);
      }
      else {
         theFormText.append('|||');
      }
      if(theForm.display_hom.checked) {
         theFormText.append('|||' + min_data[14]);
      }
      else {
         theFormText.append('|||');
      }
      if(theForm.display_fleischer.checked) {
         theFormText.append('|||' + min_data[15]);
      }
      else {
         theFormText.append('|||');
      }
      theFormText.append('">');
   }


   theFormText.append('&nbsp;&nbsp;&nbsp;<input type="submit" name="submit" value="Download CSV File" /><br /><br />');
   theFormText.append('</form>');

   
   theFormText.append('<form name="exportFormDictionary" id="exportForm" action="' + baseurl + '/index.php" method="post">');
   theFormText.append('<input type="hidden" name="r" value="search_download">');
   theFormText.append('<input type="hidden" name="pipe_delimit_export" value="search_download">');
   theFormText.append('<input type="hidden" name="file_type" value="word_dictionary">');
   var selectLength = theForm.mineral_select.options.length;

   for (i=0;i<selectLength;i++) {
      var min_data = mineral_data_array[theForm.mineral_select.options[i].value].split(/\|\|/);
      theFormText.append('<input type="hidden" name="export_data[' + min_data[0] + ']" value="'+ min_data[1]+ '">');
   }


   theFormText.append('&nbsp;&nbsp;&nbsp;<input style="width: 30em" type="submit" name="submit" value="Download Microsoft WORD Dictionary File***" />');
   theFormText.append('</form>');


   theFormText.append('<br /><div style="width: 300px; padding: 10px;">***Note: This file will not be usable unless you open it with MS Notepad and then save it.  Then you can import it as a Microsoft Word Dictionary file. </div>');

   var text = theFormText.toString();
   formDiv.innerHTML = text;
   // exportFormHandle = exportWindow.document.getElementById('exportForm');
   // exportFormHandle.submit();

   // Close Window

   // Populate Chemistry Fields
   /* var text = '<table align="center">';
   if(theForm.display_ideal.checked) {
      text += '<tr><td>RRUFF:</td><td class="ml_chemistry">' + mineral_data[2]  + '</td></tr>';
   }
   if(theForm.display_ima.checked) {
      text += '<tr><td>IMA:</td><td class="ml_chemistry">' + mineral_data[3] + '</td></tr>';
   }
   if(theForm.display_hom.checked) {
      text += '<tr><td>HOM:</td><td class="ml_chemistry">' + mineral_data[4]  + '</td></tr>';
   }
   if(theForm.display_fleischer.checked) {
      text += '<tr><td>Fleischer:</td><td class="ml_chemistry">' + mineral_data[5]  + '</td></tr>';
   }
   text += '</table>'; */

   // theForm.export.value = "EXPORT DATA";

}

function txtchangeasdf(theForm) {

   theBox = theForm.mineral_select;
   if((theForm.txt_mineral_name.value.length==1)||(theForm.txt_mineral_name.value.length==0))
   {
      current_pos=0;
   }

   var count = 0,flag=0,i=0;

   var selectLength = theForm.mineral_select.options.length;

   var txtValue = theForm.txt_mineral_name.value.replace(/[\'\"\-\(\)\_\s\]\[\{\}\|\+\=\*]/g,'');
   txtValue = txtValue.toLowerCase();
   for (i=current_pos;i<selectLength;i++)
   {
      var theMineralName = theForm.mineral_select[i].innerHTML;
      theMineralName = theMineralName.replace(/[\'\"\-\(\)\_\s\]\[\{\}\|\+\=\*]/g,'');
      theMineralName = theMineralName.substr(0,txtValue.length).toLowerCase();
      if(txtValue == theMineralName)
      {
         theForm.mineral_select[i].selected = 1;
         current_pos=i;
         theFormula(theForm);
         flag=1;
         break;
      }
   }
}

function txtchange(theForm) {
   // Use hi lo game to find mineral quickly
   // Mineral Data should be selected index

   // get the current text in user entry box
   var txtValue = theForm.txt_mineral_name.value.replace(/[\'\"\-\(\)\_\s\]\[\{\}\|\+\=\*]/g,'');
   var mineral = txtValue.toLowerCase();

   if(mineral.length > 0) {

      var letter = mineral.substr(0,1); 
      letterArray = txtSearchArray[letter];

      for(i=0;i<letterArray.length;i++) {
         if(mineral == letterArray[i].substr(0,mineral.length)) {
            var pos = letterArray[i].split(/__/);
            theForm.mineral_select[pos[1]].selected = 1;
            theFormula(theForm);
            break;
         } 
      }
   }
}

function removeOverlay() {
   var loading = document.getElementById('loading_box');
   loading.style.display = "none";
   var overlay = document.getElementById('overlay');
   overlay.style.display = "none";
}

function showOverlay() {
   var loading = document.getElementById('loading_box');
   loading.style.display = "block";
   var overlay = document.getElementById('overlay');
   overlay.style.display = "block";
}

function hiLoSearch(theForm, tags) {
   // Use hi lo game to find mineral quickly
   // Mineral Data should be selected index
      
   var form_value = theForm.mineral_select.options[theForm.mineral_select.selectedIndex].value;
   var mineral_data = mineral_data_array[form_value].split(/\|\|/);
   var mineral_tags = mineral_data[8].split(/\s/);
   

   if(tags) {
      return mineral_tags;
   }
   else {
      return mineral_data;
   }
}

function hiLoSearchSelectBox(theForm, mineral, theSelectTotal) {
   // Use hi lo game to find mineral quickly
   // Mineral Data should be selected index
   var mid = theSelectTotal/2;
   mid = Math.floor(mid);
   var max = theSelectTotal;
   var min = 0;
   // Limit of 20 steps
   for(i=0;i<=16;i++) { 
   
      if(mineral == theForm.mineral_select.options[mid].value) {
         return mid;
      }
      else if(theForm.mineral_select.options[mid].value < mineral) {
         var np = mid + (max - mid)/2;
         min = mid;
      }
      else {
         var np = mid - (mid - min)/2;
         max = mid;
      }

      mid = Math.floor(np);
          
      // alert('Current= ' + mineral_keys[mid] + '\nTarget= ' + theForm.mineral_select.options[theForm.mineral_select.selectedIndex].value + '\nIndex= '+ mid);
   }

   // alert(mineral_data[1]);
   // Populate Chemistry Fields
   return false;
}

function hiLoSearchMineral(theForm, mineral) {
   // Use hi lo game to find mineral quickly
   // Mineral Data should be selected index
   var theSelectTotal = mineral_keys.length;
   var mid = theSelectTotal/2;
   mid = Math.floor(mid);
   var max = theSelectTotal;
   var min = 0;
   // Limit of 20 steps
   for(i=0;i<=16;i++) { 
   
      if(mineral_keys[mid] == mineral) {
         mineral_data = mineral_data_array[mid].split(/\|\|/);
         return mineral_data;
      }
      else if(mineral_keys[mid] < mineral) {
         var np = mid + (max - mid)/2;
         min = mid;
      }
      else {
         var np = mid - (mid - min)/2;
         max = mid;
      }

      mid = Math.floor(np);
          
   }

   // alert(mineral_data[1]);
   // Populate Chemistry Fields
   return false;
}

function print_r(theObj){
  if(theObj.constructor == Array ||
     theObj.constructor == Object){
    ("<ul>")
    for(var p in theObj){
      if(theObj[p].constructor == Array||
         theObj[p].constructor == Object){
("<li>["+p+"] => "+typeof(theObj)+"</li>");
        ("<ul>")
        print_r(theObj[p]);
        ("</ul>")
      } else {
("<li>["+p+"] => "+theObj[p]+"</li>");
      }
    }
    ("</ul>")
  }
}


/**
* Function : dump()
* Arguments: The data - array,hash(associative array),object
*    The level - OPTIONAL
* Returns  : The textual representation of the array.
* This function was inspired by the print_r function of PHP.
* This will accept some data as the argument and return a
* text that will be a more readable version of the
* array/hash/object that is given.
*/
function dump(arr,level) {
   var dumped_text = "";
   if(!level) level = 0;

   //The padding given at the beginning of the line.
   var level_padding = "";
   for(var j=0;j<level+1;j++) level_padding += "    ";
   
   if(typeof(arr) == 'object') { //Array/Hashes/Objects
      for(var item in arr) {
         var value = arr[item];
         
         if(typeof(value) == 'object') { //If it is an array,
            dumped_text += level_padding + "'" + item + "' ...\n";
            dumped_text += dump(value,level+1);
         } else {
            dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
         }
      }
   } else { //Stings/Chars/Numbers etc.
      dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
   }
   return dumped_text;
} 


/**
 * Removes duplicates in the array 'a'
 * @author Johan K~Jnng~Lrd, http://dev.kanngard.net
 */
function unique(a) {
   tmp = new Array(0);
   for(i=0;i<a.length;i++){
      if(!contains(tmp, a[i])){
         tmp.length+=1;
         tmp[tmp.length-1]=a[i];
      }
   }
   return tmp;
}

/**
 * Returns true if 's' is contained in the array 'a'
 * @author Johan K~Jnng~Lrd, http://dev.kanngard.net
 */
function contains(a, e) {
   for(j=0;j<a.length;j++)if(a[j]==e)return true;
   return false;
}

function isInteger(val) {
   if(isNaN(val)) return false;
   return true;
}

 /** 
 * 
 *  Base64 encode / decode 
 *  http://www.webtoolkit.info/ 
 * 
 **/

 var Base64 = {

     // private property  
     _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

     // public method for encoding  
     encode : function (input) {
         var output = "";
         var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
         var i = 0;

         input = Base64._utf8_encode(input);

         while (i < input.length) {

             chr1 = input.charCodeAt(i++);
             chr2 = input.charCodeAt(i++);
             chr3 = input.charCodeAt(i++);

             enc1 = chr1 >> 2;
             enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
             enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
             enc4 = chr3 & 63;

             if (isNaN(chr2)) {
                 enc3 = enc4 = 64;
             } else if (isNaN(chr3)) {
                 enc4 = 64;
             }

             output = output +
             this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
             this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

         }

         return output;
     },

     // public method for decoding  
     decode : function (input) {
         var output = "";
         var chr1, chr2, chr3;
         var enc1, enc2, enc3, enc4;
         var i = 0;

         input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

         while (i < input.length) {

             enc1 = this._keyStr.indexOf(input.charAt(i++));
             enc2 = this._keyStr.indexOf(input.charAt(i++));
             enc3 = this._keyStr.indexOf(input.charAt(i++));
             enc4 = this._keyStr.indexOf(input.charAt(i++));

             chr1 = (enc1 << 2) | (enc2 >> 4);
             chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
             chr3 = ((enc3 & 3) << 6) | enc4;

             output = output + String.fromCharCode(chr1);

             if (enc3 != 64) {
                 output = output + String.fromCharCode(chr2);
             }
             if (enc4 != 64) {
                 output = output + String.fromCharCode(chr3);
             }

         }

         output = Base64._utf8_decode(output);


         return output;  

     },

     // private method for UTF-8 encoding  
     _utf8_encode : function (string) {
         string = string.replace(/\r\n/g,"\n");
         var utftext = "";  

         for (var n = 0; n < string.length; n++) {

             var c = string.charCodeAt(n);

             if (c < 128) {
                 utftext += String.fromCharCode(c);   
             }
             else if((c > 127) && (c < 2048)) {
                 utftext += String.fromCharCode((c >> 6) | 192);
                 utftext += String.fromCharCode((c & 63) | 128);
             }  
             else {  
                 utftext += String.fromCharCode((c >> 12) | 224);
                 utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                 utftext += String.fromCharCode((c & 63) | 128);
             }  

         }

         return utftext;
     },

     // private method for UTF-8 decoding  
     _utf8_decode : function (utftext) {
         var string = "";  
         var i = 0;
         var c = c1 = c2 = 0;

         while ( i < utftext.length ) {

             c = utftext.charCodeAt(i);

             if (c < 128) {
                 string += String.fromCharCode(c);
                 i++;
             }
             else if((c > 191) && (c < 224)) {
                 c2 = utftext.charCodeAt(i+1);
                 string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                 i += 2;
             }
             else {
                 c2 = utftext.charCodeAt(i+1);
                 c3 = utftext.charCodeAt(i+2);
                 string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                 i += 3;
             }

         }

         return string;
     }

 }

