package ocelot.desktop.ui.widget.itemdrag

import ocelot.desktop.inventory.Item
import ocelot.desktop.ui.UiHandler
import ocelot.desktop.ui.event.handlers.MouseHandler
import ocelot.desktop.ui.event.{DragEvent, MouseEvent}
import ocelot.desktop.ui.layout.Layout
import ocelot.desktop.ui.widget.Widget
import ocelot.desktop.ui.widget.slot.SlotWidget

import scala.collection.immutable.ArraySeq

class DraggedItemPool extends Widget with MouseHandler {
  override protected val layout: Layout = new Layout(this) {
    override def relayout(): Unit = {
      for (draggedItem <- draggedItem) {
        draggedItem.rawSetPosition(UiHandler.mousePosition)
      }

      super.relayout()
    }
  }

  private def canExchangeItems(targetSlot: SlotWidget[_ <: Item], draggedItem: DraggedItem): Boolean =
    targetSlot.item.forall(targetItem => draggedItem.slot.isItemAccepted(targetItem.factory))

  eventHandlers += { case DragEvent(DragEvent.State.Stop, MouseEvent.Button.Left, pos) =>
    for (item <- draggedItem) {
      val target = UiHandler.getHierarchy.reverseIterator
        .find(w => w.enabled && w.receiveMouseEvents && w.clippedBounds.contains(pos))

      target match {
        case Some(slot: SlotWidget[_]) if slot.isItemAccepted(item.item.factory) && canExchangeItems(slot, item) =>
          for (targetItem <- slot.item) {
            slot.item = None
            item.slot.setItem(targetItem)
          }

          slot.setItem(item.item)

        case _ =>
          item.slot.setItem(item.item)
      }

      draggedItem = None
    }
  }

  private var _draggedItem: Option[DraggedItem] = None

  def draggedItem: Option[DraggedItem] = _draggedItem

  def draggedItem_=(item: Option[DraggedItem]): Unit = {
    item match {
      case Some(item) => children = ArraySeq(item)
      case None => children = ArraySeq.empty
    }

    _draggedItem = item
  }

  def draggedItem_=(item: DraggedItem): Unit = {
    draggedItem = Some(item)
  }

  override protected def receiveDragEvents: Boolean = true

  override def receiveMouseEvents: Boolean = false

  override def receiveAllMouseEvents: Boolean = true

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

    for (item <- draggedItem) {
      item.position = UiHandler.mousePosition
    }
  }
}
