/*
  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 examp7.cpp
   This example is to show use of the Decorator pattern.
   
   In our scenario we have a BannerComponent. This is the Component
   that the Decorators need to add responsibility to.We create
   two (2) decorators PreBanner and PostBanner which are the
   relevance of where they add responsibilities.
   
   Finally, we chain the decorators and the component being
   decorated.
*/                   


#include <Common.hpp>
#include <BannerComponent.hpp>
#include <PreBanner.hpp>
#include <PostBanner.hpp>

using namespace corelinux;


#include <iostream>
#include <exception>

//
// In module function prototypes
//

int   main( void );

//
// Functions that work with Engine types
//

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

int main( void )
{

   //
   // Practice gracefull exception management
   //

   cout << endl;

   try
   {
      //
      // Instantiate the component implementation.
      // And invoke the operation.
      //

      BannerComponent   aBanner("A Basic Banner");

      cout << "-------------------------------------------" << endl;
      aBanner.drawBanner( cout );
      cout << endl;
      cout << "-------------------------------------------" << endl;

      //
      // And a pre decorator and invoke the
      // operation.
      //

      PreBanner   aPreBanner("A header to ",&aBanner);

      aPreBanner.drawBanner(cout);
      cout << endl;
      cout << "-------------------------------------------" << endl;


      //
      // Add a post decorator and invoke the operation
      //

      PostBanner   aPostBanner(" with a trailer.",&aBanner);

      aPostBanner.drawBanner(cout);
      cout << endl;
      cout << "-------------------------------------------" << endl;

      //
      // How you can chain decorators.
      //

      aPreBanner.setImplementation(&aPostBanner);
      aPreBanner.drawBanner(cout);
      cout << endl;
      cout << "-------------------------------------------" << endl;

   }

   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;               
}

//
// 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:00 $
   $Locker:  $
*/


