#include "utils.h"

#include <maya/MDagPath.h>
#include <maya/MSelectionList.h>
#include <maya/MStatus.h>
#include <maya/MString.h>
#include <maya/MFnDagNode.h>
#include <maya/MItDependencyGraph.h>
#include <maya/MItDependencyNodes.h>
#include <maya/MStatus.h>

#include <string>
#include <type_traits>

MStatus GetMayaObject(std::string name, MObject &object)
{
    MSelectionList s_list;
    s_list.clear();
    s_list.add(name.c_str());
    return s_list.getDependNode(0, object);
};

MStatus GetMayaDagPath(std::string name, MDagPath &dagPath)
{
    MSelectionList s_list;
    s_list.clear();
    s_list.add(name.c_str());
    return s_list.getDagPath(0, dagPath);
};

MStatus GetMayaDagPath(MObject& object, MDagPath& dagPath)
{
    MSelectionList s_list;
    s_list.clear();
    s_list.add(object);
    return s_list.getDagPath(0, dagPath);
}

MObjectArray ListTypedNodes(MFn::Type filter)
{
    MStatus status;
    MObjectArray nodes;
    MItDependencyNodes iterNode(filter);
    iterNode.reset();
    while (!iterNode.isDone())
    {
        nodes.append(iterNode.item());
        iterNode.next();
    }
    return nodes;
}

MObjectArray GetTypeNodes(MObject rootNode,
                          MItDependencyGraph::Direction direction,
                          MFn::Type filter)
{
    MStatus status;
    MObjectArray nodeList;
    MItDependencyGraph iterDG(rootNode, filter,
                              direction,
                              MItDependencyGraph::kDepthFirst,
                              MItDependencyGraph::Level::kNodeLevel,
                              &status);
    iterDG.reset();
    while (!iterDG.isDone())
    {
        MObject item = iterDG.currentItem();
        if (item.isNull())
            continue;
        nodeList.append(item);
        iterDG.next();
    }
    return nodeList;
}

MObjectArray GetTypeNodes(MPlug rootPlug,
                          MItDependencyGraph::Direction direction,
                          MFn::Type filter)
{
    MStatus status;
    MObjectArray nodeList;
    MItDependencyGraph iterDG(rootPlug, filter,
                              direction,
                              MItDependencyGraph::kDepthFirst,
                              MItDependencyGraph::Level::kNodeLevel,
                              &status);
    iterDG.reset();
    while (!iterDG.isDone())
    {
        MObject item = iterDG.currentItem();
        if (item.isNull())
            continue;
        nodeList.append(item);
        iterDG.next();
    }
    return nodeList;
}

MObjectArray GetTypeNodes(MPlug rootPlug, MString nodeTypeName,
                          MItDependencyGraph::Direction direction,
                          MFn::Type filter)
{
    MStatus status;
    MObjectArray nodeList;
    MItDependencyGraph iterDG(rootPlug, filter,
                              direction,
                              MItDependencyGraph::kDepthFirst,
                              MItDependencyGraph::Level::kNodeLevel,
                              &status);
    iterDG.reset();
    while (!iterDG.isDone())
    {
        MObject item = iterDG.currentItem();
        if (item.isNull())
            continue;
        MFnDependencyNode fnNode(item);
        if (fnNode.typeName() == nodeTypeName)
        {
            nodeList.append(item);
        }
        iterDG.next();
    }
    return nodeList;
}


