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

#include "gm/gm.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkImage.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkShader.h"
#include "include/core/SkTileMode.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkGradientShader.h"
#include "src/utils/SkPatchUtils.h"
#include "tools/Resources.h"

static sk_sp<SkShader> make_shader() {
    const SkColor colors[] = {
        SK_ColorRED, SK_ColorCYAN, SK_ColorGREEN, SK_ColorWHITE, SK_ColorMAGENTA, SK_ColorBLUE,
        SK_ColorYELLOW,
    };
    const SkPoint pts[] = { { 100.f / 4.f, 0.f }, { 3.f * 100.f / 4.f, 100.f } };

    return SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors),
                                        SkTileMode::kMirror);
}

static void draw_control_points(SkCanvas* canvas, const SkPoint cubics[12]) {
    //draw control points
    SkPaint paint;
    SkPoint bottom[SkPatchUtils::kNumPtsCubic];
    SkPatchUtils::GetBottomCubic(cubics, bottom);
    SkPoint top[SkPatchUtils::kNumPtsCubic];
    SkPatchUtils::GetTopCubic(cubics, top);
    SkPoint left[SkPatchUtils::kNumPtsCubic];
    SkPatchUtils::GetLeftCubic(cubics, left);
    SkPoint right[SkPatchUtils::kNumPtsCubic];
    SkPatchUtils::GetRightCubic(cubics, right);

    paint.setColor(SK_ColorBLACK);
    paint.setStrokeWidth(0.5f);
    SkPoint corners[4] = { bottom[0], bottom[3], top[0], top[3] };
    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, bottom, paint);
    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, bottom + 1, paint);
    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, top, paint);
    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, left, paint);
    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, right, paint);

    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, top + 1, paint);
    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, left + 1, paint);
    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, right + 1, paint);

    paint.setStrokeWidth(2);

    paint.setColor(SK_ColorRED);
    canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, corners, paint);

    paint.setColor(SK_ColorBLUE);
    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, bottom + 1, paint);

    paint.setColor(SK_ColorCYAN);
    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, top + 1, paint);

    paint.setColor(SK_ColorYELLOW);
    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, left + 1, paint);

    paint.setColor(SK_ColorGREEN);
    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, right + 1, paint);
}

// The order of the colors and points is clockwise starting at upper-left corner.
const SkPoint gCubics[SkPatchUtils::kNumCtrlPts] = {
    //top points
    {100,100},{150,50},{250,150}, {300,100},
    //right points
    {250, 150},{350,250},
    //bottom points
    {300,300},{250,250},{150,350},{100,300},
    //left points
    {50,250},{150,150}
};

const SkPoint gTexCoords[SkPatchUtils::kNumCorners] = {
    {0.0f, 0.0f}, {100.0f, 0.0f}, {100.0f,100.0f}, {0.0f, 100.0f}
};


static void dopatch(SkCanvas* canvas, const SkColor colors[], sk_sp<SkImage> img = nullptr) {
    SkPaint paint;

    const SkBlendMode modes[] = {
        SkBlendMode::kSrc,
        SkBlendMode::kDst,
        SkBlendMode::kModulate,
    };

    SkPoint texStorage[4];
    const SkPoint* tex = gTexCoords;

    sk_sp<SkShader> shader;
    if (img) {
        SkScalar w = img->width();
        SkScalar h = img->height();
        shader = img->makeShader();
        texStorage[0].set(0, 0);
        texStorage[1].set(w, 0);
        texStorage[2].set(w, h);
        texStorage[3].set(0, h);
        tex = texStorage;
    } else {
        shader = make_shader();
    }

    canvas->save();
    for (int y = 0; y < 3; y++) {
        for (int x = 0; x < 4; x++) {
            canvas->save();
            canvas->translate(x * 350.0f, y * 350.0f);
            switch (x) {
                case 0:
                    canvas->drawPatch(gCubics, nullptr, nullptr, modes[y], paint);
                    break;
                case 1:
                    canvas->drawPatch(gCubics, colors, nullptr, modes[y], paint);
                    break;
                case 2:
                    paint.setShader(shader);
                    canvas->drawPatch(gCubics, nullptr, tex, modes[y], paint);
                    paint.setShader(nullptr);
                    break;
                case 3:
                    paint.setShader(shader);
                    canvas->drawPatch(gCubics, colors, tex, modes[y], paint);
                    paint.setShader(nullptr);
                    break;
                default:
                    break;
            }

            draw_control_points(canvas, gCubics);
            canvas->restore();
        }
    }
    canvas->restore();
}

DEF_SIMPLE_GM(patch_primitive, canvas, 1500, 1100) {
    const SkColor colors[SkPatchUtils::kNumCorners] = {
        SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorCYAN
    };
    dopatch(canvas, colors);
}
DEF_SIMPLE_GM(patch_image, canvas, 1500, 1100) {
    const SkColor colors[SkPatchUtils::kNumCorners] = {
        SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorCYAN
    };
    dopatch(canvas, colors, GetResourceAsImage("images/mandrill_128.png"));
}
DEF_SIMPLE_GM(patch_alpha, canvas, 1500, 1100) {
    const SkColor colors[SkPatchUtils::kNumCorners] = {
        SK_ColorRED, 0x0000FF00, SK_ColorBLUE, 0x00FF00FF,
    };
    dopatch(canvas, colors);
}

// These two should look the same (one patch, one simple path)
DEF_SIMPLE_GM(patch_alpha_test, canvas, 550, 250) {
    canvas->translate(-75, -75);

    const SkColor colors[SkPatchUtils::kNumCorners] = {
        0x80FF0000, 0x80FF0000, 0x80FF0000, 0x80FF0000,
    };
    SkPaint paint;
    canvas->drawPatch(gCubics, colors, nullptr, SkBlendMode::kModulate, paint);

    canvas->translate(300, 0);

    SkPath path;
    path.moveTo(gCubics[0]);
    path.cubicTo(gCubics[ 1], gCubics[ 2], gCubics[ 3]);
    path.cubicTo(gCubics[ 4], gCubics[ 5], gCubics[ 6]);
    path.cubicTo(gCubics[ 7], gCubics[ 8], gCubics[ 9]);
    path.cubicTo(gCubics[10], gCubics[11], gCubics[ 0]);
    paint.setColor(colors[0]);
    canvas->drawPath(path, paint);
}

