#ifndef _ANIMATION_H_
#define _ANIMATION_H_

#include <iostream>
#include <string>
#include <vector>

// constants that represent static elements of the landscape
const char LANDSCAPE_TRAIL = '_';
const char LANDSCAPE_WALL = '|';

using namespace std;

// simple sound-making function
// also blocks the program for the duration of the sound,
// which makes animations visible to the human eye.
void make_sound();

// This makes it possible to use pointers and references to the class
// prior to its actual declaration and definition:
class Playland; // forward declaration for a class

// Generic creature that can move around landscape
class Creature {
protected:
    int m_position;
    char m_face; // what's on top
    char m_back; // what's underneath
    string& m_landscape;
    Playland& m_playland;
public:
    Creature( char face, Playland& land );
    void move( int steps );
    int get_position() const;
    virtual int fight( Creature* ) {
        cout << " creature wins! ";
        return 0;
    }
};//class Creature

// Specialized creature
class Monster : public Creature {
public:
    Monster( Playland& land );
    virtual int fight( Creature* ) {
        cout << " monster wins! ";
        return 0;
    }
}; // class Monster

// This represents the landscape background and keeps
// track of creatures that are present in the game.
// Each creature must be constructed with the reference
// to the instance of the Playland.
class Playland {
    // This allows Creature to access the landscape
    friend class Creature;
    string m_landscape; // the actual physical landscape
    vector< Creature* > m_vect_creatures; // creature roster
public:
    // Constructor; the user provides the landscape, e.g. "__|___|__"
    Playland( string const& landscape );

    // Each creature registers with the playland when it is created
    void register_creature( Creature* cret );

    // We decided that if creatures stumble upon one another while they
    // move, they engage in a fight. Since Playland keeps track of all
    // creature objects, it serves as an arbitrator to that goal as follows:
    // (1) The messenger says "I want to fight the other guy."
    // (2) The Playland finds the other creature and tells them:
    // (3) "The messenger will now fight with you."
    // (4) The result of the fight (an int) is returned back to the messenger
    int Playland::stage_fight( Creature* messenger );

};//class Playland

#endif // _ANIMATION_H_