package screens

import (
    "fmt"
    "lab.zaar.be/thefish/alchemyst-go/engine/types"
    "lab.zaar.be/thefish/alchemyst-go/ui/mainwindow"
    blt "lab.zaar.be/thefish/bearlibterminal"
    "strings"
)

const runeIndex = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

type MenuScreen struct {
    types.Rect

    mw           *mainwindow.MainWindow
    scm          *types.ScreenManager
    renderParent bool

    items  []interface{}
    offset int

    drawFunc  func()
    inputFunc func(string)

    title   string
    header  string
    footer  string
    redraw  bool
    bgColor string
    fgColor string
}

func NewMenuScreen(mw *mainwindow.MainWindow, scm *types.ScreenManager, title, header, footer string, rect types.Rect, renderParent bool) *MenuScreen {
    return &MenuScreen{
        title:        title,
        header:       header,
        footer:       footer,
        Rect:         rect,
        mw:           mw,
        scm:          scm,
        renderParent: renderParent,
    }
}

func (ms *MenuScreen) MakeList() *MenuScreen {
    ms.drawFunc = ms.ListRender
    ms.inputFunc = ms.ListHandleInput
    return ms
}

func (ms *MenuScreen) SetBgColor(color string) *MenuScreen {
    ms.bgColor = color
    return ms
}

func (ms *MenuScreen) SetFgColor(color string) *MenuScreen {
    ms.fgColor = color
    return ms
}

//fixme!!

func (ms *MenuScreen) SetItems(items []interface{}) *MenuScreen {
    ms.items = items
    return ms
}

func (ms *MenuScreen) UseEcs() bool { return false }

func (ms *MenuScreen) Enter() {
    ms.redraw = true
    ms.offset = 0
}

func (ms *MenuScreen) HandleInput(input string) {
    ms.inputFunc(input)
}

func (ms *MenuScreen) Exit() {
    menuLayer := ms.mw.GetLayer("menu")
    menuLayer.ClearRect(ms.Rect)
    bgLayer := ms.mw.GetLayer("menubg")
    bgLayer.ClearRect(ms.Rect)
}

func (ms *MenuScreen) Render() {
    if ms.renderParent {
        ms.scm.PreviousScreen.Render()
    }
    if ms.redraw || ms.renderParent {
        ms.redraw = false
        ms.drawFunc()
    }
}

func (ms *MenuScreen) ListHandleInput(input string) {
    switch input {
    case "Up", "k":
        ms.offset = ms.offset - 1
        if ms.offset < 0 {
            ms.offset = 0
        }
        break
    case "Down", "j":
        ms.offset = ms.offset + 1
        if ms.offset > len(ms.items)-1 {
            ms.offset = len(ms.items) - 1
        }
        break
    case "Escape":
        fallthrough
    case "Space":
        ms.scm.SetScreen(ms.scm.PreviousScreen)
        break
    }
}

func (ms *MenuScreen) ListRender() {
    menuLayer := ms.mw.GetLayer("menu")
    menuLayer.ClearRect(ms.Rect)
    bgLayer := ms.mw.GetLayer("menubg")
    bgLayer.ClearRect(ms.Rect)
    bgLayer.WithColor(ms.bgColor).NewWindow(ms.Rect).Splash()
    menuLayer.WithColor(ms.fgColor).NewWindow(ms.Rect).DoubleBordered(ms.title)
    menuLayer.Print(ms.X+(ms.W/2)-7, ms.Y+ms.H-1, "╡"+"[color=green]Space[/color] to close"+"╞")
    footerHeight := 0
    if ms.footer != "" {
        _, footerHeight = menuLayer.PrintInside(ms.Rect, ms.footer, 9)
        footerHeight = footerHeight + 2
    }
    _, headerHeight := menuLayer.PrintInside(ms.Rect, ms.header, blt.TK_ALIGN_LEFT)
    itemField := types.Rect{ms.X, ms.Y + headerHeight + 1, ms.W, ms.H - headerHeight - footerHeight}
    _ = itemField
    var ilw, ilh int
    if len(ms.items) > 0 {
        //fixme itemfield object, scroller, inputhandler, current selected item
        menuItems := make([]string, 0)
        for i := ms.offset; i < len(ms.items); i++ {
            if string(ms.items[i].(string)) != "" {
                menuItems = append(menuItems, ms.items[i].(string))
            }
        }
        ilw, ilh = menuLayer.PrintInside(itemField, strings.Join(menuItems, "\n"), blt.TK_ALIGN_LEFT)
    }
    if ilh < len(ms.items) {
        ms.drawScrollBar(menuLayer, itemField)
    }
    if ilw > itemField.W-4 {
        fmt.Printf("Excess width of item names found! Need h-scroll of certain names")
    }
}

func (ms *MenuScreen) drawScrollBar(menuLayer *mainwindow.Layer, itemField types.Rect) {
    scrollbarBg := types.NewRect(itemField.X+itemField.W-2, itemField.Y+1, 1, itemField.H-4)
    menuLayer.WithColor("#77000000").NewWindow(scrollbarBg).Splash()
    //tick
    menuLayer.WithColor(ms.fgColor).Put(
        scrollbarBg.X,
        scrollbarBg.Y+int(float64(ms.offset)/float64(len(ms.items))*float64(scrollbarBg.H)),
        "⏹",
    )
    menuLayer.WithColor(ms.fgColor).Put(itemField.X+itemField.W-2, itemField.Y+scrollbarBg.H+1, "↓")
    menuLayer.WithColor(ms.fgColor).Put(itemField.X+itemField.W-2, itemField.Y, "↑")

}