/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkOTUtils_DEFINED
#define SkOTUtils_DEFINED

#include "SkOTTableTypes.h"
#include "SkOTTable_name.h"
#include "SkTypeface.h"

class SkData;
class SkStream;

struct SkOTUtils {
    /**
      *  Calculates the OpenType checksum for data.
      */
    static uint32_t CalcTableChecksum(SK_OT_ULONG *data, size_t length);

    /**
      *  Renames an sfnt font. On failure (invalid data or not an sfnt font)
      *  returns NULL.
      *
      *  Essentially, this removes any existing 'name' table and replaces it
      *  with a new one in which FontFamilyName, FontSubfamilyName,
      *  UniqueFontIdentifier, FullFontName, and PostscriptName are fontName.
      *
      *  The new 'name' table records will be written with the Windows,
      *  UnicodeBMPUCS2, and English_UnitedStates settings.
      *
      *  fontName and fontNameLen must be specified in terms of ASCII chars.
      */
    static SkData* RenameFont(SkStreamAsset* fontData, const char* fontName, int fontNameLen);

    /** An implementation of LocalizedStrings which obtains it's data from a 'name' table. */
    class LocalizedStrings_NameTable : public SkTypeface::LocalizedStrings {
    public:
        /** Takes ownership of the nameTableData and will free it with SK_DELETE. */
        LocalizedStrings_NameTable(SkOTTableName* nameTableData,
                                   SkOTTableName::Record::NameID::Predefined::Value types[],
                                   int typesCount)
            : fTypes(types), fTypesCount(typesCount), fTypesIndex(0)
            , fNameTableData(nameTableData), fFamilyNameIter(*nameTableData, fTypes[fTypesIndex])
        { }

        /** Creates an iterator over all the family names in the 'name' table of a typeface.
         *  If no valid 'name' table can be found, returns NULL.
         */
        static LocalizedStrings_NameTable* CreateForFamilyNames(const SkTypeface& typeface);

        virtual bool next(SkTypeface::LocalizedString* localizedString) SK_OVERRIDE;
    private:
        static SkOTTableName::Record::NameID::Predefined::Value familyNameTypes[3];

        SkOTTableName::Record::NameID::Predefined::Value* fTypes;
        int fTypesCount;
        int fTypesIndex;
        SkAutoTDeleteArray<SkOTTableName> fNameTableData;
        SkOTTableName::Iterator fFamilyNameIter;
    };

    /** An implementation of LocalizedStrings which has one name. */
    class LocalizedStrings_SingleName : public SkTypeface::LocalizedStrings {
    public:
        LocalizedStrings_SingleName(SkString name, SkString language)
            : fName(name), fLanguage(language), fHasNext(true)
        { }

        virtual bool next(SkTypeface::LocalizedString* localizedString) SK_OVERRIDE {
            localizedString->fString = fName;
            localizedString->fLanguage = fLanguage;

            bool hadNext = fHasNext;
            fHasNext = false;
            return hadNext;
        }

    private:
        SkString fName;
        SkString fLanguage;
        bool fHasNext;
    };
};

#endif
