/*
 * 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 sk_tool_utils_DEFINED
#define sk_tool_utils_DEFINED

#include "SkColor.h"
#include "SkImageEncoder.h"
#include "SkImageInfo.h"
#include "SkPixelSerializer.h"
#include "SkRandom.h"
#include "SkStream.h"
#include "SkTDArray.h"
#include "SkTypeface.h"

class SkBitmap;
class SkCanvas;
class SkColorFilter;
class SkPaint;
class SkPath;
class SkRRect;
class SkShader;
class SkTestFont;
class SkTextBlobBuilder;

namespace sk_tool_utils {

    const char* colortype_name(SkColorType);

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

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

    /**
     * If the platform supports color emoji, return sample text the emoji can render.
     */
    const char* emoji_sample_text();

    /**
     * If the platform supports color emoji, return the type (i.e. "CBDT", "SBIX", "").
     */
    const char* platform_os_emoji();

    /**
     * Return the platform name with the version number ("Mac10.9", "Win8", etc.) if available.
     */
    const char* platform_os_name();

    /**
     * Return the platform name without the version number ("Mac", "Win", etc.) if available.
     */
    SkString major_platform_os_name();

    /**
     * Return the platform extra config (e.g. "GDI") if available.
     */
    const char* platform_extra_config(const char* config);

    /**
     * Map serif, san-serif, and monospace to the platform-specific font name.
     */
    const char* platform_font_name(const char* name);

    /**
     * Sets the paint to use a platform-independent text renderer
     */
    void set_portable_typeface(SkPaint* paint, const char* name = nullptr,
                               SkFontStyle style = SkFontStyle());

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

    /** Call to clean up portable font references. */
    void release_portable_typefaces();

    /**
     *  Call canvas->writePixels() by using the pixels from bitmap, but with an info that claims
     *  the pixels are colorType + alphaType
     */
    void write_pixels(SkCanvas*, const SkBitmap&, int x, int y, SkColorType, SkAlphaType);

    /**
     *  Returns true iff all of the pixels between the two images differ by <= the maxDiff value
     *  per component.
     *
     *  If the configs differ, return false.
     *
     *  If the colorType is half-float, then maxDiff is interpreted as 0..255 --> 0..1
     */
    bool equal_pixels(const SkPixmap&, const SkPixmap&, unsigned maxDiff = 0);
    bool equal_pixels(const SkBitmap&, const SkBitmap&, unsigned maxDiff = 0);

    // private to sk_tool_utils
    sk_sp<SkTypeface> create_font(const char* name, SkFontStyle);

    /** 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);

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

    SkBitmap create_string_bitmap(int w, int h, SkColor c, int x, int y,
                                  int textSize, const char* str);

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

    void add_to_text_blob(SkTextBlobBuilder* builder, const char* text,
                          const SkPaint& origPaint, SkScalar x, SkScalar y);

    void make_big_path(SkPath& path);

    // Return a blurred version of 'src'. This doesn't use a separable filter
    // so it is slow!
    SkBitmap slow_blur(const SkBitmap& src, float sigma);

    SkRect compute_central_occluder(const SkRRect& rr);
    SkRect compute_widest_occluder(const SkRRect& rr);
    SkRect compute_tallest_occluder(const SkRRect& rr);

    // A helper object to test the topological sorting code (TopoSortBench.cpp & TopoSortTest.cpp)
    class TopoTestNode {
    public:
        TopoTestNode(int id) : fID(id), fOutputPos(-1), fTempMark(false) { }

        void dependsOn(TopoTestNode* src) {
            *fDependencies.append() = src;
        }

        int id() const { return fID; }
        void reset() { fOutputPos = -1; }

        int outputPos() const { return fOutputPos; }

        // check that the topological sort is valid for this node
        bool check() {
            if (-1 == fOutputPos) {
                return false;
            }

            for (int i = 0; i < fDependencies.count(); ++i) {
                if (-1 == fDependencies[i]->outputPos()) {
                    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, int outputPos) {
            SkASSERT(-1 != outputPos);
            node->fOutputPos = outputPos;
        }
        static bool WasOutput(TopoTestNode* node) { return (-1 != node->fOutputPos); }
        static int NumDependencies(TopoTestNode* node) { return node->fDependencies.count(); }
        static TopoTestNode* Dependency(TopoTestNode* node, int index) {
            return node->fDependencies[index];
        }

        // Helper functions for TopoSortBench & TopoSortTest
        static void AllocNodes(SkTDArray<TopoTestNode*>* graph, int num) {
            graph->setReserve(num);

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

        static void DeallocNodes(SkTDArray<TopoTestNode*>* graph) {
            for (int i = 0; i < graph->count(); ++i) {
                delete (*graph)[i];
            }
        }

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

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

                TopoTestNode* tmp = (*graph)[i];
                (*graph)[i] = (*graph)[swap];
                (*graph)[swap] = tmp;
            }
        }

    private:
        int  fID;
        int  fOutputPos;
        bool fTempMark;

        SkTDArray<TopoTestNode*> fDependencies;
    };

    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);
    }

    template <typename T>
    inline sk_sp<SkData> EncodeImageToData(const T& src, SkEncodedImageFormat f, int q) {
        SkDynamicMemoryWStream buf;
        return SkEncodeImage(&buf, src , f, q) ? buf.detachAsData() : nullptr;
    }

    /**
     * Uses SkEncodeImage to serialize images that are not already
     * encoded as SkEncodedImageFormat::kPNG images.
     */
    inline sk_sp<SkPixelSerializer> MakePixelSerializer() {
        struct EncodeImagePixelSerializer final : SkPixelSerializer {
            bool onUseEncodedData(const void*, size_t) override { return true; }
            SkData* onEncode(const SkPixmap& pmap) override {
                return EncodeImageToData(pmap, SkEncodedImageFormat::kPNG, 100).release();
            }
        };
        return sk_make_sp<EncodeImagePixelSerializer>();
    }

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

}  // namespace sk_tool_utils

#endif  // sk_tool_utils_DEFINED
