using System;

namespace Orbiter.Interfaces
{
    [Flags]
    public enum Vessel2Callback
    {
        None                =0x00000000,
        SetClassCaps        =0x00000001,
        SaveState           =0x00000002,
        LoadStateEx         =0x00000004,
        SetStateEx          =0x00000008,
        PostCreation        =0x00000010,
        FocusChanged        =0x00000020,
        PreStep             =0x00000040,
        PostStep            =0x00000080,
        PlaybackEvent       =0x00000100,
        VisualCreated       =0x00000200,
        VisualDestroyed     =0x00000400,
        DrawHUD             =0x00000800,
        RCSMode             =0x00001000,
        ADCtrlMode          =0x00002000,
        HUDMode             =0x00004000,
        MFDMode             =0x00008000,
        NavMode             =0x00010000,
        DockEvent           =0x00020000,
        Animate             =0x00040000,
        ConsumeDirectKey    =0x00080000,
        ConsumeBufferedKey  =0x00100000,
        LoadGenericCockpit  =0x00200000,
        LoadPanel           =0x00400000,
        PanelMouseEvent     =0x00800000,
        PanelRedrawEvent    =0x01000000,
        LoadVC              =0x02000000,
        VCMouseEvent        =0x04000000,
        VCRedrawEvent       =0x08000000,
        All                 =0x0FFFFFFF,
    }
    
    public interface Vessel2
    {
        Vessel This{ get; set;}
        Vessel2 Base { get; set;}
        Vessel2Callback CallbackSetting { get;}
        void DisposeThis();
        void SetClassCaps (IntPtr configuration);
	    void SaveState (IntPtr scenario);
	    void LoadStateEx (IntPtr scenario, IntPtr status);
	    void SetStateEx (VesselStatus2 status);
	    void PostCreation ();
	    void FocusChanged (bool getFocus, IntPtr newVessel, IntPtr oldVessel);
	    void PreStep (double simt, double simdt, double mjd);
	    void PostStep (double simt, double simdt, double mjd);
	    bool PlaybackEvent (double simt, double event_t, string event_type, string event_name);
	    void VisualCreated (IntPtr vis, int refCount);
	    void VisualDestroyed (IntPtr vis, int refCount);
	    void DrawHUD (int mode, HudPaintSpecification hps, IntPtr hDC);
	    void RCSMode (int mode);
	    void ADCtrlMode (int mode);
	    void HUDMode (int mode);
	    void MFDMode (int mfd, int mode);
	    void NavMode (int mode, bool active);
	    void DockEvent (int dock, IntPtr mate);
	    void Animate (double simt);
	    int  ConsumeDirectKey (IntPtr keyState);
	    int  ConsumeBufferedKey (int key, bool down, IntPtr keyState);
	    bool LoadGenericCockpit ();
	    bool LoadPanel (int id);
	    bool PanelMouseEvent (int id, int mouseEvent, int mx, int my);
	    bool PanelRedrawEvent (int id, int mouseEvent, IntPtr surface);
	    bool LoadVC (int id);
	    bool VCMouseEvent (int id, int mouseEvent, Vector3 p);
	    bool VCRedrawEvent (int id, int mouseEvent, IntPtr surface);
    }
    
    public interface Vessel
    {
        IntPtr Handle { get;}
        string Name { get;}
	    string ClassName { get;}
	    int    FlightModel { get;}
	    int    DamageModel { get;}
        bool FocusEnabled { get; set;}
	    double Size { get; set;}
	    double ClipRadius {get; set;}
	    double Mass {get;}
        double EmptyMass { get; set;}
        double ISP { get;}
        void SetVisibilityLimit(double vislimit);
        void SetVisibilityLimit(double vislimit, double spotlimit);
        CW CW { get; set;}
        double WingAspect { get; set;}
        double WingEffectiveness { get; set;}
        Vector3 CrossSections { get; set;}
        Vector3 RotationalDrag { get; set;}
        double PitchMomentScale { get; set;}
        double BankMomentScale { get; set;}
        double TrimScale { get; set;}
        Vector3 PMI { get; set;}
        Vector3 CameraOffset { get; set;}
        LiftCoefficientDelegate LiftCoefficient { set;}
        void SetDockParameters(DockParameters parameters);
        void SetDockParameters(IntPtr dock, DockParameters parameters);
        DockParameters GetDockParameters(IntPtr dock);
        TouchDownPoints TouchDownPoints { set; get;}
        uint AddMesh(string name, Vector3 offset);
        uint AddMesh(IntPtr mesh, Vector3 offset);
        uint AddMesh(string name);
        uint AddMesh(IntPtr mesh);
        IntPtr CreatePropellantResource(double maxmass);
        IntPtr CreatePropellantResource(double maxmass, double mass);
        IntPtr CreatePropellantResource(double maxmass, double mass, double efficiency);
        IntPtr CreateThruster(Vector3 position, Vector3 direction, double maximumVacuumThrust, IntPtr propellant, double ispVacuum, double ispReference, double pressureReference);
		IntPtr CreateThruster(Vector3 position, Vector3 direction, double maximumVacuumThrust, IntPtr propellant, double ispVacuum, double ispReference);
		IntPtr CreateThruster(Vector3 position, Vector3 direction, double maximumVacuumThrust, IntPtr propellant, double ispVacuum);
		IntPtr CreateThruster(Vector3 position, Vector3 direction, double maximumVacuumThrust, IntPtr propellant);
		IntPtr CreateThruster(Vector3 position, Vector3 direction, double maximumVacuumThrust);
		IntPtr CreateThrusterGroup (IntPtr[] thruster, ThrusterGroup group);
		uint AddExhaust (IntPtr thruster, double lengthScale, double widthScale, IntPtr texture);
		uint AddExhaust (IntPtr thruster, double lengthScale, double widthScale);
		uint AddExhaust (IntPtr thruster, double lengthScale, double widthScale, double lengthOffset, IntPtr texture);
		uint AddExhaust (IntPtr thruster, double lengthScale, double widthScale, double lengthOffset);
		uint AddExhaust (IntPtr thruster, double lengthScale, double widthScale, Vector3 position, Vector3 direction, IntPtr texture);
		uint AddExhaust (IntPtr thruster, double lengthScale, double widthScale, Vector3 position, Vector3 direction);
		IntPtr AddExhaustStream (IntPtr thruster, ParticleStreamSpecification particleStream);
		IntPtr AddExhaustStream (IntPtr thruster);
		IntPtr AddExhaustStream (IntPtr thruster, Vector3 position, ParticleStreamSpecification particleStream);
		IntPtr AddExhaustStream (IntPtr thruster, Vector3 position);
        IntPtr AtmosphereReference {get;}
		double AtmosphereTemperature {get;}
		double AtmosphereDensity {get;}
		double AtmospherePressure {get;}
		double DynamicPressure {get;}
        double MachNumber { get;}
        double GetThrusterLevel(IntPtr thruster);
        void SetThrusterLevel(IntPtr thruster, double level);
        Vector3 ForceVector{ get;}
        Vector3 WeightVector{ get;}
        Vector3 ThrustVector { get;}
        Vector3 LiftVector { get;}
        Vector3 DragVector { get;}
        double Drag { get;}
        double Lift { get;}
        void DelPropellantResource(IntPtr propellant);
        void ClearPropellantResources();
        IntPtr GetPropellantHandleByIndex(uint index);
        void SetDefaultPropellantResource(IntPtr propellant);
        void SetPropellantMaxMass(IntPtr propellant, double maxMass);
        double GetPropellantMaxMass(IntPtr propellant);
        void SetPropellantEfficiency(IntPtr propellant, double efficiency);
        double GetPropellantEfficiency(IntPtr propellant);
        void SetPropellantMass(IntPtr propellant, double mass);			
        double GetPropellantMass(IntPtr propellant);
        double GetPropellantFlowrate(IntPtr propellant);
        uint PropellantCount { get;}
        double TotalPropellantMass { get;}
        double TotalPropellantFlowrate { get;}
        double FuelMass { get; set;}
        double FuelRate { get;}
        double MaxFuelMass { get; set;}
        uint CreateAnimation (double initial_state);
		IntPtr AddAnimationComponent (uint animation, double state0, double state1, MeshGroupTransformation transformation, IntPtr parent);
		IntPtr AddAnimationComponent (uint animation, double state0, double state1, MeshGroupTransformation transformation);
        Vector3 AlbedoRGB { set; }
        double GravityGradientDamping { get; set;}
        void SetSurfaceFrictionCoefficients(double longitudinal, double latitudinal);
        double MaxWheelbrakeForce { set; }
        void SetWheelbrakeLevel (double level, int which, bool permanent);
        void SetWheelbrakeLevel (double level, int which);
        void SetWheelbrakeLevel (double level);
        double GetWheelbrakeLevel (int which);
        void  InitNavRadios (uint navRadios);
		bool IsTransponderEnabled { set; }
        void CreateAirfoil(AirFoilOrientation align, Vector3 reference, AirFoilCoefficientDelegate coefficient, double chordLength, double wingArea, double aspectRatio);
        IntPtr CreateAirfoil2(AirFoilOrientation align, Vector3 reference, AirFoilCoefficientDelegate coefficient, double chordLength, double wingArea, double aspectRatio);
        IntPtr CreateAirfoil3(AirFoilOrientation align, Vector3 reference, AirFoilCoefficientExDelegate coefficient, object context, double chordLength, double wingArea, double aspectRatio);
        /// <summary>
        /// This function returns the managed object stored for the unmanaged key.
        /// </summary>
        /// <param name="key">The unmanaged key pointer.</param>
        /// <returns>The managed object associated with the key.</returns>
        /// <remarks>This is not a native Orbiter function. It is used for marshalling managed context in
        /// airfoil coefficient functions.</remarks>
        object GetAirFoilCoefficientFunctionContext (IntPtr key);
        void CreateControlSurface (ControlSurface type, double area, double liftCoefficientShift, Vector3 reference);
		void CreateControlSurface (ControlSurface type, double area, double liftCoefficientShift, Vector3 reference, int axis);
		void CreateControlSurface (ControlSurface type, double area, double liftCoefficientShift, Vector3 reference, int axis, uint animation);
		IntPtr CreateControlSurface2 (ControlSurface type, double area, double liftCoefficientShift, Vector3 reference);
		IntPtr CreateControlSurface2 (ControlSurface type, double area, double liftCoefficientShift, Vector3 reference, int axis);
		IntPtr CreateControlSurface2 (ControlSurface type, double area, double liftCoefficientShift, Vector3 reference, int axis, uint animation);			
        void CreateVariableDragElement (DoublePointer drag, double factor, Vector3 reference);
        void SetMeshVisibilityMode (uint mesh, short mode);
        void AddBeacon(BeaconLightSpecification beacon);
        AttitudeMode AttitudeMode {get; set;}
    }
}
