# A form build that adheres to Bootstrap horizontal form conventions.
#
class BootstrapFormBuilder::HorizontalFormBuilder < ActionView::Helpers::FormBuilder
  def email_field(name, opts = {})
    form_group(name) do
      super(name, opts.reverse_merge(:class => 'form-control',
                                     :placeholder => help(name)))
    end
  end

  def text_field(name, opts = {})
    form_group(name) do
      super(name, opts.reverse_merge(:class => 'form-control',
                                     :placeholder => help(name)))
    end
  end

  def password_field(name, opts = {})
    form_group(name) do
      super(name, opts.reverse_merge(:class => 'form-control',
                                     :placeholder => help(name)))
    end
  end

  def date_field(name, opts = {})
    form_group(name) do
      super(name, opts.reverse_merge(:class => 'form-control',
                                     :placeholder => help(name)))
    end
  end

  def number_field(name, opts = {})
    form_group(name) do
      super(name, opts.reverse_merge(:class => 'form-control',
                                     :placeholder => help(name)))
    end
  end

  def check_box(name, opts = {})
    form_group(name) do
      @template.content_tag(:div,
                            @template.content_tag(:label, super(name, opts) + (help(name) || "&nbsp;").html_safe),
                            :class => 'checkbox')
    end
  end

  def radio_button_group(name, button_options, opts = {})
    form_group(name) do
      buttons = button_options.map do |button|
        label(name, :value => button, :class => 'btn btn-default') do
          radio_button(name, button) +
            I18n.t("#{object_name}.#{name}_options.#{button}",
                   :scope => "helpers.label")
        end
      end.join("\n").html_safe

      @template.content_tag(:div,
                            buttons,
                            :class => 'btn-group',
                            :data => { :toggle => 'buttons' })
    end
  end

  def select(name, choices, options = {}, html_options = {})
    form_group(name) do
      super(name, choices, options, html_options.reverse_merge(:class => 'form-control'))
    end
  end

  def text_area(name, opts = {})
    form_group(name) do
      super(name, opts.reverse_merge(:class => 'form-control',
                                     :placeholder => help(name)))
    end
  end

  def form_group(name, &block)
    classes = ['form-group']

    if @object.errors.has_key?(name)
      classes << 'has-error'
    end

    @template.content_tag(:div,
                          label(name) +
                          col_wrap(block.call + errors(name)),
                          :class => classes.join(' '))
  end

  def col_wrap(html)
    @template.content_tag(:div, html, :class => 'col-sm-7')
  end

  def label(name, opts = {})
    super(name, opts.reverse_merge(:class => 'col-sm-3 control-label'))
  end

  def errors(name)
    if @object.errors.has_key?(name)
      errors = @object.errors.full_messages_for(name).join('. ')
      @template.content_tag(:span, errors, :class => 'help-text text-danger')
    else
      ''
    end
  end

  def help(name)
    i18n_name = "helpers.hints.#{object_name}.#{name}"
    if I18n.exists?(i18n_name)
      I18n.t(i18n_name)
    else
      nil
    end
  end

  def cancel_button(cancel_path)
    @template.link_to(I18n.t('helpers.button.cancel'),
                      cancel_path,
                      :class => 'btn btn-default')
  end

  def submit_button(label = "")
    @template.content_tag(:div,
                          @template.
                            content_tag(:div,
                                        submit(label, :class => 'btn btn-primary'),
                                        :class => 'col-sm-offset-3 col-sm-7'),
                          :class => 'form-group')
  end

  def submit_and_cancel(cancel_path)
    @template.content_tag(:div,
                          @template.
                            content_tag(:div,
                                        submit(:class => 'btn btn-primary') +
                                        " " + cancel_button(cancel_path),
                                        :class => 'col-sm-offset-3 col-sm-7'),
                          :class => 'form-group')
  end
end