Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports EZGL2D

Namespace EZGL2DexampleParticles
    Friend Class Particle
        Private _x As Single
        Private _y As Single
        Private _dx As Single
        Private _dy As Single
        Private _angle As Single
        Private _speed As Single
        Public Property x() As Single
            Get
                Return _x
            End Get
            Set(ByVal value As Single)
                _x = value
            End Set
        End Property
        Public Property y() As Single
            Get
                Return _y
            End Get
            Set(ByVal value As Single)
                _y = value
            End Set
        End Property
        Public Property dx() As Single
            Get
                Return _dx
            End Get
            Set(ByVal value As Single)
                _dx = value
            End Set
        End Property
        Public Property dy() As Single
            Get
                Return _dy
            End Get
            Set(ByVal value As Single)
                _dy = value
            End Set
        End Property
        Public Property angle() As Single
            Get
                Return _angle
            End Get
            Set(ByVal value As Single)
                _angle = value
            End Set
        End Property
        Public Property speed() As Single
            Get
                Return _speed
            End Get
            Set(ByVal value As Single)
                _speed = value
            End Set
        End Property

        Private ticks As Integer

        Public Sub New()

        End Sub

        Public Sub spawn(ByVal x As Single, ByVal y As Single, ByVal angle As Single, ByVal speed As Single)
            Me.angle = angle
            Me.x = x
            Me.y = y
            Me.speed = speed
            dx = CSng(Math.Cos(angle)) * speed
            dy = CSng(Math.Sin(angle)) * speed

        End Sub

        Public Function update(ByVal screenWidth As Integer, ByVal screenHeight As Integer) As Boolean
            ticks += 1

            x += dx
            y += dy
            If x < -32 Then
                Return True
            End If
            If x > screenWidth + 32 Then
                Return True
            End If
            If y < -32 Then
                Return True
            End If
            If y > screenHeight + 32 Then
                Return True
            End If

            Return False
        End Function


    End Class

	Friend Class ParticleSystem

		Public particles As IList(Of Particle) = New List(Of Particle)()

		Private size As Integer
		Private max As Integer
		Private random As New Random()
		Private ticks As Integer

		Public Sub New(ByVal numParticles As Integer)
			Me.max = numParticles
			Me.size = 0

			For i As Integer = 0 To (max + 1) - 1
				Dim p As New Particle()
				particles.Add(p)
			Next i
		End Sub

		Private Sub spawn(ByVal x As Single, ByVal y As Single, ByVal angle As Single, ByVal speed As Single)
			If size < max Then
				particles(size).spawn(x, y, angle, speed)
				size += 1
			End If

		End Sub

		Private Sub kill(ByVal index As Integer)
			If index < size Then
				size -= 1
				particles(max) = particles(index)
				particles(index) = particles(size)
				particles(size) = particles(max)
			End If
		End Sub

		Public Sub update(ByVal screenWidth As Integer, ByVal screenHeight As Integer)
			ticks += 1
			Dim angle As Single = ticks / 4.0F
			Dim dx As Single = (CSng(Math.Cos(ticks / 40.0R)) + CSng(Math.Cos(ticks / 74.0R))) * 150
			Dim dy As Single = (CSng(Math.Sin(ticks / 54.0R)) + CSng(Math.Cos(ticks / 30.0R))) * 100
			Dim x As Single = screenWidth \ 2 - dx
			Dim y As Single = screenHeight\2 - dy
			Dim speed As Single = 8
			spawn(x, y, angle, speed)
			spawn(x, y, angle + CSng(Math.PI / 2), speed)
			spawn(x, y, angle + CSng(Math.PI), speed)
			spawn(x, y, angle - CSng(Math.PI / 2), speed)

			angle = -ticks / 4.0F
			x = screenWidth\2 + dx
			y = screenHeight\2 + dy
			spawn(x, y, angle, speed)
			spawn(x, y, angle + CSng(Math.PI / 2), speed)
			spawn(x, y, angle + CSng(Math.PI), speed)
			spawn(x, y, angle - CSng(Math.PI / 2), speed)

			For i As Integer = 0 To size - 1
				If particles(i).update(screenWidth, screenHeight) Then
					kill(i)
				End If
			Next i
		End Sub

		Public Sub draw(ByVal sprite As GL2D.SpriteGL)
			For i As Integer = 0 To size - 1
				Dim p As Particle = particles(i)
				GL2D.SpriteRotateScale(CInt(Math.Truncate(p.x)), CInt(Math.Truncate(p.y)), CSng(p.angle * 180 / Math.PI), 1, 1, GL2D.SpriteGL.FLIP_NONE, sprite)

			Next i
		End Sub

	End Class
End Namespace
