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

#include <string>

#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/font_list.h"
#include "ui/views/border.h"
#include "ui/views/controls/link.h"
#include "ui/views/controls/styled_label.h"
#include "ui/views/controls/styled_label_listener.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/widget/widget.h"

using base::ASCIIToUTF16;

namespace views {

class StyledLabelTest : public ViewsTestBase, public StyledLabelListener {
 public:
  StyledLabelTest() {}
  virtual ~StyledLabelTest() {}

  // StyledLabelListener implementation.
  virtual void StyledLabelLinkClicked(const gfx::Range& range,
                                      int event_flags) override {}

 protected:
  StyledLabel* styled() { return styled_.get(); }

  void InitStyledLabel(const std::string& ascii_text) {
    styled_.reset(new StyledLabel(ASCIIToUTF16(ascii_text), this));
    styled_->set_owned_by_client();
  }

  int StyledLabelContentHeightForWidth(int w) {
    return styled_->GetHeightForWidth(w) - styled_->GetInsets().height();
  }

 private:
  scoped_ptr<StyledLabel> styled_;

  DISALLOW_COPY_AND_ASSIGN(StyledLabelTest);
};

TEST_F(StyledLabelTest, NoWrapping) {
  const std::string text("This is a test block of text");
  InitStyledLabel(text);
  Label label(ASCIIToUTF16(text));
  const gfx::Size label_preferred_size = label.GetPreferredSize();
  EXPECT_EQ(label_preferred_size.height(),
            StyledLabelContentHeightForWidth(label_preferred_size.width() * 2));
}

TEST_F(StyledLabelTest, TrailingWhitespaceiIgnored) {
  const std::string text("This is a test block of text   ");
  InitStyledLabel(text);

  styled()->SetBounds(0, 0, 1000, 1000);
  styled()->Layout();

  ASSERT_EQ(1, styled()->child_count());
  ASSERT_EQ(std::string(Label::kViewClassName),
            styled()->child_at(0)->GetClassName());
  EXPECT_EQ(ASCIIToUTF16("This is a test block of text"),
            static_cast<Label*>(styled()->child_at(0))->text());
}

TEST_F(StyledLabelTest, RespectLeadingWhitespace) {
  const std::string text("   This is a test block of text");
  InitStyledLabel(text);

  styled()->SetBounds(0, 0, 1000, 1000);
  styled()->Layout();

  ASSERT_EQ(1, styled()->child_count());
  ASSERT_EQ(std::string(Label::kViewClassName),
            styled()->child_at(0)->GetClassName());
  EXPECT_EQ(ASCIIToUTF16("   This is a test block of text"),
            static_cast<Label*>(styled()->child_at(0))->text());
}

TEST_F(StyledLabelTest, FirstLineNotEmptyWhenLeadingWhitespaceTooLong) {
  const std::string text("                                     a");
  InitStyledLabel(text);

  Label label(ASCIIToUTF16(text));
  gfx::Size label_preferred_size = label.GetPreferredSize();

  styled()->SetBounds(0, 0, label_preferred_size.width() / 2, 1000);
  styled()->Layout();

  ASSERT_EQ(1, styled()->child_count());
  ASSERT_EQ(std::string(Label::kViewClassName),
            styled()->child_at(0)->GetClassName());
  EXPECT_EQ(ASCIIToUTF16("a"),
            static_cast<Label*>(styled()->child_at(0))->text());
}

TEST_F(StyledLabelTest, BasicWrapping) {
  const std::string text("This is a test block of text");
  InitStyledLabel(text);
  Label label(ASCIIToUTF16(text.substr(0, text.size() * 2 / 3)));
  gfx::Size label_preferred_size = label.GetPreferredSize();
  EXPECT_EQ(label_preferred_size.height() * 2,
            StyledLabelContentHeightForWidth(label_preferred_size.width()));

  // Also respect the border.
  styled()->SetBorder(Border::CreateEmptyBorder(3, 3, 3, 3));
  styled()->SetBounds(
      0,
      0,
      styled()->GetInsets().width() + label_preferred_size.width(),
      styled()->GetInsets().height() + 2 * label_preferred_size.height());
  styled()->Layout();
  ASSERT_EQ(2, styled()->child_count());
  EXPECT_EQ(3, styled()->child_at(0)->x());
  EXPECT_EQ(3, styled()->child_at(0)->y());
  EXPECT_EQ(styled()->height() - 3, styled()->child_at(1)->bounds().bottom());
}

TEST_F(StyledLabelTest, CreateLinks) {
  const std::string text("This is a test block of text.");
  InitStyledLabel(text);

  // Without links, there should be no focus border.
  EXPECT_TRUE(styled()->GetInsets().empty());

  // Now let's add some links.
  styled()->AddStyleRange(gfx::Range(0, 1),
                          StyledLabel::RangeStyleInfo::CreateForLink());
  styled()->AddStyleRange(gfx::Range(1, 2),
                          StyledLabel::RangeStyleInfo::CreateForLink());
  styled()->AddStyleRange(gfx::Range(10, 11),
                          StyledLabel::RangeStyleInfo::CreateForLink());
  styled()->AddStyleRange(gfx::Range(12, 13),
                          StyledLabel::RangeStyleInfo::CreateForLink());

  // Now there should be a focus border because there are non-empty Links.
  EXPECT_FALSE(styled()->GetInsets().empty());

  // Verify layout creates the right number of children.
  styled()->SetBounds(0, 0, 1000, 1000);
  styled()->Layout();
  EXPECT_EQ(7, styled()->child_count());
}

TEST_F(StyledLabelTest, DontBreakLinks) {
  const std::string text("This is a test block of text, ");
  const std::string link_text("and this should be a link");
  InitStyledLabel(text + link_text);
  styled()->AddStyleRange(
      gfx::Range(text.size(), text.size() + link_text.size()),
      StyledLabel::RangeStyleInfo::CreateForLink());

  Label label(ASCIIToUTF16(text + link_text.substr(0, link_text.size() / 2)));
  gfx::Size label_preferred_size = label.GetPreferredSize();
  int pref_height = styled()->GetHeightForWidth(label_preferred_size.width());
  EXPECT_EQ(label_preferred_size.height() * 2,
            pref_height - styled()->GetInsets().height());

  styled()->SetBounds(0, 0, label_preferred_size.width(), pref_height);
  styled()->Layout();
  ASSERT_EQ(2, styled()->child_count());
  // The label has no focus border while the link (and thus overall styled
  // label) does, so the label should be inset by the width of the focus border.
  EXPECT_EQ(Label::kFocusBorderPadding, styled()->child_at(0)->x());
  EXPECT_EQ(0, styled()->child_at(1)->x());
}

TEST_F(StyledLabelTest, StyledRangeWithDisabledLineWrapping) {
  const std::string text("This is a test block of text, ");
  const std::string unbreakable_text("and this should not be broken");
  InitStyledLabel(text + unbreakable_text);
  StyledLabel::RangeStyleInfo style_info;
  style_info.disable_line_wrapping = true;
  styled()->AddStyleRange(
      gfx::Range(text.size(), text.size() + unbreakable_text.size()),
      style_info);

  Label label(ASCIIToUTF16(
      text + unbreakable_text.substr(0, unbreakable_text.size() / 2)));
  gfx::Size label_preferred_size = label.GetPreferredSize();
  int pref_height = styled()->GetHeightForWidth(label_preferred_size.width());
  EXPECT_EQ(label_preferred_size.height() * 2,
            pref_height - styled()->GetInsets().height());

  styled()->SetBounds(0, 0, label_preferred_size.width(), pref_height);
  styled()->Layout();
  ASSERT_EQ(2, styled()->child_count());
  EXPECT_EQ(0, styled()->child_at(0)->x());
  EXPECT_EQ(0, styled()->child_at(1)->x());
}

TEST_F(StyledLabelTest, StyledRangeUnderlined) {
  const std::string text("This is a test block of text, ");
  const std::string underlined_text("and this should be undelined");
  InitStyledLabel(text + underlined_text);
  StyledLabel::RangeStyleInfo style_info;
  style_info.font_style = gfx::Font::UNDERLINE;
  styled()->AddStyleRange(
      gfx::Range(text.size(), text.size() + underlined_text.size()),
      style_info);

  styled()->SetBounds(0, 0, 1000, 1000);
  styled()->Layout();

  ASSERT_EQ(2, styled()->child_count());
  ASSERT_EQ(std::string(Label::kViewClassName),
            styled()->child_at(1)->GetClassName());
  EXPECT_EQ(
      gfx::Font::UNDERLINE,
      static_cast<Label*>(styled()->child_at(1))->font_list().GetFontStyle());
}

TEST_F(StyledLabelTest, StyledRangeBold) {
  const std::string bold_text(
      "This is a block of text whose style will be set to BOLD in the test");
  const std::string text(" normal text");
  InitStyledLabel(bold_text + text);

  StyledLabel::RangeStyleInfo style_info;
  style_info.font_style = gfx::Font::BOLD;
  styled()->AddStyleRange(gfx::Range(0, bold_text.size()), style_info);

  // Calculate the bold text width if it were a pure label view, both with bold
  // and normal style.
  Label label(ASCIIToUTF16(bold_text));
  const gfx::Size normal_label_size = label.GetPreferredSize();
  label.SetFontList(label.font_list().DeriveWithStyle(gfx::Font::BOLD));
  const gfx::Size bold_label_size = label.GetPreferredSize();

  ASSERT_GE(bold_label_size.width(), normal_label_size.width());

  // Set the width so |bold_text| doesn't fit on a single line with bold style,
  // but does with normal font style.
  int styled_width = (normal_label_size.width() + bold_label_size.width()) / 2;
  int pref_height = styled()->GetHeightForWidth(styled_width);

  // Sanity check that |bold_text| with normal font style would fit on a single
  // line in a styled label with width |styled_width|.
  StyledLabel unstyled(ASCIIToUTF16(bold_text), this);
  unstyled.SetBounds(0, 0, styled_width, pref_height);
  unstyled.Layout();
  EXPECT_EQ(1, unstyled.child_count());

  styled()->SetBounds(0, 0, styled_width, pref_height);
  styled()->Layout();

  ASSERT_EQ(3, styled()->child_count());

  // The bold text should be broken up into two parts.
  ASSERT_EQ(std::string(Label::kViewClassName),
            styled()->child_at(0)->GetClassName());
  EXPECT_EQ(
      gfx::Font::BOLD,
      static_cast<Label*>(styled()->child_at(0))->font_list().GetFontStyle());
  ASSERT_EQ(std::string(Label::kViewClassName),
            styled()->child_at(1)->GetClassName());
  EXPECT_EQ(
      gfx::Font::BOLD,
      static_cast<Label*>(styled()->child_at(1))->font_list().GetFontStyle());
  ASSERT_EQ(std::string(Label::kViewClassName),
            styled()->child_at(2)->GetClassName());
  EXPECT_EQ(
      gfx::Font::NORMAL,
      static_cast<Label*>(styled()->child_at(2))->font_list().GetFontStyle());

  // The second bold part should start on a new line.
  EXPECT_EQ(0, styled()->child_at(0)->x());
  EXPECT_EQ(0, styled()->child_at(1)->x());
  EXPECT_EQ(styled()->child_at(1)->bounds().right(),
            styled()->child_at(2)->x());
}

TEST_F(StyledLabelTest, Color) {
  const std::string text_red("RED");
  const std::string text_link("link");
  const std::string text("word");
  InitStyledLabel(text_red + text_link + text);

  StyledLabel::RangeStyleInfo style_info_red;
  style_info_red.color = SK_ColorRED;
  styled()->AddStyleRange(gfx::Range(0, text_red.size()), style_info_red);

  StyledLabel::RangeStyleInfo style_info_link =
      StyledLabel::RangeStyleInfo::CreateForLink();
  styled()->AddStyleRange(gfx::Range(text_red.size(),
                                    text_red.size() + text_link.size()),
                          style_info_link);

  styled()->SetBounds(0, 0, 1000, 1000);
  styled()->Layout();

  Widget* widget = new Widget();
  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
  widget->Init(params);
  View* container = new View();
  widget->SetContentsView(container);
  container->AddChildView(styled());

  // Obtain the default text color for a label.
  Label* label = new Label(ASCIIToUTF16(text));
  container->AddChildView(label);
  const SkColor kDefaultTextColor = label->enabled_color();

  // Obtain the default text color for a link;
  Link* link = new Link(ASCIIToUTF16(text_link));
  container->AddChildView(link);
  const SkColor kDefaultLinkColor = link->enabled_color();

  EXPECT_EQ(SK_ColorRED,
            static_cast<Label*>(styled()->child_at(0))->enabled_color());
  EXPECT_EQ(kDefaultLinkColor,
            static_cast<Label*>(styled()->child_at(1))->enabled_color());
  EXPECT_EQ(kDefaultTextColor,
            static_cast<Label*>(styled()->child_at(2))->enabled_color());

  // Test adjusted color readability.
  styled()->SetDisplayedOnBackgroundColor(SK_ColorBLACK);
  styled()->Layout();
  label->SetBackgroundColor(SK_ColorBLACK);

  const SkColor kAdjustedTextColor = label->enabled_color();
  EXPECT_NE(kAdjustedTextColor, kDefaultTextColor);
  EXPECT_EQ(kAdjustedTextColor,
            static_cast<Label*>(styled()->child_at(2))->enabled_color());

  widget->CloseNow();
}

TEST_F(StyledLabelTest, StyledRangeWithTooltip) {
  const std::string text("This is a test block of text, ");
  const std::string tooltip_text("this should have a tooltip,");
  const std::string normal_text(" this should not have a tooltip, ");
  const std::string link_text("and this should be a link");

  const size_t tooltip_start = text.size();
  const size_t link_start =
      text.size() + tooltip_text.size() + normal_text.size();

  InitStyledLabel(text + tooltip_text + normal_text + link_text);
  StyledLabel::RangeStyleInfo tooltip_style;
  tooltip_style.tooltip = ASCIIToUTF16("tooltip");
  styled()->AddStyleRange(
      gfx::Range(tooltip_start, tooltip_start + tooltip_text.size()),
      tooltip_style);
  styled()->AddStyleRange(gfx::Range(link_start, link_start + link_text.size()),
                          StyledLabel::RangeStyleInfo::CreateForLink());

  // Break line inside the range with the tooltip.
  Label label(ASCIIToUTF16(
       text + tooltip_text.substr(0, tooltip_text.size() - 3)));
  gfx::Size label_preferred_size = label.GetPreferredSize();
  int pref_height = styled()->GetHeightForWidth(label_preferred_size.width());
  EXPECT_EQ(label_preferred_size.height() * 3,
            pref_height - styled()->GetInsets().height());

  styled()->SetBounds(0, 0, label_preferred_size.width(), pref_height);
  styled()->Layout();

  EXPECT_EQ(label_preferred_size.width(), styled()->width());

  ASSERT_EQ(5, styled()->child_count());
  // The labels have no focus border while the link (and thus overall styled
  // label) does, so the labels should be inset by the width of the focus
  // border.
  EXPECT_EQ(Label::kFocusBorderPadding, styled()->child_at(0)->x());
  EXPECT_EQ(styled()->child_at(0)->bounds().right(),
            styled()->child_at(1)->x());
  EXPECT_EQ(Label::kFocusBorderPadding, styled()->child_at(2)->x());
  EXPECT_EQ(styled()->child_at(2)->bounds().right(),
            styled()->child_at(3)->x());
  EXPECT_EQ(0, styled()->child_at(4)->x());

  base::string16 tooltip;
  EXPECT_TRUE(
      styled()->child_at(1)->GetTooltipText(gfx::Point(1, 1), &tooltip));
  EXPECT_EQ(ASCIIToUTF16("tooltip"), tooltip);
  EXPECT_TRUE(
      styled()->child_at(2)->GetTooltipText(gfx::Point(1, 1), &tooltip));
  EXPECT_EQ(ASCIIToUTF16("tooltip"), tooltip);
}

TEST_F(StyledLabelTest, SetBaseFontList) {
  const std::string text("This is a test block of text.");
  InitStyledLabel(text);
  std::string font_name("arial");
  gfx::Font font(font_name, 30);
  styled()->SetBaseFontList(gfx::FontList(font));
  Label label(ASCIIToUTF16(text), gfx::FontList(font));

  styled()->SetBounds(0,
                      0,
                      label.GetPreferredSize().width(),
                      label.GetPreferredSize().height());

  // Make sure we have the same sizing as a label.
  EXPECT_EQ(label.GetPreferredSize().height(), styled()->height());
  EXPECT_EQ(label.GetPreferredSize().width(), styled()->width());
}

TEST_F(StyledLabelTest, LineHeight) {
  const std::string text("one");
  InitStyledLabel(text);
  int default_height = styled()->GetHeightForWidth(100);
  const std::string newline_text("one\ntwo\nthree");
  InitStyledLabel(newline_text);
  styled()->SetLineHeight(18);
  EXPECT_EQ(18 * 2 + default_height, styled()->GetHeightForWidth(100));
}

TEST_F(StyledLabelTest, HandleEmptyLayout) {
  const std::string text("This is a test block of text.");
  InitStyledLabel(text);
  styled()->Layout();
  EXPECT_EQ(0, styled()->child_count());
}

}  // namespace views
