// This file contains the C++ code necessary marshal and demarshal
// all the _simple_ types that dcoppython can understand.
// "Simple" types are types that do not contain other types.
// So, int and QString are simple types; QDict, QMap and QStringList are not.
// This file is processed by gen_marshal_code.py to produce a header
// file, which is included by marshaller.cpp
//
// Marshalling:
//   The code in the "marshal" section has the following variables available:
//     PyObject * obj; // the object to marshal
//     QDataStream *str; // the stream to marshal to
//   The function should return true if the object can be marshalled.
//   str may be NULL. If so, the function should ignore the actually marshalling
//   and merely return true or false, depending on whether the object _could_
//   be marshalled.
//
// Demarshalling:
//   The code in the "demarshal" section has the following variables available:
//     QDataStream *str; // the stream to demarshal from
//   The function should return a PyObject* which is a reference to the
//   newly created object. Ownership of the reference should be passed to
//   the caller. The function can return null if for any reason it
//   could not demarshal.

type: void
%% marshall
{
  Q_UNUSED(str); // stop warnings
  Q_UNUSED(obj);
  return true;
}
%% demarshal
{
  Q_UNUSED(str); // stop warnings
  Py_INCREF(Py_None);
  return Py_None;
}

type: bool
%doc as int b (1=True, 2=False)
%doc info Any Python object is converted to bool by the standard Python truth test.
%% from_pyobj
  {
    *ok=true;
    return PyObject_IsTrue(obj);
  }
%% to_pyobj
  {
    return PyInt_FromLong(val ? 1 : 0);
  }
%% marshal
  {
    if (str) {
      bool ok;
      bool b = fromPyObject_bool(obj,&ok);
      (*str) << (Q_INT8)b;
    }
    return true;
  }
%% demarshal
  {
    Q_INT8 i;
    (*str) >> i;
    return toPyObject_bool(i!=0);
  }
%%

type:int
%doc as int i
%% marshal
  {
    if (!PyInt_Check(obj)) return false;
    if (str) {
      (*str) << (Q_INT32)PyInt_AsLong(obj);
    }
    return true;
  }
%% demarshal
  {
    Q_INT32 i;
    (*str) >> i;
    return PyInt_FromLong( (long)i );
  }
%%

type:uint
%doc as int i
%% marshal
  {
    if (!PyInt_Check(obj)) return false;
    if (str) {
      (*str) << (Q_INT32)PyInt_AsLong(obj);
    }
    return true;
  }
%% demarshal
  {
    Q_INT32 i;
    (*str) >> i;
    return PyInt_FromLong( (long)i );
  }
%%

type:double
%doc as float i
%% marshal
  {
    if (!PyFloat_Check(obj)) return false;
    if (str) {
      (*str) << PyFloat_AsDouble(obj);
    }
    return true;
  }
%% demarshal
  {
    double d;
    (*str) >> d;
    return PyFloat_FromDouble(d);
  }
%%

type:uchar
%doc as str c
%doc as int c
%% marshal
  {
    if (PyString_Check(obj) && PyString_Size(obj)==1) {
      if (str) {
        char *c = PyString_AsString(obj);
        (*str) << (*c);
      }
      return true;
    }

    if (PyInt_Check(obj)) {
      if (str) {
        long l = PyInt_AsLong(obj);
        Q_UINT8 c = (Q_UINT8)(l & 0xff);
        (*str) << c;
      }
      return true;
    }

    return false;
  }
%%demarshal
  {
    Q_UINT8 c;
    (*str) >> c;
    return PyString_FromStringAndSize((const char *)(&c),1);
  }
%%

type:char
%doc as int c
%% marshal
  {
    if (PyInt_Check(obj)) {
      if (str) {
        long l = PyInt_AsLong(obj);
        Q_INT8 c = (Q_INT8)(l & 0xff);
        (*str) << c;
      }
      return true;
    }

    return false;
  }
%%demarshal
  {
    Q_INT8 c;
    (*str) >> c;
    return PyInt_FromLong((long)c);
  }
%%


type:QByteArray
%% marshal
  {
    PyBufferProcs *pb = obj->ob_type->tp_as_buffer;

    if ( pb && pb->bf_getreadbuffer && pb->bf_getsegcount )
    {
      // Get the number of buffer segments
      int seg_count = (pb->bf_getsegcount)(obj, 0);

      if ( seg_count != 1 )
        // Can't handle more (or less) than 1 buffer segment
        // at the moment
        return false;

      // Get buffer size and data
      void *data;
      int size;

      if ( (size = (pb->bf_getreadbuffer)(obj, 0, &data)) < 0 )
        return false;

      if (str) {
        QByteArray a;
        a.setRawData( (const char*)data, size );
        (*str) << a;
        a.resetRawData( (const char*)data, size );
      }

      return true;
    }
    else
      // obj does not implement the buffer interface
      return false;
  }
%% demarshal
  {
    // Demarshal to a writable buffer object
    QByteArray a;
    (*str) >> a;

    uint size = a.size();
    char *data = a.data();

    // Create a new buffer object and copy the data.
    // Don't use PyBuffer_FromMemory() and the likes since
    // that wouldn't give correct allocation and deallocation.

    PyObject *buffer_obj = PyBuffer_New( size );

    if ( !buffer_obj )
      return NULL;

    PyBufferProcs *pb = buffer_obj->ob_type->tp_as_buffer;

    void *buffer_data;

    (pb->bf_getwritebuffer)( buffer_obj, 0, &buffer_data );

    for ( uint i = 0; i < size; i++ )
      ((char*)buffer_data)[i] = data[i];

    return buffer_obj;
  }
%%

type:QString
%doc as str s
%% marshal
  {
    if (!PyString_Check(obj)) return false;
    if (str) {
      QString s( PyString_AsString(obj) );
      (*str) << s;
    }
    return true;
  }
%% demarshal
  {
    QString s;
    (*str) >> s;
    return PyString_FromString( s.utf8().data() );
  }
%%

type:QCString
%doc as str s
%% marshal
  {
    if (!PyString_Check(obj)) return false;
    if (str) {
      QCString s( PyString_AsString(obj) );
      (*str) << s;
    }
    return true;
  }
%% demarshal
  {
    QCString s;
    (*str) >> s;
    return PyString_FromString( s.data() );
  }
%%

type:QRect
%doc as ( (int x1, int y1), (int x2, int y2) )
%doc as ( int x1, int y1, int x2, int y2 )
%% from_pyobj
{
  int xp1, yp1, xp2, yp2;
  QRect r;
  *ok=false;
  if (!PyTuple_Check(obj)) return r;
  if (!PyArg_ParseTuple(obj, (char*)"(ii)(ii)", &xp1, &yp1, &xp2, &yp2) &&
      !PyArg_ParseTuple(obj, (char*)"iiii", &xp1, &yp1, &xp2, &yp2))
    return r;
  r.setCoords( xp1, yp1, xp2, yp2 );
  *ok=true;
   return r;
}
%% to_pyobj
{
  int xp1, yp1, xp2, yp2;
  val.coords(&xp1,&yp1,&xp2,&yp2);
  return Py_BuildValue((char*)"(ii)(ii)", xp1, yp1, xp2, yp2);
}

%% marshal
%defaultcode
%% demarshal
%defaultcode
%%

type:QPoint
%doc as (int x, int y)
%% from_pyobj
{
  int x,y;
  QPoint p;
  *ok=false;
  if (!PyTuple_Check(obj)) return p;
  if (!PyArg_ParseTuple(obj, (char*)"ii", &x, &y))
    return p;
  p.setX(x);
  p.setY(y);
  *ok=true;
  return p;
}
%% to_pyobj
{
  return Py_BuildValue((char*)"ii", val.x(), val.y() );
}
%% marshall
%defaultcode
%% demarshall
%defaultcode
%%

type:QSize
%doc as (int width, int height)
%% from_pyobj
{
  int w,h;
  QSize sz;
  *ok=false;
  if (!PyTuple_Check(obj)) return sz;
  if (!PyArg_ParseTuple(obj, (char*)"ii", &w, &h))
    return sz;
  sz.setWidth(w);
  sz.setHeight(h);
  *ok=true;
  return sz;
}
%% to_pyobj
{
  return Py_BuildValue((char*)"ii", val.width(), val.height() );
}
%% marshall
%defaultcode
%% demarshall
%defaultcode
%%

type:QColor
%doc as (int red, int green, int blue)
%% from_pyobj
{
  int r,g,b;
  QColor c;
  *ok=false;
  if (!PyTuple_Check(obj)) return c;
  if (!PyArg_ParseTuple(obj, (char*)"iii", &r, &g, &b))
    return c;
  c.setRgb(r,g,b);
  *ok=true;
  return c;
}
%% to_pyobj
{
  return Py_BuildValue((char*)"iii", val.red(), val.green(), val.blue() );
}
%% marshall
%defaultcode
%% demarshall
%defaultcode
%%

type:QPointArray
%doc as [ (int x, int y), (int x, int y), (int x, int y), ... ]
%% from_pyobj
{
  *ok=false;
  if (!PyList_Check(obj)) return QPointArray();
  int size = PyList_Size(obj);
  QPointArray pa(size);
  for(int c=0;c<size;c++) {
    QPoint p = fromPyObject_QPoint(PyList_GetItem(obj,c), ok);
    if (!*ok) return false;
    pa.setPoint(c,p);
  }
  *ok=true;
  return pa;
}
%% to_pyobj
{
  PyObject *obj = PyList_New(val.size());
  if (!obj) return NULL;
  for(uint c=0;c<val.size();c++) {
    PyObject *tuple = toPyObject_QPoint( val.point(c) );
    PyList_SetItem(obj, c, tuple);
//    Py_DECREF(tuple);
  }
  return obj;
}
%% marshall
%defaultcode
%% demarshall
%defaultcode
%%

type:QDate
%doc as (int year, int month, int day)
%% from_pyobj
{
  *ok=false;
  if (!PyTuple_Check(obj)) return QDate();
  int y,m,d;
  if (!PyArg_ParseTuple(obj, (char*)"iii", &y, &m, &d))
    return QDate();
  *ok=true;
  return QDate(y,m,d);
}
%% to_pyobj
{
  return Py_BuildValue((char*)"iii", val.year(), val.month(), val.day() );
}
%% marshal
%defaultcode
%% demarshal
%defaultcode
%%

type:QTime
%doc as (int hour, int minute, int second=0, int millisecond=0)
%% from_pyobj
{
  *ok=false;
  if (!PyTuple_Check(obj)) return QTime();
  int h,m,s=0,ms=0;
  if (!PyArg_ParseTuple(obj, (char*)"ii|ii", &h, &m, &s, &ms))
    return QTime();
  *ok=true;
  return QTime(h,m,s,ms);
}
%% to_pyobj
{
  return Py_BuildValue((char*)"iiii", val.hour(), val.minute(), val.second(), val.msec() );
}
%% marshal
%defaultcode
%% demarshal
%defaultcode
%%

type:QDateTime
%doc as ( (int year, int month, int day), (int hour, int minute, int second=0, int millsecond=0) )
%doc as long unixDate
%% from_pyobj
{
  *ok=false;

  if (PyLong_Check(obj)) {
    *ok=true;
    QDateTime dt;
    dt.setTime_t( (uint)PyLong_AsLong(obj) );
    return dt;
  }

  if (PyInt_Check(obj)) {
    *ok=true;
    QDateTime dt;
    dt.setTime_t( (uint)PyInt_AsLong(obj) );
    return dt;
  }

  PyObject *date_tuple, *time_tuple;
  if (PyArg_ParseTuple(obj, (char*)"OO", &date_tuple, &time_tuple)) {
    QDateTime dt;
    dt.setTime( fromPyObject_QTime(time_tuple, ok) );
    if (*ok) dt.setDate( fromPyObject_QDate(date_tuple, ok) );
    return dt;
  }

  return QDateTime();
}
%% to_pyobj
{
  PyObject *date_tuple = toPyObject_QDate( val.date() );
  PyObject *time_tuple = toPyObject_QTime( val.time() );
  return Py_BuildValue((char*)"OO", date_tuple, time_tuple );
}
%% marshal
%defaultcode
%% demarshal
%defaultcode
%%

type:KURL
%doc as str url
%% from_pyobj
{
  *ok=false;
  if (!PyString_Check(obj)) return KURL();
  *ok=true;
  return KURL( QString(PyString_AsString(obj)) );
}
%% to_pyobj
{
  return PyString_FromString( val.prettyURL().utf8().data() );
}
%% marshal
%defaultcode
%% demarshal
%defaultcode
%%

type:DCOPRef
%% from_pyobj
{
  if (PyInstance_Check(obj) &&
      PyObject_HasAttrString(obj, (char*)"appname") &&
      PyObject_HasAttrString(obj, (char*)"name")) {
    PyObject *appname = PyObject_GetAttrString(obj, (char*)"appname");
    PyObject *name = PyObject_GetAttrString(obj, (char*)"name");
    if (PyString_Check(appname) && PyString_Check(name)) {
      char *c_appname = PyString_AsString(appname);
      char *c_name = PyString_AsString(name);
      DCOPRef ref;
      ref.setRef(QCString(c_appname), QCString(c_name) );
      Py_DECREF(appname);
      Py_DECREF(name);
      *ok=true;
      return ref;
    }
    Py_DECREF(appname);
    Py_DECREF(name);
  }
  *ok=false;
  return DCOPRef();
}
%% to_pyobj
{
  if (val.isNull()) {
    Py_INCREF(Py_None);
    return Py_None;
  }
  return ImportedModules::instance()->createDCOPObject(val.app(), val.object() );
}
%% marshal
%defaultcode
%% demarshal
%defaultcode
%%


// type:DCOPRef
// %doc as (str app, str obj, str type)
// %doc as (str app, str obj)
// %% from_pyobj
// {
//   *ok=false;
//   char *dcopref_app=NULL, *dcopref_obj=NULL, *dcopref_type=NULL;
//   if (PyArg_ParseTuple(obj,(char*)"ss|s", &dcopref_app, &dcopref_obj, &dcopref_type)) {
//     *ok=true;
//     if (dcopref_type) {
//       DCOPRef dr(QCString(dcopref_app), QCString(dcopref_obj), QCString(dcopref_type));
//       return dr;
//     }
//     DCOPRef dr(QCString(dcopref_app), QCString(dcopref_obj));
//     return dr;
//   }
//   return DCOPRef();
// }
// %% to_pyobj
// {
//   return Py_BuildValue((char*)"sss", val.app().data(), val.obj().data(), val.type().data() );
// }
// %% marshal
// %defaultcode
// %% demarshal
// %defaultcode
// %%

// type:QFont
// %% marshal
// %constructor ("default")
// %dict-map family:string,rawName:string
// %% demarshal
// %dict-map
// %%
