/*  
    Crystal Shooter, a first person shooter game engine.
    Homepage: http://members.xoom.com/thieber/cs

    Copyright (C) 1999 Thomas Hieber (thieber@gmx.net)
 
    This program is free software; you can redistribute it and/or modify 
    it under the terms of the GNU General Public License as published by 
    the Free Software Foundation; either version 2 of the License, or 
    (at your option) any later version. 
 
    This program is distributed in the hope that it will be useful, 
    but WITHOUT ANY WARRANTY; without even the implied warranty of 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    GNU General Public License for more details. 
 
    You should have received a copy of the GNU General Public License 
    along with this program; if not, write to the Free Software 
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
*/

#include "sysdef.h"
#include "csgame/gstd.h"
#include "csgame/gcontain.h"

geContainer::geContainer(geContainer* pContainer)
  : inherited(pContainer)
{
}

geContainer::~geContainer()
{
  PurgeObjects();
}

void geContainer::PrepareFrame(long elapsed_time, long current_time)
{
  inherited::PrepareFrame(elapsed_time, current_time);
  
  int NumObjects = GetNumObjects();
  for (int i=0; i<NumObjects; i++)
  {
    geObject* pObject = GetObject(i);
    ASSERT(pObject);
    pObject->PrepareFrame(elapsed_time, current_time);
  }

  PurgeObjects(); //Maybe that should move to geWorld, to ensure all cross calling has finshed
}

void geContainer::AddObject(geObject* pObject) 
{
  //first, remove the object from its old container.
  geContainer* pOldContainer = pObject->GetParent();
  if (pOldContainer && pOldContainer != this)
  {
    //Only remove that object from its old container, if there is one, and
    //if we are not its old container.
    pOldContainer->UnmanageObject(pObject);
  }

  m_ContainedObjects.Push(pObject);
}

void geContainer::FreeObject(geObject* pObject)
{
  m_ObjectsToBePurged.Push(pObject);
}

void geContainer::UnmanageObject(geObject* pObject)
{
  m_ObjectsToBeRemoved.Push(pObject);
}

void geContainer::PurgeObjects()
{
  int i=0;
  int NumberToBePurged = m_ObjectsToBePurged.Length();
  for (i=0; i<NumberToBePurged; i++)
  {
    geObject* pObjectToBePurged = (geObject*)m_ObjectsToBePurged[i];

    for (int j=0; j<GetNumObjects(); j++)
    {
      if (GetObject(j) == pObjectToBePurged)
      {
        m_ContainedObjects.Delete(j);
        delete pObjectToBePurged;
        continue; //Look for next object to be purged
      }
    }
  }

  int NumberToBeRemoved = m_ObjectsToBeRemoved.Length();
  for (i=0; i<NumberToBeRemoved; i++)
  {
    geObject* pObjectToBeRemoved = (geObject*)m_ObjectsToBeRemoved[i];

    for (int j=0; j<GetNumObjects(); j++)
    {
      if (GetObject(j) == pObjectToBeRemoved)
      {
        m_ContainedObjects.Delete(j);
        continue; //Look for next object to be removed
      }
    }
  }

  m_ObjectsToBePurged. DeleteAll();
  m_ObjectsToBeRemoved.DeleteAll();
}
