//: C10:AbstractFactory.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.
// Hrací prostředí.
#include <iostream>
using namespace std;

class Prekazka {
public:
  virtual void akce() = 0;
};

class Hrac {
public:
  virtual void bojujeS(Prekazka*) = 0;
};

class Kocicka: public Hrac {
  virtual void bojujeS(Prekazka* pr) {
    cout << "Kočička se musí vypořádat s překážkou ";
    pr->akce();
  }
};

class KungFuBorec: public Hrac {
  virtual void bojujeS(Prekazka* pr) {
    cout << "Nyní proti sobě bojuje KungFuBorec a ";
    pr->akce();
  }
};

class Hlavolam: public Prekazka {
public:
  void akce() { cout << "Hlavolam" << endl; }
};

class HroznaZbran: public Prekazka {
public:
  void akce() { cout << "HroznaZbran" << endl; }
};

// Abstraktní továrna:
class TovarnaHernichPrvku {
public:
  virtual Hrac* vytvorHrace() = 0;
  virtual Prekazka* vytvorPrekazku() = 0;
};

// Konkrétní továrny:
class KocickyAHlavolamy : public TovarnaHernichPrvku {
public:
  virtual Hrac* vytvorHrace() { return new Kocicka; }
  virtual Prekazka* vytvorPrekazku() { return new Hlavolam; }
};

class ZabitARozsekat : public TovarnaHernichPrvku {
public:
  virtual Hrac* vytvorHrace() { return new KungFuBorec; }
  virtual Prekazka* vytvorPrekazku() {
    return new HroznaZbran;
  }
};

class HerniProstredi {
  TovarnaHernichPrvku* thp;
  Hrac* h;
  Prekazka* pr;
public:
  HerniProstredi(TovarnaHernichPrvku* tovarna)
  : thp(tovarna), h(tovarna->vytvorHrace()),
    pr(tovarna->vytvorPrekazku()) {}
  void hrat() { h->bojujeS(pr); }
  ~HerniProstredi() {
    delete h;
    delete pr;
    delete thp;
  }
};

int main() {
  HerniProstredi
    g1(new KocickyAHlavolamy),
    g2(new ZabitARozsekat);
  g1.hrat();
  g2.hrat();
}
/* Výstup:
Kočička se musí vypořádat s překážkou Hlavolam
Nyní proti sobě bojuje KungFuBorec a HroznaZbran */ ///:~
