#pragma once

#include <maya/MPxNode.h>
#include <maya/MTypeId.h>
#include <maya/MString.h>
#include <vector>
#include <map>
#include <string>

// Forward declarations
class MObject;
class MPlug;
class MDataBlock;
class MStatus;

// Data structure definitions
using BlendshapeFrame = std::map<std::string, float>;
using BlendshapeCache = std::vector<BlendshapeFrame>;

class Video2ARKitNode : public MPxNode
{
public:
    Video2ARKitNode();
    virtual ~Video2ARKitNode() override;

    virtual MStatus compute(const MPlug& plug, MDataBlock& data) override;

    static void* creator();
    static MStatus initialize();

public:
    // Unique node ID
    static MTypeId id;

    // Node Attributes
    static MObject videoPath;
    static MObject currentTime;
    static MObject enable;
    static MObject outputBlendshapes;

    // Individual Blendshape Attributes
    static MObject browDownLeft, browDownRight, browInnerUp, browOuterUpLeft, browOuterUpRight, cheekPuff,
                   cheekSquintLeft, cheekSquintRight, eyeBlinkLeft, eyeBlinkRight, eyeLookDownLeft, eyeLookDownRight,
                   eyeLookInLeft, eyeLookInRight, eyeLookOutLeft, eyeLookOutRight, eyeLookUpLeft, eyeLookUpRight,
                   eyeSquintLeft, eyeSquintRight, eyeWideLeft, eyeWideRight, jawForward, jawLeft, jawOpen, jawRight,
                   mouthClose, mouthDimpleLeft, mouthDimpleRight, mouthFrownLeft, mouthFrownRight, mouthFunnel,
                   mouthLowerDownLeft, mouthLowerDownRight, mouthPressLeft, mouthPressRight, mouthPucker, mouthRight,
                   mouthRollLower, mouthRollUpper, mouthShrugLower, mouthShrugUpper, mouthSmileLeft, mouthSmileRight,
                   mouthStretchLeft, mouthStretchRight, mouthUpperUpLeft, mouthUpperUpRight, noseSneerLeft, noseSneerRight;

private:
    // This cache implementation is static. This means all nodes of this type will
    // share the same cache. For this specific use case (one video driving one rig),
    // this is a simple and effective approach.
    static BlendshapeCache m_blendshapeCache;
    static MString m_cachedVideoPath;
};
