#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, record.mOffsetBytes);
            auto generationString = StringUtils::ToPaddedString(5, record.mGenerationNumber);
            auto freeString = record.mIsFree ? "f" : "n";

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

unsigned 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(unsigned numBytes, unsigned generation, unsigned isFree)
{
    XRefRecord record;

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

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

