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

// #include <math.h>
#include <limits.h>
#include <tools/time.hxx>
#include <tools/debug.hxx>

#include <svids.hrc>
#include <svdata.hxx>
#include <scrwnd.hxx>

#include <vcl/timer.hxx>
#include <vcl/event.hxx>

#include <math.h>
#include <limits.h>

// -----------
// - Defines -
// -----------

#define WHEEL_WIDTH     25
#define WHEEL_RADIUS    ((WHEEL_WIDTH) >> 1 )
#define MAX_TIME        300
#define MIN_TIME        20
#define DEF_TIMEOUT     50

// -------------------
// - ImplWheelWindow -
// -------------------

ImplWheelWindow::ImplWheelWindow( Window* pParent ) :
            FloatingWindow  ( pParent, 0 ),
            mnRepaintTime   ( 1UL ),
            mnTimeout       ( DEF_TIMEOUT ),
            mnWheelMode     ( WHEELMODE_NONE ),
            mnActDist       ( 0UL ),
            mnActDeltaX     ( 0L ),
            mnActDeltaY     ( 0L )
{
    // we need a parent
    DBG_ASSERT( pParent, "ImplWheelWindow::ImplWheelWindow(): Parent not set!" );

    const Size      aSize( pParent->GetOutputSizePixel() );
    const sal_uInt16    nFlags = ImplGetSVData()->maWinData.mnAutoScrollFlags;
    const sal_Bool      bHorz = ( nFlags & AUTOSCROLL_HORZ ) != 0;
    const sal_Bool      bVert = ( nFlags & AUTOSCROLL_VERT ) != 0;

    // calculate maximum speed distance
    mnMaxWidth = (sal_uLong) ( 0.4 * hypot( (double) aSize.Width(), aSize.Height() ) );

    // create wheel window
    SetTitleType( FLOATWIN_TITLE_NONE );
    ImplCreateImageList();
    ResMgr* pResMgr = ImplGetResMgr();
    Bitmap aBmp;
    if( pResMgr )
        aBmp = Bitmap( ResId( SV_RESID_BITMAP_SCROLLMSK, *pResMgr ) );
    ImplSetRegion( aBmp );

    // set wheel mode
    if( bHorz && bVert )
        ImplSetWheelMode( WHEELMODE_VH );
    else if( bHorz )
        ImplSetWheelMode( WHEELMODE_H );
    else
        ImplSetWheelMode( WHEELMODE_V );

    // init timer
    mpTimer = new Timer;
    mpTimer->SetTimeoutHdl( LINK( this, ImplWheelWindow, ImplScrollHdl ) );
    mpTimer->SetTimeout( mnTimeout );
    mpTimer->Start();

    CaptureMouse();
}

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

ImplWheelWindow::~ImplWheelWindow()
{
	ImplStop();
    delete mpTimer;
}

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

void ImplWheelWindow::ImplStop()
{
    ReleaseMouse();
    mpTimer->Stop();
	Show(sal_False);
}

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

void ImplWheelWindow::ImplSetRegion( const Bitmap& rRegionBmp )
{
    Point           aPos( GetPointerPosPixel() );
    const Size      aSize( rRegionBmp.GetSizePixel() );
    Point           aPoint;
    const Rectangle aRect( aPoint, aSize );

    maCenter = maLastMousePos = aPos;
    aPos.X() -= aSize.Width() >> 1;
    aPos.Y() -= aSize.Height() >> 1;

    SetPosSizePixel( aPos, aSize );
    SetWindowRegionPixel( rRegionBmp.CreateRegion( COL_BLACK, aRect ) );
}

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

void ImplWheelWindow::ImplCreateImageList()
{
    ResMgr* pResMgr = ImplGetResMgr();
    if( pResMgr )
        maImgList.InsertFromHorizontalBitmap
            ( ResId( SV_RESID_BITMAP_SCROLLBMP, *pResMgr ), 6, NULL );
}

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

void ImplWheelWindow::ImplSetWheelMode( sal_uLong nWheelMode )
{
    if( nWheelMode != mnWheelMode )
    {
        mnWheelMode = nWheelMode;

        if( WHEELMODE_NONE == mnWheelMode )
        {
            if( IsVisible() )
                Hide();
        }
        else
        {
            if( !IsVisible() )
                Show();

            ImplDrawWheel();
        }
    }
}

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

void ImplWheelWindow::ImplDrawWheel()
{
    sal_uInt16 nId;

    switch( mnWheelMode )
    {
        case( WHEELMODE_VH ):       nId = 1; break;
        case( WHEELMODE_V    ):     nId = 2; break;
        case( WHEELMODE_H    ):     nId = 3; break;
        case( WHEELMODE_SCROLL_VH ):nId = 4; break;
        case( WHEELMODE_SCROLL_V ): nId = 5; break;
        case( WHEELMODE_SCROLL_H ): nId = 6; break;
        default:                    nId = 0; break;
    }

    if( nId )
        DrawImage( Point(), maImgList.GetImage( nId ) );
}

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

void ImplWheelWindow::ImplRecalcScrollValues()
{
    if( mnActDist < WHEEL_RADIUS )
    {
        mnActDeltaX = mnActDeltaY = 0L;
        mnTimeout = DEF_TIMEOUT;
    }
    else
    {
        sal_uLong nCurTime;

        // calc current time
        if( mnMaxWidth )
        {
            const double fExp = ( (double) mnActDist / mnMaxWidth ) * log10( (double) MAX_TIME / MIN_TIME );
            nCurTime = (sal_uLong) ( MAX_TIME / pow( 10., fExp ) );
        }
        else
            nCurTime = MAX_TIME;

        if( !nCurTime )
            nCurTime = 1UL;

        if( mnRepaintTime <= nCurTime )
            mnTimeout = nCurTime - mnRepaintTime;
        else
        {
            long nMult = mnRepaintTime / nCurTime;

            if( !( mnRepaintTime % nCurTime ) )
                mnTimeout = 0UL;
            else
                mnTimeout = ++nMult * nCurTime - mnRepaintTime;

            double fValX = (double) mnActDeltaX * nMult;
            double fValY = (double) mnActDeltaY * nMult;

            if( fValX > LONG_MAX )
                mnActDeltaX = LONG_MAX;
            else if( fValX < LONG_MIN )
                mnActDeltaX = LONG_MIN;
            else
                mnActDeltaX = (long) fValX;

            if( fValY > LONG_MAX )
                mnActDeltaY = LONG_MAX;
            else if( fValY < LONG_MIN )
                mnActDeltaY = LONG_MIN;
            else
                mnActDeltaY = (long) fValY;
        }
    }
}

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

PointerStyle ImplWheelWindow::ImplGetMousePointer( long nDistX, long nDistY )
{
    PointerStyle    eStyle;
    const sal_uInt16    nFlags = ImplGetSVData()->maWinData.mnAutoScrollFlags;
    const sal_Bool      bHorz = ( nFlags & AUTOSCROLL_HORZ ) != 0;
    const sal_Bool      bVert = ( nFlags & AUTOSCROLL_VERT ) != 0;

    if( bHorz || bVert )
    {
        if( mnActDist < WHEEL_RADIUS )
        {
            if( bHorz && bVert )
                eStyle = POINTER_AUTOSCROLL_NSWE;
            else if( bHorz )
                eStyle = POINTER_AUTOSCROLL_WE;
            else
                eStyle = POINTER_AUTOSCROLL_NS;
        }
        else
        {
            double fAngle = atan2( (double) -nDistY, nDistX ) / F_PI180;

            if( fAngle < 0.0 )
                fAngle += 360.;

            if( bHorz && bVert )
            {
                if( fAngle >= 22.5 && fAngle <= 67.5 )
                    eStyle = POINTER_AUTOSCROLL_NE;
                else if( fAngle >= 67.5 && fAngle <= 112.5 )
                    eStyle = POINTER_AUTOSCROLL_N;
                else if( fAngle >= 112.5 && fAngle <= 157.5 )
                    eStyle = POINTER_AUTOSCROLL_NW;
                else if( fAngle >= 157.5 && fAngle <= 202.5 )
                    eStyle = POINTER_AUTOSCROLL_W;
                else if( fAngle >= 202.5 && fAngle <= 247.5 )
                    eStyle = POINTER_AUTOSCROLL_SW;
                else if( fAngle >= 247.5 && fAngle <= 292.5 )
                    eStyle = POINTER_AUTOSCROLL_S;
                else if( fAngle >= 292.5 && fAngle <= 337.5 )
                    eStyle = POINTER_AUTOSCROLL_SE;
                else
                    eStyle = POINTER_AUTOSCROLL_E;
            }
            else if( bHorz )
            {
                if( fAngle >= 270. || fAngle <= 90. )
                    eStyle = POINTER_AUTOSCROLL_E;
                else
                    eStyle = POINTER_AUTOSCROLL_W;
            }
            else
            {
                if( fAngle >= 0. && fAngle <= 180. )
                    eStyle = POINTER_AUTOSCROLL_N;
                else
                    eStyle = POINTER_AUTOSCROLL_S;
            }
        }
    }
    else
        eStyle = POINTER_ARROW;

    return eStyle;
}

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

void ImplWheelWindow::Paint( const Rectangle& )
{
    ImplDrawWheel();
}

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

void ImplWheelWindow::MouseMove( const MouseEvent& rMEvt )
{
    FloatingWindow::MouseMove( rMEvt );

    const Point aMousePos( OutputToScreenPixel( rMEvt.GetPosPixel() ) );
    const long  nDistX = aMousePos.X() - maCenter.X();
    const long  nDistY = aMousePos.Y() - maCenter.Y();

    mnActDist = (sal_uLong) hypot( (double) nDistX, nDistY );

    const PointerStyle  eActStyle = ImplGetMousePointer( nDistX, nDistY );
    const sal_uInt16        nFlags = ImplGetSVData()->maWinData.mnAutoScrollFlags;
    const sal_Bool          bHorz = ( nFlags & AUTOSCROLL_HORZ ) != 0;
    const sal_Bool          bVert = ( nFlags & AUTOSCROLL_VERT ) != 0;
    const sal_Bool          bOuter = mnActDist > WHEEL_RADIUS;

    if( bOuter && ( maLastMousePos != aMousePos ) )
    {
        switch( eActStyle )
        {
            case( POINTER_AUTOSCROLL_N ):   mnActDeltaX = +0L, mnActDeltaY = +1L; break;
            case( POINTER_AUTOSCROLL_S ):   mnActDeltaX = +0L, mnActDeltaY = -1L; break;
            case( POINTER_AUTOSCROLL_W ):   mnActDeltaX = +1L, mnActDeltaY = +0L; break;
            case( POINTER_AUTOSCROLL_E ):   mnActDeltaX = -1L, mnActDeltaY = +0L; break;
            case( POINTER_AUTOSCROLL_NW ):  mnActDeltaX = +1L, mnActDeltaY = +1L; break;
            case( POINTER_AUTOSCROLL_NE ):  mnActDeltaX = -1L, mnActDeltaY = +1L; break;
            case( POINTER_AUTOSCROLL_SW ):  mnActDeltaX = +1L, mnActDeltaY = -1L; break;
            case( POINTER_AUTOSCROLL_SE ):  mnActDeltaX = -1L, mnActDeltaY = -1L; break;

            default:
            break;
        }
    }

    ImplRecalcScrollValues();
    maLastMousePos = aMousePos;
    SetPointer( eActStyle );

    if( bHorz && bVert )
        ImplSetWheelMode( bOuter ? WHEELMODE_SCROLL_VH : WHEELMODE_VH );
    else if( bHorz )
        ImplSetWheelMode( bOuter ? WHEELMODE_SCROLL_H : WHEELMODE_H );
    else
        ImplSetWheelMode( bOuter ? WHEELMODE_SCROLL_V : WHEELMODE_V );
}

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

void ImplWheelWindow::MouseButtonUp( const MouseEvent& rMEvt )
{
    if( mnActDist > WHEEL_RADIUS )
        GetParent()->EndAutoScroll();
    else
        FloatingWindow::MouseButtonUp( rMEvt );
}

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

IMPL_LINK( ImplWheelWindow, ImplScrollHdl, Timer*, EMPTYARG )
{
    if ( mnActDeltaX || mnActDeltaY )
    {
        Window*             pWindow = GetParent();
        const Point         aMousePos( pWindow->OutputToScreenPixel( pWindow->GetPointerPosPixel() ) );
        Point               aCmdMousePos( pWindow->ImplFrameToOutput( aMousePos ) );
        CommandScrollData   aScrollData( mnActDeltaX, mnActDeltaY );
        CommandEvent        aCEvt( aCmdMousePos, COMMAND_AUTOSCROLL, sal_True, &aScrollData );
        NotifyEvent         aNCmdEvt( EVENT_COMMAND, pWindow, &aCEvt );

        if ( !ImplCallPreNotify( aNCmdEvt ) )
        {
            const sal_uLong nTime = Time::GetSystemTicks();
			ImplDelData aDel( this );
            pWindow->Command( aCEvt );
			if( aDel.IsDead() )
				return 0;
            mnRepaintTime = Max( Time::GetSystemTicks() - nTime, 1UL );
            ImplRecalcScrollValues();
        }
    }

    if ( mnTimeout != mpTimer->GetTimeout() )
        mpTimer->SetTimeout( mnTimeout );
    mpTimer->Start();

    return 0L;
}
