package components

import (
	"fmt"

	"gitea.unprism.ru/yotia/display-test/drawer"
)

type progressBar struct {
	drawer   drawer.Drawer // Drawer with dysplay
	mask     mask          // Flush mask
	progress float64

	rect rect // Rect
}

type ProgressBar interface {
	Component

	SetProgress(coef float64) // Value from 0 to 1
	Clear()                   // Clear space of bar
}

// Creation function
// Now the only way to chage shape is to recreate component
func NewProgressBar(drawer drawer.Drawer, x, y, w, h int) (ProgressBar, error) {
	if err := drawer.GetDisplay().IsReady(); err != nil {
		return nil, fmt.Errorf("display is ready: %w", err)
	}

	// Check for correct sizes
	if w < 4 {
		return nil, fmt.Errorf("invalid width: below 4")
	}
	if h < 4 {
		return nil, fmt.Errorf("invalid height: below 4")
	}
	pb := progressBar{
		drawer: drawer,
		rect:   rect{x, y, w, h},
	}

	pb.mask.Update(pb.rect)
	// pb.Draw()

	return &pb, nil
}

func (pb *progressBar) flush() {
	pb.drawer.GetDisplay().FlushByMask(pb.mask.bits)
}

func (pb *progressBar) Close() error {
	return nil
}

func (pb *progressBar) Clear() {
	pb.drawer.FillBar(pb.rect.x, pb.rect.y, pb.rect.x+pb.rect.w, pb.rect.y+pb.rect.h, 0x00)
}

// Draw whole bar
func (pb *progressBar) Draw() {
	// Shape:
	// Bounds - 1px
	// Padding - 1px
	// Progress - the rest space
	pb.Clear()
	pb.drawer.PutBar(pb.rect.x, pb.rect.y, pb.rect.x+pb.rect.w, pb.rect.y+pb.rect.h, 0xFF)
	pb.drawBar()
	pb.flush()
}

// Draw only bar(without frames)
func (pb *progressBar) drawBar() {
	w := int(float64(pb.rect.w-4) * pb.progress)

	pb.drawer.FillBar(pb.rect.x+2, pb.rect.y+2, pb.rect.x+2+w, pb.rect.y+pb.rect.h-2, 0xFF)
}

func (pb *progressBar) SetProgress(coef float64) {
	pb.progress = max(0, min(1, coef))

	pb.drawBar()
	pb.flush()
}

func (pb *progressBar) GetPos() (int, int) {
	return pb.rect.x, pb.rect.y
}

func (pb *progressBar) GetSize() (int, int) {
	return pb.rect.w, pb.rect.h
}