' -*- tab-width: 4; -*-
'
' The contents of this file are subject to the Mozilla Public
' License Version 1.1 (the "License"); you may not use this file
' except in compliance with the License. You may obtain a copy of
' the License at http://www.mozilla.org/MPL/
' 
' Software distributed under the License is distributed on an "AS
' IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
' implied. See the License for the specific language governing
' rights and limitations under the License.
' 
' The Original Code is State Machine Compiler (SMC).
' 
' The Initial Developer of the Original Code is Charles W. Rapp.
' Portions created by Charles W. Rapp are
' Copyright (C) 2000 - 2003 Charles W. Rapp.
' All Rights Reserved.
' 
' Contributor(s): 
'
' State Machine
'  Stoplight
'
' Description
'  This state machine changes the stop lights.
'
' RCS ID
' $Id$
'
' CHANGE LOG
' $Log$

Public NotInheritable Class Vehicle

    '------------------------------------------------------------
    ' Member data.
    '

    ' Where am I?
    Private _position As Point

    ' Where am I going?
    Private _position As Point

    ' How fast am I going?
    Private _speed As Integer

    ' On what canvas do I appear?
    Private _canvas As TrafficCanvas

    ' How large am I?
    Private _size As Dimension

    ' What am I doing?
    Private _fsm As VehicleContext

    ' Where am I being drawn?
    Private _graphic As Graphics2D

    '------------------------------------------------------------
    ' Properties
    '

    Public ReadOnly Property XPos As Integer
        Get
            Dim newPosition As Integer = new Point(_position)

            newPosition.Translate((_direction.x * _speed), _
                                  (_direction.y * _speed))

            Return (newPosition.x)
        End Get
    End Property

    Public ReadOnly Property YPos As Integer
        Get
            Dim newPosition As Integer = new Point(_position)

            newPosition.Translate((_direction.x * _speed), _
                                  (_direction.y * _speed))

            Return (newPosition.y)
        End Get
    End Property

    Public ReadOnly Property MinX As Integer
        Get
            Return _canvas.MinX()
        End Get
    End Property

    Public ReadOnly Property MinY As Integer
        Get
            Return _canvas.MinY()
        End Get
    End Property

    Public ReadOnly Property LightsColor As Color
        Get
            Return _canvas.LightsColor(_direction)
        End Get
    End Property

    Public ReadOnly Property DistanceToIntersection As Integer
        Get
            Return _canvas.DistanceToIntersection(_position, _
                                                  _direction)
        End Get
    End Property

    Public Property Speed As Integer
       Get
           Return _speed
       End Get

       Set(ByVal speed As Integer)
           _speed = speed
       End Set
    End Property

    '------------------------------------------------------------
    ' Member methods.
    '

    Public Sub Paint(ByRef g2 As Graphics2D)

        Draw(g2, Color.black)

        Return
    End Sub

    Public Sub Move(ByRef g2 As Graphics2D)

        _graphic = g2
        _fsm.Move()

        Return
    End Sub

    Public Sub StopDemo(ByRef g As Graphics)

        Dim g2 As Graphics2D = g

        _fsm.Stop()

        ' Cover over the vehicle's last position.
        Draw(g2, Color.white)

        Return
    End Sub

    Public Sub LightGreen()

        _fsm.LightGreen()

        Return
    End Sub

    Private Sub Draw(ByRef g2 As Graphics2D, _
                     ByVal color As Paint)

        Dim p1 As Point
        Dim p2 As Point
        Dim l1 As Point
        Dim l2 As Point
        Dim position As Point
        Dim size As Dimension
        Dim lightSize As Dimension
        Dim lightDirection As Integer

        p1 = New Point(_position)
        p2 = New Point()
        position = New Point()
        size = New Dimension(_size)
        l1 = New Point()
        l2 = New Point()
        lightSize = new Dimension()

        ' Check if the vehicle is moving through a
        ' stoplight. Only paint that part of the
        ' vehicle that is not under the stop light.

        ' Get the stoplight's position, size and direction based
        ' on the vehicle's direction.
        _owner.getLightDimensions(_direction, _
                                  l1, _
                                  lightSize)
        p2.x = _position.x + _size.width
        p2.y = _position.y + _size.height
        l2.x = l1.x + lightSize.width
        l2.y = l1.y + lightSize.height

        ' Is the vehicle passing under the stoplight? It depends
        ' on what direction this vehicle is moving.
        ' For east and west, only check the x axis. For north
        ' and south, only check the y axis.
        If (_direction.x = _canvas.EAST.x And _
             _direction.y = _canvas.EAST.y) Or _
            (_direction.x = _canvas.WEST.x And _
             _direction.y = _canvas.WEST.y) _
        Then
            ' Is entire vehicle clear? It is if the vehicle's
            ' left is to the light's right or the vehicle's
            ' right is to the light's left or 
            If p1.x > l2.x Or p2.x < l1.x _
            Then
                position.x = p1.x
                position.y = p1.y
                size.width = _size.width
                size.height = _size.height

            ' Is the vehicle's right side covered?
            ElseIf p1.x < l1.x _
            Then
                ' Yes. Figure out by how much.
                position.x = p1.x
                position.y = p1.y
                size.width = l1.x - p1.x - 1
                size.height = _size.height

            ' Is the vehicle's left side covered?
            ElseIf p2.x > l2.x _
            Then
                position.x = l2.x + 1
                position.y = p1.y
                size.width = p2.x - l2.x - 1
                size.height = _size.height
            
            Else
                ' The vehicle is entirely covered.
                ' Set size to 0.
                size.width = 0
                size.height = 0
            End If

        ' Otherwise, we are heading north or south.
        Else
            ' Check if the vehicle is entirely clear of the
            ' stoplight.
            If p1.y > l2.y Or p2.y < l1.y _
            Then
                position.x = p1.x
                position.y = p1.y
                size.width = _size.width
                size.height = _size.height

            ' Top part clear.
            ElseIf p1.y < l1.y _
            Then
                position.x = p1.x
                position.y = p1.y
                size.width = _size.width
                size.height = l1.y - p1.y - 1

            ElseIf p2.y > l2.y
            Then
                position.x = p1.x
                position.y = l2.y + 1
                size.width = _size.width
                size.height = p2.y - l2.y - 1

            Else
                size.width = 0
                size.height = 0
            End If
        End If

        ' Do the painting only if there is a rectangle to
        ' paint, that is both the width and height are greater
        ' than 0.
        If size.width > 0 And size.height > 0 _
        Then
            g2.setPaint(color)
            g2.fill(New Rectangle2D.Double(position.getX(), _
                                           position.getY(), _
                                           size.getWidth(), _
                                           size.getHeight()))
        End If

        Return
    End Sub

    //-----------------------------------------------------------
    // State Machine Actions
    //

    Public Sub WatchLight()

        _canvas.WatchingLight(_direction, Me)

        Return
    End Sub

    Public Sub EndTrip()

        ' Cover over the vehicle's last position.
        Draw(_graphic, Color.white)
        _graphic = Nothing

        _canvas.VehicleGone(Me)

        Return
    End Sub

    Public Sub Advance()

        Dim distance As Integer = _
            _canvas.DistanceToIntersection(_position, _
                                           _direction)
        Dim lightColor As Color = _canvas.LightsColor(_direction)
        Dim dx As Integer
        Dim dy As Integer

        ' Cover over the vehicle's last position.
        Draw(_graphic, Color.white)

        ' Figure out the vehicle's nwe position.
        ' If the light is red, then advance to the intersection
        ' and stop. Otherwise keep going.
        If lightColor = Color.red And _
           distance <= (_size.width + _speed) _
        Then
            dx = _direction.x * distance
            dy = _direction.y * distance
        Else
            dx = _direction.x * _speed
            dy = _direction.y * _speed
        End If

        _position.Translate(dx, dy)

        ' Draw the vehicle at its new location.
        Draw(_graphic, Color.black)
        _graphic = Nothing

        Return
    End Sub

    //
    // end of State Machine Actions
    //-----------------------------------------------------------

End Class
