package ocelot.desktop.ui.widget

import ocelot.desktop.ColorScheme
import ocelot.desktop.audio.{ClickSoundSourceFactory, SoundSource}
import ocelot.desktop.color.Color
import ocelot.desktop.geometry.Size2D
import ocelot.desktop.graphics.Graphics
import ocelot.desktop.ui.event.handlers.{HoverHandler, MouseHandler}
import ocelot.desktop.ui.event.{ClickEvent, HoverEvent, MouseEvent}
import ocelot.desktop.ui.widget.tooltip.Tooltip
import ocelot.desktop.ui.widget.traits.HoverAnimation
import ocelot.desktop.util.DrawUtils

class Button(tooltip: Option[Tooltip] = None) extends Widget with MouseHandler with HoverHandler with HoverAnimation {

  def this(tooltip: Tooltip) = this(Some(tooltip))

  protected def colorScheme: ColorScheme = ColorScheme.General
  override protected val HoverAnimationColorDefault: Color = colorScheme("ButtonBackground")
  override protected val HoverAnimationColorActive: Color = colorScheme("ButtonBackgroundActive")

  def text: String = ""

  def onClick(): Unit = {}

  override protected def receiveClickEvents: Boolean = true

  eventHandlers += {
    case MouseEvent(MouseEvent.State.Pressed, MouseEvent.Button.Left) if enabled =>
      clickSoundSource.press.play()

    case ClickEvent(MouseEvent.Button.Left, _) if enabled =>
      onClick()
      clickSoundSource.release.play()
  }

  for (tooltip <- tooltip) {
    eventHandlers += {
      case HoverEvent(HoverEvent.State.Enter) => root.get.tooltipPool.addTooltip(tooltip)
      case HoverEvent(HoverEvent.State.Leave) => root.get.tooltipPool.closeTooltip(tooltip)
    }
  }

  override def minimumSize: Size2D = Size2D(24 + text.length * 8, 24)

  override def maximumSize: Size2D = minimumSize

  override def draw(g: Graphics): Unit = {
    val (background, border, foreground) = if (enabled) (
      hoverAnimation.color,
      colorScheme("ButtonBorder"),
      colorScheme("ButtonForeground"),
    )
    else (
      colorScheme("ButtonBackgroundDisabled"),
      colorScheme("ButtonBorderDisabled"),
      colorScheme("ButtonForegroundDisabled"),
    )

    g.rect(bounds, background)
    DrawUtils.ring(g, position.x, position.y, width, height, 2, border)

    g.background = Color.Transparent
    g.foreground = foreground
    val textWidth = text.iterator.map(g.font.charWidth(_)).sum
    g.text(position.x + ((width - textWidth) / 2).round, position.y + 4, text)
  }

  protected def clickSoundSource: ClickSoundSourceFactory = SoundSource.InterfaceClick
}
