$#include "mohodoc.h"

$#include "moholayer.h"

$#include "meshlayer.h"

$#include "imagelayer.h"

$#include "grouplayer.h"

$#include "bonelayer.h"

$#include "switchlayer.h"

$#include "particlelayer.h"

$#include "mesh3dlayer.h"

$#include "audiolayer.h"

$#include "notelayer.h"

/* tolua -o pkg_moho.cpp -H pkg_moho.h pkg_moho.lua_pkg */



/*

    This file is used to auto-generate Lua interfaces.

    If you make a change to this file, you must run the tolua command like so:

    In Terminal, go to the 'scripting' folder and type the following command:

    > python _make_pkg.py

*/




typedef int                int32;

typedef unsigned int    uint32;

typedef float            real;



typedef struct {

    int32        Font;

    LM_String    FontName;

    LM_String    Text;

    int32        Justification;

    bool        Fill;

    bool        Stroke;

    bool        OneFill;

    bool        CenterH;

    rgb_color    LineCol;

    rgb_color    FillCol;

    real        LineWidth;

    int32        Leading;

    int32        Kerning;

    bool        MakeLayer;

    LM_String    BalloonStyle;

    bool        BalloonFill;

    bool        BalloonStroke;

    int32        BalloonSize;

    real        BalloonLineWidth;

    rgb_color    BalloonLineCol;

    rgb_color    BalloonFillCol;

    bool        BalloonSizeProportional;

    LM_String    BalloonPoses;

    int32        TextSize;

    bool        BalloonFlipV;

    bool        BalloonFlipH;

}InsertTextParams;



module MOHO { // begin module



/************************************************************************************/

/*** Global Variables (most of this stuff is related to user preference settings) ***/



#define MING_VIEW_DIRECTOR

#define MING_VIEW_CAMERA

#define MING_VIEW_PANEL



class MohoGlobals {

    static rgb_color    BackCol, ElemCol, SelCol, InacCol, FillCol, LineCol;



    static int32        QualityFlags;

    static bool            NTSCSafe;

    static bool            HideOffscreen;

    static int32        PreferredFormat;

    static bool            ZoomBox;

    static bool            UseMasterAnimChannel;

    static bool            ScaleCompensation;

    static bool            GapFilling;

    static int32        CurveInterpretation;

    static int32        ImageSamplingMode;

    static bool            ConstructionCurvesOn;

    static InsertTextParams InsertText;

    static bool            UseSMPTE;

    static bool            UseDegreesInTimeline;

    static bool            AutoLockKeys;

    static bool            AutoNaming;

    static bool            InlineLayerNaming;

    static bool            MarkZero;

    static bool            DisableDrawingToolsNonZero;

    static bool            DisableAudioFeedback;

    static int32        DefaultInterp;



    static bool            GridOn;

    static bool            GridSnapping;

    static int32        GridSize;

    static bool            FrameSkipping;

    static int32        MingViewMode; // 0 director, 1 camera, 2 panel



    static int32        ProjWidth, ProjHeight;

    static real            ProjFPS;

    static int32        ProjStart, ProjEnd;

    static rgb_color    ProjBackCol;

    static bool            ProjDofEnabled;

    static real            ProjDofDistance;

    static real            ProjDofRange;

    static real            ProjDofBlur;

    static bool            ProjEnable3D;

    static bool            ProjDepthSort;

    static bool            ProjDistanceSort;

    static int32        ProjNoise;

    static int32        ProjRenderStyleFill;

    static int32        ProjRenderStyleLine;

    static int32        ProjRenderStyleLayer;



    static M_Shape        *NewShapeProperties;



    static real            CharWizLineWidth;



    static bool            MuteSoundtrack;

    static bool            RescaleSoundtrack;



    static bool            TopStatusBar;

    static bool            BeginnerMode;



    static bool            HideControlledBones;

};



/**********************************************************************/

/*** Anim Channels ***/



#define CHANNEL_UNKNOWN

#define CHANNEL_VAL

#define CHANNEL_VEC2

#define CHANNEL_COLOR

#define CHANNEL_BOOL

#define CHANNEL_STRING

#define CHANNEL_VEC3



#define INTERP_LINEAR

#define INTERP_SMOOTH

#define INTERP_EASE

#define INTERP_STEP

#define INTERP_NOISY

#define INTERP_CYCLE

#define INTERP_POSE

#define INTERP_EASE_IN

#define INTERP_EASE_OUT

#define INTERP_BEZIER



#define KEY_SELECTED



// val1 and val2 have specific meanings for different interpolation types

// INTERP_NOISY - val1 = noise amplitude        val2 = noise scale

//        good values: 0.1, 0.5

// INTERP_CYCLE - val1 = relative starting frame (count back this many frames and start again)

//        val2 = absolute starting frame (count back to exactly this frame, use -1 to ignore this field)

// INTERP_POSE - val1 = index to the pose

class InterpSetting {

    void Reset();



    real BezierOutAngle(int32 component);

    void SetBezierOutAngle(int32 component, real angle);

    real BezierInAngle(int32 component);

    void SetBezierInAngle(int32 component, real angle);

    

    real BezierOutPercentage(int32 component);

    void SetBezierOutPercentage(int32 component, real percent);

    real BezierInPercentage(int32 component);

    void SetBezierInPercentage(int32 component, real percent);



    int32    interpMode;

    real    val1, val2;

    int32    interval; // 1 to interpolate every frame, 2 to animate on 2's, 3 to animate on 3's, etc.

    int32    hold; // how many frames to hold the previous value before interpolating to the next

    int32    tags; // used for keyframe color, and possibly other stuff in the future

    uint8    flags;

};



class AnimChannel {

    int32 ChannelType();



    int32 CountKeys();

    int32 Duration();



    void Clear(int32 zeroFrame);

    void ClearAfter(int32 frame);

    void ClearBefore(int32 frame);



    void StoreValue();

    void AddKey(int32 when);

    void Reset(int32 when);



    bool HasKey(int32 when);

    int32 GetClosestKeyID(int32 when);

    void DeleteKey(int32 when);

    void DeleteKeyByID(int32 id);

    void SwapKeys(int32 id1, int32 id2);



    int32 GetKeyWhen(int32 id);

    void SetKeyWhen(int32 id, int32 when);

    void SetKeyWhenNoRestriction(int32 id, int32 when); // allow keyframes to be set before/after each other, or even on top of each other

    void MakeKeyframesConsistent(bool deleteDuplicates); // make sure the keyframes are all in order according to time, and remove any that overlap



    void SetKeyInterp(int32 when, int32 interpMode, real val1, real val2);

    void SetKeyInterpByID(int32 id, int32 interpMode, real val1, real val2);

    void SetKeyInterp(int32 when, InterpSetting &interp);

    void SetKeyInterpByID(int32 id, InterpSetting &interp);

    void GetKeyInterp(int32 when, InterpSetting &interp);

    void GetKeyInterpByID(int32 id, InterpSetting &interp);

    void GetKeyInterp(int32 when, int32 *interpMode, real *val1, real *val2);

    void GetKeyInterpByID(int32 id, int32 *interpMode, real *val1, real *val2);

    int32 GetKeyInterpMode(int32 when);

    int32 GetKeyInterpModeByID(int32 id);



    void SetKeySelected(int32 when, bool sel);

    bool IsKeySelected(int32 when);

    void SetKeySelectedByID(int32 id, bool sel);

    bool IsKeySelectedByID(int32 id);

};



class AnimVal : public AnimChannel {

    void SetValue(int32 when, real val);

    real GetValue(int32 when);

    

    void SetValueByID(int32 id, real val);

    real GetValueByID(int32 id);



    real    value;

};



class AnimVec2 : public AnimChannel {

    void SetValue(int32 when, LM_Vector2 val);

    LM_Vector2 GetValue(int32 when);

    

    void SetValueByID(int32 id, LM_Vector2 val);

    LM_Vector2 GetValueByID(int32 id);



    LM_Vector2    value;

};



class AnimColor : public AnimChannel {

    void SetValue(int32 when, LM_ColorVector val);

    void SetValue(int32 when, rgb_color val);

    LM_ColorVector GetValue(int32 when);

    

    void SetValueByID(int32 id, LM_ColorVector val);

    void SetValueByID(int32 id, rgb_color val);

    LM_ColorVector GetValueByID(int32 id);



    rgb_color    value;

};



class AnimBool : public AnimChannel {

    void SetValue(int32 when, bool val);

    bool GetValue(int32 when);

    

    void SetValueByID(int32 id, bool val);

    bool GetValueByID(int32 id);



    bool    value;

};



class AnimString : public AnimChannel {

    void SetValue(int32 when, const char *);

    const char *GetValue(int32 when);

    

    void SetValueByID(int32 id, const char *);

    const char *GetValueByID(int32 id);



    LM_String    value;

};



class AnimVec3 : public AnimChannel {

    void SetValue(int32 when, LM_Vector3 val);

    LM_Vector3 GetValue(int32 when);

    

    void SetValueByID(int32 id, LM_Vector3 val);

    LM_Vector3 GetValueByID(int32 id);



    LM_Vector3    value;

};



/**********************************************************************/

/*** Moho Layer ***/



#define LT_UNKNOWN

#define LT_VECTOR

#define LT_IMAGE

#define LT_GROUP

#define LT_BONE

#define LT_SWITCH

#define LT_PARTICLE

#define LT_NOTE

#define LT_3D

#define LT_AUDIO

#define LT_PATCH

#define LT_TEXT



#define LM_MASKED @ MM_MASKED

#define LM_NOTMASKED @ MM_NOTMASKED

#define LM_ADD_MASK @ MM_ADD_MASK

#define LM_SUB_MASK @ MM_SUB_MASK

#define LM_ADD_MASK_INVIS @ MM_ADD_MASK_INVIS

#define LM_SUB_MASK_INVIS @ MM_SUB_MASK_INVIS

#define LM_CLEAR_ADD_MASK @ MM_CLEAR_ADD_MASK

#define LM_CLEAR_ADD_MASK_INVIS @ MM_CLEAR_ADD_MASK_INVIS



#define LM_BM_NORMAL @ BM_NORMAL

#define LM_BM_MULTIPLY @ BM_MULTIPLY

#define LM_BM_SCREEN @ BM_SCREEN

#define LM_BM_OVERLAY @ BM_OVERLAY

#define LM_BM_ADD @ BM_ADD

#define LM_BM_DIFFERENCE @ BM_DIFFERENCE

#define LM_BM_HUE @ BM_HUE

#define LM_BM_SATURATION @ BM_SATURATION

#define LM_BM_COLOR @ BM_COLOR

#define LM_BM_LUMINOSITY @ BM_LUMINOSITY



#define LM_RS_FILL_NORMAL @ RS_FILL_NORMAL

#define LM_RS_FILL_NONE @ RS_FILL_NONE

#define LM_RS_FILL_BACKGROUND @ RS_FILL_BACKGROUND

#define LM_RS_FILL_BACKGROUND_SHOWTHROUGH @ RS_FILL_BACKGROUND_SHOWTHROUGH

#define LM_RS_FILL_CRAYON @ RS_FILL_CRAYON

#define LM_RS_FILL_HATCHED @ RS_FILL_HATCHED

#define LM_RS_FILL_PEN @ RS_FILL_PEN

#define LM_RS_FILL_CHALK @ RS_FILL_CHALK



#define LM_RS_LINE_NORMAL @ RS_LINE_NORMAL

#define LM_RS_LINE_NONE @ RS_LINE_NONE

#define LM_RS_LINE_BLACK @ RS_LINE_BLACK

#define LM_RS_LINE_SKETCHY @ RS_LINE_SKETCHY

#define LM_RS_LINE_CRAYON @ RS_LINE_CRAYON

#define LM_RS_LINE_PEN @ RS_LINE_PEN

#define LM_RS_LINE_CHALK @ RS_LINE_CHALK



#define LM_RS_LAYER_NORMAL @ RS_LAYER_NORMAL

#define LM_RS_LAYER_HEAVY_OUTLINE @ RS_LAYER_HEAVY_OUTLINE

#define LM_RS_LAYER_CUTOUT @ RS_LAYER_CUTOUT



#define LM_POSEBM_STANDARD @ RS_POSEBM_STANDARD

#define LM_POSEBM_RELATIVETODEFAULT @ RS_POSEBM_RELATIVETODEFAULT

#define LM_POSEBM_RELATIVETOCURRENT @ RS_POSEBM_RELATIVETOCURRENT



    

class MohoRenderStyle {

    MohoRenderStyle();

    ~MohoRenderStyle();



    MohoFillRenderStyle        fFillStyle;

    MohoLineRenderStyle        fLineStyle;

    MohoLayerRenderStyle    fLayerStyle;

};



class MohoLayerChannel {

    MohoLayerChannel();

    ~MohoLayerChannel();



    int32        channelID;

    LM_String    name;

    int32        subChannelCount;

    bool        selectionBased;

};



class MohoPhysicsOptions {

    MohoPhysicsOptions();

    ~MohoPhysicsOptions();



    bool        fPhysicsEnabled;

    bool        fStaticBody;

    bool        fSleeping;

    int32        fRespawnInterval;

    LM_Vector2    fInitialVelocity;



    real        fDensity;

    real        fFriction;

    real        fRestitution;



    bool        fPivotOnOrigin;

    bool        fEnableMotor;

    AnimVal        fMotorSpeed;

    real        fMotorTorque;

    

    bool        fForceObject;

    AnimVec2    fForceVector;

};





class MohoLayer {

    MohoLayer();

    ~MohoLayer();



    int32 LayerType();

    bool IsGroupType();

    bool IsBoneType();

    bool IsAudioType();



    void SetSecondarySelection(bool sel);

    bool SecondarySelection();



    const char *Name();

    void SetName(const char *name);

    

    const char *UUID();



    void ShowConstructionCurves(bool b);



    int32 CurFrame();

    void UpdateCurFrame(bool extended = false);



    bool HasAnimatedLayerEffects();

    void SetAnimatedLayerEffects(bool b);



    LM_Vector2 Origin();

    void SetOrigin(LM_Vector2 origin);

    void SetOriginWithTransformCorrection(LM_Vector2 origin);



    GroupLayer *Parent();

    SwitchLayer *AncestorSwitchLayer();

    MohoLayer *AncestorSwitchChild();



    int32 LayerParentBone();

    void SetLayerParentBone(int32 id);

    void DeleteParentBone(int32 boneID);



    bool IsVisible();

    void SetVisible(bool vis);



    bool IsRenderOnly();

    void SetRenderOnly(bool b);



    bool IsEditOnly();

    void SetEditOnly(bool b);



    bool HasScaleCompensation();

    void SetScaleCompensation(bool b);



    bool DoesRotateToFollow();

    void SetRotateToFollow(bool b);



    bool DoesFaceCamera();

    void SetFaceCamera(bool b);



    int32 MaskingMode();

    void SetMaskingMode(int32 mode);

    bool MaskExpansion();

    void SetMaskExpansion(bool b);



    int32 BlendingMode();

    void SetBlendingMode(int32 mode);



    bool IsImmuneToCamera();

    void SetImmuneToCamera(bool b);



    bool IsImmuneToDof();

    void SetImmuneToDof(bool b);



    const char *HsvImage();

    void SetHsvImage(const char *path);



    int32 TimingOffset();

    void SetTimingOffset(int32 timingOffset);

    int32 TotalTimingOffset();



    const char *LayerScript();

    void SetLayerScript(const char *path);

    void RunLayerScript();



    void GetLayerTransform(int frame, LM_Matrix *matrix, MohoDoc *doc);

    void GetFullTransform(int frame, LM_Matrix *matrix, MohoDoc *doc);

    void GetParentTransform(int frame, LM_Matrix *matrix, MohoDoc *doc);

    void GetParentBoneTransform(int32 frame, LM_Matrix *matrix, MohoDoc *doc);



    void AlignWithCamera(int32 frame, MohoDoc *doc);

    

    LM_BBox Bounds(int32 frame);

    

    int32 AnimDuration();

    int32 LayerDuration();

    void ClearAnimation(bool recursive, int32 fromFrame, bool before);

    void ResetAnimation(bool recursive, bool animatedChannelsOnly = false);

    void AddKey(int32 frame, bool recursive, bool animatedChannelsOnly);

    void ClearLayerKeyCount();

    int32 CountLayerKeys();

    int32 GetLayerKeyWhen(int32 keyID);



    int32 NumChannels @ CountChannels();

    void GetChannelInfo(int32 id, MohoLayerChannel *channelInfo);

    AnimChannel *Channel(int32 id, int32 subID, MohoDoc *doc);



    void CopyFrame(int32 fromFrame, int32 toFrame, bool recursive);

    void DeleteFrame(int32 frame, bool recursive);



    int32 CountPoses @ CountActions();

    const char *PoseName @ ActionName(int32 id);

    const char *CurrentPose @ CurrentAction();

    bool HasPose @ HasAction(const char *name);

    int32 GetPoseID @ ActionID(const char *name);

    bool IsSmartBonePose @ IsSmartBoneAction(const char *name);

    void ActivatePose @ ActivateAction(const char *name);

    void InsertPose @ InsertAction(const char *name, int32 frame, bool byReference);

    void RenamePose @ RenameAction(const char *oldName, const char *newName);

    void DeletePose @ DeleteAction(const char *name);

    void ReorderPose @ ReorderAction(const char *moveName, const char *placeAfterName);

    int32 PoseDuration @ ActionDuration(const char *name);

    void BlendPoses @ BlendActions(int32 frame, bool relativeToDefault, int32 numToBlend, LM_String names[numToBlend], real percentages[numToBlend]);

    void BlendPosesWithMode @ BlendActions(int32 frame, int32 blendMode, int32 numToBlend, LM_String names[numToBlend], real percentages[numToBlend], int32 frames[numToBlend]);



    void SetFollowingCurve(MohoLayer *layer, M_Curve *curve, real startingCurvePercentage, bool bendWithCurve);

    MohoLayer *GetFollowingLayer();

    M_Curve *GetFollowingCurve();



    bool IsPhysicsInEffect(int32 frame);

    GroupLayer *PhysicsParent(int32 frame);

    MohoPhysicsOptions *PhysicsOptions();



    void SetLocked(bool b);

    bool IsLocked();

    LM_Message *Metadata();



    // transforms

    AnimVec3    fTranslation;

    AnimVec3    fScale;

    AnimVal        fRotationX;

    AnimVal        fRotationY;

    AnimVal        fRotationZ;

    AnimBool    fFlipH;

    AnimBool    fFlipV;

    AnimVec3    fShear;

    AnimVal        fFollowing;

    AnimVec2    fPhysicsNudge;



    // layer effects

    AnimBool    fVisibility;

    AnimVal        fBlur;

    AnimVal        fAlpha;



    // layer shadow

    AnimBool    fLayerShadow;

    AnimVal        fShadowAngle;

    AnimVal        fShadowOffset;

    AnimVal        fShadowBlur;

    AnimVal        fShadowExpansion;

    AnimColor    fShadowColor;

    AnimVal        fShadowNoiseAmp, fShadowNoiseScale;



    // layer shading

    AnimBool    fLayerShading;

    AnimVal        fShadingAngle;

    AnimVal        fShadingOffset;

    AnimVal        fShadingBlur;

    AnimVal        fShadingContraction;

    AnimColor    fShadingColor;

    AnimVal        fShadingNoiseAmp, fShadingNoiseScale;



    // perspective shadow

    AnimBool    fPerspectiveShadow;

    AnimVal        fPerspectiveBlur;

    AnimVal        fPerspectiveScale;

    AnimVal        fPerspectiveShear;

    AnimColor    fPerspectiveColor;

    

    // motion blur

    AnimBool    fMotionBlur;

    AnimVal        fMotionBlurFrames;

    AnimVal        fMotionBlurSkip;

    AnimVal        fMotionBlurAlphaStart;

    AnimVal        fMotionBlurAlphaEnd;

    AnimVal        fMotionBlurRadius;



    // layer outline

    AnimBool    fLayerOutline;

    AnimVal        fOutlineWidth;

    AnimColor    fOutlineColor;

};



/**********************************************************************/

/*** Mesh Layer ***/



#define Mc_VECTOR3D_NONE @ VECTOR3D_NONE

#define Mc_VECTOR3D_EXTRUDE @ VECTOR3D_EXTRUDE

#define Mc_VECTOR3D_LATHE @ VECTOR3D_LATHE

#define Mc_VECTOR3D_INFLATE @ VECTOR3D_INFLATE



class MeshLayer : public MohoLayer {

    M_Mesh *Mesh();



    const char *FillTexture();

    void SetFillTexture(const char *path);

    const char *LineTexture();

    void SetLineTexture(const char *path);

    void Purge3DLayer();



    bool    fNoisyShapes, fNoisyLines, fAnimatedNoise, fExtraSketchy;

    real    fNoiseAmp, fNoiseScale;

    int32    fExtraLines;

    bool    fGapFilling;

    bool    fExcludeLinesFromMask;

    int32    f3DMode;

    Mesh3DOptions    f3DOptions;

};



/**********************************************************************/

/*** Audio Layer ***/



class AudioLayer : public MohoLayer {

    void SetAudioFile(const char *path);

    const char *AudioFile();

    real MaxAmplitude();

    real GetAmplitude(real startTime, real duration);

    real GetRMSAmplitude(real startTime, real duration);

    real GetMaxAmplitude(real startTime, real duration);

    void SetAudioText(const char *text);

    const char *AudioText();

    real MaxAmplitude();

    bool IsSilent();

    real GetAudioLevel(int32 frame);

    real GetStereoPosition(int32 frame);

    void SetSpatialPositioning(bool b);

    bool SpatialPositioning();

    real FrameToAudioTime(int32 frame, real frameDuration);



    AnimVal                fAudioLevel;

    AnimVal                fJumpToFrame;

};



/**********************************************************************/

/*** Note Layer ***/



class NoteLayer : public MohoLayer {

    const char *NoteText();

    void SetNoteText(const char *text);

};



/**********************************************************************/

/*** Image Layer ***/



class TrackingPoint {

public:

    const char *Name();

    void SetName(const char *str);

    int32 StartFrame();



    AnimVec2    fAnimPos;

    int32        fCompareRadius;

    int32        fSearchRadius;

    int32        fLastFrame;

    bool        fSelected;

};



#define LM_NEAREST_SAMP @ SM_NEAREST

#define LM_BILINEAR_SAMP @ SM_BILINEAR



class ImageLayer : public AudioLayer {

    void SetSourceImage(const char *path);

    const char *SourceImage();

    void SetAviAlpha(bool b);

    bool AviHasAlpha();

    void SetMovieLooping(bool b);

    bool MovieLooping();

    void SetReverseMovie(bool b);

    bool MovieReversed();

    bool IsMovieLayer();

    int32 MovieDuration();

    real MovieFps();

    void SetMovieFps(real fps);



    int32 PixelWidth();

    int32 PixelHeight();



    void ImageToLayer(LM_Vector2 pixel, LM_Vector2 &layer);

    void LayerToImage(LM_Vector2 layer, LM_Vector2 &pixel);



    void ClearMaskingPoints();

    void AddMaskingPoint(LM_Vector2 seedPt, int32 tolerance, bool reverseMask);

    void AdjustMaskingPointTolerance(int32 tolerance);

    void FinalizeMaskingPoint();



    int32 CountTrackingPoints();

    TrackingPoint *GetTrackingPoint(int32 id);

    TrackingPoint *AddTrackingPoint(LM_Vector2 pos, int32 frame);

    void DeleteSelectedTrackingPoints();

    void StartTracking(TrackingPoint *point);

    

    void SetToonEffect(bool b, int32 minEdgeThreshold, int32 maxEdgeThreshold, int32 grayThreshold, int32 blackThreshold, int32 saturation, int32 lightness, int32 quantizeLevels);

    bool HasToonEffect(int32 *minEdgeThreshold, int32 *maxEdgeThreshold, int32 *grayThreshold, int32 *blackThreshold, int32 *saturation, int32 *lightness, int32 *quantizeLevels);



    int32 SamplingMode();

    void SetSamplingMode(int32 mode);

};



/**********************************************************************/

/*** Group Layer ***/



#define GROUP_MASK_NONE

#define GROUP_MASK_SHOW_ALL

#define GROUP_MASK_HIDE_ALL



class GroupLayer : public MohoLayer {

    int32 CountLayers();

    MohoLayer *Layer(int32 id);

    MohoLayer *LayerByDepth(int32 id);

    MohoLayer *LayerByName(const char *name);

    bool IsLayerValid(MohoLayer *layer);

    bool IsLayerValid(const char *uuid);

    bool IsMyChild(MohoLayer *childLayer);



    bool IsExpanded();

    void Expand(bool b);



    int32 GetGroupMask();

    void SetGroupMask(int32 mask); // 0=none, 1=all visible, 2=all invisible



    bool IsDepthSorted();

    void SetDepthSorted(bool b);

    bool IsDistanceSorted();

    void SetDistanceSorted(bool b);

    bool IsLayerOrderingEnabled();

    void EnableLayerOrdering(bool b);

    bool IsLayerOrdered();

    AnimString *GetLayerOrdering();



    void EnablePhysics(int32 frame, bool b);

    bool IsPhysicsEnabled(int32 frame); // if frame is < 0, the return value is true if physics is *ever* enabled during the course of the animation

    int32 MostRecentPhysicsKeyframe(int32 frame); // returns the most recent keyframe (before or at the given frame) for physics enablement

    void SetPhysicsGravity(LM_Vector2 gravity);

    LM_Vector2 PhysicsGravity();

    bool MultiplePhysicsKeys();

    void UseBakedPhysics(bool b);

    bool UsingBakedPhysics();

    

    void FullDepthSort(MohoDoc *doc = NULL);

    void DepthSort(MohoDoc *doc = NULL);

};



/**********************************************************************/

/*** Bone Layer ***/



class BoneLayer : public GroupLayer {

    M_Skeleton *Skeleton();

};



/**********************************************************************/

/*** Switch Layer ***/



class SwitchLayer : public GroupLayer {

    const char *GetValue(int32 frame);

    void SetValue(int32 frame, const char *value);

    AnimString *SwitchValues();

    bool ContainsVisemes();

    const char *PhonemeToViseme(char phoneme);

    int32 RankViseme(const char *viseme);

    bool InterpMode();

    void SetInterpMode(bool b);

    void SetSourceFile(const char *path);

};



/**********************************************************************/

/*** Particle Layer ***/



class ParticleLayer : public GroupLayer {

    void FinalizeSettings();

    void SetRandomSeed(int32 seed);



    void SetNumParticles(int32 num, int32 displayNum);

    void GetNumParticles(int32 *num, int32 *displayNum);

    void SetLifetime(int32 lifetime);

    int32 Lifetime();

    void SetOrientation(bool orient);

    bool Orientation();

    void SetFreeFloating(bool freeFloating);

    bool FreeFloating();

    void SetEvenlySpaced(bool evenlySpaced);

    bool EvenlySpaced();

    void SetRandomStartTime(bool randomStartTime);

    bool RandomStartTime();

    void SetSourceDimensions(const LM_Vector3 &v);

    LM_Vector3 SourceDimensions();

    void SetDirection(real angle, real spread);

    void GetDirection(real *angle, real *spread);

    void SetVelocity(real v, real spread);

    void GetVelocity(real *v, real *spread);

    void SetDamping(real d);

    real Damping();

    void SetAcceleration(real angle, real rate);

    void GetAcceleration(real *angle, real *rate);

    void SetFullSpeedStart(bool b);

    bool FullSpeedStart();



    AnimBool *RunningTrack();

};



/**********************************************************************/

/*** Mesh3D Layer ***/



#define Mc_SHADING_NONE @ SHADING_NONE

#define Mc_SHADING_TOON @ SHADING_TOON

#define Mc_SHADING_HATCHED @ SHADING_HATCHED



class Mesh3DOptions {

public:

    // shading effects

    int32            fShadingMode;

    int32            fShadingDensity; // from 0 to 100

    rgb_color        fShadingColor;

    

    // edge rendering

    bool            fSilhouetteEdges, fMaterialEdges, fCreaseEdges;

    real            fCreaseAngle;

    real            fEdgeExtension;

    

    // other options

    bool            fBackfaceRemoval;

    bool            fResetZ;

};



class PoserActorGroup {

    int32 CountParameters();

    const char *ParameterName(int32 id);

    real ParameterMinVal(int32 id);

    real ParameterMaxVal(int32 id);

    AnimVal *Parameter(int32 id, bool createIfMissing);

    int32 PrimaryParameterID();



    LM_String    fFigureName;

    LM_String    fInternalName;

    LM_String    fExternalName;

    

    int32        fSelectedParameter;

};



class Mesh3DLayer : public MohoLayer {

    bool IsPoserLayer();

    void SetSourceMesh(const char *path);

    const char *SourceMesh();

    void SetEdgeOffset(real offset);

    real EdgeOffset();

    PoserActorGroup *GetPoserActorGroup(int32 id);

    void UpdatePoserParameters();

    void SetSelectedPoserActorGroup(int32 id);

    int32 SelectedPoserActorGroup();



    Mesh3DOptions    f3DOptions;

};



/**********************************************************************/

/*** Moho Document ***/



class MohoDoc {

    int32 CountLayers();

    MohoLayer *Layer(int id);

    MohoLayer *LayerByName(const char *name);

    bool IsLayerValid(MohoLayer *layer);

    bool IsLayerValid(const char *uuid);

    void ClearSecondarySelection(GroupLayer *group = NULL);

    int32 CountSelectedLayers(GroupLayer *group = NULL);

    MohoLayer *GetSelectedLayer(int32 id);

    int32 LayerID(MohoLayer *layer);

    int32 LayerAbsoluteID(MohoLayer *layer);

    MohoLayer *LayerByAbsoluteID(int32 id);

    MohoLayer *DuplicateLayer(MohoLayer *origLayer);



    char *Path();

    char *Name();



    void PrepUndo(MohoLayer *layer);

    void PrepMultiUndo();

    void Undo();

    void Redo();

    bool IsUndoable();

    bool IsRedoable();

    void SetDirty();



    int32 AnimDuration();



    int32 Width();

    int32 Height();

    void SetShape(int32 w, int32 h);

    real AspectRatio();



    int32 StartFrame();

    void SetStartFrame(int32 frame);

    int32 EndFrame();

    void SetEndFrame(int32 frame);



    real Fps();

    void SetFps(real fps);



    rgb_color BackCol();

    void SetBackCol(rgb_color col);



    int32 NoiseGrain();

    void SetNoiseGrain(int32 ng);



    bool Allow3D();

    void SetAllow3D(bool b);



    real StereoSeparation();

    void SetStereoSeparation(real ss);



    MohoRenderStyle *GlobalRenderStyle();



    bool IsOutsideViewEnabled();

    void GetOutsideViewMatrix(LM_Matrix *m);

    void GetCameraMatrix(int32 frame, LM_Matrix *m);

    LM_Vector3 GetCameraDirection();



    int32 CountStyles();

    M_Style *Style(int32 id);

    M_Style *Style(const char *styleName);

    void AddStyle(M_Style *style);

    void RemoveStyle(M_Style *style, MohoLayer *layer = NULL);

    void RelinkStyles(MohoLayer *layer = NULL);

    void RenameStyle(const char *oldName, const char *newName, MohoLayer *layer = NULL);

    bool IsStyleUsed(M_Style *style, MohoLayer *layer = NULL);



    void DepthSort();



    // camera

    AnimVec3        fCameraTrack;

    AnimVal            fCameraZoom;

    AnimVal            fCameraRoll;

    AnimVec2        fCameraPanTilt;

};



/**********************************************************************/

/*** Vector Mesh ***/



#define Mc_DEFAULT_CURVATURE @ SMOOTH

#define Mc_PEAK_CURVATURE @ PEAKED

#define Mc_CURVE_INTERP_LEGACY @ CURVE_INTERP_LEGACY

#define Mc_CURVE_INTERP_V7 @ CURVE_INTERP_V7



class M_Point {

    int32 GetNumCurves @ CountCurves();

    M_Curve *GetCurve @ Curve(int32 id, int32 *where);

    bool IsPointOnCurve(int32 curveID, int32 where = -1);



    void SetPos(LM_Vector2 pos, int32 frame);

    void SetCurvature(real curvature, int32 frame);

    bool IsEndpoint();

    void GetEndpointEdge(int32 *curveID, int32 *segID);



    bool        fSelected;

    bool        fPrevSelected;

    LM_Vector2    fPos;

    LM_Vector2    fTempPos;

    AnimVec2    fAnimPos;

    AnimVal        fWidth;

    real        fTempWidth;

    int32        fParent;

};



class M_Curve {

    int32 GetNumPoints @ CountPoints();

    M_Point *GetPoint @ Point(int32 id);

    AnimVal *GetCurvature @ Curvature(int32 id);



    int32 GetNumSegments @ CountSegments();

    bool IsSegmentSelected(int32 segID);

    bool IsPointOnSegment(int32 ptID, int32 segID);

    

    void GetControlPoints(int32 segID, LM_Vector2 *p1, LM_Vector2 *p2, LM_Vector2 *p3, LM_Vector2 *p4, bool forDrawing = false);



    bool IsSegmentOn(int32 segID);

    void SetSegmentOn(int32 segID, bool b);



    real GetCurvature(int32 ptID, int32 frame);

    void SetCurvature(int32 ptID, real curvature, int32 frame);



    LM_Vector2 PointOnSegment(int32 segID, real percent, bool forDrawing = false);

    LM_Vector2 ClosestPointOnSegment(int32 segID, LM_Vector2 vec, bool forDrawing = false);



    bool IsSelected();

    bool IsPartiallySelected();

    real CurveLength();

    real SegmentLength(int32 segID);

    LM_Vector2 GetPercentLocation(real percent);

    LM_Vector2 GetPercentTangent(real percent);

    void GetSegmentRange(int32 segID, real *startPercent, real *endPercent);



    void SetProfileCurve(MohoLayer *layer, M_Curve *curve);



    bool        fClosed;

    AnimVal        fStartPercent;

    AnimVal        fEndPercent;

    int32        fProfileRepeat;

};



class M_Style {

    void SetSoftEdge(real radius);

    void SetShading(real angle, real offset, real blur, rgb_color color);

    void SetShadow(real angle, real offset, real blur, rgb_color color);

    void SetHalo(real haloRadius, real blurRadius, rgb_color haloColor, bool haloOnly);

    

    void SetStrokeSoftEdge(real radius);

    void SetStrokeHalo(real haloRadius, real blurRadius, rgb_color haloColor, bool haloOnly);



    LM_String        fName;



    bool            fDefineFillCol;

    AnimColor        fFillCol;



    bool            fDefineLineWidth;

    real            fLineWidth;



    bool            fDefineLineCol;

    AnimColor        fLineCol;



    int32            fLineCaps; // 0 - none, 1 - round



    LM_String        fBrushName;

    bool            fBrushIsColor;

    bool            fBrushAlign;

    real            fBrushJitter;

    real            fBrushSpacing;

    bool            fBrushRandomize;

    bool            fBrushTint;

};



class M_Shape {

    const char *Name();

    void SetName(const char *name);

    int32 GetNumEdges @ CountEdges();

    void GetEdge(int32 edgeID, int32 *curveID, int32 *segID);

    bool ContainsEdge(int32 curveID, int32 segID);

    bool ContainsPoint(int32 pointID);



    bool AllPointsSelected();

    void ShapeBounds(LM_Vector2 *min, LM_Vector2 *max);

    void ShapeBounds(LM_Vector2 *min, LM_Vector2 *max, int32 frame);

    LM_Vector2 ShapeCenter();

    LM_Vector2 EffectHandle1();

    LM_Vector2 EffectHandle2();

    void CopyStyleProperties(M_Shape *fromShape, bool skipFill = false, bool skipLine = false);

    void RemoveStyles();

    void MakePlain();

    bool HasPositionDependentStyles();



    bool        fSelected;

    bool        fHidden;



    LM_String    fName;



    bool        fHasFill;

    bool        fHasOutline;

    bool        fFillAllowed;



    AnimVal        fEffectScale;

    AnimVal        fEffectRotation;

    AnimVec2    fEffectOffset;

    AnimVal        f3DThickness;



    M_Style        fMyStyle;

    LM_String    fInheritedStyleName;

    M_Style        *fInheritedStyle;

    LM_String    fInheritedStyleName2;

    M_Style        *fInheritedStyle2;

};



class M_PointGroup {

    const char *GroupName @ Name();

    int32 GetNumPoints @ CountPoints();

    M_Point *GetPoint @ Point(int32 id);

    bool ContainsPointID(int32 id);

    void AddPointID(int32 id);



    LM_String    fName;

};



class M_Mesh {

    void Empty @ Clear();



    int32 CurveInterpretation();

    void SetCurveInterpretation(int32 interp);



    int32 GetNumPoints @ CountPoints();

    int32 GetNumCurves @ CountCurves();

    int32 GetNumShapes @ CountShapes();

    int32 GetNumGroups @ CountGroups();

    M_Point *GetPoint @ Point(int32 id);

    M_Curve *GetCurve @ Curve(int32 id);

    M_Shape *GetShape @ Shape(int32 id);

    M_Shape *GetShape @ ShapeByName(const char *name);

    M_PointGroup *GetGroup @ Group(int32 id);



    void AddPoint(LM_Vector2 &pos, int32 attachID, int32 frame);

    void AddPoint(LM_Vector2 &pos, int32 attachCurve, int32 attachSeg, int32 frame);

    void AddLonePoint(LM_Vector2 pos, int32 frame);

    void AppendPoint(LM_Vector2 pos, int32 frame);

    void DeletePoint(int32 id);

    bool WeldPoints(int32 movingID, int32 solidID, int32 frame);

    bool ArePointsAdjacent(int32 p1, int32 p2);

    void MakePointConsistentWithNeighbors(int32 id, int32 frame);

    void SimplifyCurve(int32 curveID, real angleTolerance);

    int32 IsCurveValid(M_Curve *curve);



    int32 ClosestPoint(LM_Vector2 &pos, int32 ignoreID = -1, int32 maxPointID = -1);

    LM_Vector2 SelectedCenter();

    void SelectedBounds(LM_Vector2 *min, LM_Vector2 *max);

    void PrepMovePoints();

    void TranslatePoints(LM_Vector2 &offset);

    void ScalePoints(real sx, real sy, LM_Vector2 ¢erVec);

    void RotatePoints(real angle, LM_Vector2 ¢erVec);

    void TransformPoints(LM_Vector2 &offset, real sx, real sy, real angle, LM_Vector2 ¢erVec);



    void SelectNone();

    void SelectAll();

    void SelectInverse();

    void SelectConnected();



    void DeleteEdge(int32 curveID, int32 segID, int32 frame);



    void DeleteShape(int32 id);

    void LowerShape(int32 id, bool toBottom);

    void RaiseShape(int32 id, bool toTop);



    void AddGroup(const char *name);

    void SelectGroup(const char *name);

    void DeleteGroup(const char *name);



    int32 GetPointID @ PointID(M_Point *point);

    int32 GetCurveID @ CurveID(M_Curve *curve);

    int32 GetShapeID @ ShapeID(M_Shape *shape);

    int32 GetGroupID @ GroupID(M_PointGroup *group);

};



/**********************************************************************/

/*** Skeletons and Bones ***/



#define Mc_FLEXI_BINDING @ FLEXI_BINDING

#define Mc_REGION_BINDING @ REGION_BINDING



class M_Bone {

    const char *Name();

    void SetName(const char *name);



    bool        fSelected;



    LM_String    fName;

    int32        fParent;

    int32        fAngleControlParent;

    real        fAngleControlScale;

    int32        fPosControlParent;

    LM_Vector2    fPosControlScale;

    int32        fScaleControlParent;

    real        fScaleControlScale;

    real        fLength;

    real        fStrength;

    real        fPhysicsRadius;

    bool        fPhysicsReturnToZero;

    AnimVal        fPhysicsMotorSpeed;

    real        fPhysicsTorque;

    bool        fPhysicsLockTip;

    LM_Vector2    fOffset;

    AnimVec2    fAnimPos;

    AnimVal        fAnimAngle;

    AnimVal        fAnimScale;

    bool        fConstraints;

    real        fMinConstraint;

    real        fMaxConstraint;



    LM_Vector2    fPos;

    real        fAngle;

    real        fScale;



    LM_Vector2    fTempPos;

    real        fTempLength;

    real        fTempAngle;

    real        fTempScale;



    AnimBool    fIKLock;

    AnimVec2    fIKParentTarget;

    AnimVal        fIKGlobalAngle;



    AnimBool    fBoneDynamics;

    real        fTorqueForce;

    real        fSpringForce;

    real        fDampingForce;



    LM_Matrix    fRestMatrix;

    LM_Matrix    fMovedMatrix;

    LM_Matrix    fPtMatrix;

};



class M_Skeleton {

    int32 GetNumBones @ CountBones();

    M_Bone *GetBone @ Bone(int32 id);

    M_Bone *GetBone @ BoneByName(const char *name);

    int32 GetBoneID @ BoneID(M_Bone *bone);

    int32 SelectedBoneID();



    void SelectNone();

    void SelectAll();

    void SelectInverse();

    void SelectConnected();



    void UpdateBoneMatrix(int32 id = -1);



    M_Bone *AddBone(int32 frame);

    void DeleteBone(int32 id, int32 recursion = 0);

    int32 CountBoneChildren(int32 id, bool ignoreControlledBones = false);

    int32 GetFirstChildBone(int32 id, bool ignoreControlledBones = false);

    bool IsBoneChild(int32 boneID, int32 childID);

    bool IsBoneParent(int32 boneID, int32 parentID);

    bool IsAncestorSelected(int32 id);



    int32 NearestBone(LM_Vector2 vec);



    void LockBone(int32 id, int32 frame);

    void UnlockBone(int32 id, int32 frame);



    void IKAngleSolver(int32 boneID, const LM_Vector2 &target, int32 iterMultiplier = 1);



    int32    fBindingMode;

};



/**********************************************************************/

/*** 3D Mesh ***/



class M_Face3D {

    int32        numP;

    int32        p1;

    int32        p2;

    int32        p3;

    int32        p4;

    int32        n1;

    int32        n2;

    int32        n3;

    int32        n4;

    int32        matID;

    LM_Vector3    normal;

    int32        groupTag;

};



class M_Material3D {

    LM_String        name;

    bool            selected;

    rgb_color        color;

    bool            drawEdges;

    rgb_color        edgeColor;

    real            edgeWidth;

    LM_Path            texturePath;

    LM_Path            opacityPath;

};



class M_Mesh3D {

    void Empty @ Clear();



    void SetDefaultColor(rgb_color col);

    rgb_color DefaultColor();

    void SetDefaultEdgeColor(rgb_color col);

    rgb_color DefaultEdgeColor();

    void SetDefaultEdgeWidth(real width);

    real DefaultEdgeWidth();



    void SetClockwise(bool b);

    bool Clockwise();



    int32 CountPoints();

    LM_Vector3 Point(int32 id);

    int32 AddPoint(LM_Vector3 &vec);

    int32 AddUniquePoint(LM_Vector3 &vec);

    void RemovePoint(int32 id);

    void SetPoint(int32 id, LM_Vector3 &vec);



    int32 CountNormals();

    LM_Vector3 Normal(int32 id);

    void AddNormal(LM_Vector3 &vec);

    void RemoveNormal(int32 id);

    void SetNormal(int32 id, LM_Vector3 &vec);

    void RebuildNormals(bool overrideExisting);

    

    int32 CountTexturePoints();

    LM_Vector2 TexturePoint(int32 id);

    void AddTexturePoint(LM_Vector2 &vec);

    void RemoveTexturePoint(int32 id);



    int32 CountFaces();

    M_Face3D *Face(int32 id);

    void AddFace(int32 p1, int32 p2, int32 p3);

    void AddFace(int32 p1, int32 p2, int32 p3, int32 p4);

    void RemoveFace(int32 id);



    int32 CountMaterials();

    M_Material3D *Material(int32 id);

    M_Material3D *CreateNewMaterial(const char *name=NULL);

    void AddMaterial(M_Material3D *m);

    void RemoveMaterial(int32 id);

    void SetCurMaterial(int32 id);



    void RebuildEdgeList();



    void ScaleToRadius(real r);

};



} // end MOHO module