Imports System.Drawing
Imports Orbiter.Interfaces
Imports Wrap = Orbiter.Wrapper.Vessel

Namespace ShuttleVBdotnet
    Public Class ShuttleVBdotnetModule
        Implements VesselModule

        Public Sub ExitVessel(ByVal vessel As System.IntPtr) Implements Orbiter.Interfaces.VesselModule.ExitVessel
            Wrap.Exit(vessel)
        End Sub

        Public Overridable Function InitVessel(ByVal vessel As System.IntPtr, ByVal flightModel As Integer) As System.IntPtr Implements Orbiter.Interfaces.VesselModule.InitVessel
            Return Wrap.Init(vessel, flightModel, New ShuttleVB())
        End Function

        Public Sub InitModule(ByVal nativeDLL As System.IntPtr) Implements Orbiter.Interfaces.VesselModule.InitModule

        End Sub

        Public Sub ExitModule(ByVal nativeDLL As System.IntPtr) Implements Orbiter.Interfaces.VesselModule.ExitModule

        End Sub

    End Class
End Namespace
Public Class ShuttleVB
    Implements Orbiter.Interfaces.Vessel2

    Private MyVessel As Orbiter.Interfaces.Vessel
    Private MyVessel2 As Orbiter.Interfaces.Vessel2
    Private Const callbacks As Vessel2Callback = Vessel2Callback.SetClassCaps Or Vessel2Callback.DrawHUD
    Private Const fuelMass As Double = 750.0
    Private Const isp As Double = 50000.0
    Private Const maximumMainThrust As Double = 30000.0
    Private Const maximumHoverThrust As Double = 15000.0
    Private Const maximumRCSThrust As Double = 200.0
    Private Const liftTableSize As Integer = 9
    Private Shared ReadOnly aoa() As Double = {-180 * Constants.Radiant, -60 * Constants.Radiant, -30 * Constants.Radiant, -1 * Constants.Radiant, 15 * Constants.Radiant, 20 * Constants.Radiant, 25 * Constants.Radiant, 60 * Constants.Radiant, 180 * Constants.Radiant}
    Private Shared ReadOnly cl() As Double = {0, 0, -0.1, 0, 0.2, 0.25, 0.2, 0, 0}
    Private Shared ReadOnly scl() As Double = {(cl(1) - cl(0)) / (aoa(1) - aoa(0)), (cl(2) - cl(1)) / (aoa(2) - aoa(1)), (cl(3) - cl(2)) / (aoa(3) - aoa(2)), (cl(4) - cl(3)) / (aoa(4) - aoa(3)), (cl(5) - cl(4)) / (aoa(5) - aoa(4)), (cl(6) - cl(5)) / (aoa(6) - aoa(5)), (cl(7) - cl(6)) / (aoa(7) - aoa(6)), (cl(8) - cl(7)) / (aoa(8) - aoa(7)), 0}
    Private rcsThrusters(14) As IntPtr

    Public Property Base() As Orbiter.Interfaces.Vessel2 Implements Orbiter.Interfaces.Vessel2.Base
        Get
            Return MyVessel2
        End Get
        Set(ByVal value As Orbiter.Interfaces.Vessel2)
            MyVessel2 = value
        End Set
    End Property

    Public Property This() As Orbiter.Interfaces.Vessel Implements Orbiter.Interfaces.Vessel2.This
        Get
            Return MyVessel
        End Get
        Set(ByVal value As Orbiter.Interfaces.Vessel)
            MyVessel = value
        End Set
    End Property

    Public ReadOnly Property CallbackSetting() As Orbiter.Interfaces.Vessel2Callback Implements Orbiter.Interfaces.Vessel2.CallbackSetting
        Get
            Return callbacks
        End Get
    End Property

    Public Overridable Sub SetClassCaps(ByVal configuration As System.IntPtr) Implements Orbiter.Interfaces.Vessel2.SetClassCaps
        Dim mainThruster As IntPtr
        Dim hoverThruster As IntPtr
        'physical specs
        This.Size = 3.5
        This.EmptyMass = 500.0
        This.CW = New CW(0.3, 0.3, 0.6, 0.9)
        This.WingAspect = 0.7
        This.WingEffectiveness = 2.5
        This.CrossSections = New Orbiter.Interfaces.Vector3(10.5, 15.0, 5.8)
        This.RotationalDrag = New Orbiter.Interfaces.Vector3(0.6, 0.6, 0.35)
        If (This.FlightModel >= 1) Then
            This.PitchMomentScale = 0.0001
            This.BankMomentScale = 0.0001
        End If
        This.PMI = New Orbiter.Interfaces.Vector3(2.28, 2.31, 0.79)
        This.TrimScale = 0.05
        This.CameraOffset = New Orbiter.Interfaces.Vector3(0, 0.8, 0)
        This.LiftCoefficient = New LiftCoefficientDelegate(AddressOf LiftCoefficient)
        This.SetDockParameters(New DockParameters(New Orbiter.Interfaces.Vector3(0, 1.3, -1), New Orbiter.Interfaces.Vector3(0, 1, 0), New Orbiter.Interfaces.Vector3(0, 0, -1)))
        This.TouchDownPoints = New TouchDownPoints(New Orbiter.Interfaces.Vector3(0, -1.5, 2), New Orbiter.Interfaces.Vector3(-1, -1.5, -1.5), New Orbiter.Interfaces.Vector3(1, -1.5, -1.5))

        ' propellant resources

        Dim propellant As IntPtr = This.CreatePropellantResource(fuelMass)

        '***************** thruster definitions *******************
        Dim mainContrail As ParticleStreamSpecification = New ParticleStreamSpecification(0, 5.0, 16.0, 200.0, 0.15, 1.0, 5.0, 3.0, ParticleStreamSpecification.LightType.Diffuse, ParticleStreamSpecification.LevelMap.LimitedSquareRoot, 0.0, 2.0, ParticleStreamSpecification.AtmosphereMap.LimitedLogarithmic, 0.0001, 1.0, IntPtr.Zero)
        Dim hoverContrail As ParticleStreamSpecification = New ParticleStreamSpecification(0, 5.0, 8.0, 200.0, 0.15, 1.0, 5.0, 3.0, ParticleStreamSpecification.LightType.Diffuse, ParticleStreamSpecification.LevelMap.LimitedSquareRoot, 0.0, 2.0, ParticleStreamSpecification.AtmosphereMap.LimitedLogarithmic, 0.0001, 1.0, IntPtr.Zero)
        Dim mainExhaust As ParticleStreamSpecification = New ParticleStreamSpecification(0, 2.0, 20.0, 200.0, 0.05, 0.1, 8.0, 1.0, ParticleStreamSpecification.LightType.Emissive, ParticleStreamSpecification.LevelMap.SquareRoot, 0.0, 1.0, ParticleStreamSpecification.AtmosphereMap.LimitedLogarithmic, 0.00001, 0.1, IntPtr.Zero)
        Dim hoverExhaust As ParticleStreamSpecification = New ParticleStreamSpecification(0, 2.0, 10.0, 200.0, 0.05, 0.05, 8.0, 1.0, ParticleStreamSpecification.LightType.Emissive, ParticleStreamSpecification.LevelMap.SquareRoot, 0.0, 1.0, ParticleStreamSpecification.AtmosphereMap.LimitedLogarithmic, 0.00001, 0.1, IntPtr.Zero)
        mainThruster = This.CreateThruster(New Orbiter.Interfaces.Vector3(0, 0, -4.35), New Orbiter.Interfaces.Vector3(0, 0, 1), maximumMainThrust, propellant, isp)
        This.CreateThrusterGroup(New IntPtr() {mainThruster}, ThrusterGroup.Main)
        This.AddExhaust(mainThruster, 8, 1, New Orbiter.Interfaces.Vector3(0, 0.3, -4.35), New Orbiter.Interfaces.Vector3(0, 0, -1))
        hoverThruster = This.CreateThruster(New Orbiter.Interfaces.Vector3(0, -1.5, 0), New Orbiter.Interfaces.Vector3(0, 1, 0), maximumHoverThrust, propellant, isp)
        This.CreateThrusterGroup(New IntPtr() {hoverThruster}, ThrusterGroup.Hover)
        This.AddExhaust(hoverThruster, 8, 1, New Orbiter.Interfaces.Vector3(0, -1.5, 1), New Orbiter.Interfaces.Vector3(0, -1, 0))
        This.AddExhaust(hoverThruster, 8, 1, New Orbiter.Interfaces.Vector3(0, -1.5, -1), New Orbiter.Interfaces.Vector3(0, -1, 0))
        This.AddExhaustStream(hoverThruster, New Orbiter.Interfaces.Vector3(0, -3, 1), hoverContrail)
        This.AddExhaustStream(hoverThruster, New Orbiter.Interfaces.Vector3(0, -3, -1), hoverContrail)
        This.AddExhaustStream(mainThruster, New Orbiter.Interfaces.Vector3(0, 0.3, -10), mainContrail)
        This.AddExhaustStream(hoverThruster, New Orbiter.Interfaces.Vector3(0, -2, 1), hoverExhaust)
        This.AddExhaustStream(hoverThruster, New Orbiter.Interfaces.Vector3(0, -2, -1), hoverExhaust)
        This.AddExhaustStream(mainThruster, New Orbiter.Interfaces.Vector3(0, 0.3, -5), mainExhaust)
        rcsThrusters(0) = This.CreateThruster(New Orbiter.Interfaces.Vector3(1, 0, 3), New Orbiter.Interfaces.Vector3(0, 1, 0), maximumRCSThrust, propellant, isp)
        rcsThrusters(1) = This.CreateThruster(New Orbiter.Interfaces.Vector3(1, 0, 3), New Orbiter.Interfaces.Vector3(0, -1, 0), maximumRCSThrust, propellant, isp)
        rcsThrusters(2) = This.CreateThruster(New Orbiter.Interfaces.Vector3(-1, 0, 3), New Orbiter.Interfaces.Vector3(0, 1, 0), maximumRCSThrust, propellant, isp)
        rcsThrusters(3) = This.CreateThruster(New Orbiter.Interfaces.Vector3(-1, 0, 3), New Orbiter.Interfaces.Vector3(0, -1, 0), maximumRCSThrust, propellant, isp)
        rcsThrusters(4) = This.CreateThruster(New Orbiter.Interfaces.Vector3(1, 0, -3), New Orbiter.Interfaces.Vector3(0, 1, 0), maximumRCSThrust, propellant, isp)
        rcsThrusters(5) = This.CreateThruster(New Orbiter.Interfaces.Vector3(1, 0, -3), New Orbiter.Interfaces.Vector3(0, -1, 0), maximumRCSThrust, propellant, isp)
        rcsThrusters(6) = This.CreateThruster(New Orbiter.Interfaces.Vector3(-1, 0, -3), New Orbiter.Interfaces.Vector3(0, 1, 0), maximumRCSThrust, propellant, isp)
        rcsThrusters(7) = This.CreateThruster(New Orbiter.Interfaces.Vector3(-1, 0, -3), New Orbiter.Interfaces.Vector3(0, -1, 0), maximumRCSThrust, propellant, isp)
        rcsThrusters(8) = This.CreateThruster(New Orbiter.Interfaces.Vector3(1, 0, 3), New Orbiter.Interfaces.Vector3(-1, 0, 0), maximumRCSThrust, propellant, isp)
        rcsThrusters(9) = This.CreateThruster(New Orbiter.Interfaces.Vector3(-1, 0, 3), New Orbiter.Interfaces.Vector3(1, 0, 0), maximumRCSThrust, propellant, isp)
        rcsThrusters(10) = This.CreateThruster(New Orbiter.Interfaces.Vector3(1, 0, -3), New Orbiter.Interfaces.Vector3(-1, 0, 0), maximumRCSThrust, propellant, isp)
        rcsThrusters(11) = This.CreateThruster(New Orbiter.Interfaces.Vector3(-1, 0, -3), New Orbiter.Interfaces.Vector3(1, 0, 0), maximumRCSThrust, propellant, isp)
        rcsThrusters(12) = This.CreateThruster(New Orbiter.Interfaces.Vector3(0, 0, -3), New Orbiter.Interfaces.Vector3(0, 0, 1), maximumRCSThrust, propellant, isp)
        rcsThrusters(13) = This.CreateThruster(New Orbiter.Interfaces.Vector3(0, 0, 3), New Orbiter.Interfaces.Vector3(0, 0, -1), maximumRCSThrust, propellant, isp)
        This.CreateThrusterGroup(New IntPtr() {rcsThrusters(0), rcsThrusters(2), rcsThrusters(5), rcsThrusters(7)}, ThrusterGroup.PitchUp)
        This.CreateThrusterGroup(New IntPtr() {rcsThrusters(1), rcsThrusters(3), rcsThrusters(4), rcsThrusters(6)}, ThrusterGroup.PitchDown)
        This.CreateThrusterGroup(New IntPtr() {rcsThrusters(0), rcsThrusters(4), rcsThrusters(3), rcsThrusters(7)}, ThrusterGroup.BankLeft)
        This.CreateThrusterGroup(New IntPtr() {rcsThrusters(1), rcsThrusters(5), rcsThrusters(2), rcsThrusters(6)}, ThrusterGroup.BankRight)
        This.CreateThrusterGroup(New IntPtr() {rcsThrusters(0), rcsThrusters(4), rcsThrusters(2), rcsThrusters(6)}, ThrusterGroup.Up)
        This.CreateThrusterGroup(New IntPtr() {rcsThrusters(1), rcsThrusters(5), rcsThrusters(3), rcsThrusters(7)}, ThrusterGroup.Down)
        This.CreateThrusterGroup(New IntPtr() {rcsThrusters(8), rcsThrusters(11)}, ThrusterGroup.YawLeft)
        This.CreateThrusterGroup(New IntPtr() {rcsThrusters(9), rcsThrusters(10)}, ThrusterGroup.YawRight)
        This.CreateThrusterGroup(New IntPtr() {rcsThrusters(8), rcsThrusters(10)}, ThrusterGroup.Left)
        This.CreateThrusterGroup(New IntPtr() {rcsThrusters(9), rcsThrusters(11)}, ThrusterGroup.Right)
        This.CreateThrusterGroup(New IntPtr() {rcsThrusters(12)}, ThrusterGroup.Forward)
        This.CreateThrusterGroup(New IntPtr() {rcsThrusters(13)}, ThrusterGroup.Back)

        ' visual specs
        This.AddMesh("ShuttlePB")
    End Sub

    Private Function LiftCoefficient(ByVal angleOfAttack As Double) As Double
        Dim i As Integer = 0
        While (i < liftTableSize - 1 And aoa(i + 1) < angleOfAttack)
            i += 1
        End While
        Return cl(i) + (angleOfAttack - aoa(i)) * scl(i)
    End Function

    Public Sub ADCtrlMode(ByVal mode As Integer) Implements Orbiter.Interfaces.Vessel2.ADCtrlMode

    End Sub

    Public Sub Animate(ByVal simt As Double) Implements Orbiter.Interfaces.Vessel2.Animate

    End Sub

    Public Function ConsumeBufferedKey(ByVal key As Integer, ByVal down As Boolean, ByVal keyState As System.IntPtr) As Integer Implements Orbiter.Interfaces.Vessel2.ConsumeBufferedKey

    End Function

    Public Function ConsumeDirectKey(ByVal keyState As System.IntPtr) As Integer Implements Orbiter.Interfaces.Vessel2.ConsumeDirectKey

    End Function

    Public Sub DisposeThis() Implements Orbiter.Interfaces.Vessel2.DisposeThis

    End Sub

    Public Sub DockEvent(ByVal dock As Integer, ByVal mate As System.IntPtr) Implements Orbiter.Interfaces.Vessel2.DockEvent

    End Sub

    Public Overridable Sub DrawHUD(ByVal mode As Integer, ByVal hps As Orbiter.Interfaces.HudPaintSpecification, ByVal hDC As System.IntPtr) Implements Orbiter.Interfaces.Vessel2.DrawHUD
        Dim MyHUD As Graphics = Graphics.FromHdc(hDC)
        Dim MyFont As New Font("Arial", 10.0, System.Drawing.FontStyle.Regular, GraphicsUnit.Pixel, CType(0, Byte))
        Dim MyBrush As Brush = Brushes.Red
        Dim i As Integer
        MyHUD.DrawString(".NET Graphics Test (GDI+)", MyFont, MyBrush, 200, 250)
        For i = 1 To This.PropellantCount
            MyHUD.DrawString("Propellant " + i.ToString() + ": " + This.GetPropellantMass(This.GetPropellantHandleByIndex(i - 1)).ToString(), MyFont, MyBrush, 200, 250 + i * 10)
        Next i
        Base.DrawHUD(mode, hps, hDC)
    End Sub

    Public Sub FocusChanged(ByVal getFocus As Boolean, ByVal newVessel As System.IntPtr, ByVal oldVessel As System.IntPtr) Implements Orbiter.Interfaces.Vessel2.FocusChanged

    End Sub

    Public Sub HUDMode(ByVal mode As Integer) Implements Orbiter.Interfaces.Vessel2.HUDMode

    End Sub

    Public Function LoadGenericCockpit() As Boolean Implements Orbiter.Interfaces.Vessel2.LoadGenericCockpit

    End Function

    Public Function LoadPanel(ByVal id As Integer) As Boolean Implements Orbiter.Interfaces.Vessel2.LoadPanel

    End Function

    Public Sub LoadStateEx(ByVal scenario As System.IntPtr, ByVal status As System.IntPtr) Implements Orbiter.Interfaces.Vessel2.LoadStateEx

    End Sub

    Public Function LoadVC(ByVal id As Integer) As Boolean Implements Orbiter.Interfaces.Vessel2.LoadVC

    End Function

    Public Sub MFDMode(ByVal mfd As Integer, ByVal mode As Integer) Implements Orbiter.Interfaces.Vessel2.MFDMode

    End Sub

    Public Sub NavMode(ByVal mode As Integer, ByVal active As Boolean) Implements Orbiter.Interfaces.Vessel2.NavMode

    End Sub

    Public Function PanelMouseEvent(ByVal id As Integer, ByVal mouseEvent As Integer, ByVal mx As Integer, ByVal my As Integer) As Boolean Implements Orbiter.Interfaces.Vessel2.PanelMouseEvent

    End Function

    Public Function PanelRedrawEvent(ByVal id As Integer, ByVal mouseEvent As Integer, ByVal surface As System.IntPtr) As Boolean Implements Orbiter.Interfaces.Vessel2.PanelRedrawEvent

    End Function

    Public Function PlaybackEvent(ByVal simt As Double, ByVal event_t As Double, ByVal event_type As String, ByVal event_name As String) As Boolean Implements Orbiter.Interfaces.Vessel2.PlaybackEvent

    End Function

    Public Sub PostCreation() Implements Orbiter.Interfaces.Vessel2.PostCreation

    End Sub

    Public Sub PostStep(ByVal simt As Double, ByVal simdt As Double, ByVal mjd As Double) Implements Orbiter.Interfaces.Vessel2.PostStep

    End Sub

    Public Sub PreStep(ByVal simt As Double, ByVal simdt As Double, ByVal mjd As Double) Implements Orbiter.Interfaces.Vessel2.PreStep

    End Sub

    Public Sub RCSMode(ByVal mode As Integer) Implements Orbiter.Interfaces.Vessel2.RCSMode

    End Sub

    Public Sub SaveState(ByVal scenario As System.IntPtr) Implements Orbiter.Interfaces.Vessel2.SaveState

    End Sub

    Public Sub SetStateEx(ByVal status As Orbiter.Interfaces.VesselStatus2) Implements Orbiter.Interfaces.Vessel2.SetStateEx

    End Sub

    Public Function VCMouseEvent(ByVal id As Integer, ByVal mouseEvent As Integer, ByVal p As Orbiter.Interfaces.Vector3) As Boolean Implements Orbiter.Interfaces.Vessel2.VCMouseEvent

    End Function

    Public Function VCRedrawEvent(ByVal id As Integer, ByVal mouseEvent As Integer, ByVal surface As System.IntPtr) As Boolean Implements Orbiter.Interfaces.Vessel2.VCRedrawEvent

    End Function

    Public Sub VisualCreated(ByVal vis As System.IntPtr, ByVal refCount As Integer) Implements Orbiter.Interfaces.Vessel2.VisualCreated

    End Sub

    Public Sub VisualDestroyed(ByVal vis As System.IntPtr, ByVal refCount As Integer) Implements Orbiter.Interfaces.Vessel2.VisualDestroyed

    End Sub

End Class
