#define PY_SSIZE_T_CLEAN
#include <Python.h>

#include "cmunipack.h"
#include "framesetclass.h"

PyObject *cmpack_error(int code);
PyObject *err_closed(void);

typedef struct {
    PyObject_HEAD
	double ra, dec;
} HelCorr;

static PyObject *
HelCorr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    HelCorr *self = (HelCorr*)type->tp_alloc(type, 0);
	if (self != NULL) {
		self->ra = self->dec = 0;
	}
    return (PyObject *)self;
}

static void
HelCorr_dealloc(HelCorr* self)
{
    self->ob_base.ob_type->tp_free((PyObject*)self);
}

static int
HelCorr_init(HelCorr *self, PyObject *args)
{
	const char *objname;
	double ra, dec;

    if (!PyArg_ParseTuple(args, "(zdd)", &objname, &ra, &dec))
        return -1;

	self->ra = ra;
	self->dec = dec;
    return 0;
}

static PyObject *
HelCorr_hc(HelCorr *self, PyObject *args)
{
	double jd, hc;

    if (!PyArg_ParseTuple(args, "d", &jd))
        return NULL;

	hc = cmpack_helcorr(jd, self->ra, self->dec);
	return PyFloat_FromDouble(hc);
}

static PyObject *
HelCorr_hjd(HelCorr *self, PyObject *args)
{
	double jd, hc;

    if (!PyArg_ParseTuple(args, "d", &jd))
        return NULL;

	hc = cmpack_helcorr(jd, self->ra, self->dec);
	return PyFloat_FromDouble(jd + hc);
}

static PyGetSetDef HelCorr_getset[] = {
	{NULL}
};

static PyMethodDef HelCorr_methods[] = {
	{"hc", (PyCFunction)HelCorr_hc, METH_VARARGS,
	"Computes heliocentric correction for given geocentric Julian date"},
	{"hjd", (PyCFunction)HelCorr_hjd, METH_VARARGS,
	"Computes heliocentric Julian date for given geocentric Julian date"},
    {NULL}  /* Sentinel */
};

PyTypeObject HelCorrType = {
    PyObject_HEAD_INIT(NULL)
    .tp_name = "cmpack.HelCorr",          /*tp_name*/
    .tp_basicsize = sizeof(HelCorr),           /*tp_basicsize*/
    .tp_dealloc = (destructor)HelCorr_dealloc,           /*tp_dealloc*/
    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,        /*tp_flags*/
    .tp_doc = "Heliocentric correction",        /* tp_doc */
    .tp_methods = HelCorr_methods,           /* tp_methods */
    .tp_getset = HelCorr_getset,            /* tp_getset */
    .tp_init = (initproc)HelCorr_init,      /* tp_init */
    .tp_new = HelCorr_new                 /* tp_new */
};
