/* autogenerated by generator-region.js */

#include "../../debug.h"
#include "../../gi.h"
#include "../../util.h"
#include "region.h"
#include "rectangle.h"
#include "rectangle-int.h"

using namespace v8;


namespace GNodeJS {

namespace Cairo {



Nan::Persistent<FunctionTemplate> Region::constructorTemplate;
Nan::Persistent<Function>         Region::constructor;



/*
 * Initialize
 */

Region::Region(cairo_region_t* data) : ObjectWrap() {
  _data = data;
}

/*
 * Destroy
 */

Region::~Region() {
  if (_data != NULL) {
    cairo_region_destroy (_data);
  }
}


/*
 * Template methods
 */


Local<FunctionTemplate> Region::GetTemplate() {
  if (constructorTemplate.IsEmpty())
    Region::SetupTemplate();
  return Nan::New<FunctionTemplate> (constructorTemplate);
}

Local<Function> Region::GetConstructor() {
  if (constructor.IsEmpty())
    Region::SetupTemplate();
  return Nan::New<Function> (constructor);
}

void Region::SetupTemplate() {

  // Constructor
  auto tpl = Nan::New<FunctionTemplate>(Region::New);
  tpl->InstanceTemplate()->SetInternalFieldCount(1);
  tpl->SetClassName(Nan::New("CairoRegion").ToLocalChecked());


  SET_PROTOTYPE_METHOD(tpl, status);
  SET_PROTOTYPE_METHOD(tpl, getExtents);
  SET_PROTOTYPE_METHOD(tpl, numRectangles);
  SET_PROTOTYPE_METHOD(tpl, getRectangle);
  SET_PROTOTYPE_METHOD(tpl, isEmpty);
  SET_PROTOTYPE_METHOD(tpl, containsPoint);
  SET_PROTOTYPE_METHOD(tpl, containsRectangle);
  SET_PROTOTYPE_METHOD(tpl, equal);
  SET_PROTOTYPE_METHOD(tpl, translate);
  SET_PROTOTYPE_METHOD(tpl, intersect);
  SET_PROTOTYPE_METHOD(tpl, intersectRectangle);
  SET_PROTOTYPE_METHOD(tpl, subtract);
  SET_PROTOTYPE_METHOD(tpl, subtractRectangle);
  Nan::SetPrototypeMethod(tpl, "union", union_);
  SET_PROTOTYPE_METHOD(tpl, unionRectangle);
  Nan::SetPrototypeMethod(tpl, "xor", xor_);
  SET_PROTOTYPE_METHOD(tpl, xorRectangle);

  auto ctor = Nan::GetFunction (tpl).ToLocalChecked();

  SET_METHOD(ctor, copy);

  constructorTemplate.Reset(tpl);
  constructor.Reset(ctor);



}



/*
 * Initialize method
 */


void Region::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) {
  Nan::Set (target, Nan::New ("Region").ToLocalChecked(), Region::GetConstructor());
}



/*
 * Instance constructors
 */



NAN_METHOD(Region::New) {
  if (!info.IsConstructCall()) {
    return Nan::ThrowTypeError("Class constructors cannot be invoked without 'new'");
  }

  cairo_region_t* data = NULL;

  if (info[0]->IsExternal()) {
    data = (cairo_region_t*) External::Cast (*info[0])->Value ();
  }
  else if (info.Length() == 1) {
    auto rectangle = Nan::ObjectWrap::Unwrap<RectangleInt>(info[0].As<Object>())->_data;

    data = cairo_region_create_rectangle (rectangle);
  }
  else {
    data = cairo_region_create ();
  }

  Region* instance = new Region(data);
  instance->Wrap(info.This());

  info.GetReturnValue().Set(info.This());
}



/*
 * Methods
 */

NAN_METHOD(Region::copy) {
  // in-arguments
  auto original = Nan::ObjectWrap::Unwrap<Region>(info[0].As<Object>())->_data;

  // function call
  cairo_region_t * result = cairo_region_copy (original);

  // return
  Local<Value> args[] = { Nan::New<External> (result) };
  Local<Function> constructor = Nan::New<Function> (Region::constructor);
  Local<Value> returnValue = Nan::NewInstance(constructor, 1, args).ToLocalChecked();
  info.GetReturnValue().Set(returnValue);
}

NAN_METHOD(Region::status) {
  auto self = info.This();
  auto region = Nan::ObjectWrap::Unwrap<Region>(self)->_data;

  // function call
  cairo_status_t result = cairo_region_status (region);

  // return
  Local<Value> returnValue = Nan::New (result);
  info.GetReturnValue().Set(returnValue);
}

NAN_METHOD(Region::getExtents) {
  auto self = info.This();
  auto region = Nan::ObjectWrap::Unwrap<Region>(self)->_data;

  // out-arguments
  auto extents = Nan::NewInstance(
            Nan::New<Function>(RectangleInt::constructor),
            0,
            NULL).ToLocalChecked();

  // function call
  cairo_region_get_extents (region, Nan::ObjectWrap::Unwrap<RectangleInt>(extents)->_data);

  // return
  Local<Value> returnValue = extents;
  info.GetReturnValue().Set(returnValue);
}

NAN_METHOD(Region::numRectangles) {
  auto self = info.This();
  auto region = Nan::ObjectWrap::Unwrap<Region>(self)->_data;

  // function call
  int result = cairo_region_num_rectangles (region);

  // return
  Local<Value> returnValue = Nan::New (result);
  info.GetReturnValue().Set(returnValue);
}

NAN_METHOD(Region::getRectangle) {
  auto self = info.This();
  auto region = Nan::ObjectWrap::Unwrap<Region>(self)->_data;

  // in-arguments
  auto nth = Nan::To<int64_t>(info[0].As<Number>()).ToChecked();

  // out-arguments
  auto rectangle = Nan::NewInstance(
            Nan::New<Function>(RectangleInt::constructor),
            0,
            NULL).ToLocalChecked();

  // function call
  cairo_region_get_rectangle (region, nth, Nan::ObjectWrap::Unwrap<RectangleInt>(rectangle)->_data);

  // return
  Local<Value> returnValue = rectangle;
  info.GetReturnValue().Set(returnValue);
}

NAN_METHOD(Region::isEmpty) {
  auto self = info.This();
  auto region = Nan::ObjectWrap::Unwrap<Region>(self)->_data;

  // function call
  cairo_bool_t result = cairo_region_is_empty (region);

  // return
  Local<Value> returnValue = Nan::New ((bool) result);
  info.GetReturnValue().Set(returnValue);
}

NAN_METHOD(Region::containsPoint) {
  auto self = info.This();
  auto region = Nan::ObjectWrap::Unwrap<Region>(self)->_data;

  // in-arguments
  auto x = Nan::To<int64_t>(info[0].As<Number>()).ToChecked();
  auto y = Nan::To<int64_t>(info[1].As<Number>()).ToChecked();

  // function call
  cairo_bool_t result = cairo_region_contains_point (region, x, y);

  // return
  Local<Value> returnValue = Nan::New ((bool) result);
  info.GetReturnValue().Set(returnValue);
}

NAN_METHOD(Region::containsRectangle) {
  auto self = info.This();
  auto region = Nan::ObjectWrap::Unwrap<Region>(self)->_data;

  // in-arguments
  auto rectangle = Nan::ObjectWrap::Unwrap<RectangleInt>(info[0].As<Object>())->_data;

  // function call
  cairo_region_overlap_t result = cairo_region_contains_rectangle (region, rectangle);

  // return
  Local<Value> returnValue = Nan::New (result);
  info.GetReturnValue().Set(returnValue);
}

NAN_METHOD(Region::equal) {
  auto self = info.This();
  auto a = Nan::ObjectWrap::Unwrap<Region>(self)->_data;

  // in-arguments
  auto b = Nan::ObjectWrap::Unwrap<Region>(info[0].As<Object>())->_data;

  // function call
  cairo_bool_t result = cairo_region_equal (a, b);

  // return
  Local<Value> returnValue = Nan::New ((bool) result);
  info.GetReturnValue().Set(returnValue);
}

NAN_METHOD(Region::translate) {
  auto self = info.This();
  auto region = Nan::ObjectWrap::Unwrap<Region>(self)->_data;

  // in-arguments
  auto dx = Nan::To<int64_t>(info[0].As<Number>()).ToChecked();
  auto dy = Nan::To<int64_t>(info[1].As<Number>()).ToChecked();

  // function call
  cairo_region_translate (region, dx, dy);
}

NAN_METHOD(Region::intersect) {
  auto self = info.This();
  auto dst = Nan::ObjectWrap::Unwrap<Region>(self)->_data;

  // in-arguments
  auto other = Nan::ObjectWrap::Unwrap<Region>(info[0].As<Object>())->_data;

  // function call
  cairo_status_t result = cairo_region_intersect (dst, other);

  // return
  Local<Value> returnValue = Nan::New (result);
  info.GetReturnValue().Set(returnValue);
}

NAN_METHOD(Region::intersectRectangle) {
  auto self = info.This();
  auto dst = Nan::ObjectWrap::Unwrap<Region>(self)->_data;

  // in-arguments
  auto rectangle = Nan::ObjectWrap::Unwrap<RectangleInt>(info[0].As<Object>())->_data;

  // function call
  cairo_status_t result = cairo_region_intersect_rectangle (dst, rectangle);

  // return
  Local<Value> returnValue = Nan::New (result);
  info.GetReturnValue().Set(returnValue);
}

NAN_METHOD(Region::subtract) {
  auto self = info.This();
  auto dst = Nan::ObjectWrap::Unwrap<Region>(self)->_data;

  // in-arguments
  auto other = Nan::ObjectWrap::Unwrap<Region>(info[0].As<Object>())->_data;

  // function call
  cairo_status_t result = cairo_region_subtract (dst, other);

  // return
  Local<Value> returnValue = Nan::New (result);
  info.GetReturnValue().Set(returnValue);
}

NAN_METHOD(Region::subtractRectangle) {
  auto self = info.This();
  auto dst = Nan::ObjectWrap::Unwrap<Region>(self)->_data;

  // in-arguments
  auto rectangle = Nan::ObjectWrap::Unwrap<RectangleInt>(info[0].As<Object>())->_data;

  // function call
  cairo_status_t result = cairo_region_subtract_rectangle (dst, rectangle);

  // return
  Local<Value> returnValue = Nan::New (result);
  info.GetReturnValue().Set(returnValue);
}

NAN_METHOD(Region::union_) {
  auto self = info.This();
  auto dst = Nan::ObjectWrap::Unwrap<Region>(self)->_data;

  // in-arguments
  auto other = Nan::ObjectWrap::Unwrap<Region>(info[0].As<Object>())->_data;

  // function call
  cairo_status_t result = cairo_region_union (dst, other);

  // return
  Local<Value> returnValue = Nan::New (result);
  info.GetReturnValue().Set(returnValue);
}

NAN_METHOD(Region::unionRectangle) {
  auto self = info.This();
  auto dst = Nan::ObjectWrap::Unwrap<Region>(self)->_data;

  // in-arguments
  auto rectangle = Nan::ObjectWrap::Unwrap<RectangleInt>(info[0].As<Object>())->_data;

  // function call
  cairo_status_t result = cairo_region_union_rectangle (dst, rectangle);

  // return
  Local<Value> returnValue = Nan::New (result);
  info.GetReturnValue().Set(returnValue);
}

NAN_METHOD(Region::xor_) {
  auto self = info.This();
  auto dst = Nan::ObjectWrap::Unwrap<Region>(self)->_data;

  // in-arguments
  auto other = Nan::ObjectWrap::Unwrap<Region>(info[0].As<Object>())->_data;

  // function call
  cairo_status_t result = cairo_region_xor (dst, other);

  // return
  Local<Value> returnValue = Nan::New (result);
  info.GetReturnValue().Set(returnValue);
}

NAN_METHOD(Region::xorRectangle) {
  auto self = info.This();
  auto dst = Nan::ObjectWrap::Unwrap<Region>(self)->_data;

  // in-arguments
  auto rectangle = Nan::ObjectWrap::Unwrap<RectangleInt>(info[0].As<Object>())->_data;

  // function call
  cairo_status_t result = cairo_region_xor_rectangle (dst, rectangle);

  // return
  Local<Value> returnValue = Nan::New (result);
  info.GetReturnValue().Set(returnValue);
}



}; // Cairo

}; // GNodeJS