/*
* Copyright (c) 2003-2005 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:     Declares AIW Menu utilities for providers to access consumer menu.
*
*/





#ifndef AIW_MENU_H
#define AIW_MENU_H

// INCLUDES
#include <eikmenup.h>
#include <AiwServiceIfBase.h>

// CONSTANTS

// MACROS

// DATA TYPES

// FUNCTION PROTOTYPES

// FORWARD DECLARATIONS

// CLASS DECLARATION

/**
* CAiwMenuPane for providers to have limited access to consumer menu.
*
* AIW provider can get a reference to CAiwMenuPane in its InitializeMenuPaneL()
* method, which is derived from CAiwServiceIfMenu. With this reference,
* the provider can e.g. insert menu items to the consumer application's menu.
*
* @lib ServiceHandler.lib
* @since Series 60 2.6
*/
class CAiwMenuPane: public CBase
    {
    public:
        /**
        * Constructor.
        *
        * @param aMenuPane Consumer's menu pane handle.
        * @param aBaseCmdId Base command ID for new menu items, specified by consumer.
        */
        IMPORT_C CAiwMenuPane(CEikMenuPane& aMenuPane, TInt aBaseCmdId);

        /**
        * Destructor.
        */        
        IMPORT_C virtual ~CAiwMenuPane();   
       
    public:
        /**
        * Adds a menu item to consumer menu. For each addition a mapping element 
        * is created. This method should normally be called from provider's 
        * InitializeMenuPaneL().
        *
        * @param aServiceCmd The AIW service command the provider implements.
        * @param aMenuItem The menu item data.
        * @param aIndex Position of item where to add menu items.
        */
        IMPORT_C void AddMenuItemL(
            TInt aServiceCmd,
            CEikMenuPaneItem::SData& aMenuItem, 
            TInt aIndex);
            
        /**
        * Adds a menu item to consumer menu. For each addition a mapping element 
        * is created. This method should normally be called from provider's 
        * InitializeMenuPaneL().
        *
        * @param aServiceCmd The AIW service command the provider implements.
        * @param aMenuItem The menu item data.
        * @param aIndex Position of item where to add menu items.
        * @param aExtraText Altenative menu item text, if it is placed to a submenu.
        */
        IMPORT_C void AddMenuItemL(
            TInt aServiceCmd,
            CEikMenuPaneItem::SData& aMenuItem, 
            TInt aIndex,
            const TDesC& aExtraText);            
        
        /**
        * Adds a menu item(s) to consumer menu from provider resource. This method 
        * should normally be called from provider's InitializeMenuPaneL().
        *
        * @param aReader Resource reader pointing to the menu resource.
        * @param aServiceCmd The AIW service command the provider implements.
        * @param aIndex Position of item where to add menu items.
        * @param aAddSeparator Currently not in use.
        */
        IMPORT_C void AddMenuItemsL(
            TResourceReader& aReader,
            TInt aServiceCmd,
            TInt aIndex,
            TBool aAddSeperator = EFalse);

        /**
        * Adds a menu item(s) to consumer menu from provider resource. This method 
        * should normally be called from provider's InitializeMenuPaneL().
        *
        * @param aFileName The provider's resource where menu item(s) are defined.
        * @param aResId Resource id of a MENU_PANE.
        * @param aServiceCmd The AIW service command the provider implements.
        * @param aIndex Position of item where to add menu items.
        * @param aAddSeperator Currently not in use.
        */
        IMPORT_C void AddMenuItemsL(
            TFileName& aFileName,
            TInt aResId,
            TInt aServiceCmd,
            TInt aIndex,
            TBool aAddSeperator = EFalse);

    public:
        /**
        * Gets the provider's original menu command ID from the dynamic menu command 
        * ID (generated by the AIW framework).
        *
        * @param aDynCmdId Dynamic menu command ID.
        * @return Found provider's original menu command ID, KErrNotFound if not found.
        */
        IMPORT_C TInt MenuCmdId(TInt aDynCmdId) const;
        
        /**
        * Gets the dynamic menu command ID (generated by the AIW framework) from the 
        * provider's original menu command ID. There are usually multiple matching 
        * dynamic menu command IDs, so this method returns the first item found.
        *
        * @param aMenuCmdId Provider's original menu command ID.
        * @return Found dynamic menu command ID, KErrNotFound if not found.
        */
        IMPORT_C TInt DynCmdId(TInt aMenuCmdId) const;

        /**
        * Gets the AIW service command ID from the dynamic menu command ID (generated 
        * by the AIW framework).
        *
        * @param aDynCmdId Dynamic menu command ID.
        * @return Found AIW service command ID, KErrNotFound if not found.
        */
        IMPORT_C TInt ServiceCmdId(TInt aDynCmdId) const;

        /**
        * Add sub menu title item. This item will not be visible in menus,
        * but will be used as title for comsumer's AIW submenu (if consumer
        * requests that).
        *
        * @param aTitle Title text
        * @param aIndex Position of title item in menu (can be anything, but
        *               if there is several title item definitions in menu,
        *               then the last one will be used).
        * @since 2.8        
        */
        IMPORT_C void AddTitleItemL(const TDesC& aTitle, TInt aIndex);  

    friend class CAiwServiceHandlerImpl;

    private: 
        struct SMenuIdMap
            {
            TInt serviceCmdId;          // AIW service command ID.
            TInt origCmdId;             // Original menu ID used by provider SW
            TInt dynMenuCmdId;          // The dynamic command ID generated by AIWFW
            CAiwServiceIfBase* owner;   // A pointer to the provider object.
            RBuf extraText;             // Alternative submenu text is stored here.
            };

    private:    
        TInt FindCmdId(TInt aIndex);
        inline CEikMenuPane& MenuPane();
        inline void SetResourceSlotId(TInt aSlot);
        inline TInt ResourceSlotId() const;
        inline void SetPaneOffset(TInt aOffset);
        inline TInt PaneOffset() const;
        inline TInt MenuResourceId() const;
        inline void SetMenuResourceId(TInt aMenuResourceId);
        TBool IsCmdInRange(TInt aCmdSpaceSize, TInt aCmd);
        CAiwServiceIfBase* CommandOwner(TInt aDynId) const;
        inline CAiwServiceIfBase* InitializingOwner() const;
        inline void SetInitializingOwner(CAiwServiceIfBase* aOwner);
        const TDesC& ExtraText(TInt aDynMenuCmdId);

    private:
        // Original menu pane.
        CEikMenuPane* iMenuPane;
        
        // Base ID to generate menu IDs for placeholders. From constructor.
        TInt iBaseCmdId;     
        
        // Map needed to map provider cmd IDs to dynamic command Ids
        RArray<SMenuIdMap> iIdMap;
           
        TInt iNextCmdId;    // The next free command ID to use
        TInt iResourceSlotId;
        TInt iPaneOffset;
        TInt iMenuResourceId;
        CAiwServiceIfBase* iInitializingOwner;  // Owner that is currently initializing.

        TInt iReserved_1;
        void *iExtension; // reserved for future use
    };


inline CEikMenuPane& CAiwMenuPane::MenuPane()
    {
    return *iMenuPane;  
    }


inline void CAiwMenuPane::SetResourceSlotId(TInt aSlot)
    {
    iResourceSlotId = aSlot;
    }


inline TInt CAiwMenuPane::ResourceSlotId() const
    {
    return iResourceSlotId;
    }


inline void CAiwMenuPane::SetPaneOffset(TInt aOffset)
    {
    iPaneOffset = aOffset;
    }


inline TInt CAiwMenuPane::PaneOffset() const
    {
    return iPaneOffset; 
    }


inline CAiwServiceIfBase* CAiwMenuPane::InitializingOwner() const
    {
    return iInitializingOwner;
    }


inline void CAiwMenuPane::SetInitializingOwner(CAiwServiceIfBase* aOwner)
    {
    iInitializingOwner = aOwner;
    }


inline TInt CAiwMenuPane::MenuResourceId() const
    {
    return iMenuResourceId;
    }


inline void CAiwMenuPane::SetMenuResourceId(TInt aMenuResourceId)
    {
    iMenuResourceId = aMenuResourceId;
    }

#endif  // AIW_MENU_H

// END of File
