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

#include "src/pdf/SkPDFMakeCIDGlyphWidthsArray.h"

#include "include/core/SkScalar.h"
#include "include/core/SkSpan.h"
#include "include/core/SkTypes.h"
#include "include/private/base/SkTo.h"
#include "src/core/SkGlyph.h"
#include "src/core/SkStrikeSpec.h"
#include "src/pdf/SkPDFFont.h"
#include "src/pdf/SkPDFGlyphUse.h"
#include "src/pdf/SkPDFTypes.h"

#include <algorithm>
#include <cstddef>
#include <utility>
#include <vector>

namespace {

// Scale from em-units to 1000-units.
SkScalar from_font_units(SkScalar scaled, uint16_t emSize) {
    if (emSize == 1000) {
        return scaled;
    } else {
        return scaled * 1000 / emSize;
    }
}

SkScalar find_mode_or_0(SkSpan<const SkScalar> advances) {
    if (advances.empty()) {
        return 0;
    }

    SkScalar currentAdvance = advances[0];
    SkScalar currentModeAdvance = advances[0];
    size_t currentCount = 1;
    size_t currentModeCount = 1;

    for (size_t i = 1; i < advances.size(); ++i) {
        if (advances[i] == currentAdvance) {
            ++currentCount;
        } else {
            if (currentCount > currentModeCount) {
                currentModeAdvance = currentAdvance;
                currentModeCount = currentCount;
            }
            currentAdvance = advances[i];
            currentCount = 1;
        }
    }
    return currentCount > currentModeCount ? currentAdvance : currentModeAdvance;
}

} // namespace

std::unique_ptr<SkPDFArray> SkPDFMakeCIDGlyphWidthsArray(const SkPDFStrikeSpec& pdfStrikeSpec,
                                                         const SkPDFGlyphUse& subset,
                                                         int32_t* defaultAdvance) {
    // There are two ways of expressing advances
    //
    // range: " gfid [adv.ances adv.ances ... adv.ances]"
    //   run: " gfid gfid adv.ances"
    //
    // Assuming that on average
    // the ASCII representation of an advance plus a space is 10 characters
    // the ASCII representation of a glyph id plus a space is 4 characters
    // the ASCII representation of unused gid plus a space in a range is 2 characters
    //
    // When not in a range or run
    //  a. Skipping don't cares or defaults is a win (trivial)
    //  b. Run wins for 2+ repeats " gid gid adv.ances"
    //                             " gid [adv.ances adv.ances]"
    //     rule: 2+ repeats create run as long as possible, else start range
    //
    // When in a range
    // Cost of stopping and starting a range is 8 characters  "] gid ["
    //  c. Skipping defaults is always a win                  " adv.ances"
    //     rule: end range if default seen
    //  d. Skipping 4+ don't cares is a win                   " 0 0 0 0"
    //     rule: end range if 4+ don't cares
    // Cost of stop and start range plus run is 28 characters "] gid gid adv.ances gid ["
    //  e. Switching for 2+ repeats and 4+ don't cares wins   " 0 0 adv.ances 0 0 adv.ances"
    //     rule: end range for 2+ repeats with 4+ don't cares
    //  f. Switching for 3+ repeats wins                      " adv.ances adv.ances adv.ances"
    //     rule: end range for 3+ repeats

    int emSize = pdfStrikeSpec.fUnitsPerEM;
    SkBulkGlyphMetricsAndPaths paths{pdfStrikeSpec.fStrikeSpec};

    auto result = SkPDFMakeArray();

    std::vector<SkGlyphID> glyphIDs;
    subset.getSetValues([&](unsigned index) {
        glyphIDs.push_back(SkTo<SkGlyphID>(index));
    });
    auto glyphs = paths.glyphs(SkSpan(glyphIDs));

    // C++20 = make_unique_for_overwrite<SkScalar[]>(glyphs.size());
    auto advances = std::unique_ptr<SkScalar[]>(new SkScalar[glyphs.size()]);

    // Find the pdf integer mode (most common pdf integer advance).
    // Unfortunately, poppler enforces DW (default width) must be an integer,
    // so only consider integer pdf advances when finding the mode.
    size_t numIntAdvances = 0;
    for (const SkGlyph* glyph : glyphs) {
        SkScalar currentAdvance = from_font_units(glyph->advanceX(), emSize);
        if ((int32_t)currentAdvance == currentAdvance) {
            advances[numIntAdvances++] = currentAdvance;
        }
    }
    std::sort(advances.get(), advances.get() + numIntAdvances);
    int32_t modeAdvance = (int32_t)find_mode_or_0(SkSpan(advances.get(), numIntAdvances));
    *defaultAdvance = modeAdvance;

    // Pre-convert to pdf advances.
    for (size_t i = 0; i < glyphs.size(); ++i) {
        advances[i] = from_font_units(glyphs[i]->advanceX(), emSize);
    }

    for (size_t i = 0; i < glyphs.size(); ++i) {
        SkScalar advance = advances[i];

        // a. Skipping don't cares or defaults is a win (trivial)
        if (advance == modeAdvance) {
            continue;
        }

        // b. 2+ repeats create run as long as possible, else start range
        {
            size_t j = i + 1; // j is always one past the last known repeat
            for (; j < glyphs.size(); ++j) {
                SkScalar next_advance = advances[j];
                if (advance != next_advance) {
                    break;
                }
            }
            if (j - i >= 2) {
                result->appendInt(glyphs[i]->getGlyphID());
                result->appendInt(glyphs[j - 1]->getGlyphID());
                result->appendScalar(advance);
                i = j - 1;
                continue;
            }
        }

        {
            result->appendInt(glyphs[i]->getGlyphID());
            auto advanceArray = SkPDFMakeArray();
            advanceArray->appendScalar(advance);
            size_t j = i + 1; // j is always one past the last output
            for (; j < glyphs.size(); ++j) {
                advance = advances[j];

                // c. end range if default seen
                if (advance == modeAdvance) {
                    break;
                }

                int dontCares = glyphs[j]->getGlyphID() - glyphs[j - 1]->getGlyphID() - 1;
                // d. end range if 4+ don't cares
                if (dontCares >= 4) {
                    break;
                }

                SkScalar next_advance = 0;
                // e. end range for 2+ repeats with 4+ don't cares
                if (j + 1 < glyphs.size()) {
                    next_advance = advances[j+1];
                    int next_dontCares = glyphs[j+1]->getGlyphID() - glyphs[j]->getGlyphID() - 1;
                    if (advance == next_advance && dontCares + next_dontCares >= 4) {
                        break;
                    }
                }

                // f. end range for 3+ repeats
                if (j + 2 < glyphs.size() && advance == next_advance) {
                    next_advance = advances[j+2];
                    if (advance == next_advance) {
                        break;
                    }
                }

                while (dontCares --> 0) {
                    advanceArray->appendScalar(0);
                }
                advanceArray->appendScalar(advance);
            }
            result->appendObject(std::move(advanceArray));
            i = j - 1;
        }
    }

    return result;
}
