//=========================================================================
//  Copyright (c) Kitware, Inc.
//  All rights reserved.
//  See LICENSE.txt for details.
//
//  This software is distributed WITHOUT ANY WARRANTY; without even
//  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
//  PURPOSE.  See the above copyright notice for more information.
//=========================================================================

#ifndef pybind_smtk_session_rgg_Core_h
#define pybind_smtk_session_rgg_Core_h

#include <pybind11/pybind11.h>

#include "smtk/session/rgg/Core.h"
#include "smtk/model/Group.h"
#include "smtk/session/rgg/json/jsonCore.h"
#include <pybind11/stl.h>

namespace py = pybind11;

py::class_< smtk::session::rgg::Core > pybind11_init_smtk_session_rgg_Core(py::module &m)
{
  py::class_< smtk::session::rgg::Core > instance(m, "Core");
  instance
    .def(py::init<>())
    .def(py::init<::smtk::session::rgg::Core const &>())
    .def(py::init([](smtk::model::Group& coreG)
        { return nlohmann::json::parse(coreG.stringProperty(smtk::session::rgg::Core::propDescription)[0]);}))
    .def("__eq__", (bool (smtk::session::rgg::Core::*)(::smtk::session::rgg::Core const &) const) &smtk::session::rgg::Core::operator==)
    .def("__ne__", (bool (smtk::session::rgg::Core::*)(::smtk::session::rgg::Core const &) const) &smtk::session::rgg::Core::operator!=)
    .def("deepcopy", (smtk::session::rgg::Core & (smtk::session::rgg::Core::*)(::smtk::session::rgg::Core const &)) &smtk::session::rgg::Core::operator=)
    .def("name", &smtk::session::rgg::Core::name)
    .def("geomType", &smtk::session::rgg::Core::geomType)
    .def("zOrigin", &smtk::session::rgg::Core::zOrigin)
    .def("height", &smtk::session::rgg::Core::height)
    .def("layout", (smtk::session::rgg::Core::UuidToSchema & (smtk::session::rgg::Core::*)()) &smtk::session::rgg::Core::layout)
    .def("layout", (smtk::session::rgg::Core::UuidToSchema const & (smtk::session::rgg::Core::*)() const) &smtk::session::rgg::Core::layout)
    .def("entityToCoordinates", (smtk::session::rgg::Core::UuidToCoordinates & (smtk::session::rgg::Core::*)()) &smtk::session::rgg::Core::entityToCoordinates)
    .def("entityToCoordinates", (smtk::session::rgg::Core::UuidToCoordinates const & (smtk::session::rgg::Core::*)() const) &smtk::session::rgg::Core::entityToCoordinates)
    .def("pinsAndDuctsToCoordinates", (smtk::session::rgg::Core::UuidToCoordinates & (smtk::session::rgg::Core::*)()) &smtk::session::rgg::Core::pinsAndDuctsToCoordinates)
    .def("pinsAndDuctsToCoordinates", (smtk::session::rgg::Core::UuidToCoordinates const & (smtk::session::rgg::Core::*)() const) &smtk::session::rgg::Core::pinsAndDuctsToCoordinates)
    .def("latticeSize", &smtk::session::rgg::Core::latticeSize)
    .def("ductThickness", &smtk::session::rgg::Core::ductThickness)
    .def("exportParams", (smtk::session::rgg::CoreExportParameters & (smtk::session::rgg::Core::*)()) &smtk::session::rgg::Core::exportParams)
    .def("exportParams", (smtk::session::rgg::CoreExportParameters const & (smtk::session::rgg::Core::*)() const) &smtk::session::rgg::Core::exportParams)
    .def("setName", &smtk::session::rgg::Core::setName, py::arg("name"))
    .def("setGeomType", &smtk::session::rgg::Core::setGeomType, py::arg("type"))
    .def("setZOrigin", &smtk::session::rgg::Core::setZOrigin, py::arg("zOrigin"))
    .def("setHeight", &smtk::session::rgg::Core::setHeight, py::arg("height"))
    .def("setLayout", &smtk::session::rgg::Core::setLayout, py::arg("layout"))
    .def("setEntityToCoordinates", &smtk::session::rgg::Core::setEntityToCoordinates, py::arg("uTC"))
    .def("setPinsAndDuctsToCoordinates", &smtk::session::rgg::Core::setPinsAndDuctsToCoordinates, py::arg("uTC"))
    .def("setDuctThickness", &smtk::session::rgg::Core::setDuctThickness, py::arg("t0"), py::arg("t1") = 0)
    .def("setLatticeSize", (void(smtk::session::rgg::Core::*)(const int&, const int&)) &smtk::session::rgg::Core::setLatticeSize, "Set the lattice size via two ints")
    .def("setLatticeSize", (void(smtk::session::rgg::Core::*)(const std::pair<int, int>&)) &smtk::session::rgg::Core::setLatticeSize, "Set the lattice size via a pair of int")
    .def("setExportParams", &smtk::session::rgg::Core::setExportParams, py::arg("aep"))
    .def_property_readonly_static("propDescription", [](py::object){ return std::string(smtk::session::rgg::Core::propDescription);})
    .def_property_readonly_static("typeDescription", [](py::object){ return std::string(smtk::session::rgg::Core::typeDescription);})
    .def_property_readonly_static("geomDescription", [](py::object){ return std::string(smtk::session::rgg::Core::geomDescription);})
    ;
  py::enum_<smtk::session::rgg::Core::GeomType>(instance, "GeomType")
    .value("Hex", smtk::session::rgg::Core::GeomType::Hex)
    .value("Rect", smtk::session::rgg::Core::GeomType::Rect)
    .export_values();
  py::class_< smtk::session::rgg::Core::GeomBase >(instance, "GeomBase")
    .def("deepcopy", (smtk::session::rgg::Core::GeomBase & (smtk::session::rgg::Core::GeomBase::*)(::smtk::session::rgg::Core::GeomBase const &)) &smtk::session::rgg::Core::GeomBase::operator=)
    .def("latticeSize", &smtk::session::rgg::Core::GeomBase::latticeSize)
    .def("ductThickness", &smtk::session::rgg::Core::GeomBase::ductThickness)
    .def("setLatticeSize", &smtk::session::rgg::Core::GeomBase::setLatticeSize, py::arg("size"))
    .def("setDuctThickness", &smtk::session::rgg::Core::GeomBase::setDuctThickness, py::arg("thicknesses"))
    .def_readwrite("zOrigin", &smtk::session::rgg::Core::GeomBase::zOrigin)
    .def_readwrite("height", &smtk::session::rgg::Core::GeomBase::height)
    ;
  py::class_< smtk::session::rgg::Core::GeomHex, smtk::session::rgg::Core::GeomBase >(instance, "GeomHex")
    .def(py::init<>())
    .def(py::init<double, double, int, double>())
    .def(py::init<::smtk::session::rgg::Core::GeomHex const &>())
    .def("deepcopy", (smtk::session::rgg::Core::GeomHex & (smtk::session::rgg::Core::GeomHex::*)(::smtk::session::rgg::Core::GeomHex const &)) &smtk::session::rgg::Core::GeomHex::operator=)
    .def("latticeSize", &smtk::session::rgg::Core::GeomHex::latticeSize)
    .def("ductThickness", &smtk::session::rgg::Core::GeomHex::ductThickness)
    .def("setLatticeSize", &smtk::session::rgg::Core::GeomHex::setLatticeSize, py::arg("size"))
    .def("setDuctThickness", &smtk::session::rgg::Core::GeomHex::setDuctThickness, py::arg("thicknesses"))
    .def_readwrite("ls", &smtk::session::rgg::Core::GeomHex::ls)
    .def_readwrite("ds", &smtk::session::rgg::Core::GeomHex::ds)
    ;
  py::class_< smtk::session::rgg::Core::GeomRect, smtk::session::rgg::Core::GeomBase >(instance, "GeomRect")
    .def(py::init<>())
    .def(py::init<double, double, int, int, double, double>())
    .def(py::init<::smtk::session::rgg::Core::GeomRect const &>())
    .def("deepcopy", (smtk::session::rgg::Core::GeomRect & (smtk::session::rgg::Core::GeomRect::*)(::smtk::session::rgg::Core::GeomRect const &)) &smtk::session::rgg::Core::GeomRect::operator=)
    .def("latticeSize", &smtk::session::rgg::Core::GeomRect::latticeSize)
    .def("ductThickness", &smtk::session::rgg::Core::GeomRect::ductThickness)
    .def("setLatticeSize", &smtk::session::rgg::Core::GeomRect::setLatticeSize, py::arg("size"))
    .def("setDuctThickness", &smtk::session::rgg::Core::GeomRect::setDuctThickness, py::arg("thicknesses"))
    .def_readwrite("ls", &smtk::session::rgg::Core::GeomRect::ls)
    .def_readwrite("ds", &smtk::session::rgg::Core::GeomRect::ds)
    ;
  return instance;
}

#endif
