Option Explicit On 
Option Strict On

Imports System
Imports System.IO
Imports System.Drawing
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms

Imports Sunlight.DirectX.Graphics
Imports Sunlight.DirectX.Input
Imports Sunlight.DirectX.SoundMusic

Namespace DXTest
    ' Main form class for DXTest.
    Public Class Form1
        Inherits Sunlight.IdleForm

        ' Graphics.Direct3D object, used by the device
        Private d3d As Direct3D = New Direct3D()
        ' Graphics.Device object, which performs all display actions
        Private device As device
        ' Input.DirectInput object, to handle all user input (mouse, keyboard, joystick etc.).
        Protected WithEvents di As DirectInput = New DirectInput()
        ' Graphics.SpriteManager object, to handle sprites.
        Protected manager As SpriteManager = New SpriteManager()
        ' SoundMusic.DirectMusic object, to handle sound effects and background music.
        Protected dm As DirectMusic = New DirectMusic()
        ' Background texture object.
        Private texBackground As Texture = New Texture()
        ' Sprite texture object.
        Private texSprites As Texture = New Texture()
        ' Background sprite.
        Private spriteBackground As Sprite
        ' Fixed sprite.
        Private spriteFixed As Sprite
        ' Moving sprite.
        Private spriteMoving As Sprite
        ' Player sprite.
        Private spritePlayer As Sprite
        ' Background music object.
        Private WithEvents soundMusic As BackgroundSound = New BackgroundSound()
        ' x offset of the moving sprite.
        Private xAutomaticSprite As Integer = 0
        ' x offset of the player sprite.
        Private xPlayer As Integer = 0
        ' True when the player has pressed the 'Left' key, or moved left with the joystick.
        Private bLeft As Boolean
        ' True when the player has pressed the 'Right' key, or moved right with the joystick.
        Private bRight As Boolean
        ' True when the player has pressed the 'Quit' key.
        Private bQuit As Boolean
        ' True when the player has pressed the 'Pause' key.
        Private bPaused As Boolean
        ' True when the player has pressed the 'Help' key.
        Private bShowHelp As Boolean
        ' True when the player has pressed the 'Mode Switch' key.
        Private bModeSwitch As Boolean

#Region " Windows Form Designer generated code "

        Public Sub New()
            MyBase.New()

            'This call is required by the Windows Form Designer.
            InitializeComponent()

            'Add any initialization after the InitializeComponent() call

        End Sub

        'Form overrides dispose to clean up the component list.
        Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
            If Disposing Then
                If Not (components Is Nothing) Then
                    components.Dispose()
                End If
            End If
            MyBase.Dispose(Disposing)
        End Sub

        'Required by the Windows Form Designer
        Private components As System.ComponentModel.Container

        'NOTE: The following procedure is required by the Windows Form Designer
        'It can be modified using the Windows Form Designer.  
        'Do not modify it using the code editor.
        <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
            '
            'Form1
            '
            Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
            Me.ClientSize = New System.Drawing.Size(640, 480)
            Me.MaximizeBox = False
            Me.Name = "Form1"
            Me.Text = "Form1"

        End Sub

#End Region

        ' Called when DirectX is to be initialised.
        Protected Sub OnInit(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Init

            ' Initialise the DirectX Graphics device.
            device = New Device(d3d)
            device.ParentWindow = Me
            device.Windowed = True

            ' Initialise the DirectInput object, including the action map.
            di.ActionMapName = "DXTest"
            di.AppID = New Guid("{CA761232-ED42-11CE-BACD-00AA0057B223}")
            di.Genre = Genres.ARCADE_SIDE2SIDE
            di.Actions.Add(New ActionMap.Entry(0, Actions.AXIS_ARCADES_LATERAL, "Left/Right"))
            di.Actions.Add(New ActionMap.Entry(1, Actions.KEYBOARD_LEFT, "Left"))
            di.Actions.Add(New ActionMap.Entry(2, Actions.KEYBOARD_RIGHT, "Right"))
            di.Actions.Add(New ActionMap.Entry(3, Actions.KEYBOARD_ESCAPE, "Quit"))
            di.Actions.Add(New ActionMap.Entry(4, Actions.KEYBOARD_P, "Pause"))
            di.Actions.Add(New ActionMap.Entry(5, Actions.KEYBOARD_F1, "Help"))
            di.Actions.Add(New ActionMap.Entry(6, Actions.KEYBOARD_S, "Full Screen On/Off"))
            di.ParentWindow = Me
            di.Direct3DDevice = device

            ' Initialise the DirectMusic object.
            dm.ParentWindow = Me
            dm.Create()

            ' Load the background music. This has an event handler to allow it to repeat.
            soundMusic.DirectMusicObject = dm
            soundMusic.Filename = "passport.mid"

            ' Initialise the sprite manager.
            manager.DeviceObject = device

            ' Initialise the textures.
            texBackground.DeviceObject = device
            texBackground.Filename = "a.png"
            texSprites.DeviceObject = device
            texSprites.Filename = "sprites.png"

            ' Build the sprites.
            spriteBackground = New Sprite(manager, New Rectangle(0, 0, 640, 480), texBackground, New Point(0, 0))
            spriteFixed = New Sprite(manager, New Rectangle(288, 208, 64, 64), texSprites, New Point(128, 0))
            spriteMoving = New Sprite(manager, New Rectangle(288, 100, 64, 64), texSprites, New Point(0, 0))
            spritePlayer = New Sprite(manager, New Rectangle(288, 150, 64, 64), texSprites, New Point(64, 0))

            device.Create()

            ' di.Configure()

            soundMusic.Play()
        End Sub

        ' Called when the music has reached the end.
        Private Sub OnMusicFinished(ByVal sender As Object, ByVal e As EventArgs) Handles soundMusic.Finished
            ' just repeat
            soundMusic.Play()
        End Sub

        ' Called when the application is idle (i.e. no messages are being processed).
        ' Contains the main application logic.
        Protected Sub OnIdle(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Idle
            ' Check for updated inputs and dispatch input events.
            di.Check()

            If (bQuit) Then
                Close()
                Return
            End If

            If (bModeSwitch) Then
                device.Windowed = Not device.Windowed
                device.Reset()
                bModeSwitch = False
            End If

            If (bShowHelp) Then
                bShowHelp = False
                di.Display()
            End If

            If (Not bPaused) Then
                ' Move a sprite around with the input.
                If (bLeft) Then xPlayer -= 1
                If (bRight) Then xPlayer += 1
                spritePlayer.Left = 288 + xPlayer

                ' Move a sprite around automatically.
                xAutomaticSprite += 1
                If (xAutomaticSprite > 100) Then xAutomaticSprite = -100

                spriteMoving.Left = 288 + xAutomaticSprite
            End If

            spriteBackground.Draw()
            spriteFixed.Draw()
            spriteMoving.Draw()
            spritePlayer.Draw()

            device.BeginScene()
            manager.FinishDraw()
            device.EndScene()
            device.Flip()
        End Sub

        ' Called when an input event occurs.
        Sub OnInputAction(ByVal sender As DirectInput, ByVal e As DirectInputEventArgs) Handles di.Action
            Select Case (e.ID)
                Case 0
                    If (e.AxisPosition < -20) Then
                        bLeft = True
                        bRight = False
                    ElseIf (e.AxisPosition > 20) Then
                        bRight = True
                        bLeft = False
                    Else
                        bLeft = False
                        bRight = False
                    End If

                Case 1
                    bLeft = e.ButtonPressed

                Case 2
                    bRight = e.ButtonPressed

                Case 3
                    If (e.ButtonPressed) Then bQuit = True

                Case 4
                    If (e.ButtonPressed) Then bPaused = Not bPaused

                Case 5
                    If (e.ButtonPressed) Then bShowHelp = True

                Case 6
                    If (e.ButtonPressed) Then bModeSwitch = True
            End Select
        End Sub
    End Class
End Namespace

Module DXTestModule
    ' The main entry point for the application.
    Sub Main()
        Dim form As DXTest.Form1 = New DXTest.Form1()
        form.Run()
    End Sub
End Module