/*****************************************************************************
 * $LastChangedDate: 2011-04-23 21:07:07 -0400 (Sat, 23 Apr 2011) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   Test of Array2D class.
 *//*
 * LEGAL:   COPYRIGHT (C) 2005 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
 *****************************************************************************/

#define TESTING 1
#include <vector>
#include "test.hh"
#include "base/module.hh"
#include "base/array_2d.hh"
using namespace base;
#include "math/module.hh"
#include "math/funcs.hh"
using namespace math;

/*****************************************************************************
 * Test Array2D class.
 *****************************************************************************/
bool
TestArray2D( void )
{
    CDEBUG << "============================================\n";
    CDEBUG << "Testing Array2D class. \n";
    CDEBUG << "============================================\n";

    // Test default empty Array2D.
    {
    Array2D<int> arr;
    if ( not arr.empty() ) return Fail();
    if ( arr.size() != 0 ) return Fail();
    if ( arr.width() != 0 ) return Fail();
    if ( arr.height() != 0 ) return Fail();
    }

    // Test explicitly empty Array2D.
    {
    Array2D<int> arr( 0, 0 );
    if ( not arr.empty() ) return Fail();
    if ( arr.size() != 0 ) return Fail();
    if ( arr.width() != 0 ) return Fail();
    if ( arr.height() != 0 ) return Fail();
    }

    // Test Array2D(1,1).
    {
    Array2D<int> arr( 1, 1 );
    if ( arr.empty() ) return Fail();
    if ( arr.size() != 1 ) return Fail();
    arr.Set( 0, 0, 1234 );
    if ( arr.Get( 0, 0 ) != 1234 ) return Fail();
    if ( arr.Get( 0, 1 ) != 1234 ) return Fail();  // should clamp
    if ( arr.Get( 100, 100 ) != 1234 ) return Fail();  // should clamp
    if ( arr.Get( -1, 0 ) != 1234 ) return Fail();  // should clamp
    if ( arr.width() != 1 ) return Fail();
    if ( arr.height() != 1 ) return Fail();
    }

    // Test Array2D(2,2).
    {
    Array2D<int> arr( 2, 2 );
    if ( arr.empty() ) return Fail();
    if ( arr.size() != 4 ) return Fail();
    if ( arr.width() != 2 ) return Fail();
    if ( arr.height() != 2 ) return Fail();

    arr.Set( 0, 0, 111 ); if ( arr.Get( 0, 0 ) != 111 ) return Fail();
    arr.Set( 0, 1, 222 ); if ( arr.Get( 0, 1 ) != 222 ) return Fail();
    arr.Set( 1, 0, 333 ); if ( arr.Get( 1, 0 ) != 333 ) return Fail();
    arr.Set( 1, 1, 444 ); if ( arr.Get( 1, 1 ) != 444 ) return Fail();

    if ( arr.Get( -999, -999 ) != 111 ) return Fail();  // should clamp at min corner
    if ( arr.Get(  999,  999 ) != 444 ) return Fail();  // should clamp at max corner

    if ( arr.Get( 0, -999 ) != 111 ) return Fail();  // partial clamp at (0,0)
    if ( arr.Get( -999, 1 ) != 222 ) return Fail();  // partial clamp at (0,1)
    if ( arr.Get( 999, 0 ) != 333 ) return Fail();  // partial clamp at (1,0)
    if ( arr.Get( 1, -999 ) != 333 ) return Fail();  // partial clamp at (1,0) also
    if ( arr.Get( 999, 999 ) != 444 ) return Fail();  // partial clamp at (1,1)
    if ( arr.Get( 1, 999 ) != 444 ) return Fail();  // partial clamp at (1,1) also
    if ( arr.Get( 999, 1 ) != 444 ) return Fail();  // partial clamp at (1,1) also
    }

    // Test asymmetric Array2D(2,3).
    {
    Array2D<int> arr( 2, 3 );
    if ( arr.empty() ) return Fail();
    if ( arr.size() != 6 ) return Fail();
    if ( arr.width() != 2 ) return Fail();
    if ( arr.height() != 3 ) return Fail();

    arr.Set( 0, 0, 111 );  // first
    arr.Set( 1, 2, 222 );  // last

    if ( arr.Get( 0, 0 ) != 111 ) return Fail();
    if ( arr.Get( 1, 2 ) != 222 ) return Fail();

    if ( arr.Get( -999, -999 ) != 111 ) return Fail();
    if ( arr.Get( 999, 999 ) != 222 ) return Fail();
    }

    CDEBUG << "ok \n";
    return true;
}

/*****************************************************************************
 * main.
 *****************************************************************************/
int main( int argc, char** argv )
{
    RUN_TEST( "Array2D", TEST_ERROR_MODE_ABORT,
              TestArray2D() )
}
