#ifndef __WXHACK_H
#define __WXHACK_H

#include <wx/wx.h>

/* helper function to extract the pointer value from a swig ptr string
 * as used in wxPython 2.4
 */
static void *
decode_pointer(char *string)
{
  unsigned long p = 0;

  /* Pointer values must start with leading underscore */
  if (*string == '_')
  {
      string++;
      /* Extract hex value from pointer */
      while (*string)
      {
	  if ((*string >= '0') && (*string <= '9'))
	    p = (p << 4) + (*string - '0');
	  else if ((*string >= 'a') && (*string <= 'f'))
	    p = (p << 4) + ((*string - 'a') + 10);
	  else
	    break;
	  string++;
      }
  }
  return (void*)p;
}

/* helper function to extract the pointer value from a swig ptr string
 * as used in wxPython 2.5
 *
 * The hexvalues describe the bytes making up the pointer in memory,
 * i.e. when the pointer is considered as an array of bytes (we assume
 * char==byte in the implementation).  In the older version it was
 * always a bigendian representation.
 */
static void*
decode_pointer_new(char *string, unsigned int length)
{
    void * p = 0;
    unsigned char *pp = (unsigned char*)&p;
    unsigned int count = 0;

    /* sanity check: the string must be at least as long as twice the
     * size of the pointer (two hex digits per byte) plus one for the
     * initial underscore */
    if (length < 2 * sizeof(p) + 1)
	return NULL;

    /* Pointer values must start with leading underscore */
    if (*string == '_')
    {
	string++;
	length--;

	/* the remaining length must be at least twice as long as the
	 * size of the pointer. */

	/* now decode the hex values.  We decode exactly two bytes for
	 * each of the bytes in the pointer */
	while (count < 2 * sizeof(p))
	{
	    if ((*string >= '0') && (*string <= '9'))
		*pp = (*pp << 4) + (*string - '0');
	    else if ((*string >= 'a') && (*string <= 'f'))
		*pp = (*pp << 4) + ((*string - 'a') + 10);
	    else
		break;
	    string++;
	    count++;
	    if (count % 2 == 0)
		pp++;
	}
  }
  return p;
}

/* Return the object wrapped by the SWIG shadow object shadow
 *
 * The pointer to the real object can be decoded from the "this"
 * attribute of the python object.  In wxPython 2.4 it's a string
 * containing a hex representation of the pointer value.  In wxPython
 * 2.5 it's a special python object which can nevertheless be converted
 * to a string with a hex representation of the pointer value which is a
 * bit different than the one for 2.4.
 */
bool
wxPyConvertSwigPtr(PyObject* obj, void **ptr, const wxChar* className)
{
    PyObject * string = NULL;
    PyObject * thisobject = NULL;

    *ptr = 0;

    thisobject = PyObject_GetAttrString(obj, "this");
    if (thisobject)
    {
	if (!PyString_Check(thisobject))
	{
	    string = PyObject_Str(thisobject);
	    if (string)
	    {
		*ptr = decode_pointer_new(PyString_AsString(string),
					  PyString_Size(string));
		Py_DECREF(string);
	    }
	}
	else
	{
	    *ptr = decode_pointer(PyString_AsString(thisobject));
	}
    }

    Py_XDECREF(thisobject);

    return *ptr != 0;
}

#endif
