1// Copyright 2019 Graham Clark. All rights reserved.  Use of this source
2// code is governed by the MIT license that can be found in the LICENSE
3// file.
4
5// Package fill provides a widget that can be filled with a styled rune.
6package fill
7
8import (
9	"fmt"
10
11	"github.com/gcla/gowid"
12)
13
14//======================================================================
15
16type ISolidFill interface {
17	Cell() gowid.Cell
18}
19
20type IWidget interface {
21	gowid.IWidget
22	ISolidFill
23}
24
25type Widget struct {
26	cell gowid.Cell
27	gowid.RejectUserInput
28	gowid.NotSelectable
29}
30
31func New(chr rune) *Widget {
32	res := &Widget{cell: gowid.CellFromRune(chr)}
33	var _ gowid.IWidget = res
34	return res
35}
36
37func NewEmpty() *Widget {
38	return NewSolidFromCell(gowid.Cell{})
39}
40
41func NewSolidFromCell(cell gowid.Cell) *Widget {
42	res := &Widget{cell: cell}
43	var _ gowid.IWidget = res
44	return res
45}
46
47func (w *Widget) String() string {
48	r := ' '
49	if w.Cell().HasRune() {
50		r = w.Cell().Rune()
51	}
52	return fmt.Sprintf("fill[%c]", r)
53}
54
55func (w *Widget) Cell() gowid.Cell {
56	return w.cell
57}
58
59func (w *Widget) SetCell(c gowid.Cell, app gowid.IApp) {
60	w.cell = c
61}
62
63func (w *Widget) RenderSize(size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) gowid.IRenderBox {
64	return RenderSize(w, size, focus, app)
65}
66
67func (w *Widget) Render(size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) gowid.ICanvas {
68	return Render(w, size, focus, app)
69}
70
71//''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
72
73func RenderSize(w interface{}, size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) gowid.IRenderBox {
74	cols, haveCols := size.(gowid.IColumns)
75	rows, haveRows := size.(gowid.IRows)
76	switch {
77	case haveCols && haveRows:
78		return gowid.RenderBox{C: cols.Columns(), R: rows.Rows()}
79	case haveCols:
80		return gowid.RenderBox{C: cols.Columns(), R: 1}
81	default:
82		panic(gowid.WidgetSizeError{Widget: w, Size: size})
83	}
84}
85
86func Render(w ISolidFill, size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) gowid.ICanvas {
87	// If a col and row not provided, what can I choose??
88	cols2, ok := size.(gowid.IColumns)
89	if !ok {
90		panic(gowid.WidgetSizeError{Widget: w, Size: size, Required: "gowid.IColumns"})
91	}
92
93	cols := cols2.Columns()
94	rows := 1
95	if irows, ok2 := size.(gowid.IRows); ok2 {
96		rows = irows.Rows()
97	}
98
99	fill := w.Cell()
100	fillArr := make([]gowid.Cell, cols)
101	for i := 0; i < cols; i++ {
102		fillArr[i] = fill
103	}
104
105	res := gowid.NewCanvas()
106	if rows > 0 {
107		res.AppendLine(fillArr, false)
108		for i := 0; i < rows-1; i++ {
109			res.Lines = append(res.Lines, make([]gowid.Cell, 0, 120))
110		}
111	}
112	res.AlignRightWith(w.Cell())
113
114	return res
115}
116
117//======================================================================
118// Local Variables:
119// mode: Go
120// fill-column: 110
121// End:
122