/*
 * Copyright (C) 2012 Alec Thomas <alec@swapoff.org>
 * All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.
 *
 * Author: Alec Thomas <alec@swapoff.org>
 */

#pragma once


#include <cstdint>
#include <tuple>
#include <new>
#include <cstdlib>
#include <algorithm>
#include <bitset>
#include <cassert>
#include <iostream>
#include <iterator>
#include <list>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include <type_traits>
 #include <functional>

#include "entityx/help/Pool.h"
#include "entityx/config.h"
#include "entityx/Event.h"
#include "entityx/help/NonCopyable.h"

namespace entityx {

typedef std::uint32_t uint32_t;
typedef std::uint64_t uint64_t;

class EntityManager;


template <typename C, typename EM = EntityManager>
class ComponentHandle;



/** A convenience handle around an Entity::Id.
 *
 * If an entity is destroyed, any copies will be invalidated. Use valid() to
 * check for validity before using.
 *
 * Create entities with `EntityManager`:
 *
 *     Entity entity = entity_manager->create();
 */
class Entity {
public:
  struct Id {
    Id() : id_(0) {}
    explicit Id(uint64_t id) : id_(id) {}
    Id(uint32_t index, uint32_t version) : id_(uint64_t(index) | uint64_t(version) << 32UL) {}

    uint64_t id() const { return id_; }

    bool operator == (const Id &other) const { return id_ == other.id_; }
    bool operator != (const Id &other) const { return id_ != other.id_; }
    bool operator < (const Id &other) const { return id_ < other.id_; }

    uint32_t index() const { return id_ & 0xffffffffUL; }
    uint32_t version() const { return id_ >> 32; }

  private:
    friend class EntityManager;

    uint64_t id_;
  };


  /**
   * Id of an invalid Entity.
   */
  static const Id INVALID;

  Entity() = default;
  Entity(EntityManager *manager, Entity::Id id) : manager_(manager), id_(id) {}
  Entity(const Entity &other) = default;
  Entity &operator = (const Entity &other) = default;

  /**
   * Check if Entity handle is invalid.
   */
  operator bool() const {
    return valid();
  }

  bool operator == (const Entity &other) const {
    return other.manager_ == manager_ && other.id_ == id_;
  }

  bool operator != (const Entity &other) const {
    return !(other == *this);
  }

  bool operator < (const Entity &other) const {
    return other.id_ < id_;
  }

  /**
   * Is this Entity handle valid?
   *
   * In older versions of EntityX, there were no guarantees around entity
   * validity if a previously allocated entity slot was reassigned. That is no
   * longer the case: if a slot is reassigned, old Entity::Id's will be
   * invalid.
   */
  bool valid() const;

  /**
   * Invalidate Entity handle, disassociating it from an EntityManager and invalidating its ID.
   *
   * Note that this does *not* affect the underlying entity and its
   * components. Use destroy() to destroy the associated Entity and components.
   */
  void invalidate();

  Id id() const { return id_; }

  template <typename C, typename ... Args>
  ComponentHandle<C> assign(Args && ... args);

  template <typename C>
  ComponentHandle<C> assign_from_copy(const C &component);

  template <typename C, typename ... Args>
  ComponentHandle<C> replace(Args && ... args);

  template <typename C>
  void remove();

  template <typename C, typename = typename std::enable_if<!std::is_const<C>::value>::type>
  ComponentHandle<C> component();

  template <typename C, typename = typename std::enable_if<std::is_const<C>::value>::type>
  const ComponentHandle<C, const EntityManager> component() const;

  template <typename ... Components>
  std::tuple<ComponentHandle<Components>...> components();

  template <typename ... Components>
  std::tuple<ComponentHandle<const Components, const EntityManager>...> components() const;

  template <typename C>
  bool has_component() const;

  template <typename A, typename ... Args>
  void unpack(ComponentHandle<A> &a, ComponentHandle<Args> & ... args);

  /**
   * Destroy and invalidate this Entity.
   */
  void destroy();

  std::bitset<entityx::MAX_COMPONENTS> component_mask() const;

 private:
  EntityManager *manager_ = nullptr;
  Entity::Id id_ = INVALID;
};


/**
 * A ComponentHandle<C> is a wrapper around an instance of a component.
 *
 * It provides safe access to components. The handle will be invalidated under
 * the following conditions:
 *
 * - If a component is removed from its host entity.
 * - If its host entity is destroyed.
 */
template <typename C, typename EM>
class ComponentHandle {
public:
  typedef C ComponentType;

  ComponentHandle() : manager_(nullptr) {}

  bool valid() const;
  operator bool() const;

  C *operator -> ();
  const C *operator -> () const;

  C &operator * ();
  const C &operator * () const;

  C *get();
  const C *get() const;

  /**
   * Remove the component from its entity and destroy it.
   */
  void remove();

  /**
   * Returns the Entity associated with the component
   */
  Entity entity();

  bool operator == (const ComponentHandle<C> &other) const {
    return manager_ == other.manager_ && id_ == other.id_;
  }

  bool operator != (const ComponentHandle<C> &other) const {
    return !(*this == other);
  }

private:
  friend class EntityManager;

  ComponentHandle(EM *manager, Entity::Id id) :
      manager_(manager), id_(id) {}

  EM *manager_;
  Entity::Id id_;
};


/**
 * Base component class, only used for insertion into collections.
 *
 * Family is used for registration.
 */
struct BaseComponent {
 public:
  typedef size_t Family;

  // NOTE: Component memory is *always* managed by the EntityManager.
  // Use Entity::destroy() instead.
  void operator delete(void *p) { fail(); }
  void operator delete[](void *p) { fail(); }


 protected:
  static void fail() {
#if defined(_HAS_EXCEPTIONS) || defined(__EXCEPTIONS)
    throw std::bad_alloc();
#else
    std::abort();
#endif
  }

  static Family family_counter_;
};


/**
 * Component implementations should inherit from this.
 *
 * Components MUST provide a no-argument constructor.
 * Components SHOULD provide convenience constructors for initializing on assignment to an Entity::Id.
 *
 * This is a struct to imply that components should be data-only.
 *
 * Usage:
 *
 *     struct Position : public Component<Position> {
 *       Position(float x = 0.0f, float y = 0.0f) : x(x), y(y) {}
 *
 *       float x, y;
 *     };
 *
 * family() is used for registration.
 */
template <typename Derived>
struct Component : public BaseComponent {
 public:
  typedef ComponentHandle<Derived> Handle;
  typedef ComponentHandle<const Derived, const EntityManager> ConstHandle;

private:
  friend class EntityManager;
  /// Used internally for registration.
  static Family family();
};


/**
 * Emitted when an entity is added to the system.
 */
struct EntityCreatedEvent : public Event<EntityCreatedEvent> {
  explicit EntityCreatedEvent(Entity entity) : entity(entity) {}
  virtual ~EntityCreatedEvent();

  Entity entity;
};


/**
 * Called just prior to an entity being destroyed.
 */
struct EntityDestroyedEvent : public Event<EntityDestroyedEvent> {
  explicit EntityDestroyedEvent(Entity entity) : entity(entity) {}
  virtual ~EntityDestroyedEvent();

  Entity entity;
};


/**
 * Emitted when any component is added to an entity.
 */
template <typename C>
struct ComponentAddedEvent : public Event<ComponentAddedEvent<C>> {
  ComponentAddedEvent(Entity entity, ComponentHandle<C> component) :
      entity(entity), component(component) {}

  Entity entity;
  ComponentHandle<C> component;
};

/**
 * Emitted when any component is removed from an entity.
 */
template <typename C>
struct ComponentRemovedEvent : public Event<ComponentRemovedEvent<C>> {
  ComponentRemovedEvent(Entity entity, ComponentHandle<C> component) :
      entity(entity), component(component) {}

  Entity entity;
  ComponentHandle<C> component;
};

/**
 * Helper class to perform component operations in a typed manner.
 */
class BaseComponentHelper {
public:
  virtual ~BaseComponentHelper() {}
  virtual void remove_component(Entity e) = 0;
  virtual void copy_component_to(Entity source, Entity target) = 0;
};

template <typename C>
class ComponentHelper : public BaseComponentHelper {
public:
  void remove_component(Entity e) override {
    e.remove<C>();
  }
  void copy_component_to(Entity source, Entity target) override {
    target.assign_from_copy<C>(*(source.component<C>().get()));
  }
};

/**
 * Manages Entity::Id creation and component assignment.
 */
class EntityManager : entityx::help::NonCopyable {
 public:
  typedef std::bitset<entityx::MAX_COMPONENTS> ComponentMask;

  explicit EntityManager(EventManager &event_manager);
  virtual ~EntityManager();

  /// An iterator over a view of the entities in an EntityManager.
  /// If All is true it will iterate over all valid entities and will ignore the entity mask.
  template <class Delegate, bool All = false>
  class ViewIterator : public std::iterator<std::input_iterator_tag, Entity::Id> {
   public:
    Delegate &operator ++() {
      ++i_;
      next();
      return *static_cast<Delegate*>(this);
    }
    bool operator == (const Delegate& rhs) const { return i_ == rhs.i_; }
    bool operator != (const Delegate& rhs) const { return i_ != rhs.i_; }
    Entity operator * () { return Entity(manager_, manager_->create_id(i_)); }
    const Entity operator * () const { return Entity(manager_, manager_->create_id(i_)); }

   protected:
    ViewIterator(EntityManager *manager, uint32_t index)
        : manager_(manager), i_(index), capacity_(manager_->capacity()), free_cursor_(~0UL) {
      if (All) {
        std::sort(manager_->free_list_.begin(), manager_->free_list_.end());
        free_cursor_ = 0;
      }
    }
    ViewIterator(EntityManager *manager, const ComponentMask mask, uint32_t index)
        : manager_(manager), mask_(mask), i_(index), capacity_(manager_->capacity()), free_cursor_(~0UL) {
      if (All) {
        std::sort(manager_->free_list_.begin(), manager_->free_list_.end());
        free_cursor_ = 0;
      }
    }

    void next() {
      while (i_ < capacity_ && !predicate()) {
        ++i_;
      }

      if (i_ < capacity_) {
        Entity entity = manager_->get(manager_->create_id(i_));
        static_cast<Delegate*>(this)->next_entity(entity);
      }
    }

    inline bool predicate() {
      return (All && valid_entity()) || (manager_->entity_component_mask_[i_] & mask_) == mask_;
    }

    inline bool valid_entity() {
      const std::vector<uint32_t> &free_list = manager_->free_list_;
      if (free_cursor_ < free_list.size() && free_list[free_cursor_] == i_) {
        ++free_cursor_;
        return false;
      }
      return true;
    }

    EntityManager *manager_;
    ComponentMask mask_;
    uint32_t i_;
    size_t capacity_;
    size_t free_cursor_;
  };

  template <bool All>
  class BaseView {
  public:
    class Iterator : public ViewIterator<Iterator, All> {
    public:
      Iterator(EntityManager *manager,
        const ComponentMask mask,
        uint32_t index) : ViewIterator<Iterator, All>(manager, mask, index) {
        ViewIterator<Iterator, All>::next();
      }

      void next_entity(Entity &entity) {}
    };

    Iterator begin() { return Iterator(manager_, mask_, 0); }
    Iterator end() { return Iterator(manager_, mask_, uint32_t(manager_->capacity())); }
    const Iterator begin() const { return Iterator(manager_, mask_, 0); }
    const Iterator end() const { return Iterator(manager_, mask_, manager_->capacity()); }

  private:
    friend class EntityManager;

    explicit BaseView(EntityManager *manager) : manager_(manager) { mask_.set(); }
    BaseView(EntityManager *manager, ComponentMask mask) :
        manager_(manager), mask_(mask) {}

    EntityManager *manager_;
    ComponentMask mask_;
  };

  template <bool All, typename ... Components>
  class TypedView: public BaseView<All> {
  public:
    template <typename T> struct identity { typedef T type; };

    void each(typename identity<std::function<void(Entity entity, Components&...)>>::type f) {
      for (auto it : *this)
        f(it, *(it.template component<Components>().get())...);
    }

  private:
    friend class EntityManager;

    explicit TypedView(EntityManager *manager) : BaseView<All>(manager) {}
    TypedView(EntityManager *manager, ComponentMask mask) : BaseView<All>(manager, mask) {}
  };

  template <typename ... Components> using View = TypedView<false, Components...>;
  typedef BaseView<true> DebugView;

  template <typename ... Components>
  class UnpackingView {
   public:
    struct Unpacker {
      explicit Unpacker(ComponentHandle<Components> & ... handles) :
          handles(std::tuple<ComponentHandle<Components> & ...>(handles...)) {}

      void unpack(entityx::Entity &entity) const {
        unpack_<0, Components...>(entity);
      }


    private:
      template <int N, typename C>
      void unpack_(entityx::Entity &entity) const {
        std::get<N>(handles) = entity.component<C>();
      }

      template <int N, typename C0, typename C1, typename ... Cn>
      void unpack_(entityx::Entity &entity) const {
        std::get<N>(handles) = entity.component<C0>();
        unpack_<N + 1, C1, Cn...>(entity);
      }

      std::tuple<ComponentHandle<Components> & ...> handles;
    };


    class Iterator : public ViewIterator<Iterator> {
    public:
      Iterator(EntityManager *manager,
        const ComponentMask mask,
        uint32_t index,
        const Unpacker &unpacker) : ViewIterator<Iterator>(manager, mask, index), unpacker_(unpacker) {
        ViewIterator<Iterator>::next();
      }

      void next_entity(Entity &entity) {
        unpacker_.unpack(entity);
      }

    private:
      const Unpacker &unpacker_;
    };


    Iterator begin() { return Iterator(manager_, mask_, 0, unpacker_); }
    Iterator end() { return Iterator(manager_, mask_, static_cast<uint32_t>(manager_->capacity()), unpacker_); }
    const Iterator begin() const { return Iterator(manager_, mask_, 0, unpacker_); }
    const Iterator end() const { return Iterator(manager_, mask_, static_cast<uint32_t>(manager_->capacity()), unpacker_); }


   private:
    friend class EntityManager;

    UnpackingView(EntityManager *manager, ComponentMask mask, ComponentHandle<Components> & ... handles) :
        manager_(manager), mask_(mask), unpacker_(handles...) {}

    EntityManager *manager_;
    ComponentMask mask_;
    Unpacker unpacker_;
  };

  /**
   * Number of managed entities.
   */
  size_t size() const { return entity_component_mask_.size() - free_list_.size(); }

  /**
   * Current entity capacity.
   */
  size_t capacity() const { return entity_component_mask_.size(); }

  /**
   * Return true if the given entity ID is still valid.
   */
  bool valid(Entity::Id id) const {
    return id.index() < entity_version_.size() && entity_version_[id.index()] == id.version();
  }

  /**
   * Create a new Entity::Id.
   *
   * Emits EntityCreatedEvent.
   */
  Entity create() {
    uint32_t index, version;
    if (free_list_.empty()) {
      index = index_counter_++;
      accomodate_entity(index);
      version = entity_version_[index] = 1;
    } else {
      index = free_list_.back();
      free_list_.pop_back();
       version = entity_version_[index];
    }
    Entity entity(this, Entity::Id(index, version));
    event_manager_.emit<EntityCreatedEvent>(entity);
    return entity;
  }

  /**
   * Create a new Entity by copying another. Copy-constructs each component.
   *
   * Emits EntityCreatedEvent.
   */
  Entity create_from_copy(Entity original) {
    assert(original.valid());
    auto clone = create();
    auto mask = original.component_mask();
    for (size_t i = 0; i < component_helpers_.size(); i++) {
      BaseComponentHelper *helper = component_helpers_[i];
      if (helper && mask.test(i))
        helper->copy_component_to(original, clone);
    }
    return clone;
  }


  /**
   * Destroy an existing Entity::Id and its associated Components.
   *
   * Emits EntityDestroyedEvent.
   */
  void destroy(Entity::Id entity) {
    assert_valid(entity);
    uint32_t index = entity.index();
    auto mask = entity_component_mask_[index];
    for (size_t i = 0; i < component_helpers_.size(); i++) {
      BaseComponentHelper *helper = component_helpers_[i];
      if (helper && mask.test(i))
        helper->remove_component(Entity(this, entity));
    }
    event_manager_.emit<EntityDestroyedEvent>(Entity(this, entity));
    entity_component_mask_[index].reset();
    entity_version_[index]++;
    free_list_.push_back(index);
  }

  Entity get(Entity::Id id) {
    assert_valid(id);
    return Entity(this, id);
  }

  /**
   * Create an Entity::Id for a slot.
   *
   * NOTE: Does *not* check for validity, but the Entity::Id constructor will
   * fail if the ID is invalid.
   */
  Entity::Id create_id(uint32_t index) const {
    return Entity::Id(index, entity_version_[index]);
  }

  /**
   * Assign a Component to an Entity::Id, passing through Component constructor arguments.
   *
   *     Position &position = em.assign<Position>(e, x, y);
   *
   * @returns Smart pointer to newly created component.
   */
  template <typename C, typename ... Args>
  ComponentHandle<C> assign(Entity::Id id, Args && ... args) {
    assert_valid(id);
    const BaseComponent::Family family = component_family<C>();
    assert(!entity_component_mask_[id.index()].test(family));

    // Placement new into the component pool.
    Pool<C> *pool = accomodate_component<C>();
    ::new(pool->get(id.index())) C(std::forward<Args>(args) ...);

    // Set the bit for this component.
    entity_component_mask_[id.index()].set(family);

    // Create and return handle.
    ComponentHandle<C> component(this, id);
    event_manager_.emit<ComponentAddedEvent<C>>(Entity(this, id), component);
    return component;
  }

  /**
   * Remove a Component from an Entity::Id
   *
   * Emits a ComponentRemovedEvent<C> event.
   */
  template <typename C>
  void remove(Entity::Id id) {
    assert_valid(id);
    const BaseComponent::Family family = component_family<C>();
    const uint32_t index = id.index();

    // Find the pool for this component family.
    BasePool *pool = component_pools_[family];
    ComponentHandle<C> component(this, id);
    event_manager_.emit<ComponentRemovedEvent<C>>(Entity(this, id), component);

    // Remove component bit.
    entity_component_mask_[id.index()].reset(family);

    // Call destructor.
    pool->destroy(index);
  }

  /**
   * Check if an Entity has a component.
   */
  template <typename C>
  bool has_component(Entity::Id id) const {
    assert_valid(id);
    size_t family = component_family<C>();
    // We don't bother checking the component mask, as we return a nullptr anyway.
    if (family >= component_pools_.size())
      return false;
    BasePool *pool = component_pools_[family];
    if (!pool || !entity_component_mask_[id.index()][family])
      return false;
    return true;
  }

  /**
   * Retrieve a Component assigned to an Entity::Id.
   *
   * @returns Pointer to an instance of C, or nullptr if the Entity::Id does not have that Component.
   */
  template <typename C, typename = typename std::enable_if<!std::is_const<C>::value>::type>
  ComponentHandle<C> component(Entity::Id id) {
    assert_valid(id);
    size_t family = component_family<C>();
    // We don't bother checking the component mask, as we return a nullptr anyway.
    if (family >= component_pools_.size())
      return ComponentHandle<C>();
    BasePool *pool = component_pools_[family];
    if (!pool || !entity_component_mask_[id.index()][family])
      return ComponentHandle<C>();
    return ComponentHandle<C>(this, id);
  }

  /**
   * Retrieve a Component assigned to an Entity::Id.
   *
   * @returns Component instance, or nullptr if the Entity::Id does not have that Component.
   */
  template <typename C, typename = typename std::enable_if<std::is_const<C>::value>::type>
  const ComponentHandle<C, const EntityManager> component(Entity::Id id) const {
    assert_valid(id);
    size_t family = component_family<C>();
    // We don't bother checking the component mask, as we return a nullptr anyway.
    if (family >= component_pools_.size())
      return ComponentHandle<C, const EntityManager>();
    BasePool *pool = component_pools_[family];
    if (!pool || !entity_component_mask_[id.index()][family])
      return ComponentHandle<C, const EntityManager>();
    return ComponentHandle<C, const EntityManager>(this, id);
  }

  template <typename ... Components>
  std::tuple<ComponentHandle<Components>...> components(Entity::Id id) {
    return std::make_tuple(component<Components>(id)...);
  }

  template <typename ... Components>
  std::tuple<ComponentHandle<const Components, const EntityManager>...> components(Entity::Id id) const {
    return std::make_tuple(component<const Components>(id)...);
  }

  /**
   * Find Entities that have all of the specified Components.
   *
   * @code
   * for (Entity entity : entity_manager.entities_with_components<Position, Direction>()) {
   *   ComponentHandle<Position> position = entity.component<Position>();
   *   ComponentHandle<Direction> direction = entity.component<Direction>();
   *
   *   ...
   * }
   * @endcode
   */
  template <typename ... Components>
  View<Components...> entities_with_components() {
    auto mask = component_mask<Components ...>();
    return View<Components...>(this, mask);
  }

  template <typename T> struct identity { typedef T type; };

  template <typename ... Components>
  void each(typename identity<std::function<void(Entity entity, Components&...)>>::type f) {
    return entities_with_components<Components...>().each(f);
  }

  /**
   * Find Entities that have all of the specified Components and assign them
   * to the given parameters.
   *
   * @code
   * ComponentHandle<Position> position;
   * ComponentHandle<Direction> direction;
   * for (Entity entity : entity_manager.entities_with_components(position, direction)) {
   *   // Use position and component here.
   * }
   * @endcode
   */
  template <typename ... Components>
  UnpackingView<Components...> entities_with_components(ComponentHandle<Components> & ... components) {
    auto mask = component_mask<Components...>();
    return UnpackingView<Components...>(this, mask, components...);
  }

  /**
   * Iterate over all *valid* entities (ie. not in the free list). Not fast,
   * so should only be used for debugging.
   *
   * @code
   * for (Entity entity : entity_manager.entities_for_debugging()) {}
   *
   * @return An iterator view over all valid entities.
   */
  DebugView entities_for_debugging() {
    return DebugView(this);
  }

  template <typename C>
  void unpack(Entity::Id id, ComponentHandle<C> &a) {
    assert_valid(id);
    a = component<C>(id);
  }

  /**
   * Unpack components directly into pointers.
   *
   * Components missing from the entity will be set to nullptr.
   *
   * Useful for fast bulk iterations.
   *
   * ComponentHandle<Position> p;
   * ComponentHandle<Direction> d;
   * unpack<Position, Direction>(e, p, d);
   */
  template <typename A, typename ... Args>
  void unpack(Entity::Id id, ComponentHandle<A> &a, ComponentHandle<Args> & ... args) {
    assert_valid(id);
    a = component<A>(id);
    unpack<Args ...>(id, args ...);
  }

  /**
   * Destroy all entities and reset the EntityManager.
   */
  void reset();

  // Retrieve the component family for a type.
  template <typename C>
  static BaseComponent::Family component_family() {
    return Component<typename std::remove_const<C>::type>::family();
  }

 private:
  friend class Entity;
  template <typename C, typename EM>
  friend class ComponentHandle;


  inline void assert_valid(Entity::Id id) const {
    assert(id.index() < entity_component_mask_.size() && "Entity::Id ID outside entity vector range");
    assert(entity_version_[id.index()] == id.version() && "Attempt to access Entity via a stale Entity::Id");
  }

  template <typename C>
  C *get_component_ptr(Entity::Id id) {
    assert(valid(id));
    BasePool *pool = component_pools_[component_family<C>()];
    assert(pool);
    return static_cast<C*>(pool->get(id.index()));
  }

  template <typename C>
  const C *get_component_ptr(Entity::Id id) const {
    assert_valid(id);
    BasePool *pool = component_pools_[component_family<C>()];
    assert(pool);
    return static_cast<const C*>(pool->get(id.index()));
  }

  ComponentMask component_mask(Entity::Id id) {
    assert_valid(id);
    return entity_component_mask_.at(id.index());
  }

  template <typename C>
  ComponentMask component_mask() {
    ComponentMask mask;
    mask.set(component_family<C>());
    return mask;
  }

  template <typename C1, typename C2, typename ... Components>
  ComponentMask component_mask() {
    return component_mask<C1>() | component_mask<C2, Components ...>();
  }

  template <typename C>
  ComponentMask component_mask(const ComponentHandle<C> &c) {
    return component_mask<C>();
  }

  template <typename C1, typename ... Components>
  ComponentMask component_mask(const ComponentHandle<C1> &c1, const ComponentHandle<Components> &... args) {
    return component_mask<C1, Components ...>();
  }

  inline void accomodate_entity(uint32_t index) {
    if (entity_component_mask_.size() <= index) {
      entity_component_mask_.resize(index + 1);
      entity_version_.resize(index + 1);
      for (BasePool *pool : component_pools_)
        if (pool) pool->expand(index + 1);
    }
  }

  template <typename C>
  Pool<C> *accomodate_component() {
    BaseComponent::Family family = component_family<C>();
    if (component_pools_.size() <= family) {
      component_pools_.resize(family + 1, nullptr);
    }
    if (!component_pools_[family]) {
      Pool<C> *pool = new Pool<C>();
      pool->expand(index_counter_);
      component_pools_[family] = pool;
    }
    if (component_helpers_.size() <= family) {
      component_helpers_.resize(family + 1, nullptr);
    }
    if (!component_helpers_[family]) {
      ComponentHelper<C> *helper = new ComponentHelper<C>();
      component_helpers_[family] = helper;
    }
    return static_cast<Pool<C>*>(component_pools_[family]);
  }


  uint32_t index_counter_ = 0;

  EventManager &event_manager_;
  // Each element in component_pools_ corresponds to a Pool for a Component.
  // The index into the vector is the Component::family().
  std::vector<BasePool*> component_pools_;
  // Each element in component_helpers_ corresponds to a ComponentHelper for a Component type.
  // The index into the vector is the Component::family().
  std::vector<BaseComponentHelper*> component_helpers_;
  // Bitmask of components associated with each entity. Index into the vector is the Entity::Id.
  std::vector<ComponentMask> entity_component_mask_;
  // Vector of entity version numbers. Incremented each time an entity is destroyed
  std::vector<uint32_t> entity_version_;
  // List of available entity slots.
  std::vector<uint32_t> free_list_;
};


template <typename C>
BaseComponent::Family Component<C>::family() {
  static Family family = family_counter_++;
  assert(family < entityx::MAX_COMPONENTS);
  return family;
}


template <typename C, typename ... Args>
ComponentHandle<C> Entity::assign(Args && ... args) {
  assert(valid());
  return manager_->assign<C>(id_, std::forward<Args>(args) ...);
}

template <typename C>
ComponentHandle<C> Entity::assign_from_copy(const C &component) {
  assert(valid());
  return manager_->assign<C>(id_, std::forward<const C &>(component));
}

template <typename C, typename ... Args>
ComponentHandle<C> Entity::replace(Args && ... args) {
  assert(valid());
  auto handle = component<C>();
  if (handle) {
    *(handle.get()) = C(std::forward<Args>(args) ...);
  } else {
    handle = manager_->assign<C>(id_, std::forward<Args>(args) ...);
  }
  return handle;
}

template <typename C>
void Entity::remove() {
  assert(valid() && has_component<C>());
  manager_->remove<C>(id_);
}

template <typename C, typename>
ComponentHandle<C> Entity::component() {
  assert(valid());
  return manager_->component<C>(id_);
}

  template <typename C, typename>
const ComponentHandle<C, const EntityManager> Entity::component() const {
  assert(valid());
  return const_cast<const EntityManager*>(manager_)->component<const C>(id_);
}

template <typename ... Components>
std::tuple<ComponentHandle<Components>...> Entity::components() {
  assert(valid());
  return manager_->components<Components...>(id_);
}

template <typename ... Components>
std::tuple<ComponentHandle<const Components, const EntityManager>...> Entity::components() const {
  assert(valid());
  return const_cast<const EntityManager*>(manager_)->components<const Components...>(id_);
}


template <typename C>
bool Entity::has_component() const {
  assert(valid());
  return manager_->has_component<C>(id_);
}

template <typename A, typename ... Args>
void Entity::unpack(ComponentHandle<A> &a, ComponentHandle<Args> & ... args) {
  assert(valid());
  manager_->unpack(id_, a, args ...);
}

inline bool Entity::valid() const {
  return manager_ && manager_->valid(id_);
}

inline std::ostream &operator << (std::ostream &out, const Entity::Id &id) {
  out << "Entity::Id(" << id.index() << "." << id.version() << ")";
  return out;
}


inline std::ostream &operator << (std::ostream &out, const Entity &entity) {
  out << "Entity(" << entity.id() << ")";
  return out;
}


template <typename C, typename EM>
inline ComponentHandle<C, EM>::operator bool() const {
  return valid();
}

template <typename C, typename EM>
inline bool ComponentHandle<C, EM>::valid() const {
  return manager_ && manager_->valid(id_) && manager_->template has_component<C>(id_);
}

template <typename C, typename EM>
inline C *ComponentHandle<C, EM>::operator -> () {
  assert(valid());
  return manager_->template get_component_ptr<C>(id_);
}

template <typename C, typename EM>
inline const C *ComponentHandle<C, EM>::operator -> () const {
  assert(valid());
  return manager_->template get_component_ptr<C>(id_);
}

template <typename C, typename EM>
inline C &ComponentHandle<C, EM>::operator * () {
  assert(valid());
  return *manager_->template get_component_ptr<C>(id_);
}

template <typename C, typename EM>
inline const C &ComponentHandle<C, EM>::operator * () const {
  assert(valid());
  return *manager_->template get_component_ptr<C>(id_);
}

template <typename C, typename EM>
inline C *ComponentHandle<C, EM>::get() {
  assert(valid());
  return manager_->template get_component_ptr<C>(id_);
}

template <typename C, typename EM>
inline const C *ComponentHandle<C, EM>::get() const {
  assert(valid());
  return manager_->template get_component_ptr<C>(id_);
}

template <typename C, typename EM>
inline void ComponentHandle<C, EM>::remove() {
  assert(valid());
  manager_->template remove<C>(id_);
}

template <typename C, typename EM>
inline Entity ComponentHandle<C, EM>::entity() {
  assert(valid());
  return manager_->get(id_);
}


}  // namespace entityx


namespace std {
template <> struct hash<entityx::Entity> {
  std::size_t operator () (const entityx::Entity &entity) const {
    return static_cast<std::size_t>(entity.id().index() ^ entity.id().version());
  }
};

template <> struct hash<const entityx::Entity> {
  std::size_t operator () (const entityx::Entity &entity) const {
    return static_cast<std::size_t>(entity.id().index() ^ entity.id().version());
  }
};
}

