#include "Python.h"
#include "exceptions.h"

/** Ft.Xml.ReaderException ********************************************/

static PyObject *ReaderException;

PyObject *ReaderException_XmlParseError(PyObject *uri, int line, int column,
                                        const char *description)
{
  PyObject *code;
  PyObject *exception;

  code = PyObject_GetAttrString(ReaderException, "XML_PARSE_ERROR");
  if (code != NULL) {
    exception = PyObject_CallFunction(ReaderException, "NOiis", code, uri,
                                      line, column, description);
    if (exception) {
      PyErr_SetObject(ReaderException, exception);
    }
  }

  return NULL;
}


PyObject *ReaderException_RecursiveParseError(PyObject *uri)
{
  PyObject *code;
  PyObject *exception;

  code = PyObject_GetAttrString(ReaderException, "RECURSIVE_PARSE_ERROR");
  if (code != NULL) {
    exception = PyObject_CallFunction(ReaderException, "NO", code, uri);
    if (exception) {
      PyErr_SetObject(ReaderException, exception);
    }
  }

  return NULL;
}


/** Ft.Xml.XInclude Exception ********************************/

static PyObject *XIncludeException;

PyObject *XIncludeException_InvalidParseAttr(PyObject *value)
{
  PyObject *code, *exception;

  code = PyObject_GetAttrString(XIncludeException, "INVALID_PARSE_ATTR");
  if (code) {
    exception = PyObject_CallFunction(XIncludeException, "NO", code, value);
    if (exception) {
      PyErr_SetObject(XIncludeException, exception);
    }
  }
  return NULL;
}


PyObject *XIncludeException_MissingHref(void)
{
  PyObject *code, *exception;

  code = PyObject_GetAttrString(XIncludeException, "MISSING_HREF");
  if (code) {
    exception = PyObject_CallFunction(XIncludeException, "N", code);
    if (exception) {
      PyErr_SetObject(XIncludeException, exception);
    }
  }
  return NULL;
}

/** xml.dom.DOMException **********************************************/

static PyObject *IndexSizeErr;
static PyObject *DomstringSizeErr;
static PyObject *HierarchyRequestErr;
static PyObject *WrongDocumentErr;
static PyObject *InvalidCharacterErr;
static PyObject *NoDataAllowedErr;
static PyObject *NoModificationAllowedErr;
static PyObject *NotFoundErr;
static PyObject *NotSupportedErr;
static PyObject *InuseAttributeErr;
static PyObject *InvalidStateErr;
static PyObject *SyntaxErr;
static PyObject *InvalidModificationErr;
static PyObject *NamespaceErr;
static PyObject *InvalidAccessErr;


PyObject *DOMException_HierarchyRequestErr(const char *string)
{
  PyObject *exception = PyObject_CallFunction(HierarchyRequestErr, "s", string);
  if (exception) {
    PyErr_SetObject(HierarchyRequestErr, exception);
  }
  return NULL;
}

PyObject *DOMException_NotFoundErr(const char *string)
{
  PyObject *exception = PyObject_CallFunction(NotFoundErr, "s", string);
  if (exception) {
    PyErr_SetObject(NotFoundErr, exception);
  }
  return NULL;
}

PyObject *DOMException_NotSupportedErr(const char *string)
{
  PyObject *exception = PyObject_CallFunction(NotSupportedErr, "s", string);
  if (exception) {
    PyErr_SetObject(NotSupportedErr, exception);
  }
  return NULL;
}

PyObject *DOMException_InvalidStateErr(const char *string)
{
  PyObject *exception = PyObject_CallFunction(InvalidStateErr, "s", string);
  if (exception) {
    PyErr_SetObject(InvalidStateErr, exception);
  }
  return NULL;
}

PyObject *DOMException_NamespaceErr(const char *string)
{
  PyObject *exception = PyObject_CallFunction(NamespaceErr, "s", string);
  if (exception) {
    PyErr_SetObject(NamespaceErr, exception);
  }
  return NULL;
}

PyObject *DOMException_SyntaxErr(const char *string)
{
  PyObject *exception = PyObject_CallFunction(SyntaxErr, "s", string);
  if (exception) {
    PyErr_SetObject(SyntaxErr, exception);
  }
  return NULL;
}

/** Initialization ****************************************************/

int DomletteExceptions_Init(PyObject *module)
{
  PyObject *import;

  /* Load the ReaderException and XIncludeException */
  import = PyImport_ImportModule("Ft.Xml");
  if (import == NULL) return -1;
  ReaderException = PyObject_GetAttrString(import, "ReaderException");
  if (ReaderException == NULL) {
    Py_DECREF(import);
    return -1;
  }
  XIncludeException = PyObject_GetAttrString(import ,"XIncludeException");
  if (XIncludeException == NULL) {
    Py_DECREF(import);
    return -1;
  }
  Py_DECREF(import);

  /* Load the DOMExceptions */
  import  = PyImport_ImportModule("xml.dom");
  if (import == NULL) return -1;

#define GET_DOM_EXC(NAME) \
  NAME = PyObject_GetAttrString(import, #NAME); \
  if (NAME == NULL) {                           \
    Py_DECREF(import);                          \
    return -1;                                  \
  }

  GET_DOM_EXC(IndexSizeErr);
  GET_DOM_EXC(HierarchyRequestErr);
  GET_DOM_EXC(WrongDocumentErr);
  GET_DOM_EXC(InvalidCharacterErr);
  GET_DOM_EXC(NoDataAllowedErr);
  GET_DOM_EXC(NoModificationAllowedErr);
  GET_DOM_EXC(NotFoundErr);
  GET_DOM_EXC(NotSupportedErr);
  GET_DOM_EXC(InuseAttributeErr);
  GET_DOM_EXC(InvalidStateErr);
  GET_DOM_EXC(SyntaxErr);
  GET_DOM_EXC(InvalidModificationErr);
  GET_DOM_EXC(NamespaceErr);
  GET_DOM_EXC(InvalidAccessErr);

  /* special case exception misnaming */
  if (PyObject_HasAttrString(import, "DomstringSizeErr")) {
    /* Python 2.1+ and PyXML 0.8+ */
    DomstringSizeErr = PyObject_GetAttrString(import, "DomstringSizeErr");
  } else {
    /* PyXML < 0.8 */
    DomstringSizeErr = PyObject_GetAttrString(import, "DOMStringSizeErr");
  }
  if (DomstringSizeErr == NULL) {
    Py_DECREF(import);
    return -1;
  }
  Py_DECREF(import);

  return 0;
}

/** Finalization ******************************************************/

void DomletteExceptions_Fini(void)
{
  Py_DECREF(ReaderException);
  Py_DECREF(XIncludeException);
  Py_DECREF(IndexSizeErr);
  Py_DECREF(DomstringSizeErr);
  Py_DECREF(HierarchyRequestErr);
  Py_DECREF(WrongDocumentErr);
  Py_DECREF(InvalidCharacterErr);
  Py_DECREF(NoDataAllowedErr);
  Py_DECREF(NoModificationAllowedErr);
  Py_DECREF(NotFoundErr);
  Py_DECREF(NotSupportedErr);
  Py_DECREF(InuseAttributeErr);
  Py_DECREF(InvalidStateErr);
  Py_DECREF(SyntaxErr);
  Py_DECREF(InvalidModificationErr);
  Py_DECREF(NamespaceErr);
  Py_DECREF(InvalidAccessErr);
}
