#if   !defined(__MAZEBUILDERFACTORY_HPP)
#define __MAZEBUILDERFACTORY_HPP

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


#if   !defined(__COMMON_HPP)
#include <Common.hpp>
#endif

#if   !defined(__ABSTRACTFACTORY_HPP)
#include <AbstractFactory.hpp>
#endif

#if   !defined(__ALLOCATOR_HPP)
#include <Allocator.hpp>
#endif

#if   !defined(__MAP_HPP)
#include <Map.hpp>
#endif

#if   !defined(__NAMEIDENTIFIER_HPP)
#include <NameIdentifier.hpp>
#endif

using namespace std;

//
// We use a map for storing our allocators. We could have fire-walled this
// as well.
//

CORELINUX_MAP( 
	      NameIdentifier, 
	      CORELINUX(AllocatorPtr), 
	      less<NameIdentifier>,
	      NamedAllocators
	      );


DECLARE_CLASS( MapSite );

/**
Maze Factory creates Rooms, Doors, and Walls. It is a AbstractFactory
that uses a NameIdentifier as a key association to the respective 
Allocators (DoorAllocator, etc.).
We use protected inheritence for the AbstractFactory because we are not
interested letting the application have to do the work, they just need
to create things!
*/

DECLARE_CLASS( MazeBuilderFactory );

class MazeBuilderFactory : protected CORELINUX(AbstractFactory<NameIdentifier>)
{
public:

   //
   // Constructors and destructor
   //

                        /// Default constructor

                        MazeBuilderFactory( void );

                        /// Copy constructor

                        MazeBuilderFactory( MazeBuilderFactoryCref );

                        /// Virtual Destructor

   virtual              ~MazeBuilderFactory( void );

   //
   // Operator overloads
   //

            /// Assignment operator

            MazeBuilderFactoryRef operator=( MazeBuilderFactoryCref ) 
                              throw(CORELINUX(Exception));

            /// Equality operator

            bool  operator==( MazeBuilderFactoryCref ) const;

   //
   // Accessors
   //

            /// Return number of allocators registered

            CORELINUX(Count)  getAllocatorCount( void ) const;

            /// Return some instrumentation for this Factory

            CORELINUX(Count)  getTotalAllocates( void ) const;

            /// Return some instrumentation for this Factory

            CORELINUX(Count)  getTotalDeallocates( void ) const;

            /// Return the Room Allocator Key

   static   NameIdentifierCref   getRoomIdentifier( void );

            /// Return the Door Allocator Key

   static   NameIdentifierCref   getDoorIdentifier( void );

            /// Return the Wall Allocator Key

   static   NameIdentifierCref   getWallIdentifier( void );

   //
   // Factory methods
   //

            /// Create a Maze Part

   virtual  MapSitePtr  createPart( NameIdentifierRef ) const
                           throw(CORELINUX(AllocatorNotFoundException));

            /// Destroy a Maze Part

   virtual  void  destroyPart( NameIdentifierRef, MapSitePtr ) const
                           throw(CORELINUX(AllocatorNotFoundException));

            /// Exchange allocator default with new one

   virtual  CORELINUX(AllocatorPtr) setAllocator
                                       ( 
                                          NameIdentifierRef,
                                          CORELINUX(AllocatorPtr) 
                                       );

protected:

   //
   // Accessors overriden from AbstractFactory
   //

            /// Get the total MapSite objects created

   virtual  CORELINUX(Count)  getCreateCount( void ) const;

            /// Get the total MapSite objects destroyed

   virtual  CORELINUX(Count)  getDestroyCount( void ) const;

            /// Get the allocator identifier by NameIdentifier

   virtual  CORELINUX(AllocatorPtr) getAllocator( NameIdentifier ) const
                        throw(CORELINUX(AllocatorNotFoundException));

   //
   // Mutators overriden from AbstractFactory
   //

            /// Add a allocator to the factory

   virtual  void  addAllocator( NameIdentifier, CORELINUX(AllocatorPtr) )
                        throw(CORELINUX(AllocatorAlreadyExistsException));

            /// Remove the allocator from the factory and return to the
            /// caller

   virtual  CORELINUX(AllocatorPtr) removeAllocator( NameIdentifier )
                        throw(CORELINUX(AllocatorNotFoundException));
   //
   // Overides Iterator factory methods from AbstractFactory
   //
            /**
            Interface for creating an Iterator to iterate
            through the Allocators of an implementation.
            @return Iterator pointer of type Allocator pointer
            */

   virtual  CORELINUX(Iterator<corelinux::AllocatorPtr>)* createIterator( void ) const;

            /**
            Interface for returning a created Iterator.
            @return Iterator pointer of type Allocator pointer
            */

   virtual  void  destroyIterator( CORELINUX(Iterator<corelinux::AllocatorPtr>)* ) const;

            /**
            Interface for creating an AssociativeIterator to iterate
            through the Identifiers and Allocators of an implementation.
            @return AssociativeIterator pointer of type 
            <Identifier,Allocator pointer>
            */

   virtual  corelinux::AssociativeIterator<NameIdentifier,corelinux::AllocatorPtr>*   
               createAssociativeIterator( void ) const;

            /**
            Interface for returning a created AssociativeIterator.
            @return Iterator pointer of type 
            <Identifier,Allocator pointer>
            */

   virtual  void  destroyAssociativeIterator
                     ( 
                        corelinux::AssociativeIterator<NameIdentifier,corelinux::AllocatorPtr>* 
                     ) const;

      
protected:

            /// Routine to flush contents from map

            void  flushAllocators( void );

private:

   static   NameIdentifier    theRoomIdentifier;
   static   NameIdentifier    theDoorIdentifier;
   static   NameIdentifier    theWallIdentifier;

            NamedAllocators   theAllocators;

};

#endif // if !defined(__MAZEBUILDERFACTORY_HPP)

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


