/*
 *                 GRAPH, Version 1.00 - 4 August 1989
 *
 *            Copyright 1989, David Gay. All Rights Reserved.
 *            This software is freely redistrubatable.
 */

/* Routines for handling graphs */
#ifndef GRPH_H
#define GRPH_H

#include "list.h"
#include "user/gadgets.h"

/* Various string lengths */
#define TITLELEN 80
#define GNAMELEN 20

/* Store information on each axis */
struct ax {
    double min, max;
    double ax, cstep; /* Axes positions, ax is the position of this axis on the
 other */
                      /* cstep: interval for ticks */
    int every;        /* Frequency of numbering on ticks */
    int log;          /* log scale ? */
};

/* Information on coordinate system */
struct axes {
    struct ax x, y;
    double ratio; /* y / x, NOVAL for none (>0 !!) */
    int polar : 1; /* Not used */
    int ok : 1;
};

/* User interface state */
struct state {
    int select_mode : 1;
    int mouse : 1;          /* mouse moves expected */
    double x, y;            /* mouse pos. */
    struct object *current;
};

/* All information needed for user interface */
struct io {
    UWORD nextmenu;            /* For menu selections */
    struct RWindow *rw;        /* Currently selected output */
    int dpmx, dpmy;            /* Scale (in dots per meter) of output */
    struct Window *win;        /* Window, and assoc. info */
    WORD oldwidth, oldheight;
    struct Gadget *gadgets;
    struct Menu *menu;
    struct Memory *mem;
    char title[TITLELEN];
    struct TextFont *digits;   /* Font for displaying digits on graph */
};

/* A graph, made up from the above components */

struct graph {
    node node;
    int ok : 1;
    int saved : 1;
    char name[GNAMELEN];
    struct io io;
    list o_list;  /* List of objects in graph */
    struct axes a;
    struct state s;
};

/* Open font name, in pts points (use graph scale). Takes nearest size */
struct TextFont *open_font(struct graph *g, char *name, int pts, int style, int
 flags);
/* Convert size in inches to dots in selected output */
int xinch2dots(struct graph *g, double x);
int yinch2dots(struct graph *g, double y);

/* objects */
struct object *add_object(struct graph *g, struct object *o);
void remove_object(struct graph *g, struct object *o);
void select_object(struct graph *g, struct object *o);
void deselect(struct graph *g);

/* User has used mouse, do any necessary housekeeping (move, select objects, et
c) */
void mouse_down(struct graph *g, WORD sx, WORD sy);
void mouse_move(struct graph *g, WORD sx, WORD sy);
void mouse_up(struct graph *g, WORD sx, WORD sy);

/* Ask user to : */
struct object *choose_object(struct graph *g, char *op); /* Select object by na
me */
void enter_limits(struct graph *g); /* Define coord system */
void enter_axes(struct graph *g);   /* Choose axes display options */

/* Change graph: */
int set_dpm(struct graph *g, int dpmx, int dpmy); /* set new scale (in dpm) */
void set_thin(struct graph *g, struct RastPort *rp); /* Use thin lines */
void set_pensize(struct graph *g, struct RastPort *rp, double ptsize); /* Use l
ines ptsize points wide */
void set_mode(struct graph *g, int newmode); /* Select select/point mode */
void set_scale(struct graph *g);      /* Window size has changed */
void zoom_in(struct graph *g, double x0, double y0, double x1, double y1); /* S
et new coord limits */
void zoom_factor(struct graph *g, double factor); /* Zoom in by a factor */
void center_graph(struct graph *g, double x, double y); /* Recenter around poin
t */

/* Output routines: */
void draw_graph(struct graph *g, int allow_mes); /* Draw graph */
void refresh_graph(struct graph *g, int allow_mes, struct Region *ref); /* Redr
aw inside region ref only */
struct Region *full_refresh(struct graph *g); /* Return a region covering the w
hole graph */
void set_title(struct graph *g);   /* Change graph title */
void prt_graph(struct graph *g);   /* Output graph to printer */
void iff_todisk(struct graph *g);  /* Output graph as an ILBM file */

/* Manipulate graphs : */
struct graph *load_graph(struct graph *from, FILE *f);
int save_graph(struct graph *g, FILE *f);
struct graph *new_graph(struct graph *from); /* from allows you to display mess
ages ... (NULL if none) */
void delete_graph(struct graph *g);

/* Global init/cleanup. Must be called */
int init_grph(void);
void cleanup_grph(void);

#endif

