/*
 * Copyright (C) 2004, 2006, 2008, 2015 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "Scrollbar.h"

#include "FrameView.h"
#include "GraphicsContext.h"
#include "PlatformMouseEvent.h"
#include "ScrollAnimator.h"
#include "ScrollView.h"
#include "ScrollableArea.h"
#include "ScrollbarTheme.h"
#include "ScrollbarsController.h"
#include <algorithm>

#if PLATFORM(GTK)
// The position of the scrollbar thumb affects the appearance of the steppers, so
// when the thumb moves, we have to invalidate them for painting.
#define THUMB_POSITION_AFFECTS_BUTTONS
#endif

namespace WebCore {

Ref<Scrollbar> Scrollbar::createNativeScrollbar(ScrollableArea& scrollableArea, ScrollbarOrientation orientation, ScrollbarControlSize size)
{
    return adoptRef(*new Scrollbar(scrollableArea, orientation, size));
}

int Scrollbar::maxOverlapBetweenPages()
{
    static int maxOverlapBetweenPages = ScrollbarTheme::theme().maxOverlapBetweenPages();
    return maxOverlapBetweenPages;
}

Scrollbar::Scrollbar(ScrollableArea& scrollableArea, ScrollbarOrientation orientation, ScrollbarControlSize controlSize, ScrollbarTheme* customTheme, bool isCustomScrollbar)
    : m_scrollableArea(scrollableArea)
    , m_orientation(orientation)
    , m_controlSize(controlSize)
    , m_theme(customTheme ? *customTheme : ScrollbarTheme::theme())
    , m_isCustomScrollbar(isCustomScrollbar)
    , m_scrollTimer(*this, &Scrollbar::autoscrollTimerFired)
{
    theme().registerScrollbar(*this);

    // FIXME: This is ugly and would not be necessary if we fix cross-platform code to actually query for
    // scrollbar thickness and use it when sizing scrollbars (rather than leaving one dimension of the scrollbar
    // alone when sizing).
    int thickness = theme().scrollbarThickness(controlSize);
    Widget::setFrameRect(IntRect(0, 0, thickness, thickness));

    m_currentPos = static_cast<float>(offsetForOrientation(m_scrollableArea.scrollOffset(), m_orientation));
}

Scrollbar::~Scrollbar()
{
    stopTimerIfNeeded();
    
    theme().unregisterScrollbar(*this);
}

int Scrollbar::occupiedWidth() const
{
    return isOverlayScrollbar() ? 0 : width();
}

int Scrollbar::occupiedHeight() const
{
    return isOverlayScrollbar() ? 0 : height();
}

void Scrollbar::offsetDidChange()
{
    float position = static_cast<float>(offsetForOrientation(m_scrollableArea.scrollOffset(), m_orientation));
    if (position == m_currentPos)
        return;

    int oldThumbPosition = theme().thumbPosition(*this);
    m_currentPos = position;
    updateThumbPosition();
    if (m_pressedPart == ThumbPart)
        setPressedPos(m_pressedPos + theme().thumbPosition(*this) - oldThumbPosition);
}

void Scrollbar::setProportion(int visibleSize, int totalSize)
{
    if (visibleSize == m_visibleSize && totalSize == m_totalSize)
        return;

    m_visibleSize = visibleSize;
    m_totalSize = totalSize;

    updateThumbProportion();
}

void Scrollbar::setSteps(int lineStep, int pageStep, int pixelsPerStep)
{
    m_lineStep = lineStep;
    m_pageStep = pageStep;
    m_pixelStep = 1.0f / pixelsPerStep;
}

void Scrollbar::updateThumb()
{
#ifdef THUMB_POSITION_AFFECTS_BUTTONS
    invalidate();
#else
    theme().invalidateParts(*this, ForwardTrackPart | BackTrackPart | ThumbPart);
#endif
}

void Scrollbar::updateThumbPosition()
{
    updateThumb();
}

void Scrollbar::updateThumbProportion()
{
    updateThumb();
}

void Scrollbar::paint(GraphicsContext& context, const IntRect& damageRect, Widget::SecurityOriginPaintPolicy, EventRegionContext*)
{
    if (context.invalidatingControlTints() && theme().supportsControlTints()) {
        invalidate();
        return;
    }

    if (context.paintingDisabled() || !frameRect().intersects(damageRect))
        return;

    if (!theme().paint(*this, context, damageRect))
        Widget::paint(context, damageRect);
}

void Scrollbar::autoscrollTimerFired()
{
    autoscrollPressedPart(theme().autoscrollTimerDelay());
}

static bool thumbUnderMouse(Scrollbar* scrollbar)
{
    int thumbPos = scrollbar->theme().trackPosition(*scrollbar) + scrollbar->theme().thumbPosition(*scrollbar);
    int thumbLength = scrollbar->theme().thumbLength(*scrollbar);
    return scrollbar->pressedPos() >= thumbPos && scrollbar->pressedPos() < thumbPos + thumbLength;
}

void Scrollbar::autoscrollPressedPart(Seconds delay)
{
    // Don't do anything for the thumb or if nothing was pressed.
    if (m_pressedPart == ThumbPart || m_pressedPart == NoPart)
        return;

    // Handle the track.
    if ((m_pressedPart == BackTrackPart || m_pressedPart == ForwardTrackPart) && thumbUnderMouse(this)) {
        theme().invalidatePart(*this, m_pressedPart);
        setHoveredPart(ThumbPart);
        return;
    }

    // Handle the arrows and track.
    if (m_scrollableArea.scroll(pressedPartScrollDirection(), pressedPartScrollGranularity()))
        startTimerIfNeeded(delay);
}

void Scrollbar::startTimerIfNeeded(Seconds delay)
{
    // Don't do anything for the thumb.
    if (m_pressedPart == ThumbPart)
        return;

    // Handle the track.  We halt track scrolling once the thumb is level
    // with us.
    if ((m_pressedPart == BackTrackPart || m_pressedPart == ForwardTrackPart) && thumbUnderMouse(this)) {
        theme().invalidatePart(*this, m_pressedPart);
        setHoveredPart(ThumbPart);
        return;
    }

    // We can't scroll if we've hit the beginning or end.
    ScrollDirection dir = pressedPartScrollDirection();
    if (dir == ScrollUp || dir == ScrollLeft) {
        if (m_currentPos == 0)
            return;
    } else {
        if (m_currentPos == maximum())
            return;
    }

    m_scrollTimer.startOneShot(delay);
}

void Scrollbar::stopTimerIfNeeded()
{
    if (m_scrollTimer.isActive())
        m_scrollTimer.stop();
}

ScrollDirection Scrollbar::pressedPartScrollDirection()
{
    if (m_orientation == HorizontalScrollbar) {
        if (m_pressedPart == BackButtonStartPart || m_pressedPart == BackButtonEndPart || m_pressedPart == BackTrackPart)
            return ScrollLeft;
        return ScrollRight;
    } else {
        if (m_pressedPart == BackButtonStartPart || m_pressedPart == BackButtonEndPart || m_pressedPart == BackTrackPart)
            return ScrollUp;
        return ScrollDown;
    }
}

ScrollGranularity Scrollbar::pressedPartScrollGranularity()
{
    if (m_pressedPart == BackButtonStartPart || m_pressedPart == BackButtonEndPart ||  m_pressedPart == ForwardButtonStartPart || m_pressedPart == ForwardButtonEndPart)
        return ScrollByLine;
    return ScrollByPage;
}

void Scrollbar::moveThumb(int pos, bool draggingDocument)
{
    int delta = pos - m_pressedPos;

    if (draggingDocument) {
        if (m_draggingDocument)
            delta = pos - m_documentDragPos;
        m_draggingDocument = true;
        FloatPoint currentPosition = m_scrollableArea.scrollAnimator().currentPosition();
        int destinationPosition = (m_orientation == HorizontalScrollbar ? currentPosition.x() : currentPosition.y()) + delta;
        if (delta > 0)
            destinationPosition = std::min(destinationPosition + delta, maximum());
        else if (delta < 0)
            destinationPosition = std::max(destinationPosition + delta, 0);
        m_scrollableArea.scrollToOffsetWithoutAnimation(m_orientation, destinationPosition);
        m_documentDragPos = pos;
        return;
    }

    if (m_draggingDocument) {
        delta += m_pressedPos - m_documentDragPos;
        m_draggingDocument = false;
    }

    // Drag the thumb.
    int thumbPos = theme().thumbPosition(*this);
    int thumbLen = theme().thumbLength(*this);
    int trackLen = theme().trackLength(*this);
    int maxPos = trackLen - thumbLen;
    if (delta > 0)
        delta = std::min(maxPos - thumbPos, delta);
    else if (delta < 0)
        delta = std::max(-thumbPos, delta);
    
    if (delta) {
        float newPosition = static_cast<float>(thumbPos + delta) * maximum() / (trackLen - thumbLen);
        m_scrollableArea.scrollToOffsetWithoutAnimation(m_orientation, newPosition);
    }
}

void Scrollbar::setHoveredPart(ScrollbarPart part)
{
    if (part == m_hoveredPart)
        return;

    if ((m_hoveredPart == NoPart || part == NoPart) && theme().invalidateOnMouseEnterExit())
        invalidate();  // Just invalidate the whole scrollbar, since the buttons at either end change anyway.
    else if (m_pressedPart == NoPart) {  // When there's a pressed part, we don't draw a hovered state, so there's no reason to invalidate.
        theme().invalidatePart(*this, part);
        theme().invalidatePart(*this, m_hoveredPart);
    }
    m_hoveredPart = part;
}

void Scrollbar::setPressedPart(ScrollbarPart part)
{
    if (m_pressedPart != NoPart)
        theme().invalidatePart(*this, m_pressedPart);
    m_pressedPart = part;
    if (m_pressedPart != NoPart)
        theme().invalidatePart(*this, m_pressedPart);
    else if (m_hoveredPart != NoPart)  // When we no longer have a pressed part, we can start drawing a hovered state on the hovered part.
        theme().invalidatePart(*this, m_hoveredPart);
}

#if !PLATFORM(IOS_FAMILY)
bool Scrollbar::mouseMoved(const PlatformMouseEvent& evt)
{
    if (m_pressedPart == ThumbPart) {
        if (theme().shouldSnapBackToDragOrigin(*this, evt))
            m_scrollableArea.scrollToOffsetWithoutAnimation(m_orientation, m_dragOrigin);
        else {
            moveThumb(m_orientation == HorizontalScrollbar ? 
                      convertFromContainingWindow(evt.position()).x() :
                      convertFromContainingWindow(evt.position()).y(), theme().shouldDragDocumentInsteadOfThumb(*this, evt));
        }
        return true;
    }

    if (m_pressedPart != NoPart)
        m_pressedPos = (orientation() == HorizontalScrollbar ? convertFromContainingWindow(evt.position()).x() : convertFromContainingWindow(evt.position()).y());

    ScrollbarPart part = theme().hitTest(*this, evt.position());
    if (part != m_hoveredPart) {
        if (m_pressedPart != NoPart) {
            if (part == m_pressedPart) {
                // The mouse is moving back over the pressed part.  We
                // need to start up the timer action again.
                startTimerIfNeeded(theme().autoscrollTimerDelay());
                theme().invalidatePart(*this, m_pressedPart);
            } else if (m_hoveredPart == m_pressedPart) {
                // The mouse is leaving the pressed part.  Kill our timer
                // if needed.
                stopTimerIfNeeded();
                theme().invalidatePart(*this, m_pressedPart);
            }
        } 
        
        setHoveredPart(part);
    } 

    return true;
}
#endif

void Scrollbar::mouseEntered()
{
    m_scrollableArea.mouseEnteredScrollbar(this);
}

bool Scrollbar::mouseExited()
{
    m_scrollableArea.mouseExitedScrollbar(this);
    setHoveredPart(NoPart);
    return true;
}

bool Scrollbar::mouseUp(const PlatformMouseEvent& mouseEvent)
{
    auto previouslyPressedPart = m_pressedPart;
    setPressedPart(NoPart);
    m_pressedPos = 0;
    m_draggingDocument = false;
    stopTimerIfNeeded();

    m_scrollableArea.mouseIsDownInScrollbar(this, false);

    // m_hoveredPart won't be updated until the next mouseMoved or mouseDown, so we have to hit test
    // to really know if the mouse has exited the scrollbar on a mouseUp.
    ScrollbarPart part = theme().hitTest(*this, mouseEvent.position());
    if (part == NoPart)
        m_scrollableArea.mouseExitedScrollbar(this);

    if (previouslyPressedPart == ThumbPart)
        m_scrollableArea.doPostThumbMoveSnapping(m_orientation);

    return true;
}

bool Scrollbar::mouseDown(const PlatformMouseEvent& evt)
{
    ScrollbarPart pressedPart = theme().hitTest(*this, evt.position());
    auto action = theme().handleMousePressEvent(*this, evt, pressedPart);
    if (action == ScrollbarButtonPressAction::None)
        return true;

    m_scrollableArea.mouseIsDownInScrollbar(this, true);
    setPressedPart(pressedPart);

    int pressedPosition = (orientation() == HorizontalScrollbar ? convertFromContainingWindow(evt.position()).x() : convertFromContainingWindow(evt.position()).y());
    if (action == ScrollbarButtonPressAction::CenterOnThumb) {
        setHoveredPart(ThumbPart);
        setPressedPart(ThumbPart);
        m_dragOrigin = m_currentPos;
        // Set the pressed position to the middle of the thumb so that when we do the move, the delta
        // will be from the current pixel position of the thumb to the new desired position for the thumb.
        m_pressedPos = theme().trackPosition(*this) + theme().thumbPosition(*this) + theme().thumbLength(*this) / 2;
        moveThumb(pressedPosition);
        return true;
    }

    m_pressedPos = pressedPosition;

    if (action == ScrollbarButtonPressAction::StartDrag)
        m_dragOrigin = m_currentPos;

    if (action == ScrollbarButtonPressAction::Scroll)
        autoscrollPressedPart(theme().initialAutoscrollTimerDelay());

    return true;
}

void Scrollbar::setEnabled(bool e)
{ 
    if (m_enabled == e)
        return;
    m_enabled = e;
    theme().updateEnabledState(*this);
    invalidate();
}

bool Scrollbar::isOverlayScrollbar() const
{
    return theme().usesOverlayScrollbars();
}

bool Scrollbar::shouldParticipateInHitTesting()
{
    // Non-overlay scrollbars should always participate in hit testing.
    if (!isOverlayScrollbar())
        return true;
    return m_scrollableArea.scrollbarsController().shouldScrollbarParticipateInHitTesting(this);
}

bool Scrollbar::isWindowActive() const
{
    return m_scrollableArea.isActive();
}

void Scrollbar::invalidateRect(const IntRect& rect)
{
    if (suppressInvalidation())
        return;

    m_scrollableArea.invalidateScrollbar(*this, rect);
}

IntRect Scrollbar::convertToContainingView(const IntRect& localRect) const
{
    return m_scrollableArea.convertFromScrollbarToContainingView(*this, localRect);
}

IntRect Scrollbar::convertFromContainingView(const IntRect& parentRect) const
{
    return m_scrollableArea.convertFromContainingViewToScrollbar(*this, parentRect);
}

IntPoint Scrollbar::convertToContainingView(const IntPoint& localPoint) const
{
    return m_scrollableArea.convertFromScrollbarToContainingView(*this, localPoint);
}

IntPoint Scrollbar::convertFromContainingView(const IntPoint& parentPoint) const
{
    return m_scrollableArea.convertFromContainingViewToScrollbar(*this, parentPoint);
}

bool Scrollbar::supportsUpdateOnSecondaryThread() const
{
    // It's unfortunate that this needs to be done with an ifdef. Ideally there would be a way to feature-detect
    // the necessary support within AppKit.
#if ENABLE(ASYNC_SCROLLING) && PLATFORM(MAC)
    return !m_scrollableArea.forceUpdateScrollbarsOnMainThreadForPerformanceTesting()
        && (m_scrollableArea.hasLayerForVerticalScrollbar() || m_scrollableArea.hasLayerForHorizontalScrollbar())
        && m_scrollableArea.usesAsyncScrolling();
#else
    return false;
#endif
}

} // namespace WebCore
