package ocelot.desktop.ui.widget.settings

import ocelot.desktop.Settings
import ocelot.desktop.geometry.{Padding2D, Size2D}
import ocelot.desktop.graphics.IconSource
import ocelot.desktop.ui.UiHandler
import ocelot.desktop.ui.layout.LinearLayout
import ocelot.desktop.ui.widget.{Checkbox, Label, PaddingBox, Slider, Widget}
import ocelot.desktop.util.MathUtils.roundAt

class UISettingsTab extends SettingsTab {
  override val icon: IconSource = IconSource.Icons.SettingsUI
  override val label: String = "UI"

  override def applySettings(): Unit = {
    if (UiHandler.fullScreen != Settings.get.windowFullscreen) {
      UiHandler.fullScreen = Settings.get.windowFullscreen
    }

    if (UiHandler.scalingFactor != Settings.get.scaleFactor) {
      UiHandler.scalingFactor = Settings.get.scaleFactor
    }

    UiHandler.root.workspaceView.windowPool.refreshWindows()
  }

  children :+= new PaddingBox(
    new Checkbox("Pin newly opened windows",
      initialValue = Settings.get.pinNewWindows) {
      override def minimumSize: Size2D = Size2D(512, 24)

      override def onValueChanged(value: Boolean): Unit = {
        Settings.get.pinNewWindows = value
      }
    },
    Padding2D(bottom = 8),
  )

  children :+= new PaddingBox(
    new Checkbox("Fullscreen mode",
      initialValue = Settings.get.windowFullscreen) {
      override def minimumSize: Size2D = Size2D(512, 24)

      override def onValueChanged(value: Boolean): Unit = {
        Settings.get.windowFullscreen = value
        applySettings()
      }
    },
    Padding2D(bottom = 8),
  )

  children :+= new PaddingBox(
    new Checkbox("Save workspace on exit",
      initialValue = Settings.get.saveOnExit) {
      override def minimumSize: Size2D = Size2D(512, 24)

      override def onValueChanged(value: Boolean): Unit = {
        Settings.get.saveOnExit = value
      }
    },
    Padding2D(bottom = 8),
  )

  children :+= new PaddingBox(
    new Checkbox("Re-open last workspace on startup",
      initialValue = Settings.get.openLastWorkspace) {
      override def minimumSize: Size2D = Size2D(512, 24)

      override def onValueChanged(value: Boolean): Unit = {
        Settings.get.openLastWorkspace = value
      }
    },
    Padding2D(bottom = 8),
  )

  children :+= new PaddingBox(
    new Checkbox("Show previews on screen blocks",
      initialValue = Settings.get.renderScreenDataOnNodes) {
      override def minimumSize: Size2D = Size2D(512, 24)

      override def onValueChanged(value: Boolean): Unit = {
        Settings.get.renderScreenDataOnNodes = value
      }
    },
    Padding2D(bottom = 8),
  )

  children :+= new PaddingBox(
    new Checkbox("Enable mipmaps for screen windows",
      initialValue = Settings.get.screenWindowMipmap) {
      override def minimumSize: Size2D = Size2D(512, 24)

      override def onValueChanged(value: Boolean): Unit = {
        Settings.get.screenWindowMipmap = value
      }
    },
    Padding2D(bottom = 8),
  )

  children :+= new PaddingBox(
    new Checkbox("Enable festive decorations",
      initialValue = Settings.get.enableFestiveDecorations) {
      override def minimumSize: Size2D = Size2D(512, 24)

      override def onValueChanged(value: Boolean): Unit = {
        Settings.get.enableFestiveDecorations = value
      }
    },
    Padding2D(bottom = 8),
  )

  children :+= new PaddingBox(
    new Slider((Settings.get.scaleFactor - 1) / 2, "Interface scale", 5) {
      override def minimumSize: Size2D = Size2D(512, 24)

      // Interpolates [0; 1] as [1; 3] rounded to nearest 0.5
      private def convertToScale(slider: Float): Float = (slider * 4 + 2).round.max(2).min(6) / 2.0f

      override def formatText: String = f"$text: ${convertToScale(value)}%.1fx"

      override def onValueFinal(value: Float): Unit = {
        Settings.get.scaleFactor = convertToScale(value)
        applySettings()
      }
    },
    Padding2D(bottom = 8),
  )

  children :+= new PaddingBox(
    new Slider(Settings.get.unfocusedWindowTransparency, "Inactive window") {
      override def minimumSize: Size2D = Size2D(512, 24)

      override def formatText: String = if (value < 0.001f) s"$text: hide" else f"$text: ${value * 100}%.0f%% opacity"

      override def onValueFinal(value: Float): Unit = {
        Settings.get.unfocusedWindowTransparency = value
        Settings.get.unfocusedWindowHide = value < 0.001f
        applySettings()
      }
    },
    Padding2D(bottom = 8),
  )

  children :+= new PaddingBox(new Label("Tooltip delays:"), Padding2D(bottom = 8))

  children :+= new PaddingBox(
    new Widget {
      override val layout = new LinearLayout(this)

      children :+= new Slider(Settings.get.tooltipDelayItem / 2.0f, "Items") {
        override def minimumSize: Size2D = Size2D(247, 24)

        private def convert(value: Float): Float = roundAt(2)(value * 2.0f).toFloat
        override def formatText: String = f"$text: ${convert(value)}%.2f s"

        override def onValueFinal(value: Float): Unit = {
          // we are treating 0 as 0.001 to keep the legacy behaviour
          Settings.get.tooltipDelayItem = convert(value) max 0.001f min 2.0f
        }
      }

      children :+= new Widget {
        override def maximumSize: Size2D = Size2D(16, 8)
      }

      children :+= new Slider(Settings.get.tooltipDelayUI / 2.0f, "UI Elements") {
        override def minimumSize: Size2D = Size2D(247, 24)

        private def convert(value: Float): Float = roundAt(2)(value * 2.0f).toFloat
        override def formatText: String = f"$text: ${convert(value)}%.2f s"

        override def onValueFinal(value: Float): Unit = {
          // we are treating 0 as 0.001 to keep the legacy behaviour
          Settings.get.tooltipDelayUI = convert(value) max 0.001f min 2.0f
        }
      }
    },
    Padding2D(bottom = 16),
  )
}
