//
// $Revision:   2.9  $
//
// dBASE extensions.
//

#ifndef __DBASEEXT_H__

#define DBEXPORT _cdecl _loadds
#define FARVTABLE _huge

#define DBEXTERR int

class CSession;

#ifndef DBaseVar
class DBaseVar;
typedef long double DoubleType;
#endif

//
// Dlls export this function. This function is called every time an Instance
//  of dBASE loads the DLL.  If for some reason the DLL detirmines that it
//  cannot load, it can return an error.  If the DLL loads properly it should
//  return DBASE_INIT_OK.
//
extern "C" int CALLBACK DBaseInitInstance(void);

#define DBASE_INIT_OK                  0     // init
#define DBASE_INIT_NO_MULTI_INSTANCE   1     // dll can't support multi instance
#define DBASE_INIT_VBX_LOAD_FAIL       2     // VBX failed to load (message already put up by .VBX)
#define DBASE_INIT_ERROR               -1    // error occured loading DLL

//
// DBaseExitInstance() is called when an instance of dBASE terminate or manually
//  unloads a DLL through the RELEASE DLL command.  This give the DLL a chance
//  to free any resources associated with a running instance.
//
extern "C" void CALLBACK DBaseExitInstance(void);

//
// class DBaseExtension is an abstract base class (virtual function definitions
//  only, not implementation) with callbacks into the dBASE executable.  A
//  pointer to this class is retrieved through a call the the function DBase().
//
// Using this virtual call mechanism, a DLL can call into dBASE without getting
//   procedure addresses.
//
class FARVTABLE DBaseExtension {
public:
   //
   // Supplied for future expandability.  Returns pointer to an abstract
   //  base class.
   //
   virtual void* DBEXPORT Supports(int interfaceId)=0;

   //
   // Get the version number of this interface.  This class is designed to be
   //  extended over time.  Each time the interface is extended, the version
   //  label is bumped.
   //
   virtual WORD DBEXPORT GetExtensionVersion()=0;

   //
   // Set the session pointer for the current session.  This call is a
   //  convienance to the DLL programmer.  The DLL programmer can create an
   //  instance of class CSession in the DBaseInitInstance() and set it.
   //  In subsequent call backs, this session pointer can be retrieved with
   //  a call to GetSession().  Data that is kept on a per-instance basis
   //  (DBaseVars for example) should be kept in the session object.
   //
   virtual void DBEXPORT SetSession(CSession *pSession)=0;
   virtual CSession* DBEXPORT GetSession(void)=0;

   //
   // Get a string representation of the Last Error that Occured
   //
   virtual char * DBEXPORT GetError()=0;

   //
   // Set an error to display
   //
   virtual void DBEXPORT SetError(char *)=0;

   //
   // Stop the thread of execution that has called this function.
   //
   virtual void DBEXPORT ReturnError()=0;

   //
   // Variable Manipulation functions
   //
   virtual DBaseVar* DBEXPORT MakeVar()=0;
   virtual void DBEXPORT DestroyVar(DBaseVar*)=0;

   //
   // Returns a pointer to the variable THIS.  If null is returned, the
   //  current execution context is a function, not a method.  Though there
   //  are not protections, one should never write to the variable THIS.
   //
   virtual DBaseVar* DBEXPORT GetThis()=0;

   //
   // Returns the type of a dbase variable.
   //  return values
   //    'L'   = Logical
   //    'N'   = Numeric (floating point DoubleType)
   //    'I'   = Integer Numeric
   //    'C'   = String
   //    'D'   = Date
   //    'O'   = Object
   //    'P'   = Codeblock or function
   //    'M'   = Memo
   //    'B'   = BookMark
   //
   virtual char DBEXPORT VarGetType(DBaseVar*)=0;

   //
   // Retrieves binary value from variable.
   //
   virtual DBEXTERR DBEXPORT VarGetLogical(DBaseVar*, BOOL *pDest)=0;
   virtual DBEXTERR DBEXPORT VarGetDouble(DBaseVar*, DoubleType *pDest)=0;
   virtual DBEXTERR DBEXPORT VarGetLong(DBaseVar*, long *pDest)=0;
   virtual DBEXTERR DBEXPORT VarGetString(DBaseVar*, char**ppDest)=0;
   virtual DBEXTERR DBEXPORT VarGetStringLen(DBaseVar*, int*)=0;
   virtual DBEXTERR DBEXPORT VarGetProperty( DBaseVar* pObj, char* pPropertyName,
            DBaseVar* pDest )=0;

   virtual DBEXTERR DBEXPORT VarGetElement(DBaseVar* pArray,DBaseVar*pDest,
            int iDimCount, DBaseVar**)=0;

   virtual DBEXTERR DBEXPORT VarRunCode(DBaseVar *pSrc,DBaseVar *pDest,
            int iParaCount,DBaseVar**)=0;

   virtual void DBEXPORT VarSetLogical(DBaseVar*, BOOL)=0;
   virtual void DBEXPORT VarSetDouble(DBaseVar*, DoubleType)=0;
   virtual void DBEXPORT VarSetLong(DBaseVar*, long)=0;

   virtual void DBEXPORT VarSetZString(DBaseVar*, char* pDest)=0;
   virtual void DBEXPORT VarSetStringLen(DBaseVar*, int)=0;
   virtual char* DBEXPORT VarGetStringBuffer(DBaseVar*)=0;

   virtual DBEXTERR DBEXPORT VarSetProperty(DBaseVar* pObject, char *pPropName,
            DBaseVar* pNewVal )=0;

   virtual DBEXTERR DBEXPORT VarSetElement(DBaseVar* pArray, int iDimCount,
            DBaseVar** ppParams, DBaseVar* pNewVal)=0;

   virtual DBEXTERR DBEXPORT VarSetCodeBlock(DBaseVar *pSrc, char*)=0;

   //
   // Sets the contents of Variable pSrc from Variable pDest
   //
   virtual void DBEXPORT VarSetVar(DBaseVar *pDest, DBaseVar *pSrc)=0;

};


//
// The function 'DBase()' returns the address of the running instance's
//  DBaseExtension pointer.  This pointer in the 16 bit version is stored at
//  offset 0x40 in the stack segment (executable data segment).
//
// 32 bit versions of dBASE will use a different mechanism, code will be
//  recompilable.
//
#define EXT_PTR   0x30

static DBaseExtension* DBase(){
   DBaseExtension *pRet;

   _asm {
      mov ax,ss:[EXT_PTR]
      mov dx,ss:[EXT_PTR+2]
      mov word ptr pRet,ax
      mov word ptr pRet+2,dx
   }
   return pRet;
}

#define __DBASEEXT_H__
#endif
