1package termui
2
3import (
4 "fmt"
5 "github.com/MichaelMure/git-bug/bug"
6 "github.com/MichaelMure/git-bug/cache"
7 "github.com/jroimartin/gocui"
8)
9
10type bugTable struct {
11 cache cache.RepoCacher
12 bugs []*bug.Snapshot
13 cursor int
14}
15
16func newBugTable(cache cache.RepoCacher) *bugTable {
17 return &bugTable{
18 cache: cache,
19 cursor: 0,
20 }
21}
22
23func (bt *bugTable) paginate(max int) error {
24 allIds, err := bt.cache.AllBugIds()
25 if err != nil {
26 return err
27 }
28
29 return bt.doPaginate(allIds, max)
30}
31
32func (bt *bugTable) nextPage(max int) error {
33 allIds, err := bt.cache.AllBugIds()
34 if err != nil {
35 return err
36 }
37
38 if bt.cursor+max > len(allIds) {
39 return nil
40 }
41
42 bt.cursor += max
43
44 return bt.doPaginate(allIds, max)
45}
46
47func (bt *bugTable) previousPage(max int) error {
48 allIds, err := bt.cache.AllBugIds()
49 if err != nil {
50 return err
51 }
52
53 bt.cursor = maxInt(0, bt.cursor-max)
54
55 return bt.doPaginate(allIds, max)
56}
57
58func (bt *bugTable) doPaginate(allIds []string, max int) error {
59 // clamp the cursor
60 bt.cursor = maxInt(bt.cursor, 0)
61 bt.cursor = minInt(bt.cursor, len(allIds)-1)
62
63 // slice the data
64 nb := minInt(len(allIds)-bt.cursor, max)
65
66 ids := allIds[bt.cursor:nb]
67
68 bt.bugs = make([]*bug.Snapshot, len(ids))
69
70 for i, id := range ids {
71 b, err := bt.cache.ResolveBug(id)
72 if err != nil {
73 return err
74 }
75
76 bt.bugs[i] = b.Snapshot()
77 }
78
79 return nil
80}
81
82func (bt *bugTable) layout(g *gocui.Gui) error {
83 maxX, maxY := g.Size()
84
85 v, err := g.SetView("header", -1, -1, maxX, 3)
86
87 if err != nil {
88 if err != gocui.ErrUnknownView {
89 return err
90 }
91
92 v.Frame = false
93 }
94
95 v.Clear()
96 ui.bugTable.renderHeader(v, maxX)
97
98 v, err = g.SetView("table", -1, 1, maxX, maxY-2)
99
100 if err != nil {
101 if err != gocui.ErrUnknownView {
102 return err
103 }
104
105 v.Frame = false
106 v.Highlight = true
107 v.SelBgColor = gocui.ColorWhite
108 v.SelFgColor = gocui.ColorBlack
109
110 _, err = g.SetCurrentView("table")
111
112 if err != nil {
113 return err
114 }
115 }
116
117 _, tableHeight := v.Size()
118 err = bt.paginate(tableHeight)
119 if err != nil {
120 return err
121 }
122
123 v.Clear()
124 ui.bugTable.render(v, maxX)
125
126 v, err = g.SetView("footer", -1, maxY-3, maxX, maxY)
127
128 if err != nil {
129 if err != gocui.ErrUnknownView {
130 return err
131 }
132
133 v.Frame = false
134 }
135
136 v.Clear()
137 ui.bugTable.renderFooter(v, maxX)
138
139 v, err = g.SetView("instructions", -1, maxY-2, maxX, maxY)
140
141 if err != nil {
142 if err != gocui.ErrUnknownView {
143 return err
144 }
145
146 v.Frame = false
147 v.BgColor = gocui.ColorBlue
148
149 fmt.Fprintf(v, "[q] Quit [h] Go back [j] Down [k] Up [l] Go forward [m] Load Additional [p] Play [enter] Play and Exit")
150 }
151
152 return nil
153}
154
155func (bt *bugTable) getTableLength() int {
156 return len(bt.bugs)
157}
158
159func (bt *bugTable) render(v *gocui.View, maxX int) {
160 for _, b := range bt.bugs {
161 fmt.Fprintln(v, b.Title)
162 }
163}
164
165func (bt *bugTable) renderHeader(v *gocui.View, maxX int) {
166 fmt.Fprintf(v, "header")
167
168}
169
170func (bt *bugTable) renderFooter(v *gocui.View, maxX int) {
171 fmt.Fprintf(v, "footer")
172}
173
174func maxInt(a, b int) int {
175 if a > b {
176 return a
177 }
178 return b
179}
180
181func minInt(a, b int) int {
182 if a > b {
183 return b
184 }
185 return a
186}