$#include "lm_pkg_moho.h"

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



typedef int                int32;

typedef unsigned int    uint32;

typedef float            real;







module MOHO { // begin module



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

/*** Moho View ***/



class XGraphics : public LM_Graphics

{

};



class MohoView {

    void Refresh();

    void DrawMe();



    int32 QualityFlags();

    void SetQualityFlags(int32 qualityFlags);

    void SetTracingImage(const char *path);

    bool IsTracingEnabled();

    void TurnTracingOn(bool b);

    bool IsTracingOn();

    bool IsStereoEnabled();

    void TurnStereoOn(bool b);

    bool IsStereoOn();



    int32 PickPoint(LM_Point where, int32 pickWidth = 3);

    void PickEdge(LM_Point where, int32 *curveID, int32 *segID, int32 pickWidth = 3);

    LM_Point PickEdgeAlongLine(LM_Point lineEnd1, LM_Point lineEnd2, int32 *curveID, int32 *segID, int32 skipMinSegID, int32 skipMaxSegID);

    MohoLayer *PickGlobalEdge(LM_Point where, int32 *curveID, int32 *segID, int32 pickWidth = 3);

    int32 PickShape(LM_Point where, int32 noHigherThan = -1, int32 pickWidth = 3);

    int32 PickBone(LM_Point where, LM_Vector2 clickVec, MohoLayer *layer, bool exact, int32 pickWidth = 3);

    void FloodSelect(LM_Point where, int32 tolerance);

    M_Shape *PickGlobalShape(LM_Point where, int32 noHigherThan = -1, int32 pickWidth = 3);

    int32 PickFace(LM_Point where, int32 pickWidth = 3);

    MohoLayer *PickGlobalLayer(LM_Point where, int32 pickWidth = 3);



    LM_Vector2 Point2Vec(LM_Point where, LM_Matrix *layerM = NULL);



    XGraphics *Graphics();

    void ResetView(int32 mode = 2);



    // These may seem weird, but the purpose is to get exactly the same behavior as the right-drag versions

    void PanDown(LM_Point where);

    void PanMoved(LM_Point where);

    void PanUp(LM_Point where);



    void ZoomDown(LM_Point where);

    void ZoomMoved(LM_Point where);

    void ZoomUp(LM_Point where);



    void RotateDown(LM_Point where);

    void RotateMoved(LM_Point where);

    void RotateUp(LM_Point where);



    void OrbitDown(LM_Point where);

    void OrbitMoved(LM_Point where);

    void OrbitUp(LM_Point where);



    void DrawPreviewShape();

};



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

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



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 int32        InsertText_Font;

    static LM_String    InsertText_FontName;

    static LM_String    InsertText_Text;

    static bool            InsertText_Fill;

    static bool            InsertText_Stroke;

    static bool            InsertText_OneFill;

    static bool            InsertText_CenterH;

    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        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;

};



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

/*** Miscellaneous Support Stuff ***/



#define MSG_SCRIPT_BASE @ MSG_BASE



class MouseEvent {

    MohoView    *view;



    LM_Point    pt;

    LM_Point    startPt;

    LM_Vector2    vec;

    LM_Vector2    startVec;

    bool        shiftKey;

    bool        ctrlKey;

    bool        altKey;

    real        penPressure;

};



class KeyEvent {

    MohoView    *view;



    char        *key;

    int32        keyCode;

    bool        shiftKey;

    bool        ctrlKey;

    bool        altKey;

};



class InputDeviceEvent {

    MohoView    *view;

    

    LM_Message    *inputData;

    bool        shiftKey;

    bool        ctrlKey;

    bool        altKey;

};



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

/*** Font Preview View ***/



class LM_FontPreview : public LM_View {

    void SetPreviewText(const char *text);

    void SetFontName(const char *font);

    void Refresh();

};



extern LM_FontPreview *WF_FontPreview @ FontPreview(int32 width, int32 height);



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

/*** Mesh Preview View ***/



class LM_MeshPreview : public LM_View {

    M_Mesh *Mesh();

    bool CreateShape(bool filled);

    void AutoZoom();

    void Refresh();

};



extern LM_MeshPreview *WF_MeshPreview @ MeshPreview(int32 width, int32 height);



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

/*** 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



// 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

typedef struct {

    int32    interpMode;

    real    val1, val2;

} InterpSetting;



class AnimChannel {

    int32 ChannelType();



    int32 CountKeys();

    int32 Duration();



    void Clear(int32 zeroFrame);



    void StoreValue();

    void AddKey(int32 when);

    void Reset(int32 when);



    bool HasKey(int32 when);

    int32 GetClosestKeyID(int32 when);

    void DeleteKey(int32 when);



    int32 GetKeyWhen(int32 id);

    void SetKeyWhen(int32 id, int32 when);



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

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

    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);

};



class AnimVal : public AnimChannel {

    void SetValue(int32 when, real val);

    real GetValue(int32 when);



    real    value;

};



class AnimVec2 : public AnimChannel {

    void SetValue(int32 when, LM_Vector2 val);

    LM_Vector2 GetValue(int32 when);



    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);



    rgb_color    value;

};



class AnimBool : public AnimChannel {

    void SetValue(int32 when, bool val);

    bool GetValue(int32 when);



    bool    value;

};



class AnimString : public AnimChannel {

    void SetValue(int32 when, const char *);

    const char *GetValue(int32 when);



    LM_String    value;

};



class AnimVec3 : public AnimChannel {

    void SetValue(int32 when, LM_Vector3 val);

    LM_Vector3 GetValue(int32 when);



    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 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

    

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);



    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);



    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);

    

    int32 AnimDuration();

    int32 LayerDuration();

    void ClearAnimation(bool recursive);

    void ResetAnimation(bool recursive);



    int32 NumChannels @ CountChannels();

    void GetChannelInfo(int32 id, MohoLayerChannel *channelInfo);

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



    int32 CountPoses @ CountActions();

    const char *PoseName @ ActionName(int32 id);

    const char *CurrentPose @ CurrentAction();

    bool HasPose @ HasAction(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);

    int32 PoseDuration @ ActionDuration(const char *name);

    void BlendPoses @ BlendActions(int32 frame, bool relativeToDefault, int32 numToBlend, LM_String names[numToBlend], real percentages[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 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);

    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);



    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_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 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);

    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);

};



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

/*** Moho Script Interface ***/



extern void RedrawMoho @ Redraw();

extern void NewKeyframe(int32 channel);

extern const char *Localize(const char *str);



class ScriptInterface {

    int32        fFrame @ frame;

    int32        fLayerFrame @ layerFrame;

    MohoDoc        *fDoc @ document;

    MohoLayer    *fLayer @ layer;

    MohoView    *fView @ view;

    bool        fGridOn @ gridOn;

    real        fGridSize @ gridSize;



    void Click();



    void SetCurFrame(int32 frame);

    void UpdateUI();



    bool IsCopyable();

    void Copy(M_Mesh *mesh = NULL);

    void CopyAlternate(M_Mesh *mesh = NULL);

    bool IsPasteable();

    void Paste();

    void PasteAlternate();



    void NewKeyframe(int32 channel);

    void UpdateSelectedChannels();



    bool DisableDrawingTools();



    void SetSelLayer(MohoLayer *layer);

    void ShowLayerInLayersPalette(MohoLayer *layer);

    MohoLayer *CreateNewLayer(int32 layerType);

    MohoLayer *DuplicateLayer(MohoLayer *layer);

    void DeleteLayer(MohoLayer *layer);

    void PlaceLayerInGroup(MohoLayer *child, MohoLayer *group, bool top = true);

    void PlaceLayerBehindAnother(MohoLayer *moveLayer, MohoLayer *behindThis);

    MeshLayer *LayerAsVector(MohoLayer *layer);

    ImageLayer *LayerAsImage(MohoLayer *layer);

    GroupLayer *LayerAsGroup(MohoLayer *layer);

    BoneLayer *LayerAsBone(MohoLayer *layer);

    SwitchLayer *LayerAsSwitch(MohoLayer *layer);

    ParticleLayer *LayerAsParticle(MohoLayer *layer);

    Mesh3DLayer *LayerAs3D(MohoLayer *layer);

    AudioLayer *LayerAsAudio(MohoLayer *layer);

    NoteLayer *LayerAsNote(MohoLayer *layer);



    M_Mesh *Mesh();

    M_Shape *NewShapeProperties();

    void SnapToGrid(LM_Vector2 &v);

    void AddPointKeyframe(int32 frame);

    int32 CreateShape(bool filled, bool behindNeighborStrokes = false, int32 frame = -1000000, bool checkForBadShapes = true, bool skipDuplicateStrokes = false, bool skipFill = false, bool skipLine = false);

    real NewShapeLineWidth();

    void InsertText(const char *text, const char *font, bool fill, bool stroke, bool groupTogether, bool centerH, int32 lineOffset);

    void PickStyleProperties(M_Shape *fromShape);

    void PushStyleProperties(M_Shape *toShape);



    M_Skeleton *Skeleton();

    M_Skeleton *ParentSkeleton();

    void UpdateBonePointSelection();



    M_Mesh3D *Mesh3D();



    int32 CountAudioLayers();

    AudioLayer *GetAudioLayer(int32 id);



    // coordinate conversions

    real PixelToDoc(real pixel);

    real DocToPixel(real doc);



    int32 CountPoints();

    int32 CountSelectedPoints(bool updateCount = false);

    int32 CountCurves();

    int32 CountSelectedCurves(bool updateCount = false);

    int32 CountEdges();

    int32 CountSelectedEdges(bool updateCount = false);

    int32 CountShapes();

    int32 CountSelectedShapes(bool updateCount = false);



    int32 CountBones();

    int32 CountSelectedBones(bool updateCount = false);



    void CreateTextObject();

    void FillInFontList(LM_TextList *list);



    LM_Vector3 NoiseVector(LM_Vector3 &pos, real amp, real freq);



    void ImportEPS(const char *path);



    const char *AppDir();

    void BeginFileListing(const char *dir);

    const char *GetNextFile();



    MohoDoc *LoadDocument(const char *path);

    void DestroyDocument(MohoDoc *doc);

    

    void OpenPoserPalette();

    

    void FileNew();

    void FileOpen(const char *path);

    void FileSave();

    void FileSaveAs(const char *path);

    void FileImport(const char *path);

    void FileRender(const char *path); // path should end in .bmp, .jpg, .png, or .tga

};



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

/*** Script Preference Interface ***/



class ScriptPrefs {

    void SetBool(const char *key, bool value);

    bool GetBool(const char *key, bool defaultValue);



    void SetInt(const char *key, int32 value);

    int32 GetInt(const char *key, int32 defaultValue);



    void SetFloat(const char *key, real value);

    real GetFloat(const char *key, real defaultValue);



    void SetString(const char *key, const char *value);

    const char *GetString(const char *key, const char *defaultValue);

};



} // end MOHO module