// Copyright (c) 2012 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 "chrome_frame/find_dialog.h"

#include <richedit.h>

#include "base/guid.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome_frame/chrome_frame_automation.h"

const int kMaxFindChars = 1024;

HHOOK CFFindDialog::msg_hook_ = NULL;

CFFindDialog::CFFindDialog() {}

void CFFindDialog::Init(ChromeFrameAutomationClient* automation_client) {
  automation_client_ = automation_client;
}

LRESULT CFFindDialog::OnDestroy(UINT msg, WPARAM wparam, LPARAM lparam,
                                BOOL& handled) {
  // In order to cancel the selection when the Find dialog is dismissed, we
  // do a fake search for a string that is unlikely to appear on the page.
  // TODO(robertshield): Change this to plumb through a StopFinding automation
  // message that triggers a ViewMsg_StopFinding.
  std::string guid(base::GenerateGUID());
  automation_client_->FindInPage(ASCIIToWide(guid), FWD, CASE_SENSITIVE, false);

  UninstallMessageHook();
  return 0;
}

LRESULT CFFindDialog::OnFind(WORD wNotifyCode, WORD wID, HWND hWndCtl,
                             BOOL& bHandled) {
  string16 find_text(kMaxFindChars, L'\0');
  find_text.resize(GetDlgItemText(IDC_FIND_TEXT, &find_text[0], kMaxFindChars));

  // Repeated searches for the same string should move to the next instance.
  bool find_next = (find_text == last_find_text_);
  if (!find_next)
    last_find_text_ = find_text;

  bool match_case = IsDlgButtonChecked(IDC_MATCH_CASE) == BST_CHECKED;
  bool search_down = IsDlgButtonChecked(IDC_DIRECTION_DOWN) == BST_CHECKED;

  automation_client_->FindInPage(find_text,
                                 search_down ? FWD : BACK,
                                 match_case ? CASE_SENSITIVE : IGNORE_CASE,
                                 find_next);

  return 0;
}

LRESULT CFFindDialog::OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl,
                               BOOL& bHandled) {
  DestroyWindow();
  return 0;
}

LRESULT CFFindDialog::OnInitDialog(UINT msg, WPARAM wparam, LPARAM lparam,
                                   BOOL& handled) {
  // Init() must be called before Create() or DoModal()!
  DCHECK(automation_client_.get());

  InstallMessageHook();
  SendDlgItemMessage(IDC_FIND_TEXT, EM_EXLIMITTEXT, 0, kMaxFindChars);
  BOOL result = CheckRadioButton(IDC_DIRECTION_DOWN, IDC_DIRECTION_UP,
                                 IDC_DIRECTION_DOWN);

  HWND text_field = GetDlgItem(IDC_FIND_TEXT);
  ::SetFocus(text_field);

  return FALSE;  // we set the focus ourselves.
}

LRESULT CALLBACK CFFindDialog::GetMsgProc(int code, WPARAM wparam,
                                          LPARAM lparam) {
  // Mostly borrowed from http://support.microsoft.com/kb/q187988/
  // and http://www.codeproject.com/KB/atl/cdialogmessagehook.aspx.
  LPMSG msg = reinterpret_cast<LPMSG>(lparam);
  if (code >= 0 && wparam == PM_REMOVE &&
      msg->message >= WM_KEYFIRST && msg->message <= WM_KEYLAST) {
    HWND hwnd = GetActiveWindow();
    if (::IsWindow(hwnd) && ::IsDialogMessage(hwnd, msg)) {
      // The value returned from this hookproc is ignored, and it cannot
      // be used to tell Windows the message has been handled. To avoid
      // further processing, convert the message to WM_NULL before
      // returning.
      msg->hwnd = NULL;
      msg->message = WM_NULL;
      msg->lParam = 0L;
      msg->wParam = 0;
    }
  }

  // Passes the hook information to the next hook procedure in
  // the current hook chain.
  return ::CallNextHookEx(msg_hook_, code, wparam, lparam);
}

bool CFFindDialog::InstallMessageHook() {
  // Make sure we only call this once.
  DCHECK(msg_hook_ == NULL);
  msg_hook_ = ::SetWindowsHookEx(WH_GETMESSAGE, &CFFindDialog::GetMsgProc,
                                 _AtlBaseModule.m_hInst, GetCurrentThreadId());
  DCHECK(msg_hook_ != NULL);
  return msg_hook_ != NULL;
}

bool CFFindDialog::UninstallMessageHook() {
  DCHECK(msg_hook_ != NULL);
  BOOL result = ::UnhookWindowsHookEx(msg_hook_);
  DCHECK(result);
  msg_hook_ = NULL;

  return result != FALSE;
}
