/*
* $Log: $
* $Locker:  $
 */
#ifndef SP_H
#define SP_H

#include "gheap.h"

#define WATER 254
#define TARGET  0
#define BLOCKED 255
#define EMPTY   3
#define WATER_PENALTY  10
#define BLOCK1_PENALTY 1
#define BLOCK2_PENALTY 5

#define NORTH  1
#define WEST   2
#define EAST   4
#define SOUTH  8

#define DIR_MASK   15
#define BASE_MASK  0x7ffffff0
#define BASE_SHIFT 4
#define AMBUSH  1
#define COAST   2
#define DANGER  4
#define BASE_FL 8
#define MY_PACK 16
#define ROBOT   32
#define DEST_FL 64
#define DROP_FL 128

typedef struct sp_s
{
   unsigned char  *arr;
   unsigned char  *arr2;
   unsigned char  *info;
   unsigned short *popular;
   int      *heap_node;
   int      *pred;
   int      *base;
   int       width;
   gheap_t   heap;
   int       size;
}sp_s;

typedef sp_s *sp_t;

/** Create a new sp
    w : width,
    h : height
    rows: wightings of the nodes, 255=blocked
*/
void sp_init(sp_t sp,
             int  w,
             int  h,
             char *rows);

/** Free the mem allocated for the map. */
void sp_free(sp_t sp);

/** Unmark as target */
void sp_unmark_target(sp_t sp,int pos);


/** Mark target. */
void sp_mark_target(sp_t sp,int pos);

int sp_get_weight(sp_t sp,int pos);

void sp_set_weight(sp_t sp,int pos,int h);

/* Search function:
   returns the weighted shortest distance to some of the targets.
   drom the given point (x,y).

   The narest target is written into (*fx,*fy).
   The unwighted distance is stored into in steps.
*/

int sp_shortest_path(sp_t sp,int pos,int *fpos,int *steps,int use_other);

/** Search function (unweighted search)... */
int sp_shortest_path2(sp_t sp,int pos,int *fpos,int use_other);

/** Returns nonzero if the target is reached,zero otherwise.
    Takes the last point(*x,*y) of the shortest path, and
    replaces it with the next one.
*/
int sp_next(sp_t sp,int pos);

void sp_block_unreachable(sp_t sp,int pos,char *orig,char block_c);

void sp_bases_update(sp_t sp);

void sp_reweight(sp_t sp,
                 int  coast_penalty,
                 int  block1_penalty,
                 int  block2_penalty,
                 int  danger_penalty);

int sp_set_target(sp_t sp,int pos);

void sp_mark_targets(sp_t sp);

void sp_cleanup_targeted(sp_t sp);

#endif
