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

#include "base/mac/scoped_nsobject.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
#import "ui/base/cocoa/focus_tracker.h"
#import "ui/gfx/test/ui_cocoa_test_helper.h"

namespace {

class FocusTrackerTest : public ui::CocoaTest {
 public:
  virtual void SetUp() {
    ui::CocoaTest::SetUp();
    base::scoped_nsobject<NSView> view(
        [[NSView alloc] initWithFrame:NSZeroRect]);
    viewA_ = view.get();
    [[test_window() contentView] addSubview:viewA_];

    view.reset([[NSView alloc] initWithFrame:NSZeroRect]);
    viewB_ = view.get();
    [[test_window() contentView] addSubview:viewB_];
  }

 protected:
  NSView* viewA_;
  NSView* viewB_;
};

TEST_F(FocusTrackerTest, SaveRestore) {
  NSWindow* window = test_window();
  ASSERT_TRUE([window makeFirstResponder:viewA_]);
  base::scoped_nsobject<FocusTracker> tracker(
      [[FocusTracker alloc] initWithWindow:window]);
  // Give focus to |viewB_|, then try and restore it to view1.
  ASSERT_TRUE([window makeFirstResponder:viewB_]);
  EXPECT_TRUE([tracker restoreFocusInWindow:window]);
  EXPECT_EQ(viewA_, [window firstResponder]);
}

TEST_F(FocusTrackerTest, SaveRestoreWithTextView) {
  // Valgrind will complain if the text field has zero size.
  NSRect frame = NSMakeRect(0, 0, 100, 20);
  NSWindow* window = test_window();
  base::scoped_nsobject<NSTextField> text(
      [[NSTextField alloc] initWithFrame:frame]);
  [[window contentView] addSubview:text];

  ASSERT_TRUE([window makeFirstResponder:text]);
  base::scoped_nsobject<FocusTracker> tracker(
      [[FocusTracker alloc] initWithWindow:window]);
  // Give focus to |viewB_|, then try and restore it to the text field.
  ASSERT_TRUE([window makeFirstResponder:viewB_]);
  EXPECT_TRUE([tracker restoreFocusInWindow:window]);
  EXPECT_TRUE([[window firstResponder] isKindOfClass:[NSTextView class]]);
}

TEST_F(FocusTrackerTest, DontRestoreToViewNotInWindow) {
  NSWindow* window = test_window();
  base::scoped_nsobject<NSView> viewC(
      [[NSView alloc] initWithFrame:NSZeroRect]);
  [[window contentView] addSubview:viewC];

  ASSERT_TRUE([window makeFirstResponder:viewC]);
  base::scoped_nsobject<FocusTracker> tracker(
      [[FocusTracker alloc] initWithWindow:window]);

  // Give focus to |viewB_|, then remove viewC from the hierarchy and try
  // to restore focus.  The restore should fail.
  ASSERT_TRUE([window makeFirstResponder:viewB_]);
  [viewC removeFromSuperview];
  EXPECT_FALSE([tracker restoreFocusInWindow:window]);
}

TEST_F(FocusTrackerTest, DontRestoreFocusToViewInDifferentWindow) {
  NSWindow* window = test_window();
  ASSERT_TRUE([window makeFirstResponder:viewA_]);
  base::scoped_nsobject<FocusTracker> tracker(
      [[FocusTracker alloc] initWithWindow:window]);

  // Give focus to |viewB_|, then try and restore focus in a different
  // window.  It is ok to pass a nil NSWindow here because we only use
  // it for direct comparison.
  ASSERT_TRUE([window makeFirstResponder:viewB_]);
  EXPECT_FALSE([tracker restoreFocusInWindow:nil]);
}


}  // namespace
