// package cursor -- глобальный курсор на экране
package cursor

import (
	"fmt"

	"github.com/gdamore/tcell"

	"p78git.ddns.net/svi/libtui/alias"
	"p78git.ddns.net/svi/libtui/lib/line_cell/cell"
	"p78git.ddns.net/svi/libtui/types"
)

// Cursor -- курсор на экране
type Cursor struct {
	*cell.Cell
	app       types.IKernel
	screen    types.IScreen
	isVisible alias.IsVisible
}

// NewCursor -- возвращает новый объект экранного курсора
func NewCursor(app types.IKernel) (*Cursor, error) {
	if app == nil {
		return nil, fmt.Errorf("NewScrCursor(): IScreen==nil")
	}
	sf := &Cursor{
		app:       app,
		screen:    app.Screen(),
		Cell:      cell.NewCell(),
		isVisible: true,
	}
	sf.SetLit(alias.Lit([]rune("↖")[0]))
	return sf, nil
}

// Draw -- отрисовка курсора на экране
func (sf *Cursor) Draw() {
	sf.screen.SetCell(sf)
	posX, posY := sf.Pos()
	strOut := fmt.Sprintf("WinDebug.Draw(): pos=%v:%v", posX, posY)
	colorFg := tcell.NewRGBColor(200, 200, 200)
	style1 := tcell.StyleDefault
	colorBg := tcell.NewRGBColor(0, 0, 255)
	style1 = style1.Foreground(colorFg).Background(colorBg)
	sf.drawText(alias.Style(style1), strOut)
}

func (sf *Cursor) drawText(style alias.Style, text string) {
	posX0, posY0 := sf.Pos()
	posX, posY := posX0, posY0
	// Сначала вычислить квадрант экрана
	sizeX, sizeY := sf.screen.Size()
	if alias.SizeX(posX) >= sizeX/2 { // Кусор в правой половине
		posX -= 30
	} else {
		posX += 5
	}
	if alias.SizeY(posY) >= sizeY/2 { // Курсор в нижней половине
		posY -= 5
	} else {
		posY += 5
	}
	for adr, r := range text {
		cell := cell.NewCell()
		cell.SetPos(posX+alias.PosX(adr), posY)
		cell.SetLit(alias.Lit(r))
		cell.SetStyle(style)
		sf.screen.SetCell(cell)
	}
}

// SetPos -- устанавливает позицию курсора с подстройкой фона
func (sf *Cursor) SetPos(posX alias.PosX, posY alias.PosY) {
	cell := sf.screen.GetCell(posX, posY)
	color := cell.BgColor()
	sf.BgColorSet(color)
	sf.Cell.SetPos(posX, posY)
}

// Hide -- скрывает курсор от отображения
func (sf *Cursor) Hide() {
	sf.isVisible = false
}

// Show -- показывает курсор для отображения
func (sf *Cursor) Show() {
	sf.isVisible = true
}

// IsVisible -- возвращает признак отображения курсора
func (sf *Cursor) IsVisible() alias.IsVisible {
	return sf.isVisible
}
