/** \~russian .
 *
 ** \~english Represents map.
 *
 ** \~ @ingroup Server
 */

class Map
{
public:
	/** \~russian  . */
	const uint Id;

    /** \~russian    . */
    /** \~english Allows to check whether underlying object is valid. */
    const bool IsNotValid;

    /**
     * \~russian @name   
     * \~english @name Scripts and events
     * \~ @weight 300
     */
    //@{

    /**
     * \~russian       
     *               @a firstTime  @c true.
     *
     * @param   script   .
     *
     * @return  @c true    , @c false   .
     *
     * @remarks      ,      .
     */
    bool SetScript(string@+ script);

    /** \~russian  ID  ,    .
     *
     * @return ID  . 0,    .
     */
    uint GetScriptId();

    /** \~russian  -  .
     *
     * @param  eventType    (. @link MapEvents Map events@endlink).
     * @param  funcName    -.
     *
     */
    void SetEvent(int eventType, string& funcName);

    //@} // Scripts and events

    /**
     * \~russian @name   
     * \~english @name Invoking events
     * \~ @weight 295
     */
    //@{

    /** \~russian    #MAP_EVENT_FINISH. */
    /** \~english Invokes #MAP_EVENT_FINISH event. */
    void EventFinish(bool deleted);

    /** \~russian    #MAP_EVENT_LOOP_0. */
    /** \~english Invokes #MAP_EVENT_LOOP_0 event. */
    void EventLoop0();

    /** \~russian    #MAP_EVENT_LOOP_1. */
    /** \~english Invokes #MAP_EVENT_LOOP_1 event. */
    void EventLoop1();

    /** \~russian    #MAP_EVENT_LOOP_2. */
    /** \~english Invokes #MAP_EVENT_LOOP_2 event. */
    void EventLoop2();

    /** \~russian    #MAP_EVENT_LOOP_3. */
    /** \~english Invokes #MAP_EVENT_LOOP_3 event. */
    void EventLoop3();

    /** \~russian    #MAP_EVENT_LOOP_4. */
    /** \~english Invokes #MAP_EVENT_LOOP_4 event. */
    void EventLoop4();

    /** \~russian    #MAP_EVENT_IN_CRITTER. */
    /** \~english Invokes #MAP_EVENT_IN_CRITTER event. */
    void EventInCritter(Critter& cr);

    /** \~russian    #MAP_EVENT_OUT_CRITTER. */
    /** \~english Invokes #MAP_EVENT_OUT_CRITTER event. */
    void EventOutCritter(Critter& cr);

    /** \~russian    #MAP_EVENT_CRITTER_DEAD. */
    /** \~english Invokes #MAP_EVENT_CRITTER_DEAD event. */
    void EventCritterDead(Critter& cr, Critter@ killer);
	
	/** \~russian    #MAP_EVENT_TURN_BASED_BEGIN. */
    /** \~english Invokes #MAP_EVENT_TURN_BASED_BEGIN event. */
    void EventTurnBasedBegin();

	/** \~russian    #MAP_EVENT_TURN_BASED_END. */
    /** \~english Invokes #MAP_EVENT_TURN_BASED_END event. */
    void EventTurnBasedEnd();

	/** \~russian    #MAP_EVENT_TURN_BASED_PROCESS. */
    /** \~english Invokes #MAP_EVENT_TURN_BASED_PROCESS event. */
    void EventTurnBasedProcess(Critter& cr, bool beginTurn);

    //@} //   

    /**
     * \~russian @name 
     * \~english @name General
     * \~ @weight 200
     */
    //@{

    /** \~russian  ID  .
     *
     * @return ID  .    - 0.
     */
    uint16 GetProtoId();

    /** \~russian   ,    .
     *
     * @return   .
     */
    Location@+ GetLocation();

    /** \~russian      .
     *
     * @see SetTime
     */
    int GetTime();

    /** \~russian      .
     *
     *     @b MAPS.TXT,   
     *  @a map_time,   .
     *    ,      -1.
     *         , 
     *  >=0     ,   00.00,  .
     *
     * @param  time     ( ).
     *
     * @see    GetTime
     */
    void SetTime(int time);

    /** \~russian         .
     *
     * @param  index     (<code>0<=index<=63</code>).
     *
     * @see    SetData
     */
    int GetData(uint index);

    /** \~russian          .
     *
     *          63   
     *     .
     *
     * @param  index     (<code>0<=index<=63</code>).
     * @param  value   .
     *
     * @see    GetData
     */
    void SetData(uint index, int value);

    /** \~russian  ,        .
     *
     * @return  @c true,      .  @c false,  .
     *
     * @see    BeginTurnBased
     * @see    IsTurnBased
     * @see    SetTurnBasedAvailability
     */
    bool IsTurnBasedAvailability();

    /** \~russian           .
     *
     * @param value  .
     *
     * @see   BeginTurnBased
     * @see   IsTurnBased
     * @see   IsTurnBasedAvailability
     */
    void SetTurnBasedAvailability(bool value);

    /** \~russian     .
     *
     * @param  firstTurnCrit    ,   .
     *
     * @see    IsTurnBased
     * @see    IsTurnBasedAvailability
     * @see    SetTurnBasedAvailability
     */
    void BeginTurnBased(Critter@+ firstTurnCrit);

    /** \~russian  ,       .
     *
     * @return  @c true,      .  @c false,  .
     *
     * @see    BeginTurnBased
     * @see    IsTurnBasedAvailability
     * @see    SetTurnBasedAvailability
     */
    bool IsTurnBased();

    /** \~russian  .
     *
     * @return @c true    , @c false    .
     */
    bool Reload();

    /** \~russian    loop-.
     *
     *      5 (@c loop_0, @c loop_1, @c loop_2  ..).
     *
     * @param  loop   loop-.
     * @param  ms     
     *               ( ; 1  = 1000 .
     *
     * @see    MAP_EVENT_LOOP_0
     * @see    MAP_EVENT_LOOP_1
     * @see    MAP_EVENT_LOOP_2
     * @see    MAP_EVENT_LOOP_3
     * @see    MAP_EVENT_LOOP_4
     */
    void SetLoopTime(uint8 loop, uint16 ms);

    /** \~russian   . */
    /** \~english Returns map width. */
    uint16 GetWidth();

    /** \~russian   . */
    /** \~english Returns map height. */
    uint16 GetHeight();

    //@}

    /**
     * \~russian @name    
     * \~english @name Visual and audio effects
     * \~ @weight 190
     */
    //@{

    /** \~russian     (,  ).
     *
     * @param  protoId       ID   (. @b Effects   @b ITEMPID.H).
     * @param  hexX, hexY     ,     .
     * @param  effectRadius   .
     */
    void RunEffect(uint16 protoId, uint16 hexX, uint16 hexY, uint effectRadius);

    /** \~russian      (,   ).
     *
     *    .   @c null,
     *    .
     *
     * @param  protoId       ID   (. @b Effects   @b ITEMPID.H).
     * @param  fromCr        ,     .
     * @param  toCr          ,     .
     * @param  fromX, fromY   ,     .
     * @param  toX, toY       ,     .
     */
    void RunFlyEffect(uint16 protoId,
        Critter@+ fromCr, Critter@+ toCr,
        uint16 fromX, uint16 fromY, uint16 toX, uint16 toY);

    /** \~russian   .
     *
     * @return  .
     *
     * @see    SetRain
     */
    uint8 GetRain();

    /** \~russian / .
     *
     * @param  capacity   .
     *                      == 0,   ,   .
     *                      255.
     *
     * @see    GetRain
     */
    void SetRain(uint8 capacity);

    /** \~russian      .
     *
     *        ,      .
     *
     * @param  hexX, hexY   .
     * @param  color        .
     *                           
     *                     (. @b Other   @b _macros.fos).
     * @param  text         .
     */
    void SetText(uint16 hexX, uint16 hexY, uint color, string text);

    /** \~russian      .
     *
     *        ,      .
     *
     * @param  hexX, hexY   .
     * @param  color        .
     *                           
     *                     (. @b Other   @b _macros.fos).
     * @param  textMsg      MSG  (. @link MsgNums Msg nums@endlink).
     * @param  strNum       .
     *
     * @see    SetTextMsg(uint16, uint16, uint, uint16, uint, string&)
     */
    void SetTextMsg(uint16 hexX, uint16 hexY, uint color, uint16 textMsg, uint strNum);

    /** \~russian      .
     *
     * @param  hexX, hexY   .
     * @param  color        .
     *                           
     *                     (. @b Other   @b _macros.fos).
     * @param  textMsg      MSG  (. @link MsgNums Msg nums@endlink).
     * @param  strNum       .
     * @param  lexems        
     *                     (. <a href="http://fonline.ru/fowork/wiki/index.php/:   #@lex name@">  \@lex\@</a>,
     *                        ).
     *
     * @see    SetTextMsg(uint16, uint16, uint, uint16, uint)
     */
    void SetTextMsg(uint16 hexX, uint16 hexY, uint color, uint16 textMsg, uint strNum, string& lexems);

    /** \~russian     .
     *
     * @param soundName    .
     */
    void PlaySound(string& soundName);

    /** \~russian          .
     *
     * @param  soundName      .
     * @param  hexX, hexY   ,     .
     * @param  radius            ;
     *                       0,   ,      .
     */
    void PlaySound(string& soundName, uint16 hexX, uint16 hexY, uint radius);

    //@}

    /**
     * \~russian @name  
     * \~english @name For critters
     * \~ @weight 180
     */
    //@{

    /** \~russian    ,     .
     *
     * @param  hexX, hexY   ,    .
     *
     * @return     Critter.     @c null.
     */
    Critter@+ GetCritter(uint16 hexX, uint16 hexY);

    /** \~russian    ,   ID.
     *
     * @param  critterId   ID .
     *
     * @return     Critter.     @c null.
     */
    Critter@+ GetCritter(uint critterId);

    /** \~russian  ,    .
     *
     * @param   hexX, hexY   ,      .
     * @param   radius       ,  .
     * @param   findType      (. @link CritterFindTypes Critter find types@endlink).
     * @param   critters       ,   .
     *                             .
     *
     * @return    .
     *
     * @remarks      ,
     *            @a critters    @c null  .
     *
     * @remarks         .
     */
    uint GetCrittersHex(uint16 hexX, uint16 hexY, uint radius, int findType, Critter@[]@+ critters);

    /** \~russian         ,   .
     *
     * @param   fromHx, fromHy    .
     * @param   toHx, toHy        .
     * @param   angle             ,  .
     * @param   dist              .
     * @param   findType          (. @link CritterFindTypes Critter find types@endlink).
     * @param   critters           ,   .
     *                                 .
     *
     * @return    .
     *
     * @remarks      ,
     *            @a critters    @c null  .
     */
    uint GetCrittersPath(
        uint16 fromHx, uint16 fromHy,
        uint16 toHx, uint16 toHy,
        float angle, uint dist, int findType, Critter@[]@+ critters);

    /** \~russian         ,   .
     *
     * @param          fromHx, fromHy            .
     * @param          toHx, toHy                .
     * @param          angle                     ,  .
     * @param          dist                      .
     * @param          findType                  (. @link CritterFindTypes Critter find types@endlink).
     * @param          critters                   ,   .
     *                                                .
     * @param   [out]  preBlockHx, preBlockHy     .
     * @param   [out]  blockHx, blockHy          .
     *
     * @return    .
     *
     * @remarks   @a preBlock*  @a block*,     .
     *
     * @remarks      ,
     *            @a critters    @c null  .
     */
    uint GetCrittersPath(
        uint16 fromHx, uint16 fromHy,
        uint16 toHx, uint16 toHy,
        float angle, uint dist, int findType, Critter@[]@+ critters,
        uint16& preBlockHx, uint16& preBlockHy, uint16& blockHx, uint16& blockHy);

    /** \~russian     ,   .
     *
     * @param   pid        NPC (. @b _npc_pids.fos).
     *                     @a pid,  -1,  ,  -2 - NPC,  0 -   ( ,  NPC) (?).
     * @param   findType    (. @link CritterFindTypes Critter find types@endlink).
     * @param   critters     .        .
     *
     * @return    .
     *
     * @remarks      ,
     *            @a critters    @c null  .
     */
    uint GetCritters(uint16 pid, int findType, Critter@[]@+ critters);

    /** \~russian   ,    .
     *
     * @param   fromHx, fromHy     .
     * @param   toHx, toHy         .
     * @param   findType          (. @link CritterFindTypes Critter find types@endlink).
     * @param   critters           ,   .
     *                                 .
     *
     * @return    .
     *
     * @remarks     ,   ,
     *              ,      ,
     *             .
     */
    uint GetCrittersWhoViewPath(
        uint16 fromHx, uint16 fromHy, uint16 toHx, uint16 toHy,
        int findType, Critter@[]@+ critters);

    /** \~russian    ,           .
     *
     * @param   critters          .        .
     * @param   lookOnThem      ,  ,     (@c true) 
     *                          ,    (@c false).
     * @param   findType          (. @link CritterFindTypes Critter find types@endlink).
     * @param   crittersResult   ,      .
     *
     * @return    .
     *
     * @remarks    ,      ,
     *               .
     */
    uint GetCrittersSeeing(Critter@[]& critters, bool lookOnThem, int findType, Critter@[]@+ crittersResult);

    /** \~russian       .
     *
     * @param  protoId       NPC (.  @b _npc_pids.fos).
     * @param  hexX, hexY   .
     * @param  dir         .
     *
     * @return     Critter,   .
     *             @c null.
     */
    Critter@+ AddNpc(uint16 protoId, uint16 hexX, uint16 hexY, uint8 dir);

    /** \~russian   NPC  ,     #ST_NPC_ROLE.
     *
     * @param  npcRole    NPC.
     * @param  findType    (. @link CritterFindTypes Critter find types@endlink).
     *
     * @return  NPC  ,     #ST_NPC_ROLE.
     *
     * @see GetNpc
     */
    uint GetNpcCount(int npcRole, int findType);

    /** \~russian  NPC   .
     *
     * @param  npcRole     NPC.
     * @param  findType     (. @link CritterFindTypes Critter find types@endlink).
     * @param  skipCount   .    
     *                      ,      NPC   .
     *
     * @return     Critter,  NPC .
     *         @c null    .
     *
     * @see    GetNpcCount
     */
    Critter@+ GetNpc(int npcRole, int findType, uint skipCount);

    //@}

    /**
     * \~russian @name  
     * \~english @name For items
     * \~ @weight 170
     */
    //@{

    /** \~russian       .
     *
     * @param  hexX, hexY   .
     * @param  protoId ID    (.  @b ITEMPID.H).
     * @param  count        .
     *
     * @return     Item.     @c null.
     */
    Item@+ AddItem(uint16 hexX, uint16 hexY, uint16 protoId, uint count);

    /** \~russian     ,    .
     *
     * @param  itemId   ID .
     *
     * @return     Item.     @c null.
     */
    Item@+ GetItem(uint itemId);

    /** \~russian     ,    .
     *
     * @param  hexX, hexY   ,    .
     * @param  protoId     ID   (.  @b ITEMPID.H).
     *
     * @return     Item.     @c null.
     */
    Item@+ GetItem(uint16 hexX, uint16 hexY, uint16 protoId);

    /** \~russian   ,    .
     *
     * @param  hexX, hexY   ,    .
     * @param  items          ,      .
     *
     * @return   .
     */
    uint GetItems(uint16 hexX, uint16 hexY, Item@[]@+ items);

    /** \~russian         .
     *
     * @param  protoId  ID  (.  @b ITEMPID.H).
     * @param  items    ,        .
     *
     * @return   .
     */
    uint GetItems(uint16 protoId, Item@[]@+ items);

    /** \~russian       .
     *
     * @param  type     (. @link ItemsTypes Items types@endlink).
     * @param  items  ,       .
     *
     * @return       .
     */
    uint GetItemsByType(int type, Item@[]@+ items);

    /** \~russian     ,    .
     *
     * @warning ,      Item.
     *
     * @param   hexX, hexY   ,    .
     *
     * @return      Item.     @c null.
     */
    Item@+ GetDoor(uint16 hexX, uint16 hexY);

    /** \~russian    .
     *
     * @param  door    ,   .
     *
     * @return     - @c true.     @c false.
     *
     * @see    CloseDoor
     */
    bool OpenDoor(Item& door);

    /** \~russian    .
     *
     * @param  door    ,   .
     *
     * @return     - @c true.     @c false.
     *
     * @see    OpenDoor
     */
    bool CloseDoor(Item& door);

    /** \~russian     ,     .
     *
     * @param  hexX, hexY   ,    .
     *
     * @return     Item.     @c null.
     */
    Item@+ GetCar(uint16 hexX, uint16 hexY);

    //@}

    /**
     * \~russian @name  
     * \~english @name For hexagons
     * \~ @weight 160
     */
    //@{

    /** \~russian ,         .
     *
     * @param  hexX, hexY    .
     * @param  protoCar      .
     *
     * @return @c true       ;
     *         @c false     .
     */
    bool CheckPlaceForCar(uint16 hexX, uint16 hexY, uint16 protoCar);

    /** \~russian     .
     *
     *     .
     *
     * @param  entire    .     .
     *
     * @return        <code>EntireNum</code>.
     *
     * @see    GetEntireCoords
     */
    uint CountEntire(uint8 entire);

    /** \~russian     .
     *
     *             ,
     *    .
     *
     * @param  [in]   entire        .
     *                                .
     * @param  [in]   num             .
     * @param  [out]  hexX, hexY  ,      .
     *
     * @return @c true     ;
     *         @c false   .
     *
     * @see    CountEntire
     */
    bool GetEntireCoords(uint8 entire, uint8 num, uint16& hexX, uint16& hexY);
	
	/** \~russian    @ref GetEntireCoords,   (Dir) */
	bool GetEntireCoords(int entire, uint skip, uint16& hexX, uint16& hexY, uint8& dir);
	
	/** \~russian    .
	*
	* @param entire   ,  -1,        .
	*
	* @return @a true,   .
	*
	*/
	bool GetNearEntireCoords(int& entire, uint16& hexX, uint16& hexY);
	
	/** \~russian    @ref GetNearEntireCoords,   (Dir) */
	bool GetNearEntireCoords(int& entire, uint16& hexX, uint16& hexY, uint8& dir);

    /** \~russian    ,      .
     *
     *      , ,  
     *     .
     *
     * @param   [in]   fromHx, fromHy  C .
     * @param   [out]  toHx, toHy      ,      .
     * @param   [in]   angle              ( ).
     * @param   [in]   dist               .
     *
     * @remarks       (#IsHexRaked) ,
     *                  .
     *
     * @remarks  <code>(dist == 0)</code>      .
     */
    void GetHexCoord(uint16 fromHx, uint16  fromHy,
        uint16& toHx, uint16& toHy, float angle, uint dist);

    /** \~russian    ,      .
     *
     *      , ..   
     *        .
     *
     * @param  [in]   fromHx, fromHy  C .
     * @param  [out]  toHx, toHy      ,      .
     * @param  [in]   angle              ( ).
     * @param  [in]   dist               .
     *
     * @remarks      (#IsHexPassed) ,
     *                  .
     *
     * @see     GetHexCoord
     */
    void GetHexCoordWall(uint16 fromHx, uint16 fromHy,
        uint16& toHx, uint16& toHy, float angle, uint dist);

    /** \~russian ,     .
     *
     * @param  hexX, hexY   .
     *
     * @return @c true    ;
     *         @c false    .
     */
    bool IsHexPassed(uint16 hexX, uint16 hexY);

    /** \~russian ,   .
     *
     * @param  hexX, hexY   .
     *
     * @return @c true    ;
     *         @c false    .
     */
    bool IsHexRaked(uint16 hexX, uint16 hexY);

    /** \~russian     .
     *
     * @param  fromHx, fromHy    .
     * @param  toHx, toHy        .
     * @param  cut             ,        .
     *
     * @return    .   ,   0.
     */
    uint GetPathLength(uint16 fromHx, uint16 fromHy, uint16 toHx, uint16 toHy, uint cut);

    /** \~russian           .
     *
     * @param  cr              ,    .
     * @param  toHx, toHy        .
     * @param  cut             ,        .
     *
     * @return  .   ,   0.
     */
    uint GetPathLength(Critter& cr, uint16 toHx, uint16 toHy, uint cut);

    /** \~russian   @a hx, @a hy   @a dir  @a steps .
     *
     * ..      ,
     *         .
     *
     * @param   [out]  hexX, hexY   .
     * @param   [in]   dir          .
     * @param   [in]   steps         .
     *
     * @remarks         .
     */
    void MoveHexByDir(uint16& hexX, uint16& hexY, uint8 dir, uint steps);

    //@}

    /**
     * \~russian @name  
     * \~english @name For scenery
     * \~ @weight 180
     */
    //@{

    /** \~russian          .
     *
     * @param   hexX, hexY    ,     .
     * @param   protoId       .
     *
     * @return      Scenery.
     *          @c null          .
     *
     */
    Scenery@+ GetScenery(uint16 hexX, uint16 hexY, uint16 protoId);

    /** \~russian         .
     *
     * @param   hexX, hexY    .
     * @param   sceneries   ,         .
     *
     * @return        .
     *
     */
    uint GetSceneries(uint16 hexX, uint16 hexY, Scenery@[]@+ sceneries);

    /** \~russian           .
     *
     * @param   protoId      .
     * @param   sceneries  ,         .
     *
     * @return     .
     *
     */
    uint GetSceneries(uint16 protoId, Scenery@[]@+ sceneries);

    //@}
}
