/********************************************************/
/*     Header file for !SkyView and its modules.        */
/*                    Version 0.1                       */
/*                (c)1992 N P Hawkes                    */
/********************************************************/

#define REAL float      /* Type for floating point calcs*/
#define MAXINFO 256     /* Length of arrays holding info*/
#define INFOBOX_LINES 5 /* No. of text lines in info box*/
#define NOWHERE -1      /* Dummy window id for objects  */
                        /* not on view.  Not equal to   */
                        /* any valid id number.         */
#define NO_ONE -1       /* Dummy module number, not     */
                        /* equal to any valid number.   */

#define ZERO (REAL)0.0
#define DblPI  3.14159265
#define PI   (REAL)DblPI
#define DblTWO_PI (2.0*DblPI)
#define TWO_PI ((REAL)2.0*PI)
#define PIby2  (PI/(REAL)2.0)
#define DblCONV (DblPI/180.0) /* Convert degs to rads.  */
#define CONV (PI/(REAL)180.0)

#define SID_TO_SOL ((REAL)0.997270)  /* Convert from    */
                                     /* siderial to     */
                                     /* solar units.    */

#define NO_HITS    0          /* For Sub-Menus.         */

#define FATAL      1          /* For error reporting,   */
#define NON_FATAL  0          /* using 'werr'.          */

/* Macro to detect leap years:                          */
#define leap(y) ((y)%4 == 0 && (y)%100 != 0 || (y)%400 == 0)

/*------------------------------------------------------*/
/*            Structure for Observer Details            */
/*------------------------------------------------------*/

typedef struct {
  int  lat10;    /* Latitude * 10, in degrees.          */
  BOOL isn;      /* TRUE for N, FALSE for S.            */
  REAL latit;    /* Latitude in radians. North positive.*/
  int  long10;   /* Longitude * 10, in degrees.         */
  BOOL isw;      /* TRUE for W, FALSE for E.            */
  REAL longit;   /* Longitude in radians. West positive.*/
  int  day;      /* Day of the month.                   */
  int  month;    /* Month of the year.                  */
  int  year;     /* Year.                               */
  int  hour;     /* Hour (24 hour clock).               */
  int  min;      /* Minutes past hour.                  */
  float offset;  /* Hours by which Time is ahead of GMT.*/
  double jul;    /* Days since 12:00 on 00/01/1900      */
  REAL sid;      /* Local siderial time (radians).      */
  int  dir;      /* Int code giving direction of view   */
  REAL ang;      /* Angle in radians implied by 'dir'   */
} observerstr;

/*------------------------------------------------------*/
/*   Structure setting out details of when and where    */
/*        a newly-selected object can be viewed.        */
/*------------------------------------------------------*/

typedef struct {
  int id;               /* ID by which object is known  */
                        /* to parent module.            */
  BOOL selected_OK;     /* TRUE on successful selection */
                        /* of a new object.             */
  int horiz_id;         /* ID by which object is known  */
                        /* in Horiz window. =NOWHERE if */
                        /* not currently in window.     */
  int vert_id;          /* ID by which object is known  */
                        /* in Vert window.  =NOWHERE if */
                        /* not currently in window.     */

  BOOL now;             /* TRUE if object is currently  */
                        /* visible.                     */

  BOOL rising;          /* TRUE if object rises during  */
                        /* the current day.             */
  REAL rise_azim;       /* Azimuth for rising, if any.  */
  int  rise_hour;       /* Hour of rise, if any.        */
  int  rise_min;        /* Minute of rise, if any.      */

  BOOL setting;         /* TRUE if object sets during   */
                        /* the current day.             */
  REAL set_azim;        /* Azimuth for setting, if any. */
  int  set_hour;        /* Hour of setting, if any.     */
  int  set_min;         /* Minute of setting, if any.   */

  BOOL culminating;     /* TRUE if object culminates    */
                        /* during the current day.      */
  REAL cul_alt;         /* Altitude of culmin., if any. */
  REAL cul_azim;        /* Azimuth of culmin., if any.  */
  int  cul_hour;        /* Hour of culmination, if any. */
  int  cul_min;         /* Minute of culmination, if any*/
} selectstr;

/*------------------------------------------------------*/
/*          Variables common to all modules.            */
/*------------------------------------------------------*/

extern char app_dir[];        /* For SkyView$Dir        */
extern char *infoptr;         /* Place to write info.   */
extern observerstr ob_data;   /* Observer details.      */
extern selectstr   selection; /* Details of slected obj.*/
extern char *module_submenu_hits; /* List of hits on    */
                                  /* module submenus.   */
extern BOOL dbox_persisting;  /* Flag causing Select or */
                              /* Disp fns to be called  */
                              /* repeatedly. Used when  */
                              /* a dbox is persisting.  */
extern BOOL rebuild_request;  /* Flag allowing a Disp fn*/
                              /* to request rebuilding  */
                              /* of plotting lists.     */

/*------------------------------------------------------*/
/*         Reason codes for Select function.            */
/*------------------------------------------------------*/
typedef enum {
  new_selection,        /* Try to make a new selection  */
                        /* by dialogue with the user.   */
  window_selection,     /* Select the object which has  */
                        /* just been clicked on.        */
  recalculate_data,     /* Recalc details of when and   */
                        /* where selected obj can be    */
                        /* seen, following change of    */ 
                        /* observer data.               */
  timeonly_recalculate, /* As above, but only time of   */
                        /* day has changed.             */
  sel_info_request      /* Provide info on selected obj.*/
} selectfn_reasoncode;


/*------------------------------------------------------*/
/*       Function types for module functions.           */
/*------------------------------------------------------*/

/* A list-building function takes no arguments, and     */
/* returns void.                                        */
typedef void buildfntype(void);

/* An object-selecting function takes a                 */
/* selectfn_reasoncode as argument, and returns void.   */
typedef void selectfntype(selectfn_reasoncode reason);

/* A display function (for setting display options)     */
/* takes a pointer to BOOL as argument, and returns     */
/* a BOOL.                                              */
typedef BOOL displayfntype(BOOL *enabptr);

/* A plotting function takes (x,y) coords and an object */
/* ID as arguments, and returns a pointer to an os_error*/
typedef os_error *plotfntype(int x, int y, int id);

/* An Info function takes an object ID as argument,     */
/* and returns void.                                    */
typedef void infofntype(int id);

/*------------------------------------------------------*/
/*    Structure containing details about a module.      */
/*------------------------------------------------------*/

typedef struct {
  buildfntype *buildfn;   /*Ptr to fn for List Building.*/
  selectfntype *selectfn; /*Ptr to fn for Obj Selecting.*/
  displayfntype *dispfn;  /*Ptr to Disp Option function.*/
  infofntype *infofn;     /*Ptr to Info function.       */
  char *display_entry;    /*Entry in Display sub-menu.  */
  BOOL initial;           /*TRUE if initially enabled.  */
  menu  display_menu;     /*Display sub-sub-menu.       */
  char *select_entry;     /*Entry in Select sub-menu.   */
  menu  select_menu;      /*Select sub-sub-menu.        */
} modulestr;

/*------------------------------------------------------*/
/* Structure describing a single object to be plotted.  */
/*------------------------------------------------------*/

typedef struct {
  wimp_box bounds;      /* Bounding box.                */
  int wind_x;           /* x coordinate.                */
  int wind_y;           /* y coordinate.                */
  int module;           /* id no. of parent module.     */
  int id;               /* id by which object is known  */
                        /* to parent module.            */
  plotfntype *plotfn;   /* Pointer to plotting function.*/
  REAL alt;             /* Altitude of object.          */
  REAL azim;            /* Azimuth of object.           */
  wimp_box size;        /* Bounding box, relative coords*/
  int next;             /* Pointer to next object.      */
} plotobj;


/*------------------------------------------------------*/
/* Define a function type for initialising modules.     */
/*------------------------------------------------------*/

/* An initialisation function takes an int and a pointer*/
/* to a modulestr as arguments, and returns a BOOL.     */
typedef BOOL initfntype(int module_id, modulestr *);


/*------------------------------------------------------*/
/*   Prototype of function for adding a new object to   */
/*                 the plotting list.                   */
/*------------------------------------------------------*/

void addobj(plotobj new_object, int *horiz_id, int *vert_id);


/*------------------------------------------------------*/
/*   Functions & definitions for graphics operations.   */
/*------------------------------------------------------*/

os_error *sv_setcolour(int colour); /* Set graphics col.*/

#define MODE_20 TRUE
#define MODE_12 FALSE

os_error *sv_plotsprite(
  sprite_id *id,        /* ID of sprite.                */
  BOOL spritemode,      /* TRUE if a mode 20 sprite,    */
                        /* FALSE if a mode 12 sprite.   */
  int x, int y,         /* Screen coords at which Key   */
                        /* Pixel is to appear.          */
  int col, int row);    /* Position of Key Pixel, in    */
                        /* pixels relative to bottom    */
                        /* left of sprite definition.   */
