require 'delegate'

# Minimal Decorator Base Class
#
# Implements a SimpleDelegator, provides access to the view_context through the `h` method, and provides
# a factory method to construct Delegators or collections of Delegators
#
# In a controller, the view_context can be retrieved by calling a method of the same name
# In a view or view helper, the context is `self`
#
# See also ApplicationHelper#decorate
class BaseDecorator < SimpleDelegator

  class << self
    # Decorates a single object or a collection of objects.  If the given objects are `BaseDecorators`, they will be
    # unwrapped first
    def decorate(obj, view_context)
      decorated = Array.wrap(obj).map do |o|
        case o
          when nil
            nil
          when BaseDecorator
            new(o.__getobj__, view_context)
          else
            new(o, view_context)
        end
      end
      obj.respond_to?(:each) ? decorated : decorated.first
    end
  end

  def initialize(base, view_context)
    super(base)
    @view_context = view_context
  end

  def h
    @view_context
  end

  # For some reason, view_context.html_escape is marked as private.  To provide access to the same functionality,
  # define it here
  def html_escape(*args)
    ERB::Util.html_escape(*args)
  end

  def markdown(text)
    MarkdownProcessor.render(text).html_safe
  end

  def wrapped
    __getobj__
  end
end