/*
 ----------------------------------------------------------------------------
 |    Copyright (C) 1999   Emergent IT Inc. and Raytheon Systems Company    |
 ----------------------------------------------------------------------------
*/
  
#include  <HE5_HdfEosDef.h> 

#define  XDIM1  50
#define  XDIM2  70
#define  XDIM3  90

#define  YDIM1  2000
#define  YDIM2  2250
#define  YDIM3  2360


int main()
{
  herr_t        status = FAIL;
  
  int           i, j;
  int           rank = 1;  
  int           *rank_out;
  int           comp_level[5] = { 0,0,0,0,0 };
  int           comp_code;
  int           level[ 5 ] = { 0, 0, 0, 0, 0 };
  int           code  = 0;

  unsigned int  fill_value_1 = 1313,    fill_out_1 = 0;
  float         fill_value_2 = -1.1111, fill_out_2 = -1.;
  double        fill_value_3 = -3.3333, fill_out_3 = -1.;

  long          nprof     = FAIL;

  H5T_class_t   aclass     = H5T_NO_CLASS;
  H5T_class_t   *class_out;
  H5T_order_t   order     = H5T_ORDER_ERROR;
  hid_t         *numtype;

  hid_t         swfid     = FAIL;
  hid_t         SWid      = FAIL;
  hid_t         ntype     = FAIL;

  hssize_t      start[1];

  hsize_t       stride[1], edge[1];
  hsize_t       dims[1]        = {XDIM1};  
  hsize_t       dims_out[XDIM1]    ={0,0,0,0};
  hsize_t       maxdims_out[XDIM1] ={0,0,0,0};
  hsize_t       chunk_dims[ 1 ];

  size_t        datasize;

  hvl_t         buffer1[XDIM1];
  hvl_t         buffer2[XDIM2];
  hvl_t         buffer3[XDIM3];
  hvl_t         buffer_out[XDIM1];

  char          profnames[HE5_HDFE_NAMBUFSIZE];
  char          dimlist[HE5_HDFE_NAMBUFSIZE];
  char          maxdimlist[HE5_HDFE_NAMBUFSIZE];


  swfid = HE5_SWopen("SimpleProfile.he5", H5F_ACC_TRUNC);
  printf("file ID  ===> %d \n", swfid);
  
  SWid = HE5_SWcreate(swfid, "TestSwath_1");
  printf("Swath ID ===> %d \n", SWid);

  status = HE5_SWdefdim(SWid, "Unlim", H5S_UNLIMITED);
  printf("status ===> %d\n", status);

  status = HE5_SWdefdim(SWid, "ProfDimOne", 50);
  printf("status ===> %d\n", status);

  status = HE5_SWdefdim(SWid, "ProfDimTwo", 70);
  printf("status ===> %d\n", status);

  status = HE5_SWdefdim(SWid, "ProfDimThree", 90);
  printf("status ===> %d\n", status);
		  
  /* Populate data buffer 1 */
  /* ---------------------- */
  datasize = 0;
  for (i = 0; i < XDIM1; i++)
	{
	  buffer1[i].p = (hvl_t *)malloc( YDIM1 * sizeof(unsigned int));
	  buffer1[i].len  = YDIM1;
	  datasize += (buffer1[i].len * sizeof(unsigned int));
	  for ( j = 0; j < YDIM1; j++)
		((unsigned int *)buffer1[i].p)[j] = i;
	}  
  
  chunk_dims[ 0 ] = 10;
  
  /* 
   *****************************************************************************
   *                     Define Compression/chunking                           *
   *****************************************************************************
   */
  
  comp_code = 4;
  /*
   *---------------------------------------------------------------------------
   *        the compression schemes (comp_code) currently supported are       *
   *                                                                          *
   *                    HE5_HDFE_COMP_NONE     0                              *
   *                    HE5_HDFE_COMP_RLE      1                              *
   *                    HE5_HDFE_COMP_NBIT     2                              *
   *                    HE5_HDFE_COMP_SKPHUFF  3                              *
   *                    HE5_HDFE_COMP_DEFLATE  4                              *
   *                    HE5_HDFE_COMP_SZIP_CHIP  5                            *
   *                    HE5_HDFE_COMP_SZIP_K13   6                            *
   *                    HE5_HDFE_COMP_SZIP_EC    7                            *
   *                    HE5_HDFE_COMP_SZIP_NN    8                            *
   *                    HE5_HDFE_COMP_SZIP_K13orEC   9                        *
   *                    HE5_HDFE_COMP_SZIP_K13orNN   10                       *
   *                    HE5_HDFE_COMP_SHUF_DEFLATE   11                       *
   *                    HE5_HDFE_COMP_SHUF_SZIP_CHIP 12                       *
   *                    HE5_HDFE_COMP_SHUF_SZIP_K13  13                       *
   *                    HE5_HDFE_COMP_SHUF_SZIP_EC   14                       *
   *                    HE5_HDFE_COMP_SHUF_SZIP_NN   15                       *
   *                    HE5_HDFE_COMP_SHUF_SZIP_K13orEC  16                   *
   *                    HE5_HDFE_COMP_SHUF_SZIP_K13orNN  17                   *
   *                                                                          *
   *---------------------------------------------------------------------------
   */   
  
  comp_level[0] = 6;
  
  status = HE5_SWdefcomchunk(SWid, comp_code, comp_level, rank, chunk_dims);
  printf("status ===> %d\n", status);

  /* Define profile structure "Profile_1" */
  /* ------------------------------------ */
  status = HE5_PRdefine(SWid, "Profile_1", "ProfDimOne","Unlim", H5T_NATIVE_UINT);
  printf("status ===> %d \n", status);

  
  /* Set fill value */
  /* -------------- */
  status = HE5_SWsetfillvalue(SWid,"Profile_1", H5T_NATIVE_UINT, &fill_value_1);
  printf("status ===> %d \n", status);


  /* Write data to profile */
  /* --------------------- */
  start[0] = 0;
  edge[0]  = 50;
  status   = HE5_PRwrite(SWid, "Profile_1", start, NULL, edge, datasize, buffer1);
  printf("status ===> %d \n", status);


  /* Read data from profile to "buffer_out" */
  /* -------------------------------------- */
  start[0] = 0;
  edge[0]  = 50;
  status   = HE5_PRread(SWid, "Profile_1", start, NULL, edge, buffer_out);
  printf("status ===> %d \n", status);
  
  /* Display some elements of profile data */
  /* ------------------------------------- */
  for (i = 0; i < 10; i++)
	{
	  printf("\tThe %d-th element length is %d \n", i, (unsigned int)buffer_out[i].len);
	  for (j = buffer_out[i].len-10; j < buffer_out[i].len; j++)
		printf("\t\t %d \n", ((unsigned int *)buffer_out[i].p)[j]);
	}

  /* Free up memory */
  /* -------------- */
  status = HE5_PRreclaimspace(SWid, "Profile_1", buffer_out);		  
  printf("status ===> %d \n", status);


  /* Populate data buffer 2 */
  /* ---------------------- */
  datasize = 0;
  for (i = 0; i < XDIM2; i++)
	{
	  buffer2[i].p = (hvl_t *)malloc( YDIM2 * sizeof(float));
	  buffer2[i].len  =  YDIM2; 
	  datasize += (YDIM2 * sizeof(float));
	  for ( j = 0; j < YDIM2; j++)
		((unsigned int *)buffer2[i].p)[j] = 2.325 * i + 0.01 * j;
	}

  /* Define profile structure "Profile_2" */
  /* ------------------------------------ */
  status = HE5_PRdefine(SWid, "Profile_2", "ProfDimTwo", NULL, H5T_NATIVE_FLOAT);
  printf("status ===> %d \n", status);

  /* Set fill value */
  /* -------------- */
   status = HE5_SWsetfillvalue(SWid,"Profile_2", H5T_NATIVE_FLOAT, &fill_value_2);
   printf("status ===> %d \n", status);

  
  /* Write data to profile */
  /* --------------------- */
  start[0] = 0;
  edge[0]  = 70;
  status = HE5_PRwrite(SWid, "Profile_2", start, NULL, edge, datasize, buffer2);
  printf("status ===> %d \n", status);

  datasize = 0;
  for (i = 0; i < XDIM3; i++)
	{
	  buffer3[i].p = (hvl_t *)malloc( YDIM3 * sizeof(double));
	  buffer3[i].len  =  YDIM3;
	  datasize += (buffer3[i].len * sizeof(double));
	  for ( j = 0; j < YDIM3; j++)
		((unsigned int *)buffer3[i].p)[j] = (j+1)/1.e5;
	}

  /* Define profile structure "Profile_3" */
  /* ------------------------------------ */
  status = HE5_PRdefine(SWid, "Profile_3", "ProfDimThree", NULL, H5T_NATIVE_DOUBLE);
  printf("status ===> %d \n", status);
  
  /* Set fill value */
  /* -------------- */ 
   status = HE5_SWsetfillvalue(SWid,"Profile_3", H5T_NATIVE_DOUBLE, &fill_value_3);
   printf("status ===> %d \n", status);

  /* Write data to profile */
  /* --------------------- */
  start[0] = 0;
  edge[0]  = 90;
  status = HE5_PRwrite(SWid, "Profile_3", start, NULL, edge, datasize, buffer3);
  printf("status ===> %d \n", status);


  /* Detach from a swath */
  /* ------------------- */
  status = HE5_SWdetach(SWid);
  printf("status ===> %d \n", status);
 
  /* Reaattach to the swath */
  /* ---------------------- */
  SWid = HE5_SWattach(swfid, "TestSwath_1"); 
  printf("Swath ID ===> %d \n", SWid);

  /* Inquire about profile structures in a swath */
  /* ------------------------------------------- */
  nprof = HE5_PRinquire(SWid, profnames, NULL, NULL);
  printf("There are %li profiles in swath. \n",  nprof);
  if(nprof > 0)
	{
	  rank_out  = (int *)calloc(nprof, sizeof(int));
	  class_out = (H5T_class_t *)calloc(nprof, sizeof(H5T_class_t));	  
	  nprof = HE5_PRinquire(SWid, profnames, rank_out, class_out);
	  printf("Profile names: \"%s\" \n",  profnames);
	  for (i = 0; i < nprof; i++)
		printf("profile #%d   rank: %d   base class: %d\n",  i+1, rank_out[i], class_out[i]);
	  free(rank_out);
	  free(class_out);
	}

  rank_out  = (int *)calloc(1, sizeof(int));
  numtype = (hid_t *)calloc(1, sizeof(hid_t));

  /* Get information about specified profile */
  /* --------------------------------------- */
  status = HE5_PRinfo(SWid, "Profile_1", rank_out, dims_out, maxdims_out, numtype, NULL, NULL);
  if (status == SUCCEED)
	{
	  printf("Profile_1:\n");
	  printf("rank: %d   number type: %d \n", rank_out[0], numtype[0]);
	  for (i = 0; i < rank_out[0]; i++)
		printf("dimension #%d   size: %d   maximum size: %d\n",  i+1, (int)dims_out[i], (int)maxdims_out[i]);
	}

  status = HE5_PRinfo(SWid, "Profile_1", rank_out, dims_out, maxdims_out, numtype, dimlist, maxdimlist);
  if (status == SUCCEED)
	{
	  printf("Profile_1:\n");
	  printf("DimList: %s   MaxDimList: %s \n", dimlist, maxdimlist);
	}

  status = HE5_PRinfo(SWid, "Profile_2", rank_out, dims_out, maxdims_out, numtype, NULL, NULL);
  if (status == SUCCEED)
	{
	  printf("Profile_2:\n");
	  printf("rank: %d   number type: %d \n", rank_out[0], numtype[0]);
	  for (i = 0; i < rank_out[0]; i++)
		printf("dimension #%d   size: %d   maximum size: %d\n",  i+1, (int)dims_out[i], (int)maxdims_out[i]);
	}
  
  strcpy(dimlist,"");
  strcpy(maxdimlist,"");
  status = HE5_PRinfo(SWid, "Profile_2", rank_out, dims_out, maxdims_out, numtype, dimlist, maxdimlist);
  if (status == SUCCEED)
	{
	  printf("Profile_2:\n");
	  printf("DimList: %s   MaxDimList: %s \n", dimlist, maxdimlist);
	}

  status = HE5_PRinfo(SWid, "Profile_3", rank_out, dims_out, maxdims_out, numtype, NULL, NULL);
  if (status == SUCCEED)
	{
	  printf("Profile_3:\n");
	  printf("rank: %d   number type: %d \n", rank_out[0], numtype[0]);
	  for (i = 0; i < rank_out[0]; i++)
		printf("dimension #%d   size: %d   maximum size: %d\n",  i+1, (int)dims_out[i], (int)maxdims_out[i]);
	}

  strcpy(dimlist,"");
  strcpy(maxdimlist,"");
  status = HE5_PRinfo(SWid, "Profile_3", rank_out, dims_out, maxdims_out, numtype, dimlist, maxdimlist);
  if (status == SUCCEED)
	{
	  printf("Profile_3:\n");
	  printf("DimList: %s   MaxDimList: %s \n", dimlist, maxdimlist);
	}


  free(rank_out);
  free(numtype);

  /* Inquire profile data type information */
  /* ------------------------------------- */
  status = HE5_SWinqdatatype(SWid, "Profile_1", NULL, HE5_HDFE_PROFGROUP, &ntype, &aclass, &order, &datasize);
  if (status == SUCCEED)
	printf("Profile_1: class: %d  order: %d   size: %d (bytes) \n", aclass, order, (int)datasize);

  status = HE5_SWinqdatatype(SWid, "Profile_2", NULL, HE5_HDFE_PROFGROUP, &ntype, &aclass, &order, &datasize);
  if (status == SUCCEED)
	printf("Profile_2: class: %d  order: %d   size: %d (bytes) \n", aclass, order, (int)datasize);

  status = HE5_SWinqdatatype(SWid, "Profile_3", NULL, HE5_HDFE_PROFGROUP, &ntype, &aclass, &order, &datasize);
  if (status == SUCCEED)
	printf("Profile_3: class: %d  order: %d   size: %d (bytes) \n", aclass, order, (int)datasize);

  /* Retrieve fill values for profiles */
  /* --------------------------------- */
  status = HE5_SWgetfillvalue(SWid, "Profile_1", &fill_out_1);
  if (status == SUCCEED)
	printf("Profile_1: fill value = %d \n", fill_out_1);  

  status = HE5_SWgetfillvalue(SWid, "Profile_2", &fill_out_2);
  if (status == SUCCEED)
	printf("Profile_2: fill value = %f \n", fill_out_2);  

  status = HE5_SWgetfillvalue(SWid, "Profile_3", &fill_out_3);
  if (status == SUCCEED)
	printf("Profile_3: fill value = %f \n", fill_out_3);  

  status = HE5_SWcompinfo(SWid,"Profile_1",&code,level); 
  if (status == SUCCEED)
	printf("Profile_1: COMPRESSION: code = %d  level = %d \n", code, level[0]);

  code     = FAIL;
  level[0] = FAIL;
  status = HE5_SWcompinfo(SWid,"Profile_2",&code,level); 
  if (status == SUCCEED)
	printf("Profile_2: COMPRESSION: code = %d  level = %d \n", code, level[0]);

  code     = FAIL;
  level[0] = FAIL;
  status = HE5_SWcompinfo(SWid,"Profile_3",&code,level); 
  if (status == SUCCEED)
	printf("Profile_3: COMPRESSION: code = %d  level = %d \n", code, level[0]);  

  /* Detach from swath */
  /* ----------------- */
  status = HE5_SWdetach(SWid);
  printf("status ===> %d \n", status);

  /* Close HDF-EOS file */
  /* ------------------ */
  status = HE5_SWclose(swfid);
  printf("status ===> %d \n", status);
  
  return 0;
}























