/*
 * 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 <functional>
#include <algorithm>
#include <map>
#include <typeinfo>

#include "sfntly/font.h"
#include "sfntly/font_factory.h"
#include "sfntly/tag.h"
#include "sfntly/math/fixed1616.h"
#include "sfntly/math/font_math.h"
#include "sfntly/data/font_input_stream.h"
#include "sfntly/font_header_table.h"
#include "sfntly/horizontal_header_table.h"
#include "sfntly/horizontal_metrics_table.h"
#include "sfntly/maximum_profile_table.h"
#include "sfntly/loca_table.h"
#include "sfntly/port/exception_type.h"

namespace sfntly {

const int32_t SFNTVERSION_1 = Fixed1616::fixed(1, 0);

/******************************************************************************
 * Font class
 ******************************************************************************/
Font::~Font() {}

Font::Font(FontFactory* factory, int32_t sfnt_version, ByteVector* digest,
           TableMap* tables)
    : factory_(factory), sfnt_version_(sfnt_version) {
  // non-trivial assignments that makes debugging hard if placed in
  // initialization list
  digest_ = *digest;
  tables_ = *tables;
}

int32_t Font::version() {
  return sfnt_version_;
}

ByteVector* Font::digest() {
  return &digest_;
}

int64_t Font::checksum() {
  return checksum_;
}

int32_t Font::numTables() {
  return (int32_t)tables_.size();
}

bool Font::hasTable(int32_t tag) {
  TableMap::const_iterator result = tables_.find(tag);
  TableMap::const_iterator end = tables_.end();
  return (result != end);
}

Table* Font::table(int32_t tag) {
  if (!hasTable(tag)) {
    return NULL;
  }
  return tables_[tag];
}

TableMap* Font::tables() {
  return &tables_;
}

void Font::serialize(OutputStream* os, IntegerList* table_ordering) {
  assert(table_ordering);
  IntegerList final_table_ordering;
  tableOrdering(table_ordering, &final_table_ordering);
  TableHeaderList table_records;
  buildTableHeadersForSerialization(&final_table_ordering, &table_records);

  FontOutputStream fos(os);
  serializeHeader(&fos, &table_records);
  serializeTables(&fos, &table_records);
}

void Font::buildTableHeadersForSerialization(IntegerList* table_ordering,
                                             TableHeaderList* table_headers) {
  assert(table_headers);
  assert(table_ordering);

  IntegerList final_table_ordering;
  tableOrdering(table_ordering, &final_table_ordering);
  int32_t table_offset = Offset::kTableRecordBegin + numTables() *
                         Offset::kTableRecordSize;
  for (IntegerList::iterator tag = final_table_ordering.begin(),
                             tag_end = final_table_ordering.end();
                             tag != tag_end; ++tag) {
    TablePtr table = tables_[*tag];
    if (table != NULL) {
      TableHeaderPtr header =
          new Table::Header(*tag, table->calculatedChecksum(), table_offset,
                            table->length());
      table_headers->push_back(header);
      table_offset += (table->length() + 3) & ~3;
    }
  }
}

void Font::serializeHeader(FontOutputStream* fos,
                           TableHeaderList* table_headers) {
  fos->writeFixed(sfnt_version_);
  fos->writeUShort(table_headers->size());
  int32_t log2_of_max_power_of_2 = FontMath::log2(table_headers->size());
  int32_t search_range = 2 << (log2_of_max_power_of_2 - 1 + 4);
  fos->writeUShort(search_range);
  fos->writeUShort(log2_of_max_power_of_2);
  fos->writeUShort((table_headers->size() * 16) - search_range);

  for (TableHeaderList::iterator record = table_headers->begin(),
                                 record_end = table_headers->end();
                                 record != record_end; ++record) {
    fos->writeULong((*record)->tag());
    fos->writeULong((int32_t)((*record)->checksum()));
    fos->writeULong((*record)->offset());
    fos->writeULong((*record)->length());
  }
}

void Font::serializeTables(FontOutputStream* fos,
                           TableHeaderList* table_headers) {
  ByteVector SERIALIZATION_FILLER(3);
  std::fill(SERIALIZATION_FILLER.begin(), SERIALIZATION_FILLER.end(), 0);
  for (TableHeaderList::iterator record = table_headers->begin(),
                                 end_of_headers = table_headers->end();
                                 record != end_of_headers; ++record) {
    TablePtr target_table = table((*record)->tag());
    if (target_table == NULL) {
#if defined (SFNTLY_NO_EXCEPTION)
      return;
#else
      throw IOException("Table out of sync with font header.");
#endif
    }
    int32_t table_size = target_table->serialize(fos);
    if (table_size != (*record)->length()) {
      assert(false);
    }
    int32_t filler_size = ((table_size + 3) & ~3) - table_size;
    fos->write(&SERIALIZATION_FILLER, 0, filler_size);
  }
}

void Font::tableOrdering(IntegerList* default_table_ordering,
                         IntegerList* table_ordering) {
  assert(default_table_ordering);
  assert(table_ordering);
  table_ordering->clear();
  if (default_table_ordering->empty()) {
    defaultTableOrdering(default_table_ordering);
  }

  typedef std::map<int32_t, bool> Int2Bool;
  typedef std::pair<int32_t, bool> Int2BoolEntry;
  Int2Bool tables_in_font;
  for (TableMap::iterator table = tables_.begin(), table_end = tables_.end();
                          table != table_end; ++table) {
    tables_in_font.insert(Int2BoolEntry(table->first, false));
  }
  for (IntegerList::iterator tag = default_table_ordering->begin(),
                             tag_end = default_table_ordering->end();
                             tag != tag_end; ++tag) {
    if (hasTable(*tag)) {
      table_ordering->push_back(*tag);
      tables_in_font[*tag] = true;
    }
  }
  for (Int2Bool::iterator table = tables_in_font.begin(),
                          table_end = tables_in_font.end();
                          table != table_end; ++table) {
    if (table->second == false)
      table_ordering->push_back(table->first);
  }
}

void Font::defaultTableOrdering(IntegerList* default_table_ordering) {
  assert(default_table_ordering);
  default_table_ordering->clear();
  if (hasTable(Tag::CFF)) {
    default_table_ordering->resize(CFF_TABLE_ORDERING_SIZE);
    std::copy(CFF_TABLE_ORDERING, CFF_TABLE_ORDERING + CFF_TABLE_ORDERING_SIZE,
              default_table_ordering->begin());
    return;
  }
  default_table_ordering->resize(TRUE_TYPE_TABLE_ORDERING_SIZE);
  std::copy(TRUE_TYPE_TABLE_ORDERING,
            TRUE_TYPE_TABLE_ORDERING + TRUE_TYPE_TABLE_ORDERING_SIZE,
            default_table_ordering->begin());
}

CALLER_ATTACH WritableFontData* Font::getNewData(int32_t size) {
  return factory_->getNewData(size);
}

/******************************************************************************
 * Font::Builder class
 ******************************************************************************/
Font::Builder::~Builder() {}

Font::Builder::Builder(FontFactory* factory)
    : factory_(factory), sfnt_version_(SFNTVERSION_1) {
}

void Font::Builder::loadFont(InputStream* is) {
  // Note: we do not throw exception here for is.  This is more of an assertion.
  assert(is);
  FontInputStream font_is(is);
  TableHeaderSortedSet records;
  readHeader(&font_is, &records);
  loadTableData(&records, &font_is, &data_blocks_);
  buildAllTableBuilders(&data_blocks_, &table_builders_);
  font_is.close();
}

void Font::Builder::loadFont(ByteArray* ba,
                             int32_t offset_to_offset_table) {
  // Note: we do not throw exception here for is.  This is more of an assertion.
  assert(ba);
  WritableFontDataPtr fd = new WritableFontData(ba);
  TableHeaderSortedSet records;
  readHeader(fd, offset_to_offset_table, &records);
  loadTableData(&records, fd, &data_blocks_);
  buildAllTableBuilders(&data_blocks_, &table_builders_);
}

CALLER_ATTACH Font::Builder* Font::Builder::getOTFBuilder(
    FontFactory* factory, InputStream* is) {
  FontBuilderPtr builder = new Builder(factory);
  builder->loadFont(is);
  return builder.detach();
}

CALLER_ATTACH Font::Builder* Font::Builder::getOTFBuilder(
    FontFactory* factory, ByteArray* ba, int32_t offset_to_offset_table) {
  FontBuilderPtr builder = new Builder(factory);
  builder->loadFont(ba, offset_to_offset_table);
  return builder.detach();
}

CALLER_ATTACH Font::Builder* Font::Builder::getOTFBuilder(
    FontFactory* factory) {
  FontBuilderPtr builder = new Builder(factory);
  return builder.detach();
}

bool Font::Builder::readyToBuild() {
  // just read in data with no manipulation
  if (table_builders_.empty() && !data_blocks_.empty()) {
    return true;
  }

  // TODO(stuartg): font level checks - required tables etc.
  for (TableBuilderMap::iterator table_builder = table_builders_.begin(),
                                 table_builder_end = table_builders_.end();
                                 table_builder != table_builder_end;
                                 ++table_builder) {
    if (!table_builder->second->readyToBuild())
      return false;
  }
  return true;
}

CALLER_ATTACH Font* Font::Builder::build() {
  TableMap tables;
  if (!table_builders_.empty()) {
    buildTablesFromBuilders(&table_builders_, &tables);
  }
  FontPtr font = new Font(factory_, sfnt_version_, &digest_, &tables);
  table_builders_.clear();
  data_blocks_.clear();
  return font.detach();
}

CALLER_ATTACH WritableFontData* Font::Builder::getNewData(int32_t capacity) {
  return factory_->getNewData(capacity);
}

CALLER_ATTACH WritableFontData* Font::Builder::getNewGrowableData(
    ReadableFontData* src_data) {
  return factory_->getNewGrowableData(src_data);
}

void Font::Builder::setDigest(ByteVector* digest) {
  digest_.clear();
  digest_ = *digest;
}

void Font::Builder::cleanTableBuilders() {
  table_builders_.clear();
}

bool Font::Builder::hasTableBuilder(int32_t tag) {
  return (table_builders_.find(tag) != table_builders_.end());
}

Table::Builder* Font::Builder::getTableBuilder(int32_t tag) {
  if (hasTableBuilder(tag))
    return table_builders_[tag];
  return NULL;
}

CALLER_ATTACH Table::Builder* Font::Builder::newTableBuilder(int32_t tag) {
  TableHeaderPtr header = new Table::Header(tag);
  TableBuilderPtr builder = Table::Builder::getBuilder(this, header, NULL);
  table_builders_.insert(TableBuilderEntry(header->tag(), builder));
  return builder;
}

CALLER_ATTACH Table::Builder* Font::Builder::newTableBuilder(
    int32_t tag, ReadableFontData* src_data) {
  WritableFontDataPtr data;
  data.attach(getNewGrowableData(src_data));
  TableHeaderPtr header = new Table::Header(tag);
  TableBuilderPtr builder = Table::Builder::getBuilder(this, header, data);
  table_builders_.insert(TableBuilderEntry(tag, builder));
  return builder;
}

TableBuilderMap* Font::Builder::tableBuilders() {
  return &table_builders_;
}

void Font::Builder::tableBuilderTags(IntegerSet* key_set) {
  assert(key_set);
  key_set->clear();
  for (TableBuilderMap::iterator i = table_builders_.begin(),
                                 e = table_builders_.end(); i != e; ++i) {
    key_set->insert(i->first);
  }
}

void Font::Builder::removeTableBuilder(int32_t tag) {
  TableBuilderMap::iterator target = table_builders_.find(tag);
  if (target != table_builders_.end()) {
    table_builders_.erase(target);
  }
}

int32_t Font::Builder::numberOfTableBuilders() {
  return (int32_t)table_builders_.size();
}

int32_t Font::Builder::sfntWrapperSize() {
  return Offset::kSfntHeaderSize +
         (Offset::kTableRecordSize * table_builders_.size());
}

void Font::Builder::buildAllTableBuilders(DataBlockMap* table_data,
                                          TableBuilderMap* builder_map) {
  for (DataBlockMap::iterator record = table_data->begin(),
                              record_end = table_data->end();
                              record != record_end; ++record) {
    TableBuilderPtr builder;
    builder.attach(getTableBuilder(record->first.p_, record->second.p_));
    builder_map->insert(TableBuilderEntry(record->first->tag(), builder));
  }
  interRelateBuilders(&table_builders_);
}

CALLER_ATTACH Table::Builder* Font::Builder::getTableBuilder(
    Table::Header* header, WritableFontData* data) {
  return Table::Builder::getBuilder(this, header, data);
}

void Font::Builder::buildTablesFromBuilders(TableBuilderMap* builder_map,
                                            TableMap* table_map) {
  interRelateBuilders(builder_map);

  // Now build all the tables.
  for (TableBuilderMap::iterator builder = builder_map->begin(),
                                 builder_end = builder_map->end();
                                 builder != builder_end; ++builder) {
    TablePtr table;
    if (builder->second->readyToBuild()) {
#if !defined (SFNTLY_NO_EXCEPTION)
      try {
#endif
        table.attach(down_cast<Table*>(builder->second->build()));
#if !defined (SFNTLY_NO_EXCEPTION)
      } catch(IOException& e) {
        std::string builder_string = "Unable to build table - ";
        builder_string += typeid(builder->second).name();
        builder_string += e.what();
        throw RuntimeException(builder_string.c_str());
      }
#endif
    }
    if (table == NULL) {
#if defined (SFNTLY_NO_EXCEPTION)
      return;
#else
      std::string builder_string = "Unable to build table - ";
      builder_string += typeid(builder->second).name();
      throw RuntimeException(builder_string.c_str());
#endif
    }
    table_map->insert(TableMapEntry(table->header()->tag(), table));
  }
}

void Font::Builder::interRelateBuilders(TableBuilderMap* builder_map) {
  FontHeaderTableBuilderPtr header_table_builder =
      down_cast<FontHeaderTable::Builder*>((*builder_map)[Tag::head].p_);
  HorizontalHeaderTableBuilderPtr horizontal_header_builder =
      down_cast<HorizontalHeaderTable::Builder*>((*builder_map)[Tag::hhea].p_);
  MaximumProfileTableBuilderPtr max_profile_builder =
      down_cast<MaximumProfileTable::Builder*>((*builder_map)[Tag::maxp].p_);
  LocaTableBuilderPtr loca_table_builder =
      down_cast<LocaTable::Builder*>((*builder_map)[Tag::loca].p_);
  HorizontalMetricsTableBuilderPtr horizontal_metrics_builder =
      down_cast<HorizontalMetricsTable::Builder*>(
          (*builder_map)[Tag::hmtx].p_);

  // set the inter table data required to build certain tables
  if (horizontal_metrics_builder != NULL) {
    if (max_profile_builder != NULL) {
      horizontal_metrics_builder->setNumGlyphs(
          max_profile_builder->numGlyphs());
    }
    if (horizontal_header_builder != NULL) {
      horizontal_metrics_builder->setNumberOfHMetrics(
          horizontal_header_builder->numberOfHMetrics());
    }
  }

  if (loca_table_builder != NULL) {
    if (max_profile_builder != NULL) {
      loca_table_builder->setNumGlyphs(max_profile_builder->numGlyphs());
    }
    if (header_table_builder != NULL) {
      loca_table_builder->setFormatVersion(
          header_table_builder->indexToLocFormat());
    }
  }
}

void Font::Builder::readHeader(FontInputStream* is,
                               TableHeaderSortedSet* records) {
  assert(records);
  sfnt_version_ = is->readFixed();
  num_tables_ = is->readUShort();
  search_range_ = is->readUShort();
  entry_selector_ = is->readUShort();
  range_shift_ = is->readUShort();

  for (int32_t table_number = 0; table_number < num_tables_; ++table_number) {
    // Need to use temporary vars here.  C++ evaluates function parameters from
    // right to left and thus breaks the order of input stream.
    int32_t tag = is->readULongAsInt();
    int64_t checksum = is->readULong();
    int32_t offset = is->readULongAsInt();
    int32_t length = is->readULongAsInt();
    TableHeaderPtr table = new Table::Header(tag, checksum, offset, length);
    records->insert(table);
  }
}

void Font::Builder::loadTableData(TableHeaderSortedSet* headers,
                                  FontInputStream* is,
                                  DataBlockMap* table_data) {
  assert(table_data);
  for (TableHeaderSortedSet::iterator
           table_header = headers->begin(), table_end = headers->end();
           table_header != table_end; ++table_header) {
    is->skip((*table_header)->offset() - is->position());
    FontInputStream table_is(is, (*table_header)->length());
    int32_t roundup_length = ((*table_header)->length() + 3) & ~3;
    ByteArrayPtr array = factory_->getNewArray(roundup_length);
    array->copyFrom(&table_is, (*table_header)->length());
    WritableFontDataPtr data = new WritableFontData(array);
    table_data->insert(DataBlockEntry(*table_header, data));
  }
}

void Font::Builder::readHeader(ReadableFontData* fd, int32_t offset,
                               TableHeaderSortedSet* records) {
  assert(records);
  sfnt_version_ = fd->readFixed(offset + Offset::kSfntVersion);
  num_tables_ = fd->readUShort(offset + Offset::kNumTables);
  search_range_ = fd->readUShort(offset + Offset::kSearchRange);
  entry_selector_ = fd->readUShort(offset + Offset::kEntrySelector);
  range_shift_ = fd->readUShort(offset + Offset::kRangeShift);

  int32_t table_offset = offset + Offset::kTableRecordBegin;
  for (int32_t table_number = 0;
       table_number < num_tables_;
       table_number++, table_offset += Offset::kTableRecordSize) {
    int32_t tag = fd->readULongAsInt(table_offset + Offset::kTableTag);
    int64_t checksum = fd->readULong(table_offset + Offset::kTableCheckSum);
    int32_t offset = fd->readULongAsInt(table_offset + Offset::kTableOffset);
    int32_t length = fd->readULongAsInt(table_offset + Offset::kTableLength);
    TableHeaderPtr table = new Table::Header(tag, checksum, offset, length);
    records->insert(table);
  }
}

void Font::Builder::loadTableData(TableHeaderSortedSet* headers,
                                  WritableFontData* fd,
                                  DataBlockMap* table_data) {
  for (TableHeaderSortedSet::iterator
           table_header = headers->begin(), table_end = headers->end();
           table_header != table_end; ++table_header) {
    int32_t roundup_length = ((*table_header)->length() + 3) & ~3;
    FontDataPtr sliced_data;
    sliced_data.attach(fd->slice((*table_header)->offset(), roundup_length));
    WritableFontDataPtr data = down_cast<WritableFontData*>(sliced_data.p_);
    table_data->insert(DataBlockEntry(*table_header, data));
  }
}

}  // namespace sfntly
