require 'nested_form/builder_mixin'

class BootstrapFormBuilder < ActionView::Helpers::FormBuilder
  
  include ::NestedForm::BuilderMixin

  delegate :capture, :content_tag, to: :@template

  [:text_field, :text_area, :password_field, :select, :check_box, :file_field, :grouped_collection_select].each do |method_name|
    define_method(method_name) do |name, *args|
      error_class = object.errors.has_key?(name) ? ["error"] : []
      options = args.last unless args.empty?
      options = {} if options.nil?
      content_tag :div, class: ["control-group"] + error_class do
        output = label(name, options[:text])
        output << content_tag(:div, class: ["controls"]) do
          output = super(name, *args)

          # Uncomment to show errors inline
          #
          #if object.errors.has_key?(name)
          #  output << error_list_for(name)
          #end

          output
        end
      end
    end
  end

  def label attribute, text = nil, options = { }, &block
    options = { class: ["control-label"] }.deep_merge options

    if is_attribute_required? attribute
      options[:class] += ["required"]
    end

    super attribute, text, options, &block
  end

  def submit value = nil, options = {}
    options[:class] ||= []
    options[:class] += ["btn", "btn-success", "btn-large"]
    options[:disable_with] = I18n.t("label.submitting") if !options[:disable_with]

    content_tag :div, class: ["form-actions"] do
      super value, options
    end
  end

  private
  def field_label(name, *args)
    options = args.extract_options!
    required = object.class.validators_on(name).any? { |v| v.kind_of? ActiveModel::Validations::PresenceValidator }

    label(name, options[:label], class: ("required" if required))
  end

  def is_attribute_required? attribute
    object.class.validators_on(attribute).any? { |validator| validator.is_a? ActiveModel::Validations::PresenceValidator }
  end

  def error_list_for attribute
    content_tag :span, class: ["help-inline"] do
      object.errors[attribute].join(", ")
    end
  end
end
