/*
 * Copyright 2010 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package elemental.js.json;

import com.google.gwt.core.client.JavaScriptObject;

import elemental.json.JsonType;
import elemental.json.JsonValue;

/**
 * JSO backed implementation of JsonValue.
 */
@Deprecated
public class JsJsonValue extends JavaScriptObject implements JsonValue {

  static native JsonValue box(JsonValue value) /*-{
    // box for DevMode, not ProdMode
    return @com.google.gwt.core.client.GWT::isScript()() || value == null ? value : Object(value);
  }-*/;

  static native JsonValue debox(JsonValue value) /*-{
    // we don't debox (currently), because ProdMode is now unboxed, and DevMode should stay boxed
    return value;
  }-*/;

  static native String getJsType(Object obj) /*-{
    return typeof @elemental.js.json.JsJsonValue::debox(Lelemental/json/JsonValue;)(obj);
  }-*/;

  static native boolean isArray(Object obj) /*-{
     // ensure that array detection works cross-frame
    return Object.prototype.toString.apply(@elemental.js.json.JsJsonValue::debox(Lelemental/json/JsonValue;)(obj)) === '[object Array]';
  }-*/;

  private static native boolean isNull(JsJsonValue jsJsonValue) /*-{
    // TODO(cromwellian): if this moves to GWT, we may have to support more leniency
    return jsJsonValue === null;
  }-*/;

  protected JsJsonValue() {
  }

  @Override
  final public native boolean asBoolean() /*-{
     return @com.google.gwt.core.client.GWT::isScript()() || this == null ?
        !!@elemental.js.json.JsJsonValue::debox(Lelemental/json/JsonValue;)(this) :
        (!!@elemental.js.json.JsJsonValue::debox(Lelemental/json/JsonValue;)(this)).valueOf();
  }-*/;

  @Override
  final public native double asNumber() /*-{
    if (this == null) {
      return 0;
    }
    return @com.google.gwt.core.client.GWT::isScript()() ?
        +@elemental.js.json.JsJsonValue::debox(Lelemental/json/JsonValue;)(this) :
        (+@elemental.js.json.JsJsonValue::debox(Lelemental/json/JsonValue;)(this)).valueOf();
  }-*/;

  @Override
  // avoid casts, as compiler will throw CCE trying to cast a raw JS String to an interface
  final public native String asString() /*-{
    return this == null ? null :
        ("" + @elemental.js.json.JsJsonValue::debox(Lelemental/json/JsonValue;)(this));
  }-*/;

  final public JsonType getType() {
    if (isNull(this)) {
      return JsonType.NULL;
    }
    String jsType = getJsType(this);
    if ("string".equals(jsType)) {
      return JsonType.STRING;
    }
    else if ("number".equals(jsType)) {
      return JsonType.NUMBER;
    }
    else if ("boolean".equals(jsType)) {
      return JsonType.BOOLEAN;
    }
    else if ("object".equals(jsType)) {
      return isArray(this) ? JsonType.ARRAY : JsonType.OBJECT;
    }
    assert false : "Unknown Json Type";
    return null;
  }

  @Override
  final public native boolean jsEquals(JsonValue value) /*-{
    return @elemental.js.json.JsJsonValue::debox(Lelemental/json/JsonValue;)(this)
    === @elemental.js.json.JsJsonValue::debox(Lelemental/json/JsonValue;)(value);
  }-*/;

  final public native String toJson() /*-{
    // skip hashCode field
    return $wnd.JSON.stringify(this, function(keyName, value) {
        if (keyName == "$H") {
          return undefined; // skip hashCode property
        }
        return value;
      }, 0);
  }-*/;

  final public native Object toNative() /*-{
    return @elemental.js.json.JsJsonValue::debox(Lelemental/json/JsonValue;)(this);
  }-*/;
}
