// Copyright (c) Lawrence Livermore National Security, LLC and other VisIt
// Project developers.  See the top-level LICENSE file for dates and other
// details.  No copyright assignment is required to contribute to VisIt.

// ************************************************************************* //
//                            avtM3DC1FileFormat.h                           //
// ************************************************************************* //

#ifndef AVT_M3DC1_FILE_FORMAT_H
#define AVT_M3DC1_FILE_FORMAT_H

#include <avtMTSDFileFormat.h>

#include <vtk_hdf5.h>

#include <vector>

class DBOptionsAttributes;
class vtkPoints;

// ****************************************************************************
//  Class: avtM3DC1FileFormat
//
//  Purpose:
//      Reads in M3DC1 files as a plugin to VisIt.
//
//  Programmer: allen -- generated by xml2avt
//  Creation:   Fri Dec 4 15:04:15 PST 2009
//
// ****************************************************************************

class avtM3DC1FileFormat : public avtMTSDFileFormat
{
  public:
                       avtM3DC1FileFormat(const char *, DBOptionsAttributes *);
    virtual           ~avtM3DC1FileFormat() {;};

    //
    // This is used to return unconvention data -- ranging from material
    // information to information about block connectivity.
    //
    // virtual void      *GetAuxiliaryData(const char *var, int timestep, 
    //                                     const char *type, void *args, 
    //                                     DestructorFunction &);
    //

    //
    // If you know the times and cycle numbers, overload this function.
    // Otherwise, VisIt will make up some reasonable ones for you.
    //
    virtual void        GetCycles(std::vector<int> &);
    virtual void        GetTimes(std::vector<double> &);

    virtual int            GetNTimesteps(void);

    virtual const char    *GetType(void)   { return "M3DC1"; };
    virtual void           FreeUpResources(void); 

    virtual bool CanCacheVariable(const char *var);
    virtual void RegisterDataSelections(const std::vector<avtDataSelection_p> &sels,
                                        std::vector<bool> *selectionsApplied);

    virtual bool ProcessDataSelections(int *mins, int *maxs, int *strides);

    virtual vtkDataSet    *GetMesh(int, const char *);
    virtual vtkDataArray  *GetVar(int, const char *);
    virtual vtkDataArray  *GetVectorVar(int, const char *);

  protected:
    vtkDataArray  *GetHeaderVar(int, const char *);
    vtkDataArray  *GetFieldVar(int, const char *);

    vtkPoints *GetMeshPoints(float *elements,
                             int refinementLevel);

    float * GetElements(int timestate, const char *meshname);

    void LoadFile();

    //HDF5 helper functions.
    bool ReadAttribute( hid_t parentID, const char *attr, void *value );
    bool ReadStringAttribute( hid_t parentID, const char *attr, std::string *value );
    hid_t NormalizeH5Type( hid_t type );

    // Some stuff to keep track of data selections
    std::vector<avtDataSelection_p> selList;
    std::vector<bool>              *selsApplied;

    bool processDataSelections;
    bool haveReadWholeData;

    // DATA MEMBERS
    hid_t m_fileID;
    std::string m_filename;
    int m_refinement;
    avtCentering m_dataLocation;

    std::vector<int>    m_cycles;
    std::vector<double> m_times;

public:
    std::vector<std::string> m_scalarVarNames;
    std::vector<std::string> m_fieldVarNames;

    // Variables read from mesh and field attributes.
    int nelms;
    int nvertices;
    int nplanes;

    int element_dimension;
    unsigned int element_size;
    unsigned int scalar_size;
    
  protected:

    virtual void PopulateDatabaseMetaData(avtDatabaseMetaData *, int);

    static herr_t linkIterator(hid_t, const char *, const H5L_info_t *, void *);
    static herr_t groupIterator(hid_t, const char *, void *);

};
#endif
