/*
 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
 * Copyright (C) 2010 Google 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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "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 THE COPYRIGHT
 * OWNER 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 "SliderThumbElement.h"

#include "Event.h"
#include "Frame.h"
#include "HTMLInputElement.h"
#include "HTMLParserIdioms.h"
#include "MouseEvent.h"
#include "RenderSlider.h"
#include "RenderTheme.h"
#include "StepRange.h"
#include <wtf/MathExtras.h>

#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
#include "Page.h"
#include "TouchEvent.h"
#endif

using namespace std;

namespace WebCore {

// FIXME: Find a way to cascade appearance (see the layout method) and get rid of this class.
class RenderSliderThumb : public RenderBlock {
public:
    RenderSliderThumb(Node*);

private:
    virtual void layout();
};

RenderSliderThumb::RenderSliderThumb(Node* node)
    : RenderBlock(node)
{
}

void RenderSliderThumb::layout()
{
    // FIXME: Hard-coding this cascade of appearance is bad, because it's something
    // that CSS usually does. We need to find a way to express this in CSS.
    RenderStyle* parentStyle = parent()->style();
    if (parentStyle->appearance() == SliderVerticalPart)
        style()->setAppearance(SliderThumbVerticalPart);
    else if (parentStyle->appearance() == SliderHorizontalPart)
        style()->setAppearance(SliderThumbHorizontalPart);
    else if (parentStyle->appearance() == MediaSliderPart)
        style()->setAppearance(MediaSliderThumbPart);
    else if (parentStyle->appearance() == MediaVolumeSliderPart)
        style()->setAppearance(MediaVolumeSliderThumbPart);

    if (style()->hasAppearance()) {
        // FIXME: This should pass the style, not the renderer, to the theme.
        theme()->adjustSliderThumbSize(this);
    }
    RenderBlock::layout();
}

void SliderThumbElement::setPositionFromValue()
{
    // Since today the code to calculate position is in the RenderSlider layout
    // path, we don't actually update the value here. Instead, we poke at the
    // renderer directly to trigger layout.
    // FIXME: Move the logic of positioning the thumb here.
    if (renderer())
        renderer()->setNeedsLayout(true);
}

RenderObject* SliderThumbElement::createRenderer(RenderArena* arena, RenderStyle*)
{
    return new (arena) RenderSliderThumb(this);
}

void SliderThumbElement::dragFrom(const IntPoint& point)
{
    setPositionFromPoint(point);
    startDragging();
}

void SliderThumbElement::setPositionFromPoint(const IntPoint& point)
{
    HTMLInputElement* input = hostInput();
    ASSERT(input);

    if (!input->renderer() || !renderer())
        return;

    IntPoint offset = roundedIntPoint(input->renderer()->absoluteToLocal(point, false, true));
    RenderStyle* sliderStyle = input->renderer()->style();
    bool isVertical = sliderStyle->appearance() == SliderVerticalPart || sliderStyle->appearance() == MediaVolumeSliderPart;

    int trackSize;
    int position;
    int currentPosition;
    if (isVertical) {
        trackSize = input->renderBox()->contentHeight() - renderBox()->height();
        position = offset.y() - renderBox()->height() / 2;
        currentPosition = renderBox()->y() - input->renderBox()->contentBoxRect().y();
    } else {
        trackSize = input->renderBox()->contentWidth() - renderBox()->width();
        position = offset.x() - renderBox()->width() / 2;
        currentPosition = renderBox()->x() - input->renderBox()->contentBoxRect().x();
    }
    position = max(0, min(position, trackSize));
    if (position == currentPosition)
        return;

    StepRange range(input);
    double fraction = static_cast<double>(position) / trackSize;
    if (isVertical)
        fraction = 1 - fraction;
    double value = range.clampValue(range.valueFromProportion(fraction));

    // FIXME: This is no longer being set from renderer. Consider updating the method name.
    input->setValueFromRenderer(serializeForNumberType(value));
    renderer()->setNeedsLayout(true);
    input->dispatchFormControlChangeEvent();
}

void SliderThumbElement::startDragging()
{
    if (Frame* frame = document()->frame()) {
        frame->eventHandler()->setCapturingMouseEventsNode(this);
#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
        // Touch events come from Java to the main frame event handler, so we need
        // to flag we are capturing those events also on the main frame event
        // handler.
        frame->page()->mainFrame()->eventHandler()->setCapturingTouchEventsNode(this);
#endif
        m_inDragMode = true;
    }
}

void SliderThumbElement::stopDragging()
{
    if (!m_inDragMode)
        return;

    if (Frame* frame = document()->frame())
        frame->eventHandler()->setCapturingMouseEventsNode(0);

#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
    if (Frame* frame = document()->frame())
        frame->page()->mainFrame()->eventHandler()->setCapturingTouchEventsNode(0);
#endif
    m_inDragMode = false;
    if (renderer())
        renderer()->setNeedsLayout(true);
}

void SliderThumbElement::defaultEventHandler(Event* event)
{
    if (!event->isMouseEvent()
#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
        && !event->isTouchEvent()
#endif
        ) {
        HTMLDivElement::defaultEventHandler(event);
        return;
    }

#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
    bool isLeftButton = false;

    if (event->isMouseEvent()) {
        MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
        isLeftButton = mouseEvent->button() == LeftButton;
    }
#else
    MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
    bool isLeftButton = mouseEvent->button() == LeftButton;
#endif
    const AtomicString& eventType = event->type();

    if (eventType == eventNames().mousedownEvent && isLeftButton
#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
            || eventType == eventNames().touchstartEvent
#endif
            ) {
        startDragging();
        return;
    } else if (eventType == eventNames().mouseupEvent && isLeftButton
#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
            || eventType == eventNames().touchendEvent
            || eventType == eventNames().touchcancelEvent
#endif
            ) {
        stopDragging();
        return;
    } else if (eventType == eventNames().mousemoveEvent
#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
            || eventType == eventNames().touchmoveEvent
#endif
            ) {
        if (m_inDragMode)
#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
        {
            if (event->isMouseEvent()) {
                MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
#endif
            setPositionFromPoint(mouseEvent->absoluteLocation());
#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
            } else if (event->isTouchEvent()) {
                TouchEvent* touchEvent = static_cast<TouchEvent*>(event);
                if (touchEvent->touches() && touchEvent->touches()->item(0)) {
                    IntPoint curPoint;
                    curPoint.setX(touchEvent->touches()->item(0)->pageX());
                    curPoint.setY(touchEvent->touches()->item(0)->pageY());
                    setPositionFromPoint(curPoint);
                    // Tell the webview that webkit will handle the following move events
                    event->setDefaultPrevented(true);
                }
            }

        }
#endif
        return;
    }

    HTMLDivElement::defaultEventHandler(event);
}

#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
void SliderThumbElement::attach()
{
    HTMLDivElement::attach();
    document()->addListenerTypeIfNeeded(eventNames().touchstartEvent);
}
#endif

void SliderThumbElement::detach()
{
    if (m_inDragMode) {
        if (Frame* frame = document()->frame())
            frame->eventHandler()->setCapturingMouseEventsNode(0);
    }
    HTMLDivElement::detach();
}

HTMLInputElement* SliderThumbElement::hostInput()
{
    ASSERT(parentNode());
    return static_cast<HTMLInputElement*>(parentNode()->shadowHost());
}

const AtomicString& SliderThumbElement::shadowPseudoId() const
{
    DEFINE_STATIC_LOCAL(AtomicString, sliderThumb, ("-webkit-slider-thumb"));
    return sliderThumb;
}

}

