/*
 * 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/Node.h"
#include "core/platform/chromium/FramelessScrollView.h"
#include "core/platform/text/TextDirection.h"
#include "wtf/text/WTFString.h"

namespace WebCore {

typedef unsigned long long TimeStamp;

class Font;
class GraphicsContext;
class IntRect;
class PlatformKeyboardEvent;
class PlatformMouseEvent;
class PlatformGestureEvent;
class PlatformTouchEvent;
class PlatformWheelEvent;
class PopupMenuClient;

struct PopupContainerSettings {
    // Whether the PopupMenuClient should be told to change its text when a
    // new item is selected by using the arrow keys.
    bool setTextOnIndexChange;

    // Whether the selection should be accepted when the popup menu is
    // closed (through ESC being pressed or the focus going away).
    // Note that when TAB is pressed, the selection is always accepted
    // regardless of this setting.
    bool acceptOnAbandon;

    // Whether we should move the selection to the first/last item when
    // the user presses down/up arrow keys and the last/first item is
    // selected.
    bool loopSelectionNavigation;

    // Whether we should restrict the width of the PopupListBox or not.
    // Autocomplete popups are restricted, combo-boxes (select tags) aren't.
    bool restrictWidthOfListBox;

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

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.
    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 : public FramelessScrollView, public PopupContent {
public:
    static PassRefPtr<PopupListBox> create(PopupMenuClient* client, const PopupContainerSettings& settings)
    {
        return adoptRef(new PopupListBox(client, settings));
    }

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

    // ScrollView
    virtual HostWindow* hostWindow() const OVERRIDE;

    // PopupListBox methods

    // Hides the popup.
    void hidePopup();

    // 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(PopupMenuClient*, const PopupContainerSettings&);

    virtual ~PopupListBox()
    {
        clear();
    }

    // Closes the popup
    void abandon();

    // 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.
    IntRect getRowBounds(int index);

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

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

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

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

    // Returns the font to use for the given row
    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();

    // The settings that specify the behavior for this Popup window.
    PopupContainerSettings m_settings;

    // 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.
    PopupMenuClient* m_popupClient;

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

    // The last scrollbar that the mouse was over. Used for mouseover highlights.
    RefPtr<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<Node> m_focusedNode;
};

} // namespace WebCore

#endif
