
/*
 * 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.h"
#include "SkGradientShader.h"
#include "SkPatchUtils.h"

static 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::CreateLinear(pts, colors, NULL, SK_ARRAY_COUNT(colors),
                                          SkShader::kMirror_TileMode);
}

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

namespace skiagm {
/**
 * This GM draws a cubics coons patch using the specialized call SkCanvas::drawPatch.
 */
class SkPatchGM : public GM {
    
public:
    SkPatchGM() {
        this->setBGColor(0xFFFFFFFF);
    }

protected:
    SkString onShortName() SK_OVERRIDE {
        return SkString("patch_primitive");
    }

    SkISize onISize() SK_OVERRIDE {
        return SkISize::Make(800, 800);
    }

    uint32_t onGetFlags() const SK_OVERRIDE {
        return kSkipTiled_Flag;
    }

    void onDraw(SkCanvas* canvas) SK_OVERRIDE {

        SkPaint paint;
        
        // The order of the colors and points is clockwise starting at upper-left corner.
        const SkPoint cubics[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 SkColor colors[SkPatchUtils::kNumCorners] = {
            SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorCYAN
        };
        const SkPoint texCoords[SkPatchUtils::kNumCorners] = {
            {0.0f, 0.0f}, {100.0f, 0.0f}, {100.0f,100.0f}, {0.0f, 100.0f}}
        ;
        
        const SkXfermode::Mode modes[] = {
            SkXfermode::kSrc_Mode,
            SkXfermode::kDst_Mode,
            SkXfermode::kModulate_Mode,
        };
        
        SkAutoTUnref<SkShader> shader(make_shader());
        
        canvas->save();
        for (int y = 0; y < 3; y++) {
            SkAutoTUnref<SkXfermode> xfer(SkXfermode::Create(modes[y]));

            for (int x = 0; x < 4; x++) {
                canvas->save();
                canvas->translate(x * 350.0f, y * 350.0f);
                switch (x) {
                    case 0:
                        canvas->drawPatch(cubics, NULL, NULL, xfer, paint);
                        break;
                    case 1:
                        canvas->drawPatch(cubics, colors, NULL, xfer, paint);
                        break;
                    case 2:
                        paint.setShader(shader);
                        canvas->drawPatch(cubics, NULL, texCoords, xfer, paint);
                        paint.setShader(NULL);
                        break;
                    case 3:
                        paint.setShader(shader);
                        canvas->drawPatch(cubics, colors, texCoords, xfer, paint);
                        paint.setShader(NULL);
                        break;
                    default:
                        break;
                }
                
                draw_control_points(canvas, cubics);
                canvas->restore();
            }
        }
        canvas->restore();
    }

private:
    typedef GM INHERITED;
};

DEF_GM(return SkNEW(SkPatchGM); )

}
