// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef PPAPI_CPP_VAR_H_
#define PPAPI_CPP_VAR_H_

#include <string>
#include <vector>

#include "ppapi/c/pp_module.h"
#include "ppapi/c/pp_var.h"

namespace pp {

class Instance;

namespace deprecated {
class ScriptableObject;
}

class Var {
 public:
  struct Null {};  // Special value passed to constructor to make NULL.

  Var();  // PP_Var of type Undefined.
  Var(Null);  // PP_Var of type Null.
  Var(bool b);
  Var(int32_t i);
  Var(double d);
  Var(const char* utf8_str);  // Must be encoded in UTF-8.
  Var(const std::string& utf8_str);  // Must be encoded in UTF-8.

  // This magic constructor is used when we've gotten a PP_Var as a return
  // value that has already been addref'ed for us.
  struct PassRef {};
  Var(PassRef, PP_Var var) {
    var_ = var;
    needs_release_ = true;
  }

  // TODO(brettw): remove DontManage when this bug is fixed
  //               http://code.google.com/p/chromium/issues/detail?id=52105
  // This magic constructor is used when we've given a PP_Var as an input
  // argument from somewhere and that reference is managing the reference
  // count for us. The object will not be AddRef'ed or Release'd by this
  // class instance..
  struct DontManage {};
  Var(DontManage, PP_Var var) {
    var_ = var;
    needs_release_ = false;
  }

  // Takes ownership of the given pointer.
  Var(Instance* instance, deprecated::ScriptableObject* object);

  Var(const Var& other);

  virtual ~Var();

  Var& operator=(const Var& other);

  bool operator==(const Var& other) const;

  bool is_undefined() const { return var_.type == PP_VARTYPE_UNDEFINED; }
  bool is_null() const { return var_.type == PP_VARTYPE_NULL; }
  bool is_bool() const { return var_.type == PP_VARTYPE_BOOL; }
  bool is_string() const { return var_.type == PP_VARTYPE_STRING; }
  bool is_object() const { return var_.type == PP_VARTYPE_OBJECT; }

  // IsInt and IsDouble return the internal representation. The JavaScript
  // runtime may convert between the two as needed, so the distinction may
  // not be relevant in all cases (int is really an optimization inside the
  // runtime). So most of the time, you will want to check IsNumber.
  bool is_int() const { return var_.type == PP_VARTYPE_INT32; }
  bool is_double() const { return var_.type == PP_VARTYPE_DOUBLE; }
  bool is_number() const {
    return var_.type == PP_VARTYPE_INT32 ||
           var_.type == PP_VARTYPE_DOUBLE;
  }

  // Assumes the internal representation IsBool. If it's not, it will assert
  // in debug mode, and return false.
  bool AsBool() const;

  // AsInt and AsDouble implicitly convert between ints and doubles. This is
  // because JavaScript doesn't have a concept of ints and doubles, only
  // numbers. The distinction between the two is an optimization inside the
  // compiler. Since converting from a double to an int may be lossy, if you
  // care about the distinction, either always work in doubles, or check
  // !IsDouble() before calling AsInt().
  //
  // These functions will assert in debug mode and return 0 if the internal
  // representation is not IsNumber().
  int32_t AsInt() const;
  double AsDouble() const;

  // This assumes the object is of type string. If it's not, it will assert
  // in debug mode, and return an empty string.
  std::string AsString() const;

  // This assumes the object is of type object. If it's not, it will assert in
  // debug mode. If it is not an object or not a ScriptableObject type, returns
  // NULL.
  deprecated::ScriptableObject* AsScriptableObject() const;

  bool HasProperty(const Var& name, Var* exception = NULL) const;
  bool HasMethod(const Var& name, Var* exception = NULL) const;
  Var GetProperty(const Var& name, Var* exception = NULL) const;
  void GetAllPropertyNames(std::vector<Var>* properties,
                           Var* exception = NULL) const;
  void SetProperty(const Var& name, const Var& value, Var* exception = NULL);
  void RemoveProperty(const Var& name, Var* exception = NULL);
  Var Call(const Var& method_name, uint32_t argc, Var* argv,
           Var* exception = NULL);
  Var Construct(uint32_t argc, Var* argv, Var* exception = NULL) const;

  // Convenience functions for calling functions with small # of args.
  Var Call(const Var& method_name, Var* exception = NULL);
  Var Call(const Var& method_name, const Var& arg1, Var* exception = NULL);
  Var Call(const Var& method_name, const Var& arg1, const Var& arg2,
           Var* exception = NULL);
  Var Call(const Var& method_name, const Var& arg1, const Var& arg2,
           const Var& arg3, Var* exception = NULL);
  Var Call(const Var& method_name, const Var& arg1, const Var& arg2,
           const Var& arg3, const Var& arg4, Var* exception = NULL);

  // Returns a const reference to the PP_Var managed by this Var object.
  const PP_Var& pp_var() const {
    return var_;
  }

  // Detaches from the internal PP_Var of this object, keeping the reference
  // count the same. This is used when returning a PP_Var from an API function
  // where the caller expects the return value to be AddRef'ed for it.
  PP_Var Detach() {
    PP_Var ret = var_;
    var_ = PP_MakeUndefined();
    needs_release_ = false;
    return ret;
  }

  // Prints a short description "Var<X>" that can be used for logging, where
  // "X" is the underlying scalar or "UNDEFINED" or "OBJ" as it does not call
  // into the browser to get the object description.
  std::string DebugString() const;

  // For use when calling the raw C PPAPI when using the C++ Var as a possibly
  // NULL exception. This will handle getting the address of the internal value
  // out if it's non-NULL and fixing up the reference count.
  //
  // Danger: this will only work for things with exception semantics, i.e. that
  // the value will not be changed if it's a non-undefined exception. Otherwise,
  // this class will mess up the refcounting.
  //
  // This is a bit subtle:
  // - If NULL is passed, we return NULL from get() and do nothing.
  //
  // - If a undefined value is passed, we return the address of a undefined var
  //   from get and have the output value take ownership of that var.
  //
  // - If a non-undefined value is passed, we return the address of that var
  //   from get, and nothing else should change.
  //
  // Example:
  //   void FooBar(a, b, Var* exception = NULL) {
  //     foo_interface->Bar(a, b, Var::OutException(exception).get());
  //   }
  class OutException {
   public:
    OutException(Var* v)
        : output_(v),
          originally_had_exception_(v && v->is_null()) {
      if (output_)
        temp_ = output_->var_;
      else
        temp_.type = PP_VARTYPE_UNDEFINED;
    }
    ~OutException() {
      if (output_ && !originally_had_exception_)
        *output_ = Var(PassRef(), temp_);
    }

    PP_Var* get() {
      if (output_)
        return &temp_;
      return NULL;
    }

   private:
    Var* output_;
    bool originally_had_exception_;
    PP_Var temp_;
  };

 private:
  // Prevent an arbitrary pointer argument from being implicitly converted to
  // a bool at Var construction. If somebody makes such a mistake, (s)he will
  // get a compilation error.
  Var(void* non_scriptable_object_pointer);

  PP_Var var_;
  bool needs_release_;
};

}  // namespace pp

#endif  // PPAPI_CPP_VAR_H_
