// C++ .h file for gplot, CGM-specific classes  -*-c++-*-
// copyright Phil Andrews, Pittsburgh Supercomputing Center, 1992
// all rights reserved
#ifndef cgm_h
#define cgm_h
#include <stdio.h>
#if __MSDOS__
#include <windows.h>
  typedef unsigned char huge * HugePt;
#endif

////
// how to get the options from the X server
////
enum {useScale = 0, PSWidth, PSHeight, PSRotation, PSColrs,
      PSXOffset, PSYOffset, debugOutput, cgmOptionSize};
////
// class to hold the overall option settings
class cgmOptions {
public:
  cgmOptions() // default constructor
    {useScale=0; PSWidth=8*72; PSHeight=10*72; PSRotation=0; PSColrs=0;
   debugOutput=0; PSXOffset=20; PSYOffset=20;}
  int useScale;
  int PSWidth;
  int PSHeight;
  int PSColrs;
  int debugOutput;
  int PSRotation;
  int PSXOffset;
  int PSYOffset;
};
////
// forward declarations
////
class cgmInput;
class cgmOutput;
class baseDisplay;
class cgmContainer;
class cgmMetafile;
class colrValueExtent;
#ifndef _XLIB_H_
class XImage; // X classes 
class XPoint; // for cell arrays
#endif
struct xlDisplay;
class mPoint;      // for macintosh cell arrays
class macDisplay;  // for macintosh
//typedef POINT;      // for Windows pc
////
// typedef for file positioning
////
typedef long filePos;
////
// basic CGM class
////
class baseCGM { 
public:
   // constructor
  baseCGM(cgmContainer*, baseCGM *inPrev = NULL, baseCGM *inNext = NULL);
  virtual ~baseCGM(); // destructor
  baseCGM *next, *prev; // pointers for linked list
  virtual int cgmClass() = 0; // class
  virtual int cgmElement() = 0; // element
  virtual const char *cgmName() = 0; // clear text name
  virtual int cgmOut(cgmOutput*);
  virtual int display(baseDisplay*);
protected:
  cgmContainer *owner;
  cgmMetafile *mfOwner(); // find the metafile owner 
};
////
// necessary types for cgm classes
////
// real or integer vdc's ?
////
typedef char vdcType; 
////
// type for direct colours (R,G,B) format
////
class dColr {
public:
  dColr() {values[0] = values[1] = values[2] = 0;} // default constructor
  dColr(int, int, int); // constructor
//int& operator[](int index) const {return values[index];} // simulate array ref      ********
	 int getValue(int i) const {return ((i>=0) && (i<3)) ? values[i] : 0;}
    void setValue(int i, int j) {if ((i>=0) && (i<3)) values[i] = j;}
  void set(int r, int g, int b) {values[0]=r;values[1]=g;values[2]=b;}
private:
  int values[3]; // store values here
};
////
// the extent of colour values
////
class colrValueExtent {
public:
  colrValueExtent() {white = dColr(255, 255, 255);}
  dColr black, white;
};
////
// colour table
////
class colrTable {
public:
  // constructor
  colrTable(unsigned int, const colrValueExtent*, unsigned int = 0); 
  ~colrTable() {delete values;} // destructor
  // legitimate const functions
  int size() const {return mySize;} // max no of entries
  int no() const {return myNo;} // actual no of entries
  int start() const {return myStart;} // starting index
  dColr val(unsigned i) const {return (i<mySize) ? values[i] : values[0];}
  const colrValueExtent *extent() const {return myExtent;}
  // now the modifier functions
  void addTable(colrTable*); // insert another table
  void extendTable(int); // extend the table
  void setSize(int); // set the size
  void addColr(dColr&);
  const float *r(unsigned int) const;
protected:
  int mySize, myNo, myStart;
  dColr *values;
  void initialize(dColr*, int); // initialize values
  const colrValueExtent *myExtent;
  float rvalues[3];
};
////
// general colour, indexed or direct
////
class genColr { 
public:
  genColr(int, const colrValueExtent*, const colrTable* = NULL);
  genColr(int, int, int, const colrValueExtent*, const colrTable* = NULL);
  genColr(const dColr&, const colrValueExtent*, const colrTable* = NULL);
  int i() const {return myIndex;}
  int i(unsigned int index) // ****** const {return myDC[index];}
	  const{return myDC.getValue(index); }
  int type() const {return myType;}
  float r(unsigned i) const; // get the actual colours
private:
  int myIndex, myType;
  dColr myDC; // keep rgb values here
  // classes required to work out actual colour values
  const colrValueExtent *myExtent;
  const colrTable *myTable;
};
////
// class for a single vdc dimension
////
class vdc {
public:
  vdc(float inFloat) {myInt = 0; myFloat = inFloat; myType = 1;}
  vdc(int inInt) {myInt = inInt; myFloat = 0; myType = 0;}
  int i() const {return (myType) ? (int) myFloat : myInt;}
  float f() const {return (myType) ? myFloat : (float) myInt;}
  const vdcType type() const {return myType;}
protected:
  int myInt;
  float myFloat;
  vdcType myType;
};
////
// class to hold either a vdc or a real, for line width, etc.
////
class vdcR {
public:
  vdcR(float inFloat) {myFloat = inFloat; myType = 1; myVdc = NULL;}
  vdcR(vdc *inVdc) {myFloat = 0; myType = 0; myVdc = inVdc;}
  ~vdcR() {if (myType == 0) delete myVdc;}
  float f() const {return myFloat;}
  int type() const {return myType;}
  const vdc *v() const {return (const vdc*) myVdc;}
protected:
  float myFloat;
  vdc *myVdc;
  int myType;
};    
////
// class to hold an arbitrary number of vdc points
////
class vdcPts { 
public:
  // default constructor
  vdcPts(unsigned int inNoPts = 0, vdcType inType = 0)
    {myPtr = NULL; noPts = inNoPts; myType = inType; next=NULL;}
  // constructor for an integer set of points
  vdcPts(int *inPtr, unsigned int inNoPts=0)
    {myPtr = inPtr; noPts = inNoPts; myType = 0; next=NULL;}
  // constructor for a float set of points
  vdcPts(float *inPtr, unsigned int inNoPts=0)
    {myPtr = inPtr; noPts = inNoPts; myType = 1; next=NULL;}
  // constructor for an integer rectangle
  vdcPts(int, int, int, int); 
  // constructor for a float rectangle
  vdcPts(double, double, double, double);
  // destructor
  ~vdcPts() { if (myPtr) delete myPtr;} 
  // max width and height of the points
  float width() const, height() const, maxY() const, minY() const,
  maxX() const, minX() const;
  // values for calculations (may need to be precise)
  float x(int i) const {return (i>=noPts) ? 0 : (myType) ?
			  ((float *) myPtr)[2 * i] :
			((int *) myPtr)[2 * i]; }
  float y(int i) const {return (i>=noPts) ? 0 : (myType) ?
			  ((float *) myPtr)[2 * i + 1] :
			((int *) myPtr)[2 * i + 1]; }
  // now the squared versions
  float x2(int i) const
    {return (i>=noPts) ? 0 :(myType) ?
       ((float *) myPtr)[2 * i] * ((float *) myPtr)[2 * i] :
     ((int *) myPtr)[2 * i] * ((int *) myPtr)[2 * i]; }
  float y2(int i) const
    {return (i>=noPts) ? 0 : (myType) ?
       ((float *) myPtr)[2 * i + 1] * ((float *) myPtr)[2 * i + 1]:
     ((int *) myPtr)[2 * i + 1] * ((int *) myPtr)[2 * i + 1]; }
  // how many points do we have ?
  int no() const {return noPts;}
  // the vdcType of these points
  vdcType type() const {return myType;}
  // i'th x and y components in float
  float fx(int i) const {return ((float *)myPtr)[2*i];}
  float fy(int i) const {return ((float *)myPtr)[2*i+1];}
  // i'th x and y components in integer
  int ix(int i) const {return ((int *)myPtr)[2*i];}
  int iy(int i) const {return ((int *)myPtr)[2*i+1];}
  // i'th component in integer
  int i(int i) const {return ((int *)myPtr)[i];}
  // i'th component in float
  float f(int i) const {return ((float *)myPtr)[i];}
  vdcPts *next; // for utility use
  void shift(float, float); // shift of origin
  void scale(float); // scale the points
  vdc *newVdc(int i) const {return (myType) ? new vdc(((float *)myPtr)[i]) :
			    new vdc(((int *)myPtr)[i]);}
protected:
  unsigned int noPts; // no. of points
  vdcType myType; // real or integer ?
  void *myPtr; // pointer to memory
};
////
// cell arrays, tricky class need both speed and compactness
////
class cellArray {
public:
  cellArray(int inColMode, const colrValueExtent *inExtent,
		 vdcPts *inCorners, int inNx, int inNy,
	    int inPrec, int inRepMode,
	    const colrTable *inTable = NULL); // constructor
  ~cellArray();// {delete myCorners; delete myContents;} // destructor
  ////
  // constant functions
  const vdcPts *corners() const {return myCorners;} // 3 corners
  unsigned int nx() const {return myNx;} // cells in x direction
  unsigned int ny() const {return myNy;} // cells in y direction
  unsigned int prec() const {return myPrec;} // local colour precision
  unsigned int repMode() const {return myRepMode;} // representation mode
  unsigned int colMode() const {return myColMode;} // colour mode
#if __MSDOS__
//  const HugePt contents() const { return myContents; }
 // for pc [PLA, moved]
  void fill(POINT *offScreen, unsigned int width, unsigned int height, unsigned int hdc) const;
#else
//  const unsigned char *contents() const {return myContents;} // the colours
#endif
  void fill(XImage*, XPoint*, unsigned int, unsigned int, xlDisplay*) const;
 // for macintosh
  void fill(mPoint *offScreen, unsigned int width, unsigned int height) const;
  void fillGrey(unsigned char*&) const; // fill with a grey scale
  void fillColr(unsigned char*&) const; // fill with colours
  unsigned int getValue(unsigned long) const; // get a single integer
  float *getFloats(unsigned long) const; // get a set of float values
  float *getFloats(unsigned int ix, unsigned int iy)
	 const {return getFloats((unsigned long)iy * myNx + ix);} // convenience function
  ////
  // modifiers
  int addValue(unsigned int); // add one value
#if __MSDOS__
  int addValues(HugePt, int, int); // add values from pointer
#else
  int addValues(unsigned char*, int, int); // add values from pointer
#endif
  void decompress(); // decompress, if necessary
protected:
  vdcPts *myCorners;
  unsigned int myNx, myNy, myPrec, myRepMode, myColMode;
#if __MSDOS__
  HugePt myContents;
  unsigned int hContentsBuffer;

#else
  unsigned char *myContents;
#endif
  unsigned long bitsAdded;
  unsigned long totalBits, totalBytes;
  // classes required to work out actual colour values
  const colrValueExtent *myExtent;
  const colrTable *myTable;
  float rvalues[3];
};
////
// set of defaults created by a metafile defaults replacement element
////
class cgmDefaults {
public:
  cgmDefaults(baseCGM *inStart) // constructor
	 {myContents=inStart; myNext=NULL;}
  void display(baseDisplay *inDisplay); // display the elements
//	 {for (baseCGM *myPtr=contents(); myPtr; myPtr=myPtr->next)
//		 myPtr->display(inDisplay);}
  void addNext(cgmDefaults *inNext) {myNext=inNext;}
  cgmDefaults *next() {return myNext;}
  baseCGM *contents() {return myContents;}
protected:
  baseCGM *myContents; // the elements
  cgmDefaults *myNext;
};
////
// class for text alignment
////
class alignment {
public:
  alignment(int inH=0, int inV=0, float inCH=0, float inCV=0)
    {myH = inH; myV = inV; myCH = inCH; myCV = inCV;}
  int h() const {return myH;} // horizontal alignment
  int v() const {return myV;} // vertical alignment
  float cH() const {return myCH;} // continuous horizontal alignment
  float cV() const {return myCV;} // continuous vertical alignment
protected:
  int myH, myV;
  float myCH, myCV;
};
////
// text info (size, etc)
////
class textInfo {
public:
  textInfo() // default constructor
    {myIndex=1; myFont=0; myPrec=0; myExpan=1; myHeight=0; mySpace=0;
   myColr=NULL; myAlign=NULL; myPath=0; myOrientation=NULL;}
  int index() const {return myIndex;}
  void setIndex(int inIndex) {myIndex = inIndex;}
  int font() const {return myFont;}
  void setFont(int inFont) {myFont = inFont;}
  int prec() const {return myPrec;}
  void setPrec(int inPrec) {myPrec = inPrec;}
  float expan() const {return myExpan;}
  void setExpan(float inExpan) {myExpan = inExpan;}
  float height() const {return myHeight;}
  void setHeight(float inHeight) {myHeight = inHeight;}
  float space() const {return mySpace;}
  void setSpace(float inSpace) {mySpace = inSpace;}
  const genColr *colr() const {return myColr;}
  void setColr(genColr *inColr) {myColr = inColr;}
  const alignment *align() const {return myAlign;}
  void setAlign(alignment *inAlign) {myAlign = inAlign;}
  int path() const {return myPath;}
  void setPath(int inPath) {myPath = inPath;}
  const vdcPts *orientation() const {return myOrientation;}
  void setOrientation(const vdcPts *inOrient) {myOrientation = inOrient;}
protected:
  int myIndex; // bundle index
  int myFont; // font number
  int myPrec; // precision
  float myExpan; // character expansion factor
  float myHeight; // character height
  float mySpace; // spacing
  genColr *myColr;
  int myPath;
  alignment *myAlign;
  const vdcPts *myOrientation;
};
////
// general text class
////
class genText {
public:
  genText(const textInfo *inTextInfo, int inFinal, char *inText, int inSize,
	  vdcPts *inPos = NULL, 
	  int inAppend=0, vdc *inHeight=NULL, vdc *inWidth=NULL) // constructor
    {myPos=inPos; flag = (inFinal) ? finalFlag : 0; myContents=inText;
     mySize=inSize; myHeight=inHeight; myWidth=inWidth;
     if (inAppend) flag |= appendFlag; myInfo = inTextInfo;}
  ~genText() {if (size()) delete myContents; delete myPos; delete myHeight;
	 delete myWidth;}
  int restricted() const {return flag & restrictedFlag;}
  int final() const {return flag & finalFlag;}
  int size() const {return mySize;}
  const vdcPts *pos() const {return myPos;}
  const char *contents() const {return myContents;}
  const vdc *height() const {return myHeight;}
  const vdc *width() const {return myWidth;}
  const textInfo *info() const {return myInfo;}
protected:
  int flag;
  vdcPts *myPos; // position
  vdc *myWidth, *myHeight; // if restricted
  static const int finalFlag, restrictedFlag, appendFlag;
  char *myContents;
  int mySize;
  const textInfo *myInfo;
};
// now individual CGM classes
////
// define macro to handle CGM class declarations
// after this macro add any other public parts and any privates
////
#define CGMCLASS(className) \
class className : public baseCGM { \
public: \
  className(cgmContainer *inOwner, baseCGM *inPrev = NULL, \
	    baseCGM *inNext = NULL) \
    : baseCGM(inOwner, inPrev, inNext) {} \
  int cgmClass() {return myClass;} \
  virtual int cgmElement() = 0; \
  virtual const char *cgmName() = 0; \
  static const int myClass;

////
// define macro to help handle declaration of CGM elements
// after this macro add any other public parts and any privates
////
#define CGMELEMENT(element, className) \
class element : public className { \
public: \
  element(cgmContainer*, cgmInput*, baseCGM *inPrev = NULL, \
	  baseCGM *inNext = NULL); \
    int cgmElement() {return myElement;} \
    const char *cgmName() {return myName;} \
    static baseCGM *getNew(cgmContainer *inOwner, cgmInput *cgmIn, \
    baseCGM *inPrev) \
    { return new element(inOwner, cgmIn, inPrev);} \
      static const int myElement; \
	static const char *myName; \
      virtual int cgmOut(cgmOutput*); 
////
// the Delimiter elements
////
CGMCLASS(cgmDelimiter)
};
////
// begin metafile
////
CGMELEMENT(cgmBeginMetafile, cgmDelimiter)
  ~cgmBeginMetafile();
  void setOwner(cgmMetafile *inOwner);
  virtual int display(baseDisplay*);
private:
  char *mfName;
  int mfNameSize;
};
////
// end metafile
////
CGMELEMENT(cgmEndMetafile, cgmDelimiter)
     cgmEndMetafile(cgmContainer *inOwner=NULL)
  : cgmDelimiter(inOwner) {} // alternate constructor
  virtual int display(baseDisplay *inDisplay);
};

////
// begin picture
////
CGMELEMENT(cgmBeginPicture, cgmDelimiter)
  // alternate constructor
  cgmBeginPicture(cgmContainer*, const char*, int,
    baseCGM* = NULL, baseCGM* = NULL);
  ~cgmBeginPicture();
  virtual int display(baseDisplay*);
  const char *name() {return (picName) ? picName : "";}
  int nameSize() {return picNameSize;}
private:
  char *picName;
  int picNameSize;
};
////
// begin picture body
////
CGMELEMENT(cgmBeginPictureBody, cgmDelimiter)
  virtual int display(baseDisplay*);
};
////
// end picture
CGMELEMENT(cgmEndPicture, cgmDelimiter)
  virtual int display(baseDisplay *inDisplay);
};
////
// metafile descrptors
////
CGMCLASS(cgmMetafileDescriptor)
};
////
// metafile version
////
CGMELEMENT(cgmMetafileVersion, cgmMetafileDescriptor)
  int versionNumber;
};
////
// metafile description
////
CGMELEMENT(cgmMetafileDescription, cgmMetafileDescriptor)
  ~cgmMetafileDescription();
  char *mfDescription;
private:
  int mfDescriptionSize;
};
////
// VDC Type
////
CGMELEMENT(cgmVdcType, cgmMetafileDescriptor)
public:
  vdcType myType;
private:
  static const char **typeList;
  static const int typeListSize;
};
////
// class for unsigned integer precisions
////
class uIntPrec {
public:
  uIntPrec(unsigned int inMax = 1<<16 - 1, int inBytes = 2)
    {maxInt = inMax; noBytes = inBytes;}
  unsigned int maxInt;
  int noBytes;
};
////
// class for signed integer precisions
////
class intPrec : public uIntPrec {
public:
  intPrec(int inMin = - (1<<15), int inMax = 1<<15 - 1, int inBytes = 2)
    : uIntPrec(inMax, inBytes) {minInt = inMin;}
  int minInt;
};
////
// Integer Precision
////
CGMELEMENT(cgmIntegerPrec, cgmMetafileDescriptor)
  intPrec thisPrec;
};
////
// class for real precisions
////
class realPrec {
public:
  realPrec(float inMin = -33000, float inMax = 33000, int inDigits = 7,
	   int inFormat = 1, int inExp = 16, int inFract = 16) {
    minReal = inMin; maxReal = inMax; noDigits = inDigits;
    format = inFormat; expPart = inExp; fractPart = inFract;
  }
  float minReal;
  float maxReal;
  int noDigits;
  int format;
  int expPart;
  int fractPart;
};
////
// Real Precision
////
CGMELEMENT(cgmRealPrec, cgmMetafileDescriptor)
  realPrec thisPrec;
};
////
// index precision
////
CGMELEMENT(cgmIndexPrec, cgmMetafileDescriptor)
  intPrec thisPrec;
};
////
// Colour precision
////
CGMELEMENT(cgmColrPrec, cgmMetafileDescriptor)
  uIntPrec thisPrec;
};
////
// Colour index precision
////
CGMELEMENT(cgmColrIndexPrec, cgmMetafileDescriptor)
  uIntPrec thisPrec;
};
////
// Maximum Colour index
////
CGMELEMENT(cgmMaxColrIndex, cgmMetafileDescriptor)
  int maxIndexValue;
};
////
// Colour Value Extent
////
CGMELEMENT(cgmColrValueExtent, cgmMetafileDescriptor)
  colrValueExtent myExtent;
};
////
// type to hold element list
////
typedef int classElement[2];
////
// metafile element list
////
CGMELEMENT(cgmMetafileElementList, cgmMetafileDescriptor)
private:
  int noElements;
  classElement *elements;
};
////
// metafile defaults replacement
////
CGMELEMENT(cgmMetafileDefaultsReplacement, cgmMetafileDescriptor)
  static const char *endName;
private:
  cgmDefaults *myDefaults;
};
////
// font list
////
typedef char *fontName;
CGMELEMENT(cgmFontList, cgmMetafileDescriptor)
private:
  int noFonts;
  fontName *fontList;
};
////
// character set
////
class characterSet
{
public:
  int code;
  char *tail;
};
////
// character set list
////
CGMELEMENT(cgmCharacterSetList, cgmMetafileDescriptor)
private:
  int noSets;
  characterSet *characterSetList;
};
////
// character coding announcer
////
CGMELEMENT(cgmCharacterCodingAnnouncer, cgmMetafileDescriptor)
private:
  int announcer;
  static const char **typeList;
  static const int typeListSize;
};
////
// Picture descriptors
////
CGMCLASS(cgmPictureDescriptor)
};
////
// scaling mode
////
CGMELEMENT(cgmScalingMode, cgmPictureDescriptor)
  int mode;
  float factor;
private:
  static const char **typeList;
  static const int typeListSize;
};
////
// colour mode
////
CGMELEMENT(cgmColrMode, cgmPictureDescriptor)
  int mode;
private:
  static const char **typeList;
  static const int typeListSize;
};
////
// line width mode
////
CGMELEMENT(cgmLineWidthMode, cgmPictureDescriptor)
  int mode;
private:
  static const char **typeList;
  static const int typeListSize;
};
////
// marker size mode
////
CGMELEMENT(cgmMarkerSizeMode, cgmPictureDescriptor)
  int mode;
private:
  static const char **typeList;
  static const int typeListSize;
};
////
// edge width mode
////
CGMELEMENT(cgmEdgeWidthMode, cgmPictureDescriptor)
  int mode;
private:
  static const char **typeList;
  static const int typeListSize;
};
////
// vdc extent
////
CGMELEMENT(cgmVdcExtent, cgmPictureDescriptor)
  ~cgmVdcExtent();
  vdcPts *myPts;
};
////
// background colour
////
CGMELEMENT(cgmBackgroundColr, cgmPictureDescriptor)
  dColr background;
  virtual int display(baseDisplay*);
};
////
// control elements
////
CGMCLASS(cgmControl)
};
////
// vdc integer precision
////
CGMELEMENT(cgmVdcInteger, cgmControl)
  intPrec thisPrec;
};
////
// vdc real precision
////
CGMELEMENT(cgmVdcReal, cgmControl)
  realPrec thisPrec;
};
////
// auxiliary colour
////
CGMELEMENT(cgmAuxColr, cgmControl)
  ~cgmAuxColr() {delete myColr;}
private:
  genColr *myColr;
};
////
// transparency
////
CGMELEMENT(cgmTransparency, cgmControl)
  int myType;
  virtual int display(baseDisplay*);
private:
  static const char **typeList;
  static const int typeListSize;
};
////
// clip rectangle
////
CGMELEMENT(cgmClipRect, cgmControl)
  virtual int display(baseDisplay*);  
  ~cgmClipRect() {delete myPts;}
private:
  vdcPts *myPts;
};  
////
// clip indicator
////
CGMELEMENT(cgmClip, cgmControl)
  int myType;
  virtual int display(baseDisplay*);
private:
  static const char **typeList;
  static const int typeListSize;
};
////
// graphical primitives
////
CGMCLASS(cgmGraphicalPrimitive)
};
////
// polyline
////
CGMELEMENT(cgmPolyline, cgmGraphicalPrimitive)
  virtual int display(baseDisplay*);  
  ~cgmPolyline();
private:
  vdcPts *myPts;
};  
////
// disjoint polyline
////
CGMELEMENT(cgmDisPolyline, cgmGraphicalPrimitive)
  virtual int display(baseDisplay*);  
  ~cgmDisPolyline();
private:
  vdcPts *myPts;
};  
////
// polymarker
////
CGMELEMENT(cgmPolymarker, cgmGraphicalPrimitive)
  virtual int display(baseDisplay*);  
  ~cgmPolymarker();
private:
  vdcPts *myPts;
};  
////
// text
////
CGMELEMENT(cgmText, cgmGraphicalPrimitive)
  virtual int display(baseDisplay*);  
  ~cgmText() {delete myText;}
protected:
  genText *myText;
  static const char **typeList;
  static const int typeListSize;
};  
////
// restricted text
////
CGMELEMENT(cgmRestrText, cgmGraphicalPrimitive)
  virtual int display(baseDisplay*);  
  ~cgmRestrText() {delete myText;}
protected:
  genText *myText;
  vdc *maxWidth, *maxHeight;
  static const char **typeList;
  static const int typeListSize;
};  
////
// appended text
////
CGMELEMENT(cgmApndText, cgmGraphicalPrimitive)
  virtual int display(baseDisplay*);  
  ~cgmApndText() {delete myText;}
protected:
  genText *myText;
  static const char **typeList;
  static const int typeListSize;
};  
////
// polygon
////
CGMELEMENT(cgmPolygon, cgmGraphicalPrimitive)
  virtual int display(baseDisplay*);  
  ~cgmPolygon();
private:
  vdcPts *myPts;
};  
////
// polygon set
////
CGMELEMENT(cgmPolygonSet, cgmGraphicalPrimitive)
  virtual int display(baseDisplay*);  
  static const char **typeList;
  static const int typeListSize;
private:
  vdcPts *myPts;
  int *myFlags;
};  
////
// generalized drawing primitive
////
CGMELEMENT(cgmGDP, cgmGraphicalPrimitive)
  virtual int display(baseDisplay*);  
private:
 // fill out later
};  
////
// cell array
////
CGMELEMENT(cgmCellArray, cgmGraphicalPrimitive)
  virtual int display(baseDisplay*);  
  ~cgmCellArray();
private:
  cellArray *myCell;
};  
////
// rectangle
////
CGMELEMENT(cgmRectangle, cgmGraphicalPrimitive)
  virtual int display(baseDisplay*);  
  ~cgmRectangle();
private:
  vdcPts *myPts;
};  
////
// circle
////
CGMELEMENT(cgmCircle, cgmGraphicalPrimitive)
  virtual int display(baseDisplay*);  
  ~cgmCircle();
private:
  vdcPts *centre;
  vdc *radius;
};  
////
// circular arc, designated by 3 points
////
CGMELEMENT(cgmArc3Pt, cgmGraphicalPrimitive)
  virtual int display(baseDisplay*);  
  ~cgmArc3Pt() {delete myPts;}
private:
  vdcPts *myPts;
};  
////
// circular arc, designated by 3 points and closed
////
CGMELEMENT(cgmArc3PtClose, cgmGraphicalPrimitive)
  virtual int display(baseDisplay*);  
  ~cgmArc3PtClose() {delete myPts;}
private:
  vdcPts *myPts;
  static const char **typeList;
  static const int typeListSize;
  int myType;
};  
////
// circular arc, designated by a centre, 2 vectors and a radius
////
CGMELEMENT(cgmArcCtr, cgmGraphicalPrimitive)
  virtual int display(baseDisplay*);  
  ~cgmArcCtr() {delete myPts; delete radius;}
private:
  vdcPts *myPts;
  vdc *radius;
};  
////
// closed circular arc, designated by a centre, 2 vectors and a radius
////
CGMELEMENT(cgmArcCtrClose, cgmGraphicalPrimitive)
  virtual int display(baseDisplay*);  
  ~cgmArcCtrClose() {delete myPts; delete radius;}
private:
  vdcPts *myPts;
  vdc *radius;
  static const char **typeList;
  static const int typeListSize;
  int myType;
};  
////
// ellipse, designated by 3 pts
////
CGMELEMENT(cgmEllipse, cgmGraphicalPrimitive)
  virtual int display(baseDisplay*);  
  ~cgmEllipse() {delete myPts;}
private:
  vdcPts *myPts;
};  
////
// elliptical arc, designated by 5 pts
////
CGMELEMENT(cgmEllipArc, cgmGraphicalPrimitive)
  virtual int display(baseDisplay*);  
  ~cgmEllipArc() {delete myPts;}
private:
  vdcPts *myPts;
};  
////
// elliptical arc, designated by 5 pts, closed
////
CGMELEMENT(cgmEllipArcClose, cgmGraphicalPrimitive)
  virtual int display(baseDisplay*);  
  ~cgmEllipArcClose() {delete myPts;}
private:
  vdcPts *myPts;
  static const char **typeList;
  static const int typeListSize;
  int myType;
};  
////
// attributes class
////
class cgmPicture; // forward declaration
CGMCLASS(cgmAttribute)
};
////
// line bundle index
////
CGMELEMENT(cgmLineIndex, cgmAttribute)
  virtual int display(baseDisplay*);  
private:
  int myIndex;
};  
////
// line type 
////
CGMELEMENT(cgmLineType, cgmAttribute)
  virtual int display(baseDisplay*);  
private:
  int myType;
};  
////
// line width
////
CGMELEMENT(cgmLineWidth, cgmAttribute)
  virtual int display(baseDisplay*);  
  ~cgmLineWidth();
private:
  vdcR *myVdcR;
};  
////
// line colour
////
CGMELEMENT(cgmLineColr, cgmAttribute)
  virtual int display(baseDisplay*);  
  ~cgmLineColr() {delete myColr;}
private:
  genColr *myColr;
};  
////
// marker bundle index
////
CGMELEMENT(cgmMarkerIndex, cgmAttribute)
  virtual int display(baseDisplay*);  
private:
  int myIndex;
};  
////
// marker type 
////
CGMELEMENT(cgmMarkerType, cgmAttribute)
  virtual int display(baseDisplay*);  
private:
  int myType;
};  
////
// marker size
////
CGMELEMENT(cgmMarkerSize, cgmAttribute)
  virtual int display(baseDisplay*);  
  ~cgmMarkerSize();
private:
  vdcR *myVdcR;
};  
////
// marker colour
////
CGMELEMENT(cgmMarkerColr, cgmAttribute)
  virtual int display(baseDisplay*);  
  ~cgmMarkerColr() {delete myColr;}
private:
  genColr *myColr;
};  
////
// text bundle index
////
CGMELEMENT(cgmTextIndex, cgmAttribute)
  virtual int display(baseDisplay*);  
private:
  int myIndex;
};  
////
// text font index
////
CGMELEMENT(cgmFontIndex, cgmAttribute)
  virtual int display(baseDisplay*);  
private:
  int myIndex;
};  
////
// text precision
////
CGMELEMENT(cgmTextPrec, cgmAttribute)
  virtual int display(baseDisplay*);  
private:
  int myType;
  static const char **typeList;
  static const int typeListSize;
};  
////
// character expansion factor
////
CGMELEMENT(cgmCharExpan, cgmAttribute)
  virtual int display(baseDisplay*);  
private:
  float factor;
};  
////
// character spacing
////
CGMELEMENT(cgmCharSpace, cgmAttribute)
  virtual int display(baseDisplay*);  
private:
  float spacing;
};  
////
// text colour
////
CGMELEMENT(cgmTextColr, cgmAttribute)
  virtual int display(baseDisplay*);  
  ~cgmTextColr() {delete myColr;}
private:
  genColr *myColr;
};  
////
// character height
////
CGMELEMENT(cgmCharHeight, cgmAttribute)
  virtual int display(baseDisplay*);  
  ~cgmCharHeight() {delete height;}
private:
  vdc *height;
};  
////
// character orientation
////
CGMELEMENT(cgmCharOri, cgmAttribute)
  virtual int display(baseDisplay*);  
  ~cgmCharOri() {delete orientation;}
private:
  vdcPts *orientation;
};  
////
// text path
////
CGMELEMENT(cgmTextPath, cgmAttribute)
  virtual int display(baseDisplay*);  
private:
  int myType;
  static const char **typeList;
  static const int typeListSize;
};  
////
// text alignment
////
CGMELEMENT(cgmTextAlign, cgmAttribute)
  virtual int display(baseDisplay*);  
  ~cgmTextAlign() {delete myAlign;} // destructor
private:
  alignment *myAlign;
  static const char **typeList1;
  static const int typeListSize1;
  static const char **typeList2;
  static const int typeListSize2;
};  
////
// character set index
////
CGMELEMENT(cgmCharSetIndex, cgmAttribute)
  virtual int display(baseDisplay*);  
private:
  int myIndex;
};  
////
// alternate character set index
////
CGMELEMENT(cgmAltCharSetIndex, cgmAttribute)
  virtual int display(baseDisplay*);  
private:
  int myIndex;
};  
////
// fill bundle index
////
CGMELEMENT(cgmFillIndex, cgmAttribute)
  virtual int display(baseDisplay*);  
private:
  int myIndex;
};  
////
// interior style
////
CGMELEMENT(cgmIntStyle, cgmAttribute)
  virtual int display(baseDisplay*);  
private:
  int myType;
  static const char **typeList;
  static const int typeListSize;
};  
////
// fill colour
////
CGMELEMENT(cgmFillColr, cgmAttribute)
  virtual int display(baseDisplay*);  
  ~cgmFillColr() {delete myColr;}
private:
  genColr *myColr;
};  
////
// hatch index
////
CGMELEMENT(cgmHatchIndex, cgmAttribute)
  virtual int display(baseDisplay*);  
private:
  int myIndex;
};  
////
// pattern index
////
CGMELEMENT(cgmPatIndex, cgmAttribute)
  virtual int display(baseDisplay*);  
private:
  int myIndex;
};  
////
// edge bundle index
////
CGMELEMENT(cgmEdgeIndex, cgmAttribute)
  virtual int display(baseDisplay*);  
private:
  int myIndex;
};  
////
// edge type 
////
CGMELEMENT(cgmEdgeType, cgmAttribute)
  virtual int display(baseDisplay*);  
private:
  int myType;
};  
////
// edge width
////
CGMELEMENT(cgmEdgeWidth, cgmAttribute)
  virtual int display(baseDisplay*);  
  ~cgmEdgeWidth();
private:
  vdcR *myVdcR;
};  
////
// edge colour
////
CGMELEMENT(cgmEdgeColr, cgmAttribute)
  virtual int display(baseDisplay*);  
  ~cgmEdgeColr() {delete myColr;}
private:
  genColr *myColr;
};  
////
// edge visibility
////
CGMELEMENT(cgmEdgeVis, cgmAttribute)
  virtual int display(baseDisplay*);  
private:
  int myType;
  static const char **typeList;
  static const int typeListSize;
};  
////
// fill reference point
////
CGMELEMENT(cgmFillRefPt, cgmAttribute)
  virtual int display(baseDisplay*);  
  ~cgmFillRefPt() {delete myPts;}
private:
  vdcPts *myPts;
};  
////
// pattern size
////
CGMELEMENT(cgmPatSize, cgmAttribute)
  virtual int display(baseDisplay*);  
  ~cgmPatSize() {delete myPts;}
private:
  vdcPts *myPts;
};  
////
// pattern table
////
CGMELEMENT(cgmPatTable, cgmAttribute)
  virtual int display(baseDisplay*);  
private:
  // fill out later
};  
////
// colour table
////
CGMELEMENT(cgmColrTable, cgmAttribute)
  virtual int display(baseDisplay*);  
  ~cgmColrTable() {delete myTable;}
private:
  colrTable *myTable;
};  
////
// aspect source flags
////
CGMELEMENT(cgmASF, cgmAttribute)
     // fill out later
};  
////
// escape class
////
CGMCLASS(cgmEscape)
};
////
// escape element
////
CGMELEMENT(cgmEscapeElement, cgmEscape)
  ~cgmEscapeElement() {if (dataSize) delete myData;}
  char *data() {return myData;}
private:
  int myId, dataSize;   
  char *myData;
  static const int indexFlag;
  void makeIndex(cgmMetafile*, cgmInput*);
  int haveNumber(char c) {return (c=='-') || (c=='+') || (('0'<=c)&&(c<='9'));}
};  
////
// external class
////
CGMCLASS(cgmExternal)
};
////
// message element
////
CGMELEMENT(cgmMessage, cgmExternal)
     // fill out later
};  
////
// application data
////
CGMELEMENT(cgmApplData, cgmExternal)
     // fill out later
};  
#undef CGMCLASS
#undef CGMELEMENT
////
// classes that can contain cgm elements
////
class cgmContainer { // container class, can be a picture or a metafile
public:
  cgmContainer() {
    scalingCmd = NULL;
    colrModeCmd = NULL;
    lineModeCmd = NULL;
    markerModeCmd = NULL;
    edgeModeCmd = NULL;
    vdcExtentCmd = NULL;
    myColrTable = NULL;
  }
  // colour table
  colrTable *myColrTable;
  virtual colrTable *colrs() {return myColrTable;} // default
  // metafile descriptors 
  virtual const colrValueExtent *colrExtent() = 0;
  // picture descriptors (may be in either picture or metafile)
  // come as a command marker and a function to access them
  cgmScalingMode *scalingCmd;
  virtual int scalingMode() = 0;
  virtual float scalingFactor() = 0;
  cgmColrMode *colrModeCmd;
  virtual int colrMode() = 0;
  cgmLineWidthMode *lineModeCmd;
  virtual int lineMode() = 0;
  cgmMarkerSizeMode *markerModeCmd;
  virtual int markerMode() = 0;
  cgmEdgeWidthMode *edgeModeCmd;
  virtual int edgeMode() = 0;
  cgmVdcExtent *vdcExtentCmd; 
  virtual const vdcPts* vdcExtent()const = 0;
  textInfo tInfo;
  // function to get top level metafile
  virtual cgmMetafile *mfOwner() = 0;
  // is this a metafile ?
  virtual int mf() {return 0;}
};
////
// one picture
////
class cgmPicture : public cgmContainer{
public:
  cgmPicture(cgmMetafile*, cgmInput*, cgmBeginPicture*, cgmPicture* = NULL,
	     filePos=0);
  virtual ~cgmPicture();
  int cgmOut(cgmOutput*); // output to a cgm format
  cgmPicture *next; // next one
  cgmPicture *prev; // previous one
  void display(baseDisplay*);
  // state variables
  const colrValueExtent *colrExtent();
  int scalingMode();
  float scalingFactor();
  int colrMode();
  int lineMode();
  int markerMode();
  int edgeMode();
  const vdcPts* vdcExtent() const;
  filePos pos() {return myPos;}
  int readIn(); // read in the actual contents
  int inMem() const {return !!contents;}
  void setAside(); // store it until we need it
  cgmMetafile *mfOwner() {return metafile;}
  const char *name() {return (myBeginPicture) ? myBeginPicture->name() : NULL;}
  int nameSize() {return (myBeginPicture) ? myBeginPicture->nameSize() : 0;}
  int want() const {return myWant;}
  void setWant(int inWant) {myWant = inWant;}
private:
  int myWant;
  baseCGM *contents; // the contents of this picture
  filePos myPos; // position in file
  cgmInput *myInput; // input file handler
  cgmBeginPicture *myBeginPicture;  
  cgmMetafile *metafile; // the metafile it belongs to 
};
////
// the file itself
////
class cgmMetafile : public cgmContainer{
public:
  cgmMetafile(cgmBeginMetafile *inStart, cgmInput*); // constructor
  virtual ~cgmMetafile(); // destructor
  int cgmOut(cgmOutput*); // output to a cgm format
  // metafile state variables
  cgmMetafileVersion *versionCmd; // metafile version
  int version();
  cgmMetafileDescription *descriptionCmd; // metafile description
  const char *description();
  cgmVdcType *vdcTypeCmd; // VDC type
  vdcType myVdcType() const {return vdcTypeCmd ? vdcTypeCmd->myType : 0;}
  cgmMaxColrIndex *maxColrIndexCmd; // maximum colour index
  int maxColrIndex() const
    {return maxColrIndexCmd ? maxColrIndexCmd->maxIndexValue : 63;}
  cgmColrValueExtent *colrValueExtentCmd; // colour value extent
  colrValueExtent defExtent; // default colour value extent
  const colrValueExtent *colrExtent();
  // picture default state variables
  int scalingMode();
  float scalingFactor();
  int colrMode();
  int lineMode();
  int markerMode();
  int edgeMode();
  vdcPts *intDefVdcExtent; // integer default VDC extent
  vdcPts *floatDefVdcExtent; // float default VDC extent
  const vdcPts* vdcExtent() const; // VDC extent

  cgmPicture *firstPic; // first picture
  void addDefaults(cgmDefaults*); // add a set of defaults
  void displayDefaults(baseDisplay *inDisplay) const; // display the defaults
//	 {for (cgmDefaults *myPtr=myDefaults; myPtr; myPtr=myPtr->next())
//		 myPtr->display(inDisplay);}
  const cgmDefaults *defaults() const {return myDefaults;}
  cgmMetafile *mfOwner() {return this;}
  void display(baseDisplay *inDisplay);
  virtual int mf() {return 1;} // it's a metafile
  int indexed() {return myIndexed;}
  void setIndexed() {myIndexed = 1;}
  int makeIndex(); // try to index the file
  filePos start() {return myStart;}
protected:
  cgmBeginMetafile *contents; // leads to metafile discriptors, etc.
  cgmDefaults *myDefaults; // list of defaults
  cgmInput *myInput; // input file handler
  int myIndexed;
  filePos myStart; // actual start of the metafile
};
////
// a couple of inline functions that couldn't be done earlier
inline cgmMetafile* baseCGM::mfOwner() {return owner->mfOwner();}
inline void cgmBeginMetafile::setOwner(cgmMetafile *inOwner) {owner = inOwner;}
#endif // end of file




