package alui

import (
	"opslag.de/schobers/allg5"
	"opslag.de/schobers/geom"
)

var _ Control = &StackPanel{}

type StackPanel struct {
	Container

	Orientation Orientation
}

func (s *StackPanel) asLength(p geom.PointF32) float32 {
	switch s.Orientation {
	case OrientationHorizontal:
		return p.X
	default:
		return p.Y
	}
}

func (s *StackPanel) asWidth(p geom.PointF32) float32 {
	switch s.Orientation {
	case OrientationHorizontal:
		return p.Y
	default:
		return p.X
	}
}

func (s *StackPanel) asSize(length, width float32) geom.PointF32 {
	switch s.Orientation {
	case OrientationHorizontal:
		return geom.PtF32(length, width)
	default:
		return geom.PtF32(width, length)
	}
}

func (s *StackPanel) CalculateLayout(ctx *Context) ([]geom.PointF32, geom.PointF32) {
	desired := make([]geom.PointF32, len(s.Children))
	for i, child := range s.Children {
		desired[i] = child.DesiredSize(ctx)
	}
	var length, width float32
	for _, size := range desired {
		w, l := s.asWidth(size), s.asLength(size)
		if geom.IsNaN32(w) {
			width = geom.NaN32()
		} else if !geom.IsNaN32(width) {
			width = geom.Max32(width, w)
		}
		if geom.IsNaN32(l) {
			panic("not implemented")
		}
		length += l
	}
	switch s.Orientation {
	case OrientationHorizontal:
		return desired, geom.PtF32(length, width)
	default:
		return desired, geom.PtF32(width, length)
	}
}

func (s *StackPanel) DesiredSize(ctx *Context) geom.PointF32 {
	_, size := s.CalculateLayout(ctx)
	return size
}

func (s *StackPanel) Handle(e allg5.Event) {
	s.Container.Handle(e)
}

func (s *StackPanel) Layout(ctx *Context, bounds geom.RectangleF32) {
	s.Container.Layout(ctx, bounds)

	desired, _ := s.CalculateLayout(ctx)
	width := s.asWidth(bounds.Size())

	var offset = bounds.Min
	for i, child := range s.Children {
		length := s.asLength(desired[i])
		childSize := s.asSize(length, width)
		var bottomRight = offset.Add(childSize)
		var childBounds = geom.RectF32(offset.X, offset.Y, bottomRight.X, bottomRight.Y)
		child.Layout(ctx, childBounds)
		offset = offset.Add(s.asSize(length, 0))
	}
}

func (s *StackPanel) Render(ctx *Context, bounds geom.RectangleF32) {
	for _, child := range s.Children {
		child.Render(ctx, child.Bounds())
	}
}
