// Geom. Objekte: Statische Member: drawAll (Version mit Set, Z-Wert und Nummer)
//
// Aufruf: main
//
// Klaus Kusche, 2020

#include <cstdlib>
#include <ctime>

#include "sdlinterf.h"

#include "color.h"
#include "graobj.h"
#include "rect.h"
#include "circ.h"

using namespace std;

const int objCnt = 128;

// Zur Wahl einer zufälligen Geschwindigkeit, die nicht 0 ist:
// Berechne eine Zufallszahl z von -n ... -1 oder 1 ... n (aber nicht 0)
inline int randPM(int n)
{
  return ((rand() % n) + 1) - ((rand() % 2) * (n + 1));
}

// Erzeuge zufällig ein dynamisch angelegtes Rect- oder Circ-Objekt,
// (liefert einen Pointer auf das neue Objekt)
GraObj *mkGraObj()
{
  // Variante 1:
  // Wir geben keinen Z-Wert an an
  // Dann ist Z bei allen Objekten 0,
  // und sortiert wird nach den fortlaufenden Objekt-Nummern
  // ==> Die neuesten Objekte liegen obenauf, die älteren darunter
  if (rand() % 2 == 0) {
    // Color() liefert bei jedem Aufruf die "nächste" Farbe
    return new Rect(
      Color(), SDL_X_SIZE / 2, SDL_Y_SIZE / 2,
      rand() % 150 + 1, rand() % 150 + 1, randPM(3), randPM(3));
  } else {
    return new Circ(
      Color(), SDL_X_SIZE / 2, SDL_Y_SIZE / 2,
      rand() % 150 + 1, rand() % 150 + 1, randPM(3), randPM(3));
  }

  // Variante 2:
  // Wir geben den Objekten absteigende Z-Werte
  // ==> Die neuen Objekte entstehen ganz im Hintergrund,
  //     die älteren Objekte liegen obenauf
//  static int z = 0;
//  if (rand() % 2 == 0) {
//    return new Rect(
//      Color(), SDL_X_SIZE / 2, SDL_Y_SIZE / 2,
//      rand() % 150 + 1, rand() % 150 + 1, randPM(3), randPM(3), --z);
//  } else {
//    return new Circ(
//      Color(), SDL_X_SIZE / 2, SDL_Y_SIZE / 2,
//      rand() % 150 + 1, rand() % 150 + 1, randPM(3), randPM(3), --z);
//  }

  // Variante 3:
  // Wir geben den Objekten zufällige Z-Werte
//  if (rand() % 2 == 0) {
//    return new Rect(
//      Color(), SDL_X_SIZE / 2, SDL_Y_SIZE / 2,
//      rand() % 150 + 1, rand() % 150 + 1, randPM(3), randPM(3), rand());
//  } else {
//    return new Circ(
//      Color(), SDL_X_SIZE / 2, SDL_Y_SIZE / 2,
//      rand() % 150 + 1, rand() % 150 + 1, randPM(3), randPM(3), rand());
//  }
}

int main(void)
{
  srand(time(nullptr));
  sdlInit();

  GraObj *obj[objCnt];

  for (int i = 0; i < objCnt; ++i) {
    obj[i] = mkGraObj();
  }

  for (;;) {
    // neu: Zeichne alle Objekte nochmals, in Erzeugungs-Reihenfolge
    GraObj::drawAll();
    sdlUpdate();
    sdlMilliSleep(10);
    for (int i = 0; i < objCnt; ++i) {
      if (!obj[i]->fly()) {
        delete obj[i];
        obj[i] = mkGraObj();
      }
    }
  }

  sdlExit();

  exit(EXIT_SUCCESS);
}
