module TimeLogger class TimeLogger def initialize(timer, ui) @timer, @ui = timer, ui end def start(name) unless @current_task.nil? if @current_task.name != name stop(@current_task.name) end end @current_task = tasks[name] if @current_task.nil? @current_task = Task.new(name) tasks[name] = @current_task end @current_task.start(@timer) @ui.start(@current_task) end def stop(name) task = tasks[name] task.stop(@timer) @current_task = nil @ui.stop(task) end def list @ui.list(tasks.values) end private def tasks @tasks ||= {} end end class Task def initialize(name) @name = name end def name @name end def start(timer) @activity = TaskActivity.new(timer) @activity.start end def stop(timer) @activity.stop past_activities << @activity @activity = nil end def time past_activities.inject(0) { |t, a| t + a.time } end private def past_activities @past_activities ||= [] end end class TaskActivity def initialize(timer) @timer = timer end def start @started_at = @timer.now() end def stop @stopped_at = @timer.now() end def time diff = @stopped_at.to_i - @started_at.to_i mins = diff / 60 end end class Timer def now @now ||= Time.now end def add_minutes(val) @now = Time.at(@now.to_i + val * 60) end end class UI def start(task) message("Started task: #{task.name}") end def stop(task) message("Stopped task: #{task.name} (#{task.time} minutes)") end def list(tasks) tasks.each do |task| message("#{task.name} (#{task.time} minutes)") end end def message(msg) msgs << msg end def msgs @msgs ||= [] end end end