/*******************************************************************************
*                                                                              *
*                                   Viewmol                                    *
*                                                                              *
*                        E L E M E N T M O D U L E . C                         *
*                                                                              *
*                 Copyright (c) Joerg-R. Hill, October 2003                    *
*                                                                              *
********************************************************************************
*
* $Id: elementmodule.c,v 1.2 2003/11/07 11:00:13 jrh Exp $
* $Log: elementmodule.c,v $
* Revision 1.2  2003/11/07 11:00:13  jrh
* Release 2.4
*
* Revision 1.1  2000/12/10 15:05:35  jrh
* Initial revision
*
*/     
#include<ctype.h>
#include<stdio.h>
#include<Xm/DrawingA.h>
#include<Xm/ToggleB.h>
#include "viewmol.h"

#define PyElement_API_pointers 1
#define PyElementSpec_Type_NUM 0

extern int checkInterrupt(void);

PyElementSpecObject *element_new(void);
static PyObject *element_getSymbol(PyObject *, PyObject *);
static PyObject *element_darkColor(PyObject *, PyObject *);
static PyObject *element_lightColor(PyObject *, PyObject *);
static PyObject *element_emissionColor(PyObject *, PyObject *);
static PyObject *element_ambientColor(PyObject *, PyObject *);
static PyObject *element_specularColor(PyObject *, PyObject *);
static PyObject *element_shininess(PyObject *, PyObject *);
static PyObject *element_transperancy(PyObject *, PyObject *);
static PyObject *element_getattr(PyElementSpecObject *, char *);
static void element_dealloc(PyElementSpecObject *);

extern struct ELEMENT *elements;
extern int nmolecule;

static char PyElementSpec_Type__doc__[] =
  "Element specification";

statichere PyTypeObject PyElementSpec_Type = {
  PyObject_HEAD_INIT(NULL)
  0,                               /*ob_size*/
  "ElementSpec",                   /*tp_name*/
  sizeof(PyElementSpecObject),     /*tp_basicsize*/
  0,                               /*tp_itemsize*/
  /* methods */
  (destructor)element_dealloc,     /*tp_dealloc*/
  0,                               /*tp_print*/
  (getattrfunc)element_getattr,    /*tp_getattr*/
  0,                               /*tp_setattr*/
  0,                               /*tp_compare*/
  0,                               /*tp_repr*/
  0,                               /*tp_as_number*/
  0,                               /*tp_as_sequence*/
  0,                               /*tp_as_mapping*/
  0,                               /*tp_hash*/
  0,                               /*tp_call*/
  0,                               /*tp_str*/
  0,                               /*tp_getattro*/
  0,                               /*tp_setattro*/
  /* Space for future expansion */
  0L,0L,
  /* Documentation string */
  PyElementSpec_Type__doc__
};

static PyMethodDef element_methods[] = {
  {"getSymbol",     element_getSymbol, 1},
  {"darkColor",     element_darkColor, 1},
  {"lightColor",    element_lightColor, 1},
  {"emissionColor", element_emissionColor, 1},
  {"ambientColor",  element_ambientColor, 1},
  {"specularColor", element_specularColor, 1},
  {"shininess",     element_shininess, 1},
  {"transperancy",  element_transperancy, 1},
  {NULL,            NULL}
};

PyElementSpecObject *element_new(void)
{
  PyElementSpecObject *self;

  self=PyObject_NEW(PyElementSpecObject, &PyElementSpec_Type);
  if (self == NULL)
  {
    PyErr_NoMemory();
    return(NULL);
  }
  self->elementID=0;
  return(self);
}

static PyObject *element_getSymbol(PyObject *self, PyObject *args)
{
  PyElementSpecObject *s;
  int ielement;

  if (checkInterrupt()) return(NULL);
  if (self)
  {
    s=(PyElementSpecObject *)self;
    ielement=s->elementID;
    return(PyString_FromString(elements[ielement].symbol));
  }
  Py_INCREF(Py_None);
  return(Py_None);
}

static PyObject *element_darkColor(PyObject *self, PyObject *args)
{
  PyElementSpecObject *s;
  PyObject *tuple;
  float r=-1.0, g=-1.0, b=-1.0;
  int ielement;

  if (checkInterrupt()) return(NULL);
  if (self)
  {
    s=(PyElementSpecObject *)self;
    ielement=s->elementID;
    if (!PyArg_ParseTuple(args, "|fff", &r, &g, &b)) return(NULL);
    if (r == -1.0 && g == -1.0 && b == -1.0) /* get */
    {
      if ((tuple=PyTuple_New(3)))
      {
        PyTuple_SetItem(tuple, 0, PyFloat_FromDouble((double)elements[ielement].dark[0]));
        PyTuple_SetItem(tuple, 1, PyFloat_FromDouble((double)elements[ielement].dark[1]));
        PyTuple_SetItem(tuple, 2, PyFloat_FromDouble((double)elements[ielement].dark[2]));
        return(tuple);
      }
    }
    else                                     /* set */
    {
      if (r < 0.0 || r > 1.0 || g < 0.0 || g > 1.0 || b < 0.0 || b > 1.0)
      {
        PyErr_SetString(PyExc_ValueError, "Value out of range");
        return(NULL);
      }
      elements[ielement].dark[0]=r;
      elements[ielement].dark[1]=g;
      elements[ielement].dark[2]=b;
    }
  }
  Py_INCREF(Py_None);
  return(Py_None);
}

static PyObject *element_lightColor(PyObject *self, PyObject *args)
{
  PyElementSpecObject *s;
  PyObject *tuple;
  float r=-1.0, g=-1.0, b=-1.0;
  int ielement;

  if (checkInterrupt()) return(NULL);
  if (self)
  {
    s=(PyElementSpecObject *)self;
    ielement=s->elementID;
    if (!PyArg_ParseTuple(args, "|fff", &r, &g, &b)) return(NULL);
    if (r == -1.0 && g == -1.0 && b == -1.0) /* get */
    {
      if ((tuple=PyTuple_New(3)))
      {
        PyTuple_SetItem(tuple, 0, PyFloat_FromDouble((double)elements[ielement].light[0]));
        PyTuple_SetItem(tuple, 1, PyFloat_FromDouble((double)elements[ielement].light[1]));
        PyTuple_SetItem(tuple, 2, PyFloat_FromDouble((double)elements[ielement].light[2]));
    	  return(tuple);
      }
    }
    else                                     /* set */
    {
      if (r < 0.0 || r > 1.0 || g < 0.0 || g > 1.0 || b < 0.0 || b > 1.0)
      {
        PyErr_SetString(PyExc_ValueError, "Value out of range");
        return(NULL);
      }
      elements[ielement].light[0]=r;
      elements[ielement].light[1]=g;
      elements[ielement].light[2]=b;
    }
  }
  Py_INCREF(Py_None);
  return(Py_None);
}

static PyObject *element_emissionColor(PyObject *self, PyObject *args)
{
  PyElementSpecObject *s;
  PyObject *tuple;
  float r=-1.0, g=-1.0, b=-1.0;
  int ielement;

  if (checkInterrupt()) return(NULL);
  if (self)
  {
    s=(PyElementSpecObject *)self;
    ielement=s->elementID;
    if (!PyArg_ParseTuple(args, "|fff", &r, &g, &b)) return(NULL);
    if (r == -1.0 && g == -1.0 && b == -1.0) /* get */
    {
      if ((tuple=PyTuple_New(3)))
      {
        PyTuple_SetItem(tuple, 0, PyFloat_FromDouble((double)elements[ielement].emission[0]));
        PyTuple_SetItem(tuple, 1, PyFloat_FromDouble((double)elements[ielement].emission[1]));
        PyTuple_SetItem(tuple, 2, PyFloat_FromDouble((double)elements[ielement].emission[2]));
    	  return(tuple);
      }
    }
    else                                     /* set */
    {
      if (r < 0.0 || r > 1.0 || g < 0.0 || g > 1.0 || b < 0.0 || b > 1.0)
      {
        PyErr_SetString(PyExc_ValueError, "Value out of range");
        return(NULL);
      }
      elements[ielement].emission[0]=r;
      elements[ielement].emission[1]=g;
      elements[ielement].emission[2]=b;
    }
  }
  Py_INCREF(Py_None);
  return(Py_None);
}

static PyObject *element_ambientColor(PyObject *self, PyObject *args)
{
  PyElementSpecObject *s;
  PyObject *tuple;
  float r=-1.0, g=-1.0, b=-1.0;
  int ielement;

  if (checkInterrupt()) return(NULL);
  if (self)
  {
    s=(PyElementSpecObject *)self;
    ielement=s->elementID;
    if (!PyArg_ParseTuple(args, "|fff", &r, &g, &b)) return(NULL);
    if (r == -1.0 && g == -1.0 && b == -1.0) /* get */
    {
      if ((tuple=PyTuple_New(3)))
      {
        PyTuple_SetItem(tuple, 0, PyFloat_FromDouble((double)elements[ielement].ambient[0]));
        PyTuple_SetItem(tuple, 1, PyFloat_FromDouble((double)elements[ielement].ambient[1]));
        PyTuple_SetItem(tuple, 2, PyFloat_FromDouble((double)elements[ielement].ambient[2]));
    	  return(tuple);
      }
    }
    else                                     /* set */
    {
      if (r < 0.0 || r > 1.0 || g < 0.0 || g > 1.0 || b < 0.0 || b > 1.0)
      {
        PyErr_SetString(PyExc_ValueError, "Value out of range");
        return(NULL);
      }
      elements[ielement].ambient[0]=r;
      elements[ielement].ambient[1]=g;
      elements[ielement].ambient[2]=b;
    }
  }
  Py_INCREF(Py_None);
  return(Py_None);
}

static PyObject *element_specularColor(PyObject *self, PyObject *args)
{
  PyElementSpecObject *s;
  PyObject *tuple;
  float r=-1.0, g=-1.0, b=-1.0;
  int ielement;

  if (checkInterrupt()) return(NULL);
  if (self)
  {
    s=(PyElementSpecObject *)self;
    ielement=s->elementID;
    if (!PyArg_ParseTuple(args, "|fff", &r, &g, &b)) return(NULL);
    if (r == -1.0 && g == -1.0 && b == -1.0) /* get */
    {
      if ((tuple=PyTuple_New(3)))
      {
        PyTuple_SetItem(tuple, 0, PyFloat_FromDouble((double)elements[ielement].specular[0]));
        PyTuple_SetItem(tuple, 1, PyFloat_FromDouble((double)elements[ielement].specular[1]));
        PyTuple_SetItem(tuple, 2, PyFloat_FromDouble((double)elements[ielement].specular[2]));
    	  return(tuple);
      }
    }
    else                                     /* set */
    {
      if (r < 0.0 || r > 1.0 || g < 0.0 || g > 1.0 || b < 0.0 || b > 1.0)
      {
        PyErr_SetString(PyExc_ValueError, "Value out of range");
        return(NULL);
      }
      elements[ielement].specular[0]=r;
      elements[ielement].specular[1]=g;
      elements[ielement].specular[2]=b;
    }
  }
  Py_INCREF(Py_None);
  return(Py_None);
}

static PyObject *element_shininess(PyObject *self, PyObject *args)
{
  PyElementSpecObject *s;
  float shininess=-1.0;
  int ielement;

  if (checkInterrupt()) return(NULL);
  if (self)
  {
    s=(PyElementSpecObject *)self;
    ielement=s->elementID;
    if (!PyArg_ParseTuple(args, "|f", &shininess)) return(NULL);
    if (shininess == -1.0) /* get */
      return(PyFloat_FromDouble((double)elements[ielement].shininess));
    else                   /* set */
    {
      if (shininess < 0.0 || shininess > 128.0)
      {
        PyErr_SetString(PyExc_ValueError, "Value out of range");
        return(NULL);
      }
      elements[ielement].shininess=shininess;
    }
  }
  Py_INCREF(Py_None);
  return(Py_None);
}

static PyObject *element_transperancy(PyObject *self, PyObject *args)
{
  PyElementSpecObject *s;
  float transperancy=-1.0;
  int ielement;

  if (checkInterrupt()) return(NULL);
  if (self)
  {
    s=(PyElementSpecObject *)self;
    ielement=s->elementID;
    if (!PyArg_ParseTuple(args, "|f", &transperancy)) return(NULL);
    if (transperancy == -1.0) /* get */
      return(PyFloat_FromDouble((double)elements[ielement].alpha));
    else                      /* set */
    {
      if (transperancy < 0.0 || transperancy > 1.0)
      {
        PyErr_SetString(PyExc_ValueError, "Value out of range");
        return(NULL);
      }
      elements[ielement].alpha=transperancy;
    }
  }
  Py_INCREF(Py_None);
  return(Py_None);
}

static void element_dealloc(PyElementSpecObject *self)
{
  if (!self) return;
  PyMem_DEL(self);
}

static PyObject *element_getattr(PyElementSpecObject *self, char *name)
{
  return(Py_FindMethod(element_methods, (PyObject *)self, name));
}

void initElementModule(void)
{
  PyObject *module, *dict;
  static void *PyElement_API[PyElement_API_pointers];

  PyElementSpec_Type.ob_type=&PyType_Type;

  module=Py_InitModule("element", element_methods);
  dict=PyModule_GetDict(module);

  PyElement_API[PyElementSpec_Type_NUM]=(void *)&PyElementSpec_Type;
  PyDict_SetItemString(dict, "_C_API", PyCObject_FromVoidPtr((void *)PyElement_API, NULL));
}
