/*
   File:            amgr.h
   Author:          Andrew Moore
   Created:         7th Feb 1990

   Description:     Standard andrew header file for graphics
*/

#ifndef AMGR_H
#define AMGR_H

#include "amut.h"
#include "amxw.h"

/* #ifndef PC_TTY_PLATFORM */

/*
   Example of use:

    All coordinates are in doubles (x,y) with origin at bottom left.
    The screen covers (0,0) to (512,512)

  {
    double x,y;
    int button;

    ag_on("plop.ps"); Will open a 512x512 pixel x-window, and also save
                      results to a postscript file called plop.ps.
                      If you don't want anything saved to a file, call
                      ag_on("");

    ag_circle(256.0,256.0,128.0);  Draws a circle centered on the center
                                   of the window, radius quarter window width.

    ag_print(10.0,10.0,"hi"); printed at bottom left

    button = ag_get_xy(&x,&y);  Waits for the user to click button on window.

    printf("You clicked %s button\n",(button==1)?"left":(button==2)?"middle":
                                     "right"
          );
    ag_dot(x,y);  Draws dot where user clicked button

    ag_off();     The drawing is now saved in the postscript file
  }
*/

#ifdef PC_MVIS_PLATFORM
#ifdef FIGS_FOR_PAPER
#define AG_CHAR_HEIGHT 36.0
#define AG_CHAR_WIDTH 20.0
#else
extern double CharHeight, CharWidth;
#define AG_CHAR_HEIGHT CharHeight
#define AG_CHAR_WIDTH  CharWidth
#endif
#else
#define AG_CHAR_HEIGHT 16.0
#define AG_CHAR_WIDTH  7.0
#endif

void ag_on(const char *fname);

void ag_on_robust(char *fname);

/*Under Windows, this function will update the graphics window.  
  Under other operating systems, it will do nothing.
  This is needed because under Windows, any graphics commands that are 
  issued will not be seen until a call to ag_off() or ag_show().*/
void ag_show(void);

void ag_dot(double x, double y);

/* Draw a tiny dot (one pixel in size on ag_ window, 1/512th of width
   of entire drawing area in postscript) */
void ag_pixel(double x, double y);

void ag_line(double u, double v, double x, double y);

void ag_circle(double x, double y, double r);

void ag_box(double x, double y, double u, double v);

void ag_disc(double x, double y, double r);

/* This function is like ag_print except it ignores the current
   scale factor. Thus if you call with x = 10.0, y = 490.0 you are
   guaranteed to draw in the top left of the window no matter what
   scale factor is currently in use. */
void ag_print_absolute_coords(double x, double y, char *s);

void ag_print(double x, double y, char *s);

void ag_pen(double c);

int ag_get_line_width(void);
void ag_set_line_width(int line_width);

/* Declared but not defined - sir /9/6/2000 
void ag_boxed_print(double x, double y, double u, double v, char *s); */

/* Waits for the user to click in the graphics window. 
   Stores the coordinates of where the user clicked in
   (*xptr,*yptr).
   
    Returns 1 if the user clicked the left button
    Returns 3 if right button
    Returns 2 if middle button, but I guess that doesn't
       happen under NT */
int ag_get_xy(double *x_ptr, double *y_ptr);

/*Does the same as ag_get_xy(), but prompts the user*/
int ag_get_xy_prompted(char *prompt,double *x_ptr, double *y_ptr);

void ag_off(void);

void ag_cross(double x, double y);

/* Declared but not defined - sir /9/6/2000 
void ag_polystart(void);
void ag_polypoint(double x, double y);
void ag_polyfill(void);
void ag_polyedge(void); */

void ag_arrow(double x, double y, double u, double v);

void ag_nice_arrow( double x, double y, double u, double v, double l);

void ag_triangle( double x, double y, double a, double h, double sina, double cosa );

void ag_rectangle(double x, double y, double u, double v);

void ag_clipped_dot(double x, double y);

void ag_clipped_line(double p, double q, double u, double v);

/* Declared but not defined - sir /9/6/2000 
void ag_char_point(double x, double y, char c);
void ag_char_square(double x, double y, char c); */

void ag_uparrow(double x, double y);

void ag_downarrow(double x, double y);

void ag_rounded_box(double x, double y, double u, double v, double r);

void click_on_message(double xlo, double ylo, double xhi, double yhi, char *m);

void wait_for_click(void);

/* Declared but not defined - sir /9/6/2000 
void ag_lock(void);
void ag_unlock(void); */

/* By default, graphics, postscript and apicts are created using a 
   coordinate system in which bottom left is at (0,0) and top
   right is (512,512). This allows you to change the bottom left
   and top right. */
void set_ag_frame(double xlo,double ylo,double xhi,double yhi);

/* Change the physical size of the window on the screen. The coordinate
   system stretches so that something that would previously have appeared
   in the top right corner still appears in the top right corner. (and
   ditto for bottom left) */
void ag_window_shape(int width_in_pixels,int height_in_pixels);


/* Causes the ag_ window to disappear. It can still reapper if
   ag_on("") is called again */
void ag_disappear(void);

void ag_circle_transformed_radius(double x, double y, double r);

/* Foreground and background colors */
extern int AG_DISPLAY;
extern int AG_BKGD;
extern int AG_HIGHLIGHT;
extern int AG_HYPERLINK;

/* declarations added by Mary on 2 July 95; part of amxw color code */

void ag_set_pen_color(int amut_col);

/* ag_set_pen_rgb added by WKW */
void ag_set_pen_rgb(double r, double g, double b);
int ag_pen_color(void);
int ag_spectrum_color(double fract);
void ag_rgb(int ag_color, double *r_r, double *r_g, double *r_b);

void ag_print_vertical(double x,double y,char *string);

/* Draws a line segment in the ag graphics window consisting of
   that set of points { (x,y) | ( (x,y) - (px,py) ) . (dx,dy) == 0 }.

   This is a line perpendicular to (dx,dy) that travels through the point
   (px,py). 

   The function is clever about clipping.
*/
void ag_cut(double px,double py,double dx,double dy);


/* If you are working in an application that is driven by dispatch_xxx( )
   type functions, it is often worth using special_ag_on instead of ag_on. 
   This is because when the comment on sessionname is invoked by the
   user, all graphs will automatically be saved in auto-named .ps files
   and linked within a latex document into a session log. It is harmless
   to use this instead of ag_on if you're not sure. */
void special_ag_on(char *filename);

void ag_cross(double x, double y);
void ag_smallbox(double x, double y);
void ag_smalltriangle(double x, double y);
void ag_smallcircle(double x, double y);

#define DOT_MARKTYPE 0
#define CROSS_MARKTYPE 1
#define SMALLBOX_MARKTYPE 2
#define SMALLTRIANGLE_MARKTYPE 3
#define SMALLCIRCLE_MARKTYPE 4
#define PIXEL_MARKTYPE 5
#define FANCY_MARKTYPE 6
#define BIG_CROSS_MARKTYPE 7
#define DISC_MARKTYPE 8
#define SMALLPLUS_MARKTYPE 9
#define NUM_MARKTYPES 10

void ag_mark(double x,double y,int marktype);

void ag_set_gradient_2(int from,int to,double fr,double fg,double fb,double tr,double tg,double tb);
ivec *mk_ag_gradient_2(int numcolors,double fr,double fg,double fb,double tr,double tg,double tb);
void ag_set_gradient_1(int from,int to,double f,double t,double r,double g,double b);
ivec *mk_ag_gradient_1(int numcolors,double f,double t,double r,double g,double b);

void rgb_from_ag_gradient_2(double width,double fr,double fg,double fb,double tr,double tg,double tb,
                            double i,double *r,double *g,double *b);
void rgb_from_ag_gradient_1(double width,double f,double t,double r,double g,double b,
                            double i,double *rr,double *gg,double *bb);

void ag_cross(double x, double y);
void ag_smallbox(double x, double y);
void ag_smalltriangle(double x, double y);
void ag_smallcircle(double x, double y);

void ag_mark(double x,double y,int marktype);

/* GJG: added the ability to choose how ag_colors show up in saved PostScript
   files.  Default is as before, different ag_colors show up as actual colors
   in the PostScript file.  But, on a grayscale device, it's hard to tell the
   difference between different colors.  So, two options: colors get mapped to
   different gray levels (this option was there already, but I changed the
   mapping so that colors with adjacent indices were no longer similar), or
   colors get mapped to different patterns (e.g., solid or crosshatched or with
   diagonal lines). The following three functions switch between these
   behaviors in the obvious way.

   IMPORTANT: the call to ps_usepats must come before the call to ag_on,
   since ps_prologue decides whether to emit the pattern definitions based
   on the value of PS_MONO. */

void ps_usegray(void);
void ps_usepats(void);
void ps_usecolor(void);



/* The following group of functions are all concerned with creating
   color keys from distributions of scores (or "heights" in a plot)
*/

/* If the input is of size n then the output is also of size n.

   result[i] = x such that x is a value in scores and exactly
   fraction percentiles[i] of scores are below x. 

   Warning, despite its name, the i'th element of percentiles is expected
   to be a fraction between 0 and 1.

   percentiles should be sorted, no duplicates, and increasing */
dyv *mk_threshes_from_scores(dyv *scores,dyv *percentiles);

/* If threshes has been computed from the above function then this
   function says what color the j'th datapoint should be colored.

   Assume scores is of length R, threshes is of length N. Then 
   thresh_colors must be of length N+1.

   The result will be of length R.

   If scores[i] is below threshes[0], the i'th point will be colored
        thresh_colors[0]

   If threshes[j] <= scores[i] < threshes[j+1] the ith point will be
        colored thresh_colors[j+1]
*/
ivec *mk_colors_from_threshes(dyv *scores,dyv *threshes,ivec *thresh_colors);

/* Automatically creates a color for each datapoint, designed so that
   at various critical percentiles the colors are different. Prints to
   stdout the color key. If you want more information about the key and
   more control you should use the above component functions instead. */
/* If score_name is NULL it is ignored.

   If non-null, prints a "key" to stdout, stating which color threshold
   corresponds to which score, etc. The score_name is used as the
   variable name in the key */
ivec *mk_colors_from_scores(dyv *scores,char *score_name);

/* Gives a string describing the given color */
char *ag_color_to_name(int agcol);

/* Prints a color/percentiles/scores key to stdout */
void explain_score_colors(dyv *percentiles,dyv *threshes,ivec *thresh_colors,
			  char *score_name,double min_score,double max_score);

void ag_print_int(double x,double y,int number);
void ag_print_double(double x,double y,double number);

void ag_shape_from_args(int argc,char *argv[]);

#endif /* #ifndef AMGR_H */

