/*
 *   Interface to the ncurses panel library
 *
 * Original version by Thomas Gellekum
 */

/* Release Number */

static char *PyCursesVersion = "2.1";

/* Includes */

#include "Python.h"

#include "py_curses.h"

#include <panel.h>

static PyObject *PyCursesError;


/* Utility Functions */

/*
 * Check the return code from a curses function and return None
 * or raise an exception as appropriate.
 */

static PyObject *
PyCursesCheckERR(int code, char *fname)
{
    if (code != ERR) {
        Py_INCREF(Py_None);
        return Py_None;
    } else {
        if (fname == NULL) {
            PyErr_SetString(PyCursesError, catchall_ERR);
        } else {
            PyErr_Format(PyCursesError, "%s() returned ERR", fname);
        }
        return NULL;
    }
}

/*****************************************************************************
 The Panel Object
******************************************************************************/

/* Definition of the panel object and panel type */

typedef struct {
    PyObject_HEAD
    PANEL *pan;
    PyCursesWindowObject *wo;   /* for reference counts */
} PyCursesPanelObject;

PyTypeObject PyCursesPanel_Type;

#define PyCursesPanel_Check(v)   (Py_TYPE(v) == &PyCursesPanel_Type)

/* Some helper functions. The problem is that there's always a window
   associated with a panel. To ensure that Python's GC doesn't pull
   this window from under our feet we need to keep track of references
   to the corresponding window object within Python. We can't use
   dupwin(oldwin) to keep a copy of the curses WINDOW because the
   contents of oldwin is copied only once; code like

   win = newwin(...)
   pan = win.panel()
   win.addstr(some_string)
   pan.window().addstr(other_string)

   will fail. */

/* We keep a linked list of PyCursesPanelObjects, lop. A list should
   suffice, I don't expect more than a handful or at most a few
   dozens of panel objects within a typical program. */
typedef struct _list_of_panels {
    PyCursesPanelObject *po;
    struct _list_of_panels *next;
} list_of_panels;

/* list anchor */
static list_of_panels *lop;

/* Insert a new panel object into lop */
static int
insert_lop(PyCursesPanelObject *po)
{
    list_of_panels *new;

    if ((new = (list_of_panels *)malloc(sizeof(list_of_panels))) == NULL) {
        PyErr_NoMemory();
        return -1;
    }
    new->po = po;
    new->next = lop;
    lop = new;
    return 0;
}

/* Remove the panel object from lop */
static void
remove_lop(PyCursesPanelObject *po)
{
    list_of_panels *temp, *n;

    temp = lop;
    if (temp->po == po) {
        lop = temp->next;
        free(temp);
        return;
    }
    while (temp->next == NULL || temp->next->po != po) {
        if (temp->next == NULL) {
            PyErr_SetString(PyExc_RuntimeError,
                            "remove_lop: can't find Panel Object");
            return;
        }
        temp = temp->next;
    }
    n = temp->next->next;
    free(temp->next);
    temp->next = n;
    return;
}

/* Return the panel object that corresponds to pan */
static PyCursesPanelObject *
find_po(PANEL *pan)
{
    list_of_panels *temp;
    for (temp = lop; temp->po->pan != pan; temp = temp->next)
        if (temp->next == NULL) return NULL;    /* not found!? */
    return temp->po;
}

/* Function Prototype Macros - They are ugly but very, very useful. ;-)

   X - function name
   TYPE - parameter Type
   ERGSTR - format string for construction of the return value
   PARSESTR - format string for argument parsing */

#define Panel_NoArgNoReturnFunction(X) \
static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self) \
{ return PyCursesCheckERR(X(self->pan), # X); }

#define Panel_NoArgTrueFalseFunction(X) \
static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self) \
{ \
  if (X (self->pan) == FALSE) { Py_INCREF(Py_False); return Py_False; } \
  else { Py_INCREF(Py_True); return Py_True; } }

#define Panel_TwoArgNoReturnFunction(X, TYPE, PARSESTR) \
static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self, PyObject *args) \
{ \
  TYPE arg1, arg2; \
  if (!PyArg_ParseTuple(args, PARSESTR, &arg1, &arg2)) return NULL; \
  return PyCursesCheckERR(X(self->pan, arg1, arg2), # X); }

/* ------------- PANEL routines --------------- */

Panel_NoArgNoReturnFunction(bottom_panel)
Panel_NoArgNoReturnFunction(hide_panel)
Panel_NoArgNoReturnFunction(show_panel)
Panel_NoArgNoReturnFunction(top_panel)
Panel_NoArgTrueFalseFunction(panel_hidden)
Panel_TwoArgNoReturnFunction(move_panel, int, "ii;y,x")

/* Allocation and deallocation of Panel Objects */

static PyObject *
PyCursesPanel_New(PANEL *pan, PyCursesWindowObject *wo)
{
    PyCursesPanelObject *po;

    po = PyObject_NEW(PyCursesPanelObject, &PyCursesPanel_Type);
    if (po == NULL) return NULL;
    po->pan = pan;
    if (insert_lop(po) < 0) {
        po->wo = NULL;
        Py_DECREF(po);
        return NULL;
    }
    po->wo = wo;
    Py_INCREF(wo);
    return (PyObject *)po;
}

static void
PyCursesPanel_Dealloc(PyCursesPanelObject *po)
{
    (void)del_panel(po->pan);
    if (po->wo != NULL) {
        Py_DECREF(po->wo);
        remove_lop(po);
    }
    PyObject_DEL(po);
}

/* panel_above(NULL) returns the bottom panel in the stack. To get
   this behaviour we use curses.panel.bottom_panel(). */
static PyObject *
PyCursesPanel_above(PyCursesPanelObject *self)
{
    PANEL *pan;
    PyCursesPanelObject *po;

    pan = panel_above(self->pan);

    if (pan == NULL) {          /* valid output, it means the calling panel
                                   is on top of the stack */
        Py_INCREF(Py_None);
        return Py_None;
    }
    po = find_po(pan);
    if (po == NULL) {
        PyErr_SetString(PyExc_RuntimeError,
                        "panel_above: can't find Panel Object");
        return NULL;
    }
    Py_INCREF(po);
    return (PyObject *)po;
}

/* panel_below(NULL) returns the top panel in the stack. To get
   this behaviour we use curses.panel.top_panel(). */
static PyObject *
PyCursesPanel_below(PyCursesPanelObject *self)
{
    PANEL *pan;
    PyCursesPanelObject *po;

    pan = panel_below(self->pan);

    if (pan == NULL) {          /* valid output, it means the calling panel
                                   is on the bottom of the stack */
        Py_INCREF(Py_None);
        return Py_None;
    }
    po = find_po(pan);
    if (po == NULL) {
        PyErr_SetString(PyExc_RuntimeError,
                        "panel_below: can't find Panel Object");
        return NULL;
    }
    Py_INCREF(po);
    return (PyObject *)po;
}

static PyObject *
PyCursesPanel_window(PyCursesPanelObject *self)
{
    Py_INCREF(self->wo);
    return (PyObject *)self->wo;
}

static PyObject *
PyCursesPanel_replace_panel(PyCursesPanelObject *self, PyObject *args)
{
    PyCursesPanelObject *po;
    PyCursesWindowObject *temp;
    int rtn;

    if (PyTuple_Size(args) != 1) {
        PyErr_SetString(PyExc_TypeError, "replace requires one argument");
        return NULL;
    }
    if (!PyArg_ParseTuple(args, "O!;window object",
                          &PyCursesWindow_Type, &temp))
        return NULL;

    po = find_po(self->pan);
    if (po == NULL) {
        PyErr_SetString(PyExc_RuntimeError,
                        "replace_panel: can't find Panel Object");
        return NULL;
    }

    rtn = replace_panel(self->pan, temp->win);
    if (rtn == ERR) {
        PyErr_SetString(PyCursesError, "replace_panel() returned ERR");
        return NULL;
    }
    Py_DECREF(po->wo);
    po->wo = temp;
    Py_INCREF(po->wo);
    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
PyCursesPanel_set_panel_userptr(PyCursesPanelObject *self, PyObject *obj)
{
    Py_INCREF(obj);
    return PyCursesCheckERR(set_panel_userptr(self->pan, (void*)obj),
                            "set_panel_userptr");
}

static PyObject *
PyCursesPanel_userptr(PyCursesPanelObject *self)
{
    PyObject *obj;
    PyCursesInitialised;
    obj = (PyObject *) panel_userptr(self->pan);
    if (obj == NULL) {
        PyErr_SetString(PyCursesError, "no userptr set");
        return NULL;
    }

    Py_INCREF(obj);
    return obj;
}


/* Module interface */

static PyMethodDef PyCursesPanel_Methods[] = {
    {"above",           (PyCFunction)PyCursesPanel_above, METH_NOARGS},
    {"below",           (PyCFunction)PyCursesPanel_below, METH_NOARGS},
    {"bottom",          (PyCFunction)PyCursesPanel_bottom_panel, METH_NOARGS},
    {"hidden",          (PyCFunction)PyCursesPanel_panel_hidden, METH_NOARGS},
    {"hide",            (PyCFunction)PyCursesPanel_hide_panel, METH_NOARGS},
    {"move",            (PyCFunction)PyCursesPanel_move_panel, METH_VARARGS},
    {"replace",         (PyCFunction)PyCursesPanel_replace_panel, METH_VARARGS},
    {"set_userptr",     (PyCFunction)PyCursesPanel_set_panel_userptr, METH_O},
    {"show",            (PyCFunction)PyCursesPanel_show_panel, METH_NOARGS},
    {"top",             (PyCFunction)PyCursesPanel_top_panel, METH_NOARGS},
    {"userptr",         (PyCFunction)PyCursesPanel_userptr, METH_NOARGS},
    {"window",          (PyCFunction)PyCursesPanel_window, METH_NOARGS},
    {NULL,              NULL}   /* sentinel */
};

static PyObject *
PyCursesPanel_GetAttr(PyCursesPanelObject *self, char *name)
{
    return Py_FindMethod(PyCursesPanel_Methods, (PyObject *)self, name);
}

/* -------------------------------------------------------*/

PyTypeObject PyCursesPanel_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "_curses_panel.curses panel",       /*tp_name*/
    sizeof(PyCursesPanelObject),        /*tp_basicsize*/
    0,                  /*tp_itemsize*/
    /* methods */
    (destructor)PyCursesPanel_Dealloc, /*tp_dealloc*/
    0,                  /*tp_print*/
    (getattrfunc)PyCursesPanel_GetAttr, /*tp_getattr*/
    (setattrfunc)0, /*tp_setattr*/
    0,                  /*tp_compare*/
    0,                  /*tp_repr*/
    0,                  /*tp_as_number*/
    0,                  /*tp_as_sequence*/
    0,                  /*tp_as_mapping*/
    0,                  /*tp_hash*/
};

/* Wrapper for panel_above(NULL). This function returns the bottom
   panel of the stack, so it's renamed to bottom_panel().
   panel.above() *requires* a panel object in the first place which
   may be undesirable. */
static PyObject *
PyCurses_bottom_panel(PyObject *self)
{
    PANEL *pan;
    PyCursesPanelObject *po;

    PyCursesInitialised;

    pan = panel_above(NULL);

    if (pan == NULL) {          /* valid output, it means
                                   there's no panel at all */
        Py_INCREF(Py_None);
        return Py_None;
    }
    po = find_po(pan);
    if (po == NULL) {
        PyErr_SetString(PyExc_RuntimeError,
                        "panel_above: can't find Panel Object");
        return NULL;
    }
    Py_INCREF(po);
    return (PyObject *)po;
}

static PyObject *
PyCurses_new_panel(PyObject *self, PyObject *args)
{
    PyCursesWindowObject *win;
    PANEL *pan;

    if (!PyArg_ParseTuple(args, "O!", &PyCursesWindow_Type, &win))
        return NULL;
    pan = new_panel(win->win);
    if (pan == NULL) {
        PyErr_SetString(PyCursesError, catchall_NULL);
        return NULL;
    }
    return (PyObject *)PyCursesPanel_New(pan, win);
}


/* Wrapper for panel_below(NULL). This function returns the top panel
   of the stack, so it's renamed to top_panel(). panel.below()
   *requires* a panel object in the first place which may be
   undesirable. */
static PyObject *
PyCurses_top_panel(PyObject *self)
{
    PANEL *pan;
    PyCursesPanelObject *po;

    PyCursesInitialised;

    pan = panel_below(NULL);

    if (pan == NULL) {          /* valid output, it means
                                   there's no panel at all */
        Py_INCREF(Py_None);
        return Py_None;
    }
    po = find_po(pan);
    if (po == NULL) {
        PyErr_SetString(PyExc_RuntimeError,
                        "panel_below: can't find Panel Object");
        return NULL;
    }
    Py_INCREF(po);
    return (PyObject *)po;
}

static PyObject *PyCurses_update_panels(PyObject *self)
{
    PyCursesInitialised;
    update_panels();
    Py_INCREF(Py_None);
    return Py_None;
}


/* List of functions defined in the module */

static PyMethodDef PyCurses_methods[] = {
    {"bottom_panel",        (PyCFunction)PyCurses_bottom_panel,  METH_NOARGS},
    {"new_panel",           (PyCFunction)PyCurses_new_panel,     METH_VARARGS},
    {"top_panel",           (PyCFunction)PyCurses_top_panel,     METH_NOARGS},
    {"update_panels",       (PyCFunction)PyCurses_update_panels, METH_NOARGS},
    {NULL,              NULL}           /* sentinel */
};

/* Initialization function for the module */

PyMODINIT_FUNC
init_curses_panel(void)
{
    PyObject *m, *d, *v;

    /* Initialize object type */
    Py_TYPE(&PyCursesPanel_Type) = &PyType_Type;

    import_curses();

    /* Create the module and add the functions */
    m = Py_InitModule("_curses_panel", PyCurses_methods);
    if (m == NULL)
        return;
    d = PyModule_GetDict(m);

    /* For exception _curses_panel.error */
    PyCursesError = PyErr_NewException("_curses_panel.error", NULL, NULL);
    PyDict_SetItemString(d, "error", PyCursesError);

    /* Make the version available */
    v = PyString_FromString(PyCursesVersion);
    PyDict_SetItemString(d, "version", v);
    PyDict_SetItemString(d, "__version__", v);
    Py_DECREF(v);
}
