if Object.const_defined?(:ActiveRecord)
  class ActiveRecord::Base
    def instantiate_time_object_with_ampm(name, values)
      if values.last < 0
        hour_idx = ActionView::Helpers::DateTimeSelector::POSITION[:hour] - 1
        ampm = values.pop
        if ampm == ActionView::Helpers::DateTimeSelector::AM and values[hour_idx] == 12
          values[hour_idx] = 0
        elsif ampm == ActionView::Helpers::DateTimeSelector::PM and values[hour_idx] != 12
          values[hour_idx] += 12
        end
      end

      instantiate_time_object_without_ampm(name, values)
    end

    alias_method_chain :instantiate_time_object, :ampm
  end
end

module ActionView::Helpers
  module DateHelper
    def select_ampm(datetime, options = {}, html_options = {})      
      DateTimeSelector.new(datetime, options, html_options).select_ampm
    end    
  end
  
  class DateTimeSelector
    # POSITION is frozen, so use `remove_const` to add :ampm key and prevent warning messages about redefining a constant
    POSITION = remove_const(:POSITION).merge(:ampm => 7)

    # We give them negative values so can differentiate between normal
    # date/time values. The way the multi param stuff works, from what I
    # can see, results in a variable number of fields (if you tell it to
    # include seconds, for example). So we expect the AM/PM field, if
    # present, to be last and have a negative value.
    AM = -1
    PM = -2
 
    def select_hour_with_ampm      
      unless @options[:twelve_hour]
        return select_hour_without_ampm
      end

      if @options[:use_hidden] || @options[:discard_hour]
        build_hidden(:hour, hour12)
      else
        build_options_and_select(:hour, hour12, :start => 1, :end => 12)
      end
    end

    alias_method_chain :select_hour, :ampm

    def select_ampm
      selected = hour < 12 ? AM : PM unless hour.nil?

      # XXX i18n? 
      label = { AM => 'AM', PM => 'PM' }
      ampm_options = []
      [AM, PM].each do |meridiem|
        option = { :value => meridiem }
        option[:selected] = "selected" if selected == meridiem
        ampm_options << content_tag(:option, label[meridiem], option) + "\n"
      end
      
      build_select(:ampm, ampm_options.join)
    end

    private

    def build_selects_from_types_with_ampm(order)
      if @options[:twelve_hour] and order.include?(:hour)
        order += [:ampm] unless order.include?(:ampm)
      end
      build_selects_from_types_without_ampm(order)
    end

    alias_method_chain :build_selects_from_types, :ampm

    def hour12
      return nil if hour.nil?

      h12 = hour % 12
      h12 = 12 if h12 == 0
      return h12
    end
  end
end