/*
 * Copyright 2011 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <assert.h>
#include <stdio.h>
#include <unicode/ucnv.h>

#include <iostream>
#include <string>

#include "gtest/gtest.h"
#include "sfntly/data/memory_byte_array.h"
#include "sfntly/font.h"
#include "sfntly/font_factory.h"
#include "sfntly/table/core/cmap_table.h"
#include "sfntly/table/core/font_header_table.h"
#include "sfntly/tag.h"
#include "test/autogenerated/cmap_test_data.h"
#include "test/test_font_utils.h"
#include "test/test_utils.h"

namespace sfntly {

#if GTEST_HAS_PARAM_TEST

using ::testing::TestWithParam;
using ::testing::Values;

class CMapBasicTests : public :: testing::TestWithParam<TestCMap> {
 public:
  CMapBasicTests() {}
  virtual void SetUp();
  virtual void TearDown() {}

  void BasicTest(int32_t index);

  Ptr<CMapTable> cmap_table_;
};

void CMapBasicTests::SetUp() {
  Ptr<FontFactory> font_factory;
  font_factory.Attach(FontFactory::GetInstance());
  FontArray font_array;
  std::string font_name("../../");
#if defined (WIN32)
  font_name += "../";
#endif
  font_name += std::string(GetParam().name);
  LoadFont(font_name.c_str(), font_factory, &font_array);
  ASSERT_FALSE(font_array.empty());
  Ptr<Font> font = font_array.at(0);
  ASSERT_NE(font, reinterpret_cast<Font*>(NULL));
  cmap_table_ = down_cast<CMapTable*>(font->GetTable(Tag::cmap));
  if (!cmap_table_)
    fprintf(stderr, "No CMap: %s\n", font_name.c_str());
  ASSERT_NE(cmap_table_, reinterpret_cast<CMapTable*>(NULL));
}

void CMapBasicTests::BasicTest(int32_t index) {
  const ProtoCMap* test = &GetParam().cmaps[index];
  Ptr<CMapTable::CMap> cmap;
  cmap.Attach(cmap_table_->GetCMap(test->platform_id, test->encoding_id));
  if (!cmap) {
    fprintf(stderr, "Cannot test unsupported CMapFormat%d\n", test->format);
    return;
  }
  ASSERT_EQ(cmap->platform_id(), test->platform_id);
  ASSERT_EQ(cmap->encoding_id(), test->encoding_id);
  ASSERT_EQ(cmap->format(), test->format);
  // There is no length() method for a CMap!
  // ASSERT_EQ(cmap->length(), test->length);
  for (int32_t i = 0; i < test->num_mappings; ++i)
    ASSERT_EQ(cmap->GlyphId(test->chars[i]), test->glyph_ids[i]);
}

TEST_P(CMapBasicTests, BasicTest) {
  for (int32_t i = 0; i < GetParam().num_cmaps; ++i)
    BasicTest(i);
}


INSTANTIATE_TEST_CASE_P(CMapBasicTests,
                        CMapBasicTests,
                        ::testing::ValuesIn(kAllTestCMaps));

#else

TEST(DummyTest, ValueParameterizedTestsAreNotSupportedOnThisPlatform) {}

#endif  // GTEST_HAS_PARAM
}
