package ocelot.desktop.ui.widget.modal

import ocelot.desktop.color.RGBAColorNorm
import ocelot.desktop.geometry.Size2D
import ocelot.desktop.graphics.Graphics
import ocelot.desktop.ui.UiHandler
import ocelot.desktop.ui.event.ClickEvent
import ocelot.desktop.ui.event.handlers.MouseHandler
import ocelot.desktop.ui.layout.Layout
import ocelot.desktop.ui.widget.Widget
import ocelot.desktop.util.animation.UnitAnimation

import scala.collection.immutable.ArraySeq

class ModalDialogPool extends Widget with MouseHandler {
  override protected val layout: Layout = new Layout(this) {
    override def relayout(): Unit = {
      for (child <- children) {
        child.rawSetPosition(position + ((size - child.size) / 2).toVector.round)
      }

      super.relayout()
    }
  }

  private val curtainsAlphaAnimation = UnitAnimation.easeInOutQuad(0.13f)

  private def dialogs: ArraySeq[ModalDialog] = children.map(_.asInstanceOf[ModalDialog])

  def isVisible: Boolean = dialogs.nonEmpty

  def pushDialog(dialog: ModalDialog): Unit = this.synchronized {
    children :+= dialog
    root.get.contextMenus.closeAll()
    dialog.open()
  }

  def popDialog(): Unit = {
    dialogs.last.close()
  }

  override def minimumSize: Size2D = Size2D.Zero
  override def maximumSize: Size2D = Size2D.Inf

  override protected def receiveClickEvents: Boolean = true

  override def receiveMouseEvents: Boolean = dialogs.nonEmpty
  override def receiveScrollEvents: Boolean = dialogs.nonEmpty

  eventHandlers += {
    case ClickEvent(_, pos) =>
      if (dialogs.nonEmpty && dialogs.forall(_.autoClose)) {
        if (dialogs.forall(!_.bounds.contains(pos)))
          dialogs.foreach(_.close())
      }
  }

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

    if (dialogs.isEmpty)
      curtainsAlphaAnimation.goDown()
    else if (dialogs.length == 1) {
      if (dialogs.head.isClosing)
        curtainsAlphaAnimation.goDown()
      else
        curtainsAlphaAnimation.goUp()
      if (dialogs.head.isClosed)
        children = ArraySeq.empty
    } else if (dialogs.head.isClosed) {
      children = children.take(children.length - 1)
    }

    curtainsAlphaAnimation.update()
  }

  override def draw(g: Graphics): Unit = {
    if (curtainsAlphaAnimation.value > 0.01f)
      g.rect(root.get.bounds, RGBAColorNorm(0f, 0f, 0f, curtainsAlphaAnimation.value * 0.5f))

    drawChildren(g)
  }
}
