// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/test/plugin/plugin_windowed_test.h"

#include "base/logging.h"
#include "content/test/plugin/plugin_client.h"

namespace NPAPIClient {

WindowedPluginTest::WindowedPluginTest(NPP id, NPNetscapeFuncs *host_functions)
    : PluginTest(id, host_functions),
      window_(NULL), done_(false) {
}

WindowedPluginTest::~WindowedPluginTest() {
  if (window_)
    DestroyWindow(window_);
}

NPError WindowedPluginTest::SetWindow(NPWindow* pNPWindow) {
  if (pNPWindow->window == NULL)
    return NPERR_NO_ERROR;

  if (test_name() == "create_instance_in_paint" && test_id() == "2") {
    SignalTestCompleted();
    return NPERR_NO_ERROR;
  }

  if (window_)
    return NPERR_NO_ERROR;

  HWND parent = reinterpret_cast<HWND>(pNPWindow->window);
  if (!::IsWindow(parent)) {
    SetError("Invalid arguments passed in");
    return NPERR_INVALID_PARAM;
  }

  if ((test_name() == "create_instance_in_paint" && test_id() == "1") ||
      test_name() == "alert_in_window_message" ||
      test_name() == "set_title_in_paint" ||
      test_name() == "set_title_in_set_window_and_paint") {
    static ATOM window_class = 0;
    if (!window_class) {
      WNDCLASSEX wcex;
      wcex.cbSize         = sizeof(WNDCLASSEX);
      wcex.style          = CS_DBLCLKS;
      wcex.lpfnWndProc    = &NPAPIClient::WindowedPluginTest::WindowProc;
      wcex.cbClsExtra     = 0;
      wcex.cbWndExtra     = 0;
      wcex.hInstance      = GetModuleHandle(NULL);
      wcex.hIcon          = 0;
      wcex.hCursor        = 0;
      wcex.hbrBackground  = reinterpret_cast<HBRUSH>(COLOR_WINDOW+1);
      wcex.lpszMenuName   = 0;
      wcex.lpszClassName  = L"CreateInstanceInPaintTestWindowClass";
      wcex.hIconSm        = 0;
      window_class = RegisterClassEx(&wcex);
    }

    window_ = CreateWindowEx(
        WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
        MAKEINTATOM(window_class), 0,
        WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE ,
        0, 0, 100, 100, parent, 0, GetModuleHandle(NULL), 0);
    DCHECK(window_);
    // TODO: this propery leaks.
    ::SetProp(window_, L"Plugin_Instance", this);
  }

  if (test_name() == "set_title_in_set_window_and_paint")
    CallJSFunction(this, "PluginCreated");

  return NPERR_NO_ERROR;
}

NPError WindowedPluginTest::Destroy() {
  if (test_name() != "ensure_scripting_works_in_destroy")
    return NPERR_NO_ERROR;

  // Bug 23706: ensure that scripting works with no asserts.
  NPObject *window_obj = NULL;
  HostFunctions()->getvalue(id(), NPNVWindowNPObject,&window_obj);

  if (!window_obj) {
    SetError("Failed to get NPObject for plugin instance");
  } else {
    std::string script = "javascript:GetMagicNumber()";
    NPString script_string;
    script_string.UTF8Characters = script.c_str();
    script_string.UTF8Length =
        static_cast<unsigned int>(script.length());

    NPVariant result_var;
    bool result = HostFunctions()->evaluate(
        id(), window_obj, &script_string, &result_var);
    if (!result ||
        result_var.type != NPVariantType_Double ||
        result_var.value.doubleValue != 42.0) {
      SetError("Failed to script during NPP_Destroy");
    }
  }

  SignalTestCompleted();
  return NPERR_NO_ERROR;
}

void WindowedPluginTest::CallJSFunction(
    WindowedPluginTest* this_ptr, const char* function) {
  NPIdentifier function_id = this_ptr->HostFunctions()->getstringidentifier(
      function);

  NPObject *window_obj = NULL;
  this_ptr->HostFunctions()->getvalue(
      this_ptr->id(), NPNVWindowNPObject, &window_obj);

  NPVariant rv;
  this_ptr->HostFunctions()->invoke(
      this_ptr->id(), window_obj, function_id, NULL, 0, &rv);
}

LRESULT CALLBACK WindowedPluginTest::WindowProc(
    HWND window, UINT message, WPARAM wparam, LPARAM lparam) {
  WindowedPluginTest* this_ptr =
      reinterpret_cast<WindowedPluginTest*>
          (::GetProp(window, L"Plugin_Instance"));

  if (message == WM_PAINT) {
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(window, &ps);
    HBRUSH brush = CreateSolidBrush(RGB(255, 0, 0));
    HGDIOBJ orig = SelectObject(hdc, brush);
    RECT r;
    GetClientRect(window, &r);
    Rectangle(hdc, 0, 0, r.right, r.bottom);
    SelectObject(hdc, orig); // restore
    DeleteObject(brush);
    EndPaint(window, &ps);
  }

  if (this_ptr && !this_ptr->done_) {
    if (this_ptr->test_name() == "create_instance_in_paint" &&
        message == WM_PAINT) {
      this_ptr->done_ = true;
      CallJSFunction(this_ptr, "CreateNewInstance");
    } else if (this_ptr->test_name() == "alert_in_window_message" &&
               message == WM_PAINT) {
      this_ptr->done_ = true;
      // We call this function twice as we want to display two alerts
      // and verify that we don't hang the browser.
      CallJSFunction(this_ptr, "CallAlert");
      CallJSFunction(this_ptr, "CallAlert");
    } else if (this_ptr->test_name() == "set_title_in_paint" &&
               message == WM_PAINT) {
      this_ptr->done_ = true;
      CallJSFunction(this_ptr, "SetTitle");
    } else if (this_ptr->test_name() == "set_title_in_set_window_and_paint" &&
               message == WM_PAINT) {
      this_ptr->done_ = true;
      CallJSFunction(this_ptr, "PluginShown");
    }

    if (this_ptr->done_) {
      ::RemoveProp(window, L"Plugin_Instance");
    }
  }

  return DefWindowProc(window, message, wparam, lparam);
}

} // namespace NPAPIClient
