// 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 <cmath>

#import "chrome/browser/ui/cocoa/location_bar/page_action_decoration.h"

#include "base/strings/sys_string_conversions.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/extension_action.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/extensions/location_bar_controller.h"
#include "chrome/browser/extensions/tab_helper.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sessions/session_id.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#import "chrome/browser/ui/cocoa/extensions/extension_action_context_menu_controller.h"
#import "chrome/browser/ui/cocoa/extensions/extension_popup_controller.h"
#include "chrome/browser/ui/cocoa/last_active_browser_cocoa.h"
#import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
#include "chrome/browser/ui/omnibox/location_bar_util.h"
#include "chrome/browser/ui/webui/extensions/extension_info_ui.h"
#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/web_contents.h"
#include "skia/ext/skia_utils_mac.h"
#include "ui/gfx/canvas_skia_paint.h"
#include "ui/gfx/image/image.h"

using content::WebContents;
using extensions::Extension;
using extensions::LocationBarController;

namespace {

// Distance to offset the bubble pointer from the bottom of the max
// icon area of the decoration.  This makes the popup's upper border
// 2px away from the omnibox's lower border (matches omnibox popup
// upper border).
const CGFloat kBubblePointYOffset = 2.0;

}  // namespace

PageActionDecoration::PageActionDecoration(
    LocationBarViewMac* owner,
    Browser* browser,
    ExtensionAction* page_action)
    : owner_(NULL),
      browser_(browser),
      page_action_(page_action),
      current_tab_id_(-1),
      preview_enabled_(false),
      scoped_icon_animation_observer_(
          page_action->GetIconAnimation(
              SessionID::IdForTab(owner->GetWebContents())),
          this) {
  const Extension* extension = browser->profile()->GetExtensionService()->
      GetExtensionById(page_action->extension_id(), false);
  DCHECK(extension);

  icon_factory_.reset(new ExtensionActionIconFactory(
      browser_->profile(), extension, page_action, this));

  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE,
      content::Source<Profile>(browser_->profile()));
  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_COMMAND_PAGE_ACTION_MAC,
      content::Source<Profile>(browser_->profile()));
  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_COMMAND_SCRIPT_BADGE_MAC,
      content::Source<Profile>(browser_->profile()));

  // We set the owner last of all so that we can determine whether we are in
  // the process of initializing this class or not.
  owner_ = owner;
}

PageActionDecoration::~PageActionDecoration() {}

// Always |kPageActionIconMaxSize| wide.  |ImageDecoration| draws the
// image centered.
CGFloat PageActionDecoration::GetWidthForSpace(CGFloat width) {
  return extensions::IconsInfo::kPageActionIconMaxSize;
}

void PageActionDecoration::DrawWithBackgroundInFrame(NSRect background_frame,
                                                     NSRect frame,
                                                     NSView* control_view) {
  {
    gfx::Rect bounds(NSRectToCGRect(background_frame));
    gfx::CanvasSkiaPaint canvas(background_frame, /*opaque=*/false);
    // set_composite_alpha(true) makes the extension action paint on top of the
    // location bar instead of whatever's behind the Chrome window.
    canvas.set_composite_alpha(true);
    location_bar_util::PaintExtensionActionBackground(
        *page_action_, current_tab_id_,
        &canvas, bounds,
        SK_ColorBLACK, SK_ColorWHITE);
    // Destroying |canvas| draws the background.
  }

  ImageDecoration::DrawWithBackgroundInFrame(
      background_frame, frame, control_view);
}

bool PageActionDecoration::AcceptsMousePress() {
  return true;
}

// Either notify listeners or show a popup depending on the Page
// Action.
bool PageActionDecoration::OnMousePressed(NSRect frame) {
  return ActivatePageAction(frame);
}

bool PageActionDecoration::ActivatePageAction(NSRect frame) {
  WebContents* web_contents = owner_->GetWebContents();
  if (!web_contents) {
    // We don't want other code to try and handle this click. Returning true
    // prevents this by indicating that we handled it.
    return true;
  }

  LocationBarController* controller =
      extensions::TabHelper::FromWebContents(web_contents)->
          location_bar_controller();

  // 1 is left click.
  switch (controller->OnClicked(page_action_->extension_id(), 1)) {
    case LocationBarController::ACTION_NONE:
      break;

    case LocationBarController::ACTION_SHOW_POPUP:
      ShowPopup(frame, page_action_->GetPopupUrl(current_tab_id_));
      break;

    case LocationBarController::ACTION_SHOW_CONTEXT_MENU:
      // We are never passing OnClicked a right-click button, so assume that
      // we're never going to be asked to show a context menu.
      // TODO(kalman): if this changes, update this class to pass the real
      // mouse button through to the LocationBarController.
      NOTREACHED();
      break;

    case LocationBarController::ACTION_SHOW_SCRIPT_POPUP:
      ShowPopup(
          frame,
          extensions::ExtensionInfoUI::GetURL(page_action_->extension_id()));
      break;
  }

  return true;
}

void PageActionDecoration::OnIconUpdated() {
  // If we have no owner, that means this class is still being constructed.
  WebContents* web_contents = owner_ ? owner_->GetWebContents() : NULL;
  if (web_contents) {
    UpdateVisibility(web_contents, current_url_);
    owner_->RedrawDecoration(this);
  }
}

void PageActionDecoration::UpdateVisibility(WebContents* contents,
                                            const GURL& url) {
  // Save this off so we can pass it back to the extension when the action gets
  // executed. See PageActionDecoration::OnMousePressed.
  current_tab_id_ = contents ? ExtensionTabUtil::GetTabId(contents) : -1;
  current_url_ = url;

  bool visible = contents &&
      (preview_enabled_ || page_action_->GetIsVisible(current_tab_id_));
  if (visible) {
    SetToolTip(page_action_->GetTitle(current_tab_id_));

    // Set the image.
    gfx::Image icon = icon_factory_->GetIcon(current_tab_id_);
    if (!icon.IsEmpty()) {
      SetImage(icon.ToNSImage());
    } else if (!GetImage()) {
      const NSSize default_size = NSMakeSize(
          extensions::IconsInfo::kPageActionIconMaxSize,
          extensions::IconsInfo::kPageActionIconMaxSize);
      SetImage([[[NSImage alloc] initWithSize:default_size] autorelease]);
    }
  }

  if (IsVisible() != visible) {
    SetVisible(visible);
    content::NotificationService::current()->Notify(
        chrome::NOTIFICATION_EXTENSION_PAGE_ACTION_VISIBILITY_CHANGED,
        content::Source<ExtensionAction>(page_action_),
        content::Details<WebContents>(contents));
  }
}

void PageActionDecoration::SetToolTip(NSString* tooltip) {
  tooltip_.reset([tooltip retain]);
}

void PageActionDecoration::SetToolTip(std::string tooltip) {
  SetToolTip(tooltip.empty() ? nil : base::SysUTF8ToNSString(tooltip));
}

NSString* PageActionDecoration::GetToolTip() {
  return tooltip_.get();
}

NSPoint PageActionDecoration::GetBubblePointInFrame(NSRect frame) {
  // This is similar to |ImageDecoration::GetDrawRectInFrame()|,
  // except that code centers the image, which can differ in size
  // between actions.  This centers the maximum image size, so the
  // point will consistently be at the same y position.  x position is
  // easier (the middle of the centered image is the middle of the
  // frame).
  const CGFloat delta_height =
      NSHeight(frame) - extensions::IconsInfo::kPageActionIconMaxSize;
  const CGFloat bottom_inset = std::ceil(delta_height / 2.0);

  // Return a point just below the bottom of the maximal drawing area.
  return NSMakePoint(NSMidX(frame),
                     NSMaxY(frame) - bottom_inset + kBubblePointYOffset);
}

NSMenu* PageActionDecoration::GetMenu() {
  ExtensionService* service = browser_->profile()->GetExtensionService();
  if (!service)
    return nil;
  const Extension* extension = service->GetExtensionById(
      page_action_->extension_id(), false);
  DCHECK(extension);
  if (!extension)
    return nil;

  contextMenuController_.reset([[ExtensionActionContextMenuController alloc]
      initWithExtension:extension
                browser:browser_
        extensionAction:page_action_]);

  base::scoped_nsobject<NSMenu> contextMenu([[NSMenu alloc] initWithTitle:@""]);
  [contextMenuController_ populateMenu:contextMenu];
  return contextMenu.autorelease();
}

void PageActionDecoration::ShowPopup(const NSRect& frame,
                                     const GURL& popup_url) {
  // Anchor popup at the bottom center of the page action icon.
  AutocompleteTextField* field = owner_->GetAutocompleteTextField();
  NSPoint anchor = GetBubblePointInFrame(frame);
  anchor = [field convertPoint:anchor toView:nil];

  [ExtensionPopupController showURL:popup_url
                          inBrowser:chrome::GetLastActiveBrowser()
                         anchoredAt:anchor
                      arrowLocation:info_bubble::kTopRight
                            devMode:NO];
}

void PageActionDecoration::OnIconChanged() {
  UpdateVisibility(owner_->GetWebContents(), current_url_);
  owner_->RedrawDecoration(this);
}

void PageActionDecoration::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  switch (type) {
    case chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE: {
      ExtensionPopupController* popup = [ExtensionPopupController popup];
      if (popup && ![popup isClosing])
        [popup close];

      break;
    }
    case chrome::NOTIFICATION_EXTENSION_COMMAND_PAGE_ACTION_MAC:
    case chrome::NOTIFICATION_EXTENSION_COMMAND_SCRIPT_BADGE_MAC: {
      std::pair<const std::string, gfx::NativeWindow>* payload =
      content::Details<std::pair<const std::string, gfx::NativeWindow> >(
          details).ptr();
      std::string extension_id = payload->first;
      gfx::NativeWindow window = payload->second;
      if (window != browser_->window()->GetNativeWindow())
        break;
      if (extension_id != page_action_->extension_id())
        break;
      if (IsVisible())
        ActivatePageAction(owner_->GetPageActionFrame(page_action_));
      break;
    }

    default:
      NOTREACHED() << "Unexpected notification";
      break;
  }
}
