package ocelot.desktop.windows

import ocelot.desktop.color.{Color, IntColor}
import ocelot.desktop.entity.OpenFMRadio
import ocelot.desktop.geometry.{Padding2D, Size2D}
import ocelot.desktop.graphics.{Graphics, IconSource}
import ocelot.desktop.node.nodes.OpenFMRadioNode
import ocelot.desktop.ui.layout.{AlignItems, Layout, LinearLayout}
import ocelot.desktop.ui.widget._
import ocelot.desktop.ui.widget.window.BasicWindow
import ocelot.desktop.util.Orientation

class OpenFMRadioWindow(radioNode: OpenFMRadioNode) extends BasicWindow {
  private val scale = 2f

  private def radio: OpenFMRadio = radioNode.openFMRadio

  override def minimumSize: Size2D = new Size2D(232 * scale, 105 * scale)
  override protected val layout: Layout = new LinearLayout(this, Orientation.Vertical)

  // Volume controls
  children :+= new PaddingBox(
    new Widget {
      override protected val layout: Layout = new LinearLayout(this,
        orientation = Orientation.Horizontal, alignItems = AlignItems.Start)

      // Volume up/down buttons
      private def addVolumeUpOrDownButton(isUp: Boolean, x: Float): Unit = {
        children :+= new PaddingBox(
          new IconButton(
            IconSource.Buttons.OpenFMRadioVolumeOff(isUp),
            IconSource.Buttons.OpenFMRadioVolumeOn(isUp),
            sizeMultiplier = scale,
          ) {
            override def onClicked(): Unit = {
              if (isUp)
                radio.volUp()
              else
                radio.volDown()
            }
          },
          Padding2D(0, 0, 0, x),
        )
      }

      addVolumeUpOrDownButton(isUp = false, 0)

      // Volume label
      children :+= new PaddingBox(
        new Label {
          override def maximumSize: Size2D = Size2D(20, 20)
          override def text: String = (radio.volume * 10).floor.toInt.toString
          override def color: Color = Color.White
        },
        Padding2D(2, 0, 0, 20),
      )

      addVolumeUpOrDownButton(isUp = true, 8)

      // Redstone button
      children :+= new PaddingBox(
        new IconButton(
          IconSource.Buttons.OpenFMRadioRedstoneOff,
          IconSource.Buttons.OpenFMRadioRedstoneOn,
          mode = IconButton.Mode.Switch,
          sizeMultiplier = scale,
          model = new IconButton.Model { override var pressed: Boolean = radio.isListenRedstone },
        ),
        Padding2D(0, 0, 0, 128),
      )

      // Close button
      children :+= new PaddingBox(
        new IconButton(
          IconSource.Buttons.OpenFMRadioCloseOff,
          IconSource.Buttons.OpenFMRadioCloseOn,
          sizeMultiplier = scale,
        ) {
          override def onClicked(): Unit = close()
        },
        Padding2D(0, 0, 0, 10),
      )
    },
    Padding2D(8, 0, 0, 188),
  )

  // Url text input
  children :+= new PaddingBox(
    new TextInput(radio.url.getOrElse("")) {
      override def minimumSize: Size2D = Size2D(402, 20)
      override def maximumSize: Size2D = Size2D(402, 20)

      override def onConfirm(): Unit = {
        super.onConfirm()
        radio.url = Option(text)
      }
    },
    Padding2D(5, 0, 0, 32),
  )

  // Start/stop button
  children :+= new PaddingBox(
    new IconButton(
      IconSource.Buttons.OpenFMRadioStartOff,
      IconSource.Buttons.OpenFMRadioStopOn,
      mode = IconButton.Mode.Switch,
      sizeMultiplier = scale,
      model = IconButton.ReadOnlyModel(radio.isPlaying),
    ) {
      override def onPressed(): Unit = radio.play()
      override def onReleased(): Unit = radio.stop()
    },
    Padding2D(13, 0, 0, 208),
  )

  // Color / text titles
  children :+= new PaddingBox(
    new Widget {
      override protected val layout: Layout = new LinearLayout(this,
        orientation = Orientation.Horizontal, alignItems = AlignItems.Start)

      // Color title
      children :+= new Label {
        override def text: String = "Screen color"
        override def color: Color = Color.White
      }

      // Text title
      children :+= new Label {
        override def text: String = "Screen text"
        override def color: Color = Color.White
      }
    },
    Padding2D(10, 0, 0, 30),
  )

  // Color / text text inputs
  children :+= new PaddingBox(
    new Widget {
      override protected val layout: Layout = new LinearLayout(this,
        orientation = Orientation.Horizontal, gap = 46)

      // Color
      children :+= new TextInput(radio.screenColor.color.toHexString.toUpperCase) {
        override def minimumSize: Size2D = Size2D(118, 20)
        override def maximumSize: Size2D = Size2D(118, 20)

        override def onConfirm(): Unit = {
          super.onConfirm()
          radio.screenColor = IntColor(Integer.parseInt(text, 16))
        }

        override def validator(text: String): Boolean = {
          try {
            Integer.parseInt(text, 16)
            true
          } catch {
            case _: Throwable => false
          }
        }
      }

      // Text
      // thanks, captain obvious
      children :+= new TextInput(radio.screenText) {
        override def maximumSize: Size2D = Size2D(240, 20)

        override def onConfirm(): Unit = {
          super.onConfirm()
          radio.screenText = text
        }
      }
    },
    Padding2D(1, 0, 0, 30),
  )

  // OpenFM logo
  children :+= new PaddingBox(
    new Label {
      override def text: String = "OpenFM"
      override def color: Color = Color.White
    },
    Padding2D(22, 0, 0, 210),
  )

  override def draw(g: Graphics): Unit = {
    beginDraw(g)
    // I hate this
    g.sprite(IconSource.Window.OpenFMRadio, position.x, position.y, size.width, size.height)
    drawChildren(g)
    endDraw(g)
  }
}
