Imports System.Collections
Imports System.Windows.Forms
Imports System.Drawing

Public Class Mediator
  Private startRect As Boolean
  Private selectedIndex As Integer
  Private rectb As RectButton
  Private dSelected As Boolean
  Private drawings As ArrayList
  Private undoList As ArrayList
  Private rbutton As RectButton
  Private filbutton As FillButton
  Private circButton As CircleButton
  Private arrowButton As PickButton
  Private canvas As PictureBox
  Private selectedDrawing As Integer
  Private stmgr As StateManager
  '-----
  Public Sub New(ByVal pic As PictureBox)
    startRect = False
    dSelected = False
    drawings = New ArrayList()
    undoList = New ArrayList()
    stmgr = New StateManager(Me)
    canvas = pic
    selectedDrawing = -1
  End Sub
  '-----
  Public Sub startRectangle()
    stmgr.setRect()
    arrowButton.Pushed = False
    circButton.Pushed = False
    filbutton.Pushed = False
  End Sub
  '-----
  Public Sub startCircle()
    Dim st As State
    stmgr.setCircle()
    rectb.Pushed = False
    arrowButton.Pushed = False
    filbutton.Pushed = False
  End Sub
  '-----
  Public Sub startFill()
    Dim m As FillMemento
    stmgr.setFill()
    rectb.Pushed = False
    circButton.Pushed = False
    arrowButton.Pushed = False
    If selectedDrawing >= 0 Then
      stmgr.selectOne(getDrawing(selectedDrawing))
      m = New FillMemento(selectedDrawing, Me)
      undoList.Add(m)
    End If
    repaint()
  End Sub
  '-----
  Public Sub startArrow()
    stmgr.setArrow()
    rectb.Pushed = False
    circButton.Pushed = False
    filbutton.Pushed = False
  End Sub
  '-----
  Public Function getSelected() As Drawing
    getSelected = CType(drawings(selectedDrawing), Drawing)
  End Function
  '-----
  Public Sub fillSelected()
    Dim m As FillMemento
    Dim d As Drawing
    If (dSelected) Then
      d = CType(drawings(selectedDrawing), Drawing)
      d.setFill(True)
      m = New FillMemento(selectedDrawing, Me)
      undoList.Add(m)
    End If
  End Sub
  '-----
  Public Function getDrawings() As ArrayList
    getDrawings = drawings
  End Function
  '-----
  Public Sub addDrawing(ByVal d As Drawing)
    drawings.Add(d)
    Dim intc As New DrawInstance(drawings.Count - 1, Me)
    undoList.Add(intc)
  End Sub
  '-----
  Public Sub registerRectButton(ByVal rb As RectButton)
    rectb = rb
  End Sub
  '-----
  Public Sub registerCircleButton(ByVal cb As CircleButton)
    circButton = cb
  End Sub
  '-----
  Public Sub registerArrowButton(ByVal ab As PickButton)
    arrowButton = ab
  End Sub
  '-----
  Public Sub registerFillButton(ByVal fb As FillButton)
    filbutton = fb
  End Sub
  '-----
  Public Sub registerCanvas(ByVal p As PictureBox)
    canvas = p
  End Sub
  '-----
  Public Sub mouseDown(ByVal x As Integer, ByVal y As Integer)
    stmgr.mouseDown(x, y)
    repaint()
  End Sub
  '-----
  Public Sub mouseUp(ByVal x As Integer, ByVal y As Integer)
    stmgr.mouseUp(x, y)
  End Sub
  '-----
  Public Sub unpick()
    Dim d As Drawing
    dSelected = False
    If (selectedDrawing >= 0) Then
      d = getDrawing(selectedDrawing)
      If Not (d Is Nothing) Then
        d.setSelected(False)
      End If
      selectedDrawing = -1
      repaint()
    End If
  End Sub
  '-----
  Public Sub rememberPosition()
    Dim m As Memento
    Dim d As Drawing
    If dSelected Then
      d = CType(drawings(selectedDrawing), Drawing)
      m = New DrawMemento(d)
      undoList.Add(m)
    End If
  End Sub
  '-----
  Public Sub setSelected(ByVal index As Integer)
    Dim d As Drawing
    dSelected = True
    selectedDrawing = index
    d = getDrawing(index)
    d.setSelected(True)
    repaint()
  End Sub
  '-----
  Public Sub pickRect(ByVal x As Integer, ByVal y As Integer)
  End Sub
  '-----
  Public Sub clear()
    drawings = New ArrayList()
    undoList = New ArrayList()
    dSelected = False
    selectedDrawing = 0
    repaint()
  End Sub
  '-----
  Private Sub repaint()
    canvas.Refresh()
  End Sub
  '-----
  Public Sub mouseDrag(ByVal x As Integer, ByVal y As Integer)
    stmgr.mouseDrag(x, y)
    repaint()
  End Sub
  '-----
  Public Sub reDraw(ByVal g As Graphics)
    Dim i As Integer
    Dim v As Drawing

    For i = 0 To drawings.Count - 1
      v = getDrawing(i)
      v.draw(g)
    Next i
  End Sub
  '-----
  Public Sub undo()
    Dim obj As Object
    Dim drawObj As Object
    Dim m As Memento
    rectb.Pushed = False
    circButton.Pushed = False
    arrowButton.Pushed = False

    If (undoList.Count > 0) Then
      'Pobierz element z listy wycofań
      obj = undoList(undoList.Count - 1)
      undoList.RemoveAt(undoList.Count - 1)
      'Pobierz memento
      m = CType(obj, Memento)
      m.restore()   'I odtwóz poprzednią pozycję
      repaint()
    End If
  End Sub
  '-----
  Public Sub removeDrawing(ByVal a As Integer)
    drawings.RemoveAt(a)
  End Sub
  '-----
  Public Function getDrawing(ByVal a As Integer) As Drawing
    If a < drawings.Count Then
      Return CType(drawings(a), Drawing)
    Else
      Return Nothing
    End If
  End Function
  '-----
  Public Function findDrawing(ByVal x As Integer, ByVal y As Integer) As Integer
    Dim index As Integer, i As Integer, found As Boolean
    Dim d As Drawing
    i = 0
    index = -1
    While i < drawings.Count And Not found
      d = getDrawing(i)
      If d.contains(x, y) Then
        index = i
        found = True
      End If
      i = i + 1
    End While
    findDrawing = index
  End Function

End Class
