/**********************************************************************

	RecordTypes.x
	
	Internal types for records and formats
	
	Not for outside distribution
	
	This is the non-public portion of the header file for the 
	RecordHander utility funciton
	
	Darick DeHart	5/8/96
	
// SourceSafe information for this version:
//    $Revision: 10 $
//    $Date: 2/27/01 9:06a $
//    $Author: Paul $
***********************************************************************/

#ifndef _RECORDTYPES_
#define _RECORDTYPES_

#include "MiniCadCallBacks.h"


/***********************************************************************

	External Declarations
	
	these things are declared internally, and are here for my external only
	
***********************************************************************/

#if _MINICAD_EXTERNAL_

#define COMPILING_RECORD_LIBRARY 1

typedef long	RefNumber;
typedef short	SysNameVW8;

typedef PStr63  RefName; 

/* From InitGlobals.x */
class BlankType;
typedef BlankType			   *BlankPtr, **BlankHandle;

/* TNumStyle Stuff  - Has all been moved to MiniCadCallBacks.x 
typedef unsigned char			TNumStyleClass;
const TNumStyleClass
struct TNumStyle {
typedef TNumStyle				TNumStyleRef;
*/

class NGNodeTypeMC7
{
public:
	BlankHandle 				next;
	BlankHandle 				prev;
	BlankHandle 				aux;
	short						tdType; 	// contains constant to identify type
	short						mName;
	short						tagSel; 	//	locked/unlocked:selected/not selected
};

typedef char	TDTypeVW8;
//--------------------------------------------------------------------
#pragma pack(push, 2) // BEGIN 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
class NGNodeTypeVW8 {
public:
	BlankHandle 				next;
	BlankHandle 				prev;
	BlankHandle 				aux;
	char						isByClass;
	TDTypeVW8					tdType; 	// contains constant to identify type
	short						mName;
	short						tagSel;
	// TagSelType					tagSel;  locked/unlocked:selected/not selected
	// Darick changed TagSelType to a short
};
#pragma pack(pop) // END 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
//--------------------------------------------------------------------

typedef char	TDType;

//--------------------------------------------------------------------
#pragma pack(push, 2) // BEGIN 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)

class NGNodeTypeVW12
{
public:
	BlankHandle			 		next;		// Pointer in next node in list.
	BlankHandle			 		prev;		// Pointer to previous node in list.
	BlankHandle			 		aux;		// Pointer to start of node's aux list.

	Sint8						unused1;
	TDType						tdType; 	// Constant to identify node type (see "Objs.TDType.h").

	RefNumber					fRefNumber;	// If non-zero, index into the TRefNumberList.  // renamed [MAF 5/28/02]
	short						tagSel; 	// Object state flags.

	RefNumber					classID;	// Prior to VW9, this was in tagSel.classID
	short						isByClass;	// Bitfield to indicate which attributes of the node are controlled by the class to which the node belongs.

	BlankHandle 				owner;		// Group-like parent or AuxOwner

	short						miscFlag;	// auxChild and containerChild bit flags
};

#pragma pack(pop) // END 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
//--------------------------------------------------------------------

//--------------------------------------------------------------------
#pragma pack(push, 2) // BEGIN 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)

class NGNodeType
{
private:
	BlankHandle 				next;		// Pointer in next node in list.
	BlankHandle 				prev;		// Pointer to previous node in list.
	BlankHandle 				aux;		// Pointer to start of node's aux list.
public:
	Sint8						unused1;
	TDType						tdType; 	// Constant to identify node type (see "Objs.TDType.h").
private:            
//	SysName						mName;		// If non-zero, index into the refList.
	RefNumber					fRefNumber;	// If non-zero, index into the TRefNumberList.  // renamed [MAF 5/28/02]
	short						tagSel; 	// Object state flags.
protected:
	RefNumber					classID;	// Prior to VW9, this was in tagSel.classID
	short						isByClass;	// Bitfield to indicate which attributes of the node are controlled by the class to which the node belongs.
private:
	BlankHandle 				owner;		// Group-like parent or AuxOwner
private:
	short						miscFlag;	// auxChild and containerChild bit flags

	Byte						unused[8];	// For future use.


public:
	RefNumber GetRefNumber() { return fRefNumber; }
	TDType    GetTDType()    { return tdType; } 

	void      SetTDType(TDType tdTypeIn)    { tdType = tdTypeIn; } 
};

#pragma pack(pop) // END 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
//--------------------------------------------------------------------

typedef NGNodeType			   *NGNodePtr, **NGNodeHandle;

//--------------------------------------------------------------------
#pragma pack(push, 2) // BEGIN 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
struct FieldIndex {
	short						fieldID;
	short						fieldOffset;
};
#pragma pack(pop) // END 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
//--------------------------------------------------------------------

typedef FieldIndex			   *FieldIndexPtr;

//--------------------------------------------------------------------
#pragma pack(push, 2) // BEGIN 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
struct FieldType {
	short						fieldID;
	short						fieldOffset;
	TNumStyle					numStyle;
	Str20						fieldName;
};
#pragma pack(pop) // END 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
//--------------------------------------------------------------------

typedef FieldType			   *FieldPtr;
typedef FieldType				FieldListType[1];

//--------------------------------------------------------------------
#pragma pack(push, 2) // BEGIN 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
struct FormatTypeMC6 : public NGNodeTypeMC7 {
	short						numberOfFields;
	long						timeStamp;
	FieldListType				fieldList;
};
#pragma pack(pop) // END 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
//--------------------------------------------------------------------

//--------------------------------------------------------------------
#pragma pack(push, 2) // BEGIN 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
struct RecordTypeMC6 : public NGNodeTypeMC7 {
	SysNameVW8 					formatUsed;
	short						firstByte;
};
#pragma pack(pop) // END 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
//--------------------------------------------------------------------

//--------------------------------------------------------------------
#pragma pack(push, 2) // BEGIN 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
struct FormatTypeMC7 : public NGNodeTypeVW8 {
	short						numberOfFields;
	short						subscribeID;  /* Added for 7.0 */
	long						timeStamp;
	FieldListType				fieldList;
};
#pragma pack(pop) // END 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
//--------------------------------------------------------------------

//--------------------------------------------------------------------
#pragma pack(push, 2) // BEGIN 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
struct RecordTypeVW8 : public NGNodeTypeVW8	{
	SysNameVW8 					formatUsed;
	short						unused;  /* Mistakenly added for 7.0 */
	short						firstByte;
};
#pragma pack(pop) // END 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
//--------------------------------------------------------------------

//--------------------------------------------------------------------
#pragma pack(push, 2) // BEGIN 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)

struct RecordTypeVW12 : public NGNodeTypeVW12 {
	RefNumber 					formatUsed;
	short						unused;  /* Mistakenly added for 7.0 */
	short						firstByte;
};

#pragma pack(pop) // END 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
//--------------------------------------------------------------------

//--------------------------------------------------------------------
#pragma pack(push, 2) // BEGIN 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
struct RecordType : public NGNodeType {
	RefNumber 					formatUsed;
	short						unused;  /* Mistakenly added for 7.0 */
	short						firstByte;
};
#pragma pack(pop) // END 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
//--------------------------------------------------------------------

//--------------------------------------------------------------------
#pragma pack(push, 2) // BEGIN 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
class FormatTypeVW8 : public NGNodeTypeVW8
{
public:
	short						numberOfFields;
	short						subscribeID;  /* Added for 7.0 */
	long						timeStamp;
	Boolean						isParametric;		// new and improved for MC8		// JAK 10/28/97
	short						parametricVersion;	// new and improved for MC8		// JAK 10/28/97
	FieldListType				fieldList;
	
	// Filing.
	void ByteSwap(EByteSwapDirection direction);
};
#pragma pack(pop) // END 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
//--------------------------------------------------------------------

//--------------------------------------------------------------------
#pragma pack(push, 2) // BEGIN 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)

struct FormatTypeVW12 : public NGNodeTypeVW12 {
	short						numberOfFields;
	short						subscribeID;  /* Added for 7.0 */
	long						timeStamp;
	Boolean						isParametric;		// new and improved for MC8		// JAK 10/28/97
	short						parametricVersion;	// new and improved for MC8		// JAK 10/28/97
	FieldListType				fieldList;
};

#pragma pack(pop) // END 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
//--------------------------------------------------------------------

//--------------------------------------------------------------------
#pragma pack(push, 2) // BEGIN 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
struct FormatType : public NGNodeType {
	short						numberOfFields;
	short						subscribeID;  /* Added for 7.0 */
	long						timeStamp;
	Boolean						isParametric;		// new and improved for MC8		// JAK 10/28/97
	short						parametricVersion;	// new and improved for MC8		// JAK 10/28/97
	FieldListType				fieldList;
};
#pragma pack(pop) // END 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
//--------------------------------------------------------------------

typedef Handle RecordHandle;
typedef void* RecordPtr;
typedef Handle FormatHandle;


typedef BlankHandle 			ObjectRef;

//--------------------------------------------------------------------
#pragma pack(push, 2) // BEGIN 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
struct RefListType : public NGNodeType {  // tdType == kRefListNode.
	short						refMax;
	ObjectRef					refList[1];	// was refListMax+1
};
#pragma pack(pop) // END 2 BYTE STRUCTURE ALIGNMENT (.vwx file format)
//--------------------------------------------------------------------

typedef struct RecordItemType	*RecordItemPtr;

#else

	#include "FileTranMC7Types.h"
	#include "FileTranMC6Types.h"
	#include "FileTranVW8Types.h"
    #include "FileTranVW12Types.h"
	
#endif  /*_MINICAD_EXTERNAL_ */


/**********************************************************************************************
	
	Common declarations
	
	these are the declarations which are included in both the internal and external project
	
**********************************************************************************************/

/*** Keep version-specific type names updated as type definition changes; ***/
/***  Older version names will migrate to FileTranMCnTypes.x header files ***/

typedef RecordTypeVW8	RecordTypeMC7;
typedef RecordTypeVW12	RecordTypeVW9;
typedef RecordType		RecordTypeVW13;
typedef FormatTypeVW12	FormatTypeVW9;
typedef FormatType		FormatTypeVW13;

class TSmartFormat {
//
//	-Handler class to manage the different file versions of the format structure. 
// 	-Constructor takes a handle and then checks version of Minicad to determine where to find
// 	the fields of the handle.
// 	-The constructor verifies the size of the handle.
// 	-The SizeOf function returns the size of the entire handle, including the dynamic part.
// 	-The static offset functions check the version of MiniCad and return the correct size.
// 	-The accessor functions check that the class is valid, assert the pointer, and return a 
//	pointer to the requested field.
//
	public:
		TSmartFormat( FormatHandle h);
		void SetFormat( FormatHandle h);
		Boolean Verify();	
		size_t SizeOf();
		static size_t OffsetOfNumberOfFields();
		static size_t OffsetOfFieldList();
		
		short* NumberOfFields();
		void SetSubscribeID (short subID);
		long* TimeStamp();
		FieldListType* FieldList();
		Boolean IsValid() {return fValid;}

		void SetIsParametric(Boolean is = true);	// JAK
		Boolean IsParametric();
		void SetParametricVersion(short ver);
		short GetParametricVersion();

				
	private:
		enum EMCVer {kMCUnknown = 0, kMC6 = 6, kMC7 = 7, kMC8 = 8, kMC9 = 9, kMC13 = 13};	// version of FormatType structure

		// Boolean fMC7;				// right now, it's either MC7 or it's false and we're using minicad 6
		EMCVer fMCVer;					//
		FormatTypeMC6** f6Format;
		FormatTypeMC7** f7Format;
		FormatTypeVW8**	f8Format;
		FormatTypeVW9**	f9Format;
		FormatTypeVW13** f13Format;
		Boolean fValid;
};


class TSmartRecord {
//
//	-Handler class to manage the different file versions of the Record structure. 
// 	-Constructor takes a handle and then checks version of Minicad to determine where to find
// 	the fields of the handle.
// 	-The constructor verifies the size of the handle.
// 	-The SizeOf function returns the size of the fixed portion of the record, or the offset to firstByte.
// 	-The static offset functions check the version of MiniCad and return the correct size.
// 	-The accessor functions check that the class is valid, assert the pointer, and return a 
//	pointer to the requested field.
//	
	public:
		TSmartRecord(RecordHandle h);
		Boolean Verify();
		size_t SizeOf();
		static size_t OffsetOfFirstByte();
		
		RefNumber FormatUsed();
		void SetFormatUsed(RefNumber format);
		short* FirstByte();
		Boolean IsValid() {return fValid;}
		
	private:
		enum EMCVer {kMCUnknown = 0, kMC6 = 6, kVW8 = 8, kVW9 = 9, kVW13 = 13 };	// version of RecordType structure

		EMCVer fMCVer;					
		RecordTypeMC6** f6Record;
		RecordTypeVW8** f8Record;
		RecordTypeVW9** f9Record;
		RecordTypeVW13** f13Record;
		Boolean fValid;
};


class TRecordItem;

struct TAddFieldEnv{
	RefNumber    mName;				//format name
 	TRecordItem* value;		//stores the address of the defaultValue
	FormatHandle oldFormat;
	
};

struct TDeleteFieldEnv{
	RefNumber  mName;				//format name
	short      deleteFieldIndex;
	FormatHandle oldFormat;
};

struct FieldConvInfo {
	short	newFieldNum;
	short	oldFieldType;
	short	newFieldType;
};

typedef FieldConvInfo	FormatConvInfo[1];
typedef	FormatConvInfo  *FormatConvInfoPtr, **FormatConvInfoHdl;


// Used for new function CountExistingRecords(). JAK 6/30/99 
struct TCountExistingRecordsEnv {
	RefNumber mName;
	long      count;
};


// Callback functions
extern "C" void FE0addField( MCObjectHandle h, CallBackPtr cbp, void* env);
extern "C" void FE0deleteField( MCObjectHandle h, CallBackPtr cbp, void* env); //expands and deletes a field


// Utility Functions
void AddField_ConvertRecord(RecordHandle &r, const FormatHandle oldFormat, const FormatHandle newFormat, TRecordItem& defaultValue);
void DeleteField_ConvertRecord(RecordHandle &r, const FormatHandle oldFormat, const FormatHandle newFormat, short deleteFieldIndex);
char * GetTextField( const RecordHandle rec, const RecordItemPtr data); 
FormatHandle NewFormat( size_t );
short CalcFieldOffset( short numberOfFields, const FieldListType & fieldList);
Boolean DDSetHandleSize(GSHandle h, size_t newSize);
void DDReduceHandleSize(GSHandle h, size_t newSize);

#if _MINICAD_ 
void FixFormatWithNoDefaultRecord (BlankHandle formatH);
#endif


// Utility functions - from Pk.h
short LastField(FormatHandle theFormat);
void CompactRecord( FormatHandle, RecordHandle);
void ExpandRecord( FormatHandle, RecordHandle);

short FieldSize(long t);
FieldType GetFieldInfo( FormatHandle theFormat, short field);
FieldPtr GetFieldInfoPtr(FormatHandle theFormat, short field);
RecordItemPtr GetField( RecordPtr rec, const FieldType &info);
RecordItemPtr GetField( RecordHandle rec, const FieldType &info);


#if _MINICAD_

//¥ Low Level, to create new record formats only
FormatHandle NewFormat();
void AddFormatXUU(FormatHandle f, const FieldType &newFieldValue);

//¥ Intermediate level
RecordHandle NewRecord(BlankHandle, FormatHandle);
void SetField(FormatHandle theFormat, RecordHandle rec, FieldPtr info,
			const RecordItemType &rValue, const void *dataPtr);

//¥ High Level
enum EStrictDateCheck { eStrictDate, eNotStrictDate };

Ptr GetFieldData(RecordHandle rec, const FieldType &info, const RecordItemType &r);
PString GetFieldString(RecordHandle h, const FieldType &info, bool bMaxAccuracy=false);
Boolean GetFieldText (RecordHandle h, const FieldType &info, const char* &outText, size_t &length);

Boolean SetFieldToString(FormatHandle theFormat, RecordHandle rec,
			FieldPtr info, ConstStr255Param newVal, bool bOnlySetIfValid = false);
Boolean Date2Num(ConstStr255Param, double_gs &, EStrictDateCheck strict=eNotStrictDate);
void FindFormAndRec(RefNumber, BlankHandle &, BlankHandle &);
Boolean CheckAndInsertRecord(BlankHandle, BlankHandle, Boolean);

/* Format Conversion Routines */
void	BuildFormatConvInfo (const FormatHandle oldFmtObj, const FormatHandle newFmtObj,
		                      FormatConvInfoHdl* pConvInfoHdl);
Boolean	TransferFieldValue (TRecordItem* oldItem, TRecordItem* newItem);
Boolean	RecordToNewFormat (RecordHandle recObj, FormatHandle oldFmtObj,
		                    FormatHandle newFmtObj, FormatConvInfo fmtConvInfo);


#endif


#endif //_RECORDTYPES_
