/* This file is part of KsirK.
   Copyright (C) 2001-2007 Gael de Chalendar <kleag@free.fr>

   KsirK is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public
   License as published by the Free Software Foundation, either version 2
   of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
   02110-1301, USA
*/

#define KDE_NO_COMPAT

#ifndef KSIRK_COUNTRY_H
#define KSIRK_COUNTRY_H

#include "Sprites/infantrysprite.h"
#include "Sprites/cavalrysprite.h"
#include "Sprites/cannonsprite.h"
#include "Sprites/animspriteslist.h"

#define USE_UNSTABLE_LIBKDEGAMESPRIVATE_API
#include <libkdegamesprivate/kgame/kgameproperty.h>

#include <QPoint>
#include <QString>

class QSvgRenderer;
class QGraphicsSvgItem;

namespace Ksirk
{

class BackGnd;
class FlagSprite;

namespace GameLogic
{
class Player;
class Continent;
class GameAutomaton;

/**
 * Each country of the map is represented by a Country object. It has a name,
 * a point for its flag and points for its canon, cavalry, etc.
 * Also, it stores pointers to the objects that represent  its owner and the
 * sprites of its flag and its armies.
 */
class Country : QObject
{
  Q_OBJECT 

public:
  /**
    * Constructor
    * @param theName The name of this country.
    * @param centralPoint The point around which the fighter will be placed.
    * @param flagPoint The point (top left corner) where the flag sprite is drawn.
    * @param cannonPoint The point (top left corner) where the cannon sprite is drawn.
    * @param cavalryPoint The point (top left corner) where the cavalry sprite is drawn.
    * @param infantryPoint The point (top left corner) where the infantry sprite is drawn.
    * @param id The unique integer identifier of this country.
    */
  Country(GameAutomaton* game,
      const QString& theName,
      const QPointF& anchorPoint,
      const QPointF& centralPoint,
      const QPointF& flagPoint,
      const QPointF& cannonPoint,
      const QPointF& cavalryPoint,
      const QPointF& infantryPoint);

  /** Default destructor */
  ~Country() override;

  GameAutomaton* automaton() {return m_automaton;}

  /**
    * Removes the sprites (flag and soldiers), the owner, etc.
    * The sprites ared deleted.
    */
  void reset();

  /**
    * Creates the sprites necessary to display the armies of the country.
    * Eventually removes previously existing sprites.
    * @param backGnd The background onto which this country sprites will be drawn.
    */
  void createArmiesSprites();

  /**
    * Creates the sprite of the contry's flag. Eventually removes a previously
    * existing sprite.
    * @param theFlagFileName The flag's sprite file name :-)
    * @param backGnd The background onto which this country sprites will be drawn.
    */
  void flag(const QString& theFlagFileName, BackGnd *backGnd);
  
  /**
    * Test if this is a neighbour of country
    * @param country The country to test if this one communicate with.
    * @return true if @ref country communicate with this; false otherwise.
    */
  bool communicateWith(const Country *country) const;

  /**
    * Returns the continent this country is in.
    * @return The continent this country is in.
    */
  inline Continent* continent() {return m_continent;}
  
  /**
    * Sets the continent this country is in.
    */
  inline void setContinent(Continent* continent) {m_continent = continent;}
  
  /**
    * Change the owner of this to player and update the number of countries for 
    * previous and new owners.
    * @param player The new owner of this country.
    */
  void owner(Player *player);
  
  //@{
  /**
    * return a pointer to the Player owner of this country.
    */
  const Player* owner() const;
  Player* owner();
  //@}

  /**
    * Return the number of armies in this country
    */
  unsigned int nbArmies() const;

  /**
    * Change the number of armies to nb
    */
  void nbArmies(unsigned int nb);

  /**
    * Add nb armies. Defaults to 1.
    */
  void incrNbArmies(unsigned int nb=1);

  /**
    * Remove nb armies. Defaults to 1.
    */
  void decrNbArmies(unsigned int nb=1);

  /**
    * Return the name of the country
    */
  const QString name() const;

  /**
    * Return the localized name of the country
    */
  const QString i18name() const;

  const QPointF& anchorPoint() const;
  /**
    * Return a point inside the country territory around which are drawn the 
    * fighters.
    */
  const QPointF& centralPoint() const;

  /**
    * Return the point where the flag is displayed
    */
  const QPointF& pointFlag() const;

  /**
    * Return the point where the cannons are displayed
    */
  const QPointF& pointCannon() const;

  /**
    * Return the point where the cavalrymen are displayed
    */
  const QPointF& pointCavalry() const;

  /**
    * Return the point where the infantrymen are displayed
    */
  const QPointF& pointInfantry() const;

  /**
    * Set the anchor point.
    */
  void anchorPoint(const QPointF pt);

  /**
    * Set the point guaranteed to be inside this country territory and around 
    * which are drawn the fighters.
    */
  void centralPoint(const QPointF pt);

  /**
    * Set the point where the flag is displayed
    */
  void pointFlag(const QPointF pt);

  /**
    * Set the point where the cannons are displayed
    */
  void pointCannon(const QPointF pt);

  /**
    * Set the point where the cavalrymen are displayed
    */
  void pointCavalry(const QPointF pt);

  /**
    * Set the point where the infantrymen are displayed
    */
  void pointInfantry(const QPointF pt);

  /**
    * Return the list of cannon sprites
    */
  AnimSpritesList< CannonSprite >& spritesCannons();

  /**
    * Return the list of Cavalrymen sprites
    */
  AnimSpritesList< CavalrySprite >& spritesCavalry();

  /**
    * Return the list of Infantrymen sprites
    */
  AnimSpritesList< InfantrySprite >& spritesInfantry();

  /** Sets the list of neighbour countries. */
  void neighbours(const QList<Country*>& neighboursVect);

  //@{
  /** Returns the list of neighbour countries */
  QList< Country* >& neighbours();
  const QList< Country* >& neighbours() const;
  //@}
  void clearAllSprites();

  /** Returns the point for the given sprite, depending on its actual class */
  const QPointF& pointFor(const AnimSprite* sprite);

  /**
    * Saves a XML representation of the country for game saving purpose
    * @param xmlStream The stream to write on
    */
  void saveXml(QTextStream& xmlStream);

  /** 
    * Transmit data about this country on the network, through the given 
    * stream.
    */
  void send(QDataStream& stream);

  //@{
  /** Accessors to this country's unique integer identifier. */
/*  unsigned int id() const {return m_id;}
  unsigned int id() {return m_id;}
  void id(unsigned int id) {m_id = id;}*/
  //@}

  /**
    * Tests if there is at least one enemey adjacent to this country.
    * @return true if this country has an enemy neighbour and false otherwise.
    */
  bool hasAdjacentEnemy();

  void highlight(const QColor& color = Qt::white, qreal opacity = 1.0);

  void highlightAsAttacker();
  
  void highlightAsDefender();
  
  void clearHighlighting();

  bool isHighlightingLocked();
  void releaseHighlightingLock();

  /**
    * Copy information of the real country in a country of the arena.
    * @param trueCountry is the real country
    */
  void copyForArena(Country* trueCountry);

  private:
  GameAutomaton* m_automaton;
  
  /**
   * A pointer to the continent this country is in.
   */
  Continent* m_continent;
  
  /**
    * A pointer to the Player object that holds the country. 0 if it is not
    * affected.
    */
  Player* m_belongsTo;

  /**
    * A pointer to the sprite of the country's flag
    */
  FlagSprite* m_flag;

  /**
    * the number of armies held by the country (used to compute the number
    * of soldiers, horses and cannons
    */
  unsigned int  m_nbArmies;
  
  /**
    * The name of the country
    */
  QString m_name;

  /** the array of neigbours of this country */
  QList<Country*> m_neighbours;

  QPointF m_anchorPoint;

  /**
    * a point situated inside this country teritory such that any click on
    * this point (for example by an AI player) will be a click on this country
    */
  QPointF m_centralPoint;

  /**
    * the point of the upper left corner of the country's flag sprite
    */
  QPointF m_pointFlag;

  /**
    * the point of the upper left corner of the country's first cannon sprite
    * the subsequent cannons sprites are shifted by a fixed number of pixels
    */
  QPointF m_pointCannon;

  /**
    * the point of the upper left corner of the country's first cavalryman
    * sprite.The subsequent cavalrymen sprites are shifted by a fixed number
    * of pixels
    */
  QPointF m_pointCavalry;

  /**
    * the point of the upper left corner of the country's first soldier sprite
    * The subsequent soldier sprites are shifted by a fixed number of pixels
    */
  QPointF m_pointInfantry;

  /**
    * The list of the cannon sprites used to represent the armies of the
    * country
    */
  AnimSpritesList< CannonSprite > m_spritesCannons;

  /**
    * The list of the cavalrymen sprites used to represent the armies of the
    * country
    */
  AnimSpritesList< CavalrySprite > m_spritesCavalry;

  /**
    * The list of the soldiers sprites used to represent the armies of the
    * country
    */
  AnimSpritesList< InfantrySprite > m_spritesInfantry;

  QGraphicsSvgItem* m_highlighting;

  QSvgRenderer* m_renderer;

  bool m_highlighting_locked;

  QGraphicsSimpleTextItem* m_nbArmiesItem;
};

QDataStream& operator>>(QDataStream& stream, Country* country);
  
} // closing namespace GameLogic

} // closing namespace Ksirk

#endif // KSIRK_COUNTRY_H

