// Copyright (c) 2009 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/browser/find_bar_controller.h"

#include "build/build_config.h"
#include "chrome/browser/find_bar.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/common/notification_service.h"
#include "chrome/browser/tab_contents/web_contents.h"

FindBarController::FindBarController(FindBar* find_bar)
    : find_bar_(find_bar), web_contents_(NULL) {
}

FindBarController::~FindBarController() {
  // Web contents should have been NULLed out. If not, then we're leaking
  // notification observers.
  DCHECK(!web_contents_);
}

void FindBarController::Show() {
  // Only show the animation if we're not already showing a find bar for the
  // selected WebContents.
  if (!web_contents_->find_ui_active()) {
    web_contents_->set_find_ui_active(true);
    find_bar_->Show();
  }
  find_bar_->SetFocusAndSelection();
}

void FindBarController::EndFindSession() {
  find_bar_->Hide(true);

  // |web_contents_| can be NULL for a number of reasons, for example when the
  // tab is closing. We must guard against that case. See issue 8030.
  if (web_contents_) {
    // When we hide the window, we need to notify the renderer that we are done
    // for now, so that we can abort the scoping effort and clear all the
    // tickmarks and highlighting.
    web_contents_->StopFinding(false);  // false = don't clear selection on
                                        // page.
    find_bar_->ClearResults(web_contents_->find_result());

    // When we get dismissed we restore the focus to where it belongs.
    find_bar_->RestoreSavedFocus();
  }
}

void FindBarController::ChangeWebContents(WebContents* contents) {
  if (web_contents_) {
    NotificationService::current()->RemoveObserver(
        this, NotificationType::FIND_RESULT_AVAILABLE,
        Source<TabContents>(web_contents_));
    NotificationService::current()->RemoveObserver(
        this, NotificationType::NAV_ENTRY_COMMITTED,
        Source<NavigationController>(&web_contents_->controller()));
    find_bar_->StopAnimation();
  }

  web_contents_ = contents;

  // Hide any visible find window from the previous tab if NULL |web_contents|
  // is passed in or if the find UI is not active in the new tab.
  if (find_bar_->IsFindBarVisible() &&
      (!web_contents_ || !web_contents_->find_ui_active())) {
    find_bar_->Hide(false);
  }

  if (web_contents_) {
    NotificationService::current()->AddObserver(
        this, NotificationType::FIND_RESULT_AVAILABLE,
        Source<TabContents>(web_contents_));
    NotificationService::current()->AddObserver(
        this, NotificationType::NAV_ENTRY_COMMITTED,
        Source<NavigationController>(&web_contents_->controller()));

    // Find out what we should show in the find text box. Usually, this will be
    // the last search in this tab, but if no search has been issued in this tab
    // we use the last search string (from any tab).
    string16 find_string = web_contents_->find_text();
    if (find_string.empty())
      find_string = web_contents_->find_prepopulate_text();

    // Update the find bar with existing results and search text, regardless of
    // whether or not the find bar is visible, so that if it's subsequently
    // shown it is showing the right state for this tab. We update the find text
    // _first_ since the FindBarView checks its emptiness to see if it should
    // clear the result count display when there's nothing in the box.
    find_bar_->SetFindText(find_string);

    if (web_contents_->find_ui_active()) {
      // A tab with a visible find bar just got selected and we need to show the
      // find bar but without animation since it was already animated into its
      // visible state. We also want to reset the window location so that
      // we don't surprise the user by popping up to the left for no apparent
      // reason.
      gfx::Rect new_pos = find_bar_->GetDialogPosition(gfx::Rect());
      find_bar_->SetDialogPosition(new_pos, false);

      // Only modify focus and selection if Find is active, otherwise the Find
      // Bar will interfere with user input.
      find_bar_->SetFocusAndSelection();
    }

    find_bar_->UpdateUIForFindResult(web_contents_->find_result(),
                                     web_contents_->find_text());
  }
}

////////////////////////////////////////////////////////////////////////////////
// FindBarWin, NotificationObserver implementation:

void FindBarController::Observe(NotificationType type,
                                const NotificationSource& source,
                                const NotificationDetails& details) {
  if (type == NotificationType::FIND_RESULT_AVAILABLE) {
    // Don't update for notifications from TabContentses other than the one we
    // are actively tracking.
    if (Source<TabContents>(source).ptr() == web_contents_) {
      find_bar_->UpdateUIForFindResult(web_contents_->find_result(),
                                       web_contents_->find_text());
    }
  } else if (type == NotificationType::NAV_ENTRY_COMMITTED) {
    NavigationController* source_controller =
        Source<NavigationController>(source).ptr();
    if (source_controller == &web_contents_->controller()) {
      NavigationController::LoadCommittedDetails* commit_details =
          Details<NavigationController::LoadCommittedDetails>(details).ptr();
      PageTransition::Type transition_type =
          commit_details->entry->transition_type();
      // We hide the FindInPage window when the user navigates away, except on
      // reload.
      if (find_bar_->IsFindBarVisible()) {
        if (PageTransition::StripQualifier(transition_type) !=
            PageTransition::RELOAD) {
          EndFindSession();
        } else {
          // On Reload we want to make sure FindNext is converted to a full Find
          // to make sure highlights for inactive matches are repainted.
          web_contents_->set_find_op_aborted(true);
        }
      }
    }
  }
}
