/*
 * UPIWIN - Micro Pi Windowing Framework Kernel
 * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *-------------------------------------------------------------------------
 */
#include <string.h>
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "scode.h"
#include "log.h"
#include "gfxobj.h"
#include "bitmap.h"
#include "ep_types.h"

static PyMethodDef BitmapMethods[] = {
  {NULL, NULL, 0, NULL}
};

static PyObject *bitmap_get_width(BitmapObject *self, void *closure)
{
  if (!(self->pbmp))
  {
    PyErr_SetString(PyExc_RuntimeError, "bad bitmap object");
    return NULL;
  }
  return PyLong_FromUnsignedLong(self->pbmp->width);
}

static PyObject *bitmap_get_height(BitmapObject *self, void *closure)
{
  if (!(self->pbmp))
  {
    PyErr_SetString(PyExc_RuntimeError, "bad bitmap object");
    return NULL;
  }
  return PyLong_FromUnsignedLong(self->pbmp->height);
}

static PyGetSetDef BitmapProperties[] = {
  {"width", (getter)bitmap_get_width, NULL,
   "Width of this bitmap", NULL},
  {"height", (getter)bitmap_get_height, NULL,
   "Height of this bitmap", NULL},
  {NULL, NULL, NULL, NULL, NULL}
};

static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds)
{
  static char *kwlist[] = { "stock", "width", "height", NULL };
  const char *stock;
  int width = 0, height = 0;

  if (!PyArg_ParseTupleAndKeywords(args, kwds, "|$sii", kwlist, &stock, &width, &height))
    return -1;

  if (stock)
  {
    self->pbmp = _BMP_GetStock(stock);
    if (!(self->pbmp))
    {
      PyErr_Format(PyExc_RuntimeError, "no such stock bitmap: '%s'", stock);
      return -1;
    }
  }
  else
  {
    width = MAX(1, width);
    height = MAX(1, height);
    self->pbmp = BMP_Create(width, height, NULL);
    if (!(self->pbmp))
    {
      PyErr_SetString(PyExc_RuntimeError, "unable to create bitmap");
      return -1;
    }
  }
  return 0;
}

static void bitmap_dealloc(BitmapObject *self)
{
  if (self->pbmp)
    BMP_Delete(self->pbmp);
  Py_TYPE(self)->tp_free((PyObject *)self);
}

PyTypeObject BitmapType = {
  PyVarObject_HEAD_INIT(NULL, 0)
  .tp_name = "upiwin.Bitmap",
  .tp_doc = "Bitmap object",
  .tp_basicsize = sizeof(BitmapObject),
  .tp_itemsize = 0,
  .tp_flags = Py_TPFLAGS_DEFAULT,
  .tp_new = PyType_GenericNew,
  .tp_init = (initproc)bitmap_init,
  .tp_dealloc = (destructor)bitmap_dealloc,
  .tp_methods = BitmapMethods,
  .tp_getset = BitmapProperties,
};

HRESULT Epython_register_bitmap(PyObject *module)
{
  if (PyType_Ready(&BitmapType) < 0)
    return E_FAIL;
  Py_INCREF(&BitmapType);
  if (PyModule_AddObject(module, "Bitmap", (PyObject *)(&BitmapType)) < 0)
  {
    Py_DECREF(&BitmapType);
    return E_FAIL;
  }
  return S_OK;
}

PyObject *Epython_wrap_bitmap(PBITMAP pbmp)
{
  PyObject *rc = NULL, *args, *kwargs;
  BitmapObject *pbitmapobj;

  args = PyTuple_New(0);
  if (args)
  {
    kwargs = PyDict_New();
    if (kwargs)
    {
      rc = PyType_GenericNew(&BitmapType, args, kwargs);
      if (rc)
      {
        pbitmapobj = (BitmapObject *)rc;
        if (pbitmapobj->pbmp)
          BMP_Delete(pbitmapobj->pbmp);
        pbitmapobj->pbmp = pbmp;
      }
      Py_DECREF(kwargs);
    }
    Py_DECREF(args);
  }

  if (!rc)
    PyErr_SetString(PyExc_RuntimeError, "unable to create bitmap");
  return rc;
}
