/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkPdfNativeObject.h"

#include "SkBitmap.h"
#include "SkFlate.h"
#include "SkPdfFont.h"
#include "SkPdfNativeTokenizer.h"
#include "SkPdfReporter.h"
#include "SkStream.h"

// TODO(edisonn): mac builder does not find the header ... but from headers is ok
//#include "SkPdfStreamCommonDictionary_autogen.h"
#include "SkPdfHeaders_autogen.h"


SkPdfNativeObject SkPdfNativeObject::kNull = SkPdfNativeObject::makeNull();

bool SkPdfNativeObject::applyFlateDecodeFilter() {
    if (!SkFlate::HaveFlate()) {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kNoFlateLibrary_SkPdfIssue,
                    "forgot to link with flate library?", NULL, NULL);
        return false;
    }

    const unsigned char* old = fStr.fBuffer;
    bool deleteOld = isStreamOwned();

    SkMemoryStream skstream(fStr.fBuffer, fStr.fBytes >> 2, false);
    SkDynamicMemoryWStream uncompressedData;

    if (SkFlate::Inflate(&skstream, &uncompressedData)) {
        fStr.fBytes = (uncompressedData.bytesWritten() << 2) + kOwnedStreamBit +
                      kUnfilteredStreamBit;
        fStr.fBuffer = (const unsigned char*)new unsigned char[uncompressedData.bytesWritten()];
        uncompressedData.copyTo((void*)fStr.fBuffer);

        if (deleteOld) {
            delete[] old;
        }

        return true;
    } else {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kBadStream_SkPdfIssue, "inflate failed", this, NULL);
        return false;
    }
}

bool SkPdfNativeObject::applyDCTDecodeFilter() {
    // applyDCTDecodeFilter will fail, and it won't allow any more filters.
    // technically, it would be possible, but not a real world scenario.
    // in this way we create the image from the DCT stream directly.
    return false;
}

bool SkPdfNativeObject::applyFilter(const char* name) {
    if (strcmp(name, "FlateDecode") == 0) {
        return applyFlateDecodeFilter();
    } else if (strcmp(name, "DCTDecode") == 0) {
        return applyDCTDecodeFilter();
    }
    SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "filter not supported", this,
                NULL);
    return false;
}

bool SkPdfNativeObject::filterStream() {
    SkPdfMarkObjectUsed();

    if (!hasStream()) {
        SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kBadStream_SkPdfIssue, "No Stream", this,
                    NULL);
        return false;
    }

    if (isStreamFiltered()) {
        return true;
    }

    SkPdfStreamCommonDictionary* stream = (SkPdfStreamCommonDictionary*)this;

    if (!stream->has_Filter()) {
        fStr.fBytes = ((fStr.fBytes >> 1) << 1) + kFilteredStreamBit;
    } else if (stream->isFilterAName(NULL)) {
        SkString filterName = stream->getFilterAsName(NULL);
        applyFilter(filterName.c_str());
    } else if (stream->isFilterAArray(NULL)) {
        const SkPdfArray* filters = stream->getFilterAsArray(NULL);
        int cnt = (int) filters->size();
        for (int i = cnt - 1; i >= 0; i--) {
            const SkPdfNativeObject* filterName = filters->objAtAIndex(i);
            if (filterName != NULL && filterName->isName()) {
                if (!applyFilter(filterName->nameValue())) {
                    break;
                }
            } else {
                SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncositentSyntax_SkPdfIssue,
                            "filter name should be a Name", this, NULL);
            }
        }
    }

    return true;
}

void SkPdfNativeObject::releaseData() {
#ifdef PDF_TRACK_OBJECT_USAGE
    SkPdfReportIf(!fUsed, kInfo_SkPdfIssueSeverity, kUnusedObject_SkPdfIssue,
                  "Unused object in rendering", this, NULL);
#endif  // PDF_TRACK_OBJECT_USAGE

    SkPdfMarkObjectUnused();

    if (fData) {
        switch (fDataType) {
            case kFont_Data:
                delete (SkPdfFont*)fData;
                break;
            case kBitmap_Data:
                delete (SkBitmap*)fData;
                break;
            default:
                SkASSERT(false);
                break;
        }
    }
    fData = NULL;
    fDataType = kEmpty_Data;
}
