diff --git a/Main.go b/Main.go index 6cfed50..e7a7521 100644 --- a/Main.go +++ b/Main.go @@ -63,6 +63,14 @@ func date(year int, month time.Month, day int) time.Time { return time.Date(year, month, day, 0, 0, 0, 0, time.Local) } +func lastDay(m time.Month) time.Time { + return date(selTime.Year(), m+1, 0) +} + +func monthHeight(m time.Month) int { + return (offset(m) + lastDay(m).Day() - 1) / 7 +} + func centeredText(s string, x, y, width int, scr tcell.Screen, style tcell.Style) { start := x + max((width-utf8.RuneCountInString(s))/2, 0) i := 0 @@ -93,6 +101,105 @@ func wrappedText(s string, scr tcell.Screen, style tcell.Style) { } } +func bottomOfMonth(m time.Month, w time.Weekday) (time time.Time) { + last := lastDay(m) + day := last.Day() + + if w > last.Weekday() { + day -= 7 + } + + day += int(w - last.Weekday()) + + time = date(selTime.Year(), m, day) + return +} + +func topOfMonth(m time.Month, w time.Weekday) (time time.Time) { + first := date(selTime.Year(), m, 1) + day := 1 + + if w < first.Weekday() { + day += 7 + } + + day += int(w - first.Weekday()) + + time = date(selTime.Year(), m, day) + return +} + +func moveUp() { + weekday := selTime.Weekday() + newTime := selTime.AddDate(0, 0, -7) + if newTime.Month() == selTime.Month() { + selTime = newTime + } else if int(selTime.Month()) > monthsWide { + newMonth := selTime.Month() - time.Month(monthsWide) + selTime = bottomOfMonth(newMonth, weekday) + } +} + +func moveDown() { + weekday := selTime.Weekday() + newTime := selTime.AddDate(0, 0, +7) + if newTime.Month() == selTime.Month() { + selTime = newTime + } else if int(selTime.Month()) <= (12-1)/monthsWide*monthsWide { + newMonth := selTime.Month() + time.Month(monthsWide) + selTime = topOfMonth(newMonth, weekday) + } +} + +func offset(m time.Month) int { + return (int(date(selTime.Year(), m, 1).Weekday()) + 6) % 7 + +} + +func rowInMonth(m time.Month, day int) int { + return (day + offset(m) - 1) / 7 +} + +func leftmostInRow(m time.Month, row int) time.Time { + if row == 0 { + return date(selTime.Year(), m, 1) + } + if row > monthHeight(m) { + row = monthHeight(m) + } + + day := row*7 + 1 - offset(m) + + return date(selTime.Year(), m, day) +} + +func rightmostInRow(m time.Month, row int) time.Time { + if row >= monthHeight(m) { + return lastDay(m) + } + + day := row*7 + 7 - offset(m) + + return date(selTime.Year(), m, day) +} + +func moveRight() { + if selTime.Weekday() != time.Sunday && selTime.Day() != lastDay(selTime.Month()).Day() { + selTime = selTime.AddDate(0, 0, 1) + } else if int(selTime.Month())%monthsWide != 0 { + selTime = leftmostInRow(selTime.Month()+1, rowInMonth(selTime.Month(), selTime.Day())) + } +} + +func moveLeft() { + if selTime.Weekday() != time.Monday && selTime.Day() != 1 { + selTime = selTime.AddDate(0, 0, -1) + } else if int(selTime.Month())%monthsWide != 1 && monthsWide != 1 { // special case, if monthsWide + // is 1, (x%monthsWide) is 0 + selTime = rightmostInRow(selTime.Month()-1, rowInMonth(selTime.Month(), selTime.Day())) + } +} + func drawMonth(m time.Month, x, y int) { centeredText(months[m], x, y, maxMonthWidth, wall, defStyle) @@ -181,13 +288,24 @@ func main() { // Process event switch ev := ev.(type) { case *tcell.EventResize: - drawWall() - wall.Sync() case *tcell.EventKey: if ev.Key() == tcell.KeyEscape || ev.Key() == tcell.KeyCtrlC || ev.Rune() == 'Q' || ev.Rune() == 'q' { quit() } + switch ev.Rune() { + case 'h': + moveLeft() + case 'j': + moveDown() + case 'k': + moveUp() + case 'l': + moveRight() + } } + + drawWall() + wall.Sync() } }