/*
# File: serializearray.js
# Copyright 2005-2009 by Frank Koenen, Finkle Enterprises, LLC. All Rights Reserved.
#
# Purpose: serialize/deserialize arrays in Javascript.
#
# Usage:
#   var arr1 = new Array('A','B','C');
#   var string = serializeArray(arr1);
#   var arr2 = unserializeArray(string);
#
# History:
# 26-Feb-05 fhk; Init
#--------------------------------------------------
*/

//#--------------------------------------------------
function serializeArray(inArray){

  var theResult = "";
  var arrayConstructor = new Array().constructor.toString();
  var thing = true;

  for(var i in inArray){

   var theType = typeof(inArray[i]);
   var key = escape(i.toString());

   theResult += "key sz:" + key.length + "{" + key + "}";

   if(inArray[i] && inArray[i].constructor && inArray[i].constructor.toString() == arrayConstructor){

    var arrData = serializeArray(inArray[i]);
    theResult += "Array sz:" + arrData.length + "{" + arrData + "}";

   }
   else{
    var str = escape(inArray[i].toString());
    theResult += theType + " sz:" + str.length + "{" + str + "}";
   }
  }
  return theResult;

}

//#--------------------------------------------------
function unserializeArray(inString){

 var theResult = new Array();
 var theKey = "";

 // Note that arrays with zero entries will come in as "Array sz:0{}".
 // The recursion will then be called with "zero string",
 // which is why we check for inString.length
 while(true && inString.length > 0){

  var nextLeftBracketIndex = inString.indexOf("{", 0);
  var theType = inString.substr(0, inString.indexOf(" ", 0));
  var sizeOffset = inString.indexOf("sz:", 0) + 3;
  var dataSize = parseInt(inString.substr(sizeOffset, nextLeftBracketIndex - sizeOffset));
  var theData = inString.substr(nextLeftBracketIndex + 1, dataSize);

  // This will save legacy arrays
  if(theKey == "")
   theKey = theResult.length;

  if(theType == "key"){

   if(!isNaN(theData)){
    theKey = parseInt(theData);
   }
   else if(theData.length > 0){
    theKey = unescape(theData);
   }
  }
  else if(theType == "number"){

   theResult[theKey] = parseFloat(theData);
   theKey = "";
  }
  else if(theType == "string"){

   theResult[theKey] = unescape(theData);
   theKey = "";
  }
  else if(theType == "boolean" ){

   var val = new Boolean(theData);
   theResult[theKey] = val == true ? true : false;
   theKey = "";
  }
  else if(theType == "Array"){

   // Recurse
   theResult[theKey] = unserializeArray(theData);
   theKey = "";
  }
  else{

   prompt("Unknown object: " + theType + "\ninString: " + inString,inString);
  }

  nextLeftBracketIndex = nextLeftBracketIndex + 2 + dataSize;

  if(inString.length - nextLeftBracketIndex > 0){
   inString = inString.substr(nextLeftBracketIndex, inString.length - nextLeftBracketIndex);
  }
  else
   break;
 }

 return theResult;

}
