
/*
 * Copyright 2010 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#include "SkPDFCatalog.h"
#include "SkPDFTypes.h"
#include "SkStream.h"
#include "SkTypes.h"

SkPDFCatalog::SkPDFCatalog(SkPDFDocument::Flags flags)
    : fFirstPageCount(0),
      fNextObjNum(1),
      fNextFirstPageObjNum(0),
      fDocumentFlags(flags) {
}

SkPDFCatalog::~SkPDFCatalog() {
    fSubstituteResourcesRemaining.safeUnrefAll();
    fSubstituteResourcesFirstPage.safeUnrefAll();
}

SkPDFObject* SkPDFCatalog::addObject(SkPDFObject* obj, bool onFirstPage) {
    if (findObjectIndex(obj) != -1) {  // object already added
        return obj;
    }
    SkASSERT(fNextFirstPageObjNum == 0);
    if (onFirstPage) {
        fFirstPageCount++;
    }

    struct Rec newEntry(obj, onFirstPage);
    fCatalog.append(1, &newEntry);
    return obj;
}

size_t SkPDFCatalog::setFileOffset(SkPDFObject* obj, off_t offset) {
    int objIndex = assignObjNum(obj) - 1;
    SkASSERT(fCatalog[objIndex].fObjNumAssigned);
    SkASSERT(fCatalog[objIndex].fFileOffset == 0);
    fCatalog[objIndex].fFileOffset = offset;

    return getSubstituteObject(obj)->getOutputSize(this, true);
}

void SkPDFCatalog::emitObjectNumber(SkWStream* stream, SkPDFObject* obj) {
    stream->writeDecAsText(assignObjNum(obj));
    stream->writeText(" 0");  // Generation number is always 0.
}

size_t SkPDFCatalog::getObjectNumberSize(SkPDFObject* obj) {
    SkDynamicMemoryWStream buffer;
    emitObjectNumber(&buffer, obj);
    return buffer.getOffset();
}

int SkPDFCatalog::findObjectIndex(SkPDFObject* obj) const {
    for (int i = 0; i < fCatalog.count(); i++) {
        if (fCatalog[i].fObject == obj) {
            return i;
        }
    }
    // If it's not in the main array, check if it's a substitute object.
    for (int i = 0; i < fSubstituteMap.count(); ++i) {
        if (fSubstituteMap[i].fSubstitute == obj) {
            return findObjectIndex(fSubstituteMap[i].fOriginal);
        }
    }
    return -1;
}

int SkPDFCatalog::assignObjNum(SkPDFObject* obj) {
    int pos = findObjectIndex(obj);
    // If this assert fails, it means you probably forgot to add an object
    // to the resource list.
    SkASSERT(pos >= 0);
    uint32_t currentIndex = pos;
    if (fCatalog[currentIndex].fObjNumAssigned) {
        return currentIndex + 1;
    }

    // First assignment.
    if (fNextFirstPageObjNum == 0) {
        fNextFirstPageObjNum = fCatalog.count() - fFirstPageCount + 1;
    }

    uint32_t objNum;
    if (fCatalog[currentIndex].fOnFirstPage) {
        objNum = fNextFirstPageObjNum;
        fNextFirstPageObjNum++;
    } else {
        objNum = fNextObjNum;
        fNextObjNum++;
    }

    // When we assign an object an object number, we put it in that array
    // offset (minus 1 because object number 0 is reserved).
    SkASSERT(!fCatalog[objNum - 1].fObjNumAssigned);
    if (objNum - 1 != currentIndex) {
        SkTSwap(fCatalog[objNum - 1], fCatalog[currentIndex]);
    }
    fCatalog[objNum - 1].fObjNumAssigned = true;
    return objNum;
}

int32_t SkPDFCatalog::emitXrefTable(SkWStream* stream, bool firstPage) {
    int first = -1;
    int last = fCatalog.count() - 1;
    // TODO(vandebo): Support linearized format.
    // int last = fCatalog.count() - fFirstPageCount - 1;
    // if (firstPage) {
    //     first = fCatalog.count() - fFirstPageCount;
    //     last = fCatalog.count() - 1;
    // }

    stream->writeText("xref\n");
    stream->writeDecAsText(first + 1);
    stream->writeText(" ");
    stream->writeDecAsText(last - first + 1);
    stream->writeText("\n");

    if (first == -1) {
        stream->writeText("0000000000 65535 f \n");
        first++;
    }
    for (int i = first; i <= last; i++) {
        // For 32 bits platforms, the maximum offset has to fit within off_t
        // which is a 32 bits signed integer on these platforms.
        SkDEBUGCODE(static const off_t kMaxOff = SK_MaxS32;)
        SkASSERT(fCatalog[i].fFileOffset > 0);
        SkASSERT(fCatalog[i].fFileOffset < kMaxOff);
        stream->writeBigDecAsText(fCatalog[i].fFileOffset, 10);
        stream->writeText(" 00000 n \n");
    }

    return fCatalog.count() + 1;
}

void SkPDFCatalog::setSubstitute(SkPDFObject* original,
                                 SkPDFObject* substitute) {
#if defined(SK_DEBUG)
    // Sanity check: is the original already in substitute list?
    for (int i = 0; i < fSubstituteMap.count(); ++i) {
        if (original == fSubstituteMap[i].fSubstitute ||
            original == fSubstituteMap[i].fOriginal) {
            SkASSERT(false);
            return;
        }
    }
#endif
    // Check if the original is on first page.
    bool onFirstPage = false;
    for (int i = 0; i < fCatalog.count(); ++i) {
        if (fCatalog[i].fObject == original) {
            onFirstPage = fCatalog[i].fOnFirstPage;
            break;
        }
#if defined(SK_DEBUG)
        if (i == fCatalog.count() - 1) {
            SkASSERT(false);  // original not in catalog
            return;
        }
#endif
    }

    SubstituteMapping newMapping(original, substitute);
    fSubstituteMap.append(1, &newMapping);

    // Add resource objects of substitute object to catalog.
    SkTSet<SkPDFObject*>* targetSet = getSubstituteList(onFirstPage);
    SkTSet<SkPDFObject*> newResourceObjects;
    newMapping.fSubstitute->getResources(*targetSet, &newResourceObjects);
    for (int i = 0; i < newResourceObjects.count(); ++i) {
        addObject(newResourceObjects[i], onFirstPage);
    }
    // mergeInto returns the number of duplicates.
    // If there are duplicates, there is a bug and we mess ref counting.
    SkDEBUGCODE(int duplicates =) targetSet->mergeInto(newResourceObjects);
    SkASSERT(duplicates == 0);
}

SkPDFObject* SkPDFCatalog::getSubstituteObject(SkPDFObject* object) {
    for (int i = 0; i < fSubstituteMap.count(); ++i) {
        if (object == fSubstituteMap[i].fOriginal) {
            return fSubstituteMap[i].fSubstitute;
        }
    }
    return object;
}

off_t SkPDFCatalog::setSubstituteResourcesOffsets(off_t fileOffset,
                                                  bool firstPage) {
    SkTSet<SkPDFObject*>* targetSet = getSubstituteList(firstPage);
    off_t offsetSum = fileOffset;
    for (int i = 0; i < targetSet->count(); ++i) {
        offsetSum += setFileOffset((*targetSet)[i], offsetSum);
    }
    return offsetSum - fileOffset;
}

void SkPDFCatalog::emitSubstituteResources(SkWStream *stream, bool firstPage) {
    SkTSet<SkPDFObject*>* targetSet = getSubstituteList(firstPage);
    for (int i = 0; i < targetSet->count(); ++i) {
        (*targetSet)[i]->emit(stream, this, true);
    }
}

SkTSet<SkPDFObject*>* SkPDFCatalog::getSubstituteList(bool firstPage) {
    return firstPage ? &fSubstituteResourcesFirstPage :
                       &fSubstituteResourcesRemaining;
}
