' D. de Haas
' Amsterdam, Netherlands
' 29 October 2002
' ddhadam@yahoo.com

Option Explicit On 
Option Strict On

Imports System
Imports System.Drawing

Namespace Graphics

    Public Class Line
        ' Graphical Line, that is actually a collection of blocks

        ' All stages a line can be
        Public Enum StatusType
            Empty
            Filled
            Full
        End Enum

        Private mLines As New Graphics.BlockCollection()
        Private mX, mY, mLinesize, mCount As Integer
        Private mStatus As StatusType

        '==== Events

        '==== Constructors

        Public Sub New(ByVal x As Integer, ByVal y As Integer, ByVal blockSize As Integer, ByVal blockCount As Integer)
            ' Create a new Line on postition (x,y) and with size (blocksize) in pixels

            mX = x
            mY = y
            mLinesize = blockSize
            mCount = blockCount
        End Sub

        '==== Private Methods/Functions

        '==== Public Functions

        Public Function Clone() As Graphics.Line
            ' Creates a copy

            Dim flc As New Graphics.Line(mX, mY, mLinesize, mCount)

            Dim bl As Graphics.Block
            Dim n As Integer

            ' All blocks in the line will be added to the copy
            For n = 0 To mLines.Count - 1
                bl = mLines.Item(n)
                If Not (bl Is Nothing) Then flc.Insert(n, bl.Clone)
            Next

            Return flc
        End Function

        Public Function Insert(ByVal index As Integer, ByVal block As Graphics.Block) As Integer
            ' Add a block the line on the (index) location

            If index >= mCount Then Throw New ArgumentOutOfRangeException()

            Dim bl As Graphics.Block

            ' Make a copy of the block the will fit the line
            bl = block.Clone
            bl.BlockSize = mLinesize
            bl.SetPos(mX + (index * mLinesize), mY)

            ' Add block to the line
            mLines.Insert(index, bl)

            ' Set status of the line
            Dim n, m As Integer
            For n = 0 To mLines.Count - 1
                bl = mLines.Item(n)
                If Not (bl Is Nothing) Then m += 1
            Next

            Select Case m
                Case 0
                    mStatus = StatusType.Empty

                Case mCount
                    mStatus = StatusType.Full

                Case Else
                    mStatus = StatusType.Filled

            End Select
        End Function

        '==== Public Methodes

        Public Sub SetPos(ByVal x As Integer, ByVal y As Integer)
            ' Set the line to the give position (x,y) in pixels

            Dim bl As Block
            Dim n As Integer

            ' Move all blocks in the line to the new position
            For n = 0 To mLines.Count - 1
                bl = mLines.Item(n)
                If Not (bl Is Nothing) Then bl.SetPos(x + (bl.X - mX), y)
            Next

            mX = x
            mY = y
        End Sub

        Public Sub Draw(ByRef graph As System.Drawing.Graphics)
            ' Draws the line

            Dim bl As Block
            Dim n As Integer

            ' Draw all blocks in the line
            For n = 0 To mLines.Count - 1
                bl = mLines.Item(n)
                If Not (bl Is Nothing) Then bl.Draw(graph)
            Next

        End Sub

        Public Sub Clear()
            ' Clears the line

            mLines.Clear()
            mStatus = StatusType.Empty
        End Sub

        '==== Properties

        Public ReadOnly Property X() As Integer
            Get
                Return mX
            End Get
        End Property

        Public ReadOnly Property Y() As Integer
            Get
                Return mY
            End Get
        End Property

        Default Public ReadOnly Property Item(ByVal index As Integer) As Graphics.Block
            Get
                Return mLines.Item(index)
            End Get
        End Property

        Public ReadOnly Property BlockSize() As Integer
            Get
                Return mLinesize
            End Get
        End Property

        Public ReadOnly Property Count() As Integer
            Get
                Return mCount
            End Get
        End Property

        Public ReadOnly Property Status() As StatusType
            Get
                Return mStatus
            End Get
        End Property

    End Class

End Namespace
