/*
 */

#include "hdf5.h"

typedef struct s1 {
   int var1;
   char* var2[4];
   int var3;
} s1;
s1  st[3];


typedef struct s2 { 
   char* var2[4];
} s2;

s2 stedit[1];

int main()
{

    int i,j, len, nCount  = 3;
    hsize_t marray[]={1};
    hsize_t coord[1];
    hsize_t     dims[1], chunkDims[1], ioffset[1], icnt[1], arr_dims[]={4};
    herr_t      status, err1, err2;
    hid_t fileId, dataSetId, dataSpaceId, memSpaceId, fSpaceId, vlDataTypeId, dataTypeId, pListId;
    hid_t  array_dt;

    /* Create the file */
    fileId = H5Fcreate("cmpvsed.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    printf ("H5Fcreate returns: %i\n", fileId);

    /* Create the array datatype */

    vlDataTypeId = H5Tcopy(H5T_C_S1);
    printf ("H5Tcopy returns: %i\n", vlDataTypeId);
    status = H5Tset_size(vlDataTypeId, H5T_VARIABLE);
    printf ("H5Tset_size returns: %i\n", status);

    array_dt = H5Tarray_create (vlDataTypeId, 1, arr_dims, NULL);

    dataTypeId = H5Tcreate(H5T_COMPOUND, sizeof(s1));
    printf ("H5Tcreate returns: %i\n", dataTypeId);
    H5Tinsert(dataTypeId, "var1", HOFFSET(s1,var1), H5T_NATIVE_INT);
    H5Tinsert(dataTypeId, "var2", HOFFSET(s1,var2), array_dt);
    H5Tinsert(dataTypeId, "var3", HOFFSET(s1,var3), H5T_NATIVE_INT);

    /* Create the dataspace */
    dims[0] = nCount;
    dataSpaceId = H5Screate_simple(1, dims, NULL);
    printf ("H5Screate_simple returns: %i\n", dataSpaceId);

    /* Create the property list  */
    pListId = H5Pcreate(H5P_DATASET_CREATE);

    /* Create the dataset */
    chunkDims[0] = 1;
    status = H5Pset_chunk(pListId, 1, chunkDims);
    printf ("%i\n", status);
    dataSetId = H5Dcreate(fileId, "/String", dataTypeId, dataSpaceId, pListId);

    for (i=0; i<nCount; i++)
    {
       if (i==1) 
       {
          st[i].var1 = i+10;
          st[i].var2[0] = malloc (15 + 1);
          strcpy (st[i].var2[0], "Wake Me Up When");
          st[i].var2[1] = malloc (9 + 1);
          strcpy (st[i].var2[1], "September");
          st[i].var2[2] = malloc (4 + 1);
          strcpy (st[i].var2[2], "Ends");
          st[i].var2[3] = malloc (5 + 1);
          strcpy (st[i].var2[3], "Okay?");
	  st[i].var3 = (i+1)*10;
       }
       else
       {
          st[i].var1 = i+10;
          st[i].var2[0] = malloc (18 + 1);
          strcpy (st[i].var2[0], "Despiertame Cuando");
          st[i].var2[1] = malloc (10 + 1);
          strcpy (st[i].var2[1], "Septiembre");
          st[i].var2[2] = malloc (7 + 1);
          strcpy (st[i].var2[2], "Termina");
          st[i].var2[3] = malloc (10 + 1);
          strcpy (st[i].var2[3], "Esta Bien?");
          st[i].var3 = (i+1)*10;
       }
    }
    err2 = H5Dwrite(dataSetId, dataTypeId, H5S_ALL, H5S_ALL, H5P_DEFAULT, &st);
    printf ("H5Dwrite returns: %i\n", err2);
    
    status = H5Dvlen_reclaim (dataTypeId, dataSpaceId, H5P_DEFAULT, &st);

    /* Close everything */
    status= H5Pclose(pListId);
    printf ("%i\n", status);
    status = H5Dclose(dataSetId);
    printf ("status: %i\n", status);
    status = H5Sclose(dataSpaceId);
    printf ("status: %i\n", status);
    status = H5Tclose(vlDataTypeId);
    printf ("status: %i\n", status);
    status = H5Tclose (array_dt);
    status = H5Tclose(dataTypeId);
    printf ("status: %i\n", status);
    status = H5Fclose(fileId);    
    printf ("status: %i\n", status);

    /**************************************/ 
    /* Re-open the file and the dataset.  */
    /**************************************/ 

    fileId = H5Fopen("cmpvsed.h5", H5F_ACC_RDWR, H5P_DEFAULT);
    dataSetId = H5Dopen(fileId, "/String");

    /*********************************************/
    /* Overwrite field                           */
    /*********************************************/
    
    for (i=0; i<4; i++)
    {
        stedit[0].var2[i] = malloc (7 + 1);
        strcpy (stedit[0].var2[i], "Edited!");
    }

    vlDataTypeId = H5Tcopy(H5T_C_S1);
    printf ("H5Tcopy returns: %i\n", vlDataTypeId);
    status = H5Tset_size(vlDataTypeId, H5T_VARIABLE);
    printf ("H5Tset_size returns: %i\n", status);

    printf ("H5Tset_size returns: %i\n", status);

    array_dt = H5Tarray_create (vlDataTypeId, 1, arr_dims, NULL);

    dataTypeId = H5Tcreate(H5T_COMPOUND, sizeof(s2));
    printf ("H5Tcreate returns: %i\n", dataTypeId);
    status = H5Tinsert(dataTypeId, "var2", HOFFSET(s2,var2), array_dt);

    memSpaceId = H5Screate_simple (1, marray, NULL);
    coord[0] = 2;
    fSpaceId = H5Dget_space (dataSetId);

    status = H5Sselect_elements (fSpaceId, H5S_SELECT_SET, 
                                 1, (const hsize_t **)coord); 

    status = H5Dwrite (dataSetId, dataTypeId, memSpaceId, fSpaceId, H5P_DEFAULT, &stedit);
     
    /*********************************************/
    /* End overwrite section                     */
    /*********************************************/

    /* Release resources */

    status = H5Sclose (fSpaceId);
    status = H5Sclose (memSpaceId);
    status = H5Tclose (dataTypeId);
    status = H5Tclose (vlDataTypeId);
    status = H5Tclose (array_dt);
    status = H5Dclose (dataSetId);
    status = H5Fclose (fileId);

    return 0;
}



