/*
** (c) 1996-2000 The Regents of the University of California (through
** E.O. Lawrence Berkeley National Laboratory), subject to approval by
** the U.S. Department of Energy.  Your use of this software is under
** license -- the license agreement is attached and included in the
** directory as license.txt or you may contact Berkeley Lab's Technology
** Transfer Department at TTD@lbl.gov.  NOTICE OF U.S. GOVERNMENT RIGHTS.
** The Software was developed under funding from the U.S. Government
** which consequently retains certain rights as follows: the
** U.S. Government has been granted for itself and others acting on its
** behalf a paid-up, nonexclusive, irrevocable, worldwide license in the
** Software to reproduce, prepare derivative works, and perform publicly
** and display publicly.  Beginning five (5) years after the date
** permission to assert copyright is obtained from the U.S. Department of
** Energy, and subject to any subsequent five (5) year renewals, the
** U.S. Government is granted for itself and others acting on its behalf
** a paid-up, nonexclusive, irrevocable, worldwide license in the
** Software to reproduce, prepare derivative works, distribute copies to
** the public, perform publicly and display publicly, and to permit
** others to do so.
*/


//
// $Id: DataServices.H,v 1.19 2003/03/12 07:40:56 vince Exp $
//

// ---------------------------------------------------------------
// DataServices.H
// ---------------------------------------------------------------
#ifndef _DATASERVICES_H_
#define _DATASERVICES_H_

#include "Array.H"
#include "AmrData.H"

#include <cstdarg>
#include <string>
using std::string;

class XYPlotDataList;


class DataServices {

  public:

    enum DSRequestType {
      InvalidRequestType = 0,
      ExitRequest,
      NewRequest,
      DeleteRequest,
      FillVarOneFab,
      FillVarArrayOfFabs,
      FillVarMultiFab,
      WriteFabOneVar,
      WriteFabAllVars,
      DumpSlicePlaneOneVar,
      DumpSlicePlaneAllVars,
      DumpSliceBoxOneVar,
      DumpSliceBoxAllVars,
      MinMaxRequest,
      PointValueRequest,
#ifndef BL_NOLINEVALUES
      LineValuesRequest
#endif
    };

    DataServices(const string &filename, const FileType &filetype);
    ~DataServices();

    static void SetBatchMode();
    static void Dispatch(DSRequestType requestType, DataServices *ds, ...);

    static void SetFabOutSize(int iSize);

  private:

    // Dispatchable functions

      // FillVarOneFab
      bool FillVar(FArrayBox *destFab, const Box &destBox,
                   int finestFillLevel, const string &varname,
                   int procWithFab);

      // FillVarArrayOfFabs
      //bool FillVar(Array<FArrayBox *> &destFabs, const Array<Box> &destBoxes,
                   //int finestFillLevel, const string &varname,
                   //int procWithFab);

      // FillVarMultiFab
      bool FillVar(MultiFab &destMultiFab, int finestFillLevel,
                   const string &varname);

      // WriteFabOneVar:  write a single variable to one fab
      bool WriteFab(const string &fabfilename, const Box &region, int lev,
                    const string &varname);

      // WriteFabAllVars:  write all vars in one fab
      bool WriteFab(const string &fabfilename, const Box &region, int lev);

      // DumpSlicePlaneOneVar
      bool DumpSlice(int slicedir, int slicenum, const string &varname);

      // DumpSlicePlaneAllVars
      bool DumpSlice(int slicedir, int slicenum);

      // DumpSliceBoxOneVar
      bool DumpSlice(const Box &slicebox, const string &varname);

      // DumpSliceBoxAllVars
      bool DumpSlice(const Box &slicebox);

      // MinMaxRequest
      bool MinMax(const Box &onBox, const string &derived, int level,
                  Real &dataMin, Real &dataMax, bool &minMaxValid);

      // PointValueRequest
      void PointValue(int pointBoxArraySize, Box *pointBoxArray,
		      const string &currentDerived,
		      int coarsestLevelToSearch, int finestLevelToSearch,
		      int &intersectedLevel, Box &intersectedGrid,
		      Real &dataPointValue, bool &bPointIsValid);

#ifndef BL_NOLINEVALUES
      // LineValuesRequest
      void LineValues(int lineBoxArraySize, Box *lineBoxArray, int whichDir,
                      const string &currentDerived,
                      int coarsestLevelToSearch, int finestLevelToSearch,
                      XYPlotDataList *dataList, bool &lineIsValid);
#endif

  public:

    // information functions
    const string &GetFileName() const { return fileName; }
    FileType GetFileType()      const { return fileType; }
    bool CanDerive(const string &name) const;
    int  NumDeriveFunc() const;
    void ListDeriveFunc(std::ostream &os) const;
    const Array<string> &PlotVarNames() const { return amrData.PlotVarNames(); }
    AmrData &AmrDataRef() { return amrData; }
    bool AmrDataOk() { return bAmrDataOk; }  
    void SetWriteToLevel(const int iwtlev)  { iWriteToLevel = iwtlev; }

    // other functions
    int GetNumberOfUsers() const  { return numberOfUsers; }
    void IncrementNumberOfUsers() { ++numberOfUsers; }
    void DecrementNumberOfUsers() { --numberOfUsers; }


  private:
    const string fileName;
    const FileType fileType;
    AmrData amrData;
    bool bAmrDataOk;
    int dsArrayIndex;
    int numberOfUsers;
    int iWriteToLevel;

    static Array<DataServices *> dsArray;
    static int dsArrayIndexCounter;
    static int dsFabOutSize;
    static bool dsBatchMode;
};

#endif
