#include "stdafx.h"
#include <time.h>
#include <math.h>

#include <vector>

#include "DataOutputStream.h"
#include "DataInputStream.h"

#include "PartikelManager.h"

// MFC - Assists in finding memory leaks:
#ifdef MFC_DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

PartikelManager* PartikelManager::_instance = 0;

/****************************************************************************/
/** \brief Liefert die Singleton-Instanz
    \return Pointer auf die Instanz
*****************************************************************************/
PartikelManager* PartikelManager::getInstance()
{
 if (_instance == 0) 
   _instance = new PartikelManager();
 return _instance;
}

/****************************************************************************/
/** \brief Konstruktor
*****************************************************************************/
PartikelManager::PartikelManager() {}

/****************************************************************************/
/** \brief Destruktor
*****************************************************************************/
PartikelManager::~PartikelManager()
{
clear();
_instance = 0; // Singleton !!!
}

/*******************************************************************************
* 
*******************************************************************************/
void PartikelManager::clear(void)
{
unsigned int i=0;

for (i=0; i < m_spriteList.size(); i++)
   {
   Sprite* t = (Sprite*)m_spriteList[i];
   delete (t);
   }
m_spriteList.clear();

for (i=0; i < m_partikelSystemList.size(); i++)
   {
   PartikelSystem* t = (PartikelSystem*)m_partikelSystemList[i];
   delete (t);
   }
m_partikelSystemList.clear();
}

/*******************************************************************************
* 
*******************************************************************************/
void PartikelManager::transform(Matrix& matTranslate, Matrix& matRotate)
  {
   for (unsigned int i=0; i < m_partikelSystemList.size(); i++)
      {
      PartikelSystem* ps = m_partikelSystemList[i];
      ps->transform(matTranslate, matRotate);
      }
  }

 /*******************************************************************************
  * Projiziere die Raumkoordinaten auf die ViewPlane (2D)
  *******************************************************************************/
 void PartikelManager::project(float nearDist, float farDist)
   {
   for (unsigned int i=0; i < m_partikelSystemList.size(); i++)
      {
      PartikelSystem* ps = m_partikelSystemList[i];
      ps->project(nearDist, farDist);
      }
     }

/****************************************************************************/
/** \brief Liest den Partikelmanager aus dem Inputstream
*   \param dataIn DataInputStream
*******************************************************************************/
void PartikelManager::load(DataInputStream& dataIn) 
{
   int i=0, size=0;
   PartikelSystem* ps = 0;

   try
      {
      // Sprites laden:
      size = dataIn.readInt();
      for (i=0; i < size; i++)
         {
         Sprite* s = new Sprite();
         s->load(dataIn);
         m_spriteList.push_back(s);
         }

      // PartikelSysteme laden:
      size = dataIn.readInt();
      for (i=0; i < size; i++)
         {
         ps = new PartikelSystem(); 
         ps->load(dataIn);
         ps->init(m_spriteList);
         m_partikelSystemList.push_back(ps);
         }
      }
   catch (std::exception eof)
      {
      printf("EOF");  // TODO: Logfile schreiben
      }
}

/******************************************************************************/
/** \brief Serialisiert den PartikelManager in den Outputstream
    \param dataOut DataOutputStream
    \throws IOException 
*******************************************************************************/
void PartikelManager::save(DataOutputStream& dataOut) 
{
   int i=0, size=0;

   size = m_spriteList.size();
   dataOut.writeInt(size);    // Anzahl Sprites schreiben
   for (i=0; i < size; i++)
      {
      Sprite* sprite = m_spriteList[i];
      sprite->save(dataOut);
      }

   size = m_partikelSystemList.size();
   dataOut.writeInt(size);    // Anzahl Partikelsysteme schreiben
   for (i=0; i < size; i++)
      {
      PartikelSystem* ps = m_partikelSystemList[i];
      ps->save(dataOut);
      }
}
