// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package widget

import (
	"image"

	"golang.org/x/exp/shiny/widget/node"
	"golang.org/x/exp/shiny/widget/theme"
)

// TODO: padding, alignment.

// Flow is a container widget that lays out its children in sequence along an
// axis, either horizontally or vertically. The children's laid out size may
// differ from their natural size, along or across that axis, if a child's
// LayoutData is a FlowLayoutData.
type Flow struct {
	node.ContainerEmbed
	Axis Axis
}

// NewFlow returns a new Flow widget containing the given children.
func NewFlow(a Axis, children ...node.Node) *Flow {
	w := &Flow{
		Axis: a,
	}
	w.Wrapper = w
	for _, c := range children {
		w.Insert(c, nil)
	}
	return w
}

func (w *Flow) Measure(t *theme.Theme, widthHint, heightHint int) {
	if w.Axis != AxisHorizontal && w.Axis != AxisVertical {
		w.ContainerEmbed.Measure(t, widthHint, heightHint)
		return
	}

	if w.Axis == AxisHorizontal {
		widthHint = node.NoHint
	}
	if w.Axis == AxisVertical {
		heightHint = node.NoHint
	}

	mSize := image.Point{}
	for c := w.FirstChild; c != nil; c = c.NextSibling {
		c.Wrapper.Measure(t, widthHint, heightHint)
		if w.Axis == AxisHorizontal {
			mSize.X += c.MeasuredSize.X
			if mSize.Y < c.MeasuredSize.Y {
				mSize.Y = c.MeasuredSize.Y
			}
		} else {
			mSize.Y += c.MeasuredSize.Y
			if mSize.X < c.MeasuredSize.X {
				mSize.X = c.MeasuredSize.X
			}
		}
	}
	w.MeasuredSize = mSize
}

func (w *Flow) Layout(t *theme.Theme) {
	if w.Axis != AxisHorizontal && w.Axis != AxisVertical {
		w.ContainerEmbed.Layout(t)
		return
	}

	eaExtra, eaWeight := 0, 0
	if w.Axis == AxisHorizontal {
		eaExtra = w.Rect.Dx()
	} else {
		eaExtra = w.Rect.Dy()
	}
	for c := w.FirstChild; c != nil; c = c.NextSibling {
		if d, ok := c.LayoutData.(FlowLayoutData); ok && d.ExpandAlongWeight > 0 {
			eaWeight += d.ExpandAlongWeight
		}
		if w.Axis == AxisHorizontal {
			eaExtra -= c.MeasuredSize.X
		} else {
			eaExtra -= c.MeasuredSize.Y
		}
	}
	if eaExtra < 0 {
		eaExtra = 0
	}

	p := image.Point{}
	for c := w.FirstChild; c != nil; c = c.NextSibling {
		q := p.Add(c.MeasuredSize)
		if d, ok := c.LayoutData.(FlowLayoutData); ok {
			if d.ExpandAlongWeight > 0 {
				delta := eaExtra * d.ExpandAlongWeight / eaWeight
				eaExtra -= delta
				eaWeight -= d.ExpandAlongWeight
				if w.Axis == AxisHorizontal {
					q.X += delta
				} else {
					q.Y += delta
				}
			}
			if d.ExpandAcross {
				if w.Axis == AxisHorizontal {
					q.Y = max(q.Y, w.Rect.Dy())
				} else {
					q.X = max(q.X, w.Rect.Dx())
				}
			}
		}
		c.Rect = image.Rectangle{
			Min: p,
			Max: q,
		}
		c.Wrapper.Layout(t)
		if w.Axis == AxisHorizontal {
			p.X = q.X
		} else {
			p.Y = q.Y
		}
	}
}

// FlowLayoutData is the node LayoutData type for a Flow's children.
type FlowLayoutData struct {
	// ExpandAlongWeight is the relative weight for distributing any excess
	// space along the Flow's axis. For example, if an AxisHorizontal Flow's
	// Rect width was 100 pixels greater than the sum of its children's natural
	// widths, and three children had non-zero FlowLayoutData.ExpandAlongWeight
	// values 6, 3 and 1, then those children's laid out widths would be larger
	// than their natural widths by 60, 30 and 10 pixels.
	ExpandAlongWeight int

	// ExpandAcross is whether the child's laid out size should expand to fill
	// the Flow's cross-axis. For example, if an AxisHorizontal Flow's Rect
	// height was 80 pixels, any child whose FlowLayoutData.ExpandAcross was
	// true would also be laid out with at least an 80 pixel height.
	ExpandAcross bool
}
