lib/chronic/repeaters/repeater_day_portion.rb



module Chronic
  class RepeaterDayPortion < Repeater #:nodoc:
    PORTIONS = {
      :am => 0..(12 * 60 * 60 - 1),
      :pm => (12 * 60 * 60)..(24 * 60 * 60 - 1),
      :morning => (6 * 60 * 60)..(12 * 60 * 60),   # 6am-12am,
      :afternoon =>(13 * 60 * 60)..(17 * 60 * 60), # 1pm-5pm,
      :evening => (17 * 60 * 60)..(20 * 60 * 60),  # 5pm-8pm,
      :night =>(20 * 60 * 60)..(24 * 60 * 60),     # 8pm-12pm
    }

    def initialize(type)
      super

      if type.kind_of? Integer
        @range = (@type * 60 * 60)..((@type + 12) * 60 * 60)
      else
        @range = PORTIONS[type]
        @range || raise("Invalid type '#{type}' for RepeaterDayPortion")
      end

      @range || raise("Range should have been set by now")
    end

    def next(pointer)
      super

      full_day = 60 * 60 * 24

      if !@current_span
        now_seconds = @now - Time.construct(@now.year, @now.month, @now.day)
        if now_seconds < @range.begin
          case pointer
          when :future
            range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
          when :past
            range_start = Time.construct(@now.year, @now.month, @now.day) - full_day + @range.begin
          end
        elsif now_seconds > @range.end
          case pointer
          when :future
            range_start = Time.construct(@now.year, @now.month, @now.day) + full_day + @range.begin
          when :past
            range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
          end
        else
          case pointer
          when :future
            range_start = Time.construct(@now.year, @now.month, @now.day) + full_day + @range.begin
          when :past
            range_start = Time.construct(@now.year, @now.month, @now.day) - full_day + @range.begin
          end
        end

        @current_span = Span.new(range_start, range_start + (@range.end - @range.begin))
      else
        case pointer
        when :future
          @current_span += full_day
        when :past
          @current_span -= full_day
        end
      end
    end

    def this(context = :future)
      super

      range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
      @current_span = Span.new(range_start, range_start + (@range.end - @range.begin))
    end

    def offset(span, amount, pointer)
      @now = span.begin
      portion_span = self.next(pointer)
      direction = pointer == :future ? 1 : -1
      portion_span + (direction * (amount - 1) * RepeaterDay::DAY_SECONDS)
    end

    def width
      @range || raise("Range has not been set")
      return @current_span.width if @current_span
      if @type.kind_of? Integer
        return (12 * 60 * 60)
      else
        @range.end - @range.begin
      end
    end

    def to_s
      super << '-dayportion-' << @type.to_s
    end
  end
end