/*
 * -------------------------------------------------------------------
 *
 * Interval --
 *
 *	Designates a range of values by a minimum and maximum limit.
 *
 * -------------------------------------------------------------------
 */
typedef struct {
    double min, max, range;
} Range;

#define SetLimits(lim, lo, hi) \
	((lim).min = (lo), (lim).max = (hi), (lim).range = ((hi) - (lo)))
#define SetRange(lim) \
	((lim).range = ((lim).max > (lim).min) ? ((lim).max - (lim).min) : 0.0)

/*
 * -------------------------------------------------------------------
 *
 * AxisSite --
 *
 *	Enumerated type representing the different sites for axes
 *
 * -------------------------------------------------------------------
 */

typedef enum {
    AXIS_BOTTOM,		/* Axis in bottom margin */
    AXIS_LEFT,			/* Axis in left margin */
    AXIS_TOP,			/* Axis in top margin */
    AXIS_RIGHT,			/* Axis in right margin */
    AXIS_VIRTUAL		/* Axis isn't drawn */
} AxisSite;

/*
 * ----------------------------------------------------------------------
 *
 * TickLabel --
 *
 * 	Structure containing the X-Y screen coordinates of the tick
 * 	label (anchored at its center).
 *
 * ---------------------------------------------------------------------- 
 */
typedef struct TickLabel {
    short int x, y;
} TickLabel;

/*
 * ----------------------------------------------------------------------
 *
 * Ticks --
 *
 * 	Structure containing information where the ticks (major or
 *	minor) will be displayed on the graph.
 *
 * ----------------------------------------------------------------------
 */
typedef struct {
    int numTicks;		/* # of ticks on axis */
    double tickArr[1];		/* Array of tick values (malloc-ed). */
} Ticks;

/*
 * ----------------------------------------------------------------------
 *
 * TickSweep --
 *
 * 	Structure containing information where the ticks (major or
 *	minor) will be displayed on the graph.
 *
 * ----------------------------------------------------------------------
 */
typedef struct {
    double initial;		/* Initial value */
    double step;		/* Size of interval */
    int numSteps;		/* Number of intervals. */
} TickSweep;

/*
 * ----------------------------------------------------------------------
 *
 * Axis --
 *
 * 	Structure contains options controlling how the axis will be
 * 	displayed.
 *
 * ----------------------------------------------------------------------
 */
typedef struct {
    char *name;			/* Axis identifier */

    int deletePending;		/* Indicates that the axis was
				 * scheduled for deletion. The actual
				 * deletion may be deferred until the
				 * axis is no longer in use.  */

    int refCount;		/* Number of elements referencing this
				 * axis. */

    Tcl_HashEntry *hashPtr;	/* Points to axis entry in hash
				 * table. Used to quickly remove axis
				 * entries. */

    int logScale;		/* If non-zero, scale the axis values
				 * logarithmically. */
    int hidden;			/* If non-zero, don't display the
				 * axis title, ticks, or line. */
    int showTicks;		/* If non-zero, display tick marks and
				 * axis line. */
    int loose;			/* If non-zero, axis range extends to
				 * the outer major ticks, otherwise at
				 * the limits of the data values. This
				 * is overriddened by setting the -min
				 * and -max options.  */
    int descending;		/* If non-zero, display the range of
				 * values on the axis in descending
				 * order, from high to low. */

    unsigned int flags;		/* Set bit field definitions below */

    /*
     * AXIS_AUTO_MIN		Set axis minimum based upon data points
     * AXIS_AUTO_MAX		Set axis maximum based upon data points
     * AXIS_MAPS_ELEM		Axis is used to map element coordinates
     * AXIS_DRAWN		Axis is designated as a logical axis
     * AXIS_CONFIG_DIRTY
     * AXIS_TYPE_X		Axis is used as a X-axis
     * AXIS_TYPE_Y		Axis is used as a Y-axis
     */

    char *titleText;		/* Title of axis */
    int titleX, titleY;

    int lineWidth;		/* Width of lines representing axis
				 * (including ticks).  If zero, then
				 * no axis lines or ticks are
				 * drawn. */

    char **limitFormats;	/* One or two strings of sprintf-like
				 * formats describing how to display
				 * virtual axis limits. If NULL,
				 * display no limits. */
    int numFormats;

    double theta;		/* # of degrees to rotate tick labels. */

    double autoRange;		/* Size of a sliding window of values
				 * used to scale the axis automatically 
				 * as new data values are added. The axis
				 * will always display the latest values
				 * in this range. */

    double shiftBy;		/* Shift maximum by this interval. */

    int tickLength;		/* Length of major ticks in pixels */

    TextAttributes tickAttr;	/* Text attributes (color, font,
				 * rotation, etc.)  of labels drawn at
				 * each major tick mark */

    TextAttributes limitAttr;	/* Text attributes (color, font,
				 * rotation, etc.)  of limit labels */

    TextAttributes titleAttr;	/* Text attributes (color, font,
				 * rotation, etc.)  of axis title */

    char *formatCmd;		/* Specifies a user-defined Tcl
				 * command, called whenever the axis
				 * needs to format its tick labels. */

    char *scrollCmdPrefix;
    int scrollUnits;

    Range reqRange;		/* Represents the requested range of
				 * data values to be displayed on the
				 * axis.  These values are either
				 * determined by the data or tick
				 * range (if auto-scaling) or
				 * overridden by the user (-min/-max)
				 * to zoom or scroll selected
				 * regions. */

    Range dataRange;		/* Range of data values for all elements
				 * mapping this axis.  This is used to 
				 * auto-scale the axis in "tight" mode. */

    Range tickRange;		/* Smallest and largest major tick values 
				 * for the axis.  The tick values lie outside
				 * the range of data values.  This is used to 
				 * auto-scale the axis in "loose" mode. */
    double prevMin, prevMax;

    double range;		/* Range of axis */

    double reqStep;		/* If > 0.0, this is the requested
				 * major tick interval.  If
				 * negative or zero, a "best" step
				 * size is automatically computed
				 * based on the range of data values
				 * mapped to the axis. The default
				 * value is 0.0. */
    AxisSite site;

    GC tickGC;			/* Graphics context for axis and tick labels */

    Ticks *reqMajorPtr;		/* Requested major tick positions. If
				 * set by the user (non-NULL), points to 
				 * a malloc-ed array of values representing 
				 * each major tick value. */

    Ticks *reqMinorPtr;		/* Requested minor tick positions. If
				 * set by the user (non-NULL), points
				 * to a malloc-ed array of values
				 * representing each major tick
				 * value. */

    int reqNumMinorTicks;	/* If non-zero, represents the
				 * requested the number of minor ticks
				 * to be uniformally displayed along
				 * each major tick. */

    TickSweep minorTicks, majorTicks;


    /* The following fields are specific to logical axes */

    int width, height;		/* Extents of axis */

    int posArr[4];		/* Screen location of axis, major tick,
				 * minor tick, and tick label */

    Ticks *genMajorPtr;		/* Generated major tick positions */
    Ticks *genMinorPtr;		/* Generated minor tick positions */

    Ticks *majorPtr;		/* Major tick positions */
    Ticks *minorPtr;		/* Minor tick positions */

    int numSegments;		/* Size of the above segment array */
    XSegment *segArr;		/* Array of computed tick line segments.  Also
				 * includes the axis line */
    Blt_List  labelList;

} Axis;

#define AXIS_ALLOW_NULL (1<<12)
#define AXIS_AUTO_MAX	(1<<1)	/* Set axis maximum based upon data points */
#define AXIS_AUTO_MIN	(1<<0)	/* Set axis minimum based upon data points */
#define AXIS_CONFIG_DIRTY (1<<5)
#define AXIS_DRAWN	(1<<4)	/* Axis is designated as a logical axis */
#define AXIS_HORIZONTAL	(1<<2)
#define AXIS_MAPS_ELEM	(1<<3)	/* Axis is used to map element coordinates */
#define AXIS_TYPE_MASK  (AXIS_TYPE_X | AXIS_TYPE_Y)
#define AXIS_TYPE_X	(1<<10)
#define AXIS_TYPE_Y	(1<<11)
#define AXIS_VERTICAL    0

/*
 * -------------------------------------------------------------------
 *
 * Axis2D --
 *
 *	The pair of axes mapping a point onto the graph.
 *
 * -------------------------------------------------------------------
 */
typedef struct {
    Axis *x, *y;
} Axis2D;
