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

// This file has been auto-generated by {{code_generator_dart}}. DO NOT MODIFY!

#ifndef {{dart_class}}_h
#define {{dart_class}}_h

{% for filename in header_includes %}
#include "{{filename}}"
{% endfor %}

#include "sky/engine/tonic/dart_converter.h"
#include "sky/engine/tonic/dart_state.h"
#include "sky/engine/wtf/PassOwnPtr.h"

namespace blink {

class {{dart_class}} : public {{cpp_class}} {
 public:
  typedef {{dart_class}} NativeType;

  static PassOwnPtr<NativeType> create(Dart_Handle object,
                                       Dart_Handle& exception) {
    return adoptPtr(new {{dart_class}}(object, exception));
  }

  static PassOwnPtr<NativeType> createWithNullCheck(Dart_Handle object,
                                                    Dart_Handle& exception) {
    if (Dart_IsNull(object))
      return PassOwnPtr<NativeType>();
    return create(object, exception);
  }

  static PassOwnPtr<NativeType> create(Dart_NativeArguments args,
                                       int index,
                                       Dart_Handle& exception) {
    Dart_Handle object = Dart_GetNativeArgument(args, index);
    return create(object, exception);
  }

  static PassOwnPtr<NativeType> createWithNullCheck(Dart_NativeArguments args,
                                                    int index,
                                                    Dart_Handle& exception) {
    Dart_Handle object = Dart_GetNativeArgument(args, index);
    if (Dart_IsNull(object))
      return PassOwnPtr<NativeType>();
    return create(object, exception);
  }

{% for method in methods %}
  virtual {{method.cpp_type}} {{method.name}}({{method.argument_declarations | join(', ')}}) override;
{% endfor %}
 private:
  {{dart_class}}(Dart_Handle object, Dart_Handle& exception)
      : callback_(DartState::Current(), object, exception) {
  }

  DartCallback callback_;
};

template <>
struct DartConverter<{{ cpp_class }}*> {
  static PassOwnPtr<{{dart_class}}> FromArguments(
      Dart_NativeArguments args, int index, Dart_Handle& exception) {
    return {{dart_class}}::create(args, index, exception);
  }

  static PassOwnPtr<{{dart_class}}> FromArgumentsWithNullCheck(
      Dart_NativeArguments args, int index, Dart_Handle& exception) {
    return {{dart_class}}::createWithNullCheck(args, index, exception);
  }
};

}  // blink
#endif // {{dart_class}}_h
