# include "psastroInternal.h"

# if (HAVE_KAPA)
# include <kapa.h>

bool psastroPlotRawstars (psArray *rawstars, pmFPA *fpa, pmChip *chip)
{
    Graphdata graphdata;
    KapaSection section;

    int kapa = pmKapaOpen (true);
    if (kapa == -1) {
        psError(PS_ERR_UNKNOWN, true, "failure to open kapa");
        return false;
    }

    KapaResize (kapa, 1000, 1000);
    KapaInitGraph (&graphdata);
    KapaClearPlots (kapa);

    graphdata.color = KapaColorByName ("black");
    graphdata.ptype = 7;
    graphdata.size = 0.5;
    graphdata.style = 2;

    section.dx = 0.5;
    section.dy = 0.5;

    psVector *xVec = psVectorAlloc (rawstars->n, PS_TYPE_F32);
    psVector *yVec = psVectorAlloc (rawstars->n, PS_TYPE_F32);
    psVector *zVec = psVectorAlloc (rawstars->n, PS_TYPE_F32);

    section.x = 0.0;
    section.y = 0.5;
    section.name = NULL;
    psStringAppend (&section.name, "a0");
    KapaSetSection (kapa, &section);
    psFree (section.name);

    int n = 0;
    for (int i = 0; i < rawstars->n; i++) {
	pmAstromObj *raw = rawstars->data[i];
	if (!isfinite(raw->Mag)) continue;
	xVec->data.F32[n] = raw->chip->x;
	yVec->data.F32[n] = raw->chip->y;
	zVec->data.F32[n] = raw->Mag;
	n++;
    }
    xVec->n = yVec->n = zVec->n = n;
    pmKapaPlotVectorTriple_AutoLimits_OpenGraph (kapa, &graphdata, xVec, yVec, zVec, false);

    section.x = 0.5;
    section.y = 0.5;
    section.name = NULL;
    psStringAppend (&section.name, "a1");
    KapaSetSection (kapa, &section);
    psFree (section.name);

    n = 0;
    for (int i = 0; i < rawstars->n; i++) {
	pmAstromObj *raw = rawstars->data[i];
	if (!isfinite(raw->Mag)) continue;
	xVec->data.F32[n] = raw->FP->x;
	yVec->data.F32[n] = raw->FP->y;
	zVec->data.F32[n] = raw->Mag;
	n++;
    }
    xVec->n = yVec->n = zVec->n = n;
    pmKapaPlotVectorTriple_AutoLimits_OpenGraph (kapa, &graphdata, xVec, yVec, zVec, false);

    section.x = 0.0;
    section.y = 0.0;
    section.name = NULL;
    psStringAppend (&section.name, "a2");
    KapaSetSection (kapa, &section);
    psFree (section.name);

    n = 0;
    for (int i = 0; i < rawstars->n; i++) {
	pmAstromObj *raw = rawstars->data[i];
	if (!isfinite(raw->Mag)) continue;
	xVec->data.F32[n] = raw->TP->x;
	yVec->data.F32[n] = raw->TP->y;
	zVec->data.F32[n] = raw->Mag;
	n++;
    }
    xVec->n = yVec->n = zVec->n = n;
    pmKapaPlotVectorTriple_AutoLimits_OpenGraph (kapa, &graphdata, xVec, yVec, zVec, false);

    section.x = 0.5;
    section.y = 0.0;
    section.name = NULL;
    psStringAppend (&section.name, "a3");
    KapaSetSection (kapa, &section);
    psFree (section.name);

    n = 0;
    for (int i = 0; i < rawstars->n; i++) {
	pmAstromObj *raw = rawstars->data[i];
	if (!isfinite(raw->Mag)) continue;
	xVec->data.F32[n] = raw->sky->r;
	yVec->data.F32[n] = raw->sky->d;
	zVec->data.F32[n] = raw->Mag;
	n++;
    }
    xVec->n = yVec->n = zVec->n = n;
    pmKapaPlotVectorTriple_AutoLimits_OpenGraph (kapa, &graphdata, xVec, yVec, zVec, false);

    // pause and wait for user input: 
    // continue, save (provide name), ??
    char key[10], name[80];
    fprintf (stdout, "(s)ave plot or [c]ontinue? ");
    fscanf (stdin, "%s", key);
    fprintf (stderr, "got: %s\n", key);
    if (key[0] == 's') {
	fprintf (stdout, "enter plot name [rawstars.png]: ");
	fscanf (stdin, "%s", name);
	if (!strcmp (name, "")) strcpy (name, "rawstars.png");
	KapaPNG (kapa, name);
    }

    psFree (xVec);
    psFree (yVec);
    psFree (zVec);
    return true;
}

bool psastroPlotRefstars (psArray *refstars)
{
    Graphdata graphdata;

    int kapa = pmKapaOpen (true);
    if (kapa == -1) {
        psError(PS_ERR_UNKNOWN, true, "failure to open kapa");
        return false;
    }

    KapaResize (kapa, 1000, 1000);
    KapaInitGraph (&graphdata);
    KapaClearPlots (kapa);

    graphdata.color = KapaColorByName ("black");
    graphdata.ptype = 7;
    graphdata.size = 0.5;
    graphdata.style = 2;

    psVector *xVec = psVectorAlloc (refstars->n, PS_TYPE_F32);
    psVector *yVec = psVectorAlloc (refstars->n, PS_TYPE_F32);
    psVector *zVec = psVectorAlloc (refstars->n, PS_TYPE_F32);

    int n = 0;
    for (int i = 0; i < refstars->n; i++) {
	pmAstromObj *ref = refstars->data[i];
	if (!isfinite(ref->Mag)) continue;
	xVec->data.F32[n] = ref->sky->r;
	yVec->data.F32[n] = ref->sky->d;
	zVec->data.F32[n] = ref->Mag;
	n++;
    }
    xVec->n = yVec->n = zVec->n = n;
    pmKapaPlotVectorTriple_AutoLimits_OpenGraph (kapa, &graphdata, xVec, yVec, zVec, false);

    // pause and wait for user input: 
    // continue, save (provide name), ??
    char key[10], name[80];
    fprintf (stdout, "(s)ave plot or [c]ontinue? ");
    fscanf (stdin, "%s", key);
    fprintf (stderr, "got: %s\n", key);
    if (key[0] == 's') {
	fprintf (stdout, "enter plot name [refstars.png]: ");
	fscanf (stdin, "%s", name);
	if (!strcmp (name, "")) strcpy (name, "refstars.png");
	KapaPNG (kapa, name);
    }

    psFree (xVec);
    psFree (yVec);
    psFree (zVec);
    return true;
}

bool psastroPlotOneChipFit (psArray *rawstars, psArray *refstars, psArray *match, pmAstromFitResults *results) {

    Graphdata graphdata;
    KapaSection section;

    int kapa = pmKapaOpen (true);
    if (kapa == -1) {
        psError(PS_ERR_UNKNOWN, true, "failure to open kapa");
        return false;
    }

    KapaResize (kapa, 1000, 1000);
    KapaInitGraph (&graphdata);
    KapaClearPlots (kapa);

    graphdata.color = KapaColorByName ("black");
    graphdata.ptype = 7;
    graphdata.size = 0.5;
    graphdata.style = 2;

    section.dx = 0.5;
    section.dy = 0.5;

    psVector *xVec = psVectorAlloc (match->n, PS_TYPE_F32);
    psVector *yVec = psVectorAlloc (match->n, PS_TYPE_F32);
    psVector *zVec = psVectorAlloc (match->n, PS_TYPE_F32);

    // X vs dX
    section.x = 0.0;
    section.y = 0.5;
    section.name = NULL;
    psStringAppend (&section.name, "a0");
    KapaSetSection (kapa, &section);
    psFree (section.name);

    int n = 0;
    for (int i = 0; i < match->n; i++) {
        pmAstromMatch *pair = match->data[i];
        pmAstromObj *raw = rawstars->data[pair->raw];
        pmAstromObj *ref = refstars->data[pair->ref];
	
	xVec->data.F32[n] = raw->chip->x;
	yVec->data.F32[n] = raw->chip->x - ref->chip->x;
	zVec->data.F32[n] = raw->Mag;
	n++;
    }	
    xVec->n = yVec->n = zVec->n = n;
    pmKapaPlotVectorTriple_AutoLimits_OpenGraph (kapa, &graphdata, xVec, yVec, zVec, false);

    // X vs dY
    section.x = 0.5;
    section.y = 0.5;
    section.name = NULL;
    psStringAppend (&section.name, "a1");
    KapaSetSection (kapa, &section);
    psFree (section.name);

    n = 0;
    for (int i = 0; i < match->n; i++) {
        pmAstromMatch *pair = match->data[i];
        pmAstromObj *raw = rawstars->data[pair->raw];
        pmAstromObj *ref = refstars->data[pair->ref];
	
	if (!isfinite(raw->Mag)) continue;
	xVec->data.F32[n] = raw->chip->x;
	yVec->data.F32[n] = raw->chip->y - ref->chip->y;
	zVec->data.F32[n] = raw->Mag;
	n++;
    }	
    xVec->n = yVec->n = zVec->n = n;
    pmKapaPlotVectorTriple_AutoLimits_OpenGraph (kapa, &graphdata, xVec, yVec, zVec, false);

    // Y vs dX
    section.x = 0.0;
    section.y = 0.0;
    section.name = NULL;
    psStringAppend (&section.name, "a2");
    KapaSetSection (kapa, &section);
    psFree (section.name);

    n = 0;
    for (int i = 0; i < match->n; i++) {
        pmAstromMatch *pair = match->data[i];
        pmAstromObj *raw = rawstars->data[pair->raw];
        pmAstromObj *ref = refstars->data[pair->ref];
	
	if (!isfinite(raw->Mag)) continue;
	xVec->data.F32[n] = raw->chip->y;
	yVec->data.F32[n] = raw->chip->x - ref->chip->x;
	zVec->data.F32[n] = raw->Mag;
	n++;
    }	
    xVec->n = yVec->n = zVec->n = n;
    pmKapaPlotVectorTriple_AutoLimits_OpenGraph (kapa, &graphdata, xVec, yVec, zVec, false);

    // Y vs dY
    section.x = 0.5;
    section.y = 0.0;
    section.name = NULL;
    psStringAppend (&section.name, "a3");
    KapaSetSection (kapa, &section);
    psFree (section.name);

    n = 0;
    for (int i = 0; i < match->n; i++) {
        pmAstromMatch *pair = match->data[i];
        pmAstromObj *raw = rawstars->data[pair->raw];
        pmAstromObj *ref = refstars->data[pair->ref];
	
	if (!isfinite(raw->Mag)) continue;
	xVec->data.F32[n] = raw->chip->y;
	yVec->data.F32[n] = raw->chip->y - ref->chip->y;
	zVec->data.F32[n] = raw->Mag;
	n++;
    }	
    xVec->n = yVec->n = zVec->n = n;
    pmKapaPlotVectorTriple_AutoLimits_OpenGraph (kapa, &graphdata, xVec, yVec, zVec, false);

    // pause and wait for user input: 
    // continue, save (provide name), ??
    char key[10], name[80];
    fprintf (stdout, "(s)ave plot or [c]ontinue? ");
    fscanf (stdin, "%s", key);
    fprintf (stderr, "got: %s\n", key);
    if (key[0] == 's') {
	fprintf (stdout, "enter plot name [chipfit.png]: ");
	fscanf (stdin, "%s", name);
	if (!strcmp (name, "")) strcpy (name, "chipfit.png");
	KapaPNG (kapa, name);
    }

    psFree (xVec);
    psFree (yVec);
    psFree (zVec);
    return true;
}

# else

bool psastroPlotRawstars (psArray *rawstars, pmFPA *fpa, pmChip *chip)
{
    return false;
}

bool psastroPlotRefstars (psArray *refstars)
{
    return false;
}

bool psastroPlotOneChipFit (psArray *rawstars, psArray *refstars, psArray *match, pmAstromFitResults *results)
{
    return false;
}

# endif
