// 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"
	"image/draw"

	"golang.org/x/exp/shiny/text"
	"golang.org/x/exp/shiny/unit"
	"golang.org/x/exp/shiny/widget/node"
	"golang.org/x/exp/shiny/widget/theme"
	"golang.org/x/image/font"
	"golang.org/x/image/math/fixed"
)

// Text is a leaf widget that holds a text label.
type Text struct {
	node.LeafEmbed
	frame   text.Frame
	faceSet bool

	// TODO: scrolling, although should that be the responsibility of this
	// widget, the parent widget or something else?
}

// NewText returns a new Text widget.
func NewText(text string) *Text {
	w := &Text{}
	w.Wrapper = w
	if text != "" {
		c := w.frame.NewCaret()
		c.WriteString(text)
		c.Close()
	}
	return w
}

func (w *Text) Measure(t *theme.Theme) {
	// TODO: implement. Should the Measure method include a width hint?
	w.MeasuredSize = image.Point{}
}

func (w *Text) Layout(t *theme.Theme) {
	// TODO: can a theme change at runtime, or can it be set only once, at
	// start-up?
	if !w.faceSet {
		w.faceSet = true
		// TODO: when is face released? Should we just unconditionally call
		// SetFace for every Measure, Layout and Paint? How do we avoid
		// excessive re-calculation of soft returns when re-using the same
		// logical face (as in "Times New Roman 12pt") even if using different
		// physical font.Face values (as each Face may have its own caches)?
		face := t.AcquireFontFace(theme.FontFaceOptions{})
		w.frame.SetFace(face)
	}

	// TODO: should padding (and/or margin and border) be a universal concept
	// and part of the node.Embed type instead of having each widget implement
	// its own?
	padding := t.Pixels(unit.Ems(0.5)).Ceil()
	w.frame.SetMaxWidth(fixed.I(w.Rect.Dx() - 2*padding))
}

func (w *Text) Paint(t *theme.Theme, dst *image.RGBA, origin image.Point) {
	w.Marks.UnmarkNeedsPaint()
	dst = dst.SubImage(w.Rect.Add(origin)).(*image.RGBA)
	if dst.Bounds().Empty() {
		return
	}

	face := t.AcquireFontFace(theme.FontFaceOptions{})
	defer t.ReleaseFontFace(theme.FontFaceOptions{}, face)
	m := face.Metrics()
	ascent := m.Ascent.Ceil()
	descent := m.Descent.Ceil()
	height := m.Height.Ceil()

	padding := t.Pixels(unit.Ems(0.5)).Ceil()

	draw.Draw(dst, dst.Bounds(), t.GetPalette().Background(), image.Point{}, draw.Src)

	minDotY := fixed.I(dst.Bounds().Min.Y - descent)
	maxDotY := fixed.I(dst.Bounds().Max.Y + ascent)

	x0 := fixed.I(origin.X + w.Rect.Min.X + padding)
	d := font.Drawer{
		Dst:  dst,
		Src:  t.GetPalette().Foreground(),
		Face: face,
		Dot: fixed.Point26_6{
			X: x0,
			Y: fixed.I(origin.Y + w.Rect.Min.Y + padding + ascent),
		},
	}
	f := &w.frame
	for p := f.FirstParagraph(); p != nil; p = p.Next(f) {
		for l := p.FirstLine(f); l != nil; l = l.Next(f) {
			if d.Dot.Y > minDotY {
				if d.Dot.Y >= maxDotY {
					return
				}
				for b := l.FirstBox(f); b != nil; b = b.Next(f) {
					d.DrawBytes(b.TrimmedText(f))
					// TODO: adjust d.Dot.X for any ligatures?
				}
				d.Dot.X = x0
			}
			d.Dot.Y += fixed.I(height)
		}
	}
}
