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

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

#include <stdint.h>

#include "base/logging.h"
#include "base/mac/bundle_locations.h"
#include "base/mac/scoped_nsobject.h"
#include "content/public/browser/browser_thread.h"
#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"

using content::BrowserThread;

namespace {

// The fraction of the size of the dock icon that the badge is.
constexpr CGFloat kBadgeFraction = 0.375f;
constexpr CGFloat kBadgeMargin = 4;
constexpr CGFloat kBadgeStrokeWidth = 6;

constexpr struct {
  CGFloat offset, radius, opacity;
} kBadgeShadows[] = {
    {0, 2, 0.14},
    {2, 2, 0.12},
    {1, 3, 0.2},
};

// The maximum update rate for the dock icon. 200ms = 5fps.
constexpr int64_t kUpdateFrequencyMs = 200;

}  // namespace

// A view that draws our dock tile.
@interface DockTileView : NSView {
 @private
  int downloads_;
  BOOL indeterminate_;
  float progress_;
}

// Indicates how many downloads are in progress.
@property (nonatomic) int downloads;

// Indicates whether the progress indicator should be in an indeterminate state
// or not.
@property (nonatomic) BOOL indeterminate;

// Indicates the amount of progress made of the download. Ranges from [0..1].
@property (nonatomic) float progress;

@end

@implementation DockTileView

@synthesize downloads = downloads_;
@synthesize indeterminate = indeterminate_;
@synthesize progress = progress_;

- (void)drawRect:(NSRect)dirtyRect {
  // Not -[NSApplication applicationIconImage]; that fails to return a pasted
  // custom icon.
  NSString* appPath = [base::mac::MainBundle() bundlePath];
  NSImage* appIcon = [[NSWorkspace sharedWorkspace] iconForFile:appPath];
  [appIcon drawInRect:[self bounds]
             fromRect:NSZeroRect
            operation:NSCompositeSourceOver
             fraction:1.0];

  if (downloads_ == 0)
    return;

  const CGFloat badgeSize = NSWidth(self.bounds) * kBadgeFraction;
  const NSRect badgeRect =
      NSMakeRect(NSMaxX(self.bounds) - badgeSize - kBadgeMargin, kBadgeMargin,
                 badgeSize, badgeSize);
  const CGFloat badgeRadius = badgeSize / 2;
  const NSPoint badgeCenter = NSMakePoint(NSMidX(badgeRect), NSMidY(badgeRect));

  NSBezierPath* backgroundPath =
      [NSBezierPath bezierPathWithOvalInRect:badgeRect];
  [[NSColor clearColor] setFill];

  base::scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]);
  shadow.get().shadowColor = [NSColor blackColor];
  for (const auto shadowProps : kBadgeShadows) {
    gfx::ScopedNSGraphicsContextSaveGState scopedGState;
    shadow.get().shadowOffset = NSMakeSize(0, -shadowProps.offset);
    shadow.get().shadowBlurRadius = shadowProps.radius;
    [[NSColor colorWithCalibratedWhite:0 alpha:shadowProps.opacity] setFill];
    [shadow set];
    [backgroundPath fill];
  }

  [[NSColor colorWithCalibratedRed:0xec / 255.0
                             green:0xf3 / 255.0
                              blue:0xfe / 255.0
                             alpha:1] setFill];
  [backgroundPath fill];

  // Stroke
  if (!indeterminate_) {
    NSBezierPath* strokePath;
    if (progress_ >= 1.0) {
      strokePath = [NSBezierPath bezierPathWithOvalInRect:badgeRect];
    } else {
      CGFloat endAngle = 90.0 - 360.0 * progress_;
      if (endAngle < 0.0)
        endAngle += 360.0;
      strokePath = [NSBezierPath bezierPath];
      [strokePath
          appendBezierPathWithArcWithCenter:badgeCenter
                                     radius:badgeRadius - kBadgeStrokeWidth / 2
                                 startAngle:90.0
                                   endAngle:endAngle
                                  clockwise:YES];
    }
    [strokePath setLineWidth:kBadgeStrokeWidth];
    [[NSColor colorWithCalibratedRed:0x42 / 255.0
                               green:0x85 / 255.0
                                blue:0xf4 / 255.0
                               alpha:1] setStroke];
    [strokePath stroke];
  }

  // Download count
  base::scoped_nsobject<NSNumberFormatter> formatter(
      [[NSNumberFormatter alloc] init]);
  NSString* countString =
      [formatter stringFromNumber:[NSNumber numberWithInt:downloads_]];

  CGFloat countFontSize = 24;
  NSSize countSize = NSZeroSize;
  base::scoped_nsobject<NSAttributedString> countAttrString;
  while (1) {
    NSFont* countFont;
    if (@available(macOS 10.11, *)) {
      countFont =
          [NSFont systemFontOfSize:countFontSize weight:NSFontWeightMedium];
    } else {
      countFont = [[NSFontManager sharedFontManager]
          convertWeight:YES
                 ofFont:[NSFont systemFontOfSize:countFontSize]];
    }

    // This will generally be plain Helvetica.
    if (!countFont)
      countFont = [NSFont userFontOfSize:countFontSize];

    // Continued failure would generate an NSException.
    if (!countFont)
      break;

    countAttrString.reset([[NSAttributedString alloc]
        initWithString:countString
            attributes:@{
              NSForegroundColorAttributeName :
                  [NSColor colorWithCalibratedWhite:0 alpha:0.65],
              NSFontAttributeName : countFont,
            }]);
    countSize = [countAttrString size];
    if (countSize.width > (badgeRadius - kBadgeStrokeWidth) * 1.5) {
      countFontSize -= 1.0;
    } else {
      break;
    }
  }

  NSPoint countOrigin = badgeCenter;
  countOrigin.x -= countSize.width / 2;
  countOrigin.y -= countSize.height / 2;

  [countAttrString.get() drawAtPoint:countOrigin];
}

@end


@implementation DockIcon

+ (DockIcon*)sharedDockIcon {
  static DockIcon* icon;
  if (!icon) {
    NSDockTile* dockTile = [[NSApplication sharedApplication] dockTile];

    base::scoped_nsobject<DockTileView> dockTileView(
        [[DockTileView alloc] init]);
    [dockTile setContentView:dockTileView];

    icon = [[DockIcon alloc] init];
  }

  return icon;
}

- (void)updateIcon {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  static base::TimeDelta updateFrequency =
      base::TimeDelta::FromMilliseconds(kUpdateFrequencyMs);

  base::TimeTicks now = base::TimeTicks::Now();
  base::TimeDelta timeSinceLastUpdate = now - lastUpdate_;
  if (!forceUpdate_ && timeSinceLastUpdate < updateFrequency)
    return;

  lastUpdate_ = now;
  forceUpdate_ = NO;

  NSDockTile* dockTile = [[NSApplication sharedApplication] dockTile];

  [dockTile display];
}

- (void)setDownloads:(int)downloads {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  NSDockTile* dockTile = [[NSApplication sharedApplication] dockTile];
  DockTileView* dockTileView = (DockTileView*)([dockTile contentView]);

  if (downloads != [dockTileView downloads]) {
    [dockTileView setDownloads:downloads];
    forceUpdate_ = YES;
  }
}

- (void)setIndeterminate:(BOOL)indeterminate {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  NSDockTile* dockTile = [[NSApplication sharedApplication] dockTile];
  DockTileView* dockTileView = (DockTileView*)([dockTile contentView]);

  if (indeterminate != [dockTileView indeterminate]) {
    [dockTileView setIndeterminate:indeterminate];
    forceUpdate_ = YES;
  }
}

- (void)setProgress:(float)progress {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  NSDockTile* dockTile = [[NSApplication sharedApplication] dockTile];
  DockTileView* dockTileView = (DockTileView*)([dockTile contentView]);

  [dockTileView setProgress:progress];
}

@end
