#ifndef _EMPIRE_H
#define _EMPIRE_H
/*
 *                           E M P I R E . H
 *
 *  Header with the important definitons.
 *
 *  Version      : $Id: empire.h,v 1.11 1994/07/14 14:59:51 drepper Exp $
 *
 *  Created      : Thu May 19 19:14:33 1994
 *  Author       : Ulrich Drepper <drepper@mydec>
 *
 *  Last modified: Thu Jul 14 14:50:11 1994
 *  Author       : Ulrich Drepper <drepper@mydec>
 *
 *  This program 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */
#if !defined(__GNUC__) || __GNUC__<2 || (__GNUC__==2 && __GNUC_MINOR__<4)
# error You need at least GNU CC 2.4 for compiling
#endif

#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Xaw/Text.h>

#include "config.h"
#include "scheme.h"
#include "proto.h"

#define AUTHOR        "drepper@ira.uka.de"
#define DEFEMPHOST    "localhost"
#define DEFEMPPORT    "empire"
#define DEFSAVEFILE   ".myxec"
#define DATAFILEVAR   "MYXEC-DATA"
#define DEFDATAFILE   ".myxec-data"
#define SCHEMEFILEVAR "MYXEC-SCHEME"
#define DEFSCHEMEFILE ".myxec-scheme"

#define max(a,b)      ({typedef _at = (a); typedef _bt = (b); \
                        _at _a = (a); _bt _b = (b); \
		        _a > _b ? _a : _b; })
#define min(a,b)      ({typedef _at = (a); typedef _bt = (b); \
                        _at _a = (a); _bt _b = (b); \
		        _a < _b ? _a : _b; })
#define odd(x)        ((int)(x)&1)
#define even(x)       (((int)(x)&1)==0)

#define XNORM(x)      ({ int t = (x+empire.xMapSize/2)%empire.xMapSize; \
                         t >= 0 ? t : t+empire.xMapSize;})
#define YNORM(y)      ({ int t = (y+empire.yMapSize/2)%empire.yMapSize; \
                         t >= 0 ? t : t+empire.yMapSize;})
#define MAP2ARRX(x)   (XNORM(x)/2)
#define MAP2ARRY(y)   (YNORM(y))
#define MAP2ARR(x,y)  (MAP2ARRY(y)*empire.rowBytes+MAP2ARRX(x))

#define ARR2MAPX(x,y) ({ int tx = (2*(x)+empire.xMapSize/2+1) \
                                       %empire.xMapSize; \
                         int ty = (y); \
			 Bool oddRow=(odd(ty) && even(empire.yMapSize/2)) || \
                                     (even(ty) && odd(empire.yMapSize/2)); \
			 if (oddRow && even(tx)) { \
			     tx++; \
                         } else if (!oddRow && odd(tx)) { \
                             tx &= ~1; \
                         } \
                         tx; })
#define ARR2MAPY(x,y) ((y+empire.yMapSize/2)%empire.yMapSize)

#define HEXAPIXMAPWIDTH      34
#define HEXAPIXMAPHEIGHT     34
#define HEXATILEPIXMAPHEIGHT 26

#define CONNECTIONTIMEOUT    120000        /* 2 minutes */

#if __GNUC__==2 && __GNUC_MINOR__>=5
/* from GCC-2.5 on the seperator is '=' */
# define ILSEP =
#else
/* before we had no seperator */
# define ILSEP
#endif

/*
 * Type definitions
 */
enum {
    commIdxCiv,
    commIdxMil,
    commIdxUW,
    commIdxFood,
    commIdxShell,
    commIdxGun,
    commIdxPetrol,
    commIdxIron,
    commIdxDust,
    commIdxBars,
    commIdxOil,
    commIdxLcm,
    commIdxHcm,
    commIdxRad,
    commIdxLast
};
#define commIdxToChar(i) (commToCharArr[i])
#define charToCommIdx(c) (charToCommArr[(int)c])
#define charToProduct(c,s) ((s).product[charToCommIdx(c)])
#define charToPath(c,s) ((s).path[charToCommIdx(c)])
#define charToCutoff(c,s) ((s).cutoff[charToCommIdx(c)])
#define charToLevel(c,s) ((s).level[charToCommIdx(c)])

enum {
    resIdxMin,
    resIdxGold,
    resIdxOil,
    resIdxFert,
    resIdxUran,
    resIdxLast
};

/* definition for the world */
typedef enum { 
    OwnSector, 
    EnemySector, 
    NobodiesSector
} SectorStatus;

typedef struct _EmpireSector {
    char          typeChar;
    char          newTypeChar;
    u_char        eff;            /* efficience of sector */
    int           prodEff;        /* production efficiency (in precent) */
    int           cost;           /* production cost */
    char          prodComm[4];
    int           useProd[4];     /* plus will */
    int           maxProd[4];     /* plus total maximum */
    SectorStatus  status;
    Bool          stopped;
    Bool          occupied;
    int           mobility;
    Pixmap        typePixmap;
    int           work;
    int           avail;          /* not producing people */
    int           resource[resIdxLast];
    int           product[commIdxLast];
    char          path[commIdxLast];
    int           cutoff[commIdxLast];
    int           level[commIdxLast];
    int           dist_x;         /* coordinates of distribution center */
    int           dist_y;
} EmpireSector;

typedef struct _EmpireLand {
    /* global data defining the game; set in scanVersion */
    int           xMapSize;
    int           yMapSize;
    int           rowBytes;
    int           secPerEtu;
    int           etuPerUpdate;
    int           noFoodNeeded;
    int           sectMobMax;
    int           shipMobMax;
    int           planeMobMax;
    int           landMobMax;
    int           sectMobGain;
    int           shipMobGain;
    int           planeMobGain;
    int           landMobGain;
    double        bankPay;
    double        moneyCiv;
    double        moneyUw;
    double        moneyMil;
    double        moneyRes;
    double        nAggiGrow;
    double        civHarvest;
    double        civBirth;
    double        uwBirth;
    double        eatRate;
    double        babyRate;
    double        shipEffGain;
    double        planeEffGain;
    double        landEffGain;
    /* now follow variable values */
    Bool          isBroken;
    double        treasury;
    int           milReserve;
    double        education;
    double        happiness;
    double        technology;
    double        research;
    double        techFactor;
    double        plagueFactor;
    int           maxPop;
    int           savePopNom;
    int           savePopDenom;
    double        needHappy;
    EmpireSector *map;
} EmpireLand;

/* the different levels of warning and error messages */
typedef enum {
    NOERROR=0,
    WARN,
    ERROR,
    FATAL,
    WARNREP=128+WARN,
    ERRORREP=128+ERROR,
    FATALREP=128+FATAL,
} WarnLevel;

/* the pixmaps used for drawing the map */
typedef struct _XpmPixmap {
    char typeChar;
    Bool mayDesignate;
    char *name;
    char **data_normal;
    char **data_enemy;
    char **data_hilit;
    char **data_free;
    Pixmap pixmap_normal;
    Pixmap pixmap_enemy;
    Pixmap pixmap_hilit;
    Pixmap pixmap_free;
} XpmPixmap;

/* adding to the current text edit widget */
extern void (*currentEditAdd)(Bool, XawTextBlock *, Bool);

/*
 * definition of global variables
 */
/* main.c */
extern EmpireLand empire;
extern int restBTU;
extern int restMin;

/* connect.c */
extern Bool connected;                /* connected to server ? */
extern int  empSocket;                /* socket of connection  */

/* commands.c */
extern int charToCommArr[];
extern char commToCharArr[];

/* xinit.c */
extern Bool isMonoApp;
extern Bool xIsUp;
extern Scheme_Object *mapSelection;
extern XtAppContext appContext;
extern Widget messageText;
extern Widget topLevel;
extern Widget vertPane;
extern Widget showViewport;            /* viewport for text/map */
extern Widget mapWidget;
extern Widget editWidget;
extern Widget connIcon;
extern Widget breakCommandWidget;
extern Widget commandForm;
extern Widget horizPane;
extern Widget contentWidget;
extern Widget coordMenuLabel;
extern int actMenuCoordC;
extern int actMenuCoordR;
extern char messageStr[];
extern GC mapGC;
extern GC mapXorGC;
extern Pixmap iconConnected;
extern Pixmap iconNotConnected;
extern XpmPixmap hexaPixmap[];

/* translation.c */
extern Scheme_Env *globalSchemeEnv;

/* cmdqueue.c */
struct _CmdQueue;
extern struct _CmdQueue *cmdQueue;
extern long lastSerial;

/* timer.c */
extern XtIntervalId timerId;
extern XtInputId inputId;
extern unsigned long timerDelay;

/* xdraw.c */
extern Bool gotMap;     /* be sure a map to draw has already arrived */

/*
 * Prototypes for global functions
 */
/* libiberty/ */
#if defined(NEED_STRDUP)
char *strdup(/* char *s */);    /* it's dangerous to give arguments */
#endif

/* main.c */
void saveGameData(void);

/* message.c */
void message(WarnLevel level, const char *fmt, ...)
    __attribute__ ((format (printf, 2, 3)));

/* communications.c */
Bool getEmpLineD(int sock, ServerAnswer *answerCode, char **buf);
Bool expectAnswer(int sock, ServerAnswer answer);
Bool sendCmd(int sock, ServerCommand cmd, const char *str);
Bool sendCmdStr(Bool (*fct)(Bool, Bool, char *, void *), void *data,
		long *serialR, const char *fmt, ...)
    __attribute__ ((format (printf, 4, 5)));
Bool getLine(int sock, ServerAnswer *answerCode, char **buf);

/* connect.c */
Bool setConnectionData(const char *host, const char *port,
		       const char *usr, const char *ctry, const char *plyr);
Bool doConnect(void);
void closeConnection(void);

/* init.c */
void initialize(const char *initfile, const char *dataFile);

/* scanversion.c */
Bool scanVersion(void);

/* cmdqueue.c */
Bool enqueueCmd(long serial, Bool (*fct)(Bool, Bool, char *, void *), 
		void *data);
void feedCommand(ServerAnswer answerCode, char *buf);
void dequeueLastCmd(void);

/* commands.c */
Bool breakCommand(void);
Bool nationCommand(void);
Bool strToInt(char **str, int *i);
Bool strToFloat(char **str, float *f);
Bool strToCoord(char **str, int *x, int *y);
Bool strToRange(char **str, int *x1, int *y1, int *x2, int *y2);
Bool addDirToCoord(char **str, int *x, int *y);
char *charToSectorName(char typeChar);

/* xinit.c */
Bool xinit(int *pargc, char *argv[]);
Bool initXMap(void);
void lastXInit(void);
Pixmap getTypePixmap(int x, int y, SectorStatus status, Bool doHilit);
void showHexaData(int x, int y);

/* xdraw.c */
void exposeMap(Widget w, XtPointer ptr, XExposeEvent *ev, Boolean *cont);
void paintMap(Widget widget, XRectangle *rectangle, GC gc);
void paintHexa(Widget widget, int c, int r, Bool checked);
void buttonOnMap(Widget widget, XtPointer ptr, 
		 XEvent *ev, Boolean *cont);
void redisplaySectors(Widget widget, int x1, int y1, int x2, int y2);
void showMessageLine(void);

/* timer.c */
void inputReady(XtPointer closure, int *pfd, XtInputId *id);
void connectTimeOut(XtPointer data, XtIntervalId *_timer);

/* translation.c */
void registerActions(void);
void initScheme();
    
/* explore.c */
void queryCommandExplore(void);
Bool exploreCommand(char civOrMil, int number, int xStart, int yStart,
		    char *path);

/* designate.c */
void queryCommandDesignate(void);
Bool designateCommand(int x, int y, char typeChar);

/* move.c */
void queryCommandMove(void);
Bool moveCommand(char comm, int sx, int sy, int number, int ex, int ey);

/* census.c */
void queryCommandCensus(void);
Bool censusCommand(int xMin, int yMin, int xMax, int yMax, Bool redisplay);

/* map.c */
void queryCommandMap(void);
Bool mapCommand(int xMin, int yMin, int xMax, int yMax, Bool redisplay);

/* resource.c */
void queryCommandResource(void);
Bool resourceCommand(int xMin, int yMin, int xMax, int yMax, Bool redisplay);

/* commodity.c */
void queryCommandCommodity(void);
Bool commodityCommand(int xMin, int yMin, int xMax, int yMax, Bool redisplay);

/* produce.c */
void queryCommandProduce(void);
Bool produceCommand(int xMin, int yMin, int xMax, int yMax, Bool redisplay);

/* deliver.c */
void queryCommandDeliver(void);
Bool deliverCommand(char comm, int xl, int yu, int xr, int yl, char dir,
		    int thres, Bool ignDir);
    
/* all.c */
void queryCommandAll(void);
Bool allCommand(int xl, int yu, int xr, int yl);

/* level.c */
void queryCommandLevel(void);
Bool levelCommand(int xl, int yu, int xr, int yl);

/* dump.c */
void queryCommandDump(void);
Bool dumpCommand(int xMin, int yMin, int xMax, int yMax, Bool redisplay);

/* radar.c */
void queryCommandRadar(void);
Bool radarStationCommand(int xMin, int yMin, int xMax, int yMax,
			 Bool redisplay);
Bool radarShipCommand(int shipNr, Bool redisplay);
  
/*
 * Local Variables:
 *  mode:c
 *  c-indent-level:4
 *  c-continued-statement-offset:4
 *  c-continued-brace-offset:0
 *  c-brace-offset:0
 *  c-imaginary-offset:0
 *  c-argdecl-indent:4
 *  c-label-offset:-2
 * End:
 */
#endif /* _EMPIRE_H */
