/***************************************************************************
 * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>                *
 * Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>                   *
 *                                                                         *
 *   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.                                   *
 ***************************************************************************/

#include "meter_python.h"
#include <qobject.h>
#include "karamba.h"
#include "karambaapp.h"
#include "meter.h"

bool checkKaramba(long widget)
{
  if (!widget)
  {
    PyErr_SetString(PyExc_ValueError, "widget pointer was 0.");
    return false;
  }
  if (!karambaApp->hasKaramba((karamba*)widget))
  {
    QString tmp;

    tmp.sprintf("no %x widget found.", widget);
    PyErr_SetString(PyExc_ValueError, tmp.ascii());
    return false;
  }
  return true;
}

bool checkMeter(long widget, long meter, const char* type)
{
  if (!meter)
  {
    PyErr_SetString(PyExc_ValueError, "meter pointer was 0.");
    return false;
  }
  if (!((karamba*)widget)->hasMeter((Meter*)meter))
  {
    QString tmp;

    tmp.sprintf("widget does not have meter %x.", meter);
    PyErr_SetString(PyExc_ValueError, tmp.ascii());
    return false;
  }
  if (!((QObject*)meter)->isA(type))
  {
    QString tmp;

    tmp.sprintf("meter is not type of %s.", type);
    PyErr_SetString(PyExc_TypeError, tmp.ascii());
    return false;
  }
  return true;
}

bool checkKarambaAndMeter(long widget, long meter, const char* type)
{
  return checkKaramba(widget) && checkMeter(widget, meter, type);
}

// Converts a Python String to a QString with Unicode support
QString PyString2QString(PyObject* text)
{
    QString qtext;
    if (PyString_CheckExact(text))
    {
        char* t = PyString_AsString(text);
        qtext.setAscii(t);
    }
    else if (PyUnicode_CheckExact(text))
    {
        Py_UNICODE* t = PyUnicode_AsUnicode(text);
        int length = PyUnicode_GetSize(text);
        qtext.setUnicodeCodes((ushort*)t, length);
    }
    else
    {
        // Error raise execption ...
    }
    return qtext;
}

// Converts a QString to a Python String with Unicode support
PyObject* QString2PyString(QString string)
{
  // XXX How to do this properly ?
  const char* tmp = string.ascii();
  if(tmp)
    return PyString_FromString(tmp);
  else
    return PyString_FromString("");
}

long getMeter(long widget, char* name)
{
  karamba* theme = (karamba*)widget;
  QObjectListIt it( *theme->meterList ); // iterate over meters

  while ( it != 0 )
  {
    if (strcmp(((Meter*) *it)->name(), name) == 0)
      return (long)*it;
    ++it;
  }
  return 0;
}

PyObject* py_getThemeMeter(PyObject *self, PyObject *args, QString type)
{
  long widget, meter;
  char* name;
  if (!PyArg_ParseTuple(args, "ls", &widget, &name))
    return NULL;
  if (!checkKaramba(widget))
    return NULL;
  if(!name)
    return NULL;
  meter = getMeter(widget, name);
  if (!checkMeter(widget, meter, type))
    return NULL;
  return (Py_BuildValue("l", meter));
}

PyObject* py_getSize(PyObject *self, PyObject *args, QString type)
{
  long widget;
  long meter;
  if (!PyArg_ParseTuple(args, "ll", &widget, &meter))
    return NULL;
  if (!checkKarambaAndMeter(widget, meter, type))
    return NULL;
  return Py_BuildValue("(i,i)", ((Meter*)meter)->getWidth(),
                                ((Meter*)meter)->getHeight());
}

PyObject* py_resize(PyObject *self, PyObject *args, QString type)
{
  long widget, meter, x, y;
  if (!PyArg_ParseTuple(args, "llll", &widget, &meter, &x, &y))
    return NULL;
  if (!checkKarambaAndMeter(widget, meter, type))
    return NULL;
  ((Meter*)meter)->setSize(((Meter*)meter)->getX(), ((Meter*)meter)->getY(),
                           x, y);
  return Py_BuildValue("l", 1);
}

PyObject* py_getPos(PyObject *self, PyObject *args, QString type)
{
  long widget, meter;
  if (!PyArg_ParseTuple(args, "ll", &widget, &meter))
    return NULL;
  if (!checkKarambaAndMeter(widget, meter, type))
    return NULL;
  return Py_BuildValue("(i,i)", ((Meter*)meter)->getX(),
                                ((Meter*)meter)->getY());
}

PyObject* py_move(PyObject *self, PyObject *args, QString type)
{
  long widget, meter, x, y;
  if (!PyArg_ParseTuple(args, "llll", &widget, &meter, &x, &y))
    return NULL;
  if (!checkKarambaAndMeter(widget, meter, type))
    return NULL;
  ((Meter*)meter)->setSize(x, y,
                           ((Meter*)meter)->getWidth(),
                           ((Meter*)meter)->getHeight());
  return Py_BuildValue("l", 1);
}

PyObject* py_hide(PyObject *self, PyObject *args, QString type)
{
  long widget, meter;
  if (!PyArg_ParseTuple(args, "ll", &widget, &meter))
    return NULL;
  if (!checkKarambaAndMeter(widget, meter, type))
    return NULL;
  ((Meter*)meter)->hide();
  return Py_BuildValue("l", 1);
}

PyObject* py_show(PyObject *self, PyObject *args, QString type)
{
  long widget, meter;
  if (!PyArg_ParseTuple(args, "ll", &widget, &meter))
    return NULL;
  if (!checkKarambaAndMeter(widget, meter, type))
    return NULL;
  ((Meter*)meter)->show();
  return Py_BuildValue("l", 1);
}

PyObject* py_getValue(PyObject *self, PyObject *args, QString type)
{
  long widget, meter;
  if (!PyArg_ParseTuple(args, "ll", &widget, &meter))
    return NULL;
  if (!checkKarambaAndMeter(widget, meter, type))
    return NULL;
  return Py_BuildValue("l", ((Meter*)meter)->getValue());
}

PyObject* py_setValue(PyObject *self, PyObject *args, QString type)
{
  long widget, meter, l;
  if (!PyArg_ParseTuple(args, "lll", &widget, &meter, &l))
    return NULL;
  if (!checkKarambaAndMeter(widget, meter, type))
    return NULL;
  ((Meter*)meter)->setValue(l);
  return Py_BuildValue("l", ((long)meter));
}

PyObject* py_getStringValue(PyObject *self, PyObject *args, QString type)
{
  long widget, meter;
  if (!PyArg_ParseTuple(args, "ll", &widget, &meter))
    return NULL;
  if (!checkKarambaAndMeter(widget, meter, type))
    return NULL;
  return Py_BuildValue("O",
      QString2PyString(((Meter*)meter)->getStringValue()));
}

PyObject* py_setStringValue(PyObject *self, PyObject *args, QString type)
{
  long widget, meter;
  PyObject* s;
  if (!PyArg_ParseTuple(args, "llO", &widget, &meter, &s))
    return NULL;
  if (!s)
    return NULL;
  if (!checkKarambaAndMeter(widget, meter, type))
    return NULL;
  ((Meter*)meter)->setValue(PyString2QString(s));
  return Py_BuildValue("l", ((long)meter));
}

PyObject* py_getMinMax(PyObject *self, PyObject *args, QString type)
{
  long widget, meter;
  if (!PyArg_ParseTuple(args, "ll", &widget, &meter))
    return NULL;
  if (!checkKarambaAndMeter(widget, meter, type))
    return NULL;
  return Py_BuildValue("(i,i)", ((Meter*)meter)->getMin(),
                                ((Meter*)meter)->getMax());
}

PyObject* py_setMinMax(PyObject *self, PyObject *args, QString type)
{
  long widget, meter, x, y;
  if (!PyArg_ParseTuple(args, "llll", &widget, &meter, &x, &y))
    return NULL;
  if (!checkKarambaAndMeter(widget, meter, type))
    return NULL;
  ((Meter*)meter)->setMin(x);
  ((Meter*)meter)->setMax(y);
  return Py_BuildValue("l", 1);
}

PyObject* py_getSensor(PyObject *self, PyObject *args, QString type)
{
  long widget, meter;
  QString s;
  if (!PyArg_ParseTuple(args, "ll", &widget, &meter))
    return NULL;
  if (!checkKarambaAndMeter(widget, meter, type))
    return NULL;
  return Py_BuildValue("s",
                       ((karamba*)widget)->getSensor((Meter*)meter).ascii());
}

PyObject* py_setSensor(PyObject *self, PyObject *args, QString type)
{
  long widget, meter;
  char* s;
  QString str;

  if (!PyArg_ParseTuple(args, "lls", &widget, &meter, &s))
    return NULL;
  if (!checkKarambaAndMeter(widget, meter, type))
    return NULL;
  str = s;
  ((karamba*)widget)->setSensor(str, (Meter*)meter);
  return Py_BuildValue("l", 1);
}

PyObject* py_setColor(PyObject *self, PyObject *args, QString type)
{
  long widget, meter;
  long r, g, b;
  if (!PyArg_ParseTuple(args, "lllll", &widget, &meter, &r, &g, &b))
    return NULL;
  if (!checkKarambaAndMeter(widget, meter, type))
    return NULL;
  ((Meter*)meter)->setColor( r, g, b );
  return Py_BuildValue("l", 1);
}

PyObject* py_getColor(PyObject *self, PyObject *args, QString type)
{
  long widget, meter;
  if (!PyArg_ParseTuple(args, "ll", &widget, &meter))
    return NULL;
  if (!checkKarambaAndMeter(widget, meter, type))
    return NULL;
  QColor color = ((Meter*)meter)->getColor();
  return Py_BuildValue("(i,i,i)", color.red(), color.green(), color.blue());
}

