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

#ifndef ToolUtils_DEFINED
#define ToolUtils_DEFINED

#include "include/core/SkColor.h"
#include "include/core/SkData.h"
#include "include/core/SkEncodedImageFormat.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontStyle.h"
#include "include/core/SkFontTypes.h"
#include "include/core/SkImageEncoder.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSpan.h"
#include "include/core/SkStream.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "include/private/base/SkTArray.h"
#include "include/private/base/SkTDArray.h"
#include "include/utils/SkRandom.h"
#include "src/core/SkTInternalLList.h"
#include "tools/SkMetaData.h"

#ifdef SK_GRAPHITE_ENABLED
#include "include/gpu/graphite/Recorder.h"
#endif

class SkBitmap;
class SkCanvas;
class SkFontStyle;
class SkImage;
class SkPath;
class SkPixmap;
class SkRRect;
class SkShader;
class SkSurface;
class SkSurfaceProps;
class SkTextBlobBuilder;
class SkTypeface;

namespace ToolUtils {

const char* alphatype_name (SkAlphaType);
const char* colortype_name (SkColorType);
const char* colortype_depth(SkColorType);  // like colortype_name, but channel order agnostic
const char* tilemode_name(SkTileMode);

/**
 * Map opaque colors from 8888 to 565.
 */
SkColor color_to_565(SkColor color);

/* Return a color emoji typeface with planets to scale if available. */
sk_sp<SkTypeface> planet_typeface();

/** Return a color emoji typeface if available. */
sk_sp<SkTypeface> emoji_typeface();

/** Sample text for the emoji_typeface font. */
constexpr const char* emoji_sample_text() {
    return "\xF0\x9F\x98\x80"
           " "
           "\xE2\x99\xA2";  // 😀 ♢
}

/** A simple SkUserTypeface for testing. */
sk_sp<SkTypeface> sample_user_typeface();

/**
 * Returns a platform-independent text renderer.
 */
sk_sp<SkTypeface> create_portable_typeface(const char* name, SkFontStyle style);

static inline sk_sp<SkTypeface> create_portable_typeface() {
    return create_portable_typeface(nullptr, SkFontStyle());
}

void get_text_path(const SkFont&,
                   const void* text,
                   size_t      length,
                   SkTextEncoding,
                   SkPath*,
                   const SkPoint* positions = nullptr);

/**
 *  Returns true iff all of the pixels between the two images are identical.
 *
 *  If the configs differ, return false.
 */
bool equal_pixels(const SkPixmap&, const SkPixmap&);
bool equal_pixels(const SkBitmap&, const SkBitmap&);
bool equal_pixels(const SkImage* a, const SkImage* b);

/** Returns a newly created CheckerboardShader. */
sk_sp<SkShader> create_checkerboard_shader(SkColor c1, SkColor c2, int size);

/** Draw a checkerboard pattern in the current canvas, restricted to
    the current clip, using SkXfermode::kSrc_Mode. */
void draw_checkerboard(SkCanvas* canvas, SkColor color1, SkColor color2, int checkSize);

/** Make it easier to create a bitmap-based checkerboard */
SkBitmap create_checkerboard_bitmap(int w, int h, SkColor c1, SkColor c2, int checkSize);

sk_sp<SkImage> create_checkerboard_image(int w, int h, SkColor c1, SkColor c2, int checkSize);

/** A default checkerboard. */
inline void draw_checkerboard(SkCanvas* canvas) {
    ToolUtils::draw_checkerboard(canvas, 0xFF999999, 0xFF666666, 8);
}

/** Create pixmaps to initialize a 32x32 image w/ or w/o mipmaps.
 *  Returns the number of levels (either 1 or 6). The mipmap levels will be colored as
 *  specified in 'colors'
 */
int make_pixmaps(SkColorType,
                 SkAlphaType,
                 bool withMips,
                 const SkColor4f colors[6],
                 SkPixmap pixmaps[6],
                 std::unique_ptr<char[]>* mem);

SkBitmap create_string_bitmap(int w, int h, SkColor c, int x, int y, int textSize, const char* str);
sk_sp<SkImage> create_string_image(int w, int h, SkColor c, int x, int y, int textSize, const char* str);

// If the canvas doesn't make a surface (e.g. recording), make a raster surface
sk_sp<SkSurface> makeSurface(SkCanvas*, const SkImageInfo&, const SkSurfaceProps* = nullptr);

// A helper for inserting a drawtext call into a SkTextBlobBuilder
void add_to_text_blob_w_len(SkTextBlobBuilder*,
                            const char* text,
                            size_t      len,
                            SkTextEncoding,
                            const SkFont&,
                            SkScalar x,
                            SkScalar y);

void add_to_text_blob(SkTextBlobBuilder*, const char* text, const SkFont&, SkScalar x, SkScalar y);

// Constructs a star by walking a 'numPts'-sided regular polygon with even/odd fill:
//
//   moveTo(pts[0]);
//   lineTo(pts[step % numPts]);
//   ...
//   lineTo(pts[(step * (N - 1)) % numPts]);
//
// numPts=5, step=2 will produce a classic five-point star.
//
// numPts and step must be co-prime.
SkPath make_star(const SkRect& bounds, int numPts = 5, int step = 2);

void create_hemi_normal_map(SkBitmap* bm, const SkIRect& dst);

void create_frustum_normal_map(SkBitmap* bm, const SkIRect& dst);

void create_tetra_normal_map(SkBitmap* bm, const SkIRect& dst);

// A helper object to test the topological sorting code (TopoSortBench.cpp & TopoSortTest.cpp)
class TopoTestNode : public SkRefCnt {
public:
    TopoTestNode(int id) : fID(id) {}

    void dependsOn(TopoTestNode* src) { *fDependencies.append() = src; }
    void targets(uint32_t target) { *fTargets.append() = target; }

    int  id() const { return fID; }
    void reset() {
        fOutputPos = 0;
        fTempMark = false;
        fWasOutput = false;
    }

    uint32_t outputPos() const {
        SkASSERT(fWasOutput);
        return fOutputPos;
    }

    // check that the topological sort is valid for this node
    bool check() {
        if (!fWasOutput) {
            return false;
        }

        for (int i = 0; i < fDependencies.size(); ++i) {
            if (!fDependencies[i]->fWasOutput) {
                return false;
            }
            // This node should've been output after all the nodes on which it depends
            if (fOutputPos < fDependencies[i]->outputPos()) {
                return false;
            }
        }

        return true;
    }

    // The following 7 methods are needed by the topological sort
    static void SetTempMark(TopoTestNode* node) { node->fTempMark = true; }
    static void ResetTempMark(TopoTestNode* node) { node->fTempMark = false; }
    static bool IsTempMarked(TopoTestNode* node) { return node->fTempMark; }
    static void Output(TopoTestNode* node, uint32_t outputPos) {
        SkASSERT(!node->fWasOutput);
        node->fOutputPos = outputPos;
        node->fWasOutput = true;
    }
    static bool          WasOutput(TopoTestNode* node) { return node->fWasOutput; }
    static uint32_t      GetIndex(TopoTestNode* node) { return node->outputPos(); }
    static int           NumDependencies(TopoTestNode* node) { return node->fDependencies.size(); }
    static TopoTestNode* Dependency(TopoTestNode* node, int index) {
        return node->fDependencies[index];
    }
    static int           NumTargets(TopoTestNode* node) { return node->fTargets.size(); }
    static uint32_t      GetTarget(TopoTestNode* node, int i) { return node->fTargets[i]; }
    static uint32_t      GetID(TopoTestNode* node) { return node->id(); }

    // Helper functions for TopoSortBench & TopoSortTest
    static void AllocNodes(SkTArray<sk_sp<ToolUtils::TopoTestNode>>* graph, int num) {
        graph->reserve_back(num);

        for (int i = 0; i < num; ++i) {
            graph->push_back(sk_sp<TopoTestNode>(new TopoTestNode(i)));
        }
    }

#ifdef SK_DEBUG
    static void Print(const SkTArray<TopoTestNode*>& graph) {
        for (int i = 0; i < graph.size(); ++i) {
            SkDebugf("%d, ", graph[i]->id());
        }
        SkDebugf("\n");
    }
#endif

    // randomize the array
    static void Shuffle(SkSpan<sk_sp<TopoTestNode>> graph, SkRandom* rand) {
        for (size_t i = graph.size() - 1; i > 0; --i) {
            int swap = rand->nextU() % (i + 1);

            graph[i].swap(graph[swap]);
        }
    }

    SK_DECLARE_INTERNAL_LLIST_INTERFACE(TopoTestNode);

private:
    int      fID;
    uint32_t fOutputPos = 0;
    bool     fTempMark = false;
    bool     fWasOutput = false;

    SkTDArray<TopoTestNode*> fDependencies;
    SkTDArray<uint32_t>      fTargets;
};

template <typename T>
inline bool EncodeImageToFile(const char* path, const T& src, SkEncodedImageFormat f, int q) {
    SkFILEWStream file(path);
    return file.isValid() && SkEncodeImage(&file, src, f, q);
}

bool copy_to(SkBitmap* dst, SkColorType dstCT, const SkBitmap& src);
void copy_to_g8(SkBitmap* dst, const SkBitmap& src);

class PixelIter {
public:
    PixelIter();
    PixelIter(SkSurface* surf) {
        SkPixmap pm;
        if (!surf->peekPixels(&pm)) {
            pm.reset();
        }
        this->reset(pm);
    }

    void reset(const SkPixmap& pm) {
        fPM  = pm;
        fLoc = {-1, 0};
    }

    void* next(SkIPoint* loc = nullptr) {
        if (!fPM.addr()) {
            return nullptr;
        }
        fLoc.fX += 1;
        if (fLoc.fX >= fPM.width()) {
            fLoc.fX = 0;
            if (++fLoc.fY >= fPM.height()) {
                this->setDone();
                return nullptr;
            }
        }
        if (loc) {
            *loc = fLoc;
        }
        return fPM.writable_addr(fLoc.fX, fLoc.fY);
    }

    void setDone() { fPM.reset(); }

private:
    SkPixmap fPM;
    SkIPoint fLoc;
};

using PathSniffCallback = void(const SkMatrix&, const SkPath&, const SkPaint&);

// Calls the provided PathSniffCallback for each path in the given file.
// Supported file formats are .svg and .skp.
void sniff_paths(const char filepath[], std::function<PathSniffCallback>);

#if SK_SUPPORT_GPU
sk_sp<SkImage> MakeTextureImage(SkCanvas* canvas, sk_sp<SkImage> orig);
#endif

// Initialised with a font, this class can be called to setup GM UI with sliders for font
// variations, and returns a set of variation coordinates that matches what the sliders in the UI
// are set to. Useful for testing variable font properties, see colrv1.cpp.
class VariationSliders {
public:
    VariationSliders() {}

    VariationSliders(SkTypeface*,
                     SkFontArguments::VariationPosition variationPosition = {nullptr, 0});

    bool writeControls(SkMetaData* controls);

    /* Scans controls for information about the variation axes that the user may have configured.
     * Optionally pass in a boolean to receive information on whether the axes were updated. */
    void readControls(const SkMetaData& controls, bool* changed = nullptr);

    SkSpan<const SkFontArguments::VariationPosition::Coordinate> getCoordinates();

    static SkString tagToString(SkFourByteTag tag);

private:
    struct AxisSlider {
        SkScalar current;
        SkFontParameters::Variation::Axis axis;
        SkString name;
    };

    std::vector<AxisSlider> fAxisSliders;
    std::unique_ptr<SkFontArguments::VariationPosition::Coordinate[]> fCoords;
    static constexpr size_t kAxisVarsSize = 3;
};

#ifdef SK_GRAPHITE_ENABLED
skgpu::graphite::RecorderOptions CreateTestingRecorderOptions();
#endif

}  // namespace ToolUtils

#endif  // ToolUtils_DEFINED
