package ocelot.desktop.ui.widget.statusbar

import ocelot.desktop.color.Color
import ocelot.desktop.geometry.{Padding2D, Size2D}
import ocelot.desktop.graphics.{Graphics, IconSource}
import ocelot.desktop.ui.UiHandler
import ocelot.desktop.ui.event.handlers.ClickHandler
import ocelot.desktop.ui.event.{ClickEvent, KeyEvent, MouseEvent}
import ocelot.desktop.ui.layout.{AlignItems, LinearLayout}
import ocelot.desktop.ui.widget._
import ocelot.desktop.ui.widget.contextmenu.{ContextMenu, ContextMenuEntry}
import ocelot.desktop.{ColorScheme, OcelotDesktop}
import org.lwjgl.input.Keyboard

import scala.collection.immutable.ArraySeq
import scala.concurrent.duration.DurationInt

class StatusBar extends Widget {
  override protected val layout: LinearLayout = new LinearLayout(this, alignItems = AlignItems.Center)

  override def minimumSize: Size2D = Size2D(100, 18)
  override def maximumSize: Size2D = Size2D(Float.PositiveInfinity, 18)
  override def receiveMouseEvents = true

  private val keyMouseEntries = new Widget
  private val keyEntries = new Widget
  private var showFPS = false

  eventHandlers += {
    case KeyEvent(KeyEvent.State.Press, Keyboard.KEY_F2, _) =>
      showFPS = !showFPS
      if (showFPS) {
        children :+= new PaddingBox(new Label {
          override def maximumSize: Size2D = minimumSize
          override def color: Color = ColorScheme("StatusBarFPS")
          override def text: String = f"FPS: ${UiHandler.fps}%02.1f"
        }, Padding2D(left = 8, right = 8))
      } else {
        children = children.take(2)
      }
  }

  children :+= new ScrollView(new Widget {
    children :+= keyMouseEntries
    children :+= keyEntries
  })
  {
    override def minimumSize: Size2D = inner.minimumSize.copy(width = 5f)
    override def maximumSize: Size2D = inner.minimumSize.copy(width = Float.PositiveInfinity)
    override def hThumbVisible: Boolean = false
  }

  children :+= new PaddingBox(new Label with ClickHandler {
    override def receiveMouseEvents: Boolean = true
    eventHandlers += {
      case ClickEvent(MouseEvent.Button.Right, pos) =>
        val menu = new ContextMenu
        menu.addEntry(ContextMenuEntry("Change simulation speed", IconSource.Edit) {
          new ChangeSimulationSpeedDialog().show()
        })

        menu.addEntry(ContextMenuEntry("Reset simulation speed", IconSource.Restart) {
          OcelotDesktop.ticker.tickInterval = 50.millis
        })

        if (OcelotDesktop.tickerIntervalHistory.nonEmpty)
          menu.addSeparator()

        for (elem <- OcelotDesktop.tickerIntervalHistory.reverseIterator) {
          menu.addEntry(ContextMenuEntry((1_000_000f / elem.toMicros).toString) {
            OcelotDesktop.ticker.tickInterval = elem
          })
        }

        root.get.contextMenus.open(menu, pos)
    }

    override def maximumSize: Size2D = minimumSize
    override def color: Color = ColorScheme("StatusBarTPS")
    override def text: String = f"TPS: ${OcelotDesktop.tpsCounter.fps}%02.1f"
  }, Padding2D(left = 8, right = 8))

  def addMouseEntry(icon: String, text: String): Unit = {
    if (!keyMouseEntries.children.filter(_.isInstanceOf[MouseEntry]).map(_.asInstanceOf[MouseEntry]).exists(_.icon == icon))
      keyMouseEntries.children :+= new MouseEntry(icon, text)
  }

  def addKeyMouseEntry(icon: String, key: String, text: String): Unit = {
    if (!keyMouseEntries.children.filter(_.isInstanceOf[KeyMouseEntry]).map(_.asInstanceOf[KeyMouseEntry]).exists(v => v.icon == icon && v.key == key))
      keyMouseEntries.children :+= new KeyMouseEntry(icon, key, text)
  }

  def addKeyEntry(key: String, text: String): Unit = {
    if (!keyEntries.children.map(_.asInstanceOf[KeyEntry]).exists(_.key == key))
      keyEntries.children :+= new KeyEntry(key, text)
  }

  override def draw(g: Graphics): Unit = {
    relayout()
    g.rect(bounds, ColorScheme("StatusBar"))
    g.line(position, position + Size2D(width, 0), 1, ColorScheme("StatusBarBorder"))
    drawChildren(g)
    keyEntries.children = ArraySeq.empty
    keyMouseEntries.children = ArraySeq.empty
  }
}
