From d4734846fc09568040eb06e036d687770499d556 Mon Sep 17 00:00:00 2001
From: Leon Mika <lmika@lmika.org>
Date: Sun, 21 Aug 2022 09:38:02 +1000
Subject: [PATCH] issue-11: added the last two views

---
 internal/dynamo-browse/ui/model.go            | 32 ++++++++--
 .../ui/teamodels/layout/zstack.go             | 61 +++++++++++++++++++
 .../ui/teamodels/utils/minmax.go              | 14 +++++
 3 files changed, 103 insertions(+), 4 deletions(-)
 create mode 100644 internal/dynamo-browse/ui/teamodels/layout/zstack.go

diff --git a/internal/dynamo-browse/ui/model.go b/internal/dynamo-browse/ui/model.go
index 2d58d21..9d7d5e7 100644
--- a/internal/dynamo-browse/ui/model.go
+++ b/internal/dynamo-browse/ui/model.go
@@ -15,10 +15,22 @@ import (
 	"github.com/lmika/audax/internal/dynamo-browse/ui/teamodels/statusandprompt"
 	"github.com/lmika/audax/internal/dynamo-browse/ui/teamodels/styles"
 	"github.com/lmika/audax/internal/dynamo-browse/ui/teamodels/tableselect"
+	"github.com/lmika/audax/internal/dynamo-browse/ui/teamodels/utils"
 	"github.com/pkg/errors"
+	"log"
 	"strings"
 )
 
+const (
+	ViewModeTablePrimary   = 0
+	ViewModeTableItemEqual = 1
+	ViewModeItemPrimary    = 2
+	ViewModeItemOnly       = 3
+	ViewModeTableOnly      = 4
+
+	ViewModeCount = 5
+)
+
 type Model struct {
 	tableReadController  *controllers.TableReadController
 	tableWriteController *controllers.TableWriteController
@@ -169,7 +181,13 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 			case "backspace":
 				return m, m.tableReadController.ViewBack
 			case "w":
-				return m, func() tea.Msg { return controllers.SetTableItemView{ViewIndex: (m.mainViewIndex + 1) % 3} }
+				return m, func() tea.Msg {
+					return controllers.SetTableItemView{ViewIndex: utils.Cycle(m.mainViewIndex, 1, ViewModeCount)}
+				}
+			case "W":
+				return m, func() tea.Msg {
+					return controllers.SetTableItemView{ViewIndex: utils.Cycle(m.mainViewIndex, -1, ViewModeCount)}
+				}
 			//case "e":
 			//	m.itemEdit.Visible()
 			//	return m, nil
@@ -191,14 +209,20 @@ func (m Model) View() string {
 }
 
 func (m *Model) setMainViewIndex(viewIndex int) tea.Cmd {
+	log.Printf("setting view index = %v", viewIndex)
+
 	var newMainView tea.Model
 	switch viewIndex {
-	case 0:
+	case ViewModeTablePrimary:
 		newMainView = layout.NewVBox(layout.LastChildFixedAt(14), m.tableView, m.itemView)
-	case 1:
+	case ViewModeTableItemEqual:
 		newMainView = layout.NewVBox(layout.EqualSize(), m.tableView, m.itemView)
-	case 2:
+	case ViewModeItemPrimary:
 		newMainView = layout.NewVBox(layout.FirstChildFixedAt(7), m.tableView, m.itemView)
+	case ViewModeItemOnly:
+		newMainView = layout.NewZStack(m.itemView, m.tableView)
+	case ViewModeTableOnly:
+		newMainView = layout.NewZStack(m.tableView, m.tableView)
 	default:
 		newMainView = m.mainView
 	}
diff --git a/internal/dynamo-browse/ui/teamodels/layout/zstack.go b/internal/dynamo-browse/ui/teamodels/layout/zstack.go
new file mode 100644
index 0000000..88860b6
--- /dev/null
+++ b/internal/dynamo-browse/ui/teamodels/layout/zstack.go
@@ -0,0 +1,61 @@
+package layout
+
+import (
+	tea "github.com/charmbracelet/bubbletea"
+	"github.com/lmika/audax/internal/dynamo-browse/ui/teamodels/utils"
+)
+
+type ZStack struct {
+	visibleModel tea.Model
+	focusedModel tea.Model
+	otherModels  []tea.Model
+}
+
+func NewZStack(visibleModel tea.Model, focusedModel tea.Model, otherModels ...tea.Model) ZStack {
+	return ZStack{
+		visibleModel: visibleModel,
+		focusedModel: focusedModel,
+		otherModels:  otherModels,
+	}
+}
+
+func (vb ZStack) Init() tea.Cmd {
+	var cc utils.CmdCollector
+	cc.Collect(vb.visibleModel, vb.visibleModel.Init())
+	cc.Collect(vb.focusedModel, vb.focusedModel.Init())
+	for _, c := range vb.otherModels {
+		cc.Collect(c, c.Init())
+	}
+	return cc.Cmd()
+}
+
+func (vb ZStack) Update(msg tea.Msg) (m tea.Model, cmd tea.Cmd) {
+	switch msg.(type) {
+	case tea.KeyMsg:
+		// Only the focused model gets keyboard events
+		vb.focusedModel, cmd = vb.focusedModel.Update(msg)
+		return vb, cmd
+	}
+
+	// All other messages go to each model
+	var cc utils.CmdCollector
+	vb.visibleModel = cc.Collect(vb.visibleModel.Update(msg))
+	vb.focusedModel = cc.Collect(vb.focusedModel.Update(msg))
+	for i, c := range vb.otherModels {
+		vb.otherModels[i] = cc.Collect(c.Update(msg))
+	}
+	return vb, cc.Cmd()
+}
+
+func (vb ZStack) View() string {
+	return vb.visibleModel.View()
+}
+
+func (vb ZStack) Resize(w, h int) ResizingModel {
+	vb.visibleModel = Resize(vb.visibleModel, w, h)
+	vb.focusedModel = Resize(vb.focusedModel, w, h)
+	for i := range vb.otherModels {
+		vb.otherModels[i] = Resize(vb.otherModels[i], w, h)
+	}
+	return vb
+}
diff --git a/internal/dynamo-browse/ui/teamodels/utils/minmax.go b/internal/dynamo-browse/ui/teamodels/utils/minmax.go
index 720c39f..2fbb42f 100644
--- a/internal/dynamo-browse/ui/teamodels/utils/minmax.go
+++ b/internal/dynamo-browse/ui/teamodels/utils/minmax.go
@@ -6,3 +6,17 @@ func Max(x, y int) int {
 	}
 	return y
 }
+
+func Cycle(n int, by int, max int) int {
+	by = by % max
+	if by > 0 {
+		return (n + by) % max
+	} else if by < 0 {
+		wn := n + by
+		if wn < 0 {
+			return max + wn
+		}
+		return wn
+	}
+	return n
+}