// Copyright (c) 2011 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.

#import "chrome/browser/ui/cocoa/styled_text_field_cell.h"

#include "base/logging.h"
#include "chrome/browser/themes/theme_properties.h"
#include "chrome/browser/themes/theme_service.h"
#import "chrome/browser/ui/cocoa/nsview_additions.h"
#import "chrome/browser/ui/cocoa/themed_window.h"
#include "grit/theme_resources.h"
#import "ui/base/cocoa/nsgraphics_context_additions.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/font.h"
#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"

@implementation StyledTextFieldCell

- (CGFloat)topTextFrameOffset {
  return 0.0;
}

- (CGFloat)bottomTextFrameOffset {
  return 0.0;
}

- (CGFloat)cornerRadius {
  return 0.0;
}

- (rect_path_utils::RoundedCornerFlags)roundedCornerFlags {
  return rect_path_utils::RoundedCornerAll;
}

- (BOOL)shouldDrawBezel {
  return NO;
}

- (NSRect)textFrameForFrameInternal:(NSRect)cellFrame {
  CGFloat topOffset = [self topTextFrameOffset];
  NSRect textFrame = cellFrame;
  textFrame.origin.y += topOffset;
  textFrame.size.height -= topOffset + [self bottomTextFrameOffset];
  return textFrame;
}

// Returns the same value as textCursorFrameForFrame, but does not call it
// directly to avoid potential infinite loops.
- (NSRect)textFrameForFrame:(NSRect)cellFrame {
  return [self textFrameForFrameInternal:cellFrame];
}

// Returns the same value as textFrameForFrame, but does not call it directly to
// avoid potential infinite loops.
- (NSRect)textCursorFrameForFrame:(NSRect)cellFrame {
  return [self textFrameForFrameInternal:cellFrame];
}

// Override to show the I-beam cursor only in the area given by
// |textCursorFrameForFrame:|.
- (void)resetCursorRect:(NSRect)cellFrame inView:(NSView *)controlView {
  [super resetCursorRect:[self textCursorFrameForFrame:cellFrame]
                  inView:controlView];
}

// For NSTextFieldCell this is the area within the borders.  For our
// purposes, we count the info decorations as being part of the
// border.
- (NSRect)drawingRectForBounds:(NSRect)theRect {
  return [super drawingRectForBounds:[self textFrameForFrame:theRect]];
}

// TODO(shess): This code is manually drawing the cell's border area,
// but otherwise the cell assumes -setBordered:YES for purposes of
// calculating things like the editing area.  This is probably
// incorrect.  I know that this affects -drawingRectForBounds:.
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
  const CGFloat lineWidth = [controlView cr_lineWidth];
  const CGFloat halfLineWidth = lineWidth / 2.0;

  DCHECK([controlView isFlipped]);
  rect_path_utils::RoundedCornerFlags roundedCornerFlags =
      [self roundedCornerFlags];

  // TODO(shess): This inset is also reflected by |kFieldVisualInset|
  // in omnibox_popup_view_mac.mm.
  const NSRect frame = NSInsetRect(cellFrame, 0, lineWidth);
  const CGFloat radius = [self cornerRadius];

  // Paint button background image if there is one (otherwise the border won't
  // look right).
  ThemeService* themeProvider =
      static_cast<ThemeService*>([[controlView window] themeProvider]);
  if (themeProvider) {
    NSColor* backgroundImageColor = nil;
    if (themeProvider->HasCustomImage(IDR_THEME_BUTTON_BACKGROUND)) {
      backgroundImageColor =
          themeProvider->GetNSImageColorNamed(IDR_THEME_BUTTON_BACKGROUND);
    }
    if (backgroundImageColor) {
      // Set the phase to match window.
      NSRect trueRect = [controlView convertRect:cellFrame toView:nil];
      NSPoint midPoint = NSMakePoint(NSMinX(trueRect), NSMaxY(trueRect));
      [[NSGraphicsContext currentContext] cr_setPatternPhase:midPoint
                                                     forView:controlView];

      // NOTE(shess): This seems like it should be using a 0.0 inset,
      // but AFAICT using a halfLineWidth inset is important in mixing the
      // toolbar background and the omnibox background.
      rect_path_utils::FillRectWithInset(roundedCornerFlags, frame,
                                         halfLineWidth, halfLineWidth, radius,
                                         backgroundImageColor);
    }

    // Draw the outer stroke (over the background).
    BOOL active = [[controlView window] isMainWindow];
    NSColor* strokeColor = themeProvider->GetNSColor(
        active ? ThemeProperties::COLOR_TOOLBAR_BUTTON_STROKE :
                 ThemeProperties::COLOR_TOOLBAR_BUTTON_STROKE_INACTIVE);
    rect_path_utils::FrameRectWithInset(roundedCornerFlags, frame, 0.0, 0.0,
                                        radius, lineWidth, strokeColor);
  }

  // Fill interior with background color.
  rect_path_utils::FillRectWithInset(roundedCornerFlags, frame, lineWidth,
                                     lineWidth, radius,
                                     [self backgroundColor]);

  // Draw the shadow.  For the rounded-rect case, the shadow needs to
  // slightly turn in at the corners.  |shadowFrame| is at the same
  // midline as the inner border line on the top and left, but at the
  // outer border line on the bottom and right.  The clipping change
  // will clip the bottom and right edges (and corner).
  {
    gfx::ScopedNSGraphicsContextSaveGState state;
    [rect_path_utils::RectPathWithInset(roundedCornerFlags, frame, lineWidth,
                                        lineWidth, radius) addClip];
    const NSRect shadowFrame =
        NSOffsetRect(frame, halfLineWidth, halfLineWidth);
    NSColor* shadowShade = [NSColor colorWithCalibratedWhite:0.0
                                                       alpha:0.05 / lineWidth];
    rect_path_utils::FrameRectWithInset(roundedCornerFlags, shadowFrame,
                                        halfLineWidth, halfLineWidth,
                                        radius - halfLineWidth, lineWidth,
                                        shadowShade);
  }

  // Draw optional bezel below bottom stroke.
  if ([self shouldDrawBezel] && themeProvider &&
      themeProvider->UsingDefaultTheme()) {

    NSColor* bezelColor = themeProvider->GetNSColor(
        ThemeProperties::COLOR_TOOLBAR_BEZEL);
    [[bezelColor colorWithAlphaComponent:0.5 / lineWidth] set];
    NSRect bezelRect = NSMakeRect(cellFrame.origin.x,
                                  NSMaxY(cellFrame) - lineWidth,
                                  NSWidth(cellFrame),
                                  lineWidth);
    bezelRect = NSInsetRect(bezelRect, radius - halfLineWidth, 0.0);
    NSRectFillUsingOperation(bezelRect, NSCompositeSourceOver);
  }

  // Draw the interior before the focus ring, to make sure nothing overlaps it.
  [self drawInteriorWithFrame:cellFrame inView:controlView];

  // Draw the focus ring if needed.
  if ([self showsFirstResponder]) {
    NSColor* color = [[NSColor keyboardFocusIndicatorColor]
        colorWithAlphaComponent:0.5 / lineWidth];
    rect_path_utils::FrameRectWithInset(roundedCornerFlags, frame, 0.0, 0.0,
                                        radius, lineWidth * 2, color);
  }
}

@end
