#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 lon, lat;
	double ra, dec;
} AirMass;

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

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

static int
AirMass_init(AirMass *self, PyObject *args)
{
	const char *objname, *locname;
	double ra, dec, lon, lat;

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

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

static PyObject *
AirMass_airmass(AirMass *self, PyObject *args)
{
	int res;
	double jd, x;

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

	res = cmpack_airmass(jd, self->ra, self->dec, self->lon, self->lat, &x, NULL);
	if (res!=0) 
		return cmpack_error(res);
	if (x<=0)
		Py_RETURN_NONE;
	return PyFloat_FromDouble(x);
}

static PyObject *
AirMass_altitude(AirMass *self, PyObject *args)
{
	int res;
	double jd, h;

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

	res = cmpack_airmass(jd, self->ra, self->dec, self->lon, self->lat, NULL, &h);
	if (res!=0) 
		return cmpack_error(res);
	return PyFloat_FromDouble(h);
}

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

static PyMethodDef AirMass_methods[] = {
	{"airmass", (PyCFunction)AirMass_airmass, METH_VARARGS,
	"Computes air-mass coefficient for given Julian date in UT"},
	{"altitude", (PyCFunction)AirMass_altitude, METH_VARARGS,
	"Computes altitude of the object for given Julian date in UT"},
    {NULL}  /* Sentinel */
};

PyTypeObject AirMassType = {
    PyObject_HEAD_INIT(NULL)
    .tp_name = "cmpack.AirMass",        
    .tp_basicsize = sizeof(AirMass),    
    .tp_dealloc = (destructor)AirMass_dealloc,          
    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 
    .tp_doc = "Air-mass context",        
    .tp_methods = AirMass_methods,       
    .tp_getset = AirMass_getset,         
    .tp_init = (initproc)AirMass_init,   
    .tp_new = AirMass_new                
};
