/*
 * 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 "ExternalPopupMenu.h"

#include "WebExternalPopupMenu.h"
#include "WebMenuItemInfo.h"
#include "WebPopupMenuInfo.h"
#include "WebViewClient.h"
#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
#include "core/platform/PopupMenuClient.h"
#include "platform/geometry/FloatQuad.h"
#include "platform/geometry/IntPoint.h"
#include "platform/text/TextDirection.h"
#include "public/platform/WebVector.h"

using namespace WebCore;

namespace WebKit {

ExternalPopupMenu::ExternalPopupMenu(Frame& frame, PopupMenuClient* popupMenuClient, WebViewClient* webViewClient)
    : m_popupMenuClient(popupMenuClient)
    , m_frameView(frame.view())
    , m_webViewClient(webViewClient)
    , m_webExternalPopupMenu(0)
{
}

ExternalPopupMenu::~ExternalPopupMenu()
{
}

void ExternalPopupMenu::show(const FloatQuad& controlPosition, const IntSize&, int index)
{
    IntRect rect(controlPosition.enclosingBoundingBox());
    // WebCore reuses the PopupMenu of a page.
    // For simplicity, we do recreate the actual external popup everytime.
    hide();

    WebPopupMenuInfo info;
    getPopupMenuInfo(&info);
    if (info.items.isEmpty())
        return;
    m_webExternalPopupMenu =
        m_webViewClient->createExternalPopupMenu(info, this);
    if (m_webExternalPopupMenu)
        m_webExternalPopupMenu->show(m_frameView->contentsToWindow(rect));
    else {
        // The client might refuse to create a popup (when there is already one pending to be shown for example).
        didCancel();
    }
}

void ExternalPopupMenu::hide()
{
    if (m_popupMenuClient)
        m_popupMenuClient->popupDidHide();
    if (!m_webExternalPopupMenu)
        return;
    m_webExternalPopupMenu->close();
    m_webExternalPopupMenu = 0;
}

void ExternalPopupMenu::updateFromElement()
{
}

void ExternalPopupMenu::disconnectClient()
{
    hide();
    m_popupMenuClient = 0;
}

void ExternalPopupMenu::didChangeSelection(int index)
{
    if (m_popupMenuClient)
        m_popupMenuClient->selectionChanged(index);
}

void ExternalPopupMenu::didAcceptIndex(int index)
{
    // Calling methods on the PopupMenuClient might lead to this object being
    // derefed. This ensures it does not get deleted while we are running this
    // method.
    RefPtr<ExternalPopupMenu> guard(this);

    if (m_popupMenuClient) {
        m_popupMenuClient->valueChanged(index);
        // The call to valueChanged above might have lead to a call to
        // disconnectClient, so we might not have a PopupMenuClient anymore.
        if (m_popupMenuClient)
            m_popupMenuClient->popupDidHide();
    }
    m_webExternalPopupMenu = 0;
}

void ExternalPopupMenu::didAcceptIndices(const WebVector<int>& indices)
{
    if (!m_popupMenuClient) {
        m_webExternalPopupMenu = 0;
        return;
    }

    // Calling methods on the PopupMenuClient might lead to this object being
    // derefed. This ensures it does not get deleted while we are running this
    // method.
    RefPtr<ExternalPopupMenu> protect(this);

    if (!indices.size())
        m_popupMenuClient->valueChanged(-1, true);
    else {
        for (size_t i = 0; i < indices.size(); ++i)
            m_popupMenuClient->listBoxSelectItem(indices[i], (i > 0), false, (i == indices.size() - 1));
    }

    // The call to valueChanged above might have lead to a call to
    // disconnectClient, so we might not have a PopupMenuClient anymore.
    if (m_popupMenuClient)
        m_popupMenuClient->popupDidHide();

    m_webExternalPopupMenu = 0;
}

void ExternalPopupMenu::didCancel()
{
    // See comment in didAcceptIndex on why we need this.
    RefPtr<ExternalPopupMenu> guard(this);

    if (m_popupMenuClient)
        m_popupMenuClient->popupDidHide();
    m_webExternalPopupMenu = 0;
}

void ExternalPopupMenu::getPopupMenuInfo(WebPopupMenuInfo* info)
{
    int itemCount = m_popupMenuClient->listSize();
    WebVector<WebMenuItemInfo> items(static_cast<size_t>(itemCount));
    for (int i = 0; i < itemCount; ++i) {
        WebMenuItemInfo& popupItem = items[i];
        popupItem.label = m_popupMenuClient->itemText(i);
        popupItem.toolTip = m_popupMenuClient->itemToolTip(i);
        if (m_popupMenuClient->itemIsSeparator(i))
            popupItem.type = WebMenuItemInfo::Separator;
        else if (m_popupMenuClient->itemIsLabel(i))
            popupItem.type = WebMenuItemInfo::Group;
        else
            popupItem.type = WebMenuItemInfo::Option;
        popupItem.enabled = m_popupMenuClient->itemIsEnabled(i);
        popupItem.checked = m_popupMenuClient->itemIsSelected(i);
        PopupMenuStyle style = m_popupMenuClient->itemStyle(i);
        if (style.textDirection() == WebCore::RTL)
            popupItem.textDirection = WebTextDirectionRightToLeft;
        else
            popupItem.textDirection = WebTextDirectionLeftToRight;
        popupItem.hasTextDirectionOverride = style.hasTextDirectionOverride();
    }

    info->itemHeight = m_popupMenuClient->menuStyle().font().fontMetrics().height();
    info->itemFontSize = static_cast<int>(m_popupMenuClient->menuStyle().font().size());
    info->selectedIndex = m_popupMenuClient->selectedIndex();
    info->rightAligned = m_popupMenuClient->menuStyle().textDirection() == WebCore::RTL;
    info->allowMultipleSelection = m_popupMenuClient->multiple();
    info->items.swap(items);
}

}
