#include "PdfDocument.h"

#include "PdfObject.h"
#include "PdfDocumentCatalog.h"
#include "PdfPageTree.h"
#include "PdfPage.h"
#include "PdfOutline.h"
#include "PdfXRefTable.h"

#include "StringUtils.h"

PdfDocument::PdfDocument()
{
    mXRefTable = std::make_unique<PdfXRefTable>();
    mCatalog = std::make_unique<PdfDocumentCatalog>();
}

PdfDocument::~PdfDocument()
{

}

std::string PdfDocument::toString()
{
    indexObjects();
    auto content = getHeaderString();
    content += getBodyString();

    content += getXRefString();

    content += getTrailerString();

    content += "%%EOF\n";
    return content;
}

std::string PdfDocument::getHeaderString()
{
    auto content = "%PDF-" + mVersion + "\n";
    mXRefOffset = content.size();
    mXRefTable->addRecord(content.size(), 65535, true);
    return content;
}

std::string PdfDocument::getBodyString()
{
    const auto content = mCatalog->toString(mXRefTable.get());
    mXRefOffset += content.size();
    return content;
}

std::string PdfDocument::getXRefString()
{
    return mXRefTable->toString();
}

std::string PdfDocument::getTrailerString()
{
    const auto numObjects = mXRefTable->getNumEntries();
    mTrailer.addStringItem("Size", std::to_string(numObjects));
    mTrailer.addStringItem("Root", mCatalog->getRefString());

    std::string content = "trailer\n";
    content += mTrailer.toString();

    content += "startxref\n";
    content += std::to_string(mXRefOffset) + "\n";
    return content;
}

void PdfDocument::indexObjects()
{
    mCatalog->indexObjects(0);
}

