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

#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPathTypes.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkStream.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkDebug.h"
#include "src/base/SkUTF.h"
#include "src/base/SkUtils.h"
#include "src/shaders/SkShaderBase.h"
#include "src/utils/SkFloatToDecimal.h"

#include <cstdint>
#include <cstring>
#include <memory>

class SkBitmap;
class SkImage;
class SkPDFArray;
class SkPDFDict;
class SkPath;
class SkShader;
enum class SkBlendMode;
struct SkRect;

namespace SkPDF { struct DateTime; }

template <typename T>
bool SkPackedArrayEqual(T* u, T* v, size_t n) {
    SkASSERT(u);
    SkASSERT(v);
    return 0 == memcmp(u, v, n * sizeof(T));
}

#if 0
#define PRINT_NOT_IMPL(str) fprintf(stderr, str)
#else
#define PRINT_NOT_IMPL(str)
#endif

#define NOT_IMPLEMENTED(condition, assertion)                      \
    do {                                                           \
        if ((bool)(condition)) {                                   \
            PRINT_NOT_IMPL("NOT_IMPLEMENTED: " #condition "\n");   \
            SkDEBUGCODE(SkASSERT(!assertion);)                     \
        }                                                          \
    } while (0)

namespace SkPDFUtils {

const char* BlendModeName(SkBlendMode);

std::unique_ptr<SkPDFArray> RectToArray(const SkRect& rect);
std::unique_ptr<SkPDFArray> MatrixToArray(const SkMatrix& matrix);

void MoveTo(SkScalar x, SkScalar y, SkWStream* content);
void AppendLine(SkScalar x, SkScalar y, SkWStream* content);
void AppendRectangle(const SkRect& rect, SkWStream* content);
void EmitPath(const SkPath& path, SkPaint::Style paintStyle,
              bool doConsumeDegerates, SkWStream* content, SkScalar tolerance = 0.25f);
inline void EmitPath(const SkPath& path, SkPaint::Style paintStyle,
                     SkWStream* content, SkScalar tolerance = 0.25f) {
    SkPDFUtils::EmitPath(path, paintStyle, true, content, tolerance);
}
void ClosePath(SkWStream* content);
void PaintPath(SkPaint::Style style, SkPathFillType fill, SkWStream* content);
void StrokePath(SkWStream* content);
void ApplyGraphicState(int objectIndex, SkWStream* content);
void ApplyPattern(int objectIndex, SkWStream* content);

// Converts (value / 255.0) with three significant digits of accuracy.
// Writes value as string into result.  Returns strlen() of result.
size_t ColorToDecimal(uint8_t value, char result[5]);

static constexpr unsigned kFloatColorDecimalCount = 4;
size_t ColorToDecimalF(float value, char (&result)[kFloatColorDecimalCount + 2]);
inline void AppendColorComponent(uint8_t value, SkWStream* wStream) {
    char buffer[5];
    size_t len = SkPDFUtils::ColorToDecimal(value, buffer);
    wStream->write(buffer, len);
}
inline void AppendColorComponentF(float value, SkWStream* wStream) {
    char buffer[kFloatColorDecimalCount + 2];
    size_t len = SkPDFUtils::ColorToDecimalF(value, buffer);
    wStream->write(buffer, len);
}

inline void AppendScalar(SkScalar value, SkWStream* stream) {
    char result[kMaximumSkFloatToDecimalLength];
    size_t len = SkFloatToDecimal(value, result);
    SkASSERT(len < kMaximumSkFloatToDecimalLength);
    stream->write(result, len);
}

inline void WriteUInt16BE(SkWStream* wStream, uint16_t value) {
    char result[4] = { SkHexadecimalDigits::gUpper[       value >> 12 ],
                       SkHexadecimalDigits::gUpper[0xF & (value >> 8 )],
                       SkHexadecimalDigits::gUpper[0xF & (value >> 4 )],
                       SkHexadecimalDigits::gUpper[0xF & (value      )] };
    wStream->write(result, 4);
}

inline void WriteUInt8(SkWStream* wStream, uint8_t value) {
    char result[2] = { SkHexadecimalDigits::gUpper[value >> 4],
                       SkHexadecimalDigits::gUpper[value & 0xF] };
    wStream->write(result, 2);
}

inline void WriteUTF16beHex(SkWStream* wStream, SkUnichar utf32) {
    uint16_t utf16[2] = {0, 0};
    size_t len = SkUTF::ToUTF16(utf32, utf16);
    SkASSERT(len == 1 || len == 2);
    SkPDFUtils::WriteUInt16BE(wStream, utf16[0]);
    if (len == 2) {
        SkPDFUtils::WriteUInt16BE(wStream, utf16[1]);
    }
}

inline SkMatrix GetShaderLocalMatrix(const SkShader* shader) {
    SkMatrix localMatrix;
    if (sk_sp<SkShader> s = as_SB(shader)->makeAsALocalMatrixShader(&localMatrix)) {
        return localMatrix;
    }
    return SkMatrix::I();
}
bool InverseTransformBBox(const SkMatrix& matrix, SkRect* bbox);
void PopulateTilingPatternDict(SkPDFDict* pattern,
                               SkRect& bbox,
                               std::unique_ptr<SkPDFDict> resources,
                               const SkMatrix& matrix);

bool ToBitmap(const SkImage* img, SkBitmap* dst);

void AppendTransform(const SkMatrix&, SkWStream*);

// Takes SkTime::GetNSecs() [now] and puts it into the provided struct.
void GetDateTime(SkPDF::DateTime*);

}  // namespace SkPDFUtils

#endif
