/*
 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
 *
 * Portions are Copyright (C) 1998 Netscape Communications Corporation.
 *
 * Other contributors:
 *   Robert O'Callahan <roc+@cs.cmu.edu>
 *   David Baron <dbaron@fas.harvard.edu>
 *   Christian Biesinger <cbiesinger@web.de>
 *   Randall Jesup <rjesup@wgate.com>
 *   Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
 *   Josh Soref <timeless@mac.com>
 *   Boris Zbarsky <bzbarsky@mit.edu>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Alternatively, the contents of this file may be used under the terms
 * of either the Mozilla Public License Version 1.1, found at
 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
 * (the "GPL"), in which case the provisions of the MPL or the GPL are
 * applicable instead of those above.  If you wish to allow use of your
 * version of this file only under the terms of one of those two
 * licenses (the MPL or the GPL) and not to allow others to use your
 * version of this file under the LGPL, indicate your decision by
 * deletingthe provisions above and replace them with the notice and
 * other provisions required by the MPL or the GPL, as the case may be.
 * If you do not delete the provisions above, a recipient may use your
 * version of this file under any of the LGPL, the MPL or the GPL.
 */

#include "config.h"

#include "RenderMarquee.h"

#include "FrameView.h"
#include "HTMLMarqueeElement.h"
#include "HTMLNames.h"
#include "RenderLayer.h"
#include "RenderLayerScrollableArea.h"
#include "RenderView.h"

namespace WebCore {

using namespace HTMLNames;

RenderMarquee::RenderMarquee(RenderLayer* layer)
    : m_layer(layer)
    , m_timer(*this, &RenderMarquee::timerFired)
{
    ASSERT(layer);
    ASSERT(layer->scrollableArea());
    layer->scrollableArea()->setScrollClamping(ScrollClamping::Unclamped);
}

RenderMarquee::~RenderMarquee() = default;

int RenderMarquee::marqueeSpeed() const
{
    int result = m_layer->renderer().style().marqueeSpeed();
    Element* element = m_layer->renderer().element();
    if (is<HTMLMarqueeElement>(element))
        result = std::max(result, downcast<HTMLMarqueeElement>(*element).minimumDelay());
    return result;
}

static MarqueeDirection reverseDirection(MarqueeDirection direction)
{
    switch (direction) {
    case MarqueeDirection::Auto:
        return MarqueeDirection::Auto;
    case MarqueeDirection::Left:
        return MarqueeDirection::Right;
    case MarqueeDirection::Right:
        return MarqueeDirection::Left;
    case MarqueeDirection::Up:
        return MarqueeDirection::Down;
    case MarqueeDirection::Down:
        return MarqueeDirection::Up;
    case MarqueeDirection::Backward:
        return MarqueeDirection::Forward;
    case MarqueeDirection::Forward:
        return MarqueeDirection::Backward;
    }
    return MarqueeDirection::Auto;
}

MarqueeDirection RenderMarquee::direction() const
{
    // FIXME: Support the CSS3 "auto" value for determining the direction of the marquee.
    // For now just map MarqueeDirection::Auto to MarqueeDirection::Backward
    MarqueeDirection result = m_layer->renderer().style().marqueeDirection();
    TextDirection dir = m_layer->renderer().style().direction();
    if (result == MarqueeDirection::Auto)
        result = MarqueeDirection::Backward;
    if (result == MarqueeDirection::Forward)
        result = (dir == TextDirection::LTR) ? MarqueeDirection::Right : MarqueeDirection::Left;
    if (result == MarqueeDirection::Backward)
        result = (dir == TextDirection::LTR) ? MarqueeDirection::Left : MarqueeDirection::Right;
    
    // Now we have the real direction.  Next we check to see if the increment is negative.
    // If so, then we reverse the direction.
    Length increment = m_layer->renderer().style().marqueeIncrement();
    if (increment.isNegative())
        result = reverseDirection(result);
    
    return result;
}

bool RenderMarquee::isHorizontal() const
{
    return direction() == MarqueeDirection::Left || direction() == MarqueeDirection::Right;
}

int RenderMarquee::computePosition(MarqueeDirection dir, bool stopAtContentEdge)
{
    RenderBox* box = m_layer->renderBox();
    ASSERT(box);
    auto& boxStyle = box->style();
    if (isHorizontal()) {
        bool ltr = boxStyle.isLeftToRightDirection();
        LayoutUnit clientWidth = box->clientWidth();
        LayoutUnit contentWidth = ltr ? box->maxPreferredLogicalWidth() : box->minPreferredLogicalWidth();
        if (ltr)
            contentWidth += (box->paddingRight() - box->borderLeft());
        else {
            contentWidth = box->width() - contentWidth;
            contentWidth += (box->paddingLeft() - box->borderRight());
        }
        if (dir == MarqueeDirection::Right) {
            if (stopAtContentEdge)
                return std::max<LayoutUnit>(0, ltr ? (contentWidth - clientWidth) : (clientWidth - contentWidth));

            return ltr ? contentWidth : clientWidth;
        }

        if (stopAtContentEdge)
            return std::min<LayoutUnit>(0, ltr ? (contentWidth - clientWidth) : (clientWidth - contentWidth));

        return ltr ? -clientWidth : -contentWidth;
    }

    // Vertical
    int contentHeight = box->layoutOverflowRect().maxY() - box->borderTop() + box->paddingBottom();
    int clientHeight = roundToInt(box->clientHeight());
    if (dir == MarqueeDirection::Up) {
        if (stopAtContentEdge)
            return std::min(contentHeight - clientHeight, 0);

        return -clientHeight;
    }

    if (stopAtContentEdge)
        return std::max(contentHeight - clientHeight, 0);

    return contentHeight;
}

void RenderMarquee::start()
{
    if (m_timer.isActive() || m_layer->renderer().style().marqueeIncrement().isZero())
        return;

    auto* scrollableArea = m_layer->scrollableArea();
    ASSERT(scrollableArea);

    auto details = ScrollPositionChangeOptions::createProgrammaticUnclamped();
    if (!m_suspended && !m_stopped) {
        if (isHorizontal())
            scrollableArea->scrollToOffset(ScrollOffset(m_start, 0), details);
        else
            scrollableArea->scrollToOffset(ScrollOffset(0, m_start), details);
    } else {
        m_suspended = false;
        m_stopped = false;
    }

    m_timer.startRepeating(1_ms * speed());
}

void RenderMarquee::suspend()
{
    m_timer.stop();
    m_suspended = true;
}

void RenderMarquee::stop()
{
    m_timer.stop();
    m_stopped = true;
}

void RenderMarquee::updateMarqueePosition()
{
    bool activate = (m_totalLoops <= 0 || m_currentLoop < m_totalLoops);
    if (activate) {
        MarqueeBehavior behavior = m_layer->renderer().style().marqueeBehavior();
        m_start = computePosition(direction(), behavior == MarqueeBehavior::Alternate);
        m_end = computePosition(reverseDirection(direction()), behavior == MarqueeBehavior::Alternate || behavior == MarqueeBehavior::Slide);
        if (!m_stopped)
            start();
    }
}

void RenderMarquee::updateMarqueeStyle()
{
    auto& style = m_layer->renderer().style();
    
    if (m_direction != style.marqueeDirection() || (m_totalLoops != style.marqueeLoopCount() && m_currentLoop >= m_totalLoops))
        m_currentLoop = 0; // When direction changes or our loopCount is a smaller number than our current loop, reset our loop.
    
    m_totalLoops = style.marqueeLoopCount();
    m_direction = style.marqueeDirection();
    
    if (m_layer->renderer().isHTMLMarquee()) {
        // Hack for WinIE.  In WinIE, a value of 0 or lower for the loop count for SLIDE means to only do
        // one loop.
        if (m_totalLoops <= 0 && style.marqueeBehavior() == MarqueeBehavior::Slide)
            m_totalLoops = 1;
    }
    
    if (speed() != marqueeSpeed()) {
        m_speed = marqueeSpeed();
        if (m_timer.isActive())
            m_timer.startRepeating(1_ms * speed());
    }
    
    // Check the loop count to see if we should now stop.
    bool activate = (m_totalLoops <= 0 || m_currentLoop < m_totalLoops);
    if (activate && !m_timer.isActive())
        m_layer->renderer().setNeedsLayout();
    else if (!activate && m_timer.isActive())
        m_timer.stop();
}

void RenderMarquee::timerFired()
{
    if (m_layer->renderer().view().needsLayout())
        return;

    auto* scrollableArea = m_layer->scrollableArea();
    ASSERT(scrollableArea);

    if (m_reset) {
        m_reset = false;
        if (isHorizontal())
            scrollableArea->scrollToXOffset(m_start);
        else
            scrollableArea->scrollToYOffset(m_start);
        return;
    }
    
    const RenderStyle& style = m_layer->renderer().style();
    
    int endPoint = m_end;
    int range = m_end - m_start;
    int newPos;
    if (range == 0)
        newPos = m_end;
    else {  
        bool addIncrement = direction() == MarqueeDirection::Up || direction() == MarqueeDirection::Left;
        bool isReversed = style.marqueeBehavior() == MarqueeBehavior::Alternate && m_currentLoop % 2;
        if (isReversed) {
            // We're going in the reverse direction.
            endPoint = m_start;
            range = -range;
            addIncrement = !addIncrement;
        }
        bool positive = range > 0;
        int clientSize = (isHorizontal() ? roundToInt(m_layer->renderBox()->clientWidth()) : roundToInt(m_layer->renderBox()->clientHeight()));
        int increment = abs(intValueForLength(m_layer->renderer().style().marqueeIncrement(), clientSize));
        int currentPos = (isHorizontal() ? scrollableArea->scrollOffset().x() : scrollableArea->scrollOffset().y());
        newPos =  currentPos + (addIncrement ? increment : -increment);
        if (positive)
            newPos = std::min(newPos, endPoint);
        else
            newPos = std::max(newPos, endPoint);
    }

    if (newPos == endPoint) {
        m_currentLoop++;
        if (m_totalLoops > 0 && m_currentLoop >= m_totalLoops)
            m_timer.stop();
        else if (style.marqueeBehavior() != MarqueeBehavior::Alternate)
            m_reset = true;
    }
    
    if (isHorizontal())
        scrollableArea->scrollToXOffset(newPos);
    else
        scrollableArea->scrollToYOffset(newPos);
}

} // namespace WebCore
