#include "oosxl_module.h"


PyTypeObject TabledefType;

static void tabledef_dealloc(TabledefObject* self)
{
    Py_TYPE(self)->tp_free((PyObject*)self);
}

static PyObject* tabledef_name(TabledefObject* self, PyObject* args)
{
    if (!check_handle(self->handle, "table definition"))
        return NULL;

    const char* result = td_name(self->handle);
    if (result == NULL)
    {
        Py_RETURN_NONE;
    }

    return PyUnicode_FromString(result);
}

static PyObject* tabledef_range(TabledefObject* self, PyObject* args)
{
    int beginRow, beginCol, endRow, endCol;

    if (!check_handle(self->handle, "table definition"))
        return NULL;

    td_range(self->handle, &beginRow, &beginCol, &endRow, &endCol);
    return Py_BuildValue("(iiii)", beginRow, beginCol, endRow, endCol);
}

static PyObject* tabledef_display_name(TabledefObject* self, PyObject* args)
{
    if (!check_handle(self->handle, "table definition"))
        return NULL;

    const char* result = td_display_name(self->handle);
    if (result == NULL)
    {
        Py_RETURN_NONE;
    }

    return PyUnicode_FromString(result);
}

static PyObject* tabledef_set_display_name(TabledefObject* self, PyObject* args)
{
    const char* name;

    if (!check_handle(self->handle, "table definition"))
        return NULL;

    if (!PyArg_ParseTuple(args, "s", &name))
    {
        return NULL;
    }

    td_set_display_name(self->handle, name);
    Py_RETURN_NONE;
}

static PyObject* tabledef_comment(TabledefObject* self, PyObject* args)
{
    if (!check_handle(self->handle, "table definition"))
        return NULL;

    const char* result = td_comment(self->handle);
    if (result == NULL)
    {
        Py_RETURN_NONE;
    }

    return PyUnicode_FromString(result);
}

static PyObject* tabledef_set_comment(TabledefObject* self, PyObject* args)
{
    const char* comment;

    if (!check_handle(self->handle, "table definition"))
        return NULL;

    if (!PyArg_ParseTuple(args, "s", &comment))
    {
        return NULL;
    }

    td_set_comment(self->handle, comment);
    Py_RETURN_NONE;
}

static PyObject* tabledef_col_name(TabledefObject* self, PyObject* args)
{
    int idx;

    if (!check_handle(self->handle, "table definition"))
        return NULL;

    if (!PyArg_ParseTuple(args, "i", &idx))
    {
        return NULL;
    }

    const char* result = td_col_name(self->handle, idx);
    if (result == NULL)
    {
        Py_RETURN_NONE;
    }

    return PyUnicode_FromString(result);
}

static PyObject* tabledef_set_col_name(TabledefObject* self, PyObject* args)
{
    int idx;
    const char* name;

    if (!check_handle(self->handle, "table definition"))
        return NULL;

    if (!PyArg_ParseTuple(args, "is", &idx, &name))
    {
        return NULL;
    }

    td_set_col_name(self->handle, idx, name);
    Py_RETURN_NONE;
}

static PyObject* tabledef_insert_col(TabledefObject* self, PyObject* args)
{
    int idx;
    const char* colName;

    if (!check_handle(self->handle, "table definition"))
        return NULL;

    if (!PyArg_ParseTuple(args, "is", &idx, &colName))
    {
        return NULL;
    }

    int result = td_insert_col(self->handle, idx, colName);
    if (result == 0)
    {
        PyErr_SetString(PyExc_RuntimeError, "Failed to insert column");
        return NULL;
    }

    Py_RETURN_NONE;
}

static PyObject* tabledef_delete_col_by_index(TabledefObject* self, PyObject* args)
{
    int idx;

    if (!check_handle(self->handle, "table definition"))
        return NULL;

    if (!PyArg_ParseTuple(args, "i", &idx))
    {
        return NULL;
    }

    td_delete_col_by_index(self->handle, idx);
    Py_RETURN_NONE;
}

static PyObject* tabledef_delete_col(TabledefObject* self, PyObject* args)
{
    const char* colName;

    if (!check_handle(self->handle, "table definition"))
        return NULL;

    if (!PyArg_ParseTuple(args, "s", &colName))
    {
        return NULL;
    }

    td_delete_col(self->handle, colName);
    Py_RETURN_NONE;
}

static PyObject* tabledef_set_totals_row_label(TabledefObject* self, PyObject* args)
{
    const char* label;

    if (!check_handle(self->handle, "table definition"))
        return NULL;

    if (!PyArg_ParseTuple(args, "s", &label))
    {
        return NULL;
    }

    td_set_totals_row_label(self->handle, label);
    Py_RETURN_NONE;
}

static PyObject* tabledef_set_display_total(TabledefObject* self, PyObject* args)
{
    int show;

    if (!check_handle(self->handle, "table definition"))
        return NULL;

    if (!PyArg_ParseTuple(args, "i", &show))
    {
        return NULL;
    }

    td_set_display_total(self->handle, show);
    Py_RETURN_NONE;
}

static PyObject* tabledef_totals_row_func(TabledefObject* self, PyObject* args)
{
    int column_idx;

    if (!check_handle(self->handle, "table definition"))
        return NULL;

    if (!PyArg_ParseTuple(args, "i", &column_idx))
    {
        return NULL;
    }

    int result = td_totals_row_func(self->handle, column_idx);
    return PyLong_FromLong(result);
}

static PyObject* tabledef_set_totals_row_func(TabledefObject* self, PyObject* args)
{
    int colIndex, func;

    if (!check_handle(self->handle, "table definition"))
        return NULL;

    if (!PyArg_ParseTuple(args, "ii", &colIndex, &func))
    {
        return NULL;
    }

    td_set_totals_row_func(self->handle, colIndex, func);
    Py_RETURN_NONE;
}

static PyObject* tabledef_style_name(TabledefObject* self, PyObject* args)
{
    if (!check_handle(self->handle, "table definition"))
        return NULL;

    const char* result = td_style_name(self->handle);
    if (result == NULL)
    {
        Py_RETURN_NONE;
    }

    return PyUnicode_FromString(result);
}

static PyObject* tabledef_set_style_name(TabledefObject* self, PyObject* args)
{
    const char* style_name;

    if (!check_handle(self->handle, "table definition"))
        return NULL;

    if (!PyArg_ParseTuple(args, "s", &style_name))
    {
        return NULL;
    }

    td_set_style_name(self->handle, style_name);
    Py_RETURN_NONE;
}

static PyObject* tabledef_set_preset_style(TabledefObject* self, PyObject* args)
{
    int id;

    if (!check_handle(self->handle, "table definition"))
        return NULL;

    if (!PyArg_ParseTuple(args, "i", &id))
    {
        return NULL;
    }

    td_set_preset_style(self->handle, id);
    Py_RETURN_NONE;
}

static PyObject* tabledef_row_strips(TabledefObject* self, PyObject* args)
{
    if (!check_handle(self->handle, "table definition"))
        return NULL;

    int result = td_row_strips(self->handle);
    return PyBool_FromLong(result);
}

static PyObject* tabledef_set_row_strips(TabledefObject* self, PyObject* args)
{
    int strips;

    if (!check_handle(self->handle, "table definition"))
        return NULL;

    if (!PyArg_ParseTuple(args, "i", &strips))
    {
        return NULL;
    }

    td_set_row_strips(self->handle, strips);
    Py_RETURN_NONE;
}

static PyMethodDef tabledef_methods[] = {
    {"name", (PyCFunction)tabledef_name, METH_NOARGS, "Get table definition name"},
    {"range", (PyCFunction)tabledef_range, METH_NOARGS, "Get table definition range"},
    {"display_name", (PyCFunction)tabledef_display_name, METH_NOARGS, "Get display name"},
    {"set_display_name", (PyCFunction)tabledef_set_display_name, METH_VARARGS, "Set display name"},
    {"comment", (PyCFunction)tabledef_comment, METH_NOARGS, "Get comment"},
    {"set_comment", (PyCFunction)tabledef_set_comment, METH_VARARGS, "Set comment"},
    {"col_name", (PyCFunction)tabledef_col_name, METH_VARARGS, "Get column name"},
    {"set_col_name", (PyCFunction)tabledef_set_col_name, METH_VARARGS, "Set column name"},
    {"insert_col", (PyCFunction)tabledef_insert_col, METH_VARARGS, "Insert column"},
    {"delete_col_by_index", (PyCFunction)tabledef_delete_col_by_index, METH_VARARGS, "Delete column by index"},
    {"delete_col", (PyCFunction)tabledef_delete_col, METH_VARARGS, "Delete column by name"},
    {"set_totals_row_label", (PyCFunction)tabledef_set_totals_row_label, METH_VARARGS, "Set totals row label"},
    {"set_display_total", (PyCFunction)tabledef_set_display_total, METH_VARARGS, "Set display total"},
    {"totals_row_func", (PyCFunction)tabledef_totals_row_func, METH_VARARGS, "Get totals row function"},
    {"set_totals_row_func", (PyCFunction)tabledef_set_totals_row_func, METH_VARARGS, "Set totals row function"},
    {"style_name", (PyCFunction)tabledef_style_name, METH_NOARGS, "Get style name"},
    {"set_style_name", (PyCFunction)tabledef_set_style_name, METH_VARARGS, "Set style name"},
    {"set_preset_style", (PyCFunction)tabledef_set_preset_style, METH_VARARGS, "Set preset style"},
    {"row_strips", (PyCFunction)tabledef_row_strips, METH_NOARGS, "Check if row strips are enabled"},
    {"set_row_strips", (PyCFunction)tabledef_set_row_strips, METH_VARARGS, "Set row strips"},
    {NULL} /* Sentinel */
};

PyTypeObject TabledefType = {
    PyVarObject_HEAD_INIT(NULL, 0)
        .tp_name = "oosxl.Tabledef",
    .tp_doc = "Tabledef object",
    .tp_basicsize = sizeof(TabledefObject),
    .tp_itemsize = 0,
    .tp_flags = Py_TPFLAGS_DEFAULT,
    .tp_new = PyType_GenericNew,
    .tp_dealloc = (destructor)tabledef_dealloc,
    .tp_methods = tabledef_methods,
};

PyObject* create_tabledef_object(TabledefHandle handle)
{
    TabledefObject* obj = (TabledefObject*)PyObject_New(TabledefObject, &TabledefType);
    if (obj != NULL)
    {
        obj->handle = handle;
    }
    return (PyObject*)obj;
}
