/************************************************************************
 *   gadt.h   : base class for GFC ADTs and iterator classes.
 *   
 *   Change Log :
 *		  Spring 1996 Initial version,  Liujian Qian
 *		
 *   $Id: gadt.h,v 1.6 1998/12/10 00:11:23 qian Exp $
 ************************************************************************/
#ifndef _GADT_H_
#define _GADT_H_

#include "gcxx.h"
#include "gobject.h"

class GADT;
class GSpatial;
class GTemporal;
class GInt; 	    	class GChar;     
class GReal;   		class GVarchar;
class GTimestamp;
class GPoint;     	class GRect;     
class GCircle; 		class GTrig;
class GSegment;   	class GArc;
class GPolygon;   	class GGrid;     
class GRaster; 		class GGraph;

class DataPipe;
class GMatrix;


struct GADTDef 
{
    int  	type;
    char	*name;
    uint8   	fixed_size;	//whether this ADT has fixed size
    uint8	spatial;	//1 if a spatial ADT; otherwise 0
    GADT	*instance;
    GADTDef	*next;

    GADTDef(int _t, char* _name, uint8 fixed, uint8 _spatial, GADT* _inst) 
	: type(_t), name(_name), fixed_size(fixed), 
	  spatial(_spatial), instance(_inst), next(0)
    {};
};

class GADTManager
{
    static int		n_adts;
    static GADTDef	*adts;

    static GADTDef*	search(GType t);
public:
    /**
     * this method registers a new ADT for GFC.
     */
    static int		registerADT	(GADTDef* adt_def);
    /**
     * remove an item for the specific ADT
     */
    static void		removeADT	(GType t);
    /**
     * give the ascii name of an ADT
     */
    static const char* 	getName		(GType t);
    /**
     * give the size of a type (if possible)
     */
    static int		isFixedSize	(GType t);
    /**
     * return the preallocated object pointer with given type
     */
    static GADT*    	getPtr 		(GType t);
    /**
     * return a new object pointer
     */
    static GADT*   	getNewPtr	(GType t);
    /**
     * determine whether the given type is spatial ADT
     */
    static bool	   	isSpatial	(GType t);
    /**
     * determine if the given type has "large instance/object"
     */
    static bool	   	isLarge 	(GType t);
    /**
     * check whether the ADT is areal (2D) type
     */
    static bool		isAreal		(GType t);

    static void		printAll	(ostream& os);
    static int		numADTs		();
};

#define MATCHTYPE(x)	{ GAssert(type()==(x).type()) }
      


//////////////////////////////////////////////////////////////////////
//
/**
      Mother of all GFC ADTs.
      
      This is an abstract base class derived by all GFC ADTs.
      Important public methods includ conversion routines between
      secondary storage, main memory and ASCII string formats of 
      the same ADT object, as well as other run-time type information
      such as the type and the name of the ADTs.

      From GFC's point of view, the secondary storage (mostly in the 
      form of a database or a file) format is simply a block of binary 
      data (a serialized version of all the useful data members that 
      need to be persistent). The serialization is achieved by a pair of 
      virtual functions pack() and unpack(). Both
      functions take a reference to a DataPipe object, where
      the binary chunk of data are hold. The DataPipe class supports a
      dynamic binary data array with intelligent memory allocations.
      The use of DataPipe simplifies the passing-around of individual data 
      objects which usualy are of of variable length. 
      
      Most of the ADT objects can accept a user string (with an
      agreed format per ADT) and initialize the data members out of the
      string. This is done by the input() method.  Naturally there
      is an output() function that  converts data members into
      an ASCII string. 

      Besides converting routines mentioned above, each ADT class
      has the following common methods:

      <DL>
      <DT> operator=()<DD> the assignment operator
      <DT> type()     <DD> returns the GType number 
      <DT> clone()    <DD> return a heap-based GADT object which 
                           has same run-time type of 'this'. The new
			   object is initialized (i.e. its NOT a copy
			   of the the generating object).
      <DT> 
*/
class GADT  : public GObject
{
protected:
    //for output() buffer 
    DataPipe		bp;    

public:

    /**
     */
    NOP			GADT() {};
    /**
     */
    virtual NOP		~GADT() {};

    /**
     * return the dynamic type
     */
    virtual GType  	type  (void) const {return _Base;}

    /**
     * return a new (clean) ADT object with same type
     */
    virtual GADT*  	clone () const {return (GADT*)0; }

    /**
     *  comparing two objects (of same type) -- not  supported
     */
    virtual int	 	cmp   (const GADT& ) const {return UNDEFINED;} 

    /**
     *  for testing only
     */
    static  void 	statRep   ();

private:
    //for memory usage checking only
    static  int		n_new;	
    static  int		n_delete;
};  //class GADT




/** 
 * Base class for all Spatial ADTs. 
 */
class GSpatial : public GADT
{

public:

    /** 
     * scale the coordinates of spatial ADTs by xf,yf,zf
     */
    virtual Result    	scale      (double , double , double zf=1) =0;

    /**
     *  translate the coordinates of spatial ADTs by xf, yf, zf
     */
    virtual Result     	translate  (double , double , double zf=1) = 0;
    
    /**
     * rotate the spatial object by 'd' degree.
     */
    virtual Result	rotate	   (double d, bool clock_wise) = 0;

    /**
     * perform a 2D transformation as specified in matrix m
     */
    virtual Result	transform  (const GMatrix& m) = 0;

    /**
     * get the minimum bounding rectangle (only for spatial ADTs)
     */
    virtual Result  	mbr	   (GRect& b) const = 0;
    
    /**
     * tests if this object intersects 'a'
     */
    virtual int		intersects (const GSpatial& a) const = 0;

    /**
     * tests if it covers 'a'
     */
    virtual int   	covers     (const GSpatial& a) const = 0;

};


/**
 * Base class for all Temporal ADTs
 */
class GTemporal : public GADT
{
    
public:
    
    /** 
     * change the temporal scale of this value
     */
    virtual Result	scale	  (int) = 0;

    /**
     * check if this temporal value is Earlier Than 'a' 
     */
    virtual int		before	  (const GTemporal& a) const = 0;
    
    /**
     *  check if this  temporal value is Later than 'a'
     */
    virtual int 	after	  (const GTemporal& a) const = 0;
    
    /**
     * check if this temporal value is during 'a'
     */
    virtual int		during	  (const GTemporal& a) const = 0;

    /**
     * check if this temporal value overlaps 'a'
     */
    virtual int		overlap	  (const GTemporal& a) const = 0;
};


#endif

Documentation generated by lqian@lqian-sun on Wed Jul 14 09:36:10 EDT 1999