/**************************************************************

konvoes.c (C-Munipack project)
Conversion functions for OES Astro files
Copyright (C) 2003 David Motl, dmotl@volny.cz

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.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

**************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdint.h>
#include <fitsio.h>

#include "config.h"
#include "oesfile.h"
#include "konvoes.h"
#include "comfun.h"
#include "console.h"

/* Returns nonzero if the file is in oes format */
int oes_test(const char *block, size_t length, size_t filesize)
{
	uint32_t buf[64];

	if (filesize>=64*4 && length>=64*4) {
		memcpy(buf, block, 64*sizeof(uint32_t));
		return (buf[62]==H_MAG1_OWN && buf[63]==H_MAG2_OWN) || (buf[62]==H_MAG1_INV && buf[63]==H_MAG2_INV);
	}
	return 0;
}

/* Read parameters from SBIG file */
int oes_open(tHandle *handle, const char *filename, CmpackOpenMode flags)
{
	return oesopen((oesfile**)handle, filename);
}

/* Close file and free allocated memory */
void oes_close(tHandle handle)
{
	oesclos((oesfile*)handle);
}

/* Reads string value from header */
int oes_gets(tHandle handle, const char *key, char **val)
{
	if (oesgkys((oesfile*)handle, atoi(key), val)==0)
		return 0;
	else
		return CMPACK_ERR_KEY_NOT_FOUND;
}

char *oes_getmagic(tHandle handle)
{
	return cmpack_strdup("OES Astro file");
}

/* Reads integer value from header */
int oes_geti(tHandle handle, const char *key, int *value)
{
	if (oesgkyi((oesfile*)handle, atoi(key), value)==0)
		return 0;
	else
		return CMPACK_ERR_KEY_NOT_FOUND;
}

int oes_getsize(tHandle handle, int *width, int *height)
{
	int nx, ny;

	if (oesghpr((oesfile*)handle, &nx, &ny)==0) {
		if (width) *width = nx;
		if (height) *height = ny;
		return 0;
	} else {
		if (width) *width = 0;
		if (height) *height = 0;
		return CMPACK_ERR_INVALID_SIZE;
	}
}

/* Reads floating point value from header */
int oes_getd(tHandle handle, const char *key, double *value)
{
	if (oesgkyd((oesfile*)handle, atoi(key), value)==0)
		return 0;
	else
		return CMPACK_ERR_KEY_NOT_FOUND;
}

/* Get exposure duration */
int oes_getexptime(tHandle handle, double *val)
{
	if (oesgexp((oesfile*)handle, val)==0)
		return 0;
	else
		return CMPACK_ERR_KEY_NOT_FOUND;
}

/* Get date and time of observation */
int oes_getdatetime(tHandle handle, CmpackDateTime *dt)
{
	memset(dt, 0, sizeof(CmpackDateTime));
	if (oesgdat((oesfile*)handle, &dt->date.year, &dt->date.month, &dt->date.day, 
		&dt->time.hour, &dt->time.minute, &dt->time.second)==0) 
		return 0;
	else
		return CMPACK_ERR_KEY_NOT_FOUND;
}

/* Get CCD temperature */
int oes_getccdtemp(tHandle handle, double *val)
{
	if (oesgtem((oesfile*)handle, val)==0)
		return 0;
	else
		return CMPACK_ERR_KEY_NOT_FOUND;
}

/* Add string to history */
int oes_copyheader(tHandle handle, CmpackImageHeader *hdr, CmpackChannel channel, CmpackConsole *con)
{
	int sstat;
	char datestr[64], timestr[64];
	double exptime, ccdtemp;
	CmpackDateTime dt;
	oesfile *src = (oesfile*)handle;
	fitsfile *dst = (fitsfile*)hdr->fits;

	/* Set date and time of observation */
	memset(&dt, 0, sizeof(CmpackDateTime));
	sstat = oesgdat(src, &dt.date.year, &dt.date.month, &dt.date.day, 
		&dt.time.hour, &dt.time.minute, &dt.time.second);
	if (sstat==0) {
		sprintf(datestr, "%04d-%02d-%02d", dt.date.year, dt.date.month, dt.date.day);
		ffukys(dst,"DATE-OBS", (char*) datestr, "UT DATE OF START", &hdr->status);
		sprintf(timestr, "%02d:%02d:%02d.%03d", dt.time.hour, dt.time.minute, dt.time.second, dt.time.milisecond);
		ffukys(dst,"TIME-OBS", (char*) timestr, "UT TIME OF START", &hdr->status);
	}

	/* Other parameters */
	sstat = oesgexp(src, &exptime);
	if (sstat==0) ffpkyg(dst,"EXPTIME",exptime,2,"EXPOSURE IN SECONDS",&hdr->status);
	sstat = oesgtem(src, &ccdtemp);
	if (sstat==0) ffpkyg(dst,"CCD-TEMP",ccdtemp,1,"TEMPERATURE IN DEGREES C",&hdr->status);

	return (hdr->status!=0 ? CMPACK_ERR_WRITE_ERROR : 0);
}

/* Sequential read of parameters */
int oes_gkyn(tHandle handle, int nkey, char **key, char **val, char **com)
{
	return oesgkyn((oesfile*)handle, nkey, key, val, com);
}

/* Get image data */
int oes_getimage(tHandle handle, void *buf, int bufsize, CmpackChannel channel)
{
	return oesgimg((oesfile*)handle, (uint16_t*)buf, bufsize/sizeof(int16_t));
}

/* Get image data type */
CmpackBitpix oes_getbitpix(tHandle handle)
{
	return CMPACK_BITPIX_USHORT;
}

/* Get image data range */
int oes_getrange(tHandle handle, double *minvalue, double *maxvalue)
{
	if (minvalue)
		*minvalue = 0.0;
	if (maxvalue)
		*maxvalue = 0.0;
	return 0;
}
