// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <windows.h>

#include <string>

#include "base/util.h"
#include "renderer/renderer_command.pb.h"
#include "renderer/win32/win32_font_util.h"
#include "testing/base/public/googletest.h"
#include "testing/base/public/gunit.h"

namespace mozc {
namespace win32 {
TEST(FontUtilTest, ToLOGFONTWithTooLongFaceName) {
  LOGFONT log_font = {
    18,
    11,
    2700,
    1800,
    FW_NORMAL,
    TRUE,
    FALSE,
    TRUE,
    SYMBOL_CHARSET,
    OUT_DEFAULT_PRECIS,
    CLIP_DEFAULT_PRECIS,
    ANTIALIASED_QUALITY,
    FF_SCRIPT,
    L"" };

  // make a string which is not null-terminated.
  for (size_t i = 0; i < arraysize(log_font.lfFaceName); ++i) {
    log_font.lfFaceName[i] = L' ';
  }

  // Conversion should fail.
  mozc::commands::RendererCommand::WinLogFont win_log_font;
  EXPECT_FALSE(FontUtil::ToWinLogFont(log_font, &win_log_font));
}

TEST(FontUtilTest, ToWinLogFontWithTooLongFaceName) {
  mozc::commands::RendererCommand::WinLogFont win_log_font;
  win_log_font.set_height(18);
  win_log_font.set_width(11);
  win_log_font.set_escapement(2700);
  win_log_font.set_orientation(1800);
  win_log_font.set_weight(FW_NORMAL);
  win_log_font.set_italic(true);
  win_log_font.set_underline(false);
  win_log_font.set_strike_out(true);
  win_log_font.set_char_set(SYMBOL_CHARSET);
  win_log_font.set_out_precision(OUT_DEFAULT_PRECIS);
  win_log_font.set_clip_precision(CLIP_DEFAULT_PRECIS);
  win_log_font.set_quality(ANTIALIASED_QUALITY);
  win_log_font.set_pitch_and_family(FF_SCRIPT);

  LOGFONT log_font = { };
  wstring too_long_face_name(L' ', arraysize(log_font.lfFaceName));
  string face_name;
  mozc::Util::WideToUTF8(too_long_face_name, &face_name);
  win_log_font.set_face_name(face_name);

  // Conversion should fail.
  EXPECT_FALSE(FontUtil::ToLOGFONT(win_log_font, &log_font));
}

TEST(FontUtilTest, RoundtripToWinLogFont) {
  const LOGFONT original = {
    18,
    11,
    2700,
    1800,
    FW_NORMAL,
    TRUE,
    FALSE,
    TRUE,
    SYMBOL_CHARSET,
    OUT_DEFAULT_PRECIS,
    CLIP_DEFAULT_PRECIS,
    ANTIALIASED_QUALITY,
    FF_SCRIPT,
    L"MS Sans Serif" };

  mozc::commands::RendererCommand::WinLogFont win_log_font;
  EXPECT_TRUE(FontUtil::ToWinLogFont(original, &win_log_font));

  LOGFONT result = { };
  EXPECT_TRUE(FontUtil::ToLOGFONT(win_log_font, &result));

  EXPECT_EQ(original.lfHeight, result.lfHeight);
  EXPECT_EQ(original.lfWidth, result.lfWidth);
  EXPECT_EQ(original.lfEscapement, result.lfEscapement);
  EXPECT_EQ(original.lfOrientation, result.lfOrientation);
  EXPECT_EQ(original.lfWeight, result.lfWeight);
  EXPECT_EQ(original.lfItalic, result.lfItalic);
  EXPECT_EQ(original.lfUnderline, result.lfUnderline);
  EXPECT_EQ(original.lfStrikeOut, result.lfStrikeOut);
  EXPECT_EQ(original.lfCharSet, result.lfCharSet);
  EXPECT_EQ(original.lfOutPrecision, result.lfOutPrecision);
  EXPECT_EQ(original.lfClipPrecision, result.lfClipPrecision);
  EXPECT_EQ(original.lfQuality, result.lfQuality);
  EXPECT_EQ(original.lfPitchAndFamily, result.lfPitchAndFamily);
  EXPECT_STREQ(original.lfFaceName, result.lfFaceName);
}

TEST(FontUtilTest, RoundtripToLOGFONT) {
  mozc::commands::RendererCommand::WinLogFont original;
  original.set_height(18);
  original.set_width(11);
  original.set_escapement(2700);
  original.set_orientation(1800);
  original.set_weight(FW_NORMAL);
  original.set_italic(true);
  original.set_underline(false);
  original.set_strike_out(true);
  original.set_char_set(SYMBOL_CHARSET);
  original.set_out_precision(OUT_DEFAULT_PRECIS);
  original.set_clip_precision(CLIP_DEFAULT_PRECIS);
  original.set_quality(ANTIALIASED_QUALITY);
  original.set_pitch_and_family(FF_SCRIPT);
  string face_name;
  mozc::Util::WideToUTF8(L"MS Sans Serif", &face_name);
  original.set_face_name(face_name);

  LOGFONT log_font = { };
  EXPECT_TRUE(FontUtil::ToLOGFONT(original, &log_font));

  mozc::commands::RendererCommand::WinLogFont result;
  EXPECT_TRUE(FontUtil::ToWinLogFont(log_font, &result));

  EXPECT_EQ(original.height(), result.height());
  EXPECT_EQ(original.width(), result.width());
  EXPECT_EQ(original.escapement(), result.escapement());
  EXPECT_EQ(original.orientation(), result.orientation());
  EXPECT_EQ(original.weight(), result.weight());
  EXPECT_EQ(original.italic(), result.italic());
  EXPECT_EQ(original.underline(), result.underline());
  EXPECT_EQ(original.strike_out(), result.strike_out());
  EXPECT_EQ(original.char_set(), result.char_set());
  EXPECT_EQ(original.out_precision(), result.out_precision());
  EXPECT_EQ(original.clip_precision(), result.clip_precision());
  EXPECT_EQ(original.quality(), result.quality());
  EXPECT_EQ(original.pitch_and_family(), result.pitch_and_family());
  EXPECT_EQ(original.face_name(), result.face_name());
}
}  // namespace win32
}  // namespace mozc
