package dev.fyloz.plannervio.ui.view

import dev.fyloz.plannervio.core.service.locateI18nService
import dev.fyloz.plannervio.core.service.svgGlyph
import dev.fyloz.plannervio.ui.style.Style
import javafx.geometry.Pos
import javafx.scene.control.Label
import javafx.scene.layout.HBox
import javafx.scene.layout.Pane
import javafx.scene.layout.Region
import javafx.scene.layout.VBox
import javafx.scene.paint.Color
import kfoenix.JFXStylesheet.Companion.jfxRipplerFill
import kfoenix.jfxrippler
import tornadofx.*

/**
 * A view. Inheriting this class allows to automatically link the FXML file and the CSS files for the current theme to the fragment.
 * If a presenter class is provided, the presenter will also be created.
 *
 * @constructor Initialize the view, linking the FXML and the CSS files.
 */
abstract class AbstractView : View() {
    /**
     * Gets the name of the view's files in kebab-case.
     */
    val filename by lazy {
        javaClass.simpleName
            .split("(?=[A-Z])".toRegex())
            .map { it.toLowerCase() }
            .filter { it.isNotEmpty() }
            .filter { it != "view" }
            .joinToString("-")
    }

    protected val i18nService = locateI18nService(filename)

    init {
        messages = i18nService.bundle
    }

//    final override val root: Pane = loadFXML("/fxml/views/${filename}.fxml")
}

/**
 * A fragment of the view. Inheriting this class allows to automatically link the FXML file and the CSS files for the current theme to the fragment.
 *
 * @property view The view which the fragment is linked to.
 * @constructor Initialize the fragment, linking the FXML and the CSS files.
 */
abstract class AbstractFragment(val view: AbstractView? = null) : Fragment() {
    protected val i18nService = locateI18nService(view?.filename)

    init {
        messages = i18nService.bundle
    }
}

/** Shorthand to create a [TabButton] in a [View]. */
fun View.tabButton(tab: Tab, onClick: (TabButton) -> Unit): TabButton {
    return TabButton(tab).apply {
        alignment = Pos.BOTTOM_LEFT
        textFill = Color.RED
        graphic = hbox {
            paddingTop = 2
            this += pane {
                hboxMargin(top = 8)
                addClass(Style.jfxSvgGlyphWrapper)
                this += svgGlyph(tab.icon, size = 16.0, color = Color.WHITE)!!
            }
            this += Label(messages[tab.i18nText])
        }
        setOnMouseClicked { onClick(this) }
    }
}

fun Region.vboxMargin(all: Number = 0) {
    this.vboxMargin(all, all)
}

fun Region.vboxMargin(horizontal: Number = 0, vertical: Number = 0) {
    this.vboxMargin(vertical, horizontal, vertical, horizontal)
}

fun Region.vboxMargin(top: Number = 0, right: Number = 0, bottom: Number = 0, left: Number = 0) {
    VBox.setMargin(this, insets(top.toDouble(), right.toDouble(), bottom.toDouble(), left.toDouble()))
}

fun Region.hboxMargin(all: Number = 0) {
    this.hboxMargin(all, all)
}

fun Region.hboxMargin(horizontal: Number = 0, vertical: Number = 0) {
    this.hboxMargin(vertical, horizontal, vertical, horizontal)
}

fun Region.hboxMargin(top: Number = 0, right: Number = 0, bottom: Number = 0, left: Number = 0) {
    HBox.setMargin(this, insets(top.toDouble(), right.toDouble(), bottom.toDouble(), left.toDouble()))
}
