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

/* Release Number */

static const char PyCursesVersion[] = "2.1";

/* Includes */

// clinic/_curses_panel.c.h uses internal pycore_modsupport.h API
#ifndef Py_BUILD_CORE_BUILTIN
#  define Py_BUILD_CORE_MODULE 1
#endif

#include "Python.h"

#include "py_curses.h"

#if defined(HAVE_NCURSESW_PANEL_H)
#  include <ncursesw/panel.h>
#elif defined(HAVE_NCURSES_PANEL_H)
#  include <ncurses/panel.h>
#elif defined(HAVE_PANEL_H)
#  include <panel.h>
#endif

typedef struct {
    PyObject *PyCursesError;
    PyTypeObject *PyCursesPanel_Type;
} _curses_panel_state;

static inline _curses_panel_state *
get_curses_panel_state(PyObject *module)
{
    void *state = PyModule_GetState(module);
    assert(state != NULL);
    return (_curses_panel_state *)state;
}

static int
_curses_panel_clear(PyObject *mod)
{
    _curses_panel_state *state = get_curses_panel_state(mod);
    Py_CLEAR(state->PyCursesError);
    Py_CLEAR(state->PyCursesPanel_Type);
    return 0;
}

static int
_curses_panel_traverse(PyObject *mod, visitproc visit, void *arg)
{
    Py_VISIT(Py_TYPE(mod));
    _curses_panel_state *state = get_curses_panel_state(mod);
    Py_VISIT(state->PyCursesError);
    Py_VISIT(state->PyCursesPanel_Type);
    return 0;
}

static void
_curses_panel_free(void *mod)
{
    _curses_panel_clear((PyObject *) mod);
}

/* Utility Functions */

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

static PyObject *
PyCursesCheckERR(_curses_panel_state *state, int code, const char *fname)
{
    if (code != ERR) {
        Py_RETURN_NONE;
    }
    else {
        if (fname == NULL) {
            PyErr_SetString(state->PyCursesError, catchall_ERR);
        }
        else {
            PyErr_Format(state->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;

/* 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 *)PyMem_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;
        PyMem_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;
    PyMem_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;
}

/*[clinic input]
module _curses_panel
class _curses_panel.panel "PyCursesPanelObject *" "&PyCursesPanel_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2f4ef263ca850a31]*/

#include "clinic/_curses_panel.c.h"

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

/*[clinic input]
_curses_panel.panel.bottom

    cls: defining_class

Push the panel to the bottom of the stack.
[clinic start generated code]*/

static PyObject *
_curses_panel_panel_bottom_impl(PyCursesPanelObject *self, PyTypeObject *cls)
/*[clinic end generated code: output=8ec7fbbc08554021 input=6b7d2c0578b5a1c4]*/
{
    _curses_panel_state *state = PyType_GetModuleState(cls);
    return PyCursesCheckERR(state, bottom_panel(self->pan), "bottom");
}

/*[clinic input]
_curses_panel.panel.hide

    cls: defining_class

Hide the panel.

This does not delete the object, it just makes the window on screen invisible.
[clinic start generated code]*/

static PyObject *
_curses_panel_panel_hide_impl(PyCursesPanelObject *self, PyTypeObject *cls)
/*[clinic end generated code: output=cc6ab7203cdc1450 input=1bfc741f473e6055]*/
{
    _curses_panel_state *state = PyType_GetModuleState(cls);
    return PyCursesCheckERR(state, hide_panel(self->pan), "hide");
}

/*[clinic input]
_curses_panel.panel.show

    cls: defining_class

Display the panel (which might have been hidden).
[clinic start generated code]*/

static PyObject *
_curses_panel_panel_show_impl(PyCursesPanelObject *self, PyTypeObject *cls)
/*[clinic end generated code: output=dc3421de375f0409 input=8122e80151cb4379]*/
{
    _curses_panel_state *state = PyType_GetModuleState(cls);
    return PyCursesCheckERR(state, show_panel(self->pan), "show");
}

/*[clinic input]
_curses_panel.panel.top

    cls: defining_class

Push panel to the top of the stack.
[clinic start generated code]*/

static PyObject *
_curses_panel_panel_top_impl(PyCursesPanelObject *self, PyTypeObject *cls)
/*[clinic end generated code: output=10a072e511e873f7 input=1f372d597dda3379]*/
{
    _curses_panel_state *state = PyType_GetModuleState(cls);
    return PyCursesCheckERR(state, top_panel(self->pan), "top");
}

/* Allocation and deallocation of Panel Objects */

static PyObject *
PyCursesPanel_New(_curses_panel_state *state, PANEL *pan,
                  PyCursesWindowObject *wo)
{
    PyCursesPanelObject *po = PyObject_New(PyCursesPanelObject,
                                           state->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 = (PyCursesWindowObject*)Py_NewRef(wo);
    return (PyObject *)po;
}

static void
PyCursesPanel_Dealloc(PyCursesPanelObject *po)
{
    PyObject *tp, *obj;

    tp = (PyObject *) Py_TYPE(po);
    obj = (PyObject *) panel_userptr(po->pan);
    if (obj) {
        (void)set_panel_userptr(po->pan, NULL);
        Py_DECREF(obj);
    }
    (void)del_panel(po->pan);
    if (po->wo != NULL) {
        Py_DECREF(po->wo);
        remove_lop(po);
    }
    PyObject_Free(po);
    Py_DECREF(tp);
}

/* panel_above(NULL) returns the bottom panel in the stack. To get
   this behaviour we use curses.panel.bottom_panel(). */
/*[clinic input]
_curses_panel.panel.above

Return the panel above the current panel.
[clinic start generated code]*/

static PyObject *
_curses_panel_panel_above_impl(PyCursesPanelObject *self)
/*[clinic end generated code: output=70ac06d25fd3b4da input=c059994022976788]*/
{
    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_RETURN_NONE;
    }
    po = find_po(pan);
    if (po == NULL) {
        PyErr_SetString(PyExc_RuntimeError,
                        "panel_above: can't find Panel Object");
        return NULL;
    }
    return Py_NewRef(po);
}

/* panel_below(NULL) returns the top panel in the stack. To get
   this behaviour we use curses.panel.top_panel(). */
/*[clinic input]
_curses_panel.panel.below

Return the panel below the current panel.
[clinic start generated code]*/

static PyObject *
_curses_panel_panel_below_impl(PyCursesPanelObject *self)
/*[clinic end generated code: output=282861122e06e3de input=cc08f61936d297c6]*/
{
    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_RETURN_NONE;
    }
    po = find_po(pan);
    if (po == NULL) {
        PyErr_SetString(PyExc_RuntimeError,
                        "panel_below: can't find Panel Object");
        return NULL;
    }
    return Py_NewRef(po);
}

/*[clinic input]
_curses_panel.panel.hidden

Return True if the panel is hidden (not visible), False otherwise.
[clinic start generated code]*/

static PyObject *
_curses_panel_panel_hidden_impl(PyCursesPanelObject *self)
/*[clinic end generated code: output=66eebd1ab4501a71 input=453d4b4fce25e21a]*/
{
    if (panel_hidden(self->pan))
        Py_RETURN_TRUE;
    else
        Py_RETURN_FALSE;
}

/*[clinic input]
_curses_panel.panel.move

    cls: defining_class
    y: int
    x: int
    /

Move the panel to the screen coordinates (y, x).
[clinic start generated code]*/

static PyObject *
_curses_panel_panel_move_impl(PyCursesPanelObject *self, PyTypeObject *cls,
                              int y, int x)
/*[clinic end generated code: output=ce546c93e56867da input=60a0e7912ff99849]*/
{
    _curses_panel_state *state = PyType_GetModuleState(cls);
    return PyCursesCheckERR(state, move_panel(self->pan, y, x), "move_panel");
}

/*[clinic input]
_curses_panel.panel.window

Return the window object associated with the panel.
[clinic start generated code]*/

static PyObject *
_curses_panel_panel_window_impl(PyCursesPanelObject *self)
/*[clinic end generated code: output=5f05940d4106b4cb input=6067353d2c307901]*/
{
    return Py_NewRef(self->wo);
}

/*[clinic input]
_curses_panel.panel.replace

    cls: defining_class
    win: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type")
    /

Change the window associated with the panel to the window win.
[clinic start generated code]*/

static PyObject *
_curses_panel_panel_replace_impl(PyCursesPanelObject *self,
                                 PyTypeObject *cls,
                                 PyCursesWindowObject *win)
/*[clinic end generated code: output=c71f95c212d58ae7 input=dbec7180ece41ff5]*/
{
    _curses_panel_state *state = PyType_GetModuleState(cls);

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

    int rtn = replace_panel(self->pan, win->win);
    if (rtn == ERR) {
        PyErr_SetString(state->PyCursesError, "replace_panel() returned ERR");
        return NULL;
    }
    Py_SETREF(po->wo, (PyCursesWindowObject*)Py_NewRef(win));
    Py_RETURN_NONE;
}

/*[clinic input]
_curses_panel.panel.set_userptr

    cls: defining_class
    obj: object
    /

Set the panel's user pointer to obj.
[clinic start generated code]*/

static PyObject *
_curses_panel_panel_set_userptr_impl(PyCursesPanelObject *self,
                                     PyTypeObject *cls, PyObject *obj)
/*[clinic end generated code: output=db74f3db07b28080 input=e3fee2ff7b1b8e48]*/
{
    PyCursesInitialised;
    Py_INCREF(obj);
    PyObject *oldobj = (PyObject *) panel_userptr(self->pan);
    int rc = set_panel_userptr(self->pan, (void*)obj);
    if (rc == ERR) {
        /* In case of an ncurses error, decref the new object again */
        Py_DECREF(obj);
    }
    else {
        Py_XDECREF(oldobj);
    }

    _curses_panel_state *state = PyType_GetModuleState(cls);
    return PyCursesCheckERR(state, rc, "set_panel_userptr");
}

/*[clinic input]
_curses_panel.panel.userptr

    cls: defining_class

Return the user pointer for the panel.
[clinic start generated code]*/

static PyObject *
_curses_panel_panel_userptr_impl(PyCursesPanelObject *self,
                                 PyTypeObject *cls)
/*[clinic end generated code: output=eea6e6f39ffc0179 input=f22ca4f115e30a80]*/
{
    _curses_panel_state *state = PyType_GetModuleState(cls);

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

    return Py_NewRef(obj);
}


/* Module interface */

static PyMethodDef PyCursesPanel_Methods[] = {
    _CURSES_PANEL_PANEL_ABOVE_METHODDEF
    _CURSES_PANEL_PANEL_BELOW_METHODDEF
    _CURSES_PANEL_PANEL_BOTTOM_METHODDEF
    _CURSES_PANEL_PANEL_HIDDEN_METHODDEF
    _CURSES_PANEL_PANEL_HIDE_METHODDEF
    _CURSES_PANEL_PANEL_MOVE_METHODDEF
    _CURSES_PANEL_PANEL_REPLACE_METHODDEF
    _CURSES_PANEL_PANEL_SET_USERPTR_METHODDEF
    _CURSES_PANEL_PANEL_SHOW_METHODDEF
    _CURSES_PANEL_PANEL_TOP_METHODDEF
    _CURSES_PANEL_PANEL_USERPTR_METHODDEF
    _CURSES_PANEL_PANEL_WINDOW_METHODDEF
    {NULL,              NULL}   /* sentinel */
};

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

static PyType_Slot PyCursesPanel_Type_slots[] = {
    {Py_tp_dealloc, PyCursesPanel_Dealloc},
    {Py_tp_methods, PyCursesPanel_Methods},
    {0, 0},
};

static PyType_Spec PyCursesPanel_Type_spec = {
    .name = "_curses_panel.panel",
    .basicsize = sizeof(PyCursesPanelObject),
    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
    .slots = PyCursesPanel_Type_slots
};

/* 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. */
/*[clinic input]
_curses_panel.bottom_panel

Return the bottom panel in the panel stack.
[clinic start generated code]*/

static PyObject *
_curses_panel_bottom_panel_impl(PyObject *module)
/*[clinic end generated code: output=3aba9f985f4c2bd0 input=634c2a8078b3d7e4]*/
{
    PANEL *pan;
    PyCursesPanelObject *po;

    PyCursesInitialised;

    pan = panel_above(NULL);

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

/*[clinic input]
_curses_panel.new_panel

    win: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type")
    /

Return a panel object, associating it with the given window win.
[clinic start generated code]*/

static PyObject *
_curses_panel_new_panel_impl(PyObject *module, PyCursesWindowObject *win)
/*[clinic end generated code: output=45e948e0176a9bd2 input=74d4754e0ebe4800]*/
{
    _curses_panel_state *state = get_curses_panel_state(module);

    PANEL *pan = new_panel(win->win);
    if (pan == NULL) {
        PyErr_SetString(state->PyCursesError, catchall_NULL);
        return NULL;
    }
    return (PyObject *)PyCursesPanel_New(state, 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. */
/*[clinic input]
_curses_panel.top_panel

Return the top panel in the panel stack.
[clinic start generated code]*/

static PyObject *
_curses_panel_top_panel_impl(PyObject *module)
/*[clinic end generated code: output=86704988bea8508e input=e62d6278dba39e79]*/
{
    PANEL *pan;
    PyCursesPanelObject *po;

    PyCursesInitialised;

    pan = panel_below(NULL);

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

/*[clinic input]
_curses_panel.update_panels

Updates the virtual screen after changes in the panel stack.

This does not call curses.doupdate(), so you'll have to do this yourself.
[clinic start generated code]*/

static PyObject *
_curses_panel_update_panels_impl(PyObject *module)
/*[clinic end generated code: output=2f3b4c2e03d90ded input=5299624c9a708621]*/
{
    PyCursesInitialised;
    update_panels();
    Py_RETURN_NONE;
}

/* List of functions defined in the module */

static PyMethodDef PyCurses_methods[] = {
    _CURSES_PANEL_BOTTOM_PANEL_METHODDEF
    _CURSES_PANEL_NEW_PANEL_METHODDEF
    _CURSES_PANEL_TOP_PANEL_METHODDEF
    _CURSES_PANEL_UPDATE_PANELS_METHODDEF
    {NULL,              NULL}           /* sentinel */
};

/* Initialization function for the module */
static int
_curses_panel_exec(PyObject *mod)
{
    _curses_panel_state *state = get_curses_panel_state(mod);
    /* Initialize object type */
    state->PyCursesPanel_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
        mod, &PyCursesPanel_Type_spec, NULL);
    if (state->PyCursesPanel_Type == NULL) {
        return -1;
    }

    if (PyModule_AddType(mod, state->PyCursesPanel_Type) < 0) {
        return -1;
    }

    import_curses();
    if (PyErr_Occurred()) {
        return -1;
    }

    /* For exception _curses_panel.error */
    state->PyCursesError = PyErr_NewException(
        "_curses_panel.error", NULL, NULL);

    if (PyModule_AddObjectRef(mod, "error", state->PyCursesError) < 0) {
        return -1;
    }

    /* Make the version available */
    PyObject *v = PyUnicode_FromString(PyCursesVersion);
    if (v == NULL) {
        return -1;
    }

    PyObject *d = PyModule_GetDict(mod);
    if (PyDict_SetItemString(d, "version", v) < 0) {
        Py_DECREF(v);
        return -1;
    }
    if (PyDict_SetItemString(d, "__version__", v) < 0) {
        Py_DECREF(v);
        return -1;
    }

    Py_DECREF(v);

    return 0;
}

static PyModuleDef_Slot _curses_slots[] = {
    {Py_mod_exec, _curses_panel_exec},
    // XXX gh-103092: fix isolation.
    {Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED},
    //{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
    {0, NULL}
};

static struct PyModuleDef _curses_panelmodule = {
    PyModuleDef_HEAD_INIT,
    .m_name = "_curses_panel",
    .m_size = sizeof(_curses_panel_state),
    .m_methods = PyCurses_methods,
    .m_slots = _curses_slots,
    .m_traverse = _curses_panel_traverse,
    .m_clear = _curses_panel_clear,
    .m_free = _curses_panel_free
};

PyMODINIT_FUNC
PyInit__curses_panel(void)
{
    return PyModuleDef_Init(&_curses_panelmodule);
}
