/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Copyright by  The HDF Group and                                           *
 * The Board of Trustees of the University of Illinois.                      *
 * All rights reserved.                                                      *
 *                                                                           *
 * This file is part of H4H5TOOLS. The full H4H5TOOLS copyright notice,      *
 * including terms governing use, modification, and redistribution, is       *
 * contained in the COPYING file, which can be found at the root of the      *
 * source code distribution tree. The copyright notice can also be found     *
 * at https://www.hdfgroup.org/licenses.  If you do not have access to       *
 * either file, you may request a copy from help@hdfgroup.org.               *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include "h4toh5.h"

/* There are 12 test cases for h4toh5 library.*/
/* h4h5apitestdefault,
     h4h5apitestname,
     h4h5apitestimage,
     h4h5apitestimageattr,
     h4h5apitestsds,
     h4h5apitestsdsattr,
     h4h5apitestvdata,
     h4h5apitestvdataattr,
     h4h5apitestadvgroup,
     h4h5apitestbasvgroup,
     h4h5apitestloneimage,
     h4h5apitestlonesds,
     h4h5apitestlonevdata
     
     This file is h4h5apitestname.c.
     1) will test the option with user-specified for h4toh5 library APIs.
*/

/*-------------------------------------------------------------------------
 * Function:    main
 *
 * Purpose:      
             
 *-------------------------------------------------------------------------
 */      
int main() {

    hid_t                   h4toh5id; /* h4toh5 id*/
    int32                   file_id; /* HDF4 file id*/
    int32                   sd_id; /* HDF4 SD interface id*/
    int32                   gr_id; /* HDF4 GR interface id*/
    int32                   sds_id; /* HDF4 SDS id */
    int32                   image_id; /* HDF4 image id */
    int32                   vgroup_id; /* HDF4 vgroup id */
    int32                   vdata_id; /* HDF4 vdata id */
    int32                   vdata_ref; /* HDF4 vdata reference number*/
    int32                   vgroup_ref; /* HDF4 vgroup reference number*/
    int32                   anno_objref; /*HDF4 object reference number that has annotation                                                             to convert*/
    int32                   anno_objtag; /*HDF4 object tag that has annotation to convert */
    int32                   status;  /*temporary variable to check status of HDF4 APIs */
    int                     h4toh5status;  /*temporary variable to check status of H4toH5 APIs */

    /** open H interface **/
    file_id = Hopen("vg_all_testname.hdf",DFACC_READ,0);
    if(file_id == FAIL) {
        printf("cannot open H interface.\n");
        return FAIL;
    }

    /** open SD interface **/
    sd_id       = SDstart("vg_all_testname.hdf",DFACC_READ);
    if(sd_id == FAIL) {
        printf("cannot start SD interface.\n");
        Hclose(file_id);
        return FAIL;
    }

    /** open GR  interface**/
    gr_id       = GRstart(file_id);
    if(gr_id == FAIL) {     
        printf("cannot obtain gr id.\n");
        SDend(sd_id);
        Hclose(file_id);
        return FAIL;
    }

    /** open V interface **/
    status  = Vstart(file_id);
    if(status == FAIL) {
        printf("cannot start V interface.\n");
        SDend(sd_id);
        GRend(gr_id);
        Hclose(file_id);
        return FAIL;
    }

    if((h4toh5id= H4toH5open("vg_all_testname.hdf","vg_all_testname.h5",H425_CLOBBER)) < 0) {
        printf("cannot start H4toH5 interface\n");
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        return FAIL;
    }

    /* category I. test all API with the default name. */

    /* 1. testing SDS API; choose the SDS object with index 0;
         all attributes and dimensional scales of this SDS will
         be converted. */
    sds_id = SDselect(sd_id,0);
    if(sds_id == FAIL) {
        printf("cannot obtain SDS id.\n");
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    if(H4toH5sds(h4toh5id,sds_id,"/group1u","mysds","/mydimgroup",1,1)<0) {
        printf("SDS conversion test fails\n");
        H4toH5error_get(h4toh5id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /* 2. testing image conversions */
    /* obtain a gr id. */
    image_id = GRselect(gr_id,0);
    if(image_id == FAIL) {
        printf(" cannot obtain image id.\n");
        SDendaccess(sds_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    if(H4toH5image(h4toh5id,image_id,"/group1u","myimage","/mypalgroup","mypal",1,1)<0){
        printf("image conversion test fails\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /* 3. testing independent vdata conversion API.
         Since Vdata may be attributes, in order to avoid converting attributes;
         we use hdp to find the reference number of an independent vdata in this 
         file and obtain vdata id later. */
     
    vdata_ref = 9;
    vdata_id = VSattach(file_id,vdata_ref,"r");
 
    if(vdata_id == FAIL) {
        printf("cannot obtain Vdata id. \n");
        SDendaccess(sds_id);
        GRendaccess(image_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /* convert vdata. */
    if(H4toH5vdata(h4toh5id,vdata_id,"/group1u","myvdata",1)<0) {
        printf("vdata conversion test fails\n");
        H4toH5error_get(h4toh5id);
        VSdetach(vdata_id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }
    /* 4. testing partial vgroup API. 
         vgroup itself and vgroup with non-vgroup members will be converted. */

    /* obtaining a vgroup id. */
    vgroup_ref = Vgetid(file_id,-1);
    if(vgroup_ref == FAIL){
        printf("cannot obtain vgroup reference number.\n");
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    vgroup_id = Vattach(file_id,vgroup_ref,"r");
    if(vgroup_id == FAIL){
        printf("cannot obtain Vgroup id.\n");
         SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /* converting vgroup with an image object. */
    if(H4toH5bas_vgroup(h4toh5id,vgroup_id,"/gpartial","myvgroup",1,1)<0){
        printf("basic vgroup conversion test fails\n");
        H4toH5error_get(h4toh5id);
         SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }        
    
    
    /*5. testing the whole vgroup API. 
        Everything under this vgroup is converted.*/
    if(H4toH5adv_group(h4toh5id,vgroup_id,"/gwhole","myallvgroup",H425_OSPEC_ALLATTRS)<0){
        printf("advanced vgroup conversion test fails\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /*6. testing annotation API. */

    if(H4toH5anno_file_all_labels(h4toh5id)<0) {
        printf("File label conversion test fails\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    if(H4toH5anno_file_all_descs(h4toh5id)<0) {
        printf("File description conversion test fails\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);   
        return FAIL;
    }

    /***** object annotations testing, we have to provide the object reference
                 number and object tag that have annotations associate with it.
                 we will use hdp to check the reference of such object. In this 
                 example, vgroup is used. vgroup tag is 1965. vgroup reference is 4.
    *****/

    anno_objref = 4;
    anno_objtag = 1965;

    if(H4toH5anno_obj_label(h4toh5id,"/","/group1u",anno_objref,
             anno_objtag,NULL,0)<0){
        printf("object label conversion test fails.\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    if(H4toH5anno_obj_desc(h4toh5id,"/","/group1u",anno_objref,
            anno_objtag,NULL,0)<0){
        printf("object description conversion test fails.\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /*7. testing palette conversion.
        Note: We only tested default parameters; 
        since we already used a default palette group 
        "/HDF4_PALGROUP" when converting the image; so 
        we made another palette group for this test.*/
    if(H4toH5pal(h4toh5id,image_id,NULL,NULL,"/paltestgroup",NULL,1,0)<0){
        printf("palette conversion test fails\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /* 8. testing dimensional scale dataset API. */
    if(H4toH5all_dimscale(h4toh5id,sds_id,"/group1","sds","/dimtestgroup",1,0) <0) {
        printf("dimensional scale conversion test fails .\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }
             
    /*testing global attributes of sds and image. */
    if(H4toH5glo_sds_attr(h4toh5id,H425_OSPEC_ALLATTRS)<0) {
        printf("SD interface attribute conversion test fails\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    if(H4toH5glo_image_attr(h4toh5id,H425_OSPEC_ALLATTRS)<0) {
        printf("GR interface attribute conversion test fails\n");
        H4toH5error_get(h4toh5id);
        SDendaccess(sds_id);
        GRendaccess(image_id);
        VSdetach(vdata_id);
        Vdetach(vgroup_id);
        SDend(sd_id);
        GRend(gr_id);
        Vend(file_id);
        Hclose(file_id);
        H4toH5close(h4toh5id);
        return FAIL;
    }

    /** close all interfaces. **/
    status = VSdetach(vdata_id);
    if(status == FAIL) {
        printf("cannot detach VS interface.\n");
        SDendaccess(sds_id);
         GRendaccess(image_id);
         Vdetach(vgroup_id);
            SDend(sd_id);
         GRend(gr_id);
         Vend(file_id);
         Hclose(file_id);
         H4toH5close(h4toh5id);
            return FAIL;
    }

    status = Vdetach(vgroup_id);
    if(status == FAIL) {
        printf("cannot detach V interface. \n");
        SDendaccess(sds_id);
         GRendaccess(image_id);
            SDend(sd_id);
         GRend(gr_id);
         Vend(file_id);
         Hclose(file_id);
         H4toH5close(h4toh5id);
         return FAIL;
    }

    status = SDendaccess(sds_id);
    if(status == FAIL) {
        printf("cannot end SDS interface. \n");
         GRendaccess(image_id);
         Vdetach(vgroup_id);
            SDend(sd_id);
         GRend(gr_id);
         Vend(file_id);
         Hclose(file_id);
         H4toH5close(h4toh5id);
         return FAIL;
    }

    status = GRendaccess(image_id);
    if(status == FAIL) {
        printf("cannot end image interface. \n");
         Vdetach(vgroup_id);
            SDend(sd_id);
         GRend(gr_id);
         Vend(file_id);
         Hclose(file_id);
         H4toH5close(h4toh5id);
         return FAIL;
    }

    status = Vend(file_id);
    if(status == FAIL) {
        printf("cannot end V interface. \n");
         SDend(sd_id);
         GRend(gr_id);
         Hclose(file_id);
         H4toH5close(h4toh5id);
         return FAIL;
    }

    status = GRend(gr_id);
     if(status == FAIL) {
        printf("cannot end GR interface. \n");
            SDend(sd_id);
         Hclose(file_id);
         H4toH5close(h4toh5id);
         return FAIL;
    }

    status = SDend(sd_id);
    if(status == FAIL) {
        printf("cannot end SD interface. \n");
         Hclose(file_id);
         H4toH5close(h4toh5id);
         return FAIL;
    }

    status = Hclose(file_id);
    if(status == FAIL) {
        printf("cannot end H interface. \n");
         H4toH5close(h4toh5id);
         return FAIL;
    }

    h4toh5status = H4toH5close(h4toh5id);
    if(h4toh5status == FAIL) {
        printf("cannot close H4toH5 interface. \n");
        return FAIL;
    }
    return 0;
}







