/* Pominal Copyright (C) 2019 Daniel Anglin This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package main import ( "time" "github.com/rivo/tview" ) type Pominal struct { // workSession is a counter for work sessions. workSession int // maxWorkSessions sets the number of work sessions to complete // before running the countdown timer for each long break. maxWorkSessions int // cycle represents a Pominal cycle. A Pominal cycle increments after // every long break. cycle int // countdown is the decrementing counter for Pominal. countdown float64 // work is the time (represented in seconds) for the work sessions. work float64 // shortBreak is the time (represented in seconds) // for the short break sessions. shortBreak float64 // longBreak is the time (represented in seconds) //for the long break sessions. longBreak float64 // label labels Pominal based on the session. label string // stopChan is a no-data channel used to stop Pominal. stopChan chan struct{} } // NewPominal creates a new pominal instance func NewPominal(w, s, l float64, m int) Pominal { return Pominal{ workSession: 1, maxWorkSessions: setMaxWorkSessions(m), cycle: 1, work: setSessionTime(w), shortBreak: setSessionTime(s), longBreak: setSessionTime(l), stopChan: nil, } } // Run Pominal func (p *Pominal) Run(infoUI, timerUI *tview.TextView) { p.stopChan = make(chan struct{}) p.UpdateSession(infoUI) t := time.NewTicker(1 * time.Second) infinite: for { select { case <-p.stopChan: t.Stop() break infinite case <-t.C: p.countdown-- if p.countdown < 0 { t.Stop() p.UpdateSession(infoUI) time.Sleep(1 * time.Second) t = time.NewTicker(1 * time.Second) } else { drawTimer(timerUI, p.countdown) } } } } // Stop sends a signal to the Run method to stop the timer. // Afterwards the process returns from the Run method. func (p *Pominal) Stop() { close(p.stopChan) } // UpdateSession resets Pominal's countdown // based on the next session. If a 'short break' // session is over the work session counter is incremented. // If a 'long break' session is over then the Pominal cycle // is incremented and the work session counter is reset // to 1. func (p *Pominal) UpdateSession(i *tview.TextView) { switch p.label { case workTimerLabel: if p.workSession >= p.maxWorkSessions { p.countdown = p.longBreak p.label = longBreakTimerLabel } else { p.countdown = p.shortBreak p.label = shortBreakTimerLabel } case shortBreakTimerLabel: p.workSession++ p.countdown = p.work p.label = workTimerLabel case longBreakTimerLabel: p.cycle++ p.workSession = 1 p.countdown = p.work p.label = workTimerLabel default: p.countdown = p.work p.label = workTimerLabel } drawInfo(i, p.cycle, p.workSession, p.maxWorkSessions, p.label) alert(p.label) } // setSessionTime returns the minimum session time // if the value is less than the minimum. // Otherwise it returns the value. func setSessionTime(s float64) float64 { var min float64 = 60 if s < min { return min } return s } // setMaxWorkSessions returns the minimum amount // of work session per Pominal cycle if the user supplies // a value below it. // Otherwise it returns the value set by the user. func setMaxWorkSessions(w int) int { var min = 1 if w < min { return min } return w }