//: C07:WildLifeMonitor.cpp
// Z knihy "Myslíme v jazyce C++, část 2" od Bruce Eckela a Chucka Allisona.
// (c) 1995-2004 MindView, Inc. Všechna práva vyhrazena.
// Přečtěte si podmínky používání zdrojových kódů umístěné v souboru 
// 'Licence.txt' dodávaném spolu s balíčkem kódu dostupným na www.MindView.net.
#include <algorithm>
#include <cstdlib>
#include <cstddef>
#include <ctime>
#include <iostream>
#include <iterator>
#include <map>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

class DataPoint {
  int x, y; // Souřadnice místa
  time_t time; // Doba pozorování
public:
  DataPoint() : x(0), y(0), time(0) {}
  DataPoint(int xx, int yy, time_t tm) :
    x(xx), y(yy), time(tm) {}

  int getX() const { return x; }
  int getY() const { return y; }
  const time_t* getTime() const { return &time; }
};

string zvire[] = {
  "čipmunk", "jezevec", "svišť", "lasička",
  "veverka", "bělokur", "medvěd", "orel",
  "jestřáb", "hraboš", "jelen", "vydra", "kolibřík",
};
const int ASZ = sizeof zvire/sizeof *zvire;
vector<string> zvirata(zvire, zvire + ASZ);

// všechny inormace jsou obsaženy v 
// objektu "Pozorovani", který může být 
// odeslán do výstupního proudu
typedef pair<string, DataPoint> Pozorovani;

ostream&
operator<<(ostream& os, const Pozorovani& s) {
  return os << s.first << " Pozorován na x= "
    << s.second.getX() << ", y= " << s.second.getY()
    << ", čas = " << ctime(s.second.getTime());
}

// Generátor pozorování:
class GenPozorovani {
  vector<string>& zvirata;
  enum { D = 100 };
public:
  GenPozorovani(vector<string>& an) : zvirata(an) {}
  Pozorovani operator()() {
    Pozorovani vysledek;
    int vyber = rand() % zvirata.size();
    vysledek.first = zvirata[vyber];
    vysledek.second = DataPoint(
      rand() % D, rand() % D, time(0));
    return vysledek;
  }
};

// Zobrazí nabídku zvířat umožňující uživateli jedno 
// si vybrat, vrací hodnotu indexu:
int menu() {
  cout << "Vyberte si zvire nebo 'k' jako konec: ";
  for(size_t i = 0; i < zvirata.size(); i++)
    cout <<'['<< i <<']'<< zvirata[i] << ' ';
  cout << endl;
  string odpoved;
  cin >> odpoved;
  if(odpoved.at(0) == 'k') return 0;
  istringstream r(odpoved);
  int i;
  r >> i; // převede na int
  i %= zvirata.size();
  return i;
}

int main() {
  typedef multimap<string, DataPoint> DataMap;
  typedef DataMap::iterator DMIter;
  DataMap pozorovani;
  srand(time(0));  // náhodná čísla
  generate_n(inserter(pozorovani, pozorovani.begin()),
    50, GenPozorovani(zvirata));
  // vytisknout vše:
  copy(pozorovani.begin(), pozorovani.end(),
    ostream_iterator<Pozorovani>(cout, ""));
  // Vytisknout pozorování pro vybrané zvíře:
  for(int count = 1; count < 10; count++) {
    // Pro výběr použijte menu:
    // int i = menu();
    // generováno náhodně (pro automatické testování):
    int i = rand() % zvirata.size();
    // iterátory v "rozsahu" ukazující na 
		// začátek a za konec odpovídajícího rozsahu
    pair<DMIter, DMIter> rozsah =
      pozorovani.equal_range(zvirata[i]);
    copy(rozsah.first, rozsah.second,
      ostream_iterator<Pozorovani>(cout, ""));
  }
} ///:~
