#include "QtWidgets/QInputDialog/qinputdialog_wrap.h"

#include <QDebug>
#include <QLineEdit>
#include <QWidget>

#include "Extras/Utils/nutils.h"
#include "QtCore/QObject/qobject_wrap.h"
#include "QtWidgets/QWidget/qwidget_wrap.h"

Napi::FunctionReference QInputDialogWrap::constructor;

Napi::Object QInputDialogWrap::init(Napi::Env env, Napi::Object exports) {
  Napi::HandleScope scope(env);
  char CLASSNAME[] = "QInputDialog";
  Napi::Function func = DefineClass(
      env, CLASSNAME,
      {InstanceMethod("setCancelButtonText",
                      &QInputDialogWrap::setCancelButtonText),
       InstanceMethod("cancelButtonText", &QInputDialogWrap::cancelButtonText),
       InstanceMethod("setComboBoxEditable",
                      &QInputDialogWrap::setComboBoxEditable),
       InstanceMethod("isComboBoxEditable",
                      &QInputDialogWrap::isComboBoxEditable),
       InstanceMethod("setDoubleDecimals",
                      &QInputDialogWrap::setDoubleDecimals),
       InstanceMethod("doubleDecimals", &QInputDialogWrap::doubleDecimals),
       InstanceMethod("setDoubleMaximum", &QInputDialogWrap::setDoubleMaximum),
       InstanceMethod("doubleMaximum", &QInputDialogWrap::doubleMaximum),
       InstanceMethod("setDoubleMinimum", &QInputDialogWrap::setDoubleMinimum),
       InstanceMethod("doubleMinimum", &QInputDialogWrap::doubleMinimum),
       InstanceMethod("doubleStep", &QInputDialogWrap::doubleStep),
       InstanceMethod("setDoubleStep", &QInputDialogWrap::setDoubleStep),
       InstanceMethod("doubleValue", &QInputDialogWrap::doubleValue),
       InstanceMethod("setDoubleValue", &QInputDialogWrap::setDoubleValue),
       InstanceMethod("inputMode", &QInputDialogWrap::inputMode),
       InstanceMethod("setInputMode", &QInputDialogWrap::setInputMode),
       InstanceMethod("intMaximum", &QInputDialogWrap::intMaximum),
       InstanceMethod("setIntMaximum", &QInputDialogWrap::setIntMaximum),
       InstanceMethod("intMinimum", &QInputDialogWrap::intMinimum),
       InstanceMethod("setIntMinimum", &QInputDialogWrap::setIntMinimum),
       InstanceMethod("intStep", &QInputDialogWrap::intStep),
       InstanceMethod("setIntStep", &QInputDialogWrap::setIntStep),
       InstanceMethod("intValue", &QInputDialogWrap::intValue),
       InstanceMethod("setIntValue", &QInputDialogWrap::setIntValue),
       InstanceMethod("labelText", &QInputDialogWrap::labelText),
       InstanceMethod("setLabelText", &QInputDialogWrap::setLabelText),
       InstanceMethod("okButtonText", &QInputDialogWrap::okButtonText),
       InstanceMethod("setOkButtonText", &QInputDialogWrap::setOkButtonText),
       InstanceMethod("options", &QInputDialogWrap::options),
       InstanceMethod("setOptions", &QInputDialogWrap::setOptions),
       InstanceMethod("textEchoMode", &QInputDialogWrap::textEchoMode),
       InstanceMethod("setTextEchoMode", &QInputDialogWrap::setTextEchoMode),
       InstanceMethod("textValue", &QInputDialogWrap::textValue),
       InstanceMethod("setTextValue", &QInputDialogWrap::setTextValue),
       QDIALOG_WRAPPED_METHODS_EXPORT_DEFINE(QInputDialogWrap)});
  constructor = Napi::Persistent(func);
  exports.Set(CLASSNAME, func);
  QOBJECT_REGISTER_WRAPPER(QInputDialog, QInputDialogWrap);
  return exports;
}

QInputDialog* QInputDialogWrap::getInternalInstance() { return this->instance; }

QInputDialogWrap::~QInputDialogWrap() {
  extrautils::safeDelete(this->instance);
}

QInputDialogWrap::QInputDialogWrap(const Napi::CallbackInfo& info)
    : Napi::ObjectWrap<QInputDialogWrap>(info) {
  Napi::Env env = info.Env();
  size_t argCount = info.Length();
  if (argCount == 0) {
    // --- Construct a new instance
    this->instance = new NInputDialog();
  } else if (argCount == 1) {
    if (info[0].IsExternal()) {
      // --- Wrap a given C++ instance
      this->instance = info[0].As<Napi::External<QInputDialog>>().Data();
    } else {
      // --- Construct a new instance and pass a parent
      Napi::Object parentObject = info[0].As<Napi::Object>();
      NodeWidgetWrap* parentWidgetWrap =
          Napi::ObjectWrap<NodeWidgetWrap>::Unwrap(parentObject);
      this->instance =
          new NInputDialog(parentWidgetWrap->getInternalInstance());
    }
  } else {
    Napi::TypeError::New(
        env,
        "NodeGui: QInputDialogWrap: Wrong number of arguments to constructor")
        .ThrowAsJavaScriptException();
  }
  this->rawData =
      extrautils::configureQWidget(this->getInternalInstance(), false);
}

Napi::Value QInputDialogWrap::setCancelButtonText(
    const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto value = info[0].As<Napi::String>().Utf8Value().c_str();
  this->instance->setCancelButtonText(value);
  return env.Null();
}
Napi::Value QInputDialogWrap::cancelButtonText(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto retValue = this->instance->cancelButtonText().toStdString();
  return Napi::Value::From(env, retValue);
}
Napi::Value QInputDialogWrap::setComboBoxEditable(
    const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto value = info[0].As<Napi::Boolean>().Value();
  this->instance->setComboBoxEditable(value);
  return env.Null();
}
Napi::Value QInputDialogWrap::isComboBoxEditable(
    const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto retValue = this->instance->isComboBoxEditable();
  return Napi::Value::From(env, retValue);
}
Napi::Value QInputDialogWrap::setDoubleDecimals(
    const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto value = info[0].As<Napi::Number>().DoubleValue();
  this->instance->setDoubleDecimals(value);
  return env.Null();
}
Napi::Value QInputDialogWrap::doubleDecimals(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto retValue = this->instance->doubleDecimals();
  return Napi::Value::From(env, retValue);
}
Napi::Value QInputDialogWrap::setDoubleMaximum(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto value = info[0].As<Napi::Number>().DoubleValue();
  this->instance->setDoubleMaximum(value);
  return env.Null();
}
Napi::Value QInputDialogWrap::doubleMaximum(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto retValue = this->instance->doubleMaximum();
  return Napi::Value::From(env, retValue);
}
Napi::Value QInputDialogWrap::setDoubleMinimum(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto value = info[0].As<Napi::Number>().DoubleValue();
  this->instance->setDoubleMinimum(value);
  return env.Null();
}
Napi::Value QInputDialogWrap::doubleMinimum(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto retValue = this->instance->doubleMinimum();
  return Napi::Value::From(env, retValue);
}
Napi::Value QInputDialogWrap::doubleStep(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto retValue = this->instance->doubleStep();
  return Napi::Value::From(env, retValue);
}
Napi::Value QInputDialogWrap::setDoubleStep(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto value = info[0].As<Napi::Number>().DoubleValue();
  this->instance->setDoubleStep(value);
  return env.Null();
}
Napi::Value QInputDialogWrap::doubleValue(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto retValue = this->instance->doubleValue();
  return Napi::Value::From(env, retValue);
}
Napi::Value QInputDialogWrap::setDoubleValue(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto value = info[0].As<Napi::Number>().DoubleValue();
  this->instance->setDoubleValue(value);
  return env.Null();
}
Napi::Value QInputDialogWrap::inputMode(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto retValue = this->instance->inputMode();
  return Napi::Value::From(env, static_cast<int>(retValue));
}
Napi::Value QInputDialogWrap::setInputMode(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto value = info[0].As<Napi::Number>().Int32Value();
  this->instance->setInputMode(static_cast<QInputDialog::InputMode>(value));
  return env.Null();
}
Napi::Value QInputDialogWrap::intMaximum(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto retValue = this->instance->intMaximum();
  return Napi::Value::From(env, retValue);
}
Napi::Value QInputDialogWrap::setIntMaximum(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto value = info[0].As<Napi::Number>().Int32Value();
  this->instance->setIntMaximum(value);
  return env.Null();
}
Napi::Value QInputDialogWrap::intMinimum(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto retValue = this->instance->intMinimum();
  return Napi::Value::From(env, retValue);
}
Napi::Value QInputDialogWrap::setIntMinimum(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto value = info[0].As<Napi::Number>().Int32Value();
  this->instance->setIntMinimum(value);
  return env.Null();
}
Napi::Value QInputDialogWrap::intStep(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto retValue = this->instance->intStep();
  return Napi::Value::From(env, retValue);
}
Napi::Value QInputDialogWrap::setIntStep(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto value = info[0].As<Napi::Number>().Int32Value();
  this->instance->setIntStep(value);
  return env.Null();
}
Napi::Value QInputDialogWrap::intValue(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto retValue = this->instance->intValue();
  return Napi::Value::From(env, retValue);
}
Napi::Value QInputDialogWrap::setIntValue(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto value = info[0].As<Napi::Number>().Int32Value();
  this->instance->setIntValue(value);
  return env.Null();
}
Napi::Value QInputDialogWrap::labelText(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto retValue = this->instance->labelText().toStdString();
  return Napi::Value::From(env, retValue);
}
Napi::Value QInputDialogWrap::setLabelText(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto value = info[0].As<Napi::String>().Utf8Value().c_str();
  this->instance->setLabelText(value);
  return env.Null();
}
Napi::Value QInputDialogWrap::okButtonText(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto retValue = this->instance->okButtonText().toStdString();
  return Napi::Value::From(env, retValue);
}
Napi::Value QInputDialogWrap::setOkButtonText(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto value = info[0].As<Napi::String>().Utf8Value().c_str();
  this->instance->setOkButtonText(value);
  return env.Null();
}
Napi::Value QInputDialogWrap::options(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto retValue = this->instance->options();
  return Napi::Value::From(env, static_cast<int>(retValue));
}
Napi::Value QInputDialogWrap::setOptions(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto value = info[0].As<Napi::Number>().Int32Value();
  this->instance->setOptions(
      static_cast<QInputDialog::InputDialogOptions>(value));
  return env.Null();
}
Napi::Value QInputDialogWrap::textEchoMode(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto retValue = this->instance->textEchoMode();
  return Napi::Value::From(env, static_cast<int>(retValue));
}
Napi::Value QInputDialogWrap::setTextEchoMode(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto value = info[0].As<Napi::Number>().Int32Value();
  this->instance->setTextEchoMode(static_cast<QLineEdit::EchoMode>(value));
  return env.Null();
}
Napi::Value QInputDialogWrap::textValue(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto retValue = this->instance->textValue().toStdString();
  return Napi::Value::From(env, retValue);
}
Napi::Value QInputDialogWrap::setTextValue(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  auto value = info[0].As<Napi::String>().Utf8Value().c_str();
  this->instance->setTextValue(value);
  return env.Null();
}