// 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.

//go:build example
// +build example

//
// This build tag means that "go install golang.org/x/exp/shiny/..." doesn't
// install this example program. Use "go run main.go" to run it or "go install
// -tags=example" to install it.

// layout is an example of a laying out a widget node tree. Real GUI programs
// won't need to do this explicitly, as the shiny/widget package will
// coordinate with the shiny/screen package to call Measure, Layout and Paint
// as necessary, and will re-layout widgets when windows are re-sized. This
// program merely demonstrates how a widget node tree can be rendered onto a
// statically sized RGBA image, for visual verification of widget code without
// having to bring up and manually inspect an interactive GUI window.
package main

import (
	"fmt"
	"image"
	"image/color"
	"image/draw"
	"image/png"
	"log"
	"os"

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

var px = unit.Pixels

func colorPatch(c color.Color, w, h unit.Value) *widget.Sizer {
	return widget.NewSizer(w, h, widget.NewUniform(theme.StaticColor(c), nil))
}

func main() {
	t := theme.Default

	// Make the widget node tree.
	hf := widget.NewFlow(widget.AxisHorizontal,
		widget.NewLabel("Cyan:"),
		widget.WithLayoutData(
			colorPatch(color.RGBA{0x00, 0x7f, 0x7f, 0xff}, px(0), px(20)),
			widget.FlowLayoutData{AlongWeight: 1, ExpandAlong: true},
		),
		widget.NewLabel("Magenta:"),
		widget.WithLayoutData(
			colorPatch(color.RGBA{0x7f, 0x00, 0x7f, 0xff}, px(0), px(30)),
			widget.FlowLayoutData{AlongWeight: 2, ExpandAlong: true},
		),
		widget.NewLabel("Yellow:"),
		widget.WithLayoutData(
			colorPatch(color.RGBA{0x7f, 0x7f, 0x00, 0xff}, px(0), px(40)),
			widget.FlowLayoutData{AlongWeight: 3, ExpandAlong: true},
		),
	)

	vf := widget.NewFlow(widget.AxisVertical,
		colorPatch(color.RGBA{0xff, 0x00, 0x00, 0xff}, px(80), px(40)),
		colorPatch(color.RGBA{0x00, 0xff, 0x00, 0xff}, px(50), px(50)),
		colorPatch(color.RGBA{0x00, 0x00, 0xff, 0xff}, px(20), px(60)),
		widget.WithLayoutData(
			hf,
			widget.FlowLayoutData{ExpandAcross: true},
		),
		widget.NewLabel(fmt.Sprintf(
			"The black rectangle is 1.5 inches x 1 inch when viewed at %v DPI.", t.GetDPI())),
		widget.NewPadder(widget.AxisBoth, unit.Pixels(8),
			colorPatch(color.Black, unit.Inches(1.5), unit.Inches(1)),
		),
	)

	// Make the RGBA image.
	const width, height = 640, 480
	rgba := image.NewRGBA(image.Rect(0, 0, width, height))
	draw.Draw(rgba, rgba.Bounds(), t.GetPalette().Neutral(), image.Point{}, draw.Src)

	// Measure, layout and paint.
	vf.Measure(t, width, height)
	vf.Rect = rgba.Bounds()
	vf.Layout(t)
	vf.PaintBase(&node.PaintBaseContext{
		Theme: t,
		Dst:   rgba,
	}, image.Point{})

	// Encode to PNG.
	out, err := os.Create("out.png")
	if err != nil {
		log.Fatalf("os.Create: %v", err)
	}
	defer out.Close()
	if err := png.Encode(out, rgba); err != nil {
		log.Fatalf("png.Encode: %v", err)
	}
	fmt.Println("Wrote out.png OK.")
}
