/*
 * 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.
 *-------------------------------------------------------------------------
 */
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "scode.h"
#include "log.h"
#include "msg_queue.h"
#include "sysinput.h"
#include "ep_upiwin.h"
#include "ep_init.h"

static HRESULT convert_msg(PyObject *target, PMSG source)
{
  PyObject *attr;

  ASSERT(PyDict_CheckExact(target));
  PyDict_Clear(target);
  attr = PyLong_FromUnsignedLong(source->target);
  if (!attr)
    return E_FAIL;
  if (PyDict_SetItemString(target, "target", attr))
    return E_FAIL;
  attr = PyLong_FromUnsignedLong(source->message);
  if (!attr)
    return E_FAIL;
  if (PyDict_SetItemString(target, "message", attr))
    return E_FAIL;
  attr = Py_BuildValue("[k,k]", source->attrs[0], source->attrs[1]);
  if (!attr)
    return E_FAIL;
  if (PyDict_SetItemString(target, "attrs", attr))
    return E_FAIL;
  attr = PyLong_FromUnsignedLongLong(source->timestamp);
  if (!attr)
    return E_FAIL;
  if (PyDict_SetItemString(target, "timestamp", attr))
    return E_FAIL;
  return S_OK;
}

PyObject *Epython_get_message(PyObject *self, PyObject *args)
{
  PyObject *out;
  MSG msg;

  if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &out))
    return NULL;

  /* release the GIL to allow us to block waiting for input if necessary */
  Py_BEGIN_ALLOW_THREADS
  while (!Mq_peek(Sys_Queue, &msg, PEEK_REMOVE))
    Sys_wait_for_input();
  Py_END_ALLOW_THREADS

  if (FAILED(convert_msg(out, &msg)))
  {
    PyErr_SetString(PyExc_RuntimeError, "could not convert received message");
    return NULL;
  }
  return PyBool_FromLong(msg.message != WM_QUIT);
}

PyObject *Epython_post_quit_message(PyObject *self, PyObject *args)
{
  INT32 exitcode;

  if (!PyArg_ParseTuple(args, "i", &exitcode))
    return NULL;
  Sys_Exit_Code = exitcode;
  Mq_post1(Sys_Queue, 0, WM_QUIT, exitcode);
  Py_RETURN_NONE;
}
