/* 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 ( "fmt" "os" "os/signal" "syscall" "time" ) 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 } // 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), } } // Run Pominal func (p *Pominal) Run() { s := make(chan os.Signal, 1) signal.Notify(s, syscall.SIGINT, syscall.SIGTERM) p.UpdateSession() t := time.NewTicker(1 * time.Second) infinite: for { select { case sig := <-s: fmt.Printf("\n\nReceived signal '%s'. Closing Pominal.\n", sig) t.Stop() break infinite case <-t.C: p.countdown-- if p.countdown < 0 { fmt.Printf("\n%s session has finished.\n", p.label) t.Stop() p.UpdateSession() time.Sleep(1 * time.Second) t = time.NewTicker(1 * time.Second) } else { printScreen(p.countdown, p.cycle, p.workSession, p.maxWorkSessions, p.label, ) } } } } // 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() { 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 } 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 }