class Ransack::Helpers::FormHelper::SortLink

def default_arrow

def default_arrow
  Ransack.options[:default_arrow]
end

def default_sort_order(attr_name)

def default_sort_order(attr_name)
  return @default_order[attr_name] if Hash === @default_order
  @default_order
end

def detect_previous_sort_direction_and_invert_it(attr_name)

def detect_previous_sort_direction_and_invert_it(attr_name)
  if sort_dir = existing_sort_direction(attr_name)
    direction_text(sort_dir)
  else
    default_sort_order(attr_name) || 'asc'.freeze
  end
end

def direction_text(dir)

def direction_text(dir)
  return 'asc'.freeze if dir == 'desc'.freeze
  'desc'.freeze
end

def down_arrow

def down_arrow
  Ransack.options[:down_arrow]
end

def existing_sort_direction(f = @field)

def existing_sort_direction(f = @field)
  return unless sort = @search.sorts.detect { |s| s && s.name == f }
  sort.dir
end

def extract_label_and_mutate_args!(args)

def extract_label_and_mutate_args!(args)
  return args.shift if args[0].is_a?(String)
  Translate.attribute(@field, context: @search.context)
end

def extract_options_and_mutate_args!(args)

def extract_options_and_mutate_args!(args)
  return args.shift.with_indifferent_access if args[0].is_a?(Hash)
  {}
end

def extract_sort_fields_and_mutate_args!(args)

def extract_sort_fields_and_mutate_args!(args)
  return args.shift if args[0].is_a?(Array)
  [@field]
end

def html_options(args)

def html_options(args)
  if args.empty?
    html_options = @options
  else
    deprecation_message = "Passing two trailing hashes to `sort_link` is deprecated, merge the trailing hashes into a single one."
    caller_location = caller_locations(2, 2).first
    warn "#{deprecation_message} (called at #{caller_location.path}:#{caller_location.lineno})"
    html_options = extract_options_and_mutate_args!(args)
  end
  html_options.merge(
    class: [['sort_link'.freeze, @current_dir], html_options[:class]]
           .compact.join(' '.freeze)
  )
end

def initialize(search, attribute, args, params)

def initialize(search, attribute, args, params)
  @search         = search
  @params         = parameters_hash(params)
  @field          = attribute.to_s
  @sort_fields    = extract_sort_fields_and_mutate_args!(args).compact
  @current_dir    = existing_sort_direction
  @label_text     = extract_label_and_mutate_args!(args)
  @options        = extract_options_and_mutate_args!(args)
  @hide_indicator = @options.delete(:hide_indicator) ||
                    Ransack.options[:hide_sort_order_indicators]
  @default_order  = @options.delete :default_order
end

def name

def name
  [ERB::Util.h(@label_text), order_indicator]
  .compact
  .join(' '.freeze)
  .html_safe
end

def no_sort_direction_specified?(dir = @current_dir)

def no_sort_direction_specified?(dir = @current_dir)
  dir != 'asc'.freeze && dir != 'desc'.freeze
end

def order_indicator

def order_indicator
  return if @hide_indicator
  return default_arrow if no_sort_direction_specified?
  if @current_dir == 'desc'.freeze
    up_arrow
  else
    down_arrow
  end
end

def parameters_hash(params)

def parameters_hash(params)
  if params.respond_to?(:to_unsafe_h)
    params.to_unsafe_h
  else
    params
  end
end

def parse_sort(field)

def parse_sort(field)
  attr_name, new_dir = field.to_s.split(/\s+/)
  if no_sort_direction_specified?(new_dir)
    new_dir = detect_previous_sort_direction_and_invert_it(attr_name)
  end
  "#{attr_name} #{new_dir}"
end

def recursive_sort_params_build(fields)

def recursive_sort_params_build(fields)
  return [] if fields.empty?
  [parse_sort(fields[0])] + recursive_sort_params_build(fields.drop 1)
end

def search_and_sort_params

def search_and_sort_params
  search_params.merge(s: sort_params)
end

def search_params

def search_params
  @params[@search.context.search_key].presence || {}
end

def sort_params

def sort_params
  sort_array = recursive_sort_params_build(@sort_fields)
  return sort_array[0] if sort_array.length == 1
  sort_array
end

def up_arrow

def up_arrow
  Ransack.options[:up_arrow]
end

def url_options

def url_options
  @params.merge(
    @options.except(:class).merge(
      @search.context.search_key => search_and_sort_params))
end