class TZInfo::TZDataTransitions

:nodoc:
@private
Collection of TZDataTransition instances used when building a zone class.

def << (transition)

def << (transition)
  @transitions << transition
end 

def initialize

def initialize
  @transitions = []
end

def optimize

def optimize
  @transitions.sort!
  
  # Optimization logic from zic.c writezone.
  
  from_i = 0
  to_i = 0
  
  while from_i < @transitions.length
    if to_i > 1 && 
        !@transitions[from_i].at_utc.nil?  &&
        !@transitions[to_i - 1].at_utc.nil? &&
        @transitions[from_i].at_utc + Rational(@transitions[to_i - 1].total_offset, 86400) <=
        @transitions[to_i - 1].at_utc + Rational(@transitions[to_i - 2].total_offset, 86400)
                
      @transitions[to_i - 1] = @transitions[from_i].clone_with_at(@transitions[to_i - 1].at_utc)             
      from_i += 1
      next
    end
    
    # Shuffle transitions up, eliminating any redundant transitions 
    # along the way.
    if to_i == 0 ||
        @transitions[to_i - 1].utc_offset != @transitions[from_i].utc_offset ||
        @transitions[to_i - 1].std_offset != @transitions[from_i].std_offset ||
        @transitions[to_i - 1].zone_id != @transitions[from_i].zone_id
                
      @transitions[to_i] = @transitions[from_i]
      to_i += 1            
    end
    
    from_i += 1
  end                
  
  if to_i > 0
    @transitions = @transitions[0..to_i - 1]
  else
    @transitions = []
  end                
end

def output_module(file)

def output_module(file)
  optimize
  
  # Try and end on a transition to std if one happens in the last year.
  if @transitions.length > 1 && 
      @transitions.last.std_offset != 0 &&
      @transitions[@transitions.length - 2].std_offset == 0 &&
      @transitions[@transitions.length - 2].at_utc.year == TZDataParser::MAX_YEAR
    
    transitions = @transitions[0..@transitions.length - 2]
  else
    transitions = @transitions
  end
  
  process_offsets(file)
  file.puts('')
  
  transitions.each do |t|        
    t.write(file)
  end            
end

def process_offsets(file)

def process_offsets(file)
  # A bit of a hack at the moment. The offset used to be output with
  # each period (pair of transitions). They are now separated from the
  # transition data. The code should probably be changed at some point to
  # setup the offsets at an earlier stage.   
  
  # Assume that when this is called, the first transition is the Local
  # Mean Time initial rule or a transition with no time that defines the
  # offset for the entire zone.
  
  offsets = []
  
  # Find the first std offset. Timezones always start in std.
  @transitions.each do |t|
    if t.std_offset == 0
      offset = {:utc_offset => t.utc_offset, 
        :std_offset => t.std_offset,
        :zone_id => t.zone_id,
        :name => 'o0'}
        
      offsets << offset
      break
    end
  end
  
  @transitions.each do |t|
    offset = offsets.find do |o| 
      o[:utc_offset] == t.utc_offset &&
        o[:std_offset] == t.std_offset &&
        o[:zone_id] == t.zone_id
    end
  
    unless offset
      offset = {:utc_offset => t.utc_offset, 
        :std_offset => t.std_offset,
        :zone_id => t.zone_id,
        :name => "o#{offsets.length}"}
                                 
      offsets << offset
    end
    
    t.offset_name = offset[:name]
  end
  
  offsets.each do |offset|
    file.puts("tz.offset :#{offset[:name]}, #{offset[:utc_offset]}, #{offset[:std_offset]}, #{quote_zone_id(offset[:zone_id])}")
  end
  
end

def quote_zone_id(zone_id)

def quote_zone_id(zone_id)     
  if zone_id =~ %r{[\-+']}
    ":#{TZDataParser.quote_str(zone_id)}"          
  else
    ":#{zone_id}"
  end
end