#ifndef _DXINPUT_H_
#define _DXINPUT_H_

#define kMAX_Str                80
#define kMAX_Axis                        8
#define kMAX_Sliders                2
#define kMAX_POVs                        4

#define kInfinite_Duration 0xFFFFFF
#define HZ_to_uS(hz)                ((int)(1000000.0/(double)(hz) + 0.5))

typedef signed char           tSC;
typedef signed int            tSI;
typedef signed long           tSL;

typedef unsigned char         tUC;
typedef unsigned int          tUI;
typedef unsigned long         tUL;

typedef enum
{
   kJoy1=0,
   kJoy2,
   kJoy3,
   kJoy4,
   kJoy5,
   kJoy6,
   kJoy7,
   kJoy8,
   kJoy9,
   kJoy10,
   kJoy11,
   kJoy12,
   kJoy13,
   kJoy14,
   kJoy15,
   kJoy16,
   kMaxJoy,
        kMouse,
        kKeyBoard,
        kAllDevices
}tDevice;

typedef enum
{
        kNoButton=-1,
        kButton0=0,
        kButton1,
        kButton2,
        kButton3,
        kButton4,
        kButton5,
        kButton6,
        kButton7,
        kButton8,
        kButton9,
        kButton10,
        kButton31=31,
        kButtonMax
}tJoyButtons;

typedef enum
{
        kStick  = 1<<0,
        kWheel  = 1<<1,
        kGamePad= 1<<2,
}tDeviceMask;

typedef struct
{
        int                                   ButtonMask;
        int                                   AxisMask;
        tDeviceMask      DevType;
        char                                  Name[kMAX_Str];
}tJoyInfo;

typedef struct
{
        int         ButtonMask;
    tSL          X_pos;
        tSL            Y_pos;
        tSL            Z_pos;

        tSL        X_rot;
        tSL        Y_rot;
        tSL        Z_rot;

        tSL        Slide_pos[kMAX_Sliders];
   tUL        POV_dir[kMAX_POVs];

}tJoyData;

typedef enum
{
        kDontPlayNow=0,
        kPlayNow,
        kPlayNowIfModified,

}tLoadEffect;

typedef enum
{
   kConstant,
   kRamp,
   kCustom,

   kWave_Square,
   kWave_Sine,
   kWave_Triange,
   kWave_SawUp,
   kWave_SawDown,

   kCondition_Spring,
   kCondition_Damper,
   kCondition_Inertia,
   kCondition_Friction,

   kMaxEffectSubTypes

}tEffType;

typedef struct tEffConstant
{
        long  Mag;
}tEffConstant;

typedef struct tEffRamp
{
   long  Start;
   long  End;
}tEffRamp;

typedef struct tEffWave
{
        int         Mag;
        long    Offset;
        int            Phase;
        int            Period;
}tEffWave;

typedef struct tEffCondition
{
   long  Offset;
   long  PositiveCoefficient;
   long  NegativeCoefficient;
   int   PositiveSaturation;
   int   NegativeSaturation;
   long  DeadBand;
}tEffCondition;

typedef struct tEffCustom
{
    int         Channels;
    int        Period;
    int        Samples;
    long *ForceData;
}tEffCustom;

typedef union tEffectInfo
{
   tEffConstant   Constant;
   tEffRamp       Ramp;
   tEffWave       Wave;
   tEffCondition  Condition;
   tEffCustom     Custom;
}tEffInfo;

typedef struct tEffectEnvelope
{
   int                         AttackLevel;
   int                         AttackTime;
   int                        FadeLevel;
   int                        FadeTime;
}tEffEnvelope;

typedef struct tFFB_Effect
{
   tEffType                        Type;
   tEffInfo                        TypeInfo;
   int                                 Duration;
   int                                 Period;
   int                                 Gain;
   tJoyButtons                Trigger;
   int                                 TriggerRepeatTime;
   long                                Direction;
   tEffEnvelope            Envelope;
}tFFB_Effect;


// ===================================================================
//                                                                        Function Prototypes
// ===================================================================
// Init
// ----
int            ffb_Init(void);

// Use
// ---

void        ffb_Pause(short dev);
void        ffb_Continue(short dev);

void        ffb_Enable(short dev);
void        ffb_Disable(short dev);

int            ffb_effectCreate(short dev, tFFB_Effect* eff);
void        ffb_effectPlay(short effectID);
void        ffb_effectStop(short effectID);
void        ffb_effectStopAll(short dev);
void        ffb_effectModify(short effectID, int*        Direction, int* Duration, int* Gain,
                                                                int* Period, tEffInfo* TypeInfo, tEffEnvelope* Envelope);

#endif // _DXINPUT_H_