/*
  CoreLinux++ 
  Copyright (C) 2000 CoreLinux Consortium
  
   The CoreLinux++ Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   The CoreLinux++ Library Library is distributed in the hope that it will 
   be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with the GNU C Library; see the file COPYING.LIB.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  
*/   

/** \example examp3.cpp
   This example is to show use of the Adapter type and pattern.
   In one case we implement an adapter by deriving from both the
   target interface and Adaptee, in the other, the Adapter has-a
   Adaptee.
*/                   


#include <Common.hpp>

using namespace corelinux;

#include <FooBarClassAdapter.hpp>
#include <FooBarObjectAdapter.hpp>

#include <iostream>
#include <exception>

using namespace std;

//
// In module function prototypes
//

int   main( void );                       

//
// Functions that expect Foo objects
//

void  addOneToFoo( FooRef );
void  displayFoo( FooRef );
void  testFooConstraints( FooRef );

void  handleAssertion( AssertionCref );
void  handleException( ExceptionCref );   


int main( void )
{

   //
   // Practice gracefull exception management
   //

   cout << endl;

   try
   {
      //
      // First test out the class adapter
      //

      FooBarClassAdapter   aFooClassAdapter;

      addOneToFoo( aFooClassAdapter );

      cout << "Displaying Foo Bar Class Adapter coordinates" << endl;

      displayFoo( aFooClassAdapter );

      // Remove comment to force exception 
      // testFooConstraints( aFooClassAdapter );

      //
      // Now test out the object adapter
      //

      Bar                  aBarObject(3,1);
      FooBarObjectAdapter  aFooObjectAdapter( &aBarObject );

      addOneToFoo( aFooObjectAdapter );

      cout << endl;
      cout << "Displaying Foo Bar Object Adapter coordinates" << endl;

      displayFoo( aFooObjectAdapter );

      // Remove either comment to force exception 
      // testFooConstraints( aFooObjectAdapter );
      // FooBarObjectAdapter  aFooObject( NULLPTR );

   }
   catch( AssertionRef aAssert )
   {
      handleAssertion(aAssert);
   }
   catch( ExceptionRef aException )
   {
      handleException(aException);
   }
   catch( std::exception & e )
   {
      cerr  << e.what() << endl;
   }
   catch( ... )
   {
      cerr  << "Unknown exception." << endl;
   }

   return 0;               
}

//
// Increment Foo X and Y
//

void  addOneToFoo( FooRef aRef )
{
   aRef.setVerticalPosition( aRef.getVerticalPosition() + 1 );
   aRef.setHorizontalPosition( aRef.getHorizontalPosition() + 1 );
}

//
// Display the foo current coordinates
//

void  displayFoo( FooRef aRef )
{
   cout  << "X [" << aRef.getHorizontalPosition() <<
      "] : Y [" << aRef.getVerticalPosition() << "]" << endl;
}

//
// Stress Foo
//

void  testFooConstraints( FooRef aRef )
{
   cout << endl;
   cout << "Stressing coordinate system" << endl;
   cout << endl;
   while( 1 )
   {
      addOneToFoo( aRef );
      displayFoo( aRef );
   }
}

//
// Peform default (just show it)
//

void  handleAssertion( AssertionCref aAssert )
{
   cerr << aAssert.getFile() << ":" << aAssert.getLine() << ":" << 
      "Assertion: ";

   if( aAssert.getType() == Assertion::NEVERGETHERE )
   {
      cerr << "NEVER_GET_HERE";
   }
   else
   {
      if( aAssert.getType() == Assertion::REQUIRE )
      {
         cerr  << "REQUIRE";
      }
      else if( aAssert.getType() == Assertion::ENSURE )
      {
         cerr  << "ENSURE";
      }
      else if( aAssert.getType() == Assertion::CHECK )
      {
         cerr  << "CHECK";
      }
      else 
      {
         cerr  << "ASSERT";
      }
      cerr << "( " << aAssert.getWhy() << " )";
   }

   cerr << endl;
}

void  handleException( ExceptionCref aExcp )
{
   cerr << aExcp.getFile() << ":" << aExcp.getLine() << ":" <<
      "Exception: " << aExcp.getWhy() << endl;
}

/*
   Common rcs information do not modify
   $Author: prudhomm $
   $Revision: 1.2 $
   $Date: 2000/08/31 22:49:01 $
   $Locker:  $
*/


