package mainwindow

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

type Layer struct {
	Idx          int
	defaultColor uint32
}

func (layer *Layer) before() *Layer {
	blt.Layer(layer.Idx)
	return layer
}

func (layer *Layer) WithRawColor(c uint32) *Layer {
	layer.before()
	blt.Color(c)
	return layer
}

func (layer *Layer) WithColor(colorName string) *Layer {
	layer.before()
	c := blt.ColorFromName(colorName)
	blt.Color(c)
	return layer
}

func (layer *Layer) PutWithRawBackground(x,y int, symbol interface{}, bgColor uint32) {
	layer.before()
	prevColor := uint32(blt.State(blt.TK_COLOR))
	prevCompMode := blt.State(blt.TK_COMPOSITION)
	blt.Color(bgColor)
	blt.Composition(1)
	layer.Put(x,y,"█")
	blt.Color(prevColor)
	layer.Put(x,y, symbol)
	blt.Composition(prevCompMode)

}

func (layer *Layer) PutWithBackground(x,y int, symbol interface{}, bgColorName string) {
	layer.before()
	prevColor := uint32(blt.State(blt.TK_COLOR))
	prevCompMode := blt.State(blt.TK_COMPOSITION)
	c := blt.ColorFromName(bgColorName)
	blt.Color(c)
	blt.Composition(1)
	layer.Put(x,y,"█")
	blt.Color(prevColor)
	layer.Put(x,y, symbol)
	blt.Composition(prevCompMode)
}

func (Layer *Layer) PutToBase(x,y int, symbol interface{}, fg uint32, bg uint32) {
	if symbol == nil {
		return
	}
	rnes := []rune(symbol.(string))
	prevColor := uint32(blt.State(blt.TK_COLOR))
	prevBgColor := uint32(blt.State(blt.TK_BKCOLOR))
	blt.Layer(0)
	blt.BkColor(bg)
	blt.Color(fg)
	if (len(rnes)) > 0 {
		blt.Put(x, y, int(rnes[0]))
	}
	blt.Color(prevColor)
	blt.BkColor(prevBgColor)
}

func (layer *Layer) after() *Layer {
	blt.Color(layer.defaultColor)
	blt.Layer(0)
	return layer
}

func (layer Layer) Put(x, y int, symbol interface{}) {
	if symbol == nil {
		return
	}
	rnes := []rune(symbol.(string))
	if (len(rnes)) > 0 {
		blt.Put(x, y, int(rnes[0]))
	}
}

func (layer Layer) Print(x, y int, txt string) (w, h int) {
	w, h = blt.Print(x, y, txt)
	//blt.Layer(0)
	return w, h
}

func (layer Layer) PrintInside(rect types.Rect, text string, alignment int) (width int, height int) {
	return blt.PrintExt(rect.X + 2, rect.Y + 2, rect.W - 4, rect.H - 4, alignment, text)
}

func (layer Layer) PutStringInto(rect types.Rect, topOffset int, string string, alignment int) bool {
	if len(string) > rect.W - 2 {
		string = string[:rect.W-5]+"..."
	}
	if topOffset > rect.H - 2 {
		return false
	}
	blt.PrintExt(rect.X + 2, rect.Y + topOffset + 2, rect.W - 4, rect.H - 4, alignment, string)
	return true
}

func (layer *Layer) Decorate(f func(args ...interface{})) func(args ...interface{}) {
	return func(args ...interface{}) {
		layer.before()
		f(args)
		layer.after()
	}
}

func (layer *Layer) ClearRect(r types.Rect) {
	prevLayer := int(blt.State(blt.TK_LAYER))
	blt.Layer(layer.Idx)
	blt.ClearArea(r.X, r.Y, r.W, r.H)
	blt.Layer(prevLayer)
}

func (layer *Layer) ClearArea(x,y,w,h int) {
	layer.before()
	blt.ClearArea(x,y,w,h)
	layer.after()
}


func (layer *Layer) Render() {

}
