/**
* This is module which fixes the storgae of the 2D detector at RITA. 
* I wish to store a 3D array, 2 detector coordinates against NP, the number
* of scan points. However, intermediate storage can only be as snapshots
* of 2D arrays against scan points. This has to be formatted to a proper 
* 3D data set in C storage order. This is to slow in tcl, therefore this
* has to be done in in C.
* 
* copyright: see file COPYRIGHT
* 
* Mark Koennecke, August 2006
*/
#include <sics.h>
#include <sicsdata.h>

/*---------------------------------------------------------------------------*/
static int RitaFix(SConnection * pCon, SicsInterp * pSics, void *pData,
                   int argc, char *argv[])
{
  int x, y, np, scanDim, wrongpos, goodpos, val, *iData = NULL;
  int wrongmult, wrongconst;
  pSICSData intermediate = NULL, result = NULL;
  char buffer[256];

  if (argc < 4) {
    SCWrite(pCon, "ERROR: not enough arguments to RitaFix", eError);
    return 0;
  }

  intermediate = FindCommandData(pSics, argv[1], "SICSData");
  if (intermediate == NULL) {
    snprintf(buffer, 255, "ERROR: %s is no SICSdata", argv[1]);
    SCWrite(pCon, buffer, eError);
    return 0;
  }
  result = FindCommandData(pSics, argv[2], "SICSData");
  if (result == NULL) {
    snprintf(buffer, 255, "ERROR: %s is no SICSdata", argv[2]);
    SCWrite(pCon, buffer, eError);
    return 0;
  }

  scanDim = atoi(argv[3]);
  scanDim++;
  clearSICSData(result);
  /*
   * ensure enough memory in order to avoid memory allocation in the
   * loop
   */
  iData = getSICSDataPointer(result, 0, (128 * 128 * scanDim) + 1);
  wrongpos = 128 * 128 * scanDim;
  if (intermediate->dataUsed < wrongpos || iData == NULL) {
    SCWrite(pCon, "ERROR: source data buffer to short or out of mem",
            eError);
    return 0;
  }
  wrongmult = 128 * 128;
  for (x = 0; x < 128; x++) {
    for (y = 0; y < 128; y++) {
      goodpos = x * 128 * scanDim + y * scanDim;
      wrongconst = y * 128 + x;
      for (np = 0; np < scanDim; np++, goodpos++) {
        /*
           wrongpos = 128*128*np + y*128 + x;
           goodpos = x*128*scanDim + y*scanDim + np;
         */
        wrongpos = wrongmult * np + wrongconst;
        result->data[goodpos] = intermediate->data[wrongpos];
      }
    }
  }
  SCSendOK(pCon);
  return 1;
}

/*---------------------------------------------------------------------------*/
int MakeRitaFix(SConnection * pCon, SicsInterp * pSics, void *pData,
                int argc, char *argv[])
{
  AddCommand(pSics, "ritafixstorage", RitaFix, NULL, NULL);
  return 1;
}
