/*
** (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.
*/

#ifndef _ErrorList_H_
#define _ErrorList_H_
//
// $Id: ErrorList.H,v 1.10 2001/08/01 21:50:45 lijewski Exp $
//
#include <string>
#include <vector>

#include <REAL.H>
#include <ArrayLim.H>

extern "C"
{
    //
    // Type of extern "C" function called by ErrorRec to do tagging of cells for refinement.
    //
    typedef void (*ErrorFunc)(int* tag, ARLIM_P(tlo), ARLIM_P(thi),
                              const int* tagval, const int* clearval,
                              Real* data, ARLIM_P(data_lo), ARLIM_P(data_hi),
                              const int* lo, const int * hi, const int* nvar,
                              const int* domain_lo, const int* domain_hi,
                              const Real* dx, const Real* xlo,
                              const Real* prob_lo, const Real* time,
                              const int* level);
}

//
//@Man:
//@Memo: Error Record.
/*@Doc:

  ErrorRec is designed to tag cells for regridding based on the state
  data contained in AmrLevel and its derivatives.  It is conceivable that
  actual error tagging will be through derivation, so provision is made
  for this as well.
*/

class ErrorRec
{
public:
    //
    //@ManDoc: Error types.
    //
    enum ErrorType { Richardson=0, Special };
    //
    //@ManDoc: The constructor.
    //
    ErrorRec (const std::string& nm,
              int                ng,
              ErrorType          etyp,
              ErrorFunc          f);
    //
    //@ManDoc: The name of the quantity to derive.
    //
    const std::string& name () const;
    //
    //@ManDoc: The number of extra zones needed for derivation.
    //
    int nGrow () const;
    //
    //@ManDoc: The type of the error tagging.
    //
    ErrorType errType () const;
    //
    //@ManDoc: The extern "C" function to do the error tagging.
    //
    ErrorFunc errFunc () const;

private:
    //
    // Name of quantity to derive.
    //
    std::string derive_name;
    //
    // Number of extra zones.
    //
    int ngrow;
    //
    // Function to do error estimation.
    //
    ErrorFunc err_func;
    //
    // The type of Error.
    //
    ErrorType err_type; 
};

//
//@Man:
//@Memo: A List of ErrorRecs.
/*@Doc:

  Container class for ErrorRecs.
*/

class ErrorList
{
public:
    //
    //@ManDoc: The number of ErrorRecs in the list.
    //
    int size () const;
    //
    //@ManDoc: Append a new ErrorRec to the list.
    //
    void add (const std::string&  name,
              int                 nextra, 
              ErrorRec::ErrorType typ,
              ErrorFunc           func);
    //
    //@ManDoc: The kth ErrorRec.
    //
    const ErrorRec& operator[] (int k) const;

private:

    std::vector<ErrorRec> vec;
};

std::ostream& operator << (std::ostream& os, const ErrorList& elst);

#endif

