/*!
  @file     FrameCtrl_Manager.hpp
  @author   TorstenS
  @ingroup  FrameControl
  @brief    This class is used to handle i/o capable memory request

\if EMIT_LICENCE
    ========== licence begin  GPL
    Copyright (c) 2001-2005 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end

\endif
*/



#ifndef FRAMECTRL_MANAGER_HPP
#define FRAMECTRL_MANAGER_HPP


/*===========================================================================*
 *  INCLUDES                                                                 *
 *===========================================================================*/

// Interfaces
#include "FrameControl/FrameCtrl_ICommon.hpp"
#include "FrameControl/FrameCtrl_IConverter.hpp"
#include "FrameControl/FrameCtrl_IIOManager.hpp"
#include "FrameControl/FrameCtrl_ILog.hpp"
#include "FrameControl/FrameCtrl_IDataCache.hpp"
#include "FrameControl/FrameCtrl_IFileDirectory.hpp"
#include "FrameControl/FrameCtrl_IRestartPage.hpp"


#include "FrameControl/FrameCtrl_Types.hpp"
#include "KernelCommon/Kernel_Common.hpp"
#include "KernelCommon/Kernel_IPage.hpp"

/*===========================================================================*
 *  DEFINES                                                                  *
 *===========================================================================*/


/*===========================================================================*
 *  MACROS                                                                   *
 *===========================================================================*/


/*===========================================================================*
 *  CLASSES, STRUCTURES, TYPES, UNIONS ...                                   *
 *===========================================================================*/

/* -----------------------------------------------------------------------*/
/*!
    @class    FrameCtrl_Manager
    @brief    This class is used to handle i/o capable memory request
 */
/* -----------------------------------------------------------------------*/

class FrameCtrl_Manager :
            public FrameCtrl_ICommon,
            public FrameCtrl_IConverter,
            public FrameCtrl_IDataCache,
            public FrameCtrl_IFileDirectory,
            public FrameCtrl_IIOManager,
            public FrameCtrl_ILog,
            public FrameCtrl_IRestartPage
{
    friend class FrameCtrl_ICommon;
    friend class FrameCtrl_IConverter;
    friend class FrameCtrl_IDataCache;
    friend class FrameCtrl_IFileDirectory;
    friend class FrameCtrl_IIOManager;
    friend class FrameCtrl_ILog;
    friend class FrameCtrl_IRestartPage;

public:

    /* -----------------------------------------------------------------------*/
    /*!
       @brief   This method creates the singleton frame control.It is assumed 
                that this method will be callled only one time by the timeout 
                task and therefore no synchonization mechanism is used.
       @return  true means instance could be created; else false
     */
    /* -----------------------------------------------------------------------*/

    static bool CreateInstance();


    virtual SAPDB_UInt GetFreeFrameCount() const;

    virtual SAPDB_UInt GetPageSize() const{
        return( m_PageSize );
    }

    virtual SAPDB_UInt GetCacheSize() const{
        return( m_Capacity );
    }

    virtual Kernel_IPage::PageFrame NewConvFrame( tsp00_TaskId taskId )
    {
        return( NewFrame( FrameCtrl_ConverterKey, taskId ));
    }


    virtual void FreeConvFrame(
        tsp00_TaskId            taskId,
        Kernel_IPage::PageFrame &frame )
    {
        Free( FrameCtrl_ConverterKey, taskId, frame );
    }


    virtual Kernel_IPage::PageFrame NewIOManFrame( tsp00_TaskId taskId )
    {
        return( NewFrame( FrameCtrl_IOManagementKey, taskId ));
    }


    virtual void FreeIOManFrame(
        tsp00_TaskId            taskId,
        Kernel_IPage::PageFrame &frame )
    {
        Free( FrameCtrl_IOManagementKey, taskId, frame );
    }


    virtual Kernel_IPage::PageFrame NewLogFrame( tsp00_TaskId taskId )
    {
        return( NewFrame( FrameCtrl_LogKey, taskId ));
    }


    virtual void FreeLogFrame(
        tsp00_TaskId            taskId,
        Kernel_IPage::PageFrame &frame )
    {
        Free( FrameCtrl_LogKey, taskId, frame );
    }


    virtual Kernel_IPage::PageFrame NewDataFrame( tsp00_TaskId taskId )
    {
        return( NewFrame( FrameCtrl_DataCacheKey, taskId ));
    }


    virtual void NewAWEDataFrame(
        tsp00_TaskId            taskId,
        Kernel_IPage::PageFrame &frame,
        SAPDB_UInt4             &aweBlockNo )
    {
        New( FrameCtrl_DataCacheKey, taskId, frame, aweBlockNo );
    }

    virtual void FreeDataFrame(
        tsp00_TaskId            taskId,
        Kernel_IPage::PageFrame &frame )
    {
        Free( FrameCtrl_DataCacheKey, taskId, frame );
    }

    virtual Kernel_IPage::PageFrame NewFDirFrame( const tsp00_TaskId taskId )
    {
        return( NewFrame( FrameCtrl_FileDirectoryKey, taskId ));
    }

    virtual void FreeFDirFrame(
        const tsp00_TaskId      taskId,
        Kernel_IPage::PageFrame &frame )
    {
        Free( FrameCtrl_FileDirectoryKey, taskId, frame );
    }

    virtual Kernel_IPage::PageFrame NewRestartPageFrame( const tsp00_TaskId taskId )
    {
        return( NewFrame( FrameCtrl_RestartPageKey, taskId ));
    }

    virtual void FreeRestartPageFrame(
        const tsp00_TaskId      taskId,
        Kernel_IPage::PageFrame &frame )
    {
        Free( FrameCtrl_RestartPageKey, taskId, frame );
    }

protected:

    /// protected and not private to avoid warnings on linux!

    FrameCtrl_Manager();

    /* -----------------------------------------------------------------------*/
    /*!
       @brief   This method is used to initialize the component, in particular
                the number of i/o capable memory frames is requested from the RTE.
       @return  none
     */
    /* -----------------------------------------------------------------------*/

    void Initialize( )
    {
        m_Capacity = GetFreeFrameCount();
    }

private:

    // Copy and assignment operator are not supported

    FrameCtrl_Manager& operator=( const FrameCtrl_Manager &manager );

    FrameCtrl_Manager( const FrameCtrl_Manager &manager );

    static FrameCtrl_Manager& GetInstance(){ return( *m_Instance ); }

    void MaintainInternalCounter(
        const FrameCtrl_RegistrationKey registrationKey,
        const SAPDB_Bool                bIncrementCounter = true );

    Kernel_IPage::PageFrame NewFrame(
        const FrameCtrl_RegistrationKey   registrationKey,
        const tsp00_TaskId                taskId )
    {
        SAPDB_UInt4             dummyBlockNo;
        Kernel_IPage::PageFrame frame;

        New( registrationKey, taskId, frame, dummyBlockNo );
        return( frame );
    }

    void New(
        const FrameCtrl_RegistrationKey   registrationKey,
        const tsp00_TaskId                taskId,
        Kernel_IPage::PageFrame           &frame,
        SAPDB_UInt4                       &aweBlockNo );

    void Free(
        const FrameCtrl_RegistrationKey   registrationKey,
        const tsp00_TaskId                taskId,
        Kernel_IPage::PageFrame           &frame );

private:

    /*-------------------------------------------------------------------------
    declaration: m_Instance
    description: Reference to the proper FrameControl Manager
    --------------------------------------------------------------------------*/

    static FrameCtrl_Manager    *m_Instance;

    /*-------------------------------------------------------------------------
    declaration: m_PageSize
    description: Size in bytes of the pages managed by the page allocator 
    --------------------------------------------------------------------------*/

    const SAPDB_UInt m_PageSize;

    /*-------------------------------------------------------------------------
    declaration: m_Capacity
    description: Initial number of frames stored within the page allocator 
    --------------------------------------------------------------------------*/

    SAPDB_UInt m_Capacity;

    /*-------------------------------------------------------------------------
    declaration: m_CheckedOutByConverter
    description: Number of page frames checked out by the component converter
    --------------------------------------------------------------------------*/

    SAPDB_UInt m_CheckedOutByConverter;

    /*-------------------------------------------------------------------------
    declaration: m_CheckedOutByDataCache
    description: Number of page frames checked out by the component data cache
    --------------------------------------------------------------------------*/

    SAPDB_UInt m_CheckedOutByDataCache;

    /*-------------------------------------------------------------------------
    declaration: m_CheckedOutByLogQueue
    description: Number of page frames checked out by the component log queue
    --------------------------------------------------------------------------*/

    SAPDB_UInt m_CheckedOutByLogQueue;

    /*-------------------------------------------------------------------------
    declaration: m_CheckedOutByIOManagement
    description: Number of page frames checked out by the component I/O Management
    --------------------------------------------------------------------------*/

    SAPDB_UInt m_CheckedOutByIOManagement;

    /*-------------------------------------------------------------------------
    declaration: m_CheckedOutByFileDirectory
    description: Number of page frames checked out by the component file directory
    --------------------------------------------------------------------------*/

    SAPDB_UInt m_CheckedOutByFileDirectory;

    /*-------------------------------------------------------------------------
    declaration: m_CheckedOutByRestartRecord
    description: Number of page frames checked out by the component restart
    --------------------------------------------------------------------------*/

    SAPDB_UInt m_CheckedOutByRestartRecord;
};


#endif  /* FRAMECTRL_MANAGER_HPP */
