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


#include "interpolator.H"

#if defined( BL_FORT_USE_UNDERSCORE )
#define FORT_FACINT2  acint2_
#define FORT_FANINT2  anint2_
#elif defined( BL_FORT_USE_UPPERCASE )
#define FORT_FACINT2  ACINT2
#define FORT_FANINT2  ANINT2
#elif defined( BL_FORT_USE_LOWERCASE )
#define FORT_FACINT2  acint2
#define FORT_FANINT2  anint2
#else
#error "none of BL_FORT_USE_{UNDERSCORE,UPPERCASE,LOWERCASE} defined"
#endif

extern "C"
{
    void FORT_FACINT2(Real*, intS, intS, const Real*,
		      intS, intS, intRS, const int&);
    void FORT_FANINT2(Real*, intS, intS, const Real*,
		      intS, intS, intRS, const int&);
}

amr_interpolator::~amr_interpolator () {}

Box
bilinear_interpolator::box (const Box&     region,
                                  const IntVect& rat) const
{
    if (region.cellCentered())
    {
	return BoxLib::grow(BoxLib::coarsen(region, rat), 1);
    }
    else if (region.type() == IntVect::TheNodeVector())
    {
	return BoxLib::coarsen(region, rat);
    }
    else
    {
	BoxLib::Abort( "bilinear_interpolator::box():"
		       "Interpolation only defined for pure CELL- or NODE-based data" ); /*NOTREACHED*/
	return Box();
    }
}

void
bilinear_interpolator::fill (FArrayBox&       patch,
			     const Box&       region,
			     const FArrayBox& cgr,
			     const Box&       cb,
			     const IntVect&   rat) const
{
    if (patch.box().cellCentered())
    {
	FORT_FACINT2(
	    patch.dataPtr(), DIMLIST(patch.box()),
	    DIMLIST(region),
	    cgr.dataPtr(), DIMLIST(cgr.box()),
	    DIMLIST(cb), D_DECL(rat[0], rat[1], rat[2]), patch.nComp());
    }
    else if (patch.box().type() == IntVect::TheNodeVector())
    {
        Box eregion = BoxLib::refine(cb, rat);

	if (eregion == region)
	{
	    FORT_FANINT2(
		patch.dataPtr(), DIMLIST(patch.box()),
		DIMLIST(region),
		cgr.dataPtr(), DIMLIST(cgr.box()),
		DIMLIST(cb), D_DECL(rat[0], rat[1], rat[2]), patch.nComp());
	}
	else
	{
	    FArrayBox epatch(eregion, patch.nComp());
	    FORT_FANINT2(
		epatch.dataPtr(), DIMLIST(epatch.box()),
		DIMLIST(eregion),
		cgr.dataPtr(), DIMLIST(cgr.box()),
		DIMLIST(cb), D_DECL(rat[0], rat[1], rat[2]), patch.nComp());
	    patch.copy(epatch, region);
	}
    }
    else
    {
	BoxLib::Abort( "bilinear_interpolator::fill():"
		       "Interpolation only defined for pure CELL- or NODE-based data" );
    }
}
