/**
 * e4py.h --
 *
 *	This file includes all headers and globals.
 *
 *	Authors: Mike Krimerman.
 *		 hemkond@yahoo.com
 *
 * Copyright (c) 2003, Mike Krimerman.
 * 
 * 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
 * MIKE KRIMERMAN IS MADE AWARE OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __e4py_h
#define __e4py_h

/*
 * We need to temporarily undefine _DEBUG so that debug builds
 * will succeed with a binary distribution on win32 systems.

#ifdef	_DEBUG
#define _WASDEBUG
#undef	_DEBUG
#endif
 */

#include <Python.h>
#include <object.h>

/*
 * Now restore to _DEBUG being defined, if it was defined before
 * include-ing python.h.

#ifdef	_WASDEBUG
#define	_DEBUG
#undef	_WASDEBUG
#endif
 */

#include "e4graph.h"

/*
 *	This section declares the storage interface.
 */

extern	PyTypeObject	PyStorageType;
extern	PyObject	*PyStorage_new(PyObject* o, PyObject* _args);

#define PyStorage_Check(v) ((v)->ob_type == &PyStorageType)

typedef struct {
    PyObject_HEAD
    e4_Storage storage;
} PyStorage;

extern	PyObject	*PyStorage_New();
extern	PyObject	*PyStorage_FromStorage(e4_Storage storage);
extern	e4_Storage&	PyStorage_AsStorage(PyObject* self);

/*
 * This section declares the node interface.
 */

extern	PyTypeObject	PyNodeType;

#define PyNode_Check(v) ((v)->ob_type == &PyNodeType)

typedef struct {
    PyObject_HEAD
    e4_Node node;
} PyNode;

extern	PyObject	*PyNode_New();
extern	PyObject	*PyNode_FromNode(e4_Node node);
extern	e4_Node&	PyNode_AsNode(PyObject* self);

/*
 * This section declares the vertex interface.
 */

extern	PyTypeObject	PyVertexType;

#define PyVertex_Check(v) ((v)->ob_type == &PyVertexType)

typedef struct {
    PyObject_HEAD
    e4_Vertex vertex;
} PyVertex;

extern	PyObject	*PyVertex_New();
extern	PyObject	*PyVertex_FromVertex(e4_Vertex vertex);
extern	e4_Vertex&	PyVertex_AsVertex(PyObject* self);

/*
 * This section declares the storage visitor interface.
 */

extern	PyTypeObject	PyStorageVisitorType;
extern	PyObject	*PyStorageVisitor_new(PyObject* o, PyObject* _args);

#define PyStorageVisitor_Check(v) ((v)->ob_type == &PyStorageVisitorType)

typedef struct {
    PyObject_HEAD
    e4_StorageVisitor visitor;
} PyStorageVisitor;

extern	PyObject	*PyStorageVisitor_New();
extern	PyObject	*PyStorageVisitor_FromStorageVisitor(
						e4_StorageVisitor visitor);
extern	e4_StorageVisitor&
			PyStorageVisitor_AsStorageVisitor(PyObject* self);

/*
 * This section declares the node visitor interface.
 */

extern	PyTypeObject	PyNodeVisitorType;
extern	PyObject 	*PyNodeVisitor_new(PyObject* o, PyObject* _args);

#define PyNodeVisitor_Check(v) ((v)->ob_type == &PyNodeVisitorType)

typedef struct {
    PyObject_HEAD
    e4_NodeVisitor visitor;
} PyNodeVisitor;

extern	PyObject	*PyNodeVisitor_New();
extern	PyObject	*PyNodeVisitor_FromNodeVisitor(e4_NodeVisitor visitor);
extern	e4_NodeVisitor&	PyNodeVisitor_AsNodeVisitor(PyObject* self);

/*
 * This section declares the vertex visitor interface.
 */

extern	PyTypeObject	PyVertexVisitorType;
extern	PyObject	*PyVertexVisitor_new(PyObject* o, PyObject* _args);

#define PyVertexVisitor_Check(v) ((v)->ob_type == &PyVertexVisitorType)

typedef struct {
    PyObject_HEAD
    e4_VertexVisitor visitor;
} PyVertexVisitor;

extern	PyObject	*PyVertexVisitor_New();
extern	PyObject	*PyVertexVisitor_FromVertexVisitor(
						e4_VertexVisitor visitor);
extern	e4_VertexVisitor&
			PyVertexVisitor_AsVertexVisitor(PyObject* self);

/*
 * This section defines APIs for handling errors.
 */

extern	const char	*ErrInvalidNumArgs;
extern	const char	*ErrInvalidArgs;
extern	const char	*ErrInvalidStorage;
extern	const char	*ErrE4;

extern	PyObject	*e4pyExc_APIFailure;

/*
 * This section defines pickling for arbitrary python objects.
 */

extern	PyObject	*PickleTo(PyObject *value);
extern	PyObject	*PickleFrom(const char* buffer, int count = 0);
extern	e4_Value	e4_Value_FromPyObject(PyObject *py_value);
extern	PyObject	*PyObject_Frome4_Value(e4_Value value);

#endif //__e4py_h
