#include "PdfXRefTable.h"

#include "StringUtils.h"

PdfXRefTable::PdfXRefTable()
{
    mSections.push_back(TableSubSection());
}

std::string PdfXRefTable::toString()
{
    std::string content;
    for (const auto& section : mSections)
    {
        content += "xref\n" + std::to_string(section.mStartIndex) + " " + std::to_string(section.mRecords.size());
        content += "\n";
        for (const auto& record : section.mRecords)
        {
            auto offsetString = StringUtils::toPaddedString(10, static_cast<unsigned>(record.mOffsetBytes));
            auto generationString = StringUtils::toPaddedString(5, static_cast<unsigned>(record.mGenerationNumber));
            auto freeString = record.mIsFree ? "f" : "n";

            content += offsetString + " " + generationString + " " + freeString + "\n";
        }
        content += "\n";
    }
    return content;
}

std::size_t PdfXRefTable::getNextOffset()
{
    auto lastNumRecords = mSections[mSections.size() - 1].mRecords.size();
    if (lastNumRecords > 0)
    {
        return mSections[mSections.size() - 1].mRecords[lastNumRecords -1].mOffsetBytes + mLastAddedBytes;
    }
    else if (mSections.size() > 1)
    {
        lastNumRecords = mSections[mSections.size() - 2].mRecords.size();
        return mSections[mSections.size() - 2].mRecords[lastNumRecords -1].mOffsetBytes + mLastAddedBytes;
    }
    else
    {
        return 0;
    }
}

void PdfXRefTable::addRecord(std::size_t numBytes, std::size_t generation, unsigned isFree)
{
    XRefRecord record;

    record.mOffsetBytes = getNextOffset();
    record.mGenerationNumber = generation;
    record.mIsFree = isFree;
    mSections[mSections.size()-1].mRecords.push_back(record);
    mLastAddedBytes = numBytes;
}

std::size_t PdfXRefTable::getNumEntries()
{
    std::size_t count = 0;
    for (const auto& section : mSections)
    {
        count += section.mRecords.size();
    }
    return count;
}

