//
// SimpleSerializer.js
//
// utilidades de serializado
// y parseado de objetos java-script
//
// Ignacio Holgado
// eresMas 18/05/2k
//

// Serializador  2 beta v: 1.0

function SimpleSerializer() {};

/**
*
* deep
*
* Serializa totalmente un objeto para
* poder ser utilizado en otro entorno
* distinto.
* Ejemplo de llamada : SimpleSerializer.deep( obj , "obj" , nl);
*
*@Author ihm
*
*@param obj
*
* Objeto a serializar
*
*@param name
*
* String que contenga el nombre del
* objeto destino
*
*@param nl [optional:false]
* If true, do not use literal notation
* i.e., "new Object();" is used instead of "{}"
*
*/

SimpleSerializer.deep =
function /* deep */ ( obj, name, nl )
{
  connt ={};
  connt.n = 0;
  if ( ! Util.isOk( nl ) ) nl = false;
  //var salida = "var _t=[];var " + SimpleSerializer.__deep( obj, name ,connt ) + name + ";";
  var salida = "var _t=" + this.__getNewArrayExpr(nl) + "var " + name + ";" + SimpleSerializer.__deep( obj, name, connt, null, nl ) + name + ";";
  SimpleSerializer.__clear ( obj );
  return salida;
}

SimpleSerializer.__getNewArrayExpr =
function /*SimpleSerializer.getNewArrayExpr*/( nl )
{
  return ( nl ? "new Array();" : "[];" );
}

SimpleSerializer.__getNewObjectExpr =
function /*SimpleSerializer.getNewObjectExpr*/( nl )
{
  return ( nl ? "new Object();" : "{};" );
}

/**
*__escapeaComillas
* Escapea comillas dobles
*/


SimpleSerializer.__escapeaComillas =
function /* comillas */ ( ob )
{
	var salida = ob;
	if (Util.isNumber(ob)) return ob;
	ob = ob.replace( /\\/g, "\\\\");
	ob = ob.replace( /\'/g, "\\'");
	ob = ob.replace( /\"/g, '\\"');
	ob = ob.replace( /\n/g, '\\n');
	ob = ob.replace( /\r/g, '');
	return ob;
}


SimpleSerializer.__deep =
function /* __deep */ ( obj, name, connt, itera, nl )
{

	var iter;
	if (!Util.isAny(itera))
	{
		iter=0;
	}
	else
	{
		iter=itera;
	}

	if ( ! Util.isOk( nl ) ) nl = false;
	
	var salida ="";

	if (iter>20)
	{
	    return ""; // Sistema anti cuelgues
	}





	// Tipos base

	if ( obj==null )          return name+"= null; ";
	if (!Util.isAny( obj ))   return "";


	if (Util.isNumber(obj))
	{
		return name+"="+obj+";";
	}
	if (obj.constructor.toString().indexOf("function Date()") >-1 )
	{
		return name+"= new Date(" + Number(obj) + ");";
	}

	if (Util.isString(obj))
	{
		return name+"='" + SimpleSerializer.__escapeaComillas ( obj ) + "'; ";
	}

	if (Util.isBoolean(obj))
	{
		return name+"="+obj+";";
	}
	


	var k="";
	var s="";
	var name2=name;

	if (name.length>8)
	{
		name2="_t[" + connt.n  + "]";
		// s+=name2 + "=" + name + ";";
		s+=name2 + "=" ;
		connt.n++;
	}

	var nc = "" + obj.constructor;


	// Objeto generico

	if (nc.indexOf("Array")>-1)
	{
		var bool=false;

		// Miramos si el array esta en la tabla
		if (Util.isAny(obj.__t__))
		{
			return name + "=" + obj.__t__ + ";";
		}

		obj.__t__ = name2;

   		//k+= name + "=[];"+s;
   		k += s + name + "=" + this.__getNewArrayExpr(nl);

   		for (var i in obj)
   		{
   	    	if (i!="__t__")
   	    	{
   	    		f=false;
   	    		var j;
   	    		m=obj[ i ];
   	    		k+= SimpleSerializer.__deep(m,name2 + "['" + SimpleSerializer.__escapeaComillas(i) + "']",connt,iter+1, nl);
			}
   	  	}
   	  	return k;
  	}



	if (nc.indexOf("Object")>-1)
	{
		var bool=false;

		// Miramos si el objeto esta en la tabla
		if (Util.isAny(obj.__t__))
		{
			return name + "=" + obj.__t__ + ";";
		}

		obj.__t__ = name2;

	    // k+= name + "={};"+s;
	    k += s + name + "=" + this.__getNewObjectExpr(nl);
	    for (var i in obj)
	    {
	       	if (i!="__t__")
   	    	{
		       	f=false;
		       	var j;
		       	m=obj[ i ];
		       	k+= SimpleSerializer.__deep(m,name2 + "['" + SimpleSerializer.__escapeaComillas(i) + "']",connt,iter+1 , nl);
			}
	    }
	    return k;
  	}


  	if (Util.isFunction(obj))
  	{
  		// Serializacion de un metodo
    	k= "" + obj;
    	if (k.indexOf("anonymous")==10)
    	{
    		k= "function "+ k.substring(19,k.length-1);
      		k=s + name + "=" + k +"; ";
    	}
    	else
    	{
      		k=k.substring(0,k.length-1);
      		k=s + name + "=" + k +"; ";
    	}
    	return k;
  	}


  	// El objeto a serializar es un objeto generico.

  	var m="";
  	var k2="" + obj.constructor;
  	k2=k2.substring(9,k2.indexOf("{"));


    // quitamos los argumentos de los constructores
  	{
    	var i,j;
    	i=k2.indexOf("(");
    	j=k2.indexOf(")");
    	k2=k2.substring(0,i+1)+k2.substring(j);
  	}

  	k+=s +name+"= new "+ k2;
  	k+=";"
  	var bool=false;


  	// Miramos si el objeto esta en la tabla
	if (Util.isAny(obj.__t__))
	{
		return s + name + "=" + obj.__t__ + ";";
	}

	obj.__t__ = name2;

    var f=true;
    // Serializamos los elementos:
    for (var i in obj)
    {
    	if (i!="__t__")
   	    {
    		f=false;
    		m=obj[i];
    		if (Util.isFunction(m))
    		{
    			if (m!==((obj.constructor.prototype)[i]))
      			{
       				k+= SimpleSerializer.__deep(m, name2+"['"+ SimpleSerializer.__escapeaComillas(i) +"']",connt,iter+1, nl);
      			}
    		}
    		else
    		{
     			k+= SimpleSerializer.__deep(m,name2+"['" + SimpleSerializer.__escapeaComillas(i) + "']",connt ,iter+1, nl);
    		}
		}
	}
  	return k;
}

SimpleSerializer.__clear =
function /* __deep */ ( obj )
{
	if (obj == null) return;
	if (Util.isAny(obj.__t__) )
	{
		delete obj.__t__;
		for (i in obj)
		{
			SimpleSerializer.__clear(obj[i]);
		}
	}
}





// Serializador de primera capa
// Solo serializa la primera capa

/**
*
*  shallow( name1 , name2 )
*  Params:
*
*
* name1 : Nombre del objeto a serializar
* name2 : Nombre del objeto destino
*
*
*/


SimpleSerializer.shallow =
function /* shallow */( name1 , name2 )
  {


  var salida ="";
  var obj;
  var s="";
  var m="";
  var k="";
  var mmtmp="obj="+ name1;
  eval(mmtmp);

  // Tipos base

  if (Util.isNumber(obj))
  {
    return name2+"="+obj+"; ";
  }

  if (Util.isString(obj))
  {
    return name2+"='"+obj+"'; ";
  }

  if (Util.isBoolean(obj))
  {
    return name2+"="+obj+"; ";
  }

  if (Util.isArray(obj))
  {
    k=""+ name2 + "= new Array() ;  ";

    for (var i in obj)
    {

      var j;
      m=obj[ i ];
      k+= name2 + "[" + i + "] = " + name1 + "[" + i + "];  " ;
    }
    return k;
  }

  if (Util.isFunction(obj))
  {
    // Serializacion de un metodo
    k= "" + obj;
    if (k.indexOf("anonymous")==10)
    {
      k= "function "+ k.substring(19,k.length-1);
      k="" + name2 + "=" + k +"; ";
    }
    else
    {
      k=k.substring(0,k.length-1);
      k="" + name2 + "=" + k +"; ";
    }
    return k;
  }


  // El objeto a serializar es un objeto generico.

  k="" + obj.constructor;
  k=k.substring(9,k.indexOf("{"));


    // quitamos los argumentos de los constructores
  {
    var i,j;
    i=k.indexOf("(");
    j=k.indexOf(")");
    k=k.substring(0,i+1)+k.substring(j,k.length);
  }

  k=name2+"= new "+ k;
  k+="; "
  var bool=false;


  // Copiamos las referencias a los elementos:

  for (var i in obj)
  {
    f=false;

    m=obj[i];

    if (Util.isFunction(m))
    {
      if (m!==((obj.constructor.prototype)[i]))
      {
        k+= name2 + "[" + i + "] = " + name1 + "[" + i + "];  " ;
      }
    }
    else
    {
      k+= name2 + "[" + i + "] = " + name1 + "[" + i + "];  " ;
    }
  }
      // if (f) k+=names+"="+obj+"; "; // No hay subobjetos !!

  return k;
}

register( SimpleSerializer );
