require "roleplay/version"

module Roleplay

  def included(base)
    base.send(:extend, ClassMethods)
  end

  def playing(name)
    modules = self.class.roles[name]
    raise "role #{name} does not define any modules" unless modules.present?
    value = self.dup
    value.singleton_class.send(:attr_accessor, :role)
    value.role = {name => modules}
    modules.each do |m|
      value.extend m
    end
    value
  end
  alias :as_a :playing

  def playing!(name)
    modules = self.class.roles[name]
    raise "role #{name} does not define any modules" unless modules.present?
    singleton_class.send(:attr_accessor, :role)
    self.role = {name => modules}
    modules.each do |m|
      extend m
    end
    self
  end
  alias :as_a! :playing!

  module ClassMethods

    attr_accessor :roles

    def plays_role(name, opts={})
      @roles ||= {}
      raise "no modules specified for role #{name}" unless opts[:using].present?
      roles[name] = [opts[:using]].flatten
    end

    def new_with_role(name)
      value = new
      modules = roles[name]
      raise "role #{name} does not define any modules" unless modules.present?
      value.singleton_class.send(:attr_accessor, :role)
      value.role = {name => modules}
      modules.each do |m|
        value.extend m
      end
      value
    end
  end
end

Object.send(:include, Roleplay)