/*
 * 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/SkPaint.h"
#include "include/private/base/SkTo.h"
#include "src/core/SkStrike.h"
#include "src/core/SkStrikeSpec.h"
#include "src/pdf/SkPDFGlyphUse.h"

#include <algorithm>
#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 SkTypeface& typeface,
                                                         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;
    SkStrikeSpec strikeSpec = SkStrikeSpec::MakePDFVector(typeface, &emSize);
    SkBulkGlyphMetricsAndPaths paths{strikeSpec};

    auto result = SkPDFMakeArray();

    std::vector<SkGlyphID> glyphIDs;
    subset.getSetValues([&](unsigned index) {
        glyphIDs.push_back(SkToU16(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;
}
