//RLPlot.h, Copyright (c) 2000-2008 R.Lackner
//
//    This file is part of RLPlot.
//
//    RLPlot is free software; you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation; either version 2 of the License, or
//    (at your option) any later version.
//
//    RLPlot is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with RLPlot; if not, write to the Free Software
//    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
#ifndef _RLPLOT_H
#define _RLPLOT_H
#define NUM_UNITS  3
#define TMP_TXT_SIZE 4096

#include <stdio.h>
#include "Version.h"

#define Swap(a,b) {a^=b;b^=a;a^=b;}
inline int iround(double a) {return a < 0.0 ?(int)(a-0.499) : (int)(a+0.499);}

#define _PI	3.1415926535897932384626433832795028841971693993751
#define _SQRT2	1.4142135623730950488016887242096980785696718753769

#ifdef _WINDOWS					//platform is windows
#include <windows.h>
#if _MSC_VER >= 1400
#define USE_WIN_SECURE
#endif
#define w_char WCHAR
#define _SBINC	1				//scrollbox extra space/line
#define _TXH	4.0				//graph text default size in mm

#else							//platform is *nix
#include <sys/types.h>
#define DWORD u_int32_t
#define w_char wchar_t
#define _SBINC	8				//scrollbox extra space/line
#define _TXH	3.0				//graph text default size in mm

typedef struct tagPOINT { // pt 
    long x; 
    long y; 
} POINT; 

typedef struct _RECT {    // rc 
    long left; 
    long top; 
    long right; 
    long bottom; 
} RECT; 

#endif	//_WINDOWS

enum {SIZE_MINE, SIZE_SYMBOL, SIZE_SYM_LINE, SIZE_DATA_LINE, SIZE_TEXT,
	SIZE_GRECT_TOP, SIZE_GRECT_BOTTOM, SIZE_GRECT_LEFT, SIZE_GRECT_RIGHT,
	SIZE_DRECT_LEFT, SIZE_DRECT_RIGHT, SIZE_DRECT_TOP, SIZE_DRECT_BOTTOM,
	SIZE_DATA_LINE_PAT, SIZE_XPOS, SIZE_XPOS_LAST = SIZE_XPOS+200, 
	SIZE_YPOS, SIZE_YPOS_LAST = SIZE_YPOS+200, SIZE_ZPOS, 
	SIZE_ZPOS_LAST = SIZE_ZPOS+200, SIZE_BOUNDS_XMIN,
	SIZE_BOUNDS_XMAX, SIZE_BOUNDS_YMIN, SIZE_BOUNDS_YMAX, SIZE_BOUNDS_ZMIN,
	SIZE_BOUNDS_ZMAX, SIZE_BOUNDS_LEFT, SIZE_BAR_BASE,
	SIZE_BOUNDS_RIGHT, SIZE_BOUNDS_TOP, SIZE_BOUNDS_BOTTOM, SIZE_XAXISY,
	SIZE_YAXISX, SIZE_AXIS_LINE, SIZE_PATLENGTH, SIZE_BAR_DEPTH,
	SIZE_AXIS_TICKS, SIZE_TICK_LABELS, SIZE_ERRBAR, SIZE_ERRBAR_LINE, 
	SIZE_BAR_LINE, SIZE_BAR, SIZE_XBASE, SIZE_YBASE, SIZE_ZBASE, SIZE_BUBBLE_LINE,
	SIZE_BUBBLE_HATCH_LINE, SIZE_BARMINX, SIZE_BARMINY, SIZE_ARROW_LINE,
	SIZE_ARROW_CAPWIDTH, SIZE_ARROW_CAPLENGTH, SIZE_HAIRLINE, SIZE_WHISKER,
	SIZE_WHISKER_LINE, SIZE_BOX_LINE, SIZE_BOXMINX, SIZE_BOXMINY, SIZE_BOX,
	SIZE_RADIUS1, SIZE_RADIUS2, SIZE_SEGLINE, SIZE_LB_XPOS, SIZE_LB_YPOS,
	SIZE_LB_XDIST, SIZE_LB_YDIST, SIZE_TLB_XDIST, SIZE_TLB_YDIST, SIZE_ANGLE1,
	SIZE_ANGLE2, SIZE_XCENTER, SIZE_YCENTER, SIZE_ZCENTER, SIZE_CELLWIDTH, SIZE_CELLTEXT,
	SIZE_A, SIZE_B, SIZE_MX, SIZE_MY, SIZE_MIN_Z, SIZE_MAX_Z, SIZE_MIN_X, SIZE_MAX_X,
	SIZE_MIN_Y, SIZE_MAX_Y, SIZE_TICK_ANGLE, SIZE_RRECT_RAD, SIZE_XCENT, SIZE_YCENT,
	SIZE_ZCENT, SIZE_DRADIUS, SIZE_CURSORPOS, SIZE_CURSOR_XMIN, SIZE_CURSOR_YMIN,
	SIZE_CURSOR_XMAX, SIZE_CURSOR_YMAX, SIZE_XSTEP, SIZE_LSPC, SIZE_SCALE};
enum {COL_SYM_LINE, COL_SYM_FILL, COL_DATA_LINE, COL_TEXT, COL_BG,
	COL_AXIS, COL_BAR_LINE, COL_BAR_FILL, COL_ERROR_LINE, COL_BUBBLE_LINE, 
	COL_BUBBLE_FILLLINE, COL_BUBBLE_FILL, COL_ARROW, COL_WHISKER, COL_BOX_LINE,
	COL_DRECT, COL_GRECT, COL_GRECTLINE, COL_POLYLINE, COL_POLYGON};
enum {MRK_NONE, MRK_INVERT, MRK_GODRAW, MRK_SSB_DRAW};
enum {CMD_NONE, CMD_ADDCHAR, CMD_ADDCHARW, CMD_SETFOCUS, CMD_KILLFOCUS, CMD_DELETE,
	CMD_BACKSP, CMD_CURRLEFT, CMD_CURRIGHT, CMD_CURRUP, CMD_CURRDOWN,
	CMD_SHIFTLEFT, CMD_SHIFTRIGHT, CMD_SHIFTUP, CMD_SHIFTDOWN,
	CMD_NEWGRAPH, CMD_DELGRAPH, CMD_DELOBJ, CMD_DROP_PLOT, CMD_DROP_GRAPH, CMD_OPEN,
	CMD_SAVEAS, CMD_ADDROWCOL, CMD_MOUSE_EVENT, CMD_REDRAW, CMD_DOPLOT,
	CMD_LBUP, CMD_ENDDIALOG, CMD_RADIOBUTT, CMD_ADDCHILD, CMD_BAR_TYPE,
	CMD_BAR_FILL, CMD_SET_AXDEF, CMD_SET_DATAOBJ, CMD_SETTEXT, CMD_GETTEXT,
	CMD_SETTEXTDEF, CMD_GETTEXTDEF, CMD_ADDPLOT, CMD_SYM_TYPE, CMD_SYMTEXT, 
	CMD_SYMTEXTDEF, CMD_RANGETEXT, CMD_SYM_RANGETEXT, CMD_FOCTXT, CMD_CONTINUE,
	CMD_ERR_TYPE, CMD_ARROW_ORG, CMD_ARROW_TYPE, CMD_FLUSH, CMD_BOX_FILL,
	CMD_TABDLG, CMD_NOTABDLG, CMD_TAB, CMD_SHTAB, CMD_BOX_TYPE, CMD_BUBBLE_TYPE,
	CMD_BUBBLE_ATTRIB, CMD_BUBBLE_FILL, CMD_BUBBLE_LINE, CMD_DL_LINE, 
	CMD_DL_TYPE, CMD_SEG_FILL, CMD_SEG_LINE, CMD_SELECT, CMD_MOVE, CMD_CUT,
	CMD_SETSCROLL, CMD_SETHPOS, CMD_SETVPOS, CMD_PG_FILL, CMD_BOUNDS,
	CMD_SHIFT_OUT, CMD_CAN_CLOSE, CMD_RESET_LINE, CMD_SET_TICKSTYLE,
	CMD_GET_GRIDLINE, CMD_SET_GRIDLINE, CMD_SET_GRIDTYPE, CMD_TLB_TXTDEF,
	CMD_DROP_LABEL, CMD_DROP_OBJECT, CMD_PAGEUP, CMD_PAGEDOWN, CMD_AUTOSCALE,
	CMD_MRK_DIRTY, CMD_SETNAME, CMD_TOOLMODE, CMD_DROPFILE, CMD_AXIS, CMD_INIT,
	CMD_GET_CELLDIMS, CMD_SET_CELLDIMS, CMD_TEXTSIZE, CMD_PASTE_TSV, CMD_PASTE_XML,
	CMD_PASTE_SSV, CMD_PASTE_CSV, CMD_COPY_TSV, CMD_COPY_XML, CMD_COPY_SYLK, CMD_QUERY_COPY,
	CMD_MOUSECURSOR, CMD_NEWPAGE, CMD_MINRC, CMD_MAXRC,CMD_SETCHILD, CMD_SYM_FILL,
	CMD_LINEUP, CMD_LINEDOWN, CMD_CONFIG, CMD_FINDTEXT, CMD_MOVE_TOP, CMD_MOVE_UP,
	CMD_MOVE_DOWN, CMD_MOVE_BOTTOM, CMD_UPDATE, CMD_CURRPOS, CMD_POS_FIRST, CMD_POS_LAST,
	CMD_ADDAXIS, CMD_REG_AXISPLOT, CMD_USEAXIS, CMD_SET_GO3D, CMD_UNDO, CMD_DELOBJ_CONT,
	CMD_RMU, CMD_REPL_GO, CMD_UNDO_MOVE, CMD_SAVEPOS, CMD_WHISKER_STYLE, CMD_TICK_TYPE,
	CMD_ZOOM, CMD_CLIP, CMD_STARTLINE, CMD_ADDTOLINE, CMD_REQ_POINT, CMD_DRAW_LATER,
	CMD_SEG_MOVEABLE, CMD_ARROW_ORG3D, CMD_MUTATE, CMD_PRINT, CMD_UPDHISTORY, CMD_ALLTEXT,
	CMD_SET_LINE, CMD_SAVE_SYMBOLS, CMD_SAVE_TICKS, CMD_SAVE_BARS, CMD_SAVE_BARS_CONT,
	CMD_SAVE_ERRS, CMD_SAVE_ARROWS, CMD_SAVE_DROPLINES, CMD_SAVE_LABELS, CMD_UNLOCK, CMD_SYMTEXT_UNDO,
	CMD_FILLRANGE, CMD_BUSY, CMD_ERROR, CMD_CLEAR_ERROR, CMD_SETPARAM, CMD_SETFUNC,
	CMD_LEGEND, CMD_FILENAME, CMD_LAYERS, CMD_OBJTREE, CMD_TEXTDEF,
	CMD_HASSTACK, CMD_WRITE_GRAPHS, CMD_SETFONT, CMD_SETSTYLE, CMD_COPY, CMD_PASTE,
	CMD_INSROW, CMD_INSCOL, CMD_DELROW, CMD_DELCOL, CMD_ADDTXT, CMD_ETRACC, CMD_SHPGUP, 
	CMD_SHPGDOWN, CMD_ERRDESC, CMD_SAVE, CMD_GETMARK, CMD_PASTE_OBJ, CMD_COL_MOUSE,
	CMD_MARKOBJ, CMD_SCALE, CMD_GETFILENAME, CMD_TEXTTHERE, CMD_HIDEMARK, CMD_MENUHEIGHT,
	CMD_RECALC, CMD_DRAWPG, CMD_UPDPG, CMD_MINMAX, CMD_STEP, CMD_SIGNAL_POL};
enum {SYM_CIRCLE, SYM_CIRCLEF, SYM_RECT, SYM_RECTF, SYM_TRIAU, SYM_TRIAUF,
	SYM_TRIAD, SYM_TRIADF, SYM_DIAMOND, SYM_DIAMONDF, SYM_PLUS, SYM_CROSS,
	SYM_STAR, SYM_HLINE, SYM_VLINE, SYM_CIRCLEC, SYM_RECTC, SYM_TRIAUC, SYM_TRIAUL, SYM_TRIAUR,
	SYM_TRIADC, SYM_TRIADL, SYM_TRIADR, SYM_DIAMONDC, SYM_4STAR, SYM_4STARF, SYM_5GON, SYM_5GONF, 
	SYM_5GONC, SYM_5STAR, SYM_5STARF, SYM_6STAR, SYM_6STARF, SYM_1QUAD, SYM_2QUAD, SYM_3QUAD,
	SYM_TEXT = 0x004f, SYM_POS_PARENT = 0x1000};
//types of graphic objects: stored in Id and used for proper destruction of objects
//  and retrieving information.
enum {GO_UNKNOWN, GO_AXIS, GO_TICK, GO_GRIDLINE, GO_SYMBOL, GO_BUBBLE, GO_BAR, 
	GO_ERRBAR, GO_ARROW, GO_BOX, GO_LABEL, GO_MLABEL, GO_WHISKER, GO_DROPLINE, 
	GO_DATALINE, GO_DATAPOLYGON, GO_REGLINE, GO_SDELLIPSE, GO_SEGMENT, 
	GO_POLYLINE, GO_POLYGON, GO_RECTANGLE, GO_ELLIPSE, GO_ROUNDREC,
	GO_DRAGHANDLE, GO_DRAGRECT, GO_DRAG3D, GO_FRAMERECT, GO_SPHERE, GO_SVGOPTIONS,
	GO_PLANE, GO_BRICK, GO_LINESEG, GO_LINE3D, GO_GRIDLINE3D, GO_GRIDRADIAL,
	GO_SPHSCANL, GO_DROPL3D, GO_ARROW3D, GO_PLANE3D, GO_LEGITEM, GO_LEGEND,
	GO_OBJTREE, GO_BEZIER, GO_TEXTFRAME,
	GO_PLOT = 0x100, GO_PLOTSCATT, GO_REGRESSION, GO_BARCHART, GO_BUBBLEPLOT, 
	GO_BOXPLOT, GO_DENSDISP, GO_STACKBAR, GO_STACKPG, GO_WATERFALL, GO_POLARPLOT,
	GO_PIECHART, GO_RINGCHART, GO_GROUP, GO_STARCHART, GO_SCATT3D, GO_PLOT3D,
	GO_RIBBON, GO_LIMITS, GO_FUNCTION, GO_FITFUNC, GO_FREQDIST, GO_GRID3D, GO_FUNC3D,
	GO_XYSTAT, GO_FITFUNC3D, GO_NORMQUANT, GO_CONTOUR,
	GO_GRAPH = 0x200, GO_PAGE, GO_SPREADDATA = 0x300, GO_DEFRW};
enum {OC_UNKNOWN, OC_BITMAP, OC_HIMETRIC, OC_TRANSPARENT = 0x100};
enum {FILL_NONE, FILL_HLINES, FILL_VLINES, FILL_HVCROSS, FILL_DLINEU, FILL_DLINED,
	FILL_DCROSS, FILL_STIPPLE1, FILL_STIPPLE2, FILL_STIPPLE3, FILL_STIPPLE4, 
	FILL_STIPPLE5, FILL_ZIGZAG, FILL_COMBS, FILL_BRICKH, FILL_BRICKV, FILL_BRICKDU, 
	FILL_BRICKDD, FILL_TEXTURE1, FILL_TEXTURE2, FILL_WAVES1, FILL_SCALES, FILL_SHINGLES, 
	FILL_WAVES2, FILL_HERRING, FILL_CIRCLES, FILL_GRASS, FILL_FOAM, FILL_RECS, 
	FILL_HASH, FILL_WATER, NUM_FILLS, FILL_LIGHT3D = 0x100};
enum {ERRBAR_VSYM, ERRBAR_VUP, ERRBAR_VDOWN, ERRBAR_HSYM, ERRBAR_HLEFT,
	ERRBAR_HRIGHT};
enum {BAR_NONE, BAR_VERTB, BAR_VERTT, BAR_VERTU, BAR_HORL, BAR_HORR, BAR_HORU, 
	BAR_RELWIDTH = 0x100, BAR_CENTERED = 0x200, BAR_WIDTHDATA = 0x400};
enum {TM_STANDARD, TM_DRAW, TM_POLYLINE, TM_POLYGON, TM_RECTANGLE, TM_ELLIPSE,
	TM_ROUNDREC, TM_ARROW, TM_TEXT, TM_MARK, TM_ZOOMIN, TM_MOVE = 0x100, 
	TM_PASTE=0x200};
enum {MC_LAST, MC_ARROW, MC_CROSS, MC_TEXT, MC_WAIT, MC_MOVE, MC_NORTH,
	MC_NE, MC_EAST, MC_SE, MC_SALL, MC_ZOOM, MC_PASTE, MC_DRAWPEN, MC_DRAWREC, 
	MC_DRAWRREC, MC_DRAWELLY, MC_TXTFRM, MC_COLWIDTH};
enum {FILE_ERROR, FILE_READ, FILE_WRITE, INIT_VARS, SAVE_VARS};
enum {ARROW_NOCAP, ARROW_LINE, ARROW_TRIANGLE, ARROW_UNITS = 0x100};
enum {MENU_NONE, MENU_SPREAD, MENU_GRAPH, MENU_PAGE};
enum {GT_UNKNOWN, GT_STANDARD, GT_CIRCCHART, GT_POLARPLOT, GT_3D};
enum {ICO_NONE, ICO_INFO, ICO_ERROR, ICO_RLPLOT, ICO_QT};
enum {FF_UNKNOWN, FF_CSV, FF_TSV, FF_XML, FF_SYLK, FF_RLP, FF_SVG, FF_EPS,
	FF_WMF, FF_RLW, FF_SSV};
enum {LB_X_DATA = 0x01, LB_X_PARENT = 0x02, LB_Y_DATA = 0x10, LB_Y_PARENT = 0x20};
enum {BUBBLE_CIRCLE = 0x000, BUBBLE_SQUARE = 0x001, BUBBLE_UPTRIA = 0x002,
	BUBBLE_DOWNTRIA = 0x003, BUBBLE_UNITS = 0x000, BUBBLE_XAXIS = 0x010,
	BUBBLE_YAXIS = 0x020, BUBBLE_DIAMET = 0x000, BUBBLE_CIRCUM = 0x100,
	BUBBLE_AREA = 0x200};
enum {DH_UNKNOWN, DH_12, DH_22, DH_19, DH_29, DH_39, DH_49, DH_59, DH_69, DH_79,
	DH_89, DH_99, DH_18, DH_28, DH_38, DH_48, DH_58, DH_68, DH_78, DH_88, DH_DATA};
enum {FE_NONE = 0x1000, FE_PARENT, FE_PLOT, FE_FLUSH, FE_DELOBJ, FE_REPLGO, FE_MUTATE};

//drop line styles
#define DL_LEFT          0x001
#define DL_RIGHT         0x002
#define DL_YAXIS         0x004
#define DL_TOP           0x010
#define DL_BOTTOM        0x020
#define DL_XAXIS         0x040
#define DL_CIRCULAR      0x100

typedef struct {
	int num;
	char* display;
	float convert;			//multiply to get mm
	}tag_Units;

typedef struct {
	int x, y, z;
	}POINT3D;

typedef struct {
	double Xmin;
	double Ymax;
	double Xmax;
	double Ymin;
	}fRECT;

typedef struct {
	double fx;
	double fy;
	double fz;
	}fPOINT3D;

typedef struct {
	double fx;
	double fy;
	}lfPOINT;

typedef struct {
	lfPOINT sx, sy, sz;
	}scaleINFO;

typedef struct {
	double finc, fp;
	}RunLinePat;				//used for line patterns

typedef struct {
	double width, patlength;
	DWORD color, pattern;
	}LineDEF;

typedef struct {
	int type;					//pattern
	DWORD color;
	double scale;
	LineDEF *hatch;
	DWORD color2;
	}FillDEF;

typedef struct {
	lfPOINT org;				//zoom origin
	double scale;				//zoom factor
	}ZoomDEF;

typedef struct rlp_datetime {
	int aday, year, doy, month, dom, dow, hours, minutes;
	double seconds;
}rlp_datetime;

// Axis definitions are stored in the following structure
// not to be confused with the Axis class grapic object
// bits stored in flags havethe following meaning
#define AXIS_NOTICKS      0x0			// no ticks at all
#define AXIS_POSTICKS     0x1			// positive direction of ticks
#define AXIS_NEGTICKS     0x2			// negative direction 
#define AXIS_SYMTICKS     0x3			// ticks are symmetrical
#define AXIS_GRIDLINE     0x4			// ticks control a gridline
#define AXIS_MINORTICK    0x8			// its a small tick only
#define AXIS_USER         0x00			// axis placement by user
#define AXIS_LEFT         0x10			// left of plot
#define AXIS_RIGHT        0x20			// right  -"-
#define AXIS_TOP          0x30			// top    -"-
#define AXIS_BOTTOM       0x40			// bottom -"-
#define AXIS_AUTOSCALE    0x80			// rescale upon editing
#define AXIS_INVERT       0x100			// axis top->bottom, right to left
#define AXIS_AUTOTICK     0x200			// select tick s automatically
#define AXIS_DEFRECT      0x400			// use axis to define drawing rectangle
#define AXIS_LINEAR       0x0000		// transforms ...
#define AXIS_LOG          0x1000
#define AXIS_RECI         0x2000
#define AXIS_SQR          0x3000
#define AXIS_DATETIME     0x4000		// its a date- or time axis
#define AXIS_X_DATA       0x10000		// loc.x is data coordinates
#define AXIS_Y_DATA       0x20000       // loc.y is data coordinates
#define AXIS_Z_DATA       0x40000       // loc.z is data coordinates
#define AXIS_ANGULAR      0x100000      // angular (circular) axis
#define AXIS_RADIAL       0x200000		// radial axis
#define AXIS_3D           0x400000		// three dimensional axis

typedef struct {
	void *owner;				//owners are usually graph, output or axis classes
	DWORD flags;
	double min, max;
	fPOINT3D loc[2];			//placement of axis coordinates
	double Start, Step;			//used for linear axis
	lfPOINT Center;				//of polar plot
	double Radius;				//   -"-
	int nBreaks;				//axis break ...
	lfPOINT *breaks;
	}AxisDEF;

//Attributes for text properties
//Text fonts
enum {FONT_HELVETICA, FONT_TIMES, FONT_COURIER, FONT_GREEK};
//Text styles
#define TXA_VTOP        0
#define TXA_VCENTER     4
#define TXA_VBOTTOM     8
#define TXA_HLEFT       0
#define TXA_HCENTER     1
#define TXA_HRIGHT      2
#define TXM_OPAQUE      0
#define TXM_TRANSPARENT 1
#define TXS_NORMAL      0
#define TXS_ITALIC      1
#define TXS_BOLD        2
#define TXS_UNDERLINE   4
#define TXS_SUPER       8
#define TXS_SUB			16
typedef struct {
	DWORD ColTxt, ColBg;				//colors ..
	double fSize;						//Text size in units
	double RotBL, RotCHAR;				//Rotation in degrees
	int iSize;							//Text size is given in iSize as pix
	int Align, Mode, Style;				//Text Alignement 0   1   2
										//                4   5   6
										//                8   9  10
										//Mode 0 = opaque, 1 = transparent
	int Font;
	char *text;
	}TextDEF;

// Store mouse events in the following structure
// Action defines the type of event:
enum {MOUSE_LBDOWN, MOUSE_LBUP, MOUSE_LBDOUBLECLICK, MOUSE_MBDOWN, MOUSE_MBUP, 
	MOUSE_MBDOUBLECLICK, MOUSE_RBDOWN, MOUSE_RBUP, MOUSE_RBDOUBLECLICK,
	MOUSE_MOVE};
typedef struct {
	unsigned short StateFlags;	//  1 Mouse left button down
								//  2       middle button down
								//  4       right button down
								//  8       shift pressed
								// 16       control pressed
	unsigned short Action;
	int x, y;
	} MouseEvent;

//use this structure if type of data is not known
typedef struct {
	int type;
	double value;
	char *text;
	double *a_data;
	int a_count;
	} anyResult;

//the AccRange class allows to access data objects with a 'a1:b1' style
class AccRange{
public:
	AccRange(char *asc);
	~AccRange();
	int CountItems();
	bool GetFirst(int *x, int *y);
	bool GetNext(int *x, int *y);
	bool NextRow(int *y);
	bool NextCol(int *x);
	bool IsInRange(int x, int y);
	bool BoundRec(RECT *rec);
	char *RangeDesc(void *d, int style);	//d points to a DataObj class
	int DataTypes(void *d, int *numerical, int *strings, int *datetime);

private:
	char *txt;
	int x1, y1, x2, y2, cx, cy, curridx;

	bool Reset();
	bool Parse(int start);
};

class Triangle {
public:
	Triangle *next;
	fPOINT3D pt[4];
	int order[3];					//sort order

	Triangle();
	void SetRect();
	bool TestVertex(double x, double y);
	bool Sort();
	void LinePoint(int i1, int i2, double z, lfPOINT *res);
	bool IsoLine(double z, void *dest);

private:
	double cx, cy, r2;				//circumcircle
	fRECT rc;					//bounding rectangle
	lfPOINT ld[3];					//line eqations
	bool bSorted;					//vertices are sorted
};

class Triangulate {
public:
	Triangle *trl;

	Triangulate(Triangle *t_list);
	bool AddEdge(fPOINT3D *p1, fPOINT3D *p2);
	bool AddVertex(fPOINT3D *v);

private:
	typedef struct edge {
		edge *next;
		fPOINT3D p1, p2;
	};
	edge *edges;
};

class anyOutput{
public:
	int units;						//use units mm, inch ...
	int minLW;						//minimum line width in pix
	int MrkMode;						//existing mark on screen
	int OC_type;						//specify display, printer clipboard ...
	void *MrkRect;						//pointer to e.g. the marked rectangle
	fRECT Box1;						//User drawing rectangle
	lfPOINT Box1z;						// add 3D to Box1
	RECT DeskRect;						//this is maximum size Rectangle
	double ddx, ddy, ddz;					//convert to device coordinates
	double hres, vres;					//resolution in dpi
	double LineWidth;					//line width in units
	int iLine;						//current width of line in pixels
	DWORD dLineCol;						//current color of line;
	DWORD dBgCol;						//color of background
	DWORD dFillCol, dFillCol2;
	DWORD dPattern;						//current line bit-pattern
	TextDEF TxtSet;						//store current text settings here
	RunLinePat RLP;						//continuous setings of pattern line
	AxisDEF xAxis, yAxis, zAxis;				//axis and transform definitions
	lfPOINT VPorg;						//zoom origin
	double VPscale;						//zoom factor
	int MenuHeight;						//ofset due to pull down menus
	int cCursor;						//mouse coursor identifier
	double rotM[3][3];					//rotation matrix for 3D
	fPOINT3D rotC;						//rotation center
	bool hasHistMenu;					//File History List
	int HistMenuSize;					//     -"-
	lfPOINT light_source;					//angles for shading
	double light_vec[3][3];					//     -"-
	double disp_x, disp_y;					//displacement on page

	anyOutput();
	void SetRect(fRECT rec, int units, AxisDEF *x_ax, AxisDEF *y_ax);
	void UseAxis(AxisDEF *ax, int type);
	void SetSpace(fPOINT3D*,fPOINT3D*,int,double*,fPOINT3D*,AxisDEF*,AxisDEF*,AxisDEF*);
	void LightSource(double x, double y);
	DWORD VecColor(double *plane_vec, DWORD col1, DWORD col2);
	bool GetSize(RECT *rc);
	virtual bool ActualSize(RECT *rc) {return GetSize(rc);};
	double fx2fix(double x);
	int fx2ix(double x){return (int)(0.5 + fx2fix(x));};
	double fy2fiy(double y);
	int fy2iy(double y){return (int)(0.5 + fy2fiy(y));};
	bool fp2fip(lfPOINT *fdp, lfPOINT *fip);
	bool fvec2ivec(fPOINT3D *v, fPOINT3D *iv);
	bool cvec2ivec(fPOINT3D *v, fPOINT3D *iv);
	bool uvec2ivec(fPOINT3D *v, fPOINT3D *iv);
	double un2fix(double x);
	int un2ix(double x) {return (int)(0.5 + un2fix(x));};
	int co2ix(double x) {return un2ix(x) + iround(VPorg.fx);};
	double co2fix(double x) {return un2fix(x) + VPorg.fx;};
	double un2fiy(double y);
	int un2iy(double y) {return (int)(0.5 + un2fiy(y));};
	int co2iy(double y) {return un2iy(y) + iround(VPorg.fy);};
	double co2fiy(double y) {return un2fiy(y) + VPorg.fy;};
	double un2fiz(double z);
	double fz2fiz(double z);
	double fix2un(double fix);
	double fiy2un(double fiy);
	virtual bool SetLine(LineDEF *lDef){return false;};
	bool GetLine(LineDEF *lDef);
	virtual void Focus() {return;};
	virtual void Caption(char *txt, bool bModified){return;};
	virtual void MouseCursor(int cid, bool force){return;};
	virtual bool SetScroll(bool, int, int, int, int){return false;};
	virtual bool SetFill(FillDEF *fill){return false;};
	virtual bool SetTextSpec(TextDEF *set);
	virtual bool Erase(DWORD Color){return false;};
	virtual bool StartPage(){return false;};
	virtual bool EndPage(){return false;};
	virtual bool Eject() {return false;};		//printers only
	virtual bool UpdateRect(RECT *rc, bool invert){return false;};
	virtual bool CopyBitmap(int x, int y, anyOutput* src, int sx, int sy,
		int sw, int sh, bool invert){return false;};
	virtual void ShowBitmap(int x, int y, anyOutput* src){return;};
	bool ShowMark(void *rc, int Mode);
	bool HideMark();
	virtual void MouseCapture(bool bgrab){return;};
	int CalcCursorPos(char *txt, POINT p, POINT *fit);
	bool TextCursor(char *txt, POINT p, POINT *fit, int *pos, int disp);
	bool PatLine(POINT p1, POINT p2);
	virtual void ShowLine(POINT * pts, int cp, DWORD color) {return;};
	virtual void ShowEllipse(POINT p1, POINT p2, DWORD color){return;}; 
	virtual void ShowInvert(RECT *rec){return;};
	virtual bool SetMenu(int type){return false;};
	virtual void CheckMenu(int mid, bool check){return;};
	virtual void FileHistory(){return;};
	virtual bool oGetPix(int x, int y, DWORD *col){return false;};
	virtual bool oDrawIcon(int type, int x, int y) {return false;};
	virtual bool oGetTextExtent(char *text, int cb, int *width, int *height);
	virtual bool oGetTextExtentW(w_char *text, int cb, int *width, int *height);
	virtual bool oCircle(int x1, int y1, int x2, int y2, char *nam = 0L){return false;};
	virtual bool oSphere(int cx, int cy, int r, POINT *pts, int cp, char *nam = 0L);
	virtual bool oPolyline(POINT * pts, int cp, char *nam = 0L){return false;};
	virtual bool oRectangle(int x1, int y1, int x2, int y2, char *nam = 0L){return false;};
	virtual bool oSolidLine(POINT *p){return false;};
	virtual bool oTextOut(int x, int y, char *txt, int cb){return false;};
	virtual bool oTextOutW(int x, int y, w_char *txt, int cb){return false;};
	virtual bool oPolygon(POINT *pts, int cp, char *nam = 0L){return false;};
};

enum {ET_UNKNOWN, ET_VALUE, ET_TEXT, ET_FORMULA, ET_ERROR, ET_BOOL, 
	ET_DATE, ET_TIME, ET_DATETIME, ET_BUSY=0x100, ET_CIRCULAR=0x200, ET_EMPTY=0x400, 
	ET_NODRAW=0x800, ET_NODRAW_EMPTY=0xc00};

class EditText {
public:
	char *text, *ftext;
	int Align, type, row, col;
	void *parent;				//points to a data object: defined below
	anyOutput *disp;
	double Value;

	EditText(void *par, char *msg, int r, int c);
	~EditText();
	bool AddChar(int c, anyOutput *Out, void *data_obj);
	void Update(int select, anyOutput *Out, POINT *MousePos);
	bool Redraw(anyOutput *Out, bool display);
	void Mark(anyOutput *Out, int mark);
	bool Command(int cmd, anyOutput *Out, void *data_obj);
	bool GetValue(double *v);
	bool GetText(char *t, int size, bool bTranslate);
	bool GetResult(anyResult *r, bool use_last = false);
	bool SetValue(double v);
	bool SetText(char *t);
	void SetRec(RECT *rc);
	int GetX() {return loc.x;};
	int GetY() {return loc.y;};
	int GetRX() {return crb.x;};
	int GetRY() {return crb.y;};
	int Cursor() {return CursorPos;};
	bool isValue();
	bool isFormula();
	bool isInRect(POINT *p) {return (p->x>loc.x && p->x<crb.x && p->y>loc.y && p->y<rb.y);};
	bool hasMark() {return (m1 != m2 && m1 >= 0 && m2 >= 0);};

private:
	LineDEF *bgLine;
	FillDEF *bgFill;
	int length, CursorPos, m1, m2, mx1, mx2;
	POINT loc, rb, crb;
	DWORD TextCol;

	void FindType();
	void set_etracc();
};

class fmtText {

typedef struct _fmt_txt_info {
	int tag, uc, uc_len;
	char *txt;
}fmt_txt_info;

typedef struct _fmt_uc_info {
	int tag, cb;
	w_char *uc_txt;
}fmt_uc_info;

public:
	fmtText();
	fmtText(anyOutput *o, int x, int y, char *txt);
	~fmtText();
	bool StyleAt(int idx,  TextDEF *txt_def, int *style, int *font);
	int rightTag(char *txt, int cb);
	int leftTag(char *txt, int cb);
	int ucTag(char *txt, int cb, int *tl, int *ucc);
	int ucLeft(char *txt, int cb, int *tl, int *ucc);
	void cur_right(int *pos);
	void cur_left(int *pos);
	bool oGetTextExtent(anyOutput *o, int *width, int *height, int cb);
	void SetText(anyOutput *o, char *txt, int *px, int *py);
	void DrawText(anyOutput *o);
	void EditMode(bool bEdit);

private:
	bool SetTextDef(TextDEF *td, int idx);
	bool Parse();
	void DrawBullet(anyOutput *o, int x, int y, int type, double size, DWORD lc, DWORD fc);
	bool DrawFormattedW(anyOutput *o);
	void DrawFormatted(anyOutput *o);

	char *src;
	POINT pos;
	int n_split, n_split_W, uc_state;
	DWORD flags;
	fmt_txt_info *split_text;
	fmt_uc_info *split_text_W;
};

class TextValue {

typedef struct _TxtValItem {
	unsigned int hv1, hv2;
	char *text;
	double val;
}TextValItem;

public:
	TextValue();
	TextValue(TextValItem **tvi, int ntvi);
	~TextValue();
	double GetValue(char* txt);
	bool GetItem(int idx, char **text, double *value);
	void Reset();
	TextValue *Copy();
	int Count() {return nitems;};

private:
	TextValItem **items;
	int nitems;
	double next, inc;
};

class RangeInfo {
public:
	int col_width, row_height, first_width;
	RangeInfo(int sel, int cw, int rh, int fw, RangeInfo *next);
	RangeInfo(int sel, char *range, RangeInfo *next);
	~RangeInfo();
	int SetWidth(int w);
	int SetDefWidth(int w);
	int SetHeight(int h);
	int SetFirstWidth(int w);
	int GetWidth(int col);
	int GetHeight(int row);
	int GetFirstWidth();
	int Type(){return r_type;};
	RangeInfo *Next(){return ri_next;};

private:
	int r_type;		// 0 default
					// 1 column info
					// 2 row info
	RangeInfo *ri_next;
	AccRange *ar;
};

class DataObj{
public:
	int cRows, cCols, c_disp, r_disp;
	RangeInfo *ri;
	EditText ***etRows;

	DataObj();
	~DataObj();
	virtual bool Init(int nRows, int nCols);
	virtual bool mpos2dpos(POINT *mp, POINT *dp, bool can_scroll){return false;};
	virtual bool SetValue(int row, int col, double val);
	virtual bool SetText(int row, int col, char *txt);
	virtual bool GetValue(int row, int col, double *v);
	virtual bool GetText(int row, int col, char *txt, int len, bool bTranslate = true);
	char **GetTextPtr(int row, int col);
	virtual bool GetResult(anyResult *r, int row, int col, bool use_last = false);
	virtual bool GetSize(int *width, int *height);
	virtual bool isEmpty(int row, int col);
	virtual bool Select(POINT *p){return false;};
	virtual bool WriteData(char *FileName) {return false;};
	virtual bool AddCols(int nCols){return false;};
	virtual bool AddRows(int nRows){return false;};
	virtual bool ChangeSize(int nCols, int nRows, bool bUndo){return false;};
	virtual bool Command(int cmd, void *tmpl, anyOutput *o){return false;};
	virtual bool ReadData(char *, unsigned char *, int){return false;};
	virtual void FlushData();
	bool ValueRec(RECT *rc);
};

class StrData {
public:
	StrData(DataObj *par, RECT *rc = 0L);
	~StrData();
	bool GetSize(int *w, int *h);
	void RestoreData(DataObj *dest);

private:
	int pw, ph;
	RECT drc;
	DataObj *src;
	char ***str_data;
};

class HatchOut:public anyOutput {
public:
	HatchOut(anyOutput *Parent);
	~HatchOut();
	bool SetFill(FillDEF *fill);
	bool StartPage();
	bool oCircle(int x1, int y1, int x2, int y2, char *nam = 0L);
	bool oSphere(int cx, int cy, int r, POINT *pts, int cp, char *nam = 0L);
	bool oRectangle(int x1, int y1, int x2, int y2, char *nam = 0L);
	bool oPolygon(POINT *pts, int cp, char *nam = 0L);

private:
	anyOutput *out;
	double xbase, ybase;
	LineDEF ParLineDef, MyLineDef;
	bool ParInit;
	int ho, ht;
	DWORD ParLinPat;
	RECT UseRect;
	struct {
		int cx, cy, r;
		}circ_grad;

	bool PrepareParent(bool Restore);
	bool DoHatch();
	bool MkPolyLine(POINT *p, anyOutput *o);
	bool HatchLine(POINT p1, POINT p2);
	bool HatchArc(int x, int y, int r, int qad, bool start);
	bool IsInside(POINT p);
	void Lines000();
	void Lines090();
	void Lines045();
	void Lines315();
	void Stipple(int type);
	void Zigzag();
	void Combs();
	void BricksH();
	void BricksV();
	void Bricks045();
	void Bricks315();
	void Texture1();
	void Texture2();
	void Arcs(int type);
	void Waves2(int type);
	void Herringbone();
	void Circles();
	void Grass();
	void Foam();
	void Recs();
	void Hash();
	void CircGrad();
};

class GraphObj {
public:
	unsigned long Id;			//accepts an identifier during read from file
								//  it is set to an object identifier after
								//  construction
	GraphObj *parent;
	DataObj *data;
	int type, moveable;
	RECT rDims;
	char *name;

	GraphObj(GraphObj *par, DataObj *d);
	virtual ~GraphObj();
	virtual double GetSize(int select);
	virtual bool SetSize(int select, double value){return false;};
	virtual DWORD GetColor(int select);
	virtual bool SetColor(int select, DWORD col) {return false;};
	virtual void DoPlot(anyOutput *target){return;};
	virtual void DoMark(anyOutput *target, bool mark){return;};
	virtual bool Command(int cmd, void *tmpl, anyOutput *o){return false;};
	virtual bool PropertyDlg(){return false;};
	virtual void RegGO(void *n);
	virtual bool FileIO(int rw) {return false;};
	virtual void * ObjThere(int x, int y);
	virtual void Track(POINT *p, anyOutput *o);
	virtual double DefSize(int select);
	virtual bool hasTransp(){return false;};
};

class ssButton:public GraphObj {
public:

	ssButton(GraphObj *par, int x, int y, int w, int h);
	~ssButton();
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *target, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);

private:
	bool bLBdown, bSelected, bMarked;
	TextDEF TextDef;
	LineDEF Line;
	FillDEF Fill;
};

class dragHandle:public GraphObj {
public:

	dragHandle(GraphObj *par, int type);
	~dragHandle();
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	void * ObjThere(int x, int y);
	void Track(POINT *p, anyOutput *o);

private:
	RECT upd, drec, *minRC, *maxRC;
	LineDEF LineDef;
	FillDEF FillDef;
};

class dragRect:public GraphObj {
public:

	dragRect(GraphObj *par, int type);
	~dragRect();
	double GetSize(int select){return parent->GetSize(select);};
	DWORD GetColor(int select){return parent->GetColor(select);};
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void*tmpl, anyOutput *o);
	void * ObjThere(int x, int y);

private:
	dragHandle **handles;
};

class Drag3D:public GraphObj {
public:
	Drag3D(GraphObj *par);
	~Drag3D();
	double GetSize(int select){return parent->GetSize(select);};
	void DoPlot(anyOutput *o);
	void * ObjThere(int x, int y);

private:
	dragHandle **handles;
};

class FrmRect:public GraphObj {
public:

	FrmRect(GraphObj *par, fRECT *limRC, fRECT *cRC, fRECT *chld);
	~FrmRect();
	double GetSize(int select);
	bool SetSize(int select, double value);
	bool SetColor(int select, DWORD col);
	void DoMark(anyOutput *o, bool mark);
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg(){return parent ? parent->Command(CMD_CONFIG, 0L, 0L) : false;};
	void * ObjThere(int x, int y);
	void Track(POINT *p, anyOutput *o);

private:
	RECT *minRC, *maxRC;
	anyOutput *mo;
	RECT mrc;
	dragRect *drag;
	bool swapX, swapY;
	fRECT *limRC, *cRC, *chldRC, CurrRect;
	LineDEF Line, FillLine;
	FillDEF Fill;
};

class svgOptions:public GraphObj{
public:
	svgOptions(int src);
	~svgOptions();
	bool FileIO(int rw);

private:
	char *script, *svgattr;
};

class Symbol:public GraphObj{
public:
	int idx;

	Symbol(GraphObj *par, DataObj *d, double x, double y, int which, 
		int xc = -1, int xr = -1, int yc = -1, int yr = -1);
	Symbol(int src);
	~Symbol();
	double GetSize(int select);
	bool SetSize(int select, double value);
	DWORD GetColor(int select);
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *target);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);

private:
	lfPOINT fPos;
	POINT *ssRef;
	long cssRef;
	double size;
	LineDEF SymLine;
	FillDEF SymFill;
	TextDEF *SymTxt;
};

class Bubble:public GraphObj{
public:
	Bubble(GraphObj *par, DataObj *d, double x, double y, double s, 
		int which, FillDEF *fill, LineDEF *outline, int xc = -1, 
		int xr = -1, int yc = -1, int yr = -1, int sc = -1, int sr = -1);
	Bubble(int src);
	~Bubble();
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);

private:
	bool DoAutoscale(anyOutput *o);

	lfPOINT fPos;
	double fs;
	LineDEF BubbleLine, BubbleFillLine;
	FillDEF BubbleFill;
	POINT pts[5];
	POINT *ssRef;
	long cssRef;
};

class Bar:public GraphObj {
public:
	Bar(GraphObj *par, DataObj *d, double x, double y, int which, 
		int xc = -1, int xr = -1, int yc = -1, int yr = -1, char *desc = 0L);
	Bar(int src);
	~Bar();
	double GetSize(int select);
	bool SetSize(int select, double value);
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *target);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);

private:
	anyOutput *mo;
	RECT mrc;
	double size;
	LineDEF BarLine, HatchLine;
	FillDEF BarFill;
	lfPOINT fPos, BarBase;
	POINT *ssRef;
	long cssRef;
};

class DataLine:public GraphObj{
public:
	bool isPolygon, dirty;
	lfPOINT *Values;
	lfPOINT min, max;
	LineDEF LineDef;
	FillDEF pgFill;
	LineDEF pgFillLine;
	long nPnt, nPntSet, cp;
	DWORD BgColor;
	POINT *pts;
	char *ssXref, *ssYref;
	anyOutput *mo;
	RECT mrc;

	DataLine(GraphObj *par, DataObj *d, char *xrange=0L, char *yrange=0L, char *name=0L);
	DataLine(GraphObj *par, DataObj *d, lfPOINT *val, long nval, char *name);
	DataLine(int src);
	virtual ~DataLine();
	bool SetColor(int select, DWORD col);
	virtual void DoPlot(anyOutput *target);
	virtual void DoMark(anyOutput *o, bool mark);
	virtual bool Command(int cmd, void *tmpl, anyOutput *o);
	virtual bool PropertyDlg();
	virtual bool FileIO(int rw);

	void FileValues(char *name, int type, double start, double step);
	void SetValues();
	void LineData(lfPOINT *val, long nval);
	void DrawCurve(anyOutput *target);
	void DrawSpline(anyOutput *target);
};

class DataPolygon:public DataLine{
public:
	DataPolygon(GraphObj *par, DataObj *d, char *xrange=0L, char *yrange=0L, char *name=0L);
	DataPolygon(GraphObj *par, DataObj *d, lfPOINT *val, long nval, char *name = 0L);
	DataPolygon(int src);
	~DataPolygon();
	void DoPlot(anyOutput *target);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);
};

class RegLine:public GraphObj{
public:
	RegLine(GraphObj *par, DataObj *d, lfPOINT *values, long n, int type);
	RegLine(int src);
	~RegLine();
	double GetSize(int select);
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);

	void Recalc(lfPOINT *values, long n);
	LineDEF *GetLine(){return &LineDef;};

private:
	long nPoints, cp;
	double mx, my;
	LineDEF LineDef;
	fRECT lim, uclip;
	lfPOINT l1, l2, l3, l4, l5;
	DWORD BgColor;
	POINT *pts;
};

class SDellipse:public GraphObj{
public:
	SDellipse(GraphObj *par, DataObj *d, lfPOINT *values, long n, int sel);
	SDellipse(int src);
	~SDellipse();
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	void RegGO(void *n);
	bool FileIO(int rw);

	void Recalc(lfPOINT *values, long n);

private:
	long nPoints, cp;
	double sd1, sd2, mx, my;
	POINT *pts;
	LineDEF LineDef;
	fRECT lim;
	lfPOINT *val;
	RegLine *rl;
};

class ErrorBar:public GraphObj{
public:
	ErrorBar(GraphObj *par, DataObj *d, double x, double y, double err, int type,
		int xc=-1, int xr=-1, int yc=-1, int yr=-1, int ec=-1, int er=-1);
	ErrorBar(int src);
	~ErrorBar();
	bool SetSize(int select, double value);
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *target);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);

private:
	anyOutput *mo;
	RECT mrc;
	lfPOINT fPos;
	double ferr, SizeBar;
	POINT ebpts[6];
	LineDEF ErrLine;
	POINT *ssRef;
	long cssRef;
};

class Arrow:public GraphObj {
public:
	Arrow(GraphObj *par, DataObj *d, lfPOINT fp1, lfPOINT fp2, int which = 0,
		int xc1=-1, int xr1=-1, int yc1=-1, int yr1=-1, int xc2=-1, int xr2=-1,
		int yc2=-1, int yr2=-1);
	Arrow(int src);
	~Arrow();
	double GetSize(int select);
	bool SetSize(int select, double value);
	DWORD GetColor(int select){return LineDef.color;};
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);
	void * ObjThere(int x, int y);
	void Track(POINT *p, anyOutput *o);

private:
	anyOutput *mo;
	RECT mrc;
	dragHandle *dh1, *dh2;
	POINT pts[5];
	lfPOINT pos1, pos2;
	double cw, cl;
	LineDEF LineDef;
	POINT *ssRef;
	long cssRef;
	bool bModified;

	void Redraw(anyOutput *o);
};

class Box:public GraphObj {
public:
	Box(GraphObj *par, DataObj *d, lfPOINT fp1, lfPOINT fp2, int which, 
		int xc1=-1, int xr1=-1, int yc1=-1, int yr1=-1, int xc2=-1, int xr2=-1,
		int yc2=-1, int yr2=-1);
	Box(int src);
	~Box();
	double GetSize(int select);
	bool SetSize(int select, double value);
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);

private:
	anyOutput *mo;
	RECT mrc;
	double size;
	lfPOINT pos1, pos2;
	POINT pts[5];
	LineDEF Outline, Hatchline;
	FillDEF Fill;
	POINT *ssRef;
	long cssRef;
};

class Whisker:public GraphObj {
public:
	Whisker(GraphObj *par, DataObj *d, lfPOINT fp1, lfPOINT fp2, int which,
		int xc1=-1, int xr1=-1, int yc1=-1, int yr1=-1, int xc2=-1, int xr2=-1,
		int yc2=-1, int yr2=-1);
	Whisker(int src);
	~Whisker();
	bool SetSize(int select, double value);
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);

private:
	anyOutput *mo;
	RECT mrc;
	double size;
	POINT pts[6];
	lfPOINT pos1, pos2;
	LineDEF LineDef;
	POINT *ssRef;
	long cssRef;
};

class DropLine:public GraphObj{
public:
	DropLine(GraphObj *par, DataObj *d, double x, double y, int which, int xc = -1, 
		int xr = -1, int yc = -1, int yr = -1);
	DropLine(int src);
	~DropLine();
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);

private:
	lfPOINT fPos;
	POINT pts[4];
	LineDEF LineDef;
	POINT *ssRef;
	long cssRef;
	bool bModified;
};

class line_segment:public GraphObj{
public:
	line_segment(GraphObj *par, DataObj *d, LineDEF *ld, POINT3D *p1, POINT3D *p2);
	~line_segment();
	double GetSize(int select);
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	void * ObjThere(int x, int y);

private:
	LineDEF Line;
	POINT3D **ldata;
	fPOINT3D fmin, fmax;
	int *nldata, nli, ndf_go;
	double prop;
	bool bDrawDone;
	GraphObj *co, **df_go;

	void DoClip(GraphObj *co);
};

class sph_scanline:public GraphObj{
public:
	int rad;
	bool vert;

	sph_scanline(POINT3D *center, int radius, bool bVert);
	bool Command(int cmd, void *tmpl, anyOutput *o);

	void DoClip(GraphObj *co);
	bool GetPoint(POINT *p, int sel);

private:
	POINT3D p1, p2, cent;
	bool bValid1, bValid2;
};

class Sphere:public GraphObj{
public:
	Sphere(GraphObj *par, DataObj *d, int sel, double x, double y, double z, double r,
		int xc = -1, int xr = -1, int yc = -1, int yr = -1, int zc = -1, int zr = -1,
		int rc = -1, int rr = -1);
	Sphere(int src);
	~Sphere();
	double GetSize(int select);
	bool SetSize(int select, double value);
	DWORD GetColor(int select);
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);

private:
	int ix, iy, rx, ry, nscl;
	LineDEF Line;
	FillDEF Fill;
	fPOINT3D fPos, fip;
	double size;
	POINT *ssRef;
	long cssRef;
	GraphObj *co;
	bool bModified, bDrawDone;
	sph_scanline **scl;

	void DoClip(GraphObj *co);
	void DrawPG(anyOutput *o, int start);
};

class plane:public GraphObj{
public:
	plane(GraphObj *par, DataObj *d, fPOINT3D *pts, int nPts, LineDEF *line, 
		FillDEF *fill);
	~plane();
	double GetSize(int select);
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	void * ObjThere(int x, int y);

	bool GetPolygon(POINT3D **pla, int *npt, int sel);
	double *GetVec() {return PlaneVec;};

private:
	LineDEF Line;
	FillDEF Fill;
	double *PlaneVec;
	POINT3D **ldata, ReqPoint;
	int *nldata, nli, n_ipts, n_lines, n_linept;
	POINT *ipts;
	lfPOINT xBounds, yBounds, zBounds;
	bool bDrawDone, bReqPoint, bSigPol;
	GraphObj *co;
	line_segment **lines;
	long totalArea;

	void DoClip(GraphObj *co);
	bool IsValidPG(POINT3D *pg, int npg);
};

class Plane3D:public GraphObj {
public:
	Plane3D(GraphObj *par, DataObj *da, fPOINT3D *pt, long npt);
	Plane3D(int src);
	~Plane3D();
	bool SetSize(int select, double value);
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);

private:
	plane *ipl;
	fPOINT3D *dt, *pts;
	long ndt;
	LineDEF Line;
	FillDEF Fill;
};

class Brick:public GraphObj{
public:
	Brick(GraphObj *par, DataObj *da, double x, double y, double z, 
		double d, double w, double h, DWORD flags, int xc = -1,
		int xr = -1, int yc = -1, int yr = -1, int zc = -1, int zr = -1,
		int dc = -1, int dr = -1, int wc = -1, int wr = -1, int hc = -1,
		int hr = -1);
	Brick(int src);
	~Brick();
	bool SetSize(int select, double value);
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);

private:
	LineDEF Line;
	FillDEF Fill;
	fPOINT3D fPos;
	double depth, width, height;
	DWORD flags;
	POINT *ssRef;
	long cssRef;
	plane **faces;
	anyOutput *mo;
	RECT mrc;
	bool bModified;
};

class DropLine3D:public GraphObj{
public:
	DropLine3D(GraphObj *par, DataObj *d, fPOINT3D *p1, int xc = -1,
		int xr = -1, int yc = -1, int yr = -1, int zc = -1, int zr = -1);
	DropLine3D(int src);
	~DropLine3D();
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);

private:
	line_segment *ls[6];
	POINT mpts[6][2];
	LineDEF Line;
	fPOINT3D fPos;
	POINT *ssRef;
	long cssRef;
	bool bModified;
	anyOutput *mo;
	RECT mrc;
};

class Arrow3D:public GraphObj{
public:
	Arrow3D(GraphObj *par, DataObj *d, fPOINT3D *p1, fPOINT3D *p2, int xc1 = -1,
		int xr1 = -1, int yc1 = -1, int yr1 = -1, int zc1 = -1, int zr1 = -1, 
		int xc2 = -1, int xr2 = -1, int yc2 = -1, int yr2 = -1, int zc2 = -1, 
		int zr2 = -1);
	Arrow3D(int src);
	~Arrow3D();
	bool SetSize(int select, double value);
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);

private:
	line_segment *ls[3];
	plane *cap;
	double cw, cl;
	POINT mpts[3][2];
	LineDEF Line;
	fPOINT3D fPos1, fPos2;
	POINT *ssRef;
	long cssRef;
	bool bModified;
};

class Line3D:public GraphObj{
public:
	LineDEF Line;

	Line3D(GraphObj *par, DataObj *d, char *rx, char *ry, char *rz);
	Line3D(GraphObj *par, DataObj *d, fPOINT3D *pt, int n_pt, int xc1 = -1,
		int xr1 = -1, int yc1 = -1, int yr1 = -1, int zc1 = -1, int zr1 = -1, 
		int xc2 = -1, int xr2 = -1, int yc2 = -1, int yr2 = -1, int zc2 = -1, 
		int zr2 = -1);
	Line3D(int src);
	~Line3D();
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);

private:
	line_segment **ls;
	fPOINT3D *values, min, max;
	POINT *pts;
	long nPts, npts;
	char *x_range, *y_range, *z_range;
	POINT *ssRef;
	long cssRef;
	bool bModified;
	anyOutput *mo;
	RECT mrc;

	void DoUpdate();
};

class Label:public GraphObj{
public:
	Label(GraphObj *par, DataObj *d, double x, double y, TextDEF *td, DWORD flg,
		int xc = -1, int xr = -1, int yc = -1, int yr = -1, int tc = -1, int tr = -1);
	Label(int src);
	~Label();
	double GetSize(int select);
	bool SetSize(int select, double value);
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);
	void * ObjThere(int x, int y);
	void Track(POINT *p, anyOutput *o);

	bool CalcRect(anyOutput *o);
	void RedrawEdit(anyOutput *o);
	void ShowCursor(anyOutput *o);
	bool AddChar(int ci, anyOutput *o);
	void CalcCursorPos(int x, int y, anyOutput *o);
	void SetModified();
	void DoPlotText(anyOutput *o);
	bool CheckMark();
	TextDEF *GetTextDef(){return &TextDef;};

private:
	lfPOINT fPos, fDist;
	double si, csi, curr_z;
	DWORD flags, bgcolor;
	TextDEF TextDef;
	LineDEF bgLine;
	int ix, iy, m1, m2, CursorPos;
	bool is3D;
	RECT Cursor, rm1, rm2;
	POINT pts[5];
	POINT *ssRef;
	long cssRef;
	anyOutput *defDisp;
	bool bModified, bBGvalid;
};

class mLabel:public GraphObj{
public:
	mLabel(GraphObj *, DataObj *, double, double, TextDEF *, char *, int, DWORD);
	mLabel(GraphObj *, DataObj *, double, double, TextDEF *, char *);
	mLabel(int src);
	~mLabel();
	double GetSize(int select);
	bool SetSize(int select, double value);
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	void RegGO(void *n);
	bool FileIO(int rw);
	void Track(POINT *p, anyOutput *o);

private:
	lfPOINT fPos, fDist, cPos, cPos1, dist;
	double si, csi, curr_z, lspc;
	DWORD flags, undo_flags;
	TextDEF TextDef;
	long nLines;
	int cli;
	bool is3D;
	Label **Lines;
};

class TextFrame:public GraphObj{
	enum {TF_MAXLINE=120};
public:
	TextFrame(GraphObj *parent, DataObj *data, lfPOINT *p1, lfPOINT *p2, char *txt);
	TextFrame(int src);
	~TextFrame();
	double GetSize(int select);
	bool SetSize(int select, double value);
	void DoMark(anyOutput *o, bool mark);
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);
	void * ObjThere(int x, int y);
	void Track(POINT *p, anyOutput *o);

private:
	fRECT pad;
	RECT ipad, Cursor, *tm_rec;
	fmtText fmt_txt;
	int nlines, linc, tm_c, csize, cpos;
	bool bModified, bResize, has_m1, has_m2;
	unsigned char c_char, m1_char, m2_char;
	double lspc;
	lfPOINT pos1, pos2;
	POINT cur_pos, m1_pos, m2_pos, m1_cpos, m2_cpos;
	TextDEF TextDef;
	dragRect *drc;
	unsigned char *text, **lines;
	LineDEF Line, FillLine;
	FillDEF Fill;

	void text2lines(anyOutput *o);
	void lines2text();
	void ShowCursor(anyOutput *o);
	void AddChar(anyOutput *o, int c);
	void DelChar(anyOutput *o);
	void CalcCursorPos(int x, int y, anyOutput *o);
	void ReplMark(anyOutput *o, char *ntext);
	void procTokens();
	bool DoPaste(anyOutput *o);
	void TextMark(anyOutput *o, int mode);
	bool CopyText(anyOutput *o, bool b_cut);
};

class segment:public GraphObj{
public:
	segment(GraphObj *par, DataObj *d, lfPOINT *c, double r1, double r2, double a1, double a2);
	segment(int src);
	~segment();
	bool SetSize(int select, double value);
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);
	void * ObjThere(int x, int y);
	void Track(POINT *p, anyOutput *o);

private:
	lfPOINT fCent;
	long nPts;
	double radius1, radius2, angle1, angle2, shift;
	LineDEF segLine, segFillLine;
	FillDEF segFill;
	POINT *pts;
	bool bModified;
	anyOutput *mo;
	RECT mrc;
};

class polyline:public GraphObj {
public:
	dragHandle **pHandles;
	lfPOINT *Values;
	long nPoints, nPts;
	POINT *pts;
	LineDEF pgLine, pgFillLine;
	FillDEF pgFill;
	bool bModified;

	polyline(GraphObj *par, DataObj *d, lfPOINT *fpts, int cpts);
	polyline(int src);
	virtual ~polyline();
	double GetSize(int select);
	bool SetSize(int select, double value);
	DWORD GetColor(int select);
	virtual void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	virtual bool PropertyDlg();
	virtual bool FileIO(int rw);
	void * ObjThere(int x, int y);
	void Track(POINT *p, anyOutput *o);

private:
	void ShowPoints(anyOutput *o);
};

class Bezier:public polyline {
public:
	Bezier(GraphObj *par, DataObj *d, lfPOINT *fpts, int cpts, int mode, double res);
	Bezier(int src);
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool FileIO(int rw);

private:
	void AddPoints(int n, lfPOINT *p);

	void FitCurve(lfPOINT *d, int npt, double error);
	void IpolBez(lfPOINT *d, lfPOINT tHat1, lfPOINT tHat2);
	void FitCubic(lfPOINT *d, int first, int last, lfPOINT tHat1, lfPOINT tHat2, double error);
	void RemovePoint(lfPOINT *d, int sel);
	void GenerateBezier(lfPOINT *d, int first, int last, double * uPrime, lfPOINT tHat1, lfPOINT tHat2, lfPOINT *bezCurve);
	double *Reparameterize(lfPOINT *d, int first, int last, double *u, lfPOINT *bezCurve);
	lfPOINT fBezier(int degree, lfPOINT *V, double t);
	double *ChordLengthParameterize(lfPOINT *d, int first, int last);
	double ComputeMaxError(lfPOINT *d, int first, int last, lfPOINT *bezCurve, double *u, int *splitPoint);
};

class polygon:public polyline {
public:
	polygon(GraphObj *par, DataObj *d, lfPOINT *fpts, int cpts);
	polygon(int src):polyline(src){};
	bool PropertyDlg();
};

class rectangle:public GraphObj {
public:
	lfPOINT fp1, fp2;
	LineDEF Line, FillLine;
	FillDEF Fill;
	double rad;
	bool bModified;

	rectangle(GraphObj *par, DataObj *d, lfPOINT *p1, lfPOINT *p2);
	rectangle(int src);
	virtual ~rectangle();
	double GetSize(int select);
	bool SetSize(int select, double value);
	DWORD GetColor(int select){return Line.color;};
	void DoMark(anyOutput *o, bool mark);
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);
	void * ObjThere(int x, int y);
	void Track(POINT *p, anyOutput *o);

private:
	POINT *pts;
	long nPts;
	dragRect *drc;
	void PlotRoundRect(anyOutput *o);
};

class ellipse:public rectangle {
public:
	ellipse(GraphObj *par, DataObj *d, lfPOINT *p1, lfPOINT *p2);
	ellipse(int src);
};

class roundrec:public rectangle {
public:
	roundrec(GraphObj *par, DataObj *d, lfPOINT *p1, lfPOINT *p2);
	roundrec(int src);
};

class LegItem:public GraphObj{
public:
	DWORD flags;

	LegItem(GraphObj *par, DataObj *d, LineDEF *ld, LineDEF *lf, FillDEF *fill, char *desc);
	LegItem(GraphObj *par, DataObj *d, LineDEF *ld, Symbol *sy);
	LegItem(GraphObj *par, DataObj *d, LineDEF *ld, int err, char *desc);
	LegItem(int src);
	~LegItem();
	double GetSize(int select);
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	void RegGO(void *n);
	bool FileIO(int rw);
	void Track(POINT *p, anyOutput *o);

	bool HasFill(LineDEF *ld, FillDEF *fd, char *desc);
	bool HasSym(LineDEF *ld, GraphObj *sy);
	bool HasErr(LineDEF *ld, int err);

private:
	LineDEF DataLine, OutLine, HatchLine;
	FillDEF Fill;
	Symbol *Sym;
	Label *Desc;
	RECT hcr;

	void DefDesc(char *txt);
};

class Legend:public GraphObj{
public:
	Legend(GraphObj *par, DataObj *d);
	Legend(int src);
	~Legend();
	double GetSize(int select);
	bool SetSize(int select, double value);
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	void RegGO(void *n);
	bool FileIO(int rw);
	void Track(POINT *p, anyOutput *o);

	bool HasFill(LineDEF *ld, FillDEF *fd, char *desc);
	bool HasSym(LineDEF *ld, GraphObj *sy, char *desc);
	bool HasErr(LineDEF *ld, int err, char *desc);

private:
	lfPOINT pos, lb_pos;
	RECT trc;
	anyOutput *to;
	fRECT B_Rect, C_Rect, D_Rect, E_Rect, F_Rect;
	long nItems;
	bool hasLine;
	LegItem **Items;
};

class Plot:public GraphObj{
public:
	fRECT Bounds;					//contains minima and maxima for x and y
	bool dirty;						//rescale before redraw;
	int use_xaxis, use_yaxis, use_zaxis;		//this plot uses its own axes
	lfPOINT xBounds, yBounds, zBounds;	//like Bounds but in 3D space
	int hidden;						//plot (layer) is not visible
	int x_dtype, y_dtype, z_dtype;	//data types
	char *x_info, *y_info, *z_info;	//descriptor used e.g. for axis label or legend
	char *data_desc;				//descriptor for data, used for legend etc
	TextValue *x_tv, *y_tv;			//TextValue object for ordinal axes

	Plot(GraphObj *par, DataObj *d);
	~Plot(){return;};
	virtual double GetSize(int select);
	virtual bool SetSize(int select, double value){return false;};
	virtual DWORD GetColor(int select);
	virtual bool SetColor(int select, DWORD col){return false;};
	virtual void DoPlot(anyOutput *o){return;};
	virtual bool Command(int cmd, void *tmpl, anyOutput *o){return false;};
	virtual bool PropertyDlg(){return false;};
	virtual void RegGO(void *n){return;};
	virtual bool FileIO(int rw) {return false;};

	void CheckBounds(double x, double y);
	bool UseAxis(int idx);
	void ApplyAxes(anyOutput *o);
	void CheckBounds3D(double x, double y, double z);
	bool SavVarObs(GraphObj **gol, long ngo, DWORD flags);
	DataObj *CreaCumData(char *xr, char *yr, int mode, double base);
};

class PlotScatt:public Plot{
public:
	char *xRange, *yRange;
	long nPoints;
	int DefSym;
	lfPOINT BarDist;
	Bar **Bars;
	Symbol **Symbols;
	DataLine *TheLine;
	ErrorBar **Errors;
	Label **Labels;

	PlotScatt(GraphObj *par, DataObj *d, DWORD presel);
	PlotScatt(GraphObj *par, DataObj *d, int cBars, Bar **bars, ErrorBar **errs);
	PlotScatt(GraphObj *par, DataObj *d, int nPts, Symbol **sym, DataLine *lin);
	PlotScatt(int src);
	virtual ~PlotScatt();
	double GetSize(int select);
	bool SetSize(int select, double value);
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *target);
	virtual bool Command(int cmd, void *tmpl, anyOutput *o);
	virtual bool PropertyDlg();
	void RegGO(void *n);
	virtual bool FileIO(int rw);

	bool ForEach(int cmd, void *tmp, anyOutput *o);

private:
	DWORD DefSel;
	char *ErrRange, *LbRange;
	Arrow **Arrows;
	DropLine **DropLines;

	bool CreateBarChart();
};

class xyStat:public PlotScatt{
public:
	xyStat(GraphObj *par, DataObj *d);
	xyStat(int src);
	~xyStat();
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	virtual bool FileIO(int rw);

	void CreateData();

private:
	double ci;
	DataObj *curr_data;
	char *case_prefix;

};

class BarChart:public PlotScatt{
public:
	BarChart(GraphObj *par, DataObj *d);
};

class FreqDist:public Plot {
public:
	FreqDist(GraphObj *par, DataObj *d);
	FreqDist(GraphObj *par, DataObj *d, char* range, bool bOnce);
	FreqDist(GraphObj *par, DataObj *d, double *vals, int nvals, int nclasses);
	FreqDist(int src);
	~FreqDist();
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	void RegGO(void *n);
	bool FileIO(int rw);

private:
	double dmin, dmax, start, step;
	long nPlots;
	char *ssRef;
	LineDEF BarLine, HatchLine;
	FillDEF BarFill;
	DataObj *curr_data;
	GraphObj **plots;

	void ProcData(int sel);
};

class Regression:public Plot{
public:
	Regression(GraphObj *par, DataObj *d);
	Regression(int src);
	~Regression();
	double GetSize(int select);
	bool SetSize(int select, double value);
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *target);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	void RegGO(void *n);
	bool FileIO(int rw);

private:
	long nPoints;
	char *xRange, *yRange;
	Symbol **Symbols;
	RegLine *rLine;
	SDellipse *sde;

	void Recalc();
};

class BubblePlot:public Plot{
public:
	BubblePlot(GraphObj *par, DataObj *d);
	BubblePlot(int src);
	~BubblePlot();
	void DoPlot(anyOutput *target);
	DWORD GetColor(int select);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	void RegGO(void *n);
	bool FileIO(int rw);

private:
	long nPoints;
	LineDEF BubbleLine, BubbleFillLine;
	FillDEF BubbleFill;
	Bubble **Bubbles;
};

class PolarPlot:public Plot{
public:
	PolarPlot(GraphObj *par, DataObj *d);
	PolarPlot(int src);
	~PolarPlot();
	double GetSize(int select);
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	void RegGO(void *n);
	bool FileIO(int rw);

	bool AddPlot();
	bool Config();

private:
	int nPlots, nAxes;
	double offs;
	anyOutput *CurrDisp;
	fRECT CurrRect;
	LineDEF FillLine;
	FillDEF Fill;
	Plot **Plots;
	GraphObj **Axes;			//Axis not yet defined
};

class BoxPlot:public Plot {
public:
	BoxPlot(GraphObj *par, DataObj *d);
	BoxPlot(int src);
	BoxPlot(GraphObj *par, DataObj *dt, int mode, int c1, int c2, int c3, char *box_name);
	~BoxPlot();
	double GetSize(int select);
	bool SetSize(int select, double value);
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	void RegGO(void *n);
	bool FileIO(int rw);

	bool ForEach(int cmd, void *tmp, anyOutput *o);
	void CreateData();

private:
	char *xRange, *yRange, *case_prefix;
	long nPoints;
	double ci_box, ci_err;
	DataObj *curr_data;
	lfPOINT BoxDist;
	Box **Boxes;
	Whisker **Whiskers;
	Symbol **Symbols;
	Label **Labels;
	DataLine *TheLine;
};

class DensDisp:public Plot {
public:
	DensDisp(GraphObj *par, DataObj *d);
	DensDisp(int src);
	~DensDisp();
	bool SetSize(int select, double value);
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	void RegGO(void *n);
	bool FileIO(int rw);

private:
	LineDEF DefLine, DefFillLine;
	FillDEF DefFill;
	long nPoints;
	char *xRange, *yRange;
	Box **Boxes;

	void DoUpdate();

};

class StackBar:public Plot{
public:
	int numPlots, numXY, numPG, numPL;
	BoxPlot **Boxes;
	PlotScatt **xyPlots;
	DataPolygon **Polygons;
	DataLine **Lines;
	lfPOINT dspm;

	StackBar(GraphObj *par, DataObj *d);
	StackBar(int src);
	virtual ~StackBar();
	bool SetSize(int select, double value);
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	void RegGO(void *n);
	bool FileIO(int rw);

private:
	char *ssXrange, *ssYrange;
	double StartVal;
	int cum_data_mode;
	DataObj *CumData;
};

class StackPG:public StackBar{
public:
	StackPG(GraphObj *par, DataObj *d);
};

class GroupBars:public StackBar{
public:
	GroupBars(GraphObj *par, DataObj *d, int type):StackBar(par, d){mode = type;};
	bool PropertyDlg();

private:
	int mode;
};

class Waterfall:public StackBar{
public:
	Waterfall(GraphObj *par, DataObj *d);
	bool PropertyDlg();
};

class MultiLines:public StackBar{
public:
	MultiLines(GraphObj *par, DataObj *d);
	bool PropertyDlg();
};

class PieChart:public Plot {
public:
	PieChart(GraphObj *par, DataObj *d);
	PieChart(int src);
	virtual ~PieChart();
	bool SetSize(int select, double value);
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	void RegGO(void *n);
	bool FileIO(int rw);
	void DoUpdate();

private:
	long nPts;
	char *ssRefA, *ssRefR;
	lfPOINT CtDef;
	double FacRad;
	segment **Segments;
};

class RingChart:public PieChart {
public:
	RingChart(GraphObj *par, DataObj *d);
};

class GoGroup:public Plot {
public:
	GraphObj **Objects;
	int nObs;
	lfPOINT fPos;

	GoGroup(GraphObj *par, DataObj *d);
	GoGroup(int src);
	virtual ~GoGroup();
	double GetSize(int select);
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	void RegGO(void *n);
	bool FileIO(int rw);
};

class StarChart:public GoGroup {
public:
	StarChart(GraphObj *par, DataObj *d);
	bool PropertyDlg();

private:
};

class Ribbon:public Plot {
public:
	Ribbon(GraphObj *par, DataObj *d, double z, double width, char *xr, char *yr);
	Ribbon(GraphObj *par, DataObj *d, int which, char *xr, char *yr, char *zr);
	Ribbon(GraphObj *par, DataObj *d, GraphObj **go, int ngo);
	Ribbon(int src);
	~Ribbon();
	double GetSize(int select);
	bool SetSize(int select, double value);
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	void RegGO(void *n);
	bool FileIO(int rw);

private:
	long nPlanes, nVal;
	double z_value, z_width, relwidth;
	char *ssRefX, *ssRefY, *ssRefZ;
	FillDEF Fill;
	LineDEF Line;
	fPOINT3D *values;
	Plane3D **planes;

	void CreateObs();
	void UpdateObs(bool bNewData);
};

class Grid3D:public Plot {
public:
	Grid3D(GraphObj *par, DataObj *d, int sel, double x1=0.0, double xstep=1.0, double z1=0.0, double zstep=1.0);
	Grid3D(int src);
	~Grid3D();
	bool SetSize(int select, double value);
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	void RegGO(void *n);
	bool FileIO(int rw);

	void CreateObs(bool set_undo);

private:
	long nLines, nPlanes;
	fPOINT3D start, step;
	LineDEF Line;
	FillDEF Fill;
	Line3D **lines;
	Plane3D **planes;

	bool Configure();
};

class Scatt3D:public Plot{
public:
	Scatt3D(GraphObj *par, DataObj *d, DWORD flags);
	Scatt3D(GraphObj *par, DataObj *d, Brick **cols, long nob);
	Scatt3D(GraphObj *par, DataObj *d, Sphere **ba, long nob);
	Scatt3D(int src);
	~Scatt3D();
	double GetSize(int select);
	bool SetSize(int select, double value);
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	void RegGO(void *n);
	bool FileIO(int rw);

private:
	long nBalls, nColumns, nDropLines, nArrows;
	DWORD c_flags;
	char *ssRefX, *ssRefY, *ssRefZ;
	Line3D *Line;
	Sphere **Balls;
	Brick **Columns;
	DropLine3D **DropLines;
	Arrow3D **Arrows;
	Ribbon *rib;
};

class Limits:public Plot {
public:
	Limits(int src);
	~Limits();
	double GetSize(int select);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool FileIO(int rw);
};

class Function:public Plot{
public:
	Function(GraphObj *par, DataObj *d, char *desc);
	Function(int src);
	~Function();
	bool SetSize(int select, double value);
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	void RegGO(void *n);
	bool FileIO(int rw);

	bool Update(anyOutput *o, DWORD flags);
	LineDEF *GetLine() {return &Line;};

private:
	double x1,x2, xstep;
	LineDEF Line;
	char *param;
	char *cmdxy;
	DataLine *dl;
};

class FitFunc:public Plot{
public:
	FitFunc(GraphObj *par, DataObj *d);
	FitFunc(int src);
	~FitFunc();
	bool SetSize(int select, double value);
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	void RegGO(void *n);
	bool FileIO(int rw);

private:
	double x1, x2, xstep, conv, chi2;
	char *ssXref, *ssYref;
	long nPoints;
	int maxiter;
	LineDEF Line;
	Symbol **Symbols;
	char *cmdxy, *parxy;
	Function *dl;
};

class NormQuant:public Plot{
public:
	NormQuant(GraphObj *par, DataObj *d, char* range);
	NormQuant(GraphObj *par, DataObj *d, double *data, int ndata);
	NormQuant(int src);
	~NormQuant();
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);

private:
	char *ssRef;
	int nData, nValidData;
	double *x_vals, *y_vals, *src_data;
	Symbol *sy;

	bool ProcessData();
};

	
class GridLine:public GraphObj{
public:
	DWORD flags;
	long ncpts;
	POINT pts[6], *cpts;
	LineDEF LineDef;
	POINT3D *gl1, *gl2, *gl3;
	line_segment **ls;
	bool bModified;
	anyOutput *mo;
	RECT mrc;

	GridLine(GraphObj *par, DataObj *d, int type, DWORD df);
	GridLine(int src);
	virtual ~GridLine();
	virtual void DoPlot(anyOutput *o);
	virtual void DoMark(anyOutput *o, bool mark);
	virtual bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	bool FileIO(int rw);
};

class GridLine3D:public GridLine {
public:
	GridLine3D(GraphObj *par, DataObj *d, int type, DWORD df);
	GridLine3D(int src);
	~GridLine3D();
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
};

class GridRadial:public GridLine {
public:
	GridRadial(GraphObj *par, DataObj *d, int type, DWORD df);
	GridRadial(int src);
	~GridRadial();
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
};

class Tick:public GraphObj{
public:
	Tick(GraphObj *par, DataObj *d, double val, DWORD Flags);
	Tick(int src);
	~Tick();
	double GetSize(int select);
	bool SetSize(int select, double value);
	bool SetColor(int select, DWORD col);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	void RegGO(void *n);
	bool FileIO(int rw);
	void Track(POINT *p, anyOutput *o);

	void DoPlot(double six, double csx, anyOutput *o);
	bool ProcSeg();
	
private:
	double value, size, fix, fiy, fiz, lsi, lcsi, angle, lbx, lby;
	int n_seg, s_seg;
	double *seg;
	bool bModified, bValidTick;
	long numPG;
	anyOutput *mo;
	RECT mrc;
	int gl_type;
	GridLine *Grid;
	Label *label;
	DataPolygon **Polygons;
	DWORD flags;
	POINT pts[2];
	line_segment *ls;

	bool CmpPoints(double x1, double y1, double x2, double y2);
	bool StoreSeg(lfPOINT *line);
};

class Axis:public GraphObj{
public:
	AxisDEF *axis;
	LineDEF axline;
	TextValue *atv;
	long NumTicks;
	Tick **Ticks;

	Axis(GraphObj *par, DataObj *d, AxisDEF *ax, DWORD flags);
	Axis(int src);
	~Axis();
	double GetSize(int select);
	bool SetSize(int select, double value);
	DWORD GetColor(int select);
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	void RegGO(void *n);
	bool FileIO(int rw);
	void *ObjThere(int x, int y);
	void Track(POINT *p, anyOutput *o);

	AxisDEF *GetAxis() {return axis;};
	bool GetValuePos(double val, double *fix, double *fiy, double *fiz, anyOutput *o);
	void TickFile(char *name);
	void BreakSymbol(POINT3D *p1, double dsi, double dcsi, bool connect, anyOutput *o);
	void DrawBreaks(anyOutput *o);
	void CreateTicks();
	DWORD GradColor(double value);

private:
	double sizAxLine, sizAxTick, sizAxTickLabel;
	double si, csi;
	double brksymsize, brkgap, tick_angle;
	int brksym, nl_segs, gl_type, tick_type, grad_type;
	bool bModified;
	DWORD colAxis, gCol_0, gCol_1, gCol_2, gTrans;
	LineDEF GridLine;
	GraphObj *axisLabel;
	POINT pts[2], gradient_box[5];
	POINT3D pts3D[2];
	fPOINT3D flim[2];
	lfPOINT lbdist, tlbdist;
	TextDEF tlbdef;
	anyOutput *drawOut, *scaleOut;
	line_segment **l_segs;
	char *ssMATval, *ssMATlbl, *ssMITval; 
	anyOutput *mo;
	RECT mrc;

	void SetTick(long idx, double val, DWORD flags, char *txt);
	void mkTimeAxis();
	void ManuTicks(double sa, double st, int n, DWORD flags);
	void UpdateTicks();
	bool ssTicks();
	void GradientBar(anyOutput *o);
};

class ContourPlot:public Plot {
public:
	ContourPlot(GraphObj *par, DataObj *d);
	ContourPlot(int src);
	~ContourPlot();
	bool SetSize(int select, double value);
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	void RegGO(void *n);
	bool FileIO(int rw);

private:
	char *ssRefX, *ssRefY, *ssRefZ;
	Symbol **Symbols;
	Label **Labels;
	long nval, nSym, nLab;
	DWORD flags;
	double sr_zval;
	fPOINT3D *val;
	AxisDEF z_axis;
	Axis *zAxis;

	bool LoadData(char *xref, char *yref, char *zref);
	bool DoTriangulate();
	bool DoAxis(anyOutput *o);
	void DoSymbols(Triangle *trl);
};

class Plot3D:public Plot{
	typedef struct {
		double Zmin, Zmax;
		GraphObj *go;
		}obj_desc;
public:
	long nPlots, nAxes;
	Axis **Axes;
	GraphObj **plots, **Sc_Plots;
	double *RotDef;
	fPOINT3D cub1, cub2, rotC;
	int nscp;

	Plot3D(GraphObj *par, DataObj *d, DWORD flags);
	Plot3D(int src);
	virtual ~Plot3D();
	double GetSize(int select);
	bool SetColor(int select, DWORD col);
	void DoPlot(anyOutput *o);
	void DoMark(anyOutput *o, bool mark);
	virtual bool Command(int cmd, void *tmpl, anyOutput *o);
	virtual bool PropertyDlg();
	virtual void RegGO(void *n);
	virtual bool FileIO(int rw);

	void * ObjThere(int x, int y);
	void Track(POINT *p, anyOutput *o);
	void CreateAxes();
	void DoAutoscale();
	void CalcRotation(double dx, double dy, anyOutput *o, bool accept);
	bool AcceptObj(GraphObj *go);
	void SortObj();
	bool Rotate(double dx, double dy, double dz, anyOutput *o, bool accept);
	bool AddAxis();

private:
	long nObs, nmaxObs;
	DWORD crea_flags;
	Drag3D *drag;
	fPOINT3D cu1, cu2, rc;
	obj_desc **dispObs;

	bool AddPlot(int family);
	int cmp_obj_desc(obj_desc *obj1, obj_desc *obj2);
};

class Chart25D:public Plot3D {
public:
	Chart25D(GraphObj *par, DataObj *d, DWORD flags);
	~Chart25D();
	bool PropertyDlg();

private:
	fPOINT3D dspm;
};

class Ribbon25D:public Plot3D {
public:
	Ribbon25D(GraphObj *par, DataObj *d, DWORD flags);
	~Ribbon25D();
	bool PropertyDlg();

private:
	fPOINT3D dspm;
};

class BubblePlot3D:public Plot3D {
public:
	BubblePlot3D(GraphObj *par, DataObj *d);
	~BubblePlot3D();
	bool PropertyDlg();
};

class Func3D:public Plot3D {
public:
	Func3D(GraphObj *par, DataObj *d);
	Func3D(int src);
	~Func3D();
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	void RegGO(void *n);
	bool FileIO(int rw);

private:
	bool Update();

	double x1, x2, xstep, z1, z2, zstep;
	LineDEF Line;
	FillDEF Fill;
	char *param, *cmdxy;
	DataObj *gda;
	Grid3D  *gob;
};

class FitFunc3D:public Plot3D {
public:
	FitFunc3D(GraphObj *par, DataObj *d);
	FitFunc3D(int src);
	~FitFunc3D();
	bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	void RegGO(void *n);
	bool FileIO(int rw);

private:
	bool Update();

	double x1, x2, xstep, z1, z2, zstep, conv, chi2;
	char *ssXref, *ssYref, *ssZref;
	int maxiter;
	LineDEF Line;
	FillDEF Fill;
	char *param, *cmdxy;
	DataObj *gda;
	Grid3D  *gob;
};

class Graph:public GraphObj{
public:
	long NumPlots;
	int ToolMode, units, nscp;
	anyOutput *Disp, *CurrDisp;
	fRECT GRect, DRect, Bounds;
	bool OwnDisp, bModified;
	fRECT CurrRect;
	GraphObj **Plots, *PasteObj;
	DWORD ColBG, ColAX;
	GraphObj **Sc_Plots;
	Axis **Axes;
	char *filename;

	Graph(GraphObj *par, DataObj *d, anyOutput *o, int style);
	Graph(int src);
	virtual ~Graph();
	double GetSize(int select);
	bool SetSize(int select, double value);
	DWORD GetColor(int select);
	bool SetColor(int select, DWORD col);
	virtual void DoPlot(anyOutput *o);
	virtual bool Command(int cmd, void *tmpl, anyOutput *o);
	bool PropertyDlg();
	void RegGO(void *n);
	virtual bool FileIO(int rw);
	virtual double DefSize(int select);
	bool hasTransp();

private:
	int NumAxes, AxisTempl, tickstyle, zoom_level;
	double scale;
	RECT rcDim, rcUpd, rc_mrk;
	DWORD ColDR, ColGR, ColGRL;
	AxisDEF x_axis, y_axis;
	FrmRect *frm_g, *frm_d;
	bool dirty, bDialogOpen;
	POINT *tl_pts;
	long tl_nPts;
	ZoomDEF *zoom_def;

	bool AddPlot(int family);
	void DoAutoscale();
	void CreateAxes(int templ);
	bool ExecTool(MouseEvent *mev);
	bool Configure();
	bool AddAxis();
	bool MoveObj(int cmd, GraphObj *g); 
	bool DoZoom(char *z);
	bool DoScale(scaleINFO *sc, anyOutput *o);
};

class Page:public Graph{
public:
	Page(GraphObj *par, DataObj *d);
	Page(int src);
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);
	void RegGO(void *n);
	bool FileIO(int rw);
	double DefSize(int select);

private:
	LineDEF LineDef;
	FillDEF FillDef;

	bool Configure();
};

class ObjTree:public GraphObj {
public:
	ObjTree(GraphObj *par, DataObj *d, GraphObj *root);
	~ObjTree();
	void DoPlot(anyOutput *o);
	bool Command(int cmd, void *tmpl, anyOutput *o);

	anyOutput *CreateBitmap(int *w, int *h, anyOutput *tmpl);
	int count_lines(){ return count;};
	char *get_name(int line);
	int get_vis(int line);
	bool set_vis(int line, bool vis);
	GraphObj *get_obj(int line);

private:
	GraphObj **list, *base;
	int count, maxcount;
	TextDEF TextDef;
};

class notary{
public:
	notary();
	~notary();
	int RegisterGO(GraphObj *go);
	void AddRegGO(GraphObj *go);
	bool PushGO(unsigned int id, GraphObj *go);
	GraphObj *PopGO(unsigned int id);
	void FreeStack();

private:
	unsigned int NextPopGO, NextPushGO, NextRegGO;
	GraphObj ***gObs;
	GraphObj ***goStack;
};

class Default{
public:
	int dUnits, cUnits, iMenuHeight;
	char DecPoint[2], ColSep[2];
	char *svgAttr, *svgScript, *currPath, *IniFile;
	char *File1, *File2, *File3, *File4, *File5, *File6;
	char *fmt_date, *fmt_time, *fmt_datetime;
	double min4log, ss_txt;
	RECT clipRC;

	Default();
	~Default();
	void SetDisp(anyOutput *o);
	double GetSize(int select);
	DWORD Color(int select);
	LineDEF *GetLine();
	void SetLine(int u, LineDEF *l, int which);
	FillDEF *GetFill();
	void SetFill(int u, FillDEF *fd);
	LineDEF *GetOutLine();
	bool PropertyDlg();
	LineDEF *plLineDEF(LineDEF *ld);
	LineDEF *pgLineDEF(LineDEF *ol);
	FillDEF *pgFillDEF(FillDEF *fd);
	double rrectRad(double rad);
	void FileHistory(char *path);
	void Idle(int cmd);
	void UpdRect(anyOutput *o, int x1, int y1, int x2, int y2);
	void UpdAdd(anyOutput * o, int x, int y);

private:
	LineDEF Line_0, Line_1, Line_2, *pl, *pgl;
	FillDEF Fill_0, Fill_1, Fill_2, *pg;
	LineDEF FillLine_0, FillLine_1, FillLine_2, *pg_fl;
	LineDEF OutLine_0, OutLine_1, OutLine_2;
	double *rrect_rad;
	anyOutput *cdisp, *out_upd;
	RECT rec_upd;
	bool can_upd;
	DWORD axis_color;
};

class DefsRW:public GraphObj{
public:
	DefsRW():GraphObj(0, 0){Id = 0; return;};
	DefsRW(int rw):GraphObj(0,0){FileIO(rw);Id=GO_DEFRW;return;};
	~DefsRW() {return;};
	bool FileIO(int rw);
};

class ReadCache{
public:
	unsigned char last, *Cache, Line[4096];
	int iFile, idx, max;
	bool eof;

	ReadCache();
	~ReadCache();
	virtual bool Open(char *name);
	virtual void Close();
	virtual unsigned char Getc();
	virtual unsigned char *GetField();
	void ReadLine(char *dest, int size);
	bool GetInt(long *in);
	bool GetFloat(double *fn);
	unsigned char Lastc();
	bool IsEOF();
};

class MemCache:public ReadCache{
public:
	MemCache(unsigned char *ptr);
	~MemCache();
	bool Open(char *name){return false;};
	void Close(){return;};
	unsigned char Getc();
	unsigned char *GetField();
};

#define UNDO_CONTINUE 0x01
#define UNDO_STORESET 0x1000
class UndoObj {
	enum {UNDO_UNDEFINED, UNDO_DEL_GO, UNDO_GOLIST, UNDO_DROPMEM,
		UNDO_VALDWORD, UNDO_VALINT, UNDO_VALLONG, UNDO_OBJCONF, UNDO_OBJCONF_1,
		UNDO_LFP, UNDO_POINT, UNDO_VOIDPTR, UNDO_MOVE, UNDO_RECT,
		UNDO_STRING, UNDO_ROTDEF, UNDO_SETGO, UNDO_LINEDEF, UNDO_FILLDEF,
		UNDO_AXISDEF, UNDO_LFP3D, UNDO_FLOAT, UNDO_MEM, UNDO_MUTATE, 
		UNDO_DROPGOLIST, UNDO_TEXTDEF, UNDO_SAVVAR, UNDO_DATA, UNDO_ET, UNDO_TEXTBUF};
	typedef struct _UndoInfo {
		int cmd;
		DWORD flags;
		GraphObj *owner;
		void *data;
		void **loc;
		ZoomDEF zd;
		}UndoInfo;

	typedef struct _UndoList {
		void *array;
		void **loc_arr;
		long count, size;
		long *loc_count;
		}UndoList;

	typedef struct _UndoBuff {
		int count;
		UndoInfo **buff;
		anyOutput *disp;
		}UndoBuff;

	typedef struct _EtBuff {
		char *txt;
		DataObj *DaO;
		int *cur, *m1, *m2, vcur, vm1, vm2, row, col;
		}EtBuff;

	typedef struct _TextBuff {
		int *psize, size, *ppos, pos;
		unsigned char **pbuff, *buff;
		}TextBuff;

public:
	int *pcb;
	anyOutput *cdisp, *ldisp;
	bool busy;

	UndoObj();
	~UndoObj();
	void Flush();
	bool isEmpty(anyOutput *o);
	void SetDisp(anyOutput *o);
	void KillDisp(anyOutput *o);
	void InvalidGO(GraphObj *go);
	void Pop(anyOutput *o);
	void Restore(bool redraw, anyOutput *o);
	void ListGOmoved(GraphObj **oldlist, GraphObj **newlist, long size);
	void DeleteGO(GraphObj **go, DWORD flags, anyOutput *o);
	void MutateGO(GraphObj **old, GraphObj *repl, DWORD flags, anyOutput *o);
	void StoreListGO(GraphObj *parent, GraphObj ***go, long *count, DWORD flags);
	void DropListGO(GraphObj *parent, GraphObj ***go, long *count, DWORD flags);
	void DropMemory(GraphObj *parent, void **mem, DWORD flags);
	void SavVarBlock(GraphObj *parent, void **mem, DWORD flags);
	void ValDword(GraphObj *parent, DWORD *val, DWORD flags);
	void Point(GraphObj *parent, POINT *pt, anyOutput * o, DWORD flags);
	void VoidPtr(GraphObj *parent, void **pptr, void *ptr, anyOutput * o, DWORD flags);
	void ValInt(GraphObj *parent, int *val, DWORD flags);
	void ValLong(GraphObj *parent, long *val, DWORD flags);
	void ObjConf(GraphObj *go, DWORD flags);
	int SaveLFP(GraphObj *go, lfPOINT *lfp, DWORD flags);
	void MoveObj(GraphObj *go, lfPOINT *lfp, DWORD flags);
	void ValRect(GraphObj *go, fRECT *rec, DWORD flags);
	int String(GraphObj *go, char **s, DWORD flags);
	void RotDef(GraphObj *go, double **d, DWORD flags);
	void SetGO(GraphObj *parent, GraphObj **where, GraphObj *go, DWORD flags);
	void Line(GraphObj *go, LineDEF *ld, DWORD flags);
	void Fill(GraphObj *go, FillDEF *fd, DWORD flags);
	void AxisDef(GraphObj *go, AxisDEF *ad, DWORD flags);
	void TextDef(GraphObj *go, TextDEF *td, DWORD flags);
	void ValLFP3D(GraphObj *go, fPOINT3D *lfp, DWORD flags);
	void ValFloat(GraphObj *parent, double *val, DWORD flags);
	void DataMem(GraphObj *go, void **mem, int size, long *count, DWORD flags);
	void DataObject(GraphObj *go, anyOutput *o, DataObj *d, RECT *rc, DWORD flags);
	void TextCell(EditText *et, anyOutput *o, char *text, int *cur, int *m1, int *m2, void* DaO, DWORD flags);
	void TextBuffer(GraphObj *parent, int *psize, int *ppos, unsigned char **pbuff, DWORD flags, anyOutput *o); 

private:
	UndoInfo **buff, **buff0;
	int stub1, ndisp;
	UndoBuff **buffers;

	int NewItem(int cmd, DWORD flags, GraphObj *owner, void *data, void **loc);
	void FreeInfo(UndoInfo** inf);
	void RestoreConf(UndoInfo *inf);
	void RestoreData(UndoInfo *inf);
};

//prototypes: spreadwi.cpp
int ProcMemData(GraphObj *g, unsigned char *ptr, bool dispatch);
void SpreadMain(bool show);

//prototypes: WinSpec.cpp or QT_Spec.cpp
char *SaveDataAsName(char *oldname);
char *SaveGraphAsName(char *oldname);
char *OpenGraphName(char *oldname);
char *OpenDataName(char *oldname);
void InfoBox(char *Msg);
void ErrorBox(char *Msg);
bool YesNoBox(char *Msg);
int YesNoCancelBox(char *Msg);
void Qt_Box();
void HideTextCursor();
void HideTextCursorObj(anyOutput *out);
void ShowTextCursor(anyOutput *out, RECT *disp, DWORD color);
void HideCopyMark();
void ShowCopyMark(anyOutput *out, RECT *mrk, int nRec);
void InvalidateOutput(anyOutput *o);
void SuspendAnimation(anyOutput *o, bool bSusp);
void InitTextCursor(bool init);
void EmptyClip();
void CopyText(char *txt, int len);
unsigned char* PasteText();
void GetDesktopSize(int *width, int *height);
void FindBrowser();
void LoopDlgWnd();
void CloseDlgWnd(void *hDlg);
void ShowDlgWnd(void *hDlg);
void ResizeDlgWnd(void *hDlg, int w, int h);
anyOutput *NewDispClass(GraphObj *g);
bool DelDispClass(anyOutput *w);
anyOutput *NewBitmapClass(int w, int h, double hr, double vr);
bool DelBitmapClass(anyOutput *w);

//prototypes: FileIO.cpp
bool SaveGraphAs(GraphObj *g);
char *GraphToMem(GraphObj *g, long *size);
void UpdGOfromMem(GraphObj *go, unsigned char *buff);
bool OpenGraph(GraphObj *root, char *name, unsigned char *mem, bool bPaste);
void SavVarInit(long len);
void *SavVarFetch();

//prototypes:TheDialog.cpp
DWORD GetNewColor(DWORD oldcol);
bool ShowLayers(GraphObj *root);
void GetNewFill(FillDEF *oldfill);
void ShowBanner(bool show);
void RLPlotInfo();
bool DoSpShSize(DataObj *dt, GraphObj *parent);
bool FillSsRange(DataObj *d, char **range, GraphObj *msg_go);
bool GetBitmapRes(double *res, double *width, double *height, char *header);
void OD_scheme(int, void *, RECT *, anyOutput *, void *, int);
FillDEF *GetSchemeFill(int *i);
void OD_linedef(int, void *, RECT *, anyOutput *o, void *, int);
void OD_filldef(int, void *, RECT *, anyOutput *o, void *, int);
void OD_paperdef(int, void *, RECT *, anyOutput *o, void *, int);
void FindPaper(double w, double h, double tol);
bool GetPaper(double *w, double *h);
void OD_axisplot(int, void *, RECT *, anyOutput *o, void *, int);

//prototypes: Utils.cpp
anyOutput *GetRectBitmap(RECT *rc, anyOutput *src);
void RestoreRectBitmap(anyOutput **pmo, RECT *mrc, anyOutput *o);
void NiceAxis(AxisDEF *axis, int nTick);
void NiceStep(AxisDEF *axis, int nTick);
double base4log(AxisDEF *axis, int direc);
double TransformValue(AxisDEF *axis, double val, bool transform);
void SortAxisBreaks(AxisDEF *axis);
double GetAxisFac(AxisDEF *axis, double delta, int direc);
char *str_ltrim(char *str);
char *str_rtrim(char *str);
char *str_trim(char *str);
void rmquot(char *str);
int strpos(char *needle, char *haystack);
char *strreplace(char *needle, char *replace, char *haystack);
char *substr(char *text, int pos1, int pos2);
int rlp_strcpy(char*dest, int size, char*src);
void ReshapeFormula(char **text);
void TranslateResult(anyResult *res);
void CleanTags(char *txt, int *i1, int *i2, int *i3);
void ChangeChar(char *text, char c1, char c2);
char *Int2Nat(char *Text);
char *Nat2Int(char *Text);
void WriteNatFloatToBuff(char *buff, double val);
bool Txt2Flt(char *txt, double *val);
void RmTrail(char *txt);
double NiceValue(double fv);
char *NiceTime(double val);
char *Int2ColLabel(int nr, bool uc);
char *mkCellRef(int row, int col);
char *mkRangeRef(int r1, int c1, int r2, int c2);
char *str2xml(char *str, bool bGreek);
char **split(char *str, char sep, int *nl);
char *fit_num_rect(anyOutput *o, int max_width, char *num_str);
void add_to_buff(char** dest, int *pos, int *csize, char *txt, int len);
void add_int_to_buff(char** dest, int *pos, int *csize, int value, bool lsp, int ndig);
void add_dbl_to_buff(char** dest, int *pos, int *csize, double value, bool lsp);
void add_hex_to_buff(char** dest, int *pos, int *csize, DWORD value, bool lsp);
void SetMinMaxRect(RECT *rc, int x1, int y1, int x2, int y2);
void UpdateMinMaxRect(RECT *rc, int x, int y);
void IncrementMinMaxRect(RECT *rc, int i);
bool IsInRect(RECT *rc, int x, int y);
bool IsCloseToLine(POINT *p1, POINT *p2, int x, int y);
bool IsCloseToPL(POINT p, POINT *pts, int cp);
bool IsInPolygon(POINT *p, POINT *pts, int cp);
bool OverlapRect(RECT *rc1, RECT *rc2);
void AddToPolygon(long *cp, POINT *pts, POINT *np);
void DrawBezier(long *cp, POINT *pts, POINT p0, POINT p1, POINT p2, POINT p3, int depth=0);
void ClipBezier(long *cp, POINT *pts, POINT p0, POINT p1, POINT p2, POINT p3, POINT *clp1, POINT *clp2);
int mkCurve(lfPOINT *src, int n1, lfPOINT **dst, bool bClosed);
POINT *MakeArc(int ix, int iy, int r, int qad, long *npts);
void InvertLine(POINT*, int, LineDEF*, RECT*, anyOutput*, bool);
unsigned int ColDiff(DWORD col1, DWORD col2);
DWORD IpolCol(DWORD color1, DWORD color2, double fact);
double ran2(long *idum);
unsigned long isqr(unsigned long n);
bool MatMul(double a[3][3], double b[3][3], double c[3][3]);
char *GetNumFormat(double Magn);
void DeleteGO(GraphObj *go);
bool DeleteGOL(GraphObj ***gol, long n, GraphObj *go, anyOutput *o);
bool BackupFile(char *FileName);
bool IsRlpFile(char *FileName);
bool IsXmlFile(char *FileName);
bool FileExist(char *FileName);
bool IsPlot3D(GraphObj *g);
void *memdup(void *ptr, int cb_old, int cb_new);
double sininv(double val);
double trig2deg(double si, double csi);
bool ReplaceGO(GraphObj **oldobj, GraphObj **newobj);
unsigned int HashValue(unsigned char *str);
unsigned int Hash2(unsigned char * str);
bool cmpLineDEF(LineDEF *l1, LineDEF *l2);
bool cmpFillDEF(FillDEF *f1, FillDEF *f2);
bool cmpAxisDEF(AxisDEF *a1, AxisDEF *a2);
bool cmpTextDEF(TextDEF *t1, TextDEF *t2);
DWORD CheckNewFloat(double *loc, double old_v, double new_v, GraphObj *par, DWORD flags);
DWORD CheckNewInt(int *loc, int old_v, int new_v, GraphObj *par, DWORD flags);
DWORD CheckNewDword(DWORD *loc, DWORD old_v, DWORD new_v, GraphObj *par, DWORD flags);
DWORD CheckNewLFPoint(lfPOINT *loc, lfPOINT *old_v, lfPOINT *new_v, GraphObj *par, DWORD flags);
DWORD CheckNewString(char **loc, char *s_old, char *s_new, GraphObj *par, DWORD flags);
void clip_line_sphere(GraphObj *par, POINT3D **li, int r, int cx, int cy, int cz);
void clip_line_plane(GraphObj *par, POINT3D **li, POINT3D *pg, int np, double *vec);
void clip_sphline_sphere(GraphObj *par, POINT3D *lim1, POINT3D *lim2, POINT3D *cent, 
	int r1, int r2, int cx, int cy, int cz);
void clip_sphline_plane(GraphObj *par, POINT3D *lim1, POINT3D *lim2, POINT3D *cent, 
	int r1, POINT3D *pg, int np, double *vec);
void clip_plane_plane(GraphObj *par, POINT3D *pg1, int n1, double *v1, POINT3D *pg2, 
	int n2, double *v2, POINT *m, int nm);

//prototypes Export.cpp
void DoExportWmf(GraphObj *g, char *FileName, float res, DWORD flags);
void DoExportSvg(GraphObj *g, char *FileName, DWORD flags);
void DoExportEps(GraphObj *g, char *FileName, DWORD flags);

//prototypes Output.cpp
void DoExportTif(GraphObj *g, char *FileName, DWORD flags);

//prototypes mfcalc.cpp
void LockData(bool lockExec, bool lockWrite);
char  *yywarn(char *txt, bool bNew);
bool do_xyfunc(DataObj *, double, double, double, char *, lfPOINT **, long *, char *);
bool do_func3D(DataObj *d, double x1, double x2, double xstep, double z1, double z2, double zstep, 
	char *expr, char *param);
anyResult *do_formula(DataObj *, char *);
bool MoveFormula(DataObj *d, char *of, char *nf, int nfsize, int dx, int dy, int r0, int c0);
int do_fitfunc(DataObj *d, char *rx, char *ry, char *rz, char **par, char *expr, 
	double conv, int maxiter, double *chi_2);

//prototypes rlp_math.cp
double **dmatrix(int nrl, int nrh, int ncl, int nch);
void free_dmatrix(double **m, int nrl, int nrh, int ncl, int);
bool mrqmin(double *, double *, double *, int, double **, int, int *, int, double **, double **, double *,
	void (*funcs)(double, double, double **, double *, double *, int), double *);
bool Check_MRQerror();
void SortArray(int n, double *vals);
void SortArray2(int n, double *a1, double *a2);
void SortFpArray(int n, lfPOINT *vals);
double *randarr(double *v0, int n, long *seed);
double *resample(double *v0, int n, long *seed);
void spline(lfPOINT *v, int n, double *y2);
double gammln(double x);
double factrl(int n);
double gammp(double a, double x);
double gammq(double a, double x);
double betai(double a, double b, double x);
double bincof(double n, double k);
double binomdistf(double k, double n, double p);
double betaf(double z, double w);
double errf(double x);
double errfc(double x);
double norm_dist(double x, double m, double s);
double norm_freq(double x, double m, double s);
double exp_dist(double x, double l, double s);
double exp_inv(double p, double l, double s);
double exp_freq(double x, double l, double s);
double lognorm_dist(double x, double m, double s);
double lognorm_freq(double x, double m, double s);
double chi_dist(double x, double df, double);
double chi_freq(double x, double df);
double t_dist(double t, double df, double);
double t_freq(double t, double df);
double pois_dist(double x, double m, double);
double f_dist(double f, double df1, double df2);
double f_freq(double f, double df1, double df2);
double weib_dist(double x, double shape, double scale);
double weib_freq(double x, double shape, double scale);
double geom_freq(double x, double p);
double geom_dist(double x, double p);
double hyper_freq(double k, double n0, double m, double n1);
double hyper_dist(double k, double n0, double m, double n1);
double cauch_dist(double x, double loc, double scale);
double cauch_freq(double x, double loc, double scale);
double logis_dist(double x, double loc, double scale);
double logis_freq(double x, double loc, double scale);
double ks_dist(int n, double d);
void swilk1(int n, double *v0, double (*func)(double, double, double), double p1, double p2, 
	bool bsorted, double *w, double *p);
void KolSmir(int n, double *v0, double (*func)(double, double, double),
	double p1, double p2, bool bsorted, double *d, double *p);
double distinv(double (*sf)(double, double, double), double df1, double df2, double p, double x0);
void d_quartile(int n, double *v, double *q1, double *q2, double *q3);
double d_variance(int n, double *v, double *mean = 0L, double *ss = 0L);
double d_amean(int n, double *v);
double d_kurt(int n, double *v);
double d_skew(int n, double *v);
double d_gmean(int n, double *v);
double d_hmean(int n, double *v);
double d_classes(DataObj *d, double start, double step, double *v, int nv, char *range);
double d_pearson(double *x, double *y, int n, char *dest, DataObj *data, double *ra);
double d_rank(int n, double *v, double v1);
void crank(int n, double *w0, double *s);
double d_spearman(double *x, double *y, int n, char *dest, DataObj *data, double *ra);
double d_kendall(double *x, double *y, int n, char *dest, DataObj *data, double *ra);
double d_regression(double *x, double *y, int n, char *dest, DataObj *data, double *ra);
double d_covar(double *x, double *y, int n, char *dest, DataObj *data);
double d_utest(double *x, double *y, int n1, int n2, char *dest, DataObj *data, double *results);
double d_ttest(double *x, double *y, int n1, int n2, char *dest, DataObj *data, double *results);
double d_ttest2(double *x, double *y, int n, char *dest, DataObj *data, double *results);
double d_ftest(double *x, double *y, int n1, int n2, char *dest, DataObj *data, double *results);
bool do_anova1(int n, int *nv, double **vals, double **res_tab, double *gm, double **means, double **ss);
bool bartlett(int n, int *nc, double *ss, double *chi2);
bool levene(int type, int n, int *nv, double *means, double **vals, double *F, double *P);
double wprob(double w, double rr, double cc);
double ptukey(double q, double rr, double cc, double df, int lower_tail, int log_p);
double qtukey(double p, double rr, double cc, double df, int lower_tail, int log_p);
int year2aday(int y);
void add_date(rlp_datetime *base, rlp_datetime *inc);
char *date2text(rlp_datetime *dt, char *fmt);
double date2value(rlp_datetime *dt);
void parse_datevalue(rlp_datetime *dt, double dv);
bool date_value(char *desc, char *fmt, double *value);
char *value_date(double dv, char *fmt);
double now_today();
void split_date(double dv, int *y, int *mo, int *dom, int *dow, int *doy, int *h, int *m, double *s);
Triangle* Triangulate1(char *xr, char *yr, char *zr, DataObj *data);

//prototypes reports.cpp
void rep_anova(GraphObj *parent, DataObj *data);
void rep_bdanova(GraphObj *parent, DataObj *data);
void rep_twanova(GraphObj *parent, DataObj *data);
void rep_fmanova(GraphObj *parent, DataObj *data);
void rep_twoway_anova(GraphObj *parent, DataObj *data);
void rep_kruskal(GraphObj *parent, DataObj *data);
void rep_samplestats(GraphObj *parent, DataObj *data);
void rep_regression(GraphObj *parent, DataObj *data);
void rep_robustline(GraphObj *parent, DataObj *data);
void rep_twowaytable(GraphObj *parent, DataObj *data);
void rep_compmeans(GraphObj *parent, DataObj *data);
void rep_correl(GraphObj *parent, DataObj *data, int style);
#endif //_RLPLOT_H
