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

import (
	"fmt"

	"github.com/gdamore/tcell"

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

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

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

// Draw -- отрисовывает виджет потребованию
func (sf *Widget) Draw() {
	if !sf.isVisible.Get() {
		return
	}
	for _, cell := range sf.bufCell {
		sf.screen.SetCell(cell)
	}
}

// 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) {
	x_, y_ := sf.size.Get()
	if x_ == sizeX && y_ == sizeY {
		return
	}
	sf.size.Set(sizeX, sizeY)
	posX, posY := sf.pos.Get()
	bufCellNew := make([]types.ICell, 0)
	lenBuf := len(sf.bufCell)
	for dx := alias.PosX(0); dx < alias.PosX(sizeX); dx++ {
		for dy := alias.PosY(0); dy < alias.PosY(sizeY); dy++ {
			ind := int(dx) * int(dy)
			var cell_ types.ICell
			if lenBuf != 0 && lenBuf > ind {
				cell_ = sf.bufCell[ind]
			} else {
				cell_ = cell.NewCell()
				cell_.SetStyle(sf.style)
				cell_.BgColorSet(sf.bgColor.Get())
				cell_.FgColorSet(sf.FgColor().Get())
				cell_.SetLit(sf.lit)
			}
			cell_.SetPos(dx+posX, dy+posY)
			bufCellNew = append(bufCellNew, cell_)
		}
	}
	sf.bufCell = bufCellNew
}

// 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)
}
