/*
** (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 _TagBox_H_
#define _TagBox_H_
//
// $Id: TagBox.H,v 1.18 2003/02/28 22:42:15 lijewski Exp $
//
#include <IntVect.H>
#include <Box.H>
#include <Array.H>
#include <BaseFab.H>
#include <FabArray.H>
#include <BoxArray.H>
#include <BoxDomain.H>
#include <PArray.H>
#include <Geometry.H>

//
//@Man:
//@Memo: Tagged cells in a Box.
/*@Doc:

  This class is used to tag cells in a Box that need addition refinement.
*/

class TagBox
    :
    public BaseFab<char>
{
public:
    //
    //@ManDoc: The type of each tag.
    //
    typedef char TagType;
    //
    //@ManDoc: Possible values for each cell.
    //
    enum TagVal { CLEAR=0, BUF, SET };
    //
    //@ManDoc: Construct an invalid TagBox with no memory.
    //
    TagBox ();
    //
    //@ManDoc: Construct a TagBox on Box `bx' with number of components `n'.
    //
    TagBox (const Box& bx, int n = 1);
    //
    //@ManDoc: Resize the box on which the TagBox is defined.
    //
    void resize (const Box& b, int ncomp=1);

    /*@ManDoc: Construct and return a new tagbox in which the coarsened cell
               is tagged of any of the corresponding fine cells are tagged.
    */
    TagBox* coarsen (const IntVect& ratio);

    /*@ManDoc: Mark neighbors of every tagged cell a distance nbuff away
               only search interior for initial tagged points where nwid
               is given as the width of the bndry region.
    */
    void buffer (int nbuff, int nwid);
    //
    //@ManDoc: Tag cells on intersect with src if corresponding src cell is tagged.
    //
    void merge (const TagBox& src);

    /*@ManDoc: Add location of every tagged cell to IntVect array,
               starting at given location.  Returns the number of
               collated points.
    */
    int collate (IntVect* ar, int start) const;
    //
    //@ManDoc: Returns number of tagged cells in specified Box.
    //
    int numTags (const Box& bx) const;
    //
    //@ManDoc: Returns total number of tagged cells in the TagBox.
    //
    int numTags () const;

    /*@ManDoc: Returns Array<int> of size domain.numPts() suitable for calling
               Fortran, with positions set to same value as in the TagBox
               dataPtr().
    */
    Array<int> tags () const;

    /*@ManDoc: Set values as specified by the array.
               It's an error if ar.length() != domain.numPts().
    */
    void tags (const Array<int>& ar);

private:
    //
    // Disallowed.
    //
    TagBox (const TagBox& rhs);
    TagBox& operator= (const TagBox& rhs);
};

//
//@Man:
//@Memo: An array of TagBoxes.
/*@Doc:

  A container class for TagBoxes.
*/

class TagBoxArray
    :
    public FabArray<TagBox>
{
public:
    //
    //@ManDoc: The type of each tag.
    //
    typedef TagBox::TagType TagType;
    //
    //@ManDoc: The constructor.
    //
    TagBoxArray (const BoxArray& bs, int _ngrow=0);
    //
    //@ManDoc: Returns the grow factor for the TagBoxArray.
    //
    int borderSize () const;
    //
    //@ManDoc: Calls buffer() on all contained TagBoxes.
    //
    void buffer (int nbuf);

    /*@ManDoc: Map tagged cells through a periodic boundary to other grids in
               TagBoxArray cells which were outside domain are set to TagBox::CLEAR.
    */
    void mapPeriodic (const Geometry& geom);
    //
    //@ManDoc: Set values in `bd' to `val'.
    //
    void setVal (const BoxDomain& bd, TagBox::TagVal val);
    //
    //@ManDoc: Set values in `ba' to `val'. 
    //
    void setVal (const BoxArray& ba, TagBox::TagVal val);
    //
    //@ManDoc: Calls coarsen() on all contained TagBoxes.
    //
    void coarsen (const IntVect& ratio);
    //
    //@ManDoc: The total number of Tags in all the contained TagBoxes.
    //
    long numTags () const;

    /*@ManDoc: Calls collate() on all contained TagBoxes.
               The callee must delete[] the space when not needed.
    */
    IntVect* collate (long& numtags) const;

private:
    //
    // Disallowed.
    //
    TagBoxArray ();
    TagBoxArray (const TagBoxArray& rhs);
    TagBoxArray& operator= (const TagBoxArray& rhs);
    //
    // Not to be confused with FabArray::n_grow which defines
    // the invalid regions of the fabs in the FabArray.
    //
    int m_border;
};

#endif /*_TagBox_H_*/
