﻿function __TO_JSON(o) {
  if (o == null) {
    return "null";
  } else {
    switch (o.constructor) {
      case String:
        var v = [];
        for (var i = 0; i < o.length; i++) {
          var c = o.charAt(i);
          if (c >= " ") {
            if (c == "\\" || c == '"') v.push("\\");
            v.push(c);
          } else {
            switch(c) {
              case "\n": v.push("\\n"); break;
              case "\r": v.push("\\r"); break;
              case "\b": v.push("\\b"); break;
              case "\f": v.push("\\f"); break;
              case "\t": v.push("\\t"); break;
              default:
                v.push("\\u00");
                v.push(c.charCodeAt().toString(16));
            }
          }
        }
        return '"' + v.join('') + '"';
      case Boolean:
        return o.toString();
      case Number:
        return isFinite(o) ? o.toString() : __TO_JSON(null);
      case Array:
        var v = [];
        for (var i = 0; i < o.length; i++) {
          v.push(__TO_JSON(o[i])) ;
        }
        return "[" + v.join(", ") + "]";
      case Date:
        var d = new Object();
        d.__TYPE = "System.DateTime";
        d.Year = o.getUTCFullYear();
        d.Month = o.getUTCMonth() + 1;
        d.Day = o.getUTCDate();
        d.Hour = o.getUTCHours();
        d.Minute = o.getUTCMinutes();
        d.Second = o.getUTCSeconds();
        d.Millisecond = o.getUTCMilliseconds();
        d.TimezoneOffset = o.getTimezoneOffset();
        return __TO_JSON(d);
      default:
        if (o==window) {
          return "null";
        } if (typeof(o)=="object") {
          var v = [];
          for (a in o) {
            if (typeof(o[a]) != "function") {
               v.push('"'+a+'":'+__TO_JSON(o[a]));
            }
          }
          if (v.length > 0) {              
            return "{" + v.join(", ") + "}";
          } else {
            return "{}";        
          }
        } else {
          return "null";
        }
    }
  }
}