/*
 * Copyright (c) 2011, 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.
 */

#ifndef PopupListBox_h
#define PopupListBox_h

#include "core/dom/Element.h"
#include "platform/scroll/FramelessScrollView.h"
#include "platform/text/TextDirection.h"
#include "wtf/text/WTFString.h"

namespace WebCore {
class Font;
class GraphicsContext;
class IntRect;
class PlatformKeyboardEvent;
class PlatformMouseEvent;
class PlatformGestureEvent;
class PlatformTouchEvent;
class PlatformWheelEvent;
class PopupMenuClient;
}

namespace blink {

typedef unsigned long long TimeStamp;

class PopupContent {
public:
    virtual void layout() = 0;
    virtual void setMaxHeight(int) = 0;
    virtual void setMaxWidthAndLayout(int) = 0;
    virtual int popupContentHeight() const = 0;
    virtual ~PopupContent() { };
};

// A container for the data for each menu item (e.g. represented by <option>
// or <optgroup> in a <select> widget) and is used by PopupListBox.
struct PopupItem {
    enum Type {
        TypeOption,
        TypeGroup,
        TypeSeparator
    };

    PopupItem(const String& label, Type type)
        : label(label)
        , type(type)
        , yOffset(0)
    {
    }
    String label;
    Type type;
    int yOffset; // y offset of this item, relative to the top of the popup.
    WebCore::TextDirection textDirection;
    bool hasTextDirectionOverride;
    bool enabled;
};

// This class uses WebCore code to paint and handle events for a drop-down list
// box ("combobox" on Windows).
class PopupListBox FINAL : public WebCore::FramelessScrollView, public PopupContent {
public:
    static PassRefPtr<PopupListBox> create(WebCore::PopupMenuClient* client, bool deviceSupportsTouch)
    {
        return adoptRef(new PopupListBox(client, deviceSupportsTouch));
    }

    // FramelessScrollView
    virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect&) OVERRIDE;
    virtual bool handleMouseDownEvent(const WebCore::PlatformMouseEvent&) OVERRIDE;
    virtual bool handleMouseMoveEvent(const WebCore::PlatformMouseEvent&) OVERRIDE;
    virtual bool handleMouseReleaseEvent(const WebCore::PlatformMouseEvent&) OVERRIDE;
    virtual bool handleWheelEvent(const WebCore::PlatformWheelEvent&) OVERRIDE;
    virtual bool handleKeyEvent(const WebCore::PlatformKeyboardEvent&) OVERRIDE;
    virtual bool handleTouchEvent(const WebCore::PlatformTouchEvent&) OVERRIDE;
    virtual bool handleGestureEvent(const WebCore::PlatformGestureEvent&) OVERRIDE;

    // ScrollView
    virtual WebCore::HostWindow* hostWindow() const OVERRIDE;
    virtual bool shouldPlaceVerticalScrollbarOnLeft() const OVERRIDE;

    // PopupListBox methods

    // Closes the popup
    void abandon();

    // Updates our internal list to match the client.
    void updateFromElement();

    // Frees any allocated resources used in a particular popup session.
    void clear();

    // Sets the index of the option that is displayed in the <select> widget in the page
    void setOriginalIndex(int);

    // Gets the index of the item that the user is currently moused over or has
    // selected with the keyboard. This is not the same as the original index,
    // since the user has not yet accepted this input.
    int selectedIndex() const { return m_selectedIndex; }

    // Moves selection down/up the given number of items, scrolling if necessary.
    // Positive is down. The resulting index will be clamped to the range
    // [0, numItems), and non-option items will be skipped.
    void adjustSelectedIndex(int delta);

    // Returns the number of items in the list.
    int numItems() const { return static_cast<int>(m_items.size()); }

    void setBaseWidth(int width) { m_baseWidth = std::min(m_maxWindowWidth, width); }

    // Computes the size of widget and children.
    virtual void layout() OVERRIDE;

    // Returns whether the popup wants to process events for the passed key.
    bool isInterestedInEventForKey(int keyCode);

    // Gets the height of a row.
    int getRowHeight(int index);

    virtual void setMaxHeight(int maxHeight) OVERRIDE { m_maxHeight = maxHeight; }

    void setMaxWidth(int maxWidth) { m_maxWindowWidth = maxWidth; }

    virtual void setMaxWidthAndLayout(int) OVERRIDE;

    void disconnectClient() { m_popupClient = 0; }

    const Vector<PopupItem*>& items() const { return m_items; }

    virtual int popupContentHeight() const OVERRIDE;

    static const int defaultMaxHeight;

private:
    friend class PopupContainer;
    friend class RefCounted<PopupListBox>;

    PopupListBox(WebCore::PopupMenuClient*, bool deviceSupportsTouch);

    virtual ~PopupListBox()
    {
        clear();
    }

    // Hides the popup. Other classes should not call this. Use abandon instead.
    void hidePopup();

    // Returns true if the selection can be changed to index.
    // Disabled items, or labels cannot be selected.
    bool isSelectableItem(int index);

    // Select an index in the list, scrolling if necessary.
    void selectIndex(int index);

    // Accepts the selected index as the value to be displayed in the <select>
    // widget on the web page, and closes the popup. Returns true if index is
    // accepted.
    bool acceptIndex(int index);

    // Clears the selection (so no row appears selected).
    void clearSelection();

    // Scrolls to reveal the given index.
    void scrollToRevealRow(int index);
    void scrollToRevealSelection() { scrollToRevealRow(m_selectedIndex); }

    // Invalidates the row at the given index.
    void invalidateRow(int index);

    // Get the bounds of a row.
    WebCore::IntRect getRowBounds(int index);

    // Converts a point to an index of the row the point is over
    int pointToRowIndex(const WebCore::IntPoint&);

    // Paint an individual row
    void paintRow(WebCore::GraphicsContext*, const WebCore::IntRect&, int rowIndex);

    // Test if the given point is within the bounds of the popup window.
    bool isPointInBounds(const WebCore::IntPoint&);

    // Called when the user presses a text key. Does a prefix-search of the items.
    void typeAheadFind(const WebCore::PlatformKeyboardEvent&);

    // Returns the font to use for the given row
    WebCore::Font getRowFont(int index);

    // Moves the selection down/up one item, taking care of looping back to the
    // first/last element if m_loopSelectionNavigation is true.
    void selectPreviousRow();
    void selectNextRow();

    // If the device is a touch screen we increase the height of menu items
    // to make it easier to unambiguously touch them.
    bool m_deviceSupportsTouch;

    // This is the index of the item marked as "selected" - i.e. displayed in
    // the widget on the page.
    int m_originalIndex;

    // This is the index of the item that the user is hovered over or has
    // selected using the keyboard in the list. They have not confirmed this
    // selection by clicking or pressing enter yet however.
    int m_selectedIndex;

    // If >= 0, this is the index we should accept if the popup is "abandoned".
    // This is used for keyboard navigation, where we want the
    // selection to change immediately, and is only used if the settings
    // acceptOnAbandon field is true.
    int m_acceptedIndexOnAbandon;

    // This is the number of rows visible in the popup. The maximum number
    // visible at a time is defined as being kMaxVisibleRows. For a scrolled
    // popup, this can be thought of as the page size in data units.
    int m_visibleRows;

    // Our suggested width, not including scrollbar.
    int m_baseWidth;

    // The maximum height we can be without being off-screen.
    int m_maxHeight;

    // A list of the options contained within the <select>
    Vector<PopupItem*> m_items;

    // The <select> PopupMenuClient that opened us.
    WebCore::PopupMenuClient* m_popupClient;

    // The scrollbar which has mouse capture. Mouse events go straight to this
    // if not null.
    RefPtr<WebCore::Scrollbar> m_capturingScrollbar;

    // The last scrollbar that the mouse was over. Used for mouseover highlights.
    RefPtr<WebCore::Scrollbar> m_lastScrollbarUnderMouse;

    // The string the user has typed so far into the popup. Used for typeAheadFind.
    String m_typedString;

    // The char the user has hit repeatedly. Used for typeAheadFind.
    UChar m_repeatingChar;

    // The last time the user hit a key. Used for typeAheadFind.
    TimeStamp m_lastCharTime;

    // If width exeeds screen width, we have to clip it.
    int m_maxWindowWidth;

    // To forward last mouse release event.
    RefPtr<WebCore::Element> m_focusedElement;
};

} // namespace blink

#endif
