/*
 * t4graph.h --
 *
 *	Main include file for the T4Graph package.
 *
 *	Authors: Jacob Levy and Jean-Claude Wippler.
 *		 jyl@best.com	jcw@equi4.com
 *
 * Copyright (c) 2000-2003, JYL Software Inc.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE, EVEN IF
 * JYL SOFTWARE INC. IS MADE AWARE OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef	__T4GRAPH_H__
#define	__T4GRAPH_H__

#ifndef	__cplusplus
#error This file can only be included in C++ files
#endif

/*
 * External dependencies:
 */

#include "tcl.h"
#include "e4graph.h"

/*
 * Ensure correct shared library exporting in WIN32:
 */

#ifndef e4_TGRAPHDLL
    #if defined(_WIN32) && !defined(E4_STATIC)
        #ifdef E4_TGRAPHDLL
            #define e4_TGRAPHDLL __declspec(dllexport)
        #else
            #define e4_TGRAPHDLL __declspec(dllimport)
        #endif
    #else
        #define e4_TGRAPHDLL
	#define DLLEXPORT
    #endif
#endif

/*
 * Forward declarations of the internal representation types, so they
 * can refer to each other.
 */

class e4_TGRAPHDLL T4InternalRep;
class e4_TGRAPHDLL T4Storage;
class e4_TGRAPHDLL T4Node;
class e4_TGRAPHDLL T4Vertex;

/*
 * These functions must be declared extern "C" so their signatures will
 * not be mangled by the C++ compilers. This is depended upon by the Tcl
 * extension loading mechanism.
 */

extern "C" {
extern DLLEXPORT int		Tgraph_RealInit(Tcl_Interp *interp);
extern DLLEXPORT int		Tgraph_Init(Tcl_Interp *interp);
extern DLLEXPORT int		Tgraph_SafeInit(Tcl_Interp *interp);
extern DLLEXPORT int		Tgraphd_Init(Tcl_Interp *interp);
extern DLLEXPORT int		Tgraphd_SafeInit(Tcl_Interp *interp);
}

/*
 * This structure defines options to be passed to e4_Storage::SetState
 * or an e4_Storage constructor.
 */

typedef struct T4StorageOptions {
    char *driver;		/* String name of storage driver to use. */
    char *rwmode;		/* Read/write mode for storage. */
    int modes;			/* Behavior modes to be set on the newly
				 * opened storage. */
} T4StorageOptions;

/*
 * This structure contains the information about a stored procedure
 * defined as a Tcl procedure for quick access.
 */

typedef struct T4CmdInfo
{
    Tcl_ObjCmdProc *objProc;	/* Command's object-based procedure. */
    ClientData objClientData;	/* User-specified data */
    char *cmdName;		/* Fully qualified command name. */
} T4CmdInfo;

/*
 * Enumeration of the kinds of vertex names. Right now, T4Graph supports
 * two kinds of vertex names:
 *
 * T4VNK_INDEX		"n(3)" or simply "n"
 * T4VNK_RANK		"33" or "-1"
 */

typedef enum T4VertexNameKinds {
    T4VNK_INDEX = 0,
    T4VNK_RANK
} T4VertexNameKinds;

/*
 * Declarations of all command procedures:
 */

extern "C" {
extern int		T4Graph_EventProc(ClientData cd,
					  Tcl_Interp *interp,
					  int objc,
					  Tcl_Obj *CONST objv[]);
extern int		T4Graph_OpenStorageProc(ClientData cd,
						Tcl_Interp *interp,
						int objc,
						Tcl_Obj *CONST objv[]);
extern int		T4Graph_StorageCmdProc(ClientData cd,
					       Tcl_Interp *interp,
					       int objc,
					       Tcl_Obj *CONST objv[]);
extern int		T4Graph_VersionProc(ClientData cd,
					    Tcl_Interp *interp,
					    int objc,
					    Tcl_Obj *CONST objv[]);

}	/* end of extern "C" */

/*
 * Parse the options for storage option control:
 */

extern int		T4Graph_ParseStorageOptions(Tcl_Interp *interp,
						    int objc,
						    Tcl_Obj *CONST objv[],
						    T4StorageOptions *options);

/*
 * Create Tcl commands to manipulate a specific T4Graph object:
 */

extern int		T4Graph_MakeStorageCommand(Tcl_Interp *interp,
						   T4Storage *s);

/*
 * Delete Tcl commands that were created to manipulate T4Graph objects:
 */

extern void		T4Graph_DeleteStorageCommand(Tcl_Interp *interp,
						     T4Storage *s);

/*
 * Define a stored procedure based on the value of a given vertex.
 */

extern T4CmdInfo	*T4Graph_DefineStoredProcedure(Tcl_Interp *interp,
						       char *cmdname,
						       T4Storage *s,
						       e4_Vertex v);

/*
 * Parse a vertex specification. The vertex name can be one of the
 * allowed formats as defined by enum T4VertexNameKinds.
 */

extern int		T4Graph_ParseVertexName(Tcl_Interp *interp, char *spec,
						char **fnp, int *indexp,
						T4VertexNameKinds *vnkp);

/*
 * Parse an insert order name. The name is a string. It is translated
 * by this function into one of the values acceptable for e4_InsertOrder.
 */

extern int		T4Graph_ParseInsertOrder(Tcl_Interp *interp,
						 Tcl_Obj *spec,
						 e4_InsertOrder *iop);

/*
 * This procedure sets up an exit handler for the T4Graph package:
 */

extern void		T4Graph_SetupExitHandler();

/*
 * Procedures to manage the global storage registry:
 */

extern bool		T4Graph_InitStorageRegistry();
extern void		T4Graph_DestroyStorageRegistry();

extern T4Storage *	T4Graph_FirstStorage(Tcl_HashSearch *sp);
extern T4Storage *	T4Graph_NextStorage(Tcl_HashSearch *sp);
extern T4Storage *	T4Graph_FindRegisteredStorage(int id);
extern T4Storage *	T4Graph_RegisterStorage(e4_Storage s,
						char *fnm,
						char *dnm);
extern void		T4Graph_UnregisterStorage(int id);

/*
 * Ensure the interpreter is set up to close storages registered in it
 * when the interpreter is deleted.
 */

extern void		T4Graph_RegisterInterp(Tcl_Interp *interp);

#endif	/* __T4GRAPH_H__ */
