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

#define PyLabel_API_pointers 1
#define PyLabelSpec_Type_NUM 0

extern int  makeAnnotation(int, int, float, float, float, int,
				   const GLfloat *, int, int, char *);
extern void deleteAnnotation(int *);
extern void getRGBColor(Widget, Pixel, float *, float *, float *);
extern void pixelToWorld(int, double *, double *);
extern int  checkInterrupt(void);

extern struct WINDOW windows[];
extern struct ANNOTATION *annotation;
extern Pixel stdcol[9];

PyLabelSpecObject *label_new(void);
static PyObject *label_label(PyObject *, PyObject *);
static PyObject *label_text(PyObject *, PyObject *);
static PyObject *label_translate(PyObject *, PyObject *);
static PyObject *label_setColor(PyObject *, PyObject *);
static PyObject *label_delete(PyObject *, PyObject *);
static PyObject *label_getattr(PyLabelSpecObject *, char *);
static void label_dealloc(PyLabelSpecObject *);

static char PyLabelSpec_Type__doc__[] =
  "Label specification";

statichere PyTypeObject PyLabelSpec_Type = {
  PyObject_HEAD_INIT(NULL)
  0,                               /*ob_size*/
  "LabelSpec",                     /*tp_name*/
  sizeof(PyLabelSpecObject),       /*tp_basicsize*/
  0,                               /*tp_itemsize*/
  /* methods */
  (destructor)label_dealloc,       /*tp_dealloc*/
  0,                               /*tp_print*/
  (getattrfunc)label_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 */
  PyLabelSpec_Type__doc__
};

static PyMethodDef label_methods[] = {
  {"label",            label_label,     1},
  {"text",             label_text,      1},
  {"translate",        label_translate, 1},
  {"setColor",         label_setColor,  1},
  {"delete",           label_delete,  1},
  {NULL,               NULL}
};

static PyObject *label_translate(PyObject *self, PyObject *args)
{
  PyLabelSpecObject *s;
  Dimension width, height;
  int x, y, z, which;

  if (checkInterrupt()) return(NULL);
  if (!PyArg_ParseTuple(args, "iii", &x, &y, &z)) return(NULL);
 
  if (!self)
  {
    Py_INCREF(Py_None);
    return(Py_None);
  }
  s=(PyLabelSpecObject *)self;
  which=s->labelID;
  XtVaGetValues(windows[VIEWER].widget, XtNwidth, &width, XtNheight, &height, NULL);
  annotation[which].x=2.0*(double)x/(double)width-1.0;
  annotation[which].y=2.0*(double)y/(double)height-1.0;
  annotation[which].z=z;
  Py_INCREF(Py_None);
  return(Py_None);
}

static PyObject *label_setColor(PyObject *self, PyObject *args)
{
  PyLabelSpecObject *s;
  Pixel color=(Pixel)0;
  float r, g, b, a, rs, gs, bs, diff, d;
  int which, i;

  if (checkInterrupt()) return(NULL);
  if (!PyArg_ParseTuple(args, "ffff", &r, &g, &b, &a)) return(NULL);
 
  if (!self)
  {
    Py_INCREF(Py_None);
    return(Py_None);
  }
  s=(PyLabelSpecObject *)self;
  which=s->labelID;
  diff=10.0;
  for (i=0; i<9; i++)
  {
     getRGBColor(windows[VIEWER].widget, stdcol[i], &rs, &gs, &bs);
     d=(rs-r)*(rs-r)+(gs-g)*(gs-g)+(bs-b)*(bs-b);
     if (d < diff)
     {
	 color=stdcol[i];
	 diff=d;
     }
  }
  annotation[which].color=color;
  annotation[which].color_rgb[0]=r;
  annotation[which].color_rgb[1]=g;
  annotation[which].color_rgb[2]=b;
  annotation[which].color_rgb[3]=a;
  Py_INCREF(Py_None);
  return(Py_None);
}

static PyObject *label_label(PyObject *self, PyObject *args)
{
  const float black[4] = {0.0, 0.0, 0.0, 1.0};
  int mode=EDITABLE | MOVEABLE, which;

  if (checkInterrupt()) return(NULL);
  if (!PyArg_ParseTuple(args, "|i", &mode)) return(NULL);
  which=makeAnnotation((-1), COORDINATES, 0.0, 0.0, 0.0,
	                 stdcol[BLACK], black, mode, 0, "");
  return((PyObject *)annotation[which].pyObject);
}

PyLabelSpecObject *label_new(void)
{
  PyLabelSpecObject *self;

  self=PyObject_NEW(PyLabelSpecObject, &PyLabelSpec_Type);
  if (self == NULL)
  {
    PyErr_NoMemory();
    return(NULL);
  }
  self->labelID=0;
  return((PyLabelSpecObject *)self);
}

static PyObject *label_text(PyObject *self, PyObject *args)
{
  PyLabelSpecObject *s;
  int which;
  char *text=NULL;

  if (checkInterrupt()) return(NULL);
  if (!PyArg_ParseTuple(args, "|s", &text)) return(NULL);
  if (!self)
  {
    Py_INCREF(Py_None);
    return(Py_None);
  }
  s=(PyLabelSpecObject *)self;
  which=s->labelID;
  if (text == NULL) /* get */
    return(PyString_FromString(annotation[which].text));
  else              /* set */
  {
    strncpy(annotation[which].text, text, MAXLENLINE-1); 
    Py_INCREF(Py_None);
    return(Py_None);
  }
}

static PyObject *label_delete(PyObject *self, PyObject *args)
{
  PyLabelSpecObject *s;
  int which;

  if (checkInterrupt()) return(NULL);
  if (!self)
  {
    Py_INCREF(Py_None);
    return(Py_None);
  }
  s=(PyLabelSpecObject *)self;
  which=s->labelID;
  deleteAnnotation(&which);
  Py_INCREF(Py_None);
  return(Py_None);
}

static void label_dealloc(PyLabelSpecObject *self)
{
  /* This has to be a dummy function, since labels are handled in Viewmol
  PyMem_DEL(self); */
}

static PyObject *label_getattr(PyLabelSpecObject *self, char *name)
{
  return(Py_FindMethod(label_methods, (PyObject *)self, name));
}

void initLabelModule(void)
{
  PyObject *module, *dict;
  static void *PyLabel_API[PyLabel_API_pointers];

  PyLabelSpec_Type.ob_type=&PyType_Type;

  module=Py_InitModule("label", label_methods);
  dict=PyModule_GetDict(module);

  PyLabel_API[PyLabelSpec_Type_NUM]=(void *)&PyLabelSpec_Type;
  PyDict_SetItemString(dict, "_C_API", PyCObject_FromVoidPtr((void *)PyLabel_API, NULL));
  PyDict_SetItemString(dict, "EDITABLE", PyInt_FromLong((long)(EDITABLE)));
  PyDict_SetItemString(dict, "MOVABLE", PyInt_FromLong((long)(MOVEABLE)));
}
