/*
 * 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,
                    const SkMatrix* localMatrix) {
    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(SkSamplingOptions(), localMatrix);
        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, nullptr, nullptr);
}
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"), nullptr);
}
DEF_SIMPLE_GM(patch_image_persp, canvas, 1500, 1100) {
    const SkColor colors[SkPatchUtils::kNumCorners] = {
        SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorCYAN
    };
    SkMatrix localM;
    localM.reset();
    localM[6] = 0.00001f;    // force perspective
    dopatch(canvas, colors, GetResourceAsImage("images/mandrill_128.png"), &localM);
}
DEF_SIMPLE_GM(patch_alpha, canvas, 1500, 1100) {
    const SkColor colors[SkPatchUtils::kNumCorners] = {
        SK_ColorRED, 0x0000FF00, SK_ColorBLUE, 0x00FF00FF,
    };
    dopatch(canvas, colors, nullptr, nullptr);
}

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

