/**************************************************************
 * 
 * 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_sc.hxx"


#include <vcl/svapp.hxx>
#include <vcl/taskpanelist.hxx>

#include "olinewin.hxx"
#include "olinetab.hxx"
#include "document.hxx"
#include "dbfunc.hxx"
#include "sc.hrc"

// ============================================================================

const long SC_OL_BITMAPSIZE                 = 12;
const long SC_OL_POSOFFSET                  = 2;

const size_t SC_OL_NOLEVEL                  = static_cast< size_t >( -1 );
const size_t SC_OL_HEADERENTRY              = static_cast< size_t >( -1 );

const sal_uInt16 SC_OL_IMAGE_PLUS               = 9;
const sal_uInt16 SC_OL_IMAGE_MINUS              = SC_OL_IMAGE_PLUS + 1;
const sal_uInt16 SC_OL_IMAGE_NOTPRESSED         = SC_OL_IMAGE_MINUS + 1;
const sal_uInt16 SC_OL_IMAGE_PRESSED            = SC_OL_IMAGE_NOTPRESSED + 1;

// ============================================================================

ScOutlineWindow::ScOutlineWindow( Window* pParent, ScOutlineMode eMode, ScViewData* pViewData, ScSplitPos eWhich ) :
	Window( pParent ),
    mrViewData( *pViewData ),
    meWhich( eWhich ),
    mbHoriz( eMode == SC_OUTLINE_HOR ),
    mbMirrorEntries( false ),           // updated in SetHeaderSize
    mbMirrorLevels( false ),            // updated in SetHeaderSize
    mpSymbols( NULL ),
    maLineColor( COL_BLACK ),
    mnHeaderSize( 0 ),
    mnHeaderPos( 0 ),
    mnMainFirstPos( 0 ),
    mnMainLastPos( 0 ),
    mbMTActive( false ),
    mbMTPressed( false ),
    mnFocusLevel( 0 ),
    mnFocusEntry( SC_OL_HEADERENTRY ),
    mbDontDrawFocus( false )
{
    EnableRTL( sal_False );                 // mirroring is done manually

    InitSettings();
    maFocusRect.SetEmpty();
    SetHeaderSize( 0 );

    // insert the window into task pane list for "F6 cycling"
    if( SystemWindow* pSysWin = GetSystemWindow() )
        if( TaskPaneList* pTaskPaneList = pSysWin->GetTaskPaneList() )
            pTaskPaneList->AddWindow( this );
}

ScOutlineWindow::~ScOutlineWindow()
{
    // remove the window from task pane list
    if( SystemWindow* pSysWin = GetSystemWindow() )
        if( TaskPaneList* pTaskPaneList = pSysWin->GetTaskPaneList() )
            pTaskPaneList->RemoveWindow( this );
}

void ScOutlineWindow::SetHeaderSize( long nNewSize )
{
    sal_Bool bLayoutRTL = GetDoc().IsLayoutRTL( GetTab() );
    mbMirrorEntries = bLayoutRTL && mbHoriz;
    mbMirrorLevels = bLayoutRTL && !mbHoriz;

    bool bNew = (nNewSize != mnHeaderSize);
    mnHeaderSize = nNewSize;
    mnHeaderPos = mbMirrorEntries ? (GetOutputSizeEntry() - mnHeaderSize) : 0;
    mnMainFirstPos = mbMirrorEntries ? 0 : mnHeaderSize;
    mnMainLastPos = GetOutputSizeEntry() - (mbMirrorEntries ? mnHeaderSize : 0) - 1;
    if ( bNew )
        Invalidate();
}

long ScOutlineWindow::GetDepthSize() const
{
    long nSize = GetLevelCount() * SC_OL_BITMAPSIZE;
    if ( nSize > 0 )
        nSize += 2 * SC_OL_POSOFFSET + 1;
    return nSize;
}

void ScOutlineWindow::ScrollPixel( long nDiff )
{
    HideFocus();
    mbDontDrawFocus = true;

    long nStart = mnMainFirstPos;
    long nEnd = mnMainLastPos;

    long nInvStart, nInvEnd;
    if (nDiff < 0)
    {
        nStart -= nDiff;
        nInvStart = nEnd + nDiff;
        nInvEnd = nEnd;
    }
    else
    {
        nEnd -= nDiff;
        nInvStart = nStart;
        nInvEnd = nStart + nDiff;
    }

    ScrollRel( nDiff, nStart, nEnd );
    Invalidate( GetRectangle( 0, nInvStart, GetOutputSizeLevel() - 1, nInvEnd ) );
    Update();

    // if focus becomes invisible, move it to next visible button
    ImplMoveFocusToVisible( nDiff < 0 );

    mbDontDrawFocus = false;
    ShowFocus();
}

void ScOutlineWindow::ScrollRel( long nEntryDiff, long nEntryStart, long nEntryEnd )
{
    Rectangle aRect( GetRectangle( 0, nEntryStart, GetOutputSizeLevel() - 1, nEntryEnd ) );
    if ( mbHoriz )
        Scroll( nEntryDiff, 0, aRect );
    else
        Scroll( 0, nEntryDiff, aRect );
}

// internal -------------------------------------------------------------------

void ScOutlineWindow::InitSettings()
{
    const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
    SetBackground( rStyleSettings.GetFaceColor() );
    maLineColor = rStyleSettings.GetButtonTextColor();
    mpSymbols = ScGlobal::GetOutlineSymbols( rStyleSettings.GetHighContrastMode() );
    Invalidate();
}

const ScOutlineArray* ScOutlineWindow::GetOutlineArray() const
{
    const ScOutlineTable* pTable = GetDoc().GetOutlineTable( GetTab() );
    if ( !pTable ) return NULL;
    return mbHoriz ? pTable->GetColArray() : pTable->GetRowArray();
}

const ScOutlineEntry* ScOutlineWindow::GetOutlineEntry( size_t nLevel, size_t nEntry ) const
{
    const ScOutlineArray* pArray = GetOutlineArray();
    return pArray ? pArray->GetEntry( sal::static_int_cast<sal_uInt16>(nLevel), sal::static_int_cast<sal_uInt16>(nEntry) ) : NULL;
}

bool ScOutlineWindow::IsHidden( SCCOLROW nColRowIndex ) const
{
    return mbHoriz ? 
        GetDoc().ColHidden(static_cast<SCCOL>(nColRowIndex), GetTab()) : 
        GetDoc().RowHidden(static_cast<SCROW>(nColRowIndex), GetTab());
}

bool ScOutlineWindow::IsFiltered( SCCOLROW nColRowIndex ) const
{
    // columns cannot be filtered
    return !mbHoriz && GetDoc().RowFiltered( static_cast<SCROW>(nColRowIndex), GetTab() );
}

bool ScOutlineWindow::IsFirstVisible( SCCOLROW nColRowIndex ) const
{
    bool bAllHidden = true;
    for ( SCCOLROW nPos = 0; (nPos < nColRowIndex) && bAllHidden; ++nPos )
        bAllHidden = IsHidden( nPos );
    return bAllHidden;
}

void ScOutlineWindow::GetVisibleRange( SCCOLROW& rnColRowStart, SCCOLROW& rnColRowEnd ) const
{
    if ( mbHoriz )
    {
        rnColRowStart = mrViewData.GetPosX( WhichH( meWhich ) );
        rnColRowEnd = rnColRowStart + mrViewData.VisibleCellsX( WhichH( meWhich ) );
    }
    else
    {
        rnColRowStart = mrViewData.GetPosY( WhichV( meWhich ) );
        rnColRowEnd = rnColRowStart + mrViewData.VisibleCellsY( WhichV( meWhich ) );
    }

    // include collapsed columns/rows in front of visible range
    while ( (rnColRowStart > 0) && IsHidden( rnColRowStart - 1 ) )
        --rnColRowStart;
}

Point ScOutlineWindow::GetPoint( long nLevelPos, long nEntryPos ) const
{
    return mbHoriz ? Point( nEntryPos, nLevelPos ) : Point( nLevelPos, nEntryPos );
}

Rectangle ScOutlineWindow::GetRectangle(
        long nLevelStart, long nEntryStart, long nLevelEnd, long nEntryEnd ) const
{
    return Rectangle( GetPoint( nLevelStart, nEntryStart ), GetPoint( nLevelEnd, nEntryEnd ) );
}

long ScOutlineWindow::GetOutputSizeLevel() const
{
    Size aSize( GetOutputSizePixel() );
    return mbHoriz ? aSize.Height() : aSize.Width();
}

long ScOutlineWindow::GetOutputSizeEntry() const
{
    Size aSize( GetOutputSizePixel() );
    return mbHoriz ? aSize.Width() : aSize.Height();
}

size_t ScOutlineWindow::GetLevelCount() const
{
    const ScOutlineArray* pArray = GetOutlineArray();
    size_t nLevelCount = pArray ? pArray->GetDepth() : 0;
    return nLevelCount ? (nLevelCount + 1) : 0;
}

long ScOutlineWindow::GetLevelPos( size_t nLevel ) const
{
    // #i51970# must always return the *left* edge of the area used by a level
    long nPos = static_cast< long >( SC_OL_POSOFFSET + nLevel * SC_OL_BITMAPSIZE );
    return mbMirrorLevels ? (GetOutputSizeLevel() - nPos - SC_OL_BITMAPSIZE) : nPos;
}

size_t ScOutlineWindow::GetLevelFromPos( long nLevelPos ) const
{
    if( mbMirrorLevels ) nLevelPos = GetOutputSizeLevel() - nLevelPos - 1;
    long nStart = SC_OL_POSOFFSET;
    if ( nLevelPos < nStart ) return SC_OL_NOLEVEL;
    size_t nLevel = static_cast< size_t >( (nLevelPos - nStart) / SC_OL_BITMAPSIZE );
    return (nLevel < GetLevelCount()) ? nLevel : SC_OL_NOLEVEL;
}

long ScOutlineWindow::GetColRowPos( SCCOLROW nColRowIndex ) const
{
    long nDocPos = mbHoriz ?
        mrViewData.GetScrPos( static_cast<SCCOL>(nColRowIndex), 0, meWhich, sal_True ).X() :
        mrViewData.GetScrPos( 0, static_cast<SCROW>(nColRowIndex), meWhich, sal_True ).Y();
    return mnMainFirstPos + nDocPos;
}

long ScOutlineWindow::GetHeaderEntryPos() const
{
    return mnHeaderPos + (mnHeaderSize - SC_OL_BITMAPSIZE) / 2;
}

bool ScOutlineWindow::GetEntryPos(
        size_t nLevel, size_t nEntry,
        long& rnStartPos, long& rnEndPos, long& rnImagePos ) const
{
    const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
    if ( !pEntry || !pEntry->IsVisible() )
        return false;

    SCCOLROW nStart = pEntry->GetStart();
    SCCOLROW nEnd = pEntry->GetEnd();

    long nEntriesSign = mbMirrorEntries ? -1 : 1;

    // --- common calculation ---

    rnStartPos = GetColRowPos( nStart );
    rnEndPos = GetColRowPos( nEnd + 1 );

    bool bHidden = IsHidden( nStart );
    rnImagePos = bHidden ?
                (rnStartPos - ( SC_OL_BITMAPSIZE / 2 ) * nEntriesSign) :
                rnStartPos + nEntriesSign;
    long nCenter = (rnStartPos + rnEndPos - SC_OL_BITMAPSIZE * nEntriesSign +
                        ( mbMirrorEntries ? 1 : 0 )) / 2L;
    rnImagePos = mbMirrorEntries ? Max( rnImagePos, nCenter ) : Min( rnImagePos, nCenter );

    // --- refinements ---

    // do not cut leftmost/topmost image
    if ( bHidden && IsFirstVisible( nStart ) )
        rnImagePos = rnStartPos;

    // do not cover previous collapsed image
    if ( !bHidden && nEntry )
    {
        const ScOutlineEntry* pPrevEntry = GetOutlineEntry( nLevel, nEntry - 1 );
        SCCOLROW nPrevEnd = pPrevEntry->GetEnd();
        if ( (nPrevEnd + 1 == nStart) && IsHidden( nPrevEnd ) )
        {
            if ( IsFirstVisible( pPrevEntry->GetStart() ) )
                rnStartPos += SC_OL_BITMAPSIZE * nEntriesSign;
            else
                rnStartPos += ( SC_OL_BITMAPSIZE / 2 ) * nEntriesSign;
            rnImagePos = rnStartPos;
        }
    }

    // restrict rnStartPos...rnEndPos to valid area
    rnStartPos = std::max( rnStartPos, mnMainFirstPos );
    rnEndPos = std::max( rnEndPos, mnMainFirstPos );

    if ( mbMirrorEntries )
        rnImagePos -= SC_OL_BITMAPSIZE - 1;     // start pos aligns with right edge of bitmap

    // --- all rows filtered? ---

    bool bVisible = true;
    if ( !mbHoriz )
    {
        bVisible = false;
        for ( SCCOLROW nRow = nStart; (nRow <= nEnd) && !bVisible; ++nRow )
            bVisible = !IsFiltered( nRow );
    }
    return bVisible;
}

bool ScOutlineWindow::GetImagePos( size_t nLevel, size_t nEntry, Point& rPos ) const
{
    bool bRet = nLevel < GetLevelCount();
    if ( bRet )
    {
        long nLevelPos = GetLevelPos( nLevel );
        if ( nEntry == SC_OL_HEADERENTRY )
            rPos = GetPoint( nLevelPos, GetHeaderEntryPos() );
        else
        {
            long nStartPos, nEndPos, nImagePos;
            bRet = GetEntryPos( nLevel, nEntry, nStartPos, nEndPos, nImagePos );
            rPos = GetPoint( nLevelPos, nImagePos );
        }
    }
    return bRet;
}

bool ScOutlineWindow::IsButtonVisible( size_t nLevel, size_t nEntry ) const
{
    bool bRet = false;
    if ( nEntry == SC_OL_HEADERENTRY )
        bRet = (mnHeaderSize > 0) && (nLevel < GetLevelCount());
    else
    {
        const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
        if ( pEntry && pEntry->IsVisible() )
        {
            SCCOLROW nStart, nEnd;
            GetVisibleRange( nStart, nEnd );
            bRet = (nStart <= pEntry->GetStart()) && (pEntry->GetStart() <= nEnd);
        }
    }
    return bRet;
}

bool ScOutlineWindow::ItemHit( const Point& rPos, size_t& rnLevel, size_t& rnEntry, bool& rbButton ) const
{
    const ScOutlineArray* pArray = GetOutlineArray();
    if ( !pArray ) return false;

    SCCOLROW nStartIndex, nEndIndex;
    GetVisibleRange( nStartIndex, nEndIndex );

    size_t nLevel = GetLevelFromPos( mbHoriz ? rPos.Y() : rPos.X() );
    if ( nLevel == SC_OL_NOLEVEL )
        return false;

//    long nLevelPos = GetLevelPos( nLevel );
    long nEntryMousePos = mbHoriz ? rPos.X() : rPos.Y();

    // --- level buttons ---

    if ( mnHeaderSize > 0 )
    {
        long nImagePos = GetHeaderEntryPos();
        if ( (nImagePos <= nEntryMousePos) && (nEntryMousePos < nImagePos + SC_OL_BITMAPSIZE) )
        {
            rnLevel = nLevel;
            rnEntry = SC_OL_HEADERENTRY;
            rbButton = true;
            return true;
        }
    }

    // --- expand/collapse buttons and expanded lines ---

    // search outline entries backwards
    size_t nEntry = pArray->GetCount( sal::static_int_cast<sal_uInt16>(nLevel) );
    while ( nEntry )
    {
        --nEntry;

        const ScOutlineEntry* pEntry = pArray->GetEntry( sal::static_int_cast<sal_uInt16>(nLevel),
                                                         sal::static_int_cast<sal_uInt16>(nEntry) );
        SCCOLROW nStart = pEntry->GetStart();
        SCCOLROW nEnd = pEntry->GetEnd();

        if ( (nEnd >= nStartIndex) && (nStart <= nEndIndex) )
        {
            long nStartPos, nEndPos, nImagePos;
            if ( GetEntryPos( nLevel, nEntry, nStartPos, nEndPos, nImagePos ) )
            {
                rnLevel = nLevel;
                rnEntry = nEntry;

                // button?
                if ( (nStart >= nStartIndex) && (nImagePos <= nEntryMousePos) && (nEntryMousePos < nImagePos + SC_OL_BITMAPSIZE) )
                {
                    rbButton = true;
                    return true;
                }

                // line?
                if ( mbMirrorEntries )
                    ::std::swap( nStartPos, nEndPos );      // in RTL mode, nStartPos is the larger value
                if ( (nStartPos <= nEntryMousePos) && (nEntryMousePos <= nEndPos) )
                {
                    rbButton = false;
                    return true;
                }
            }
        }
    }

    return false;
}

bool ScOutlineWindow::ButtonHit( const Point& rPos, size_t& rnLevel, size_t& rnEntry ) const
{
    bool bButton;
    bool bRet = ItemHit( rPos, rnLevel, rnEntry, bButton );
    return bRet && bButton;
}

bool ScOutlineWindow::LineHit( const Point& rPos, size_t& rnLevel, size_t& rnEntry ) const
{
    bool bButton;
    bool bRet = ItemHit( rPos, rnLevel, rnEntry, bButton );
    return bRet && !bButton;
}

void ScOutlineWindow::DoFunction( size_t nLevel, size_t nEntry ) const
{
    ScDBFunc& rFunc = *mrViewData.GetView();
    if ( nEntry == SC_OL_HEADERENTRY )
        rFunc.SelectLevel( mbHoriz, sal::static_int_cast<sal_uInt16>(nLevel) );
    else
    {
        const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
        if ( pEntry )
        {
            if ( pEntry->IsHidden() )
                rFunc.ShowOutline( mbHoriz, sal::static_int_cast<sal_uInt16>(nLevel), sal::static_int_cast<sal_uInt16>(nEntry) );
            else
                rFunc.HideOutline( mbHoriz, sal::static_int_cast<sal_uInt16>(nLevel), sal::static_int_cast<sal_uInt16>(nEntry) );
        }
    }
}

void ScOutlineWindow::DoExpand( size_t nLevel, size_t nEntry ) const
{
    const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
    if ( pEntry && pEntry->IsHidden() )
        DoFunction( nLevel, nEntry );
}

void ScOutlineWindow::DoCollapse( size_t nLevel, size_t nEntry ) const
{
    const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
    if ( pEntry && !pEntry->IsHidden() )
        DoFunction( nLevel, nEntry );
}

void ScOutlineWindow::Resize()
{
    Window::Resize();
    SetHeaderSize( mnHeaderSize );  // recalculates header/group positions
    if ( !IsFocusButtonVisible() )
    {
        HideFocus();
        ShowFocus();    // calculates valid position
    }
}

void ScOutlineWindow::DataChanged( const DataChangedEvent& rDCEvt )
{
    if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
         (rDCEvt.GetFlags() & SETTINGS_STYLE) )
    {
        InitSettings();
        Invalidate();
    }
    Window::DataChanged( rDCEvt );
}

// drawing --------------------------------------------------------------------

void ScOutlineWindow::SetEntryAreaClipRegion()
{
    SetClipRegion( Rectangle(
        GetPoint( 0, mnMainFirstPos ),
        GetPoint( GetOutputSizeLevel() - 1, mnMainLastPos ) ) );
}

void ScOutlineWindow::DrawLineRel(
        long nLevelStart, long nEntryStart, long nLevelEnd, long nEntryEnd )
{
    DrawLine( GetPoint( nLevelStart, nEntryStart ), GetPoint( nLevelEnd, nEntryEnd ) );
}

void ScOutlineWindow::DrawRectRel(
        long nLevelStart, long nEntryStart, long nLevelEnd, long nEntryEnd )
{
    DrawRect( GetRectangle( nLevelStart, nEntryStart, nLevelEnd, nEntryEnd ) );
}

void ScOutlineWindow::DrawImageRel( long nLevelPos, long nEntryPos, sal_uInt16 nId )
{
    DBG_ASSERT( mpSymbols, "ScOutlineWindow::DrawImageRel - no images" );
    const Image& rImage = mpSymbols->GetImage( nId );
    SetLineColor();
    SetFillColor( GetBackground().GetColor() );
    Point aPos( GetPoint( nLevelPos, nEntryPos ) );
    DrawRect( Rectangle( aPos, rImage.GetSizePixel() ) );
    DrawImage( aPos, rImage );
}

void ScOutlineWindow::DrawBorderRel( size_t nLevel, size_t nEntry, bool bPressed )
{
    Point aPos;
    if ( GetImagePos( nLevel, nEntry, aPos ) )
    {
        DBG_ASSERT( mpSymbols, "ScOutlineWindow::DrawBorderRel - no images" );
        sal_uInt16 nId = bPressed ? SC_OL_IMAGE_PRESSED : SC_OL_IMAGE_NOTPRESSED;
        bool bClip = (nEntry != SC_OL_HEADERENTRY);
        if ( bClip )
            SetEntryAreaClipRegion();
        DrawImage( aPos, mpSymbols->GetImage( nId ) );
        if ( bClip )
            SetClipRegion();
    }
    mbMTPressed = bPressed;
}

void ScOutlineWindow::ShowFocus()
{
    if ( HasFocus() )
    {
        // first move to a visible position
        ImplMoveFocusToVisible( true );

        if ( IsFocusButtonVisible() )
        {
            Point aPos;
            if ( GetImagePos( mnFocusLevel, mnFocusEntry, aPos ) )
            {
                aPos += Point( 1, 1 );
                maFocusRect = Rectangle( aPos, Size( SC_OL_BITMAPSIZE - 2, SC_OL_BITMAPSIZE - 2 ) );
                bool bClip = (mnFocusEntry != SC_OL_HEADERENTRY);
                if ( bClip )
                    SetEntryAreaClipRegion();
                InvertTracking( maFocusRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
                if ( bClip )
                    SetClipRegion();
            }
        }
    }
}

void ScOutlineWindow::HideFocus()
{
    if ( !maFocusRect.IsEmpty() )
    {
        bool bClip = (mnFocusEntry != SC_OL_HEADERENTRY);
        if ( bClip )
            SetEntryAreaClipRegion();
        InvertTracking( maFocusRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
        if ( bClip )
            SetClipRegion();
        maFocusRect.SetEmpty();
    }
}

void ScOutlineWindow::Paint( const Rectangle& /* rRect */ )
{
    long nEntriesSign = mbMirrorEntries ? -1 : 1;
    long nLevelsSign  = mbMirrorLevels  ? -1 : 1;

    Size aSize = GetOutputSizePixel();
    long nLevelEnd = (mbHoriz ? aSize.Height() : aSize.Width()) - 1;
    long nEntryEnd = (mbHoriz ? aSize.Width() : aSize.Height()) - 1;

    SetLineColor( maLineColor );
    long nBorderPos = mbMirrorLevels ? 0 : nLevelEnd;
    DrawLineRel( nBorderPos, 0, nBorderPos, nEntryEnd );

    const ScOutlineArray* pArray = GetOutlineArray();
    if ( !pArray ) return;

    size_t nLevelCount = GetLevelCount();

    // --- draw header images ---

    if ( mnHeaderSize > 0 )
    {
        long nEntryPos = GetHeaderEntryPos();
        for ( size_t nLevel = 0; nLevel < nLevelCount; ++nLevel )
            DrawImageRel( GetLevelPos( nLevel ), nEntryPos, static_cast< sal_uInt16 >( nLevel + 1 ) );

        SetLineColor( maLineColor );
        long nLinePos = mnHeaderPos + (mbMirrorEntries ? 0 : (mnHeaderSize - 1));
        DrawLineRel( 0, nLinePos, nLevelEnd, nLinePos );
    }

    // --- draw lines & collapse/expand images ---

    SetEntryAreaClipRegion();

    SCCOLROW nStartIndex, nEndIndex;
    GetVisibleRange( nStartIndex, nEndIndex );

    for ( size_t nLevel = 0; nLevel + 1 < nLevelCount; ++nLevel )
    {
        long nLevelPos = GetLevelPos( nLevel );
        long nEntryPos1 = 0, nEntryPos2 = 0, nImagePos = 0;

        size_t nEntryCount = pArray->GetCount( sal::static_int_cast<sal_uInt16>(nLevel) );
        size_t nEntry;

        // first draw all lines in the current level
        SetLineColor();
        SetFillColor( maLineColor );
        for ( nEntry = 0; nEntry < nEntryCount; ++nEntry )
        {
            const ScOutlineEntry* pEntry = pArray->GetEntry( sal::static_int_cast<sal_uInt16>(nLevel),
                                                             sal::static_int_cast<sal_uInt16>(nEntry) );
            SCCOLROW nStart = pEntry->GetStart();
            SCCOLROW nEnd = pEntry->GetEnd();

            // visible range?
            bool bDraw = (nEnd >= nStartIndex) && (nStart <= nEndIndex);
            // find output coordinates
            if ( bDraw )
                bDraw = GetEntryPos( nLevel, nEntry, nEntryPos1, nEntryPos2, nImagePos );
            // draw, if not collapsed
            if ( bDraw && !pEntry->IsHidden() )
            {
                if ( nStart >= nStartIndex )
                    nEntryPos1 += nEntriesSign;
                nEntryPos2 -= 2 * nEntriesSign;
                long nLinePos = nLevelPos;
                if ( mbMirrorLevels )
                    nLinePos += SC_OL_BITMAPSIZE - 1;   // align with right edge of bitmap
                DrawRectRel( nLinePos, nEntryPos1, nLinePos + nLevelsSign, nEntryPos2 );

                if ( nEnd <= nEndIndex )
                    DrawRectRel( nLinePos, nEntryPos2 - nEntriesSign,
                                 nLinePos + ( SC_OL_BITMAPSIZE / 3 ) * nLevelsSign, nEntryPos2 );
            }
        }

        // draw all images in the level from last to first
        nEntry = nEntryCount;
        while ( nEntry )
        {
            --nEntry;

            const ScOutlineEntry* pEntry = pArray->GetEntry( sal::static_int_cast<sal_uInt16>(nLevel),
                                                             sal::static_int_cast<sal_uInt16>(nEntry) );
            SCCOLROW nStart = pEntry->GetStart();
//            SCCOLROW nEnd = pEntry->GetEnd();

            // visible range?
            bool bDraw = (nStartIndex <= nStart) && (nStart <= nEndIndex + 1);
            // find output coordinates
            if ( bDraw )
                bDraw = GetEntryPos( nLevel, nEntry, nEntryPos1, nEntryPos2, nImagePos );
            // draw, if not hidden by higher levels
            if ( bDraw )
            {
                sal_uInt16 nImageId = pEntry->IsHidden() ? SC_OL_IMAGE_PLUS : SC_OL_IMAGE_MINUS;
                DrawImageRel( nLevelPos, nImagePos, nImageId );
            }
        }
    }

    SetClipRegion();

    if ( !mbDontDrawFocus )
        ShowFocus();
}

// focus ----------------------------------------------------------------------

/** Increments or decrements a value and wraps at the specified limits.
    @return  true = value wrapped. */
bool lcl_RotateValue( size_t& rnValue, size_t nMin, size_t nMax, bool bForward )
{
    DBG_ASSERT( nMin <= nMax, "lcl_RotateValue - invalid range" );
    DBG_ASSERT( nMax < static_cast< size_t >( -1 ), "lcl_RotateValue - range overflow" );
    bool bWrap = false;
    if ( bForward )
    {
        if ( rnValue < nMax )
            ++rnValue;
        else
        {
            rnValue = nMin;
            bWrap = true;
        }
    }
    else
    {
        if ( rnValue > nMin )
            --rnValue;
        else
        {
            rnValue = nMax;
            bWrap = true;
        }
    }
    return bWrap;
}

bool ScOutlineWindow::IsFocusButtonVisible() const
{
    return IsButtonVisible( mnFocusLevel, mnFocusEntry );
}

bool ScOutlineWindow::ImplMoveFocusByEntry( bool bForward, bool bFindVisible )
{
    const ScOutlineArray* pArray = GetOutlineArray();
    if ( !pArray )
        return false;

    bool bWrapped = false;
    size_t nEntryCount = pArray->GetCount( sal::static_int_cast<sal_uInt16>(mnFocusLevel) );
    // #i29530# entry count may be decreased after changing active sheet
    if( mnFocusEntry >= nEntryCount )
        mnFocusEntry = SC_OL_HEADERENTRY;
    size_t nOldEntry = mnFocusEntry;

    do
    {
        if ( mnFocusEntry == SC_OL_HEADERENTRY )
        {
            // move from header to first or last entry
            if ( nEntryCount > 0 )
                mnFocusEntry = bForward ? 0 : (nEntryCount - 1);
            /*  wrapped, if forward from right header to first entry,
                or if backward from left header to last entry */
            // Header and entries are now always in consistent order,
            // so there's no need to check for mirroring here.
            if ( !nEntryCount || !bForward )
                bWrapped = true;
        }
        else if ( lcl_RotateValue( mnFocusEntry, 0, nEntryCount - 1, bForward ) )
        {
            // lcl_RotateValue returns true -> wrapped the entry range -> move to header
            mnFocusEntry = SC_OL_HEADERENTRY;
            /*  wrapped, if forward from last entry to left header,
                or if backward from first entry to right header */
            if ( bForward )
                bWrapped = true;
        }
    }
    while ( bFindVisible && !IsFocusButtonVisible() && (nOldEntry != mnFocusEntry) );

    return bWrapped;
}

bool ScOutlineWindow::ImplMoveFocusByLevel( bool bForward )
{
    const ScOutlineArray* pArray = GetOutlineArray();
    if ( !pArray )
        return false;

    bool bWrapped = false;
    size_t nLevelCount = GetLevelCount();

    if ( mnFocusEntry == SC_OL_HEADERENTRY )
    {
        if ( nLevelCount > 0 )
            bWrapped = lcl_RotateValue( mnFocusLevel, 0, nLevelCount - 1, bForward );
    }
    else
    {
        const ScOutlineEntry* pEntry = pArray->GetEntry( sal::static_int_cast<sal_uInt16>(mnFocusLevel),
                                                         sal::static_int_cast<sal_uInt16>(mnFocusEntry) );
        if ( pEntry )
        {
            SCCOLROW nStart = pEntry->GetStart();
            SCCOLROW nEnd = pEntry->GetEnd();
            size_t nNewLevel = mnFocusLevel;
            size_t nNewEntry = 0;

            bool bFound = false;
            if ( bForward && (mnFocusLevel + 2 < nLevelCount) )
            {
                // next level -> find first child entry
                nNewLevel = mnFocusLevel + 1;
                // TODO - change ScOutlineArray interface to size_t usage
                sal_uInt16 nTmpEntry = 0;
                bFound = pArray->GetEntryIndexInRange( sal::static_int_cast<sal_uInt16>(nNewLevel), nStart, nEnd, nTmpEntry );
                nNewEntry = nTmpEntry;
            }
            else if ( !bForward && (mnFocusLevel > 0) )
            {
                // previous level -> find parent entry
                nNewLevel = mnFocusLevel - 1;
                // TODO - change ScOutlineArray interface to size_t usage
                sal_uInt16 nTmpEntry = 0;
                bFound = pArray->GetEntryIndex( sal::static_int_cast<sal_uInt16>(nNewLevel), nStart, nTmpEntry );
                nNewEntry = nTmpEntry;
            }

            if ( bFound && IsButtonVisible( nNewLevel, nNewEntry ) )
            {
                mnFocusLevel = nNewLevel;
                mnFocusEntry = nNewEntry;
            }
        }
    }

    return bWrapped;
}

bool ScOutlineWindow::ImplMoveFocusByTabOrder( bool bForward, bool bFindVisible )
{
    bool bRet = false;
    size_t nOldLevel = mnFocusLevel;
    size_t nOldEntry = mnFocusEntry;

    do
    {
        /*  one level up, if backward from left header,
            or one level down, if forward from right header */
        if ( (!bForward) && (mnFocusEntry == SC_OL_HEADERENTRY) )
            bRet |= ImplMoveFocusByLevel( bForward );
        // move to next/previous entry
        bool bWrapInLevel = ImplMoveFocusByEntry( bForward, false );
        bRet |= bWrapInLevel;
        /*  one level up, if wrapped backward to right header,
            or one level down, if wrapped forward to right header */
        if ( bForward && bWrapInLevel )
            bRet |= ImplMoveFocusByLevel( bForward );
    }
    while ( bFindVisible && !IsFocusButtonVisible() && ((nOldLevel != mnFocusLevel) || (nOldEntry != mnFocusEntry)) );

    return bRet;
}

void ScOutlineWindow::ImplMoveFocusToVisible( bool bForward )
{
    // first try to find an entry in the same level
    if ( !IsFocusButtonVisible() )
        ImplMoveFocusByEntry( bForward, true );
    // then try to find any other entry
    if ( !IsFocusButtonVisible() )
        ImplMoveFocusByTabOrder( bForward, true );
}

void ScOutlineWindow::MoveFocusByEntry( bool bForward )
{
    HideFocus();
    ImplMoveFocusByEntry( bForward, true );
    ShowFocus();
}

void ScOutlineWindow::MoveFocusByLevel( bool bForward )
{
    HideFocus();
    ImplMoveFocusByLevel( bForward );
    ShowFocus();
}

void ScOutlineWindow::MoveFocusByTabOrder( bool bForward )
{
    HideFocus();
    ImplMoveFocusByTabOrder( bForward, true );
    ShowFocus();
}

void ScOutlineWindow::GetFocus()
{
    Window::GetFocus();
    ShowFocus();
}

void ScOutlineWindow::LoseFocus()
{
    HideFocus();
    Window::LoseFocus();
}


// mouse ----------------------------------------------------------------------

void ScOutlineWindow::StartMouseTracking( size_t nLevel, size_t nEntry )
{
    mbMTActive = true;
    mnMTLevel = nLevel;
    mnMTEntry = nEntry;
    DrawBorderRel( nLevel, nEntry, true );
}

void ScOutlineWindow::EndMouseTracking()
{
    if ( mbMTPressed )
        DrawBorderRel( mnMTLevel, mnMTEntry, false );
    mbMTActive = false;
}

void ScOutlineWindow::MouseMove( const MouseEvent& rMEvt )
{
    if ( IsMouseTracking() )
	{
        size_t nLevel, nEntry;
        bool bHit = false;

        if ( ButtonHit( rMEvt.GetPosPixel(), nLevel, nEntry ) )
            bHit = (nLevel == mnMTLevel) && (nEntry == mnMTEntry);

        if ( bHit != mbMTPressed )
            DrawBorderRel( mnMTLevel, mnMTEntry, bHit );
	}
}

void ScOutlineWindow::MouseButtonUp( const MouseEvent& rMEvt )
{
    if ( IsMouseTracking() )
	{
        EndMouseTracking();

        size_t nLevel, nEntry;
        if ( ButtonHit( rMEvt.GetPosPixel(), nLevel, nEntry ) )
            if ( (nLevel == mnMTLevel) && (nEntry == mnMTEntry) )
                DoFunction( nLevel, nEntry );
	}
}

void ScOutlineWindow::MouseButtonDown( const MouseEvent& rMEvt )
{
    size_t nLevel, nEntry;
    bool bHit = ButtonHit( rMEvt.GetPosPixel(), nLevel, nEntry );
    if ( bHit )
        StartMouseTracking( nLevel, nEntry );
    else if ( rMEvt.GetClicks() == 2 )
	{
        bHit = LineHit( rMEvt.GetPosPixel(), nLevel, nEntry );
        if ( bHit )
            DoFunction( nLevel, nEntry );
	}

    // if an item has been hit and window is focused, move focus to this item
    if ( bHit && HasFocus() )
    {
        HideFocus();
        mnFocusLevel = nLevel;
        mnFocusEntry = nEntry;
        ShowFocus();
    }
}


// keyboard -------------------------------------------------------------------

void ScOutlineWindow::KeyInput( const KeyEvent& rKEvt )
{
    const KeyCode& rKCode = rKEvt.GetKeyCode();
    bool bNoMod = !rKCode.GetModifier();
    bool bShift = (rKCode.GetModifier() == KEY_SHIFT);
    bool bCtrl = (rKCode.GetModifier() == KEY_MOD1);

    sal_uInt16 nCode = rKCode.GetCode();
    bool bUpDownKey = (nCode == KEY_UP) || (nCode == KEY_DOWN);
    bool bLeftRightKey = (nCode == KEY_LEFT) || (nCode == KEY_RIGHT);

    // TAB key
    if ( (nCode == KEY_TAB) && (bNoMod || bShift) )
        // move forward without SHIFT key
        MoveFocusByTabOrder( bNoMod );      // TAB uses logical order, regardless of mirroring

    // LEFT/RIGHT/UP/DOWN keys
    else if ( bNoMod && (bUpDownKey || bLeftRightKey) )
    {
        bool bForward = (nCode == KEY_DOWN) || (nCode == KEY_RIGHT);
        if ( mbHoriz == bLeftRightKey )
            // move inside level with LEFT/RIGHT in horizontal and with UP/DOWN in vertical
            MoveFocusByEntry( bForward != mbMirrorEntries );
        else
            // move to next/prev level with LEFT/RIGHT in vertical and with UP/DOWN in horizontal
            MoveFocusByLevel( bForward != mbMirrorLevels );
    }

    // CTRL + number
    else if ( bCtrl && (nCode >= KEY_1) && (nCode <= KEY_9) )
    {
        size_t nLevel = static_cast< size_t >( nCode - KEY_1 );
        if ( nLevel < GetLevelCount() )
            DoFunction( nLevel, SC_OL_HEADERENTRY );
    }

    // other key codes
    else switch ( rKCode.GetFullCode() )
    {
        case KEY_ADD:       DoExpand( mnFocusLevel, mnFocusEntry );     break;
        case KEY_SUBTRACT:  DoCollapse( mnFocusLevel, mnFocusEntry );   break;
        case KEY_SPACE:
        case KEY_RETURN:    DoFunction( mnFocusLevel, mnFocusEntry );   break;
        default:            Window::KeyInput( rKEvt );
    }
}


// ============================================================================

