/**********************************************************
Copyright (c) 2000, BeOpen.com.
Copyright (c) 1995-2000, Corporation for National Research Initiatives.
Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
All rights reserved.

See the file "Misc/COPYRIGHT" for information on usage and
redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
******************************************************************/

/* SV module -- interface to the Indigo video board */

/* WARNING! This module is for hardware that we don't have any more,
   so it hasn't been tested.  It has been converted to the new coding
   style, and it is possible that this conversion has broken something
   -- user beware! */

#include <sys/time.h>
#include <svideo.h>
#include "Python.h"
#include "compile.h"
#include "yuv.h"		/* for YUV conversion functions */

typedef struct {
	PyObject_HEAD
	SV_nodeP ob_svideo;
	svCaptureInfo ob_info;
} svobject;

typedef struct {
	PyObject_HEAD
	void *ob_capture;
	int ob_mustunlock;
	svCaptureInfo ob_info;
	svobject *ob_svideo;
} captureobject;

static PyObject *SvError;		/* exception sv.error */

static PyObject *newcaptureobject(svobject *, void *, int);

/* Set a SV-specific error from svideo_errno and return NULL */
static PyObject *
sv_error(void)
{
	PyErr_SetString(SvError, svStrerror(svideo_errno));
	return NULL;
}

static PyObject *
svc_conversion(captureobject *self, PyObject *args, void (*function)(),	float factor)
{
	PyObject *output;
	int invert;
	char* outstr;

	if (!PyArg_Parse(args, "i", &invert))
		return NULL;

	if (!(output = PyString_FromStringAndSize(
		NULL,
		(int)(self->ob_info.width * self->ob_info.height * factor))))
	{
		return NULL;
	}
	if (!(outstr = PyString_AsString(output))) {
		Py_DECREF(output);
		return NULL;
	}

	(*function)((boolean)invert, self->ob_capture,
		    outstr,
		    self->ob_info.width, self->ob_info.height);

	return output;
}

/*
 * 3 functions to convert from Starter Video YUV 4:1:1 format to
 * Compression Library 4:2:2 Duplicate Chroma format.
 */
static PyObject *
svc_YUVtoYUV422DC(captureobject *self, PyObject *args)
{
	if (self->ob_info.format != SV_YUV411_FRAMES) {
		PyErr_SetString(SvError, "data has bad format");
		return NULL;
	}
	return svc_conversion(self, args, yuv_sv411_to_cl422dc, 2.0);
}

static PyObject *
svc_YUVtoYUV422DC_quarter(captureobject *self, PyObject *args)
{
	if (self->ob_info.format != SV_YUV411_FRAMES) {
		PyErr_SetString(SvError, "data has bad format");
		return NULL;
	}
	return svc_conversion(self, args,
			      yuv_sv411_to_cl422dc_quartersize, 0.5);
}

static PyObject *
svc_YUVtoYUV422DC_sixteenth(captureobject *self, PyObject *args)
{
	if (self->ob_info.format != SV_YUV411_FRAMES) {
		PyErr_SetString(SvError, "data has bad format");
		return NULL;
	}
	return svc_conversion(self, args,
			      yuv_sv411_to_cl422dc_sixteenthsize, 0.125);
}

static PyObject *
svc_YUVtoRGB(captureobject *self, PyObject *args)
{
	switch (self->ob_info.format) {
	case SV_YUV411_FRAMES:
	case SV_YUV411_FRAMES_AND_BLANKING_BUFFER:
		break;
	default:
		PyErr_SetString(SvError, "data had bad format");
		return NULL;
	}
	return svc_conversion(self, args, svYUVtoRGB, (float) sizeof(long));
}

static PyObject *
svc_RGB8toRGB32(captureobject *self, PyObject *args)
{
	if (self->ob_info.format != SV_RGB8_FRAMES) {
		PyErr_SetString(SvError, "data has bad format");
		return NULL;
	}
	return svc_conversion(self, args, svRGB8toRGB32, (float) sizeof(long));
}

static PyObject *
svc_InterleaveFields(captureobject *self, PyObject *args)
{
	if (self->ob_info.format != SV_RGB8_FRAMES) {
		PyErr_SetString(SvError, "data has bad format");
		return NULL;
	}
	return svc_conversion(self, args, svInterleaveFields, 1.0);
}

static PyObject *
svc_GetFields(captureobject *self, PyObject *args)
{
	PyObject *f1 = NULL;
	PyObject *f2 = NULL;
	PyObject *ret = NULL;
	int fieldsize;
	char* obcapture;

	if (self->ob_info.format != SV_RGB8_FRAMES) {
		PyErr_SetString(SvError, "data has bad format");
		return NULL;
	}

	fieldsize = self->ob_info.width * self->ob_info.height / 2;
	obcapture = (char*)self->ob_capture;
	
	if (!(f1 = PyString_FromStringAndSize(obcapture, fieldsize)))
		goto finally;
	if (!(f2 = PyString_FromStringAndSize(obcapture + fieldsize,
					      fieldsize)))
		goto finally;
	ret = Py_BuildValue("(OO)", f1, f2);

  finally:
	Py_XDECREF(f1);
	Py_XDECREF(f2);
	return ret;
}
	
static PyObject *
svc_UnlockCaptureData(captureobject *self, PyObject *args)
{
	if (!PyArg_Parse(args, ""))
		return NULL;

	if (!self->ob_mustunlock) {
		PyErr_SetString(SvError, "buffer should not be unlocked");
		return NULL;
	}

	if (svUnlockCaptureData(self->ob_svideo->ob_svideo, self->ob_capture))
		return sv_error();

	self->ob_mustunlock = 0;

	Py_INCREF(Py_None);
	return Py_None;
}

#ifdef USE_GL
#include <gl.h>

static PyObject *
svc_lrectwrite(captureobject *self, PyObject *args)
{
	Screencoord x1, x2, y1, y2;

	if (!PyArg_Parse(args, "(hhhh)", &x1, &x2, &y1, &y2))
		return NULL;

	lrectwrite(x1, x2, y1, y2, (unsigned long *) self->ob_capture);

	Py_INCREF(Py_None);
	return Py_None;
}
#endif

static PyObject *
svc_writefile(captureobject *self, PyObject *args)
{
	PyObject *file;
	int size;
	FILE* fp;

	if (!PyArg_Parse(args, "O", &file))
		return NULL;

	if (!PyFile_Check(file)) {
		PyErr_SetString(SvError, "not a file object");
		return NULL;
	}

	if (!(fp = PyFile_AsFile(file)))
		return NULL;

	size = self->ob_info.width * self->ob_info.height;

	if (fwrite(self->ob_capture, sizeof(long), size, fp) != size) {
		PyErr_SetString(SvError, "writing failed");
		return NULL;
	}

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
svc_FindVisibleRegion(captureobject *self, PyObject *args)
{
	void *visible;
	int width;

	if (!PyArg_Parse(args, ""))
		return NULL;

	if (svFindVisibleRegion(self->ob_svideo->ob_svideo,
				self->ob_capture, &visible,
				self->ob_info.width))
		return sv_error();

	if (visible == NULL) {
		PyErr_SetString(SvError, "data in wrong format");
		return NULL;
	}

	return newcaptureobject(self->ob_svideo, visible, 0);
}

static PyMethodDef capture_methods[] = {
	{"YUVtoRGB",		(PyCFunction)svc_YUVtoRGB},
	{"RGB8toRGB32",		(PyCFunction)svc_RGB8toRGB32},
	{"InterleaveFields",	(PyCFunction)svc_InterleaveFields},
	{"UnlockCaptureData",	(PyCFunction)svc_UnlockCaptureData},
	{"FindVisibleRegion",	(PyCFunction)svc_FindVisibleRegion},
	{"GetFields",		(PyCFunction)svc_GetFields},
	{"YUVtoYUV422DC",	(PyCFunction)svc_YUVtoYUV422DC},
	{"YUVtoYUV422DC_quarter",(PyCFunction)svc_YUVtoYUV422DC_quarter},
	{"YUVtoYUV422DC_sixteenth",(PyCFunction)svc_YUVtoYUV422DC_sixteenth},
#ifdef USE_GL
	{"lrectwrite",		(PyCFunction)svc_lrectwrite},
#endif
	{"writefile",		(PyCFunction)svc_writefile},
	{NULL,			NULL} 		/* sentinel */
};

static void
capture_dealloc(captureobject *self)
{
	if (self->ob_capture != NULL) {
		if (self->ob_mustunlock)
			(void)svUnlockCaptureData(self->ob_svideo->ob_svideo,
						  self->ob_capture);
		self->ob_capture = NULL;
		Py_DECREF(self->ob_svideo);
		self->ob_svideo = NULL;
	}
	PyObject_Del(self);
}

static PyObject *
capture_getattr(svobject *self, char *name)
{
	return Py_FindMethod(capture_methods, (PyObject *)self, name);
}

PyTypeObject Capturetype = {
	PyObject_HEAD_INIT(&PyType_Type)
	0,				/*ob_size*/
	"capture",			/*tp_name*/
	sizeof(captureobject),		/*tp_size*/
	0,				/*tp_itemsize*/
	/* methods */
	(destructor)capture_dealloc,	/*tp_dealloc*/
	0,				/*tp_print*/
	(getattrfunc)capture_getattr,	/*tp_getattr*/
	0,				/*tp_setattr*/
	0,				/*tp_compare*/
	0,				/*tp_repr*/
};

static PyObject *
newcaptureobject(svobject *self, void *ptr, int mustunlock)
{
	captureobject *p;

	p = PyObject_New(captureobject, &Capturetype);
	if (p == NULL)
		return NULL;
	p->ob_svideo = self;
	Py_INCREF(self);
	p->ob_capture = ptr;
	p->ob_mustunlock = mustunlock;
	p->ob_info = self->ob_info;
	return (PyObject *) p;
}

static PyObject *
sv_GetCaptureData(svobject *self, PyObject *args)
{
	void *ptr;
	long fieldID;
	PyObject *res, *c;

	if (!PyArg_Parse(args, ""))
		return NULL;

	if (svGetCaptureData(self->ob_svideo, &ptr, &fieldID))
		return sv_error();

	if (ptr == NULL) {
		PyErr_SetString(SvError, "no data available");
		return NULL;
	}

	c = newcaptureobject(self, ptr, 1);
	if (c == NULL)
		return NULL;
	res = Py_BuildValue("(Oi)", c, fieldID);
	Py_DECREF(c);
	return res;
}

static PyObject *
sv_BindGLWindow(svobject *self, PyObject *args)
{
	long wid;
	int mode;

	if (!PyArg_Parse(args, "(ii)", &wid, &mode))
		return NULL;

	if (svBindGLWindow(self->ob_svideo, wid, mode))
		return sv_error();

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
sv_EndContinuousCapture(svobject *self, PyObject *args)
{

	if (!PyArg_Parse(args, ""))
		return NULL;

	if (svEndContinuousCapture(self->ob_svideo))
		return sv_error();

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
sv_IsVideoDisplayed(svobject *self, PyObject *args)
{
	int v;

	if (!PyArg_Parse(args, ""))
		return NULL;

	v = svIsVideoDisplayed(self->ob_svideo);
	if (v == -1)
		return sv_error();

	return PyInt_FromLong((long) v);
}

static PyObject *
sv_OutputOffset(svobject *self, PyObject *args)
{
	int x_offset;
	int y_offset;

	if (!PyArg_Parse(args, "(ii)", &x_offset, &y_offset))
		return NULL;

	if (svOutputOffset(self->ob_svideo, x_offset, y_offset))
		return sv_error();

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
sv_PutFrame(svobject *self, PyObject *args)
{
	char *buffer;

	if (!PyArg_Parse(args, "s", &buffer))
		return NULL;

	if (svPutFrame(self->ob_svideo, buffer))
		return sv_error();

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
sv_QuerySize(svobject *self, PyObject *args)
{
	int w;
	int h;
	int rw;
	int rh;

	if (!PyArg_Parse(args, "(ii)", &w, &h))
		return NULL;

	if (svQuerySize(self->ob_svideo, w, h, &rw, &rh))
		return sv_error();

	return Py_BuildValue("(ii)", (long) rw, (long) rh);
}

static PyObject *
sv_SetSize(svobject *self, PyObject *args)
{
	int w;
	int h;

	if (!PyArg_Parse(args, "(ii)", &w, &h))
		return NULL;

	if (svSetSize(self->ob_svideo, w, h))
		return sv_error();

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
sv_SetStdDefaults(svobject *self, PyObject *args)
{

	if (!PyArg_Parse(args, ""))
		return NULL;

	if (svSetStdDefaults(self->ob_svideo))
		return sv_error();

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
sv_UseExclusive(svobject *self, PyObject *args)
{
	boolean onoff;
	int mode;

	if (!PyArg_Parse(args, "(ii)", &onoff, &mode))
		return NULL;

	if (svUseExclusive(self->ob_svideo, onoff, mode))
		return sv_error();

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
sv_WindowOffset(svobject *self, PyObject *args)
{
	int x_offset;
	int y_offset;

	if (!PyArg_Parse(args, "(ii)", &x_offset, &y_offset))
		return NULL;

	if (svWindowOffset(self->ob_svideo, x_offset, y_offset))
		return sv_error();

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
sv_CaptureBurst(svobject *self, PyObject *args)
{
	int bytes, i;
	svCaptureInfo info;
	void *bitvector = NULL;
	PyObject *videodata = NULL;
	PyObject *bitvecobj = NULL;
	PyObject *res = NULL;
	static PyObject *evenitem, *odditem;

	if (!PyArg_Parse(args, "(iiiii)", &info.format,
			 &info.width, &info.height,
			 &info.size, &info.samplingrate))
		return NULL;

	switch (info.format) {
	case SV_RGB8_FRAMES:
		bitvector = malloc(SV_BITVEC_SIZE(info.size));
		break;
	case SV_YUV411_FRAMES_AND_BLANKING_BUFFER:
		break;
	default:
		PyErr_SetString(SvError, "illegal format specified");
		return NULL;
	}

	if (svQueryCaptureBufferSize(self->ob_svideo, &info, &bytes)) {
		res = sv_error();
		goto finally;
	}

	if (!(videodata = PyString_FromStringAndSize(NULL, bytes)))
		goto finally;

	/* XXX -- need to do something about the bitvector */
	{
		char* str = PyString_AsString(videodata);
		if (!str)
			goto finally;
		
		if (svCaptureBurst(self->ob_svideo, &info, str, bitvector)) {
			res = sv_error();
			goto finally;
		}
	}

	if (bitvector) {
		if (evenitem == NULL) {
			if (!(evenitem = PyInt_FromLong(0)))
				goto finally;
		}
		if (odditem == NULL) {
			if (!(odditem = PyInt_FromLong(1)))
				goto finally;
		}
		if (!(bitvecobj = PyTuple_New(2 * info.size)))
			goto finally;

		for (i = 0; i < 2 * info.size; i++) {
			int sts;

			if (SV_GET_FIELD(bitvector, i) == SV_EVEN_FIELD) {
				Py_INCREF(evenitem);
				sts = PyTuple_SetItem(bitvecobj, i, evenitem);
			} else {
				Py_INCREF(odditem);
				sts = PyTuple_SetItem(bitvecobj, i, odditem);
			}
			if (sts < 0)
				goto finally;
		}
	} else {
		bitvecobj = Py_None;
		Py_INCREF(Py_None);
	}

	res = Py_BuildValue("((iiiii)OO)", info.format,
			    info.width, info.height,
			    info.size, info.samplingrate,
			    videodata, bitvecobj);

  finally:
	if (bitvector)
		free(bitvector);

	Py_XDECREF(videodata);
	Py_XDECREF(bitvecobj);
	return res;
}

static PyObject *
sv_CaptureOneFrame(svobject *self, PyObject *args)
{
	svCaptureInfo info;
	int format, width, height;
	int bytes;
	PyObject *videodata = NULL;
	PyObject *res = NULL;
	char *str;
	
	if (!PyArg_Parse(args, "(iii)", &format, &width, &height))
		return NULL;

	info.format = format;
	info.width = width;
	info.height = height;
	info.size = 0;
	info.samplingrate = 0;
	if (svQueryCaptureBufferSize(self->ob_svideo, &info, &bytes))
		return sv_error();

	if (!(videodata = PyString_FromStringAndSize(NULL, bytes)))
		return NULL;
	
	str = PyString_AsString(videodata);
	if (!str)
		goto finally;

	if (svCaptureOneFrame(self->ob_svideo, format, &width, &height, str)) {
		res = sv_error();
		goto finally;
	}

	res = Py_BuildValue("(iiO)", width, height, videodata);

  finally:
	Py_XDECREF(videodata);
	return res;
}

static PyObject *
sv_InitContinuousCapture(svobject *self, PyObject *args)
{
	svCaptureInfo info;

	if (!PyArg_Parse(args, "(iiiii)", &info.format,
			 &info.width, &info.height,
			 &info.size, &info.samplingrate))
		return NULL;

	if (svInitContinuousCapture(self->ob_svideo, &info))
		return sv_error();

	self->ob_info = info;

	return Py_BuildValue("(iiiii)", info.format, info.width, info.height,
			     info.size, info.samplingrate);
}

static PyObject *
sv_LoadMap(svobject *self, PyObject *args)
{
	PyObject *rgb;
	PyObject *res = NULL;
	rgb_tuple *mapp = NULL;
	int maptype;
	int i, j;			     /* indices */

	if (!PyArg_Parse(args, "(iO)", &maptype, &rgb))
		return NULL;

	if (!PyList_Check(rgb) || PyList_Size(rgb) != 256) {
		PyErr_BadArgument();
		return NULL;
	}

	if (!(mapp = PyMem_NEW(rgb_tuple, 256)))
		return PyErr_NoMemory();

	for (i = 0; i < 256; i++) {
		PyObject* v = PyList_GetItem(rgb, i);
		if (!v)
			goto finally;

		if (!PyTuple_Check(v) || PyTuple_Size(v) != 3) {
			PyErr_BadArgument();
			goto finally;
		}
		for (j = 0; j < 3; j++) {
			PyObject* cell = PyTuple_GetItem(v, j);
			if (!cell)
				goto finally;

			if (!PyInt_Check(cell)) {
				PyErr_BadArgument();
				goto finally;
			}
			switch (j) {
			case 0: mapp[i].red = PyInt_AsLong(cell); break;
			case 1: mapp[i].blue = PyInt_AsLong(cell); break;
			case 2: mapp[i].green = PyInt_AsLong(cell); break;
			}
			if (PyErr_Occurred())
				goto finally;
		}
	}

	if (svLoadMap(self->ob_svideo, maptype, mapp)) {
		res = sv_error();
		goto finally;
	}

	Py_INCREF(Py_None);
	res = Py_None;

  finally:
	PyMem_DEL(mapp);
	return res;
}
		
static PyObject *
sv_CloseVideo(svobject *self, PyObject *args)
{
	if (!PyArg_Parse(args, ""))
		return NULL;

	if (svCloseVideo(self->ob_svideo))
		return sv_error();

	self->ob_svideo = NULL;
	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
doParams(svobject *self, PyObject *args,
         int (*func)(SV_nodeP, long *, int), int modified)
{
	PyObject *list;
	PyObject *res = NULL;
	long *PVbuffer = NULL;
	long length;
	int i;
	
	if (!PyArg_Parse(args, "O", &list))
		return NULL;

	if (!PyList_Check(list)) {
		PyErr_BadArgument();
		return NULL;
	}

	if ((length = PyList_Size(list)) < 0)
		return NULL;

	PVbuffer = PyMem_NEW(long, length);
	if (PVbuffer == NULL)
		return PyErr_NoMemory();

	for (i = 0; i < length; i++) {
		PyObject *v = PyList_GetItem(list, i);
		if (!v)
			goto finally;

		if (!PyInt_Check(v)) {
			PyErr_BadArgument();
			goto finally;
		}
		PVbuffer[i] = PyInt_AsLong(v);
		/* can't just test the return value, because what if the
		   value was -1?!
		*/
		if (PVbuffer[i] == -1 && PyErr_Occurred())
			goto finally;
	}

	if ((*func)(self->ob_svideo, PVbuffer, length)) {
		res = sv_error();
		goto finally;
	}

	if (modified) {
		for (i = 0; i < length; i++) {
			PyObject* v = PyInt_FromLong(PVbuffer[i]);
			if (!v || PyList_SetItem(list, i, v) < 0)
				goto finally;
		}
	}

	Py_INCREF(Py_None);
	res = Py_None;

  finally:
	PyMem_DEL(PVbuffer);
	return res;
}

static PyObject *
sv_GetParam(PyObject *self, PyObject *args)
{
	return doParams(self, args, svGetParam, 1);
}

static PyObject *
sv_GetParamRange(PyObject *self, PyObject *args)
{
	return doParams(self, args, svGetParamRange, 1);
}

static PyObject *
sv_SetParam(PyObject *self, PyObject *args)
{
	return doParams(self, args, svSetParam, 0);
}

static PyMethodDef svideo_methods[] = {
	{"BindGLWindow",	(PyCFunction)sv_BindGLWindow},
	{"EndContinuousCapture",(PyCFunction)sv_EndContinuousCapture},
	{"IsVideoDisplayed",	(PyCFunction)sv_IsVideoDisplayed},
	{"OutputOffset",	(PyCFunction)sv_OutputOffset},
	{"PutFrame",		(PyCFunction)sv_PutFrame},
	{"QuerySize",		(PyCFunction)sv_QuerySize},
	{"SetSize",		(PyCFunction)sv_SetSize},
	{"SetStdDefaults",	(PyCFunction)sv_SetStdDefaults},
	{"UseExclusive",	(PyCFunction)sv_UseExclusive},
	{"WindowOffset",	(PyCFunction)sv_WindowOffset},
	{"InitContinuousCapture",(PyCFunction)sv_InitContinuousCapture},
	{"CaptureBurst",	(PyCFunction)sv_CaptureBurst},
	{"CaptureOneFrame",	(PyCFunction)sv_CaptureOneFrame},
	{"GetCaptureData",	(PyCFunction)sv_GetCaptureData},
	{"CloseVideo",		(PyCFunction)sv_CloseVideo},
	{"LoadMap",		(PyCFunction)sv_LoadMap},
	{"GetParam",		(PyCFunction)sv_GetParam},
	{"GetParamRange",	(PyCFunction)sv_GetParamRange},
	{"SetParam",		(PyCFunction)sv_SetParam},
	{NULL,			NULL} 		/* sentinel */
};

static PyObject *
sv_conversion(PyObject *self, PyObject *args, void (*function)(),
              int inputfactor, float factor)
{
	int invert, width, height, inputlength;
	char *input, *str;
	PyObject *output;

	if (!PyArg_Parse(args, "(is#ii)", &invert,
			 &input, &inputlength, &width, &height))
		return NULL;

	if (width * height * inputfactor > inputlength) {
		PyErr_SetString(SvError, "input buffer not long enough");
		return NULL;
	}

	if (!(output = PyString_FromStringAndSize(NULL,
					      (int)(width * height * factor))))
		return NULL;

	str = PyString_AsString(output);
	if (!str) {
		Py_DECREF(output);
		return NULL;
	}
	(*function)(invert, input, str, width, height);

	return output;
}

static PyObject *
sv_InterleaveFields(PyObject *self, PyObject *args)
{
	return sv_conversion(self, args, svInterleaveFields, 1, 1.0);
}

static PyObject *
sv_RGB8toRGB32(PyObject *self, PyObject *args)
{
	return sv_conversion(self, args, svRGB8toRGB32, 1, (float) sizeof(long));
}

static PyObject *
sv_YUVtoRGB(PyObject *self, PyObject *args)
{
	return sv_conversion(self, args, svYUVtoRGB, 2, (float) sizeof(long));
}

static void
svideo_dealloc(svobject *self)
{
	if (self->ob_svideo != NULL)
		(void) svCloseVideo(self->ob_svideo);
	PyObject_Del(self);
}

static PyObject *
svideo_getattr(svobject *self, char *name)
{
	return Py_FindMethod(svideo_methods, (PyObject *)self, name);
}

PyTypeObject Svtype = {
	PyObject_HEAD_INIT(&PyType_Type)
	0,			/*ob_size*/
	"sv",			/*tp_name*/
	sizeof(svobject),	/*tp_size*/
	0,			/*tp_itemsize*/
	/* methods */
	(destructor)svideo_dealloc, /*tp_dealloc*/
	0,			/*tp_print*/
	(getattrfunc)svideo_getattr, /*tp_getattr*/
	0,			/*tp_setattr*/
	0,			/*tp_compare*/
	0,			/*tp_repr*/
};

static PyObject *
newsvobject(SV_nodeP svp)
{
	svobject *p;

	p = PyObject_New(svobject, &Svtype);
	if (p == NULL)
		return NULL;
	p->ob_svideo = svp;
	p->ob_info.format = 0;
	p->ob_info.size = 0;
	p->ob_info.width = 0;
	p->ob_info.height = 0;
	p->ob_info.samplingrate = 0;
	return (PyObject *) p;
}

static PyObject *
sv_OpenVideo(PyObject *self, PyObject *args)
{
	SV_nodeP svp;

	if (!PyArg_Parse(args, ""))
		return NULL;

	svp = svOpenVideo();
	if (svp == NULL)
		return sv_error();

	return newsvobject(svp);
}

static PyMethodDef sv_methods[] = {
	{"InterleaveFields",	(PyCFunction)sv_InterleaveFields},
	{"RGB8toRGB32",		(PyCFunction)sv_RGB8toRGB32},
	{"YUVtoRGB",		(PyCFunction)sv_YUVtoRGB},
	{"OpenVideo",		(PyCFunction)sv_OpenVideo},
	{NULL,			NULL}	/* Sentinel */
};

void
initsv(void)
{
	PyObject *m, *d;

	m = Py_InitModule("sv", sv_methods);
	d = PyModule_GetDict(m);

	SvError = PyErr_NewException("sv.error", NULL, NULL);
	if (SvError == NULL || PyDict_SetItemString(d, "error", SvError) != 0)
		return;
}
