/*
 * Created on 09.10.2003
 *
 * Copyright (c) 2003 by Hyperwave AG. All rights reserved
 * $Id: WebSerializer.js,v 1.1.2.18 2003/11/30 17:13:35 mmair Exp $
 */
{
  /**
   * Helper class to serialize and deserialize Value Object.
   *
   * @author ckoch, sweber, mmair, wputz
   */
  
  /**
   * Constructor get a serialized object what should be deserialized.
   *
   * @param theString: string: A serialized object.
   */
  WebSerializer = function(theString) {
    if (theString == "__proto__")
      return;

    this.kvm = new KeyValueMap();
    this.kvm.disableSort();
    if (typeof theString == "string" && theString) {
      this.kvm.addUrlParameters(theString);
    }
  }
  class$ = doInherit(WebSerializer);


  /**
   * Specifies markup for an empty array which should be serialized
   * or deserialized.
   */  
  class$.static_.EMPTY_ARRAY_MARKER = "[_empty_]";

  
  /**
   * Adds a value.
   *
   * @param theKey: string: Name of the property.
   * @param theValue: string|number|boolean|ValueObjectIFC: Value of the property.
   */
  class$.addValue = function (theKey, theValue) {
    if (theValue == null || typeof theValue == "undefined") {
      return;
    }
    if (typeof theValue.serialize == "function") {
      this.kvm.addKeyValue(theKey, theValue.serialize());
    }
    else {
      this.kvm.addKeyValue(theKey, theValue.toString());
    }
  }
  
  /**
   * Adds some values.
   *
   * @param theKey: string: Name of the property.
   * @param theValue: string[]|number[]|boolean[]|ValueObjectIFC[]: Value of the property.
   */
  class$.addValueArray = function (theKey, theValueArray) {
    if (theValueArray == null || typeof theValueArray == "undefined") {
      return;
    }
    for (var i = 0; i<theValueArray.length; i ++) {
      this.addValue(theKey, theValueArray[i]);
    }
    // mark as empty array if necessary
    if (theValueArray.length == 0){
      this.addValue( theKey, this.static_.EMPTY_ARRAY_MARKER);
    }
  }
  
  /**
   * Returns the string representation.
   *
   * @return string: The serialized object.
   */
  class$.getString = function () {
    return this.kvm.getParameterString();
  }
  
  /**
   * Converts the stored string into the wished types
   *
   * @param theValue: string: the value from the key value map
   * @param theType: string: the type to convert the value to
   * @return string|boolean|number|(typeof theType)|(typeof theValue): the converted value or null
   *         if no value was found.
   */
  class$._convertType = function (theValue, theType) {
    if (theValue == null){
      return null;
    }
    if (typeof theType == "string") {
      switch (theType) {
        case "string":
          return theValue;
        case "boolean":
          return theValue == "true";
        case "number":
          return Number(theValue);
        break;
      }
    }
    else {
      try {
      	return theType.static_.deserialize(theValue);
      }
      catch (e) {
        return theValue;
      }
    }
  }

  /**
   * Return the value from a key.
   *
   * @param theKey: string: the key of the value
   * @param theType: string: the type to convert the value to
   * @return string|boolean|number|(typeof theType)|(typeof theValue): the converted value
   */
  class$.getValue = function (theKey, theType) {
    var value = this.kvm.getOneValue(theKey);
    return this._convertType(value, theType);
  }
  
  /**
   * Return the value array from a key.
   *
   * @param theKey: string: the key of the value
   * @param theType: string: the type to convert the value to
   * @return string[]|boolean[]|number[]|(typeof theType)[]|(typeof theValue)[]: the converted value
   */
  class$.getValueArray = function (theKey, theType) {
    var values = this.kvm.getAllValues(theKey);
    // "theKey" was not set during serialization
    if (values.length == 0)
    {
      return null;
    }
    // "theKey" was set to an empty array during serialization
    if ( (values.length == 1) &&
         (values[0] == WebSerializer.static_.EMPTY_ARRAY_MARKER) )
    {
      return [];
    }
    var ret = new Array(values.length);
    for (var i = values.length; i --;) {
      ret[i] = this._convertType(values[i], theType);
    }
    return ret;
  }

  /**
   * Checks if the given property is defined and sets it on the object.
   *
   * @param anObject: object: javascript object where to set the property
   * @param anId: string: property identifier on the javascript object
   * @param aProperty: object: the property to be set
   */
  class$.static_.setProperty = function(anObject, anId, aProperty) {
    if ((aProperty != null) && (typeof aProperty != "undefined")) {
      if (typeof aProperty.serializeToObject == "function") {
        anObject[anId]=aProperty.serializeToObject();
      }
      else {
        anObject[anId]=aProperty;
      }
    }
  }

  /**
   * Checks if the given property is defined and sets it on the object.
   * Tries to use the method <code>serializeToObject</code> of the array elements.
   *
   * @param anObject: object: javascript object where to set the property
   * @param anId: string: property identifier on the javascript object
   * @param aPropertyArray: array: the propertys to be set
   */
  class$.static_.setPropertyArray = function(anObject, anId, aPropertyArray) {
    if ((aPropertyArray != null) && (typeof aPropertyArray != "undefined")) {
      anObject[anId]=new Array();
      for (var i=aPropertyArray.length; i--;) {
        if (typeof aPropertyArray[i].serializeToObject == "function") {
          anObject[anId][i]=aPropertyArray[i].serializeToObject();
        }
        else {
          anObject[anId][i]=aPropertyArray[i];
        }
      }
    }
  }
}

