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

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

#include "base/logging.h"

// Minimum and maximum click-hold timeout.
static const NSTimeInterval kMinTimeout = 0.0;
static const NSTimeInterval kMaxTimeout = 5.0;

// Drag distance threshold to activate click-hold; should be >= 0.
static const CGFloat kDragDistThreshold = 2.5;

// See |-resetToDefaults| (and header file) for other default values.

@interface ClickHoldButtonCell (Private)
- (void)resetToDefaults;
@end  // @interface ClickHoldButtonCell (Private)

@implementation ClickHoldButtonCell

@synthesize enableClickHold = enableClickHold_;
@synthesize clickHoldTimeout = clickHoldTimeout_;
@synthesize trackOnlyInRect = trackOnlyInRect_;
@synthesize activateOnDrag = activateOnDrag_;
@synthesize clickHoldTarget = clickHoldTarget_;
@synthesize clickHoldAction = clickHoldAction_;

// Overrides:

+ (BOOL)prefersTrackingUntilMouseUp {
  return NO;
}

- (id)init {
  if ((self = [super init]))
    [self resetToDefaults];
  return self;
}

- (id)initWithCoder:(NSCoder*)decoder {
  if ((self = [super initWithCoder:decoder]))
    [self resetToDefaults];
  return self;
}

- (id)initImageCell:(NSImage*)image {
  if ((self = [super initImageCell:image]))
    [self resetToDefaults];
  return self;
}

- (id)initTextCell:(NSString*)string {
  if ((self = [super initTextCell:string]))
    [self resetToDefaults];
  return self;
}

- (BOOL)startTrackingAt:(NSPoint)startPoint
                 inView:(NSView*)controlView {
  return enableClickHold_ ? YES :
                            [super startTrackingAt:startPoint
                                            inView:controlView];
}

- (BOOL)continueTracking:(NSPoint)lastPoint
                      at:(NSPoint)currentPoint
                  inView:(NSView*)controlView {
  return enableClickHold_ ? YES :
                            [super continueTracking:lastPoint
                                                 at:currentPoint
                                             inView:controlView];
}

- (BOOL)trackMouse:(NSEvent*)originalEvent
            inRect:(NSRect)cellFrame
            ofView:(NSView*)controlView
      untilMouseUp:(BOOL)untilMouseUp {
  if (!enableClickHold_) {
    return [super trackMouse:originalEvent
                      inRect:cellFrame
                      ofView:controlView
                untilMouseUp:untilMouseUp];
  }

  // If doing click-hold, track the mouse ourselves.
  NSPoint currPoint = [controlView convertPoint:[originalEvent locationInWindow]
                                       fromView:nil];
  NSPoint lastPoint = currPoint;
  NSPoint firstPoint = currPoint;
  NSTimeInterval timeout =
      MAX(MIN(clickHoldTimeout_, kMaxTimeout), kMinTimeout);
  NSDate* clickHoldBailTime = [NSDate dateWithTimeIntervalSinceNow:timeout];

  if (![self startTrackingAt:currPoint inView:controlView])
    return NO;

  enum {
    kContinueTrack, kStopClickHold, kStopMouseUp, kStopLeftRect, kStopNoContinue
  } state = kContinueTrack;
  do {
    NSEvent* event = [NSApp nextEventMatchingMask:(NSLeftMouseDraggedMask |
                                                   NSLeftMouseUpMask)
                                        untilDate:clickHoldBailTime
                                           inMode:NSEventTrackingRunLoopMode
                                          dequeue:YES];
    currPoint = [controlView convertPoint:[event locationInWindow]
                                 fromView:nil];

    // Time-out.
    if (!event) {
      state = kStopClickHold;

    // Drag? (If distance meets threshold.)
    } else if (activateOnDrag_ && ([event type] == NSLeftMouseDragged)) {
      CGFloat dx = currPoint.x - firstPoint.x;
      CGFloat dy = currPoint.y - firstPoint.y;
      if ((dx*dx + dy*dy) >= (kDragDistThreshold*kDragDistThreshold))
        state = kStopClickHold;

    // Mouse up.
    } else if ([event type] == NSLeftMouseUp) {
      state = kStopMouseUp;

    // Stop tracking if mouse left frame rectangle (if requested to do so).
    } else if (trackOnlyInRect_ && ![controlView mouse:currPoint
                                                inRect:cellFrame]) {
      state = kStopLeftRect;

    // Stop tracking if instructed to.
    } else if (![self continueTracking:lastPoint
                                    at:currPoint
                                inView:controlView]) {
      state = kStopNoContinue;
    }

    lastPoint = currPoint;
  } while (state == kContinueTrack);

  [self stopTracking:lastPoint
                  at:lastPoint
              inView:controlView
           mouseIsUp:NO];

  switch (state) {
    case kStopClickHold:
      if (clickHoldAction_) {
        [static_cast<NSControl*>(controlView) sendAction:clickHoldAction_
                                                      to:clickHoldTarget_];
      }
      return YES;

    case kStopMouseUp:
      if ([self action]) {
        [static_cast<NSControl*>(controlView) sendAction:[self action]
                                                      to:[self target]];
      }
      return YES;

    case kStopLeftRect:
    case kStopNoContinue:
      return NO;

    default:
      NOTREACHED() << "Unknown terminating state!";
  }

  return NO;
}

@end  // @implementation ClickHoldButtonCell

@implementation ClickHoldButtonCell (Private)

// Resets various members to defaults indicated in the header file. (Those
// without indicated defaults are *not* touched.) Please keep the values below
// in sync with the header file, and please be aware of side-effects on code
// which relies on the "published" defaults.
- (void)resetToDefaults {
  [self setEnableClickHold:NO];
  [self setClickHoldTimeout:0.25];
  [self setTrackOnlyInRect:NO];
  [self setActivateOnDrag:YES];
}

@end  // @implementation ClickHoldButtonCell (Private)
