//=========================================================================
//  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_attribute_Attribute_h
#define pybind_attribute_Attribute_h

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

#include "smtk/attribute/Attribute.h"
#include "smtk/attribute/FileItem.h"
#include "smtk/attribute/IntItem.h"
#include "smtk/attribute/MeshSelectionItem.h"
#include "smtk/attribute/StringItem.h"

#include "smtk/common/pybind11/PybindUUIDTypeCaster.h"

namespace py = pybind11;

void pybind11_init_smtk_attribute_MeshModifyMode(py::module &m)
{
  py::enum_<smtk::attribute::MeshModifyMode>(m, "MeshModifyMode")
    .value("NONE", smtk::attribute::MeshModifyMode::NONE)
    .value("RESET", smtk::attribute::MeshModifyMode::RESET)
    .value("MERGE", smtk::attribute::MeshModifyMode::MERGE)
    .value("SUBTRACT", smtk::attribute::MeshModifyMode::SUBTRACT)
    .value("ACCEPT", smtk::attribute::MeshModifyMode::ACCEPT)
    .value("NUM_OF_MODIFYMODES", smtk::attribute::MeshModifyMode::NUM_OF_MODIFYMODES)
    .export_values();
}

void pybind11_init_smtk_attribute_Attribute(py::module &m)
{
  py::class_<smtk::attribute::Attribute, std::shared_ptr<smtk::attribute::Attribute> > instance(m, "Attribute");
  instance
    .def(py::init<::smtk::attribute::Attribute const &>())
    .def("deepcopy", (smtk::attribute::Attribute & (smtk::attribute::Attribute::*)(::smtk::attribute::Attribute const &)) &smtk::attribute::Attribute::operator=)
    .def_property("appliesToInteriorNodes", &smtk::attribute::Attribute::appliesToInteriorNodes, &smtk::attribute::Attribute::setAppliesToInteriorNodes)
    .def_property("appliesToBoundaryNodes", &smtk::attribute::Attribute::appliesToBoundaryNodes, &smtk::attribute::Attribute::setAppliesToBoundaryNodes)
    .def_property("userData", &smtk::attribute::Attribute::userData, &smtk::attribute::Attribute::setUserData)
    // .def_static("New", &smtk::attribute::Attribute::New, py::arg("myName"), py::arg("myDefinition"))
    // .def_static("New", &smtk::attribute::Attribute::New, py::arg("myName"), py::arg("myDefinition"), py::arg("myId"))
    .def("associateEntity", (bool (smtk::attribute::Attribute::*)(::smtk::common::UUID const &)) &smtk::attribute::Attribute::associateEntity)
    .def("associateEntity", (bool (smtk::attribute::Attribute::*)(::smtk::model::EntityRef const &)) &smtk::attribute::Attribute::associateEntity)
    .def("associatedModelEntityIds", &smtk::attribute::Attribute::associatedModelEntityIds)
    .def("associations", (smtk::attribute::ConstModelEntityItemPtr (smtk::attribute::Attribute::*)() const) &smtk::attribute::Attribute::associations)
    .def("associations", (smtk::attribute::ModelEntityItemPtr (smtk::attribute::Attribute::*)()) &smtk::attribute::Attribute::associations)
    .def("clearAllUserData", &smtk::attribute::Attribute::clearAllUserData)
    .def("clearUserData", &smtk::attribute::Attribute::clearUserData, py::arg("key"))
    .def("color", &smtk::attribute::Attribute::color)
    .def("definition", &smtk::attribute::Attribute::definition)
    .def("disassociateEntity", (void (smtk::attribute::Attribute::*)(::smtk::common::UUID const &, bool)) &smtk::attribute::Attribute::disassociateEntity)
    .def("disassociateEntity", (void (smtk::attribute::Attribute::*)(::smtk::model::EntityRef const &, bool)) &smtk::attribute::Attribute::disassociateEntity)
    .def("find", (smtk::attribute::ItemPtr (smtk::attribute::Attribute::*)(::std::string const &, ::smtk::attribute::SearchStyle)) &smtk::attribute::Attribute::find, py::arg("name"), py::arg("style") = smtk::attribute::ACTIVE_CHILDREN)
    .def("find", (smtk::attribute::ConstItemPtr (smtk::attribute::Attribute::*)(::std::string const &, ::smtk::attribute::SearchStyle) const) &smtk::attribute::Attribute::find, py::arg("name"), py::arg("style") = smtk::attribute::ACTIVE_CHILDREN)
    .def("findDirectory", (smtk::attribute::DirectoryItemPtr (smtk::attribute::Attribute::*)(::std::string const &)) &smtk::attribute::Attribute::findDirectory)
    .def("findDirectory", (smtk::attribute::ConstDirectoryItemPtr (smtk::attribute::Attribute::*)(::std::string const &) const) &smtk::attribute::Attribute::findDirectory)
    .def("findDouble", (smtk::attribute::DoubleItemPtr (smtk::attribute::Attribute::*)(::std::string const &)) &smtk::attribute::Attribute::findDouble)
    .def("findDouble", (smtk::attribute::ConstDoubleItemPtr (smtk::attribute::Attribute::*)(::std::string const &) const) &smtk::attribute::Attribute::findDouble)
    .def("findFile", (smtk::attribute::FileItemPtr (smtk::attribute::Attribute::*)(::std::string const &)) &smtk::attribute::Attribute::findFile)
    .def("findFile", (smtk::attribute::ConstFileItemPtr (smtk::attribute::Attribute::*)(::std::string const &) const) &smtk::attribute::Attribute::findFile)
    .def("findGroup", (smtk::attribute::GroupItemPtr (smtk::attribute::Attribute::*)(::std::string const &)) &smtk::attribute::Attribute::findGroup)
    .def("findGroup", (smtk::attribute::ConstGroupItemPtr (smtk::attribute::Attribute::*)(::std::string const &) const) &smtk::attribute::Attribute::findGroup)
    .def("findInt", (smtk::attribute::IntItemPtr (smtk::attribute::Attribute::*)(::std::string const &)) &smtk::attribute::Attribute::findInt)
    .def("findInt", (smtk::attribute::ConstIntItemPtr (smtk::attribute::Attribute::*)(::std::string const &) const) &smtk::attribute::Attribute::findInt)
    .def("findMesh", (smtk::attribute::MeshItemPtr (smtk::attribute::Attribute::*)(::std::string const &)) &smtk::attribute::Attribute::findMesh)
    .def("findMesh", (smtk::attribute::ConstMeshItemPtr (smtk::attribute::Attribute::*)(::std::string const &) const) &smtk::attribute::Attribute::findMesh)
    .def("findMeshSelection", (smtk::attribute::MeshSelectionItemPtr (smtk::attribute::Attribute::*)(::std::string const &)) &smtk::attribute::Attribute::findMeshSelection)
    .def("findMeshSelection", (smtk::attribute::ConstMeshSelectionItemPtr (smtk::attribute::Attribute::*)(::std::string const &) const) &smtk::attribute::Attribute::findMeshSelection)
    .def("findModelEntity", (smtk::attribute::ModelEntityItemPtr (smtk::attribute::Attribute::*)(::std::string const &)) &smtk::attribute::Attribute::findModelEntity)
    .def("findModelEntity", (smtk::attribute::ConstModelEntityItemPtr (smtk::attribute::Attribute::*)(::std::string const &) const) &smtk::attribute::Attribute::findModelEntity)
    .def("findRef", (smtk::attribute::RefItemPtr (smtk::attribute::Attribute::*)(::std::string const &)) &smtk::attribute::Attribute::findRef)
    .def("findRef", (smtk::attribute::ConstRefItemPtr (smtk::attribute::Attribute::*)(::std::string const &) const) &smtk::attribute::Attribute::findRef)
    .def("findString", (smtk::attribute::StringItemPtr (smtk::attribute::Attribute::*)(::std::string const &)) &smtk::attribute::Attribute::findString)
    .def("findString", (smtk::attribute::ConstStringItemPtr (smtk::attribute::Attribute::*)(::std::string const &) const) &smtk::attribute::Attribute::findString)
    .def("findVoid", (smtk::attribute::VoidItemPtr (smtk::attribute::Attribute::*)(::std::string const &)) &smtk::attribute::Attribute::findVoid)
    .def("findVoid", (smtk::attribute::ConstVoidItemPtr (smtk::attribute::Attribute::*)(::std::string const &) const) &smtk::attribute::Attribute::findVoid)
    .def("id", &smtk::attribute::Attribute::id)
    .def("isA", &smtk::attribute::Attribute::isA, py::arg("def"))
    .def("isAboutToBeDeleted", &smtk::attribute::Attribute::isAboutToBeDeleted)
    .def("isColorSet", &smtk::attribute::Attribute::isColorSet)
    .def("isEntityAssociated", (bool (smtk::attribute::Attribute::*)(::smtk::common::UUID const &) const) &smtk::attribute::Attribute::isEntityAssociated)
    .def("isEntityAssociated", (bool (smtk::attribute::Attribute::*)(::smtk::model::EntityRef const &) const) &smtk::attribute::Attribute::isEntityAssociated)
    .def("isMemberOf", (bool (smtk::attribute::Attribute::*)(::std::string const &) const) &smtk::attribute::Attribute::isMemberOf)
    .def("isMemberOf", (bool (smtk::attribute::Attribute::*)(::std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > > const &) const) &smtk::attribute::Attribute::isMemberOf)
    .def("isValid", &smtk::attribute::Attribute::isValid)
    .def("item", &smtk::attribute::Attribute::item, py::arg("ith"))
    .def("itemAtPath", (smtk::attribute::ConstItemPtr (smtk::attribute::Attribute::*)(::std::string const &, ::std::string const &) const) &smtk::attribute::Attribute::itemAtPath)
    .def("itemAtPath", (smtk::attribute::ItemPtr (smtk::attribute::Attribute::*)(::std::string const &, ::std::string const &)) &smtk::attribute::Attribute::itemAtPath)
    .def("modelManager", &smtk::attribute::Attribute::modelManager)
    .def("name", &smtk::attribute::Attribute::name)
    .def("numberOfItems", &smtk::attribute::Attribute::numberOfItems)
    // .def("references", &smtk::attribute::Attribute::references, py::arg("list"))
    .def("references", [](const smtk::attribute::Attribute &a) { std::vector<smtk::attribute::ItemPtr> v; a.references(v); return v; })
    .def("removeAllAssociations", &smtk::attribute::Attribute::removeAllAssociations)
    .def("setColor", (void (smtk::attribute::Attribute::*)(double, double, double, double)) &smtk::attribute::Attribute::setColor)
    .def("setColor", (void (smtk::attribute::Attribute::*)(double const *)) &smtk::attribute::Attribute::setColor)
    .def("system", &smtk::attribute::Attribute::system)
    .def("type", &smtk::attribute::Attribute::type)
    .def("types", &smtk::attribute::Attribute::types)
    .def("unsetColor", &smtk::attribute::Attribute::unsetColor)
    ;
}

#endif
