#ifndef _H_Value
#define _H_Value
/*
 * Copyright 2008 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.
 */

#ifndef _WINDOWS
// TODO(jat): remove; for abort() which should probably go away
#include <stdlib.h>
#endif

#include <string>

#include "Debug.h"

#include "BrowserChannel.h"

class Value {
public:
  enum ValueType {
    NULL_TYPE = VALUE_TYPE_NULL,
    BOOLEAN = VALUE_TYPE_BOOLEAN,
    BYTE = VALUE_TYPE_BYTE,
    CHAR = VALUE_TYPE_CHAR,
    SHORT = VALUE_TYPE_SHORT,
    INT = VALUE_TYPE_INT,
    LONG = VALUE_TYPE_LONG,
    FLOAT = VALUE_TYPE_FLOAT,
    DOUBLE = VALUE_TYPE_DOUBLE,
    STRING = VALUE_TYPE_STRING,
    JAVA_OBJECT = VALUE_TYPE_JAVA_OBJECT,
    JS_OBJECT = VALUE_TYPE_JS_OBJECT,
    UNDEFINED = VALUE_TYPE_UNDEFINED
  };

private:
  ValueType type;
  union {
    bool  boolValue;
    unsigned char byteValue;
    unsigned short charValue;
    double doubleValue;
    float floatValue;
    int32_t intValue;
    int64_t longValue;
    short shortValue;
    std::string* stringValue;
  } value;

public:
  Value() {
    type = UNDEFINED;
  }

  Value(const Value& other) {
    copyValue(other);
  }

  Value& operator=(const Value& other) {
    clearOldValue();
    copyValue(other);
    return *this;
  }

  ~Value() {
    clearOldValue();
  }

  bool getBoolean() const {
    assertType(BOOLEAN);
    return value.boolValue;
  }

  unsigned char getByte() const {
    assertType(BYTE);
    return value.byteValue;
  }

  unsigned short getChar() const {
    assertType(CHAR);
    return value.charValue;
  }

  double getDouble() const {
    assertType(DOUBLE);
    return value.doubleValue;
  }

  float getFloat() const {
    assertType(FLOAT);
    return value.floatValue;
  }

  int getInt() const {
    assertType(INT);
    return value.intValue;
  }

  int getJavaObjectId() const {
    assertType(JAVA_OBJECT);
    return value.intValue;
  }

  int getJsObjectId() const {
    assertType(JS_OBJECT);
    return value.intValue;
  }

  int64_t getLong() const {
    assertType(LONG);
    return value.longValue;
  }

  short getShort() const {
    assertType(SHORT);
    return value.shortValue;
  }

  const std::string getString() const {
    assertType(STRING);
    return std::string(*value.stringValue);
  }

  ValueType getType() const {
    return type;
  }

  bool isBoolean() const {
    return type == BOOLEAN;
  }

  bool isByte() const {
    return type == BYTE;
  }

  bool isChar() const {
    return type == CHAR;
  }

  bool isDouble() const {
    return type == DOUBLE;
  }

  bool isFloat() const {
    return type == FLOAT;
  }

  bool isInt() const {
    return type == INT;
  }

  bool isJavaObject() const {
    return type == JAVA_OBJECT;
  }

  bool isJsObject() const {
    return type == JS_OBJECT;
  }

  bool isLong() const {
    return type == LONG;
  }

  bool isNull() const {
    return type == NULL_TYPE;
  }

  bool isNumber() const {
    switch (type) {
      case BYTE:
      case CHAR:
      case DOUBLE:
      case FLOAT:
      case INT:
      case LONG:
      case SHORT:
        return true;
      default:
        return false;
    }
  }

  bool isPrimitive() const {
    switch (type) {
      case BOOLEAN:
      case BYTE:
      case CHAR:
      case DOUBLE:
      case FLOAT:
      case INT:
      case LONG:
      case SHORT:
        return true;
      default:
        return false;
    }
  }

  bool isShort() const {
    return type == SHORT;
  }

  bool isString() const {
    return type == STRING;
  }

  bool isUndefined() const {
    return type == UNDEFINED;
  }

  void setBoolean(bool val) {
    clearOldValue();
    type = BOOLEAN;
    value.boolValue = val;
  }

  void setByte(unsigned char val) {
    clearOldValue();
    type = BYTE;
    value.byteValue = val;
  }

  void setChar(unsigned short val) {
    clearOldValue();
    type = CHAR;
    value.charValue = val;
  }

  void setDouble(double val) {
    clearOldValue();
    type = DOUBLE;
    value.doubleValue = val;
  }

  void setFloat(float val) {
    clearOldValue();
    type = FLOAT;
    value.floatValue = val;
  }

  void setInt(int val) {
    clearOldValue();
    type = INT;
    value.intValue = val;
  }

  void setJavaObject(int objectId) {
    clearOldValue();
    type = JAVA_OBJECT;
    value.intValue = objectId;
  }

  void setJsObjectId(int val) {
    clearOldValue();
    type = JS_OBJECT;
    value.intValue = val;
  }

  void setLong(int64_t val) {
    clearOldValue();
    type = LONG;
    value.longValue = val;
  }

  void setNull() {
    clearOldValue();
    type = NULL_TYPE;
  }

  void setShort(short val) {
    clearOldValue();
    type = SHORT;
    value.shortValue = val;
  }

  void setString(const char* chars, int len) {
    setString(std::string(chars, len));
  }

  void setString(const std::string& val) {
    clearOldValue();
    type = STRING;
    value.stringValue = new std::string(val);
  }

  void setUndefined() {
    clearOldValue();
    type = UNDEFINED;
  }

  std::string toString() const {
    char buf[64];
    switch (type) {
      case NULL_TYPE:
        return "null";
      case BOOLEAN:
        snprintf(buf, sizeof(buf), "boolean(%s)", getBoolean() ? "true"
            : "false");
        return std::string(buf);
      case BYTE:
        snprintf(buf, sizeof(buf), "byte(%d)", getByte());
        return std::string(buf);
      case CHAR:
        snprintf(buf, sizeof(buf), "char(%d)", getChar());
        return std::string(buf);
      case SHORT:
        snprintf(buf, sizeof(buf), "short(%d)", getShort());
        return std::string(buf);
      case INT:
        snprintf(buf, sizeof(buf), "int(%d)", getInt());
        return std::string(buf);
      case LONG:
        snprintf(buf, sizeof(buf), "long(%lld)",
            static_cast<long long>(getLong()));
        return std::string(buf);
      case FLOAT:
        snprintf(buf, sizeof(buf), "float(%g)", getFloat());
        return std::string(buf);
      case DOUBLE:
        snprintf(buf, sizeof(buf), "double(%g)", getDouble());
        return std::string(buf);
      case STRING:
        snprintf(buf, sizeof(buf), "string(%.20s)", getString().c_str());
        return std::string(buf);
      case JAVA_OBJECT:
        snprintf(buf, sizeof(buf), "JavaObj(%d)", getJavaObjectId());
        return std::string(buf);
      case JS_OBJECT:
        snprintf(buf, sizeof(buf), "JsObj(%d)", getJsObjectId());
        return std::string(buf);
      case UNDEFINED:
        return "undefined";
      default:
        return "Unknown type";
    }
  }

private:
  void assertType(ValueType reqType) const {
    if (type != reqType) {
      Debug::log(Debug::Error) << "Value::assertType - expecting type "
          << int(reqType) << ", was " << int(type) << Debug::flush;
      // TODO(jat): is this portable?  Should we do something else here?
      abort();
    }
  }

  void clearOldValue() {
    if (type == STRING) {
      delete value.stringValue;
      type = UNDEFINED;
    }
  }

  // Precondition: existing value, if any, has been cleared
  void copyValue(const Value& other) {
    type = other.type;
    value = other.value;
    // handle deep copies of value types that need it
    switch (type) {
      case STRING:
        value.stringValue = new std::string(*value.stringValue);
        break;
      default:
        // no other values need deep copies
        break;
    }
  }
};

inline Debug::DebugStream& operator<<(Debug::DebugStream& dbg, const Value& val) {
  if (dbg.isActive()) {
    dbg << val.toString();
  }
  return dbg;
}

#endif
