/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_unotools.hxx"
#ifndef GCC
#endif

//_________________________________________________________________________________________________________________
//	includes
//_________________________________________________________________________________________________________________

#include <unotools/dynamicmenuoptions.hxx>
#include <unotools/moduleoptions.hxx>
#include <unotools/configmgr.hxx>
#include <unotools/configitem.hxx>
#include <tools/debug.hxx>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/uno/Sequence.hxx>

#ifndef __SGI_STL_VECTOR
#include <vector>
#endif

#include <itemholder1.hxx>

#include <algorithm>

//_________________________________________________________________________________________________________________
//	namespaces
//_________________________________________________________________________________________________________________

using namespace ::std					;
using namespace ::utl					;
using namespace ::rtl					;
using namespace ::osl					;
using namespace ::com::sun::star::uno	;
using namespace ::com::sun::star::beans	;

//_________________________________________________________________________________________________________________
//	const
//_________________________________________________________________________________________________________________

#define ROOTNODE_MENUS                                  OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/Menus/"     ))
#define PATHDELIMITER                                   OUString(RTL_CONSTASCII_USTRINGPARAM("/"                        ))

#define SETNODE_NEWMENU                                 OUString(RTL_CONSTASCII_USTRINGPARAM("New"                      ))
#define SETNODE_WIZARDMENU                              OUString(RTL_CONSTASCII_USTRINGPARAM("Wizard"                   ))
#define SETNODE_HELPBOOKMARKS                           OUString(RTL_CONSTASCII_USTRINGPARAM("HelpBookmarks"            ))

#define PROPERTYNAME_URL                                DYNAMICMENU_PROPERTYNAME_URL
#define PROPERTYNAME_TITLE                              DYNAMICMENU_PROPERTYNAME_TITLE
#define PROPERTYNAME_IMAGEIDENTIFIER                    DYNAMICMENU_PROPERTYNAME_IMAGEIDENTIFIER
#define PROPERTYNAME_TARGETNAME                         DYNAMICMENU_PROPERTYNAME_TARGETNAME

#define PROPERTYCOUNT                                   4

#define OFFSET_URL                                      0
#define OFFSET_TITLE                                    1
#define OFFSET_IMAGEIDENTIFIER                          2
#define OFFSET_TARGETNAME                               3

#define PATHPREFIX_SETUP                                OUString(RTL_CONSTASCII_USTRINGPARAM("m"                        ))
#define PATHPREFIX_USER                                 OUString(RTL_CONSTASCII_USTRINGPARAM("u"                        ))

//_________________________________________________________________________________________________________________
//	private declarations!
//_________________________________________________________________________________________________________________

/*-****************************************************************************************************************
    @descr  struct to hold information about one menu entry.
****************************************************************************************************************-*/
struct SvtDynMenuEntry
{
    public:
        SvtDynMenuEntry() {};

        SvtDynMenuEntry(  const OUString& sNewURL             ,
                    const OUString& sNewTitle           ,
                    const OUString& sNewImageIdentifier ,
                    const OUString& sNewTargetName      )
        {
            sURL                = sNewURL               ;
            sTitle              = sNewTitle             ;
            sImageIdentifier    = sNewImageIdentifier   ;
            sTargetName         = sNewTargetName        ;
        }

    public:
        OUString    sName               ;
        OUString    sURL                ;
        OUString    sTitle              ;
        OUString    sImageIdentifier    ;
        OUString    sTargetName         ;
};

/*-****************************************************************************************************************
    @descr  support simple menu structures and operations on it
****************************************************************************************************************-*/
class SvtDynMenu
{
    public:
        //---------------------------------------------------------------------------------------------------------
        // append setup written menu entry
        // Don't touch name of entry. It was defined by setup and must be the same everytime!
        // Look for double menu entries here too ... may be some seperator items are supeflous ...
        void AppendSetupEntry( const SvtDynMenuEntry& rEntry )
        {
            if(
                ( lSetupEntries.size()         <  1           )  ||
                ( lSetupEntries.rbegin()->sURL != rEntry.sURL )
              )
            {
                lSetupEntries.push_back( rEntry );
            }
        }

        //---------------------------------------------------------------------------------------------------------
        // append user specific menu entry
        // We must find unique name for it by using special prefix
        // and next count of user setted entries!
        // Look for double menu entries here too ... may be some seperator items are supeflous ...
        void AppendUserEntry( SvtDynMenuEntry& rEntry )
        {
            if(
                ( lUserEntries.size()         <  1           )  ||
                ( lUserEntries.rbegin()->sURL != rEntry.sURL )
              )
            {
                rEntry.sName  = PATHPREFIX_USER;
                rEntry.sName += OUString::valueOf( (sal_Int32)impl_getNextUserEntryNr() );
                lUserEntries.push_back( rEntry );
            }
        }

        //---------------------------------------------------------------------------------------------------------
        // the only way to free memory!
        void Clear()
        {
            lSetupEntries.clear();
            lUserEntries.clear();
        }

        //---------------------------------------------------------------------------------------------------------
        // convert internal list to external format
        // for using it on right menus realy
        // Notice:   We build a property list with 4 entries and set it on result list then.
        //           The while-loop starts with pointer on internal member list lSetupEntries, change to
        //           lUserEntries then and stop after that with NULL!
        //           Separator entries will be packed in another way then normal entries! We define
        //           special strings "sEmpty" and "sSeperator" to perform too ...
        Sequence< Sequence< PropertyValue > > GetList() const
        {
            sal_Int32                             nSetupCount = (sal_Int32)lSetupEntries.size();
            sal_Int32                             nUserCount  = (sal_Int32)lUserEntries.size();
            sal_Int32                             nStep       = 0;
            Sequence< PropertyValue >             lProperties ( PROPERTYCOUNT );
            Sequence< Sequence< PropertyValue > > lResult     ( nSetupCount+nUserCount );
            OUString                              sSeperator  ( RTL_CONSTASCII_USTRINGPARAM("private:separator") );
            OUString                              sEmpty      ;
            const vector< SvtDynMenuEntry >*            pList       = &lSetupEntries;

            lProperties[OFFSET_URL            ].Name = PROPERTYNAME_URL             ;
            lProperties[OFFSET_TITLE          ].Name = PROPERTYNAME_TITLE           ;
            lProperties[OFFSET_IMAGEIDENTIFIER].Name = PROPERTYNAME_IMAGEIDENTIFIER ;
            lProperties[OFFSET_TARGETNAME     ].Name = PROPERTYNAME_TARGETNAME      ;

            while( pList != NULL )
            {
                for( vector< SvtDynMenuEntry >::const_iterator pItem =pList->begin();
                                                         pItem!=pList->end()  ;
                                                         ++pItem              )
                {
                    if( pItem->sURL == sSeperator )
                    {
                        lProperties[OFFSET_URL              ].Value <<= sSeperator  ;
                        lProperties[OFFSET_TITLE            ].Value <<= sEmpty      ;
                        lProperties[OFFSET_IMAGEIDENTIFIER  ].Value <<= sEmpty      ;
                        lProperties[OFFSET_TARGETNAME       ].Value <<= sEmpty      ;
                    }
                    else
                    {
                        lProperties[OFFSET_URL              ].Value <<= pItem->sURL            ;
                        lProperties[OFFSET_TITLE            ].Value <<= pItem->sTitle          ;
                        lProperties[OFFSET_IMAGEIDENTIFIER  ].Value <<= pItem->sImageIdentifier;
                        lProperties[OFFSET_TARGETNAME       ].Value <<= pItem->sTargetName     ;
                    }
                    lResult[nStep] = lProperties;
                    ++nStep;
                }
                if( pList == &lSetupEntries )
                    pList = &lUserEntries;
                else
                    pList = NULL;
            }
            return lResult;
        }

    private:
        //---------------------------------------------------------------------------------------------------------
        // search for an entry named "ux" with x=[0..i] inside our menu
        // which has set highest number x. So we can add another user entry.
        sal_Int32 impl_getNextUserEntryNr() const
        {
            sal_Int32 nNr = 0;
            for( vector< SvtDynMenuEntry >::const_iterator pItem =lUserEntries.begin();
                                                     pItem!=lUserEntries.end()  ;
                                                     ++pItem                    )
            {
                if( pItem->sName.compareTo( PATHPREFIX_USER, 1 ) == 0 )
                {
                    OUString  sNr      = pItem->sName.copy( 1, pItem->sName.getLength()-1 );
                    sal_Int32 nCheckNr = sNr.toInt32();
                    if( nCheckNr > nNr )
                        nNr = nCheckNr;
                }
            }
            // Attention: Code isn't prepared for recyling of unused fragmented numbers!
            // If we reach end of sal_Int32 range ... we must stop further working ...
            // But I think nobody expand a menu to more then 1000 ... 100000 ... entries ... or?
            DBG_ASSERT( !(nNr>0x7fffffff), "Menu::impl_getNextUserEntryNr()\nUser count can be out of range next time ...\n" );
            return nNr;
        }

    private:
        vector< SvtDynMenuEntry > lSetupEntries;
        vector< SvtDynMenuEntry > lUserEntries ;
};

class SvtDynamicMenuOptions_Impl : public ConfigItem
{
	//-------------------------------------------------------------------------------------------------------------
	//	public methods
	//-------------------------------------------------------------------------------------------------------------

	public:

		//---------------------------------------------------------------------------------------------------------
		//	constructor / destructor
		//---------------------------------------------------------------------------------------------------------

         SvtDynamicMenuOptions_Impl();
        ~SvtDynamicMenuOptions_Impl();

		//---------------------------------------------------------------------------------------------------------
		//	overloaded methods of baseclass
		//---------------------------------------------------------------------------------------------------------

		/*-****************************************************************************************************//**
			@short		called for notify of configmanager
			@descr		These method is called from the ConfigManager before application ends or from the
			 			PropertyChangeListener if the sub tree broadcasts changes. You must update your
						internal values.

			@seealso	baseclass ConfigItem

            @param      "lPropertyNames" is the list of properties which should be updated.
			@return		-

			@onerror	-
		*//*-*****************************************************************************************************/

        virtual void Notify( const Sequence< OUString >& lPropertyNames );

		/*-****************************************************************************************************//**
			@short		write changes to configuration
			@descr		These method writes the changed values into the sub tree
						and should always called in our destructor to guarantee consistency of config data.

			@seealso	baseclass ConfigItem

			@param		-
			@return		-

			@onerror	-
		*//*-*****************************************************************************************************/

    	virtual void Commit();

		//---------------------------------------------------------------------------------------------------------
		//	public interface
		//---------------------------------------------------------------------------------------------------------

		/*-****************************************************************************************************//**
            @short      base implementation of public interface for "SvtDynamicMenuOptions"!
            @descr      These class is used as static member of "SvtDynamicMenuOptions" ...
						=> The code exist only for one time and isn't duplicated for every instance!

			@seealso	-

			@param		-
			@return		-

			@onerror	-
		*//*-*****************************************************************************************************/

        void                                    Clear       (           EDynamicMenuType    eMenu           );
        Sequence< Sequence< PropertyValue > >   GetMenu     (           EDynamicMenuType    eMenu           ) const ;
        void                                    AppendItem  (           EDynamicMenuType    eMenu           ,
                                                                const   OUString&           sURL            ,
                                                                const   OUString&           sTitle          ,
                                                                const   OUString&           sImageIdentifier,
                                                                const   OUString&           sTargetName     );

	//-------------------------------------------------------------------------------------------------------------
	//	private methods
	//-------------------------------------------------------------------------------------------------------------

	private:

		/*-****************************************************************************************************//**
            @short      return list of key names of our configuration management which represent oue module tree
			@descr		These methods return the current list of key names! We need it to get needed values from our
                        configuration management and support dynamical menu item lists!

			@seealso	-

            @param      "nNewCount"     ,   returns count of menu entries for "new"
            @param      "nWizardCount"  ,   returns count of menu entries for "wizard"
			@return		A list of configuration key names is returned.

			@onerror	-
		*//*-*****************************************************************************************************/

        Sequence< OUString > impl_GetPropertyNames( sal_uInt32& nNewCount, sal_uInt32& nWizardCount, sal_uInt32& nHelpBookmarksCount );

        /*-****************************************************************************************************//**
            @short      sort given source list and expand it for all well known properties to destination
            @descr      We must support sets of entries with count inside the name .. but some of them could be missing!
                        e.g. s1-s2-s3-s0-u1-s6-u5-u7
                        Then we must sort it by name and expand it to the follow one:
                            sSetNode/s0/URL
                            sSetNode/s0/Title
                            sSetNode/s0/...
                            sSetNode/s1/URL
                            sSetNode/s1/Title
                            sSetNode/s1/...
                            ...
                            sSetNode/s6/URL
                            sSetNode/s6/Title
                            sSetNode/s6/...
                            sSetNode/u1/URL
                            sSetNode/u1/Title
                            sSetNode/u1/...
                            ...
                            sSetNode/u7/URL
                            sSetNode/u7/Title
                            sSetNode/u7/...
                        Rules: We start with all setup written entries names "sx" and x=[0..n].
                        Then we handle all "ux" items. Inside these blocks we sort it ascending by number.

            @attention  We add these expanded list to the end of given "lDestination" list!
                        So we must start on "lDestination.getLength()".
                        Reallocation of memory of destination list is done by us!

            @seealso    method impl_GetPropertyNames()

            @param      "lSource"      ,   original list (e.g. [m1-m2-m3-m6-m0] )
            @param      "lDestination" ,   destination of operation
            @param      "sSetNode"     ,   name of configuration set to build complete path
			@return		A list of configuration key names is returned.

			@onerror	-
		*//*-*****************************************************************************************************/

        void impl_SortAndExpandPropertyNames( const Sequence< OUString >& lSource      ,
                                                    Sequence< OUString >& lDestination ,
                                              const OUString&             sSetNode     );

	//-------------------------------------------------------------------------------------------------------------
	//	private member
	//-------------------------------------------------------------------------------------------------------------

	private:

        SvtDynMenu  m_aNewMenu              ;
        SvtDynMenu  m_aWizardMenu           ;
        SvtDynMenu  m_aHelpBookmarksMenu    ;
};

//_________________________________________________________________________________________________________________
//	definitions
//_________________________________________________________________________________________________________________

//*****************************************************************************************************************
//	constructor
//*****************************************************************************************************************
SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl()
	// Init baseclasses first
    :   ConfigItem( ROOTNODE_MENUS )
	// Init member then...
{
    // Get names and values of all accessable menu entries and fill internal structures.
	// See impl_GetPropertyNames() for further informations.
    sal_uInt32              nNewCount           = 0;
    sal_uInt32              nWizardCount        = 0;
    sal_uInt32              nHelpBookmarksCount = 0;
    Sequence< OUString >    lNames              = impl_GetPropertyNames ( nNewCount           ,
                                                                          nWizardCount        ,
                                                                          nHelpBookmarksCount );
    Sequence< Any >         lValues             = GetProperties         ( lNames              );

	// Safe impossible cases.
	// We need values from ALL configuration keys.
	// Follow assignment use order of values in relation to our list of key names!
    DBG_ASSERT( !(lNames.getLength()!=lValues.getLength()), "SvtDynamicMenuOptions_Impl::SvtDynamicMenuOptions_Impl()\nI miss some values of configuration keys!\n" );

	// Copy values from list in right order to ouer internal member.
	// Attention: List for names and values have an internal construction pattern!
    //
    // first "New" menu ...
    //      Name                            Value
    //      /New/1/URL                      "private:factory/swriter"
    //      /New/1/Title                    "Neues Writer Dokument"
    //      /New/1/ImageIdentifier          "icon_writer"
    //      /New/1/TargetName               "_blank"
    //
    //      /New/2/URL                      "private:factory/scalc"
    //      /New/2/Title                    "Neues Calc Dokument"
    //      /New/2/ImageIdentifier          "icon_calc"
    //      /New/2/TargetName               "_blank"
    //
    // second "Wizard" menu ...
    //      /Wizard/1/URL                   "file://b"
    //      /Wizard/1/Title                 "MalWas"
    //      /Wizard/1/ImageIdentifier       "icon_?"
    //      /Wizard/1/TargetName            "_self"
    //
    //      ... and so on ...

    sal_uInt32  nItem     = 0 ;
    sal_uInt32  nPosition = 0 ;
    OUString    sName         ;

    // We must use these one instance object(!) to get information about installed modules.
    // These information are used to filter menu entries wich need not installed modules ...
    // Such entries shouldnt be available then!
    // see impl_IsEntrySupported() too
    SvtModuleOptions aModuleOptions;

    // Get names/values for new menu.
	// 4 subkeys for every item!
    for( nItem=0; nItem<nNewCount; ++nItem )
	{
        SvtDynMenuEntry   aItem                       ;
        lValues[nPosition] >>= aItem.sURL             ;
		++nPosition;
        lValues[nPosition] >>= aItem.sTitle           ;
		++nPosition;
        lValues[nPosition] >>= aItem.sImageIdentifier ;
		++nPosition;
        lValues[nPosition] >>= aItem.sTargetName      ;
		++nPosition;
        m_aNewMenu.AppendSetupEntry( aItem );
	}

	// Attention: Don't reset nPosition here!

    // Get names/values for wizard menu.
	// 4 subkeys for every item!
    for( nItem=0; nItem<nWizardCount; ++nItem )
	{
        SvtDynMenuEntry   aItem                       ;
        lValues[nPosition] >>= aItem.sURL             ;
		++nPosition;
        lValues[nPosition] >>= aItem.sTitle           ;
		++nPosition;
        lValues[nPosition] >>= aItem.sImageIdentifier ;
		++nPosition;
        lValues[nPosition] >>= aItem.sTargetName      ;
		++nPosition;
        m_aWizardMenu.AppendSetupEntry( aItem );
	}

	// Attention: Don't reset nPosition here!

	// Get names/values for wizard menu.
	// 4 subkeys for every item!
    for( nItem=0; nItem<nHelpBookmarksCount; ++nItem )
	{
        SvtDynMenuEntry   aItem                       ;
        lValues[nPosition] >>= aItem.sURL             ;
		++nPosition;
        lValues[nPosition] >>= aItem.sTitle           ;
		++nPosition;
        lValues[nPosition] >>= aItem.sImageIdentifier ;
		++nPosition;
        lValues[nPosition] >>= aItem.sTargetName      ;
		++nPosition;
        m_aHelpBookmarksMenu.AppendSetupEntry( aItem );
	}

/*TODO: Not used in the moment! see Notify() ...
	// Enable notification mechanism of ouer baseclass.
	// We need it to get information about changes outside these class on ouer used configuration keys!
    EnableNotification( lNames );
*/
}

//*****************************************************************************************************************
//	destructor
//*****************************************************************************************************************
SvtDynamicMenuOptions_Impl::~SvtDynamicMenuOptions_Impl()
{
	// We must save our current values .. if user forget it!
	if( IsModified() == sal_True )
	{
		Commit();
	}
}

//*****************************************************************************************************************
//	public method
//*****************************************************************************************************************
void SvtDynamicMenuOptions_Impl::Notify( const Sequence< OUString >& )
{
    DBG_ASSERT( sal_False, "SvtDynamicMenuOptions_Impl::Notify()\nNot implemented yet! I don't know how I can handle a dynamical list of unknown properties ...\n" );
}

//*****************************************************************************************************************
//	public method
//*****************************************************************************************************************
void SvtDynamicMenuOptions_Impl::Commit()
{
    DBG_ERROR( "SvtDynamicMenuOptions_Impl::Commit()\nNot implemented yet!\n" );
    /*
    // Write all properties!
    // Delete complete sets first.
    ClearNodeSet( SETNODE_NEWMENU    );
    ClearNodeSet( SETNODE_WIZARDMENU );
    ClearNodeSet( SETNODE_HELPBOOKMARKS );

    MenuEntry                    aItem                           ;
    OUString                    sNode                           ;
    Sequence< PropertyValue >   lPropertyValues( PROPERTYCOUNT );
    sal_uInt32                  nItem          = 0              ;

    // Copy "new" menu entries to save-list!
    sal_uInt32 nNewCount = m_aNewMenu.size();
    for( nItem=0; nItem<nNewCount; ++nItem )
	{
        aItem = m_aNewMenu[nItem];
        // Format:  "New/1/URL"
        //          "New/1/Title"
        //          ...
        sNode = SETNODE_NEWMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;

        lPropertyValues[OFFSET_URL             ].Name  =   sNode + PROPERTYNAME_URL             ;
        lPropertyValues[OFFSET_TITLE           ].Name  =   sNode + PROPERTYNAME_TITLE           ;
        lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name  =   sNode + PROPERTYNAME_IMAGEIDENTIFIER ;
        lPropertyValues[OFFSET_TARGETNAME      ].Name  =   sNode + PROPERTYNAME_TARGETNAME      ;

        lPropertyValues[OFFSET_URL             ].Value <<= aItem.sURL                           ;
        lPropertyValues[OFFSET_TITLE           ].Value <<= aItem.sTitle                         ;
        lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier               ;
        lPropertyValues[OFFSET_TARGETNAME      ].Value <<= aItem.sTargetName                    ;

        SetSetProperties( SETNODE_NEWMENU, lPropertyValues );
	}

    // Copy "wizard" menu entries to save-list!
    sal_uInt32 nWizardCount = m_aWizardMenu.size();
    for( nItem=0; nItem<nWizardCount; ++nItem )
	{
        aItem = m_aWizardMenu[nItem];
        // Format:  "Wizard/1/URL"
        //          "Wizard/1/Title"
        //          ...
        sNode = SETNODE_WIZARDMENU + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;

        lPropertyValues[OFFSET_URL             ].Name  =   sNode + PROPERTYNAME_URL             ;
        lPropertyValues[OFFSET_TITLE           ].Name  =   sNode + PROPERTYNAME_TITLE           ;
        lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name  =   sNode + PROPERTYNAME_IMAGEIDENTIFIER ;
        lPropertyValues[OFFSET_TARGETNAME      ].Name  =   sNode + PROPERTYNAME_TARGETNAME      ;

        lPropertyValues[OFFSET_URL             ].Value <<= aItem.sURL                           ;
        lPropertyValues[OFFSET_TITLE           ].Value <<= aItem.sTitle                         ;
        lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier               ;
        lPropertyValues[OFFSET_TARGETNAME      ].Value <<= aItem.sTargetName                    ;

        SetSetProperties( SETNODE_WIZARDMENU, lPropertyValues );
	}

	// Copy help bookmarks entries to save-list!
    sal_uInt32 nHelpBookmarksCount = m_aHelpBookmarksMenu.size();
    for( nItem=0; nItem<nHelpBookmarksCount; ++nItem )
	{
        aItem = m_aHelpBookmarksMenu[nItem];
        // Format:  "HelpBookmarks/1/URL"
        //          "HelpBookmarks/1/Title"
        //          ...
        sNode = SETNODE_HELPBOOKMARKS + PATHDELIMITER + PATHPREFIX + OUString::valueOf( (sal_Int32)nItem ) + PATHDELIMITER;

        lPropertyValues[OFFSET_URL             ].Name  =   sNode + PROPERTYNAME_URL             ;
        lPropertyValues[OFFSET_TITLE           ].Name  =   sNode + PROPERTYNAME_TITLE           ;
        lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Name  =   sNode + PROPERTYNAME_IMAGEIDENTIFIER ;
        lPropertyValues[OFFSET_TARGETNAME      ].Name  =   sNode + PROPERTYNAME_TARGETNAME      ;

        lPropertyValues[OFFSET_URL             ].Value <<= aItem.sURL                           ;
        lPropertyValues[OFFSET_TITLE           ].Value <<= aItem.sTitle                         ;
        lPropertyValues[OFFSET_IMAGEIDENTIFIER ].Value <<= aItem.sImageIdentifier               ;
        lPropertyValues[OFFSET_TARGETNAME      ].Value <<= aItem.sTargetName                    ;

        SetSetProperties( SETNODE_HELPBOOKMARKS, lPropertyValues );
	}
    */
}

//*****************************************************************************************************************
//	public method
//*****************************************************************************************************************
void SvtDynamicMenuOptions_Impl::Clear( EDynamicMenuType eMenu )
{
    switch( eMenu )
	{
        case E_NEWMENU      :   {
                                    m_aNewMenu.Clear();
                                    SetModified();
                                }
                                break;

        case E_WIZARDMENU   :   {
                                    m_aWizardMenu.Clear();
                                    SetModified();
                                }
                                break;

        case E_HELPBOOKMARKS :  {
                                    m_aHelpBookmarksMenu.Clear();
                                    SetModified();
                                }
                                break;
	}
}

//*****************************************************************************************************************
//	public method
//*****************************************************************************************************************
Sequence< Sequence< PropertyValue > > SvtDynamicMenuOptions_Impl::GetMenu( EDynamicMenuType eMenu ) const
{
    Sequence< Sequence< PropertyValue > > lReturn;
    switch( eMenu )
	{
        case E_NEWMENU      :   {
                                    lReturn = m_aNewMenu.GetList();
                                }
                                break;

        case E_WIZARDMENU   :   {
                                    lReturn = m_aWizardMenu.GetList();
                                }
                                break;

        case E_HELPBOOKMARKS :  {
                                    lReturn = m_aHelpBookmarksMenu.GetList();
                                }
                                break;
	}
    return lReturn;
}

//*****************************************************************************************************************
//	public method
//*****************************************************************************************************************
void SvtDynamicMenuOptions_Impl::AppendItem(            EDynamicMenuType    eMenu           ,
                                                const   OUString&           sURL            ,
                                                const   OUString&           sTitle          ,
                                                const   OUString&           sImageIdentifier,
                                                const   OUString&           sTargetName     )
{
    SvtDynMenuEntry aItem( sURL, sTitle, sImageIdentifier, sTargetName );

    switch( eMenu )
	{
        case E_NEWMENU  :   {
                                m_aNewMenu.AppendUserEntry( aItem );
								SetModified();
							}
							break;

        case E_WIZARDMENU   :   {
                                m_aWizardMenu.AppendUserEntry( aItem );
								SetModified();
							}
							break;

        case E_HELPBOOKMARKS :  {
                                m_aHelpBookmarksMenu.AppendUserEntry( aItem );
								SetModified();
							}
							break;
	}
}

//*****************************************************************************************************************
//	private method
//*****************************************************************************************************************
Sequence< OUString > SvtDynamicMenuOptions_Impl::impl_GetPropertyNames( sal_uInt32& nNewCount, sal_uInt32& nWizardCount, sal_uInt32& nHelpBookmarksCount )
{
	// First get ALL names of current existing list items in configuration!
    Sequence< OUString > lNewItems           = GetNodeNames( SETNODE_NEWMENU       );
    Sequence< OUString > lWizardItems        = GetNodeNames( SETNODE_WIZARDMENU    );
    Sequence< OUString > lHelpBookmarksItems = GetNodeNames( SETNODE_HELPBOOKMARKS );

	// Get information about list counts ...
    nNewCount           = lNewItems.getLength          ();
    nWizardCount        = lWizardItems.getLength       ();
    nHelpBookmarksCount = lHelpBookmarksItems.getLength();

    // Sort and expand all three list to result list ...
    Sequence< OUString > lProperties;
    impl_SortAndExpandPropertyNames( lNewItems          , lProperties, SETNODE_NEWMENU       );
    impl_SortAndExpandPropertyNames( lWizardItems       , lProperties, SETNODE_WIZARDMENU    );
    impl_SortAndExpandPropertyNames( lHelpBookmarksItems, lProperties, SETNODE_HELPBOOKMARKS );

	// Return result.
    return lProperties;
}

//*****************************************************************************************************************
//  private helper
//*****************************************************************************************************************
class CountWithPrefixSort
{
    public:
        int operator() ( const OUString& s1 ,
                         const OUString& s2 ) const
        {
            // Get order numbers from entry name without prefix.
            // e.g. "m10" => 10
            //      "m5"  => 5
            sal_Int32 n1 = s1.copy( 1, s1.getLength()-1 ).toInt32();
            sal_Int32 n2 = s2.copy( 1, s2.getLength()-1 ).toInt32();
            // MUST be in [0,1] ... because it's a difference between
            // insert-positions of given entries in sorted list!
            return( n1<n2 );
        }
};

class SelectByPrefix
{
    public:
        bool operator() ( const OUString& s ) const
        {
            // Prefer setup written entries by check first letter of given string. It must be a "s".
            return( s.indexOf( PATHPREFIX_SETUP ) == 0 );
        }
};

//*****************************************************************************************************************
//	private method
//*****************************************************************************************************************
void SvtDynamicMenuOptions_Impl::impl_SortAndExpandPropertyNames( const Sequence< OUString >& lSource      ,
                                                                        Sequence< OUString >& lDestination ,
                                                                  const OUString&             sSetNode     )
{
    OUString            sFixPath                                    ;
    vector< OUString >  lTemp                                       ;
    sal_Int32           nSourceCount     = lSource.getLength()      ;
    sal_Int32           nDestinationStep = lDestination.getLength() ; // start on end of current list ...!

    lDestination.realloc( (nSourceCount*PROPERTYCOUNT)+nDestinationStep ); // get enough memory for copy operations after nDestination ...

    // Copy all items to temp. vector to use fast sort operations :-)
    for( sal_Int32 nSourceStep=0; nSourceStep<nSourceCount; ++nSourceStep )
        lTemp.push_back( lSource[nSourceStep] );

    // Sort all entries by number ...
    stable_sort( lTemp.begin(), lTemp.end(), CountWithPrefixSort() );
    // and split into setup & user written entries!
    stable_partition( lTemp.begin(), lTemp.end(), SelectByPrefix() );

    // Copy sorted entries to destination and expand every item with
    // 4 supported sub properties.
    for( vector< OUString >::const_iterator pItem =lTemp.begin() ;
                                            pItem!=lTemp.end()   ;
                                            ++pItem              )
    {
        sFixPath  = sSetNode       ;
        sFixPath += PATHDELIMITER  ;
        sFixPath += *pItem         ;
        sFixPath += PATHDELIMITER  ;

        lDestination[nDestinationStep]  = sFixPath                      ;
        lDestination[nDestinationStep] += PROPERTYNAME_URL              ;
        ++nDestinationStep;
        lDestination[nDestinationStep]  = sFixPath                      ;
        lDestination[nDestinationStep] += PROPERTYNAME_TITLE            ;
        ++nDestinationStep;
        lDestination[nDestinationStep]  = sFixPath                      ;
        lDestination[nDestinationStep] += PROPERTYNAME_IMAGEIDENTIFIER  ;
        ++nDestinationStep;
        lDestination[nDestinationStep]  = sFixPath                      ;
        lDestination[nDestinationStep] += PROPERTYNAME_TARGETNAME       ;
        ++nDestinationStep;
    }
}

//*****************************************************************************************************************
//	initialize static member
//	DON'T DO IT IN YOUR HEADER!
//	see definition for further informations
//*****************************************************************************************************************
SvtDynamicMenuOptions_Impl*     SvtDynamicMenuOptions::m_pDataContainer = NULL  ;
sal_Int32                       SvtDynamicMenuOptions::m_nRefCount      = 0     ;

//*****************************************************************************************************************
//	constructor
//*****************************************************************************************************************
SvtDynamicMenuOptions::SvtDynamicMenuOptions()
{
    // Global access, must be guarded (multithreading!).
    MutexGuard aGuard( GetOwnStaticMutex() );
	// Increase ouer refcount ...
	++m_nRefCount;
	// ... and initialize ouer data container only if it not already exist!
    if( m_pDataContainer == NULL )
	{
        m_pDataContainer = new SvtDynamicMenuOptions_Impl;
        ItemHolder1::holdConfigItem(E_DYNAMICMENUOPTIONS);
	}
}

//*****************************************************************************************************************
//	destructor
//*****************************************************************************************************************
SvtDynamicMenuOptions::~SvtDynamicMenuOptions()
{
    // Global access, must be guarded (multithreading!)
    MutexGuard aGuard( GetOwnStaticMutex() );
	// Decrease ouer refcount.
	--m_nRefCount;
	// If last instance was deleted ...
	// we must destroy ouer static data container!
    if( m_nRefCount <= 0 )
	{
		delete m_pDataContainer;
		m_pDataContainer = NULL;
	}
}

//*****************************************************************************************************************
//	public method
//*****************************************************************************************************************
void SvtDynamicMenuOptions::Clear( EDynamicMenuType eMenu )
{
    MutexGuard aGuard( GetOwnStaticMutex() );
    m_pDataContainer->Clear( eMenu );
}

//*****************************************************************************************************************
//	public method
//*****************************************************************************************************************
Sequence< Sequence< PropertyValue > > SvtDynamicMenuOptions::GetMenu( EDynamicMenuType eMenu ) const
{
    MutexGuard aGuard( GetOwnStaticMutex() );
    return m_pDataContainer->GetMenu( eMenu );
}

//*****************************************************************************************************************
//	public method
//*****************************************************************************************************************
void SvtDynamicMenuOptions::AppendItem(         EDynamicMenuType    eMenu           ,
                                        const   OUString&           sURL            ,
                                        const   OUString&           sTitle          ,
                                        const   OUString&           sImageIdentifier,
                                        const   OUString&           sTargetName     )
{
    MutexGuard aGuard( GetOwnStaticMutex() );
    m_pDataContainer->AppendItem( eMenu, sURL, sTitle, sImageIdentifier, sTargetName );
}

//*****************************************************************************************************************
//	private method
//*****************************************************************************************************************
Mutex& SvtDynamicMenuOptions::GetOwnStaticMutex()
{
	// Initialize static mutex only for one time!
    static Mutex* pMutex = NULL;
	// If these method first called (Mutex not already exist!) ...
    if( pMutex == NULL )
    {
		// ... we must create a new one. Protect follow code with the global mutex -
		// It must be - we create a static variable!
        MutexGuard aGuard( Mutex::getGlobalMutex() );
		// We must check our pointer again - because it can be that another instance of ouer class will be fastr then these!
        if( pMutex == NULL )
        {
			// Create the new mutex and set it for return on static variable.
            static Mutex aMutex;
            pMutex = &aMutex;
        }
    }
	// Return new created or already existing mutex object.
    return *pMutex;
}
