// Copyright 2013 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 <Cocoa/Cocoa.h>

#include "chrome/browser/ui/cocoa/screen_capture_notification_ui_cocoa.h"

#include "base/compiler_specific.h"
#include "base/i18n/rtl.h"
#include "base/mac/bundle_locations.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"

@interface ScreenCaptureNotificationController()
- (void)Hide;
@end

class ScreenCaptureNotificationUICocoa : public ScreenCaptureNotificationUI {
 public:
  explicit ScreenCaptureNotificationUICocoa(const string16& text);
  virtual ~ScreenCaptureNotificationUICocoa();

  // ScreenCaptureNotificationUI interface.
  virtual void OnStarted(const base::Closure& stop_callback) OVERRIDE;

 private:
  const string16 text_;
  ScreenCaptureNotificationController* window_controller_;

  DISALLOW_COPY_AND_ASSIGN(ScreenCaptureNotificationUICocoa);
};

ScreenCaptureNotificationUICocoa::ScreenCaptureNotificationUICocoa(
    const string16& text)
    : text_(text),
      window_controller_(nil) {
}

ScreenCaptureNotificationUICocoa::~ScreenCaptureNotificationUICocoa() {
  // ScreenCaptureNotificationController is responsible for releasing itself in
  // its windowWillClose: method.
  [window_controller_ Hide];
  window_controller_ = nil;
}

void ScreenCaptureNotificationUICocoa::OnStarted(
    const base::Closure& stop_callback) {
  DCHECK(!stop_callback.is_null());
  DCHECK(window_controller_ == nil);

  window_controller_ =
      [[ScreenCaptureNotificationController alloc]
          initWithCallback:stop_callback
                     text:text_];
  [window_controller_ showWindow:nil];
}

scoped_ptr<ScreenCaptureNotificationUI> ScreenCaptureNotificationUI::Create(
    const string16& text) {
  return scoped_ptr<ScreenCaptureNotificationUI>(
      new ScreenCaptureNotificationUICocoa(text));
}

@implementation ScreenCaptureNotificationController
- (id)initWithCallback:(const base::Closure&)stop_callback
                  text:(const string16&)text {
  NSString* nibpath =
      [base::mac::FrameworkBundle() pathForResource:@"ScreenCaptureNotification"
                                             ofType:@"nib"];
  self = [super initWithWindowNibPath:nibpath owner:self];
  if (self) {
    stop_callback_ = stop_callback;
    text_ = text;
  }
  return self;
}

- (void)dealloc {
  [super dealloc];
}

- (IBAction)stopSharing:(id)sender {
  if (!stop_callback_.is_null()) {
    stop_callback_.Run();
  }
}

- (void)Hide {
  stop_callback_.Reset();
  [self close];
}

- (void)windowDidLoad {
  [statusField_ setStringValue:base::SysUTF16ToNSString(text_)];

  string16 button_label =
      l10n_util::GetStringUTF16(IDS_MEDIA_SCREEN_CAPTURE_NOTIFICATION_STOP);
  [stopButton_ setTitle:base::SysUTF16ToNSString(button_label)];

  // Resize the window dynamically based on the content.
  CGFloat oldConnectedWidth = NSWidth([statusField_ bounds]);
  [statusField_ sizeToFit];
  NSRect statusFrame = [statusField_ frame];
  CGFloat newConnectedWidth = NSWidth(statusFrame);

  // Set a max width for the connected to text field.
  const int kMaximumStatusWidth = 400;
  if (newConnectedWidth > kMaximumStatusWidth) {
    newConnectedWidth = kMaximumStatusWidth;
    statusFrame.size.width = newConnectedWidth;
    [statusField_ setFrame:statusFrame];
  }

  CGFloat oldstopWidth = NSWidth([stopButton_ bounds]);
  [stopButton_ sizeToFit];
  NSRect stopFrame = [stopButton_ frame];
  CGFloat newStopWidth = NSWidth(stopFrame);

  // Move the stop button appropriately.
  stopFrame.origin.x += newConnectedWidth - oldConnectedWidth;
  [stopButton_ setFrame:stopFrame];

  // Then resize the window appropriately.
  NSWindow *window = [self window];
  NSRect windowFrame = [window frame];
  windowFrame.size.width += (newConnectedWidth - oldConnectedWidth +
                             newStopWidth - oldstopWidth);
  [window setFrame:windowFrame display:NO];

  if (base::i18n::IsRTL()) {
    // Handle right to left case
    CGFloat buttonInset = NSWidth(windowFrame) - NSMaxX(stopFrame);
    CGFloat buttonTextSpacing
        = NSMinX(stopFrame) - NSMaxX(statusFrame);
    stopFrame.origin.x = buttonInset;
    statusFrame.origin.x = NSMaxX(stopFrame) + buttonTextSpacing;
    [statusField_ setFrame:statusFrame];
    [stopButton_ setFrame:stopFrame];
  }

  // Center the window at the bottom of the screen, above the dock (if present).
  NSRect desktopRect = [[NSScreen mainScreen] visibleFrame];
  NSRect windowRect = [[self window] frame];
  CGFloat x = (NSWidth(desktopRect) - NSWidth(windowRect)) / 2;
  CGFloat y = NSMinY(desktopRect);
  [[self window] setFrameOrigin:NSMakePoint(x, y)];
}

- (void)windowWillClose:(NSNotification*)notification {
  [self stopSharing:self];
  [self autorelease];
}

@end


@implementation ScreenCaptureNotificationWindow
- (id)initWithContentRect:(NSRect)contentRect
                styleMask:(NSUInteger)aStyle
                  backing:(NSBackingStoreType)bufferingType
                    defer:(BOOL)flag {
  // Pass NSBorderlessWindowMask for the styleMask to remove the title bar.
  self = [super initWithContentRect:contentRect
                          styleMask:NSBorderlessWindowMask
                            backing:bufferingType
                              defer:flag];

  if (self) {
    // Set window to be clear and non-opaque so we can see through it.
    [self setBackgroundColor:[NSColor clearColor]];
    [self setOpaque:NO];
    [self setMovableByWindowBackground:YES];

    // Pull the window up to Status Level so that it always displays.
    [self setLevel:NSStatusWindowLevel];
  }
  return self;
}
@end

@implementation ScreenCaptureNotificationView
- (void)drawRect:(NSRect)rect {
  // All magic numbers taken from screen shots provided by UX.
  NSRect bounds = NSInsetRect([self bounds], 1, 1);

  NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:bounds
                                                       xRadius:5
                                                       yRadius:5];
  NSColor *gray = [NSColor colorWithCalibratedWhite:0.91 alpha:1.0];
  [gray setFill];
  [path fill];
  [path setLineWidth:4];
  NSColor *green = [NSColor colorWithCalibratedRed:0.13
                                             green:0.69
                                              blue:0.11
                                             alpha:1.0];
  [green setStroke];
  [path stroke];


  // Draw drag handle on proper side
  const CGFloat kHeight = 21.0;
  const CGFloat kBaseInset = 12.0;
  const CGFloat kDragHandleWidth = 5.0;

  NSColor *dark = [NSColor colorWithCalibratedWhite:0.70 alpha:1.0];
  NSColor *light = [NSColor colorWithCalibratedWhite:0.97 alpha:1.0];

  // Turn off aliasing so it's nice and crisp.
  NSGraphicsContext *context = [NSGraphicsContext currentContext];
  BOOL alias = [context shouldAntialias];
  [context setShouldAntialias:NO];

  // Handle bidirectional locales properly.
  CGFloat inset = base::i18n::IsRTL() ?
      NSMaxX(bounds) - kBaseInset - kDragHandleWidth : kBaseInset;

  NSPoint top = NSMakePoint(inset, NSMidY(bounds) - kHeight / 2.0);
  NSPoint bottom = NSMakePoint(inset, top.y + kHeight);

  path = [NSBezierPath bezierPath];
  [path moveToPoint:top];
  [path lineToPoint:bottom];
  [dark setStroke];
  [path stroke];

  top.x += 1;
  bottom.x += 1;
  path = [NSBezierPath bezierPath];
  [path moveToPoint:top];
  [path lineToPoint:bottom];
  [light setStroke];
  [path stroke];

  top.x += 2;
  bottom.x += 2;
  path = [NSBezierPath bezierPath];
  [path moveToPoint:top];
  [path lineToPoint:bottom];
  [dark setStroke];
  [path stroke];

  top.x += 1;
  bottom.x += 1;
  path = [NSBezierPath bezierPath];
  [path moveToPoint:top];
  [path lineToPoint:bottom];
  [light setStroke];
  [path stroke];

  [context setShouldAntialias:alias];
}

@end
