package ocelot.desktop.ui.widget

import ocelot.desktop.ColorScheme
import ocelot.desktop.color.Color
import ocelot.desktop.geometry.Size2D
import ocelot.desktop.graphics.Graphics
import ocelot.desktop.ui.event.handlers.MouseHandler
import ocelot.desktop.ui.event.{ClickEvent, MouseEvent}
import ocelot.desktop.ui.widget.traits.HoverAnimation
import ocelot.desktop.util.DrawUtils

class Checkbox(val label: String, val initialValue: Boolean = false, val isSmall: Boolean = false)
    extends Widget with MouseHandler with HoverAnimation {

  override protected val HoverAnimationColorDefault: Color = ColorScheme("CheckboxBackground")
  override protected val HoverAnimationColorActive: Color = ColorScheme("CheckboxBackgroundActive")

  private var _checked: Boolean = initialValue

  def checked: Boolean = _checked

  def checked_=(value: Boolean): Unit = {
    if (_checked != value) {
      _checked = value
      onValueChanged(value)
    }
  }

  def check(): Unit = checked = true
  def uncheck(): Unit = checked = false
  def toggle(): Unit = checked = !checked

  protected def onValueChanged(newValue: Boolean): Unit = {}

  override protected def receiveClickEvents: Boolean = true

  eventHandlers += {
    case ClickEvent(MouseEvent.Button.Left, _) => toggle()
  }

  private val boxSize: Float = if (isSmall) 12 else 16

  private var corrected: Boolean = false
  private var textWidth = label.length * 8
  private def wideWidth(g: Graphics): Int = label.map(g.font.charWidth(_)).sum

  override def minimumSize: Size2D = Size2D(textWidth, if (isSmall) 8 else 16)
  override def maximumSize: Size2D = minimumSize.copy(width = Float.PositiveInfinity)

  override def draw(g: Graphics): Unit = {
    if (isSmall) g.setSmallFont()

    if (!corrected) {
      textWidth = wideWidth(g)
      corrected = true
    }

    g.rect(position.x, position.y, boxSize, boxSize, hoverAnimation.color)
    DrawUtils.ring(g, position.x, position.y, boxSize, boxSize, 2, ColorScheme("CheckboxBorder"))

    g.background = Color.Transparent

    if (checked) {
      g.line(position.x + 1, position.y + boxSize / 2 + 1,
        position.x + boxSize / 4 + 1, position.y + boxSize / 4 * 3 + 1, 3, ColorScheme("CheckboxForeground"))
      g.line(position.x + boxSize / 4, position.y + boxSize / 4 * 3 + 1,
        position.x + boxSize - 1, position.y + 2, 3, ColorScheme("CheckboxForeground"))
    }

    g.foreground = ColorScheme("CheckboxLabel")
    g.text(position.x + boxSize + 8, position.y, label)

    g.setNormalFont()
  }
}
