// package widget -- базовый виджет для построения других виджетов
package widget

import (
	"fmt"

	"github.com/gdamore/tcell"

	"p78git.ddns.net/svi/libtui/alias"
	"p78git.ddns.net/svi/libtui/lib/color"
	"p78git.ddns.net/svi/libtui/lib/line_cell"
	"p78git.ddns.net/svi/libtui/lib/line_cell/cell"
	"p78git.ddns.net/svi/libtui/lib/pos"
	"p78git.ddns.net/svi/libtui/lib/safe_bool"
	"p78git.ddns.net/svi/libtui/lib/size"
	"p78git.ddns.net/svi/libtui/types"
)

// Widget -- базовый виджет для построения других виджетов
type Widget struct {
	app       types.IKernel
	screen    types.IScreen
	pos       types.IPos
	size      types.ISize
	bufLine   []*line_cell.LineCell
	bgColor   types.IColor
	fgColor   types.IColor
	isVisible types.ISafeBool
	style     alias.Style
	lit       alias.Lit
	isWisible types.ISafeBool
}

// NewWidget -- возвращает новый виджет
func NewWidget(app types.IKernel) (*Widget, error) {
	if app == nil {
		return nil, fmt.Errorf("NewWidget(): IApp==nil")
	}
	sf := &Widget{
		app:       app,
		screen:    app.Screen(),
		pos:       pos.NewPos(),
		size:      size.NewSize(),
		bufLine:   make([]*line_cell.LineCell, 0),
		bgColor:   color.NewColor(),
		fgColor:   color.NewColor(),
		isVisible: safe_bool.NewSafeBool(),
		style:     0,
		lit:       alias.Lit([]rune("d")[0]),
		isWisible: safe_bool.NewSafeBool(),
	}
	sf.bgColor.Set(0, 0, 255)
	sf.fgColor.Set(0, 255, 0)
	color := tcell.Color(sf.bgColor.Get())
	sf.style = alias.Style(tcell.StyleDefault.Background(color).Foreground(tcell.Color(sf.fgColor.Get())))
	sf.Resize(15, 5)
	sf.isVisible.Set()
	return sf, nil
}

// Draw -- отрисовывает виджет потребованию
func (sf *Widget) Draw() {
	if !sf.isVisible.Get() {
		return
	}
	for _, line := range sf.bufLine {
		line.Draw()
	}
	/*
		cell := cell.NewCell()
		cell.SetLit(alias.Lit([]rune("=")[0]))
		st0 := tcell.StyleDefault
		st0 = st0.Background(tcell.ColorBlue).Foreground(tcell.ColorYellow)
		scr := sf.app.Scr()
		x0, y0 := sf.Pos()
		for x := x0; x < x0+20; x++ {
			for y := y0; y < y0+5; y++ {
				// cell.SetPos(x, y)
				scr.SetCell(int(x), int(y), st0, []rune("`")[0])
			}
		}
	*/
}

// FgColor -- возвращает цвет переднего фона
func (sf *Widget) FgColor() types.IColor {
	return sf.fgColor
}

// BgColor -- возвращает цвет фона
func (sf *Widget) BgColor() types.IColor {
	return sf.bgColor
}

// Size -- возвращает объект размера виджета
func (sf *Widget) Size() (alias.SizeX, alias.SizeY) {
	return sf.size.Get()
}

// Resize -- изменяет размер виджета
func (sf *Widget) Resize(sizeX alias.SizeX, sizeY alias.SizeY) {
	sf.size.Set(sizeX, sizeY)
	posX, posY := sf.pos.Get()
	bufLine := make([]*line_cell.LineCell, 0)
	fnAddLine := func(_y_ alias.PosY) {
		line, err := line_cell.NewLineCell(sf.app)
		if err != nil {
			fmt.Printf("Widget.Resize().fnAddLine(): in crete line_cell, err=\n\t%v\n", err)
			sf.app.CancelApp()
			return
		}
		for dx := posX; dx < posX+alias.PosX(sizeX); dx++ {
			cell_ := cell.NewCell()
			cell_.SetStyle(sf.style)
			cell_.BgColorSet(sf.bgColor.Get())
			cell_.FgColorSet(sf.FgColor().Get())
			cell_.SetLit(sf.lit)
			cell_.SetPos(dx, _y_)
			if err = line.AddCell(cell_); err != nil {
				fmt.Printf("Widget.Resize().fnAddLine(): in crete cell, err=\n\t%v\n", err)
				sf.app.CancelApp()
				return
			}
		}
		sf.bufLine = append(sf.bufLine, line)
	}

	for dy := posY; dy < posY+alias.PosY(sizeY); dy++ {
		fnAddLine(dy)
	}
	sf.bufLine = bufLine
}

// Pos -- возвращает размера виджета
func (sf *Widget) Pos() (alias.PosX, alias.PosY) {
	return sf.pos.Get()
}

// SetPos -- устанавливает позицию виджета на экране
func (sf *Widget) SetPos(posX alias.PosX, posY alias.PosY) {
	sf.pos.Set(posX, posY)
	for _, line := range sf.bufLine {
		line.SetPos(posX, posY)
	}
}

// Show -- показать виджет
func (sf *Widget) Show() {
	sf.isVisible.Set()
}

// Hide -- скрывает виджет
func (sf *Widget) Hide() {
	sf.isVisible.Reset()
}

// IsVisible -- признак видимости окна
func (sf *Widget) IsVisible() alias.IsVisible {
	return alias.IsVisible(sf.isVisible.Get())
}
