/**************************************************************
 * 
 * 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.
 * 
 *************************************************************/


#include "precompiled_sc.hxx"
#ifndef _SC_ZOOMSLIDERTBCONTRL_HXX
#include "tbzoomsliderctrl.hxx"
#endif
#ifndef _SV_IMAGE_HXX
#include <vcl/image.hxx>
#endif
#ifndef _SV_TOOLBOX_HXX
#include <vcl/toolbox.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _SV_GRADIENT_HXX
#include <vcl/gradient.hxx>
#endif
#include <svl/itemset.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/objsh.hxx>
#include <svx/zoomslideritem.hxx>
#include <svx/dialmgr.hxx>
#include <svx/dialogs.hrc>
#include <set>
#include "docsh.hxx"
#include "stlpool.hxx"
#include "scitems.hxx"
#include "printfun.hxx"

//========================================================================
// class ScZoomSliderControl ---------------------------------------
//========================================================================

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

SFX_IMPL_TOOLBOX_CONTROL( ScZoomSliderControl, SvxZoomSliderItem );

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

ScZoomSliderControl::ScZoomSliderControl(
    sal_uInt16     nSlotId,
    sal_uInt16	   nId,
    ToolBox&   rTbx ) 
    :SfxToolBoxControl( nSlotId, nId, rTbx )
{
    rTbx.Invalidate();
}

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

__EXPORT ScZoomSliderControl::~ScZoomSliderControl()
{

}

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

void ScZoomSliderControl::StateChanged( sal_uInt16 /*nSID*/, SfxItemState eState,
                                       const SfxPoolItem* pState )
{
    sal_uInt16                  nId	 = GetId();
    ToolBox&                rTbx = GetToolBox();
    ScZoomSliderWnd*        pBox = (ScZoomSliderWnd*)(rTbx.GetItemWindow( nId ));
    DBG_ASSERT( pBox ,"Control not found!" );

    if ( SFX_ITEM_AVAILABLE != eState || pState->ISA( SfxVoidItem ) )
    {
        SvxZoomSliderItem aZoomSliderItem( 100 );
        pBox->Disable();
        pBox->UpdateFromItem( &aZoomSliderItem );
    }
    else
    {
        pBox->Enable();
        DBG_ASSERT( pState->ISA( SvxZoomSliderItem ), "invalid item type" );
        const SvxZoomSliderItem* pZoomSliderItem = dynamic_cast< const SvxZoomSliderItem* >( pState );

        DBG_ASSERT( pZoomSliderItem, "Sc::ScZoomSliderControl::StateChanged(), wrong item type!" );
        if( pZoomSliderItem )
            pBox->UpdateFromItem( pZoomSliderItem );
    }
}

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

Window* ScZoomSliderControl::CreateItemWindow( Window *pParent )
{
    // #i98000# Don't try to get a value via SfxViewFrame::Current here.
    // The view's value is always notified via StateChanged later.
    ScZoomSliderWnd* pSlider    = new ScZoomSliderWnd( pParent,
        ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >( m_xFrame->getController(),
        ::com::sun::star::uno::UNO_QUERY ), m_xFrame, 100 );
    return  pSlider;
}

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

struct ScZoomSliderWnd::ScZoomSliderWnd_Impl
{
    sal_uInt16                   mnCurrentZoom;
    sal_uInt16                   mnMinZoom;
    sal_uInt16                   mnMaxZoom;
    sal_uInt16                   mnSliderCenter;
    std::vector< long >      maSnappingPointOffsets;
    std::vector< sal_uInt16 >    maSnappingPointZooms;
    Image                    maSliderButton;
    Image                    maIncreaseButton;
    Image                    maDecreaseButton;
    bool                     mbValuesSet;
    bool                     mbOmitPaint;

    ScZoomSliderWnd_Impl( sal_uInt16 nCurrentZoom ) :
        mnCurrentZoom( nCurrentZoom ),
        mnMinZoom( 10 ),
        mnMaxZoom( 400 ),
        mnSliderCenter( 100 ),
        maSnappingPointOffsets(),
        maSnappingPointZooms(),
        maSliderButton(),
        maIncreaseButton(),
        maDecreaseButton(),
        mbValuesSet( true ),
        mbOmitPaint( false ) 
        {

        }
};

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

const long nButtonWidth     = 10;
const long nButtonHeight    = 10;
const long nIncDecWidth     = 11;
const long nIncDecHeight    = 11;
const long nSliderHeight    = 2;      //  
const long nSliderWidth     = 4;      //
const long nSnappingHeight  = 4;
const long nSliderXOffset   = 20;
const long nSnappingEpsilon = 5; // snapping epsilon in pixels
const long nSnappingPointsMinDist = nSnappingEpsilon; // minimum distance of two adjacent snapping points


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

sal_uInt16 ScZoomSliderWnd::Offset2Zoom( long nOffset ) const
{
    Size aSliderWindowSize = GetOutputSizePixel();
    const long nControlWidth = aSliderWindowSize.Width();
    sal_uInt16 nRet = 0;
    
    if( nOffset < nSliderXOffset )
        return mpImpl->mnMinZoom;
    if( nOffset > nControlWidth - nSliderXOffset )
        return mpImpl->mnMaxZoom;

    // check for snapping points:
    sal_uInt16 nCount = 0;
    std::vector< long >::iterator aSnappingPointIter;
    for ( aSnappingPointIter = mpImpl->maSnappingPointOffsets.begin();
        aSnappingPointIter != mpImpl->maSnappingPointOffsets.end();
        ++aSnappingPointIter )
    {
        const long nCurrent = *aSnappingPointIter;
        if ( Abs(nCurrent - nOffset) < nSnappingEpsilon )
        {
            nOffset = nCurrent;
            nRet = mpImpl->maSnappingPointZooms[ nCount ];
            break;
        }
        ++nCount;
    }

    if( 0 == nRet )
    {
        if( nOffset < nControlWidth / 2 )
        {
            // first half of slider
            const long nFirstHalfRange      = mpImpl->mnSliderCenter - mpImpl->mnMinZoom;
            const long nHalfSliderWidth     = nControlWidth/2 - nSliderXOffset;
            const long nZoomPerSliderPixel  = (1000 * nFirstHalfRange) / nHalfSliderWidth;
            const long nOffsetToSliderLeft  = nOffset - nSliderXOffset;
            nRet = mpImpl->mnMinZoom + sal_uInt16( nOffsetToSliderLeft * nZoomPerSliderPixel / 1000 );
        }
        else
        {
            // second half of slider
            const long nSecondHalfRange         = mpImpl->mnMaxZoom - mpImpl->mnSliderCenter;
            const long nHalfSliderWidth         = nControlWidth/2 - nSliderXOffset;
            const long nZoomPerSliderPixel      = 1000 * nSecondHalfRange / nHalfSliderWidth;
            const long nOffsetToSliderCenter    = nOffset - nControlWidth/2;
            nRet = mpImpl->mnSliderCenter + sal_uInt16( nOffsetToSliderCenter * nZoomPerSliderPixel / 1000 );
        }
    }

    if( nRet < mpImpl->mnMinZoom )
        return mpImpl->mnMinZoom;
    
    else if( nRet > mpImpl->mnMaxZoom )
        return mpImpl->mnMaxZoom;

    return nRet;
}

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

long ScZoomSliderWnd::Zoom2Offset( sal_uInt16 nCurrentZoom ) const
{
    Size aSliderWindowSize = GetOutputSizePixel();
    const long nControlWidth = aSliderWindowSize.Width();
    long  nRect = nSliderXOffset;

    const long nHalfSliderWidth = nControlWidth/2 - nSliderXOffset;
    if( nCurrentZoom <= mpImpl->mnSliderCenter )
    {
        nCurrentZoom = nCurrentZoom - mpImpl->mnMinZoom;
        const long nFirstHalfRange = mpImpl->mnSliderCenter - mpImpl->mnMinZoom;
        const long nSliderPixelPerZoomPercent = 1000 * nHalfSliderWidth  / nFirstHalfRange;
        const long nOffset = (nSliderPixelPerZoomPercent * nCurrentZoom) / 1000;
        nRect += nOffset;
    }
    else
    {
        nCurrentZoom = nCurrentZoom - mpImpl->mnSliderCenter;
        const long nSecondHalfRange = mpImpl->mnMaxZoom - mpImpl->mnSliderCenter;
        const long nSliderPixelPerZoomPercent = 1000 * nHalfSliderWidth  / nSecondHalfRange;
        const long nOffset = (nSliderPixelPerZoomPercent * nCurrentZoom) / 1000;
        nRect += nHalfSliderWidth + nOffset;
    }
    return nRect;
}

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


ScZoomSliderWnd::ScZoomSliderWnd( Window* pParent, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >& rDispatchProvider,
                const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& _xFrame , sal_uInt16 nCurrentZoom ):
                Window( pParent ),
                mpImpl( new ScZoomSliderWnd_Impl( nCurrentZoom ) ),
                aLogicalSize( 115, 40 ),
                m_xDispatchProvider( rDispatchProvider ),
                m_xFrame( _xFrame )
{
    sal_Bool bIsHC                  = GetSettings().GetStyleSettings().GetHighContrastMode();
    mpImpl->maSliderButton      = Image( SVX_RES( bIsHC ? RID_SVXBMP_SLIDERBUTTON_HC : RID_SVXBMP_SLIDERBUTTON ) );
    mpImpl->maIncreaseButton    = Image( SVX_RES( bIsHC ? RID_SVXBMP_SLIDERINCREASE_HC : RID_SVXBMP_SLIDERINCREASE ) );
    mpImpl->maDecreaseButton    = Image( SVX_RES( bIsHC ? RID_SVXBMP_SLIDERDECREASE_HC : RID_SVXBMP_SLIDERDECREASE ) );
    Size  aSliderSize           = LogicToPixel( Size( aLogicalSize), MapMode( MAP_10TH_MM ) );
    SetSizePixel( Size( aSliderSize.Width() * nSliderWidth-1, aSliderSize.Height() + nSliderHeight ) );
}

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

ScZoomSliderWnd::~ScZoomSliderWnd()
{
    delete mpImpl;
}

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

void ScZoomSliderWnd::MouseButtonDown( const MouseEvent& rMEvt )
{   
    if ( !mpImpl->mbValuesSet )
        return ;
    Size aSliderWindowSize = GetOutputSizePixel();

    const Point aPoint = rMEvt.GetPosPixel();

    const long nButtonLeftOffset    = ( nSliderXOffset - nIncDecWidth )/2;
    const long nButtonRightOffset   = ( nSliderXOffset + nIncDecWidth )/2;

    const long nOldZoom = mpImpl->mnCurrentZoom;

    // click to - button
    if ( aPoint.X() >= nButtonLeftOffset && aPoint.X() <= nButtonRightOffset )
    {
        mpImpl->mnCurrentZoom = mpImpl->mnCurrentZoom - 5;
    }
    // click to + button
    else if ( aPoint.X() >= aSliderWindowSize.Width() - nSliderXOffset + nButtonLeftOffset &&
              aPoint.X() <= aSliderWindowSize.Width() - nSliderXOffset + nButtonRightOffset )
    {
        mpImpl->mnCurrentZoom = mpImpl->mnCurrentZoom + 5;
    }
    else if( aPoint.X() >= nSliderXOffset && aPoint.X() <= aSliderWindowSize.Width() - nSliderXOffset )
    {
        mpImpl->mnCurrentZoom = Offset2Zoom( aPoint.X() );
    }

    if( mpImpl->mnCurrentZoom < mpImpl->mnMinZoom )
        mpImpl->mnCurrentZoom = mpImpl->mnMinZoom;
    else if( mpImpl->mnCurrentZoom > mpImpl->mnMaxZoom )
        mpImpl->mnCurrentZoom = mpImpl->mnMaxZoom;

    if( nOldZoom == mpImpl->mnCurrentZoom )
        return ;

    Rectangle aRect( Point( 0, 0 ), aSliderWindowSize );
    
    Paint( aRect );
    mpImpl->mbOmitPaint = true;
    
    SvxZoomSliderItem   aZoomSliderItem( mpImpl->mnCurrentZoom );

    ::com::sun::star::uno::Any  a;
    aZoomSliderItem.QueryValue( a );
    
    ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs( 1 );
    aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScalingFactor" ));
    aArgs[0].Value = a;
    
    SfxToolBoxControl::Dispatch( m_xDispatchProvider, String::CreateFromAscii(".uno:ScalingFactor"), aArgs );

    mpImpl->mbOmitPaint = false;
}

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

void ScZoomSliderWnd::MouseMove( const MouseEvent& rMEvt )
{
    if ( !mpImpl->mbValuesSet )
        return ;

    Size aSliderWindowSize   = GetOutputSizePixel();
    const long nControlWidth = aSliderWindowSize.Width();
    const short nButtons     = rMEvt.GetButtons();

    // check mouse move with button pressed
    if ( 1 == nButtons )
    {
        const Point aPoint = rMEvt.GetPosPixel();

        if ( aPoint.X() >= nSliderXOffset && aPoint.X() <= nControlWidth - nSliderXOffset )
        {
            mpImpl->mnCurrentZoom = Offset2Zoom( aPoint.X() );

            Rectangle aRect( Point( 0, 0 ), aSliderWindowSize  );
            Paint( aRect );

            mpImpl->mbOmitPaint = true; // optimization: paint before executing command,

            // commit state change
            SvxZoomSliderItem aZoomSliderItem( mpImpl->mnCurrentZoom );

            ::com::sun::star::uno::Any a;
            aZoomSliderItem.QueryValue( a );

            ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs( 1 );
            aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScalingFactor" ));
            aArgs[0].Value = a;

            SfxToolBoxControl::Dispatch( m_xDispatchProvider, String::CreateFromAscii(".uno:ScalingFactor"), aArgs );

            mpImpl->mbOmitPaint = false;
        }
    }
}

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

void ScZoomSliderWnd::UpdateFromItem( const SvxZoomSliderItem* pZoomSliderItem )
{
    if( pZoomSliderItem )
    {
        mpImpl->mnCurrentZoom = pZoomSliderItem->GetValue();
        mpImpl->mnMinZoom     = pZoomSliderItem->GetMinZoom();
        mpImpl->mnMaxZoom     = pZoomSliderItem->GetMaxZoom();

        DBG_ASSERT( mpImpl->mnMinZoom <= mpImpl->mnCurrentZoom &&
            mpImpl->mnMinZoom <  mpImpl->mnSliderCenter &&
            mpImpl->mnMaxZoom >= mpImpl->mnCurrentZoom &&
            mpImpl->mnMaxZoom > mpImpl->mnSliderCenter,
            "Looks like the zoom slider item is corrupted" );
       const com::sun::star::uno::Sequence < sal_Int32 > rSnappingPoints = pZoomSliderItem->GetSnappingPoints();
       mpImpl->maSnappingPointOffsets.clear();
       mpImpl->maSnappingPointZooms.clear();

       // get all snapping points:
       std::set< sal_uInt16 > aTmpSnappingPoints;
       for ( sal_uInt16 j = 0; j < rSnappingPoints.getLength(); ++j )
       {
           const sal_Int32 nSnappingPoint = rSnappingPoints[j];
           aTmpSnappingPoints.insert( (sal_uInt16)nSnappingPoint );
       }

       // remove snapping points that are to close to each other:
       std::set< sal_uInt16 >::iterator aSnappingPointIter;
       long nLastOffset = 0;

       for ( aSnappingPointIter = aTmpSnappingPoints.begin(); aSnappingPointIter != aTmpSnappingPoints.end(); ++aSnappingPointIter )
       {
           const sal_uInt16 nCurrent = *aSnappingPointIter;
           const long nCurrentOffset = Zoom2Offset( nCurrent );

           if ( nCurrentOffset - nLastOffset >= nSnappingPointsMinDist )
           {
               mpImpl->maSnappingPointOffsets.push_back( nCurrentOffset );
               mpImpl->maSnappingPointZooms.push_back( nCurrent );
               nLastOffset = nCurrentOffset;
           }
       }
    }

    Size aSliderWindowSize = GetOutputSizePixel();
    Rectangle aRect( Point( 0, 0 ), aSliderWindowSize );
   
    if ( !mpImpl->mbOmitPaint )
       Paint(aRect);
}

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

void ScZoomSliderWnd::Paint( const Rectangle& rRect )
{
    DoPaint( rRect );
}

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

void ScZoomSliderWnd::DoPaint( const Rectangle& /*rRect*/ )
{
    if( mpImpl->mbOmitPaint )
        return;

    Size aSliderWindowSize = GetOutputSizePixel();
    Rectangle aRect( Point( 0, 0 ), aSliderWindowSize );
    
    VirtualDevice* pVDev = new VirtualDevice( *this );
    pVDev->SetOutputSizePixel( aSliderWindowSize );

    Rectangle   aSlider = aRect;

    aSlider.Top()     += ( aSliderWindowSize.Height() - nSliderHeight )/2 - 1;
    aSlider.Bottom()   = aSlider.Top() + nSliderHeight;
    aSlider.Left()    += nSliderXOffset;
    aSlider.Right()   -= nSliderXOffset;

    Rectangle aFirstLine( aSlider );
    aFirstLine.Bottom() = aFirstLine.Top();

    Rectangle aSecondLine( aSlider );
    aSecondLine.Top() = aSecondLine.Bottom();

    Rectangle aLeft( aSlider );
    aLeft.Right() = aLeft.Left();

    Rectangle aRight( aSlider );
    aRight.Left() = aRight.Right();

    // draw VirtualDevice's background color
    Color  aStartColor,aEndColor;
    aStartColor = GetSettings().GetStyleSettings().GetFaceColor();
    aEndColor   = GetSettings().GetStyleSettings().GetFaceColor();
    if( aEndColor.IsDark() )
        aStartColor = aEndColor;

    Gradient g;
    g.SetAngle( 0 );
    g.SetStyle( GRADIENT_LINEAR );

    g.SetStartColor( aStartColor );
    g.SetEndColor( aEndColor );
    pVDev->DrawGradient( aRect, g );

    // draw slider
    pVDev->SetLineColor( Color ( COL_WHITE ) );
    pVDev->DrawRect( aSecondLine );
    pVDev->DrawRect( aRight );

    pVDev->SetLineColor( Color( COL_GRAY ) );
    pVDev->DrawRect( aFirstLine );
    pVDev->DrawRect( aLeft );

    // draw snapping points:
    std::vector< long >::iterator aSnappingPointIter;
    for ( aSnappingPointIter = mpImpl->maSnappingPointOffsets.begin();
        aSnappingPointIter != mpImpl->maSnappingPointOffsets.end();
        ++aSnappingPointIter )
    {
        pVDev->SetLineColor( Color( COL_GRAY ) );
        Rectangle aSnapping( aRect );
        aSnapping.Bottom()   = aSlider.Top();
        aSnapping.Top() = aSnapping.Bottom() - nSnappingHeight;
        aSnapping.Left() += *aSnappingPointIter;
        aSnapping.Right() = aSnapping.Left();
        pVDev->DrawRect( aSnapping );

        aSnapping.Top() += nSnappingHeight + nSliderHeight;
        aSnapping.Bottom() += nSnappingHeight + nSliderHeight;
        pVDev->DrawRect( aSnapping );
    }

    // draw slider button
    Point aImagePoint = aRect.TopLeft();
    aImagePoint.X() += Zoom2Offset( mpImpl->mnCurrentZoom );
    aImagePoint.X() -= nButtonWidth/2;
    aImagePoint.Y() += ( aSliderWindowSize.Height() - nButtonHeight)/2;
    pVDev->DrawImage( aImagePoint, mpImpl->maSliderButton );

    // draw decrease button
    aImagePoint = aRect.TopLeft();
    aImagePoint.X() += (nSliderXOffset - nIncDecWidth)/2;
    aImagePoint.Y() += ( aSliderWindowSize.Height() - nIncDecHeight)/2;
    pVDev->DrawImage( aImagePoint, mpImpl->maDecreaseButton );

    // draw increase button
    aImagePoint.X() = aRect.TopLeft().X() + aSliderWindowSize.Width() - nIncDecWidth - (nSliderXOffset - nIncDecWidth)/2;
    pVDev->DrawImage( aImagePoint, mpImpl->maIncreaseButton );
    
    DrawOutDev( Point(0, 0), aSliderWindowSize, Point(0, 0), aSliderWindowSize, *pVDev );

    delete pVDev;

}

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