
/*
   File:          ongr.h
   Author:        Andrew W. Moore
   Created:       August 19th 1992

   Description:   Some simple graph-drawing
*/

#ifndef ONGR_H
#define ONGR_H

#include "ambs.h" /* Header file for a set of basic convenience routines */
#include "amgr.h" /* Header file for Simple X and PostScript graphcs */
#include "amar.h" /* Simple array handling */
#include "amut.h"
#include "agbox.h"
#include "awdut.h"

/* This API includes functions for...

      Manipulating color_strings

      Manipulating "map"s, which are transformations from an arbitrary
      rectangle in a 2-d space into ag_graphic coordinates.

      Rendering whole scatterplots, histograms and all their
      components */

/* The size of a "large" dot when rendered during a plot routine */
#define DOT_RADIUS 4.0

/* The assumed maximum number of characters in the marking of 
   a "tick" along an axis */
#define CH_IN_NUM 6

/* Returns an ag_color associated with code. code can be as large as
   you like but after about 12, it wraps around. Use this if you want, say,
   different bars in a chart to have different colors. You simply use
   color_code_to_ag_color(i); as the color of the i'th bar. */
int color_code_to_ag_color(int color_code);

/* A color_string is an array of chars in which each char has an
   assigned ag_color */

/* NOTE: see amgr.h and/or amxw.h for color definitions. They include
   AG_GREEN, AG_BLUE etc */
typedef struct color_string
{
  char *string;
  ivec *colors;
} color_string;

int string_length(char *s);

/* MAKES and returns the color string "" */
color_string *mk_empty_color_string(void);

/* cst := "<cst><s>" where the characters in s are
   colored with "color" */
void append_to_color_string(color_string *cst,char *s,int color);

/* Number of chars in string */
int color_string_length(color_string *cst);

int string_length(char *s);

/* The i'th character */
char color_string_char_ref(color_string *cst,int i);

/* The color of the i'th character */
int color_string_color_ref(color_string *cst,int i);

/* Renders the color_string */
void ag_print_color_string(double x,double y,color_string *cst);

/* Just like print_and_shrink (in agbox.h) except does it
   for a color_string. The height of agb is reduced accordingly */
void print_and_shrink_color_string(agbox *agb,color_string *cst);

void free_color_string(color_string *cst);

/* Very useful function if you want to list a color key where
   the i'th key is to be associated with the i'th color code
   (see int color_code_to_ag_color(int color_code) above).

   Reduces agb by as much as is necessary to draw the color keys.
   If there are stupicly many color keys behaves sensibly and NEVER
   ends up eating more than the top third of agb */
void print_color_key_and_shrink(agbox *agb,string_array *labels);
void print_color_key_and_shrink_special_colors(agbox *agb,string_array *labels,ivec *colors);

/* A map represents the transformations needed while rendering
   a lingraph, rsgraph or ssgraph. It has three components: 

     outer (in ag_coords) gives the drawing coordinates of the
     extent of the region the graph'll be drawn in, including all
     the space for axes and labels etc. (But NOT including color_key
     space....that's a mistake on the part of the programmer) 

     inner (in ag_coords) gives the drawing coords of the inner
     regions that we're drawing scatterplots etc in */
typedef struct map
{
  agbox *inner;
  agbox *outer;
  agbox *image;
} map;

agbox *map_image_box(map *mp);
agbox *map_inner_box(map *mp);
agbox *map_outer_box(map *mp);

/* All the following are in image (i.e. scatterplot
   coords) coords (not ag_coords) */
double map_ylo(map *mp);
double map_xlo(map *mp);
double map_yhi(map *mp);
double map_xhi(map *mp);
double map_width(map *mp,int comp);
double map_ref(map *mp,int comp,int hilo);

/* Alters the scatterplot coords of the map. inner and 
   outer are unchanged */
void map_image_set(map *mp,int comp,int hilo,double v);

/* Inner operations */
double map_inner_ref(map *mp,int comp,int hilo);
double map_inner_width(map *mp,int comp);

/* Outer operations */
double map_outer_ref(map *mp,int comp,int hilo);
double map_outer_width(map *mp,int comp);

map *mk_map(agbox *inner,agbox *outer,agbox *image);
void free_map(map *mp);

/* The following two functions make a map and automatically deduce
   a good "inner" agbox */
map *mk_map_from_frame_and_image(agbox *ag_frame,agbox *image_frame);
map *mk_map_from_frame_and_limits(agbox *ag_frame,double xlo,double ylo,double xhi,double yhi);

/* Transforms an image coord to an ag coord.
   component should be XCOORD or YCOORD */
double map_i2a(map *mp,double v,int component);
double map_i2a_x(map *mp,double x);
double map_i2a_y(map *mp,double y);

/* Draws a line. Args in image coords */
void ongr_line(map *mp,double x1,double y1,double x2,double y2);

/* All the following take args in image coords */
void ongr_print(map *mp,double x,double y,char *string);
void ongr_box(map *mp,double x1,double y1,double x2,double y2);
void ongr_rectangle(map *mp,double x1,double y1,double x2,double y2);

/* marktypes (e.g. DOT_MARKTYPE) defined in amgr.h */
void ongr_mark(map *mp,double x,double y,int marktype);

/* Draws a real-valued axis. Figures out (and draws) appropriate
   places and values for the "ticks" along the axis */
void draw_map_real_axis(map *mp,int comp);

/* Draws a histogram axis that is to be made up of bars
   where the i'th bar is called labels[i] */
void draw_map_hist_axis(map *mp,int comp,string_array *labels);

/* Draws the label for the XCOMP or YCOMP axis */
void draw_map_label(map *mp,int comp,char *label);

/* As above except does nothing if label is NULL */
void maybe_draw_map_label(map *mp,int comp,char *label);

/* Draws both the axes, treating them both as real valued */
void draw_map_real_axes(map *mp);

/* marktype can be -1 meaning "just join...no special marks" */
/* Draws the (x,y) points.

   Draws lines between them if join is TRUE

   Uses the requested marktype.

   Uses color "amut_col" */
void plot_graphic_in_frame(map *mp,dyv *x,dyv *y,bool join,int marktype,int amut_col);

/* Returns an ag_color associated with code. code can be as large as
   you like but after about 12, it wraps around. Use this if you want, say,
   different bars in a chart to have different colors. You simply use
   color_code_to_ag_color(i); as the color of the i'th bar. */
int color_code_to_ag_color(int color_code);

/* Draws a rectangle in the given color. All image coords */
void ongr_framed_box(map *mp,double x1,double y1,double x2,double y2,int col);

/* Draws a histogram with N bars where N = dym_rows(freqs);
   Each bar is compartmented into K subbars, on top of each other, where
   K = dym_cols(freqs); and the j'th subcomponent of the i'th bar has
   height = dym_ref(freqs,i,j); and is on top of the j-1'th subcomponent. 
   The i'th bar is centered on x=xlo + (i+0.5); * (xhi - xlo); / num_bars */
void ongr_plot_hist(map *mp,dym *freqs,bool ratio);

/* ARTUR: Draws the grid described in imat (just like a
          bitmap). It's like a quilt of little squares scaled
          so that the (i,j)'th square has color im[i][j] */
void ongr_render_imat(map *mp,imat *im,dyv *xtics, dyv *ytics);

#endif /* #ifndef ONGR_H */
