package ocelot.desktop.ui.widget

import ocelot.desktop.ColorScheme
import ocelot.desktop.color.Color
import ocelot.desktop.graphics.{Graphics, IconSource}

import scala.collection.mutable.ArrayBuffer

class Histogram extends Widget {
  var value = "N/A"
  var title = "Hello world"
  var history: ArrayBuffer[Float] = ArrayBuffer(50)

  private def drawBars(g: Graphics): Unit = {
    def drawBarSegment(i: Int, color: Color): Unit = {
      g.sprite(IconSource.BarSegment, position.x, position.y + i * 6, 16, 4, color)
      g.sprite(IconSource.BarSegment, position.x + 18, position.y + i * 6, 16, 4, color)
    }

    val ratio = history.last
    val fillBars = (ratio * 10).round
    val emptyBars = (9 - fillBars).max(0)

    for (i <- 0 until emptyBars)
      drawBarSegment(i, ColorScheme("HistogramBarEmpty"))

    for (i <- emptyBars + 1 until 10)
      drawBarSegment(i, ColorScheme("HistogramBarFill"))

    drawBarSegment(emptyBars, ColorScheme("HistogramBarTop"))

    drawText(g, position.x + 17, value)
  }

  private def drawText(g: Graphics, x: Float, text: String): Unit = {
    g.setSmallFont()
    g.background = Color.Transparent
    g.text(x - text.length * 4, position.y + 62, text)
    g.setNormalFont()
  }

  private def drawHistogram(g: Graphics): Unit = {
    val marginLeft = 41
    val marginBottom = 12
    var x = position.x + marginLeft

    val cellThickness = 2f
    val cellSize = 11f
    val horizontalLineCount = ((height - cellThickness - marginBottom) / cellSize).toInt
    val verticalLineCount = ((width - cellThickness - marginLeft) / cellSize).toInt
    val gridWidth = verticalLineCount * cellSize
    val gridHeight = horizontalLineCount * cellSize

    // Text
    drawText(g, x + gridWidth / 2, title)

    // Horizontal lines
    for (i <- 0 until horizontalLineCount + 1)
      g.rect(x, position.y + i * cellSize, gridWidth, cellThickness, ColorScheme("HistogramGrid"))

    // Additional line closes grid from right
    for (i <- 0 until verticalLineCount + 1) {
      val lesserThenPreLast = i < verticalLineCount - 1

      // Vertical line
      g.rect(
        x,
        position.y,
        cellThickness,
        if (lesserThenPreLast) gridHeight else gridHeight + cellThickness,
        ColorScheme("HistogramGrid"),
      )

      // History
      val historyIndex = history.length - verticalLineCount + i - 1
      val historyValueWidth = if (i < verticalLineCount) cellSize else cellThickness
      var historyValueHeight: Float = cellThickness

      // Value fill
      if (historyIndex > 0) {
        val historyValue = history(historyIndex)

        historyValueHeight = (historyValue * (gridHeight + cellThickness)).max(cellThickness)

        g.rect(
          x,
          position.y + gridHeight + cellThickness - historyValueHeight,
          historyValueWidth,
          historyValueHeight,
          ColorScheme("HistogramFill"),
        )
      }

      // Value line
      g.rect(
        x,
        position.y + gridHeight + cellThickness - historyValueHeight,
        historyValueWidth,
        cellThickness,
        ColorScheme("HistogramEdge"),
      )

      x += cellSize
    }
  }

  override def draw(g: Graphics): Unit = {
    drawBars(g)
    drawHistogram(g)
  }
}
