package ocelot.desktop.ui.event.handlers

import ocelot.desktop.geometry.Vector2D
import ocelot.desktop.ui.UiHandler
import ocelot.desktop.ui.event.{DragEvent, MouseEvent}
import ocelot.desktop.ui.widget.Widget

import scala.collection.mutable

trait DragHandler extends Widget {
  private val startPositions = new mutable.HashMap[MouseEvent.Button.Value, Vector2D]()
  private val prevPositions = new mutable.HashMap[MouseEvent.Button.Value, Vector2D]()
  private val dragButtons = new mutable.HashSet[MouseEvent.Button.Value]()

  private val Tolerance = 8

  eventHandlers += {
    case MouseEvent(MouseEvent.State.Press, button) =>
      startPositions += (button -> UiHandler.mousePosition)

    case MouseEvent(MouseEvent.State.Release, button) =>
      val mousePos = UiHandler.mousePosition
      startPositions.remove(button)

      if (dragButtons.remove(button))
        handleEvent(DragEvent(DragEvent.State.Stop, button, mousePos))
  }

  override def update(): Unit = {
    super.update()

    val mousePos = UiHandler.mousePosition

    for ((button, startPos) <- startPositions) {
      if (!dragButtons.contains(button) && (startPos - mousePos).lengthSquared > Tolerance * Tolerance) {
        handleEvent(DragEvent(DragEvent.State.Start, button, mousePos, startPos, Vector2D(0, 0)))
        dragButtons += button
        prevPositions += (button -> mousePos)
      }
    }

    dragButtons.foreach(button => {
      handleEvent(DragEvent(DragEvent.State.Drag, button, mousePos, startPositions(button),
        mousePos - prevPositions(button)))
      prevPositions(button) = mousePos
    })
  }
}
