#pragma once
#include "AutoPopulatedLocation.h"

//class PrimitiveLocation;

/**
 * @brief Composite static locations contain other locations.
 */
class CompositeLocation : public AutoPopulatedLocation
{
public:
  /////////
  // GUI //
  /////////
  typedef std::vector<AutoPopulatedLocation*>::iterator sub_location_iterator;
  std::pair<sub_location_iterator, sub_location_iterator> getSubLocations()
  {
    return std::make_pair(m_subLocations.begin(),
                          m_subLocations.end());
  }
  typedef std::vector<AutoPopulatedLocation*>::const_iterator sub_location_const_iterator;
  std::pair<sub_location_const_iterator, sub_location_const_iterator> getSubLocations() const
  {
    return std::make_pair(m_subLocations.begin(),
                          m_subLocations.end());
  }
  //size_t getNbSubLocations() const { return m_subLocations.size(); }

  //typedef std::list<PrimitiveLocation*>::iterator primitive_sub_location_iterator;
  //std::pair<primitive_sub_location_iterator, primitive_sub_location_iterator> getPrimitiveSubLocations()
  //{
  //  return std::make_pair(m_primitiveSubLocationsCache.begin(),
  //                        m_primitiveSubLocationsCache.end());
  //}
  //typedef std::list<PrimitiveLocation*>::const_iterator primitive_sub_location_const_iterator;
  //std::pair<primitive_sub_location_const_iterator, primitive_sub_location_const_iterator> getPrimitiveSubLocations() const
  //{
  //  return std::make_pair(m_primitiveSubLocationsCache.begin(),
  //                        m_primitiveSubLocationsCache.end());
  //}
  //size_t getNbPrimitiveSubLocations() const { return m_primitiveSubLocationsCache.size(); }

protected:
  friend class AutoPopulatedLocation;

  void addSubLocation(AutoPopulatedLocation* location);

  //void onPrimitiveSubLocationAdded(PrimitiveLocation* location)
  //{
  //  m_primitiveSubLocationsCache.insert(m_primitiveSubLocationsCache.end(), location);

  //  for (std::list<AutoPopulatedLocation*>::const_iterator it = m_subscribers.begin(); it != m_subscribers.end(); ++it)
  //  {
  //    assert(dynamic_cast<CompositeLocation*>(*it) != NULL);
  //    dynamic_cast<CompositeLocation*>(*it)->onPrimitiveSubLocationAdded(location);
  //  }
  //}

  /**
   * @brief Sub-locations (possibly composite) included in this composite location.
   */
  std::vector<AutoPopulatedLocation*> m_subLocations;
  /**
   * @brief Primitive sub-locations included in this composite location.
   */
  //std::list<PrimitiveLocation*> m_primitiveSubLocationsCache;
};
