/**************************************************************
 * 
 * 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_svtools.hxx"
#include <svtools/roadmap.hxx>

#ifndef _STRING_HXX
#define _STRING_HXX
#endif

#include <vector>
#include <algorithm>
#include <vcl/bitmap.hxx>
#include <tools/color.hxx>
#include <memory>

#define ROADMAP_INDENT_X        4
#define ROADMAP_INDENT_Y        27
#define ROADMAP_ITEM_DISTANCE_Y 6
#define RMINCOMPLETE        -1
#define NADDITEM            1
#define INCOMPLETELABEL     ::String::CreateFromAscii("...")        // TODO: Cast to String

//.........................................................................
namespace svt
{
//.........................................................................

    typedef std::vector< ::rtl::OUString > S_Vector;
    typedef std::vector< RoadmapItem* > HL_Vector;

	//=====================================================================
	//= ColorChanger
	//=====================================================================
	class IDLabel :  public FixedText
	{
	public:
		IDLabel( Window* _pParent, WinBits _nWinStyle = 0 );
		~IDLabel( );
		virtual void	DataChanged( const DataChangedEvent& rDCEvt );
	};

	//=====================================================================
	//= ColorChanger
	//=====================================================================
	class ColorChanger
	{
	protected:
		OutputDevice*	m_pDev;

	public:
		ColorChanger( OutputDevice* _pDev, const Color& _rNewLineColor, const Color& _rNewFillColor )
			:m_pDev( _pDev )
		{
			m_pDev->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
			m_pDev->SetLineColor( _rNewLineColor );
			m_pDev->SetFillColor( _rNewFillColor );
		}

		~ColorChanger()
		{
			m_pDev->Pop();
		}
	};

	//=====================================================================
	//= RoadmapItem
	//=====================================================================
	class RoadmapItem : public RoadmapTypes
	{
	private:
		IDLabel*                mpID;
		HyperLabel*             mpDescription;
        const Size              m_aItemPlayground;

	public:
		RoadmapItem( ORoadmap& _rParent, const Size& _rItemPlayground );
		~RoadmapItem( );
		
        void					SetID( sal_Int16 _ID );
        sal_Int16				GetID() const;

        void					SetIndex( ItemIndex _Index );
        ItemIndex               GetIndex() const;

        void					SetLabel( const ::rtl::OUString& _rText );
        ::rtl::OUString			GetLabel( );

		void					Update( ItemIndex _RMIndex, const ::rtl::OUString& _rText );
        
        void					SetPosition( RoadmapItem* OldHyperLabel );

		void					ToggleBackgroundColor( const Color& _rGBColor );
        void					SetInteractive( sal_Bool _bInteractive );

        void					SetClickHdl( const Link& rLink );
        const Link&				GetClickHdl() const;
		void					SetZOrder( RoadmapItem* pRefRoadmapHyperLabel, sal_uInt16 nFlags );
		void					Enable( sal_Bool bEnable = sal_True);
		sal_Bool					IsEnabled() const;
		void					GrabFocus();

        bool                    Contains( const Window* _pWindow ) const;
		
		HyperLabel*				GetDescriptionHyperLabel() const { return mpDescription; }

    private:
        void                    ImplUpdateIndex( const ItemIndex _nIndex );
        void                    ImplUpdatePosSize();
	};

	//=====================================================================
	//= RoadmapImpl
	//=====================================================================
    class RoadmapImpl : public RoadmapTypes
	{
	protected:
        const ORoadmap&     m_rAntiImpl;
        Link                m_aSelectHdl;
		BitmapEx	        m_aPicture;
        HL_Vector           m_aRoadmapSteps;
        ItemId              m_iCurItemID;
        sal_Bool            m_bInteractive;
        sal_Bool            m_bComplete;
        Size                m_aItemSizePixel;

	public:
        RoadmapImpl( const ORoadmap& _rAntiImpl )
            :m_rAntiImpl( _rAntiImpl )
            ,m_iCurItemID( -1 )
            ,m_bInteractive( sal_True )
            ,m_bComplete( sal_True )
        {
        }

        RoadmapItem* InCompleteHyperLabel;

        void			    addHyperLabel( RoadmapItem*  _rRoadmapStep ) { m_aRoadmapSteps.push_back(_rRoadmapStep); }

        HL_Vector&	        getHyperLabels() { return m_aRoadmapSteps; }
		const HL_Vector&	getHyperLabels() const { return m_aRoadmapSteps; }

        void                insertHyperLabel( ItemIndex _Index, RoadmapItem* _rRoadmapStep ) { m_aRoadmapSteps.insert( m_aRoadmapSteps.begin() + _Index, _rRoadmapStep ); }

        ItemIndex           getItemCount() const { return m_aRoadmapSteps.size();}

        void                setCurItemID( ItemId i ) {m_iCurItemID = i; }
        ItemId              getCurItemID() const { return m_iCurItemID; }

        void                setInteractive(const sal_Bool _bInteractive) {m_bInteractive = _bInteractive; }
        sal_Bool            isInteractive() const { return m_bInteractive; };

        void                setComplete(const sal_Bool _bComplete) {m_bComplete = _bComplete; }
        sal_Bool            isComplete() const { return m_bComplete; };

		void			    setPicture( const BitmapEx& _rPic ) { m_aPicture = _rPic; }
		const BitmapEx&	    getPicture( ) const { return m_aPicture; }

        void			    setSelectHdl( const Link& _rHdl ) { m_aSelectHdl = _rHdl; }
		const Link&	        getSelectHdl( ) const { return m_aSelectHdl; }

        void                initItemSize();
        const Size&         getItemSize() const { return m_aItemSizePixel; }

        void removeHyperLabel( ItemIndex _Index )
        {
            if ( ( _Index > -1 ) && ( _Index < getItemCount() ) )
            {
                delete m_aRoadmapSteps[_Index];
                m_aRoadmapSteps.erase( m_aRoadmapSteps.begin() + _Index);
            }
        }
	};


	//=====================================================================
	//= Roadmap
	//=====================================================================
	//---------------------------------------------------------------------
    void RoadmapImpl::initItemSize()
    {
        Size aLabelSize( m_rAntiImpl.GetOutputSizePixel() );
        aLabelSize.Height() = m_rAntiImpl.LogicToPixel( Size( 0, LABELBASEMAPHEIGHT ), MAP_APPFONT ).Height();
        aLabelSize.Width() -= m_rAntiImpl.LogicToPixel( Size( 2 * ROADMAP_INDENT_X, 0 ), MAP_APPFONT ).Width();
        m_aItemSizePixel = aLabelSize;
    }

	//=====================================================================
	//= Roadmap
	//=====================================================================
	//---------------------------------------------------------------------
	ORoadmap::ORoadmap( Window* _pParent, const ResId& _rId )
        :Control( _pParent, _rId )
		,m_pImpl( new RoadmapImpl( *this ) )
	{
		implInit();
	}

	//---------------------------------------------------------------------
	ORoadmap::ORoadmap( Window* _pParent, WinBits _nWinStyle )
		:Control( _pParent, _nWinStyle )
		,m_pImpl( new RoadmapImpl( *this ) )

    {
        implInit();
	}

	//---------------------------------------------------------------------
	void ORoadmap::implInit()
	{
		const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
		Color aTextColor = rStyleSettings.GetFieldTextColor();
        Font aFont = GetFont( );
		aFont.SetColor( aTextColor );
		aFont.SetWeight( WEIGHT_BOLD );
        aFont.SetUnderline( UNDERLINE_SINGLE );
		SetFont( aFont );
		SetBackground( Wallpaper( rStyleSettings.GetFieldColor() ) );
        m_pImpl->InCompleteHyperLabel = NULL;
        m_pImpl->setCurItemID(-1 );
        m_pImpl->setComplete( sal_True );

        // Roadmap control should be reachable as one unit with a Tab key
        // the next Tab key should spring out of the control.
        // To reach it the control itself should get focus and set it
        // on entries. The entries themself should not be reachable with
        // the Tab key directly. So each entry should have WB_NOTABSTOP.
        //
        // In other words the creator should create the control with the following
        // flags:
        // SetStyle( ( GetStyle() | WB_TABSTOP ) & ~WB_DIALOGCONTROL );

// TODO: if somebody sets a new font from outside (OutputDevice::SetFont), we would have to react
// on this with calculating a new bold font.
// Unfortunately, the OutputDevice does not offer a notify mechanism for a changed font.
// So settings the font from outside is simply a forbidded scenario at the moment
        EnableMapMode( sal_False );
	}

	//---------------------------------------------------------------------
	ORoadmap::~ORoadmap( )
	{
        HL_Vector aItemsCopy = m_pImpl->getHyperLabels();
        m_pImpl->getHyperLabels().clear();
        for ( HL_Vector::iterator i = aItemsCopy.begin(); i< aItemsCopy.end(); ++i )
        {
            delete *i;
        }
        if ( ! m_pImpl->isComplete() )
            delete m_pImpl->InCompleteHyperLabel;
		delete m_pImpl;
        m_pImpl = NULL;
    }


    RoadmapTypes::ItemId ORoadmap::GetCurrentRoadmapItemID() const
    {
        return m_pImpl->getCurItemID();
    }


	RoadmapItem* ORoadmap::GetPreviousHyperLabel( ItemIndex _Index)
	{
		RoadmapItem* pOldItem = NULL;
		if ( _Index > 0 )
			pOldItem = m_pImpl->getHyperLabels().at( _Index - 1 );
		return pOldItem;
	}


   	//---------------------------------------------------------------------

    RoadmapItem* ORoadmap::InsertHyperLabel( ItemIndex _Index, const ::rtl::OUString& _sLabel, ItemId _RMID, sal_Bool _bEnabled)
    {
        if ( m_pImpl->getItemCount() == 0 )
            m_pImpl->initItemSize();

        RoadmapItem* pItem = NULL;
        RoadmapItem* pOldItem = GetPreviousHyperLabel( _Index );

        pItem = new RoadmapItem( *this, m_pImpl->getItemSize() );
        if ( _RMID != RMINCOMPLETE )
        {
            pItem->SetInteractive( m_pImpl->isInteractive() );
            m_pImpl->insertHyperLabel( _Index, pItem );
        }
        else
        {
            pItem->SetInteractive( sal_False );
		}
        pItem->SetPosition( pOldItem );
        pItem->Update( _Index, _sLabel );
        pItem->SetClickHdl(LINK( this, ORoadmap, ImplClickHdl ) );
        pItem->SetID( _RMID );
        pItem->SetIndex( _Index );
        if (!_bEnabled)
            pItem->Enable( _bEnabled );
        return pItem;
    }

	//---------------------------------------------------------------------
	void ORoadmap::SetRoadmapBitmap( const BitmapEx& _rBmp, sal_Bool _bInvalidate )
	{
		m_pImpl->setPicture( _rBmp );
		if ( _bInvalidate )
			Invalidate( );
	}

	//---------------------------------------------------------------------
	const BitmapEx& ORoadmap::GetRoadmapBitmap( ) const
	{
		return m_pImpl->getPicture( );
	}

	//---------------------------------------------------------------------
    void ORoadmap::SetRoadmapInteractive( sal_Bool _bInteractive )
    {
        m_pImpl->setInteractive( _bInteractive );

        const HL_Vector& rItems = m_pImpl->getHyperLabels();
        for (   HL_Vector::const_iterator i = rItems.begin();
                i < rItems.end();
                ++i
            )
        {
            (*i)->SetInteractive( _bInteractive );
        }
    }

	//---------------------------------------------------------------------
    sal_Bool ORoadmap::IsRoadmapInteractive()
    {
        return m_pImpl->isInteractive();
    }

	//---------------------------------------------------------------------
    void ORoadmap::SetRoadmapComplete( sal_Bool _bComplete )
    {
        sal_Bool bWasComplete = m_pImpl->isComplete();
        m_pImpl->setComplete( _bComplete );
        if ( _bComplete )
        {
            if ( m_pImpl->InCompleteHyperLabel != NULL)
            {
                delete m_pImpl->InCompleteHyperLabel;
                m_pImpl->InCompleteHyperLabel = NULL;
            }
        }
        else if ( bWasComplete )
            m_pImpl->InCompleteHyperLabel = InsertHyperLabel( m_pImpl->getItemCount(), ::String::CreateFromAscii( "..." ), RMINCOMPLETE );
    }

	//---------------------------------------------------------------------
    void ORoadmap::UpdatefollowingHyperLabels( ItemIndex _nIndex )
    {
        const HL_Vector& rItems = m_pImpl->getHyperLabels();
        if ( _nIndex < (ItemIndex)rItems.size() )
        {
            RoadmapItem* pItem = NULL;
            for (   HL_Vector::const_iterator i = rItems.begin() + _nIndex;
                    i< rItems.end();
                    ++i, ++_nIndex
                )
            {
                pItem = *i;

                pItem->SetIndex( _nIndex );
                pItem->SetPosition( GetPreviousHyperLabel( _nIndex ) );
            }
        }
        if ( ! m_pImpl->isComplete() )
        {
	        RoadmapItem* pOldItem = GetPreviousHyperLabel( m_pImpl->getItemCount() );
            m_pImpl->InCompleteHyperLabel->SetPosition( pOldItem );
            m_pImpl->InCompleteHyperLabel->Update( m_pImpl->getItemCount(), ::String::CreateFromAscii("...") );
        }
    }

	//---------------------------------------------------------------------
    void ORoadmap::ReplaceRoadmapItem( ItemIndex _Index, const ::rtl::OUString& _RoadmapItem, ItemId _RMID, sal_Bool _bEnabled )
    {
        RoadmapItem* pItem = GetByIndex( _Index);
        if ( pItem != NULL )
        {
            pItem->Update( _Index,  _RoadmapItem );
            pItem->SetID( _RMID );
            pItem->Enable( _bEnabled );
        }
    }

	//---------------------------------------------------------------------
    RoadmapTypes::ItemIndex ORoadmap::GetItemCount() const
    {
        return m_pImpl->getItemCount();
    }

	//---------------------------------------------------------------------
    RoadmapTypes::ItemId ORoadmap::GetItemID( ItemIndex _nIndex ) const
    {
        const RoadmapItem* pHyperLabel = GetByIndex( _nIndex );
        if ( pHyperLabel )
            return pHyperLabel->GetID();
        return -1;
    }

	//---------------------------------------------------------------------
    RoadmapTypes::ItemIndex ORoadmap::GetItemIndex( ItemId _nID ) const
    {
        ItemId nLocID = 0;
        const HL_Vector& rItems = m_pImpl->getHyperLabels();
        for (   HL_Vector::const_iterator i = rItems.begin();
                i < rItems.end();
                ++i
            )
        {
            nLocID = (*i)->GetID();
            if ( nLocID == _nID )
                return ItemIndex( i - rItems.begin() );
        }
        return -1;
    }

	//---------------------------------------------------------------------
    void ORoadmap::InsertRoadmapItem( ItemIndex _Index, const ::rtl::OUString& _RoadmapItem, ItemId _nUniqueId, sal_Bool _bEnabled )
    {
        InsertHyperLabel( _Index, _RoadmapItem, _nUniqueId, _bEnabled );
            // Todo: YPos is superfluous, if items are always appended
        UpdatefollowingHyperLabels( _Index + 1 );
    }

	//---------------------------------------------------------------------
    void ORoadmap::DeleteRoadmapItem( ItemIndex _Index )
    {
        if ( m_pImpl->getItemCount() > 0 && ( _Index > -1)  &&  ( _Index < m_pImpl->getItemCount() ) )
        {
            m_pImpl->removeHyperLabel( _Index );
            UpdatefollowingHyperLabels( _Index );
        }
    }

	//---------------------------------------------------------------------
    sal_Bool ORoadmap::IsRoadmapComplete( ) const
    {
        return m_pImpl->isComplete();
    }

	//---------------------------------------------------------------------
    sal_Bool ORoadmap::IsRoadmapItemEnabled( ItemId _nItemId, ItemIndex _nStartIndex  ) const
    {
        const RoadmapItem* _pLabelItem = GetByID( _nItemId, _nStartIndex  );
        return _pLabelItem ? _pLabelItem->IsEnabled() : sal_False;
    }

	//---------------------------------------------------------------------
    void ORoadmap::EnableRoadmapItem( ItemId _nItemId, sal_Bool _bEnable, ItemIndex _nStartIndex )
    {
        RoadmapItem* pItem = GetByID( _nItemId, _nStartIndex );
        if ( pItem != NULL )
            pItem->Enable( _bEnable );
    }

	//---------------------------------------------------------------------
    void ORoadmap::ChangeRoadmapItemLabel( ItemId _nID, const ::rtl::OUString& _sLabel, ItemIndex _nStartIndex )
    {
        RoadmapItem* pItem = GetByID( _nID, _nStartIndex );
        if ( pItem != NULL )
		{
            pItem->Update( pItem->GetIndex(), _sLabel );

            const HL_Vector& rItems = m_pImpl->getHyperLabels();
			for (   HL_Vector::const_iterator i = rItems.begin() + _nStartIndex;
                    i < rItems.end();
                    ++i
                )
			{
				(*i)->SetPosition( GetPreviousHyperLabel( i - rItems.begin() ) );
			}
		}
    }

	//---------------------------------------------------------------------

    ::rtl::OUString ORoadmap::GetRoadmapItemLabel( ItemId _nID, ItemIndex _nStartIndex )
    {
        RoadmapItem* pItem = GetByID( _nID, _nStartIndex );
        if ( pItem != NULL )
            return pItem->GetLabel();
        else
            return ::rtl::OUString();
    }

	//---------------------------------------------------------------------
    void ORoadmap::ChangeRoadmapItemID( ItemId _nID, ItemId _NewID, ItemIndex _nStartIndex )
    {
        RoadmapItem* pItem = GetByID( _nID, _nStartIndex );
        if ( pItem != NULL )
            pItem->SetID( _NewID );
    }

	//---------------------------------------------------------------------
    RoadmapItem* ORoadmap::GetByID( ItemId _nID, ItemIndex _nStartIndex)
    {
        ItemId nLocID = 0;
        const HL_Vector& rItems = m_pImpl->getHyperLabels();
        for (   HL_Vector::const_iterator i = rItems.begin() + _nStartIndex;
                i < rItems.end();
                ++i
            )
        {
            nLocID = (*i)->GetID();
            if ( nLocID == _nID )
                return *i;
        }
        return NULL;
    }

	//---------------------------------------------------------------------
    const RoadmapItem* ORoadmap::GetByID( ItemId _nID, ItemIndex _nStartIndex  ) const
    {
        return const_cast< ORoadmap* >( this )->GetByID( _nID, _nStartIndex );
    }

	//---------------------------------------------------------------------
    RoadmapItem* ORoadmap::GetByIndex( ItemIndex _nItemIndex)
    {
        const HL_Vector& rItems = m_pImpl->getHyperLabels();
        if ( ( _nItemIndex > -1 ) && ( _nItemIndex < (ItemIndex)rItems.size() ) )
        {
            return rItems.at( _nItemIndex );
        }
        return NULL;
    }

    //---------------------------------------------------------------------
    const RoadmapItem* ORoadmap::GetByIndex( ItemIndex _nItemIndex ) const
    {
        return const_cast< ORoadmap* >( this )->GetByIndex( _nItemIndex );
    }

	//---------------------------------------------------------------------
    RoadmapTypes::ItemId ORoadmap::GetNextAvailableItemId( ItemIndex _nNewIndex )
    {
        RoadmapItem* pItem = NULL;

        ItemIndex searchIndex = ++_nNewIndex;
        while ( searchIndex < m_pImpl->getItemCount() )
        {
            pItem = GetByIndex( searchIndex );
            if ( pItem->IsEnabled() )
                return pItem->GetID( );

            ++searchIndex;
        }
        return -1;
    }

	//---------------------------------------------------------------------
    RoadmapTypes::ItemId ORoadmap::GetPreviousAvailableItemId( ItemIndex _nNewIndex )
    {
        RoadmapItem* pItem = NULL;
        ItemIndex searchIndex = --_nNewIndex;
        while ( searchIndex > -1 )
        {
            pItem = GetByIndex( searchIndex );
            if ( pItem->IsEnabled() )
                return pItem->GetID( );

            searchIndex--;
        }
        return -1;
    }

	//---------------------------------------------------------------------
    void ORoadmap::DeselectOldRoadmapItems()
    {
        const HL_Vector& rItems = m_pImpl->getHyperLabels();
        for (   HL_Vector::const_iterator i = rItems.begin();
                i < rItems.end();
                ++i
            )
        {
            (*i)->ToggleBackgroundColor( COL_TRANSPARENT );
        }
    }

	//---------------------------------------------------------------------
    void ORoadmap::SetItemSelectHdl( const Link& _rHdl )
    {
        m_pImpl->setSelectHdl( _rHdl );
    }

	//---------------------------------------------------------------------
    Link ORoadmap::GetItemSelectHdl( ) const
    {
        return m_pImpl->getSelectHdl();
    }

	//---------------------------------------------------------------------
    void ORoadmap::Select()
    {
        GetItemSelectHdl().Call( this );
        CallEventListeners( VCLEVENT_ROADMAP_ITEMSELECTED );
    }

    //---------------------------------------------------------------------
    void ORoadmap::GetFocus()
	{
        RoadmapItem* pCurHyperLabel = GetByID( GetCurrentRoadmapItemID() );
        if ( pCurHyperLabel != NULL )
		    pCurHyperLabel->GrabFocus();
	}

	//---------------------------------------------------------------------
    sal_Bool ORoadmap::SelectRoadmapItemByID( ItemId _nNewID )
    {
        DeselectOldRoadmapItems();
        RoadmapItem* pItem = GetByID( _nNewID );
        if ( pItem != NULL )
        {
            if ( pItem->IsEnabled() )
            {
				const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
                pItem->ToggleBackgroundColor( rStyleSettings.GetHighlightColor() ); //HighlightColor

				pItem->GrabFocus();
                m_pImpl->setCurItemID(_nNewID);

                Select();
                return sal_True;
            }
        }
        return sal_False;
    }

	//---------------------------------------------------------------------
	void ORoadmap::Paint( const Rectangle& _rRect )
	{
		Control::Paint( _rRect );


		// draw the bitmap
		if ( !!m_pImpl->getPicture() )
		{
			Size aBitmapSize = m_pImpl->getPicture().GetSizePixel();
			Size aMySize = GetOutputSizePixel();

			Point aBitmapPos( aMySize.Width() - aBitmapSize.Width(),  aMySize.Height() - aBitmapSize.Height() );

			// draw it
			DrawBitmapEx( aBitmapPos, m_pImpl->getPicture() );
		}

        //.................................................................
		// draw the headline
        DrawHeadline();
	}

	//---------------------------------------------------------------------
    void ORoadmap::DrawHeadline()
	{
		Point aTextPos = LogicToPixel( Point( ROADMAP_INDENT_X, 8 ), MAP_APPFONT );

		Size aOutputSize( GetOutputSizePixel() );

		// draw it
		DrawText( Rectangle( aTextPos, aOutputSize ), GetText(), TEXT_DRAW_LEFT | TEXT_DRAW_TOP | TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );
        DrawTextLine( aTextPos, aOutputSize.Width(), STRIKEOUT_NONE, UNDERLINE_SINGLE, UNDERLINE_NONE, sal_False );
		const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
        SetLineColor( rStyleSettings.GetFieldTextColor());
		SetTextColor(rStyleSettings.GetFieldTextColor());
	}

	//---------------------------------------------------------------------
    RoadmapItem* ORoadmap::GetByPointer(Window* pWindow)
    {
        const HL_Vector& rItems = m_pImpl->getHyperLabels();
        for (   HL_Vector::const_iterator i = rItems.begin();
                i < rItems.end();
                ++i
            )
        {
			if ( (*i)->Contains( pWindow ) )
                return *i;
        }
        return NULL;
    }

	//---------------------------------------------------------------------
    long ORoadmap::PreNotify( NotifyEvent& _rNEvt )
    {
        // capture KeyEvents for taskpane cycling
        if ( _rNEvt.GetType() == EVENT_KEYINPUT )
        {
            Window* pWindow = _rNEvt.GetWindow();
            RoadmapItem* pItem = GetByPointer( pWindow );
            if ( pItem != NULL )
            {
                sal_Int16 nKeyCode = _rNEvt.GetKeyEvent()->GetKeyCode().GetCode();
		        switch( nKeyCode )
		        {
			        case KEY_UP:
                        {   // Note: Performancewise this is not optimal, because we search for an ID in the labels
                            //       and afterwards we search again for a label with the appropriate ID ->
                            //       unnecessarily we search twice!!!
                            ItemId nPrevItemID = GetPreviousAvailableItemId( pItem->GetIndex() );
                            if ( nPrevItemID != -1 )
                                return SelectRoadmapItemByID( nPrevItemID );
                        }
                        break;
			        case KEY_DOWN:
                        {
                            ItemId nNextItemID = GetNextAvailableItemId( pItem->GetIndex() );
                            if ( nNextItemID != -1 )
                                return SelectRoadmapItemByID( nNextItemID );
                        }
                        break;
                    case KEY_SPACE:
                        return SelectRoadmapItemByID( pItem->GetID() );
                }
            }
        }
        return Window::PreNotify( _rNEvt );
    }

	//---------------------------------------------------------------------
  	IMPL_LINK(ORoadmap, ImplClickHdl, HyperLabel*, _CurHyperLabel)
	{
       return SelectRoadmapItemByID( _CurHyperLabel->GetID() );
    }



    //---------------------------------------------------------------------
	void ORoadmap::DataChanged( const DataChangedEvent& rDCEvt )
	{
		if ((( rDCEvt.GetType() == DATACHANGED_SETTINGS	)	||
			( rDCEvt.GetType() == DATACHANGED_DISPLAY	))	&&
			( rDCEvt.GetFlags() & SETTINGS_STYLE		))
		{
			const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
			SetBackground( Wallpaper( rStyleSettings.GetFieldColor() ) );
			Color aTextColor = rStyleSettings.GetFieldTextColor();
			Font aFont = GetFont();
			aFont.SetColor( aTextColor );
			SetFont( aFont );
			RoadmapTypes::ItemId curItemID = GetCurrentRoadmapItemID();
			RoadmapItem* pLabelItem = GetByID( curItemID );
            if ( pLabelItem != NULL )
                pLabelItem->ToggleBackgroundColor(rStyleSettings.GetHighlightColor());
			Invalidate();
		}
	}


    //---------------------------------------------------------------------
    RoadmapItem::RoadmapItem( ORoadmap& _rParent, const Size& _rItemPlayground )
        :m_aItemPlayground( _rItemPlayground )
	{
		mpID = new IDLabel( &_rParent, WB_WORDBREAK );
		mpID->SetTextColor( mpID->GetSettings().GetStyleSettings().GetFieldTextColor( ) );
        mpID->Show();
		mpDescription = new HyperLabel( &_rParent, WB_NOTABSTOP | WB_WORDBREAK );
        mpDescription->Show();
	}

    //---------------------------------------------------------------------
    bool RoadmapItem::Contains( const Window* _pWindow ) const
    {
        return ( mpID == _pWindow ) || ( mpDescription == _pWindow );
    }

    //---------------------------------------------------------------------
    void RoadmapItem::GrabFocus()
	{
        if ( mpDescription )
            mpDescription->GrabFocus();
	}

    //---------------------------------------------------------------------
	void RoadmapItem::SetInteractive( sal_Bool _bInteractive )
	{
        if ( mpDescription )
		mpDescription->SetInteractive(_bInteractive);
	}

    //---------------------------------------------------------------------
	void RoadmapItem::SetID( sal_Int16 _ID )
	{
        if ( mpDescription )
		    mpDescription->SetID(_ID);
	}

    //---------------------------------------------------------------------
	sal_Int16 RoadmapItem::GetID() const
	{
        return mpDescription ? mpDescription->GetID() : sal_Int16(-1);
	}

    //---------------------------------------------------------------------
    void RoadmapItem::ImplUpdateIndex( const ItemIndex _nIndex )
    {
        if ( mpDescription )
		    mpDescription->SetIndex( _nIndex );

        if ( mpID )
        {
            ::rtl::OUString aIDText = ::rtl::OUString::valueOf( (sal_Int32)( _nIndex + 1 ) ) +  ::rtl::OUString::createFromAscii( "." );
 		    mpID->SetText( aIDText );
        }

        // update the geometry of both controls
        ImplUpdatePosSize();
    }

    //---------------------------------------------------------------------
	void RoadmapItem::SetIndex( ItemIndex _Index )
	{
        ImplUpdateIndex( _Index );
	}

    //---------------------------------------------------------------------
    RoadmapTypes::ItemIndex RoadmapItem::GetIndex() const
	{
        return mpDescription ? mpDescription->GetIndex() : ItemIndex(-1);
	}

    //---------------------------------------------------------------------
	void RoadmapItem::SetLabel( const ::rtl::OUString& _rText )
	{
        if ( mpDescription )
		    mpDescription->SetText(_rText);
	}

    //---------------------------------------------------------------------
	::rtl::OUString RoadmapItem::GetLabel( )
	{
        return mpDescription ? mpDescription->GetText() : String();
	}

    //---------------------------------------------------------------------
	void RoadmapItem::SetPosition( RoadmapItem* _pOldItem )
	{
		Point aIDPos;
		if ( _pOldItem == NULL )
		{
			aIDPos = mpID->LogicToPixel( Point( ROADMAP_INDENT_X, ROADMAP_INDENT_Y ), MAP_APPFONT );
		}
		else
		{
			Size aOldSize = _pOldItem->GetDescriptionHyperLabel()->GetSizePixel();

            aIDPos = _pOldItem->mpID->GetPosPixel();
            aIDPos.Y() += aOldSize.Height();
            aIDPos.Y() += mpID->GetParent()->LogicToPixel( Size( 0, ROADMAP_ITEM_DISTANCE_Y ) ).Height();
		}
		mpID->SetPosPixel( aIDPos );

		sal_Int32 nDescPos = aIDPos.X() + mpID->GetSizePixel().Width();
		mpDescription->SetPosPixel( Point( nDescPos, aIDPos.Y() ) );
	}

    //---------------------------------------------------------------------
	void RoadmapItem::SetZOrder( RoadmapItem* pRefRoadmapHyperLabel, sal_uInt16 nFlags )
	{
		if (pRefRoadmapHyperLabel == NULL)
			mpDescription->SetZOrder( NULL, nFlags); //WINDOW_ZORDER_FIRST );
		else
			mpDescription->SetZOrder( pRefRoadmapHyperLabel->mpDescription, nFlags); //, WINDOW_ZORDER_BEHIND );
	}

    //---------------------------------------------------------------------
	void RoadmapItem::Enable( sal_Bool _bEnable)
	{
		mpID->Enable(_bEnable);
		mpDescription->Enable(_bEnable);
	}

    //---------------------------------------------------------------------
	sal_Bool RoadmapItem::IsEnabled() const
	{
		return mpID->IsEnabled();
	}

    //---------------------------------------------------------------------
	void RoadmapItem::ToggleBackgroundColor( const Color& _rGBColor )
	{
		if (_rGBColor == COL_TRANSPARENT)
		{
			mpID->SetTextColor( mpID->GetSettings().GetStyleSettings().GetFieldTextColor( ) );
			mpID->SetControlBackground( COL_TRANSPARENT );
		}
		else
		{
			mpID->SetControlBackground( mpID->GetSettings().GetStyleSettings().GetHighlightColor() );
			mpID->SetTextColor( mpID->GetSettings().GetStyleSettings().GetHighlightTextColor( ) );
		}
		mpDescription->ToggleBackgroundColor(_rGBColor);
	}

    //---------------------------------------------------------------------
    void RoadmapItem::ImplUpdatePosSize()
    {
        // calculate widths
        long nIDWidth = mpID->GetTextWidth( mpID->GetText() );
		long nMaxIDWidth = mpID->GetTextWidth( ::rtl::OUString::createFromAscii( "100." ) );
		nIDWidth = ::std::min( nIDWidth, nMaxIDWidth );

        // check how many space the description would need
        Size aDescriptionSize = mpDescription->CalcMinimumSize( m_aItemPlayground.Width() - nIDWidth );

        // position and size both controls
        Size aIDSize( nIDWidth, aDescriptionSize.Height() );
 		mpID->SetSizePixel( aIDSize );

        Point aIDPos = mpID->GetPosPixel();
        mpDescription->SetPosPixel( Point( aIDPos.X() + nIDWidth, aIDPos.Y() ) );
        mpDescription->SetSizePixel( aDescriptionSize );
    }

    //---------------------------------------------------------------------
	void RoadmapItem::Update( ItemIndex _RMIndex, const ::rtl::OUString& _rText )
	{
        // update description label
        mpDescription->SetLabel( _rText );

        // update the index in both controls, which triggers updating the geometry of both
        ImplUpdateIndex( _RMIndex );
	}

    //---------------------------------------------------------------------
	RoadmapItem::~RoadmapItem( )
	{
        {
            ::std::auto_ptr<Control> aTemp(mpID);
		    mpID = NULL;
        }
        {
            ::std::auto_ptr<Control> aTemp(mpDescription);
		    mpDescription = NULL;
        }
	}

    //---------------------------------------------------------------------
	void RoadmapItem::SetClickHdl( const Link& rLink )
	{
        if ( mpDescription )
		    mpDescription->SetClickHdl( rLink);
	}

    //---------------------------------------------------------------------
	const Link& RoadmapItem::GetClickHdl( ) const
	{
		return mpDescription->GetClickHdl();
	}

	//---------------------------------------------------------------------
    IDLabel::IDLabel( Window* _pParent, WinBits _nWinStyle )
		:FixedText( _pParent, _nWinStyle )
	{

	}

	//---------------------------------------------------------------------
	IDLabel::~IDLabel( )
	{
	}

	//---------------------------------------------------------------------
	void IDLabel::DataChanged( const DataChangedEvent& rDCEvt )
	{
		const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
		FixedText::DataChanged( rDCEvt );
		if ((( rDCEvt.GetType() == DATACHANGED_SETTINGS	)	||
			( rDCEvt.GetType() == DATACHANGED_DISPLAY	))	&&
			( rDCEvt.GetFlags() & SETTINGS_STYLE		))
		{
			const Color& rGBColor = GetControlBackground();
			if (rGBColor == COL_TRANSPARENT)
				SetTextColor( rStyleSettings.GetFieldTextColor( ) );
			else
			{
				SetControlBackground(rStyleSettings.GetHighlightColor());
				SetTextColor( rStyleSettings.GetHighlightTextColor( ) );
			}
			Invalidate();
		}
	}




//.........................................................................
}	// namespace svt
//.........................................................................
