// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/android/select_popup.h"

#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "base/containers/heap_array.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/browser/web_contents/web_contents_view_android.h"
#include "ui/gfx/geometry/rect_f.h"

// Must come after all headers that specialize FromJniType() / ToJniType().
#include "content/public/android/content_jni_headers/SelectPopup_jni.h"

using base::android::AttachCurrentThread;
using base::android::JavaParamRef;
using base::android::ScopedJavaLocalRef;

namespace content {

namespace {

// Describes the type and enabled state of a select popup item.
//
// A Java counterpart will be generated for this enum.
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.content.browser.input
enum PopupItemType {
  // Popup item is of type group
  POPUP_ITEM_TYPE_GROUP,

  // Popup item is disabled
  POPUP_ITEM_TYPE_DISABLED,

  // Popup item is enabled
  POPUP_ITEM_TYPE_ENABLED,
};

}  // namespace

SelectPopup::SelectPopup(WebContentsImpl* web_contents)
    : web_contents_(web_contents) {
  JNIEnv* env = AttachCurrentThread();
  java_obj_ = JavaObjectWeakGlobalRef(
      env, Java_SelectPopup_create(env, web_contents_->GetJavaWebContents(),
                                   reinterpret_cast<intptr_t>(this)));
}

SelectPopup::~SelectPopup() {
  JNIEnv* env = AttachCurrentThread();
  ScopedJavaLocalRef<jobject> j_obj = java_obj_.get(env);
  if (j_obj.is_null())
    return;
  Java_SelectPopup_onNativeDestroyed(env, j_obj);
  popup_client_.reset();
}

void SelectPopup::ShowMenu(
    mojo::PendingRemote<blink::mojom::PopupMenuClient> popup_client,
    const gfx::Rect& bounds,
    std::vector<blink::mojom::MenuItemPtr> items,
    int selected_item,
    bool multiple,
    bool right_aligned) {
  JNIEnv* env = AttachCurrentThread();
  ScopedJavaLocalRef<jobject> j_obj = java_obj_.get(env);
  if (j_obj.is_null())
    return;

  // Hide the popup menu if the mojo connection is still open.
  if (popup_client_)
    HideMenu();

  // For multi-select list popups we find the list of previous selections by
  // iterating through the items. But for single selection popups we take the
  // given |selected_item| as is.
  ScopedJavaLocalRef<jintArray> selected_array;
  if (multiple) {
    auto native_selected_array = base::HeapArray<jint>::WithSize(items.size());
    size_t selected_count = 0;
    for (size_t i = 0; i < items.size(); ++i) {
      if (items[i]->checked)
        native_selected_array[selected_count++] = i;
    }

    selected_array = ScopedJavaLocalRef<jintArray>::Adopt(
        env, env->NewIntArray(selected_count));
    env->SetIntArrayRegion(selected_array.obj(), 0, selected_count,
                           native_selected_array.data());
  } else {
    selected_array =
        ScopedJavaLocalRef<jintArray>::Adopt(env, env->NewIntArray(1));
    jint value = selected_item;
    env->SetIntArrayRegion(selected_array.obj(), 0, 1, &value);
  }

  auto enabled_array =
      ScopedJavaLocalRef<jintArray>::Adopt(env, env->NewIntArray(items.size()));
  std::vector<std::string> labels;
  labels.reserve(items.size());
  for (size_t i = 0; i < items.size(); ++i) {
    labels.push_back(items[i]->label.value_or(""));
    jint enabled = (items[i]->type == blink::mojom::MenuItem::Type::kGroup
                        ? POPUP_ITEM_TYPE_GROUP
                        : (items[i]->enabled ? POPUP_ITEM_TYPE_ENABLED
                                             : POPUP_ITEM_TYPE_DISABLED));
    env->SetIntArrayRegion(enabled_array.obj(), i, 1, &enabled);
  }
  ScopedJavaLocalRef<jobjectArray> items_array(
      base::android::ToJavaArrayOfStrings(env, labels));
  ui::ViewAndroid* view = web_contents_->GetNativeView();
  popup_view_ = view->AcquireAnchorView();
  const ScopedJavaLocalRef<jobject> popup_view = popup_view_.view();
  if (popup_view.is_null())
    return;

  popup_client_.Bind(std::move(popup_client));
  popup_client_.set_disconnect_handler(
      base::BindOnce(&SelectPopup::HideMenu, base::Unretained(this)));

  // |bounds| is in physical pixels.
  gfx::RectF bounds_dip = gfx::RectF(bounds);
  bounds_dip.Scale(1 / web_contents_->GetNativeView()->GetDipScale());
  view->SetAnchorRect(popup_view, bounds_dip);
  Java_SelectPopup_show(
      env, j_obj, popup_view, reinterpret_cast<jlong>(popup_client_.get()),
      items_array, enabled_array, multiple, selected_array, right_aligned);
}

void SelectPopup::HideMenu() {
  JNIEnv* env = AttachCurrentThread();
  ScopedJavaLocalRef<jobject> j_obj = java_obj_.get(env);
  if (!j_obj.is_null())
    Java_SelectPopup_hideWithoutCancel(env, j_obj);
  popup_view_.Reset();
  popup_client_.reset();
}

void SelectPopup::SelectMenuItems(JNIEnv* env,
                                  jlong selectPopupDelegate,
                                  const JavaParamRef<jintArray>& indices) {
  blink::mojom::PopupMenuClient* popup_client_raw_ptr =
      reinterpret_cast<blink::mojom::PopupMenuClient*>(selectPopupDelegate);
  DCHECK(popup_client_raw_ptr && popup_client_.get() == popup_client_raw_ptr);

  if (indices.is_null()) {
    popup_client_->DidCancel();
    return;
  }

  std::vector<int> selected_indices;
  base::android::JavaIntArrayToIntVector(env, indices, &selected_indices);
  popup_client_->DidAcceptIndices(selected_indices);
}

}  // namespace content
