/*
 * 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.
 */

#ifndef AutofillPopupMenuClient_h
#define AutofillPopupMenuClient_h

#include "platform/PopupMenuClient.h"

namespace WebCore {
class FontSelector;
class HTMLInputElement;
class PopupMenuStyle;
class RenderStyle;
}

namespace blink {
class WebString;
class WebViewImpl;
template <typename T> class WebVector;

// The Autofill suggestions popup menu client, used to display name suggestions
// with right-justified labels.
class AutofillPopupMenuClient : public WebCore::PopupMenuClient {
public:
    AutofillPopupMenuClient();
    virtual ~AutofillPopupMenuClient();

    // Returns the number of suggestions available.
    virtual unsigned getSuggestionsCount() const;

    // Returns the suggestion at |listIndex|.
    virtual WebString getSuggestion(unsigned listIndex) const;

    // Returns the label at |listIndex|.
    virtual WebString getLabel(unsigned listIndex) const;

    // Returns the icon at |listIndex|.
    virtual WebString getIcon(unsigned listIndex) const;

    // Removes the suggestion at |listIndex| from the list of suggestions.
    virtual void removeSuggestionAtIndex(unsigned listIndex);

    // Returns true if the suggestion at |listIndex| can be removed.
    bool canRemoveSuggestionAtIndex(unsigned listIndex);

    // WebCore::PopupMenuClient methods:
    virtual void valueChanged(unsigned listIndex, bool fireEvents = true);
    virtual void selectionChanged(unsigned, bool);
    virtual void selectionCleared();
    virtual WTF::String itemText(unsigned listIndex) const;
    virtual WTF::String itemLabel(unsigned listIndex) const;
    virtual WTF::String itemIcon(unsigned listIndex) const;
    virtual WTF::String itemToolTip(unsigned lastIndex) const { return WTF::String(); }
    virtual WTF::String itemAccessibilityText(unsigned lastIndex) const { return WTF::String(); }
    virtual bool itemIsEnabled(unsigned listIndex) const;
    virtual WebCore::PopupMenuStyle itemStyle(unsigned listIndex) const;
    virtual WebCore::PopupMenuStyle menuStyle() const;
    virtual int clientInsetLeft() const { return 0; }
    virtual int clientInsetRight() const { return 0; }
    virtual WebCore::LayoutUnit clientPaddingLeft() const;
    virtual WebCore::LayoutUnit clientPaddingRight() const;
    virtual int listSize() const { return getSuggestionsCount(); }
    virtual int selectedIndex() const { return m_selectedIndex; }
    virtual void popupDidHide();
    virtual bool itemIsSeparator(unsigned listIndex) const;
    virtual bool itemIsLabel(unsigned listIndex) const { return false; }
    virtual bool itemIsSelected(unsigned listIndex) const { return false; }
    virtual bool valueShouldChangeOnHotTrack() const { return false; }
    virtual void setTextFromItem(unsigned listIndex);
    virtual WebCore::FontSelector* fontSelector() const;
    virtual WebCore::HostWindow* hostWindow() const;
    virtual PassRefPtr<WebCore::Scrollbar> createScrollbar(
        WebCore::ScrollableArea* client,
        WebCore::ScrollbarOrientation orientation,
        WebCore::ScrollbarControlSize size);

    void initialize(WebCore::HTMLInputElement*,
                    const WebVector<WebString>& names,
                    const WebVector<WebString>& labels,
                    const WebVector<WebString>& icons,
                    const WebVector<int>& itemIDs,
                    int separatorIndex);

    void setSuggestions(const WebVector<WebString>& names,
                        const WebVector<WebString>& labels,
                        const WebVector<WebString>& icons,
                        const WebVector<int>& itemIDs);

private:
    WebViewImpl* getWebView() const;
    WebCore::HTMLInputElement* getTextField() const { return m_textField.get(); }
    WebCore::RenderStyle* textFieldStyle() const;

    int getSelectedIndex() const { return m_selectedIndex; }
    void setSelectedIndex(int index) { m_selectedIndex = index; }

    bool itemIsWarning(unsigned listIndex) const;

    // The names, labels and icons that make up the contents of the menu items.
    Vector<WTF::String> m_names;
    Vector<WTF::String> m_labels;
    Vector<WTF::String> m_icons;
    Vector<int> m_itemIDs;

    // The index of the selected item.  -1 if there is no selected item.
    int m_selectedIndex;

    RefPtr<WebCore::HTMLInputElement> m_textField;
    OwnPtr<WebCore::PopupMenuStyle> m_regularStyle;
    OwnPtr<WebCore::PopupMenuStyle> m_warningStyle;

    // Use legacy behavior while the chromium side hasn't been updated.
    bool m_useLegacyBehavior;
};

} // namespace blink

#endif
