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

#include "include/core/SkTypes.h"

#if SK_SUPPORT_GPU

#include "include/core/SkCanvas.h"
#include "include/core/SkFont.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "src/core/SkGeometry.h"
#include "tools/viewer/ClickHandlerSlide.h"

enum class VerbType {
    kTriangles,
    kQuadratics,
    kCubics,
    kConics
};

static const char* verb_type_name(VerbType verbType) {
    switch (verbType) {
        case VerbType::kTriangles: return "kTriangles";
        case VerbType::kQuadratics: return "kQuadratics";
        case VerbType::kCubics: return "kCubics";
        case VerbType::kConics: return "kConics";
    }
    SkUNREACHABLE;
};

/**
 * This sample visualizes simple strokes.
 */
class StrokeVerbSlide : public ClickHandlerSlide {
public:
    StrokeVerbSlide() { fName = "StrokeVerb"; }

    void load(SkScalar w, SkScalar h) override { this->updatePath(); }

    void draw(SkCanvas*) override;

    bool onChar(SkUnichar) override;

protected:
    class Click;

    ClickHandlerSlide::Click* onFindClickHandler(SkScalar x, SkScalar y,
                                                 skui::ModifierKey) override;
    bool onClick(ClickHandlerSlide::Click*) override;


private:
    void updateAndInval() { this->updatePath(); }

    void updatePath();

    VerbType fVerbType = VerbType::kCubics;

    SkPoint fPoints[4] = {
            {100.05f, 100.05f}, {400.75f, 100.05f}, {400.75f, 300.95f}, {100.05f, 300.95f}};

    float fConicWeight = .5;
    float fStrokeWidth = 40;
    SkPaint::Join fStrokeJoin = SkPaint::kMiter_Join;
    SkPaint::Cap fStrokeCap = SkPaint::kButt_Cap;

    SkPath fPath;
};

void StrokeVerbSlide::draw(SkCanvas* canvas) {
    canvas->clear(SK_ColorBLACK);

    SkPaint outlinePaint;
    outlinePaint.setColor(0xff808080);
    outlinePaint.setStyle(SkPaint::kStroke_Style);
    outlinePaint.setStrokeWidth(fStrokeWidth);
    outlinePaint.setStrokeJoin(fStrokeJoin);
    outlinePaint.setStrokeCap(fStrokeCap);
    outlinePaint.setAntiAlias(true);
    canvas->drawPath(fPath, outlinePaint);

    SkString caption;
    caption.appendf("VerbType_%s", verb_type_name(fVerbType));
    if (VerbType::kCubics == fVerbType) {
        caption.appendf(" (%s)", SkCubicTypeName(SkClassifyCubic(fPoints)));
    } else if (VerbType::kConics == fVerbType) {
        caption.appendf(" (w=%f)", fConicWeight);
    }

    caption.appendf(" (stroke_width=%f)", fStrokeWidth);

    SkPaint pointsPaint;
    pointsPaint.setColor(SK_ColorBLUE);
    pointsPaint.setStrokeWidth(8);
    pointsPaint.setAntiAlias(true);

    if (VerbType::kCubics == fVerbType) {
        canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, fPoints, pointsPaint);
    } else {
        canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, fPoints, pointsPaint);
        canvas->drawPoints(SkCanvas::kPoints_PointMode, 1, fPoints + 3, pointsPaint);
    }

    SkFont font(nullptr, 20);
    SkPaint captionPaint;
    captionPaint.setColor(SK_ColorWHITE);
    canvas->drawString(caption, 10, 30, font, captionPaint);
}

void StrokeVerbSlide::updatePath() {
    fPath.reset();
    fPath.moveTo(fPoints[0]);
    switch (fVerbType) {
        case VerbType::kCubics:
            fPath.cubicTo(fPoints[1], fPoints[2], fPoints[3]);
            break;
        case VerbType::kQuadratics:
            fPath.quadTo(fPoints[1], fPoints[3]);
            break;
        case VerbType::kConics:
            fPath.conicTo(fPoints[1], fPoints[3], fConicWeight);
            break;
        case VerbType::kTriangles:
            fPath.lineTo(fPoints[1]);
            fPath.lineTo(fPoints[3]);
            fPath.close();
            break;
    }
}

class StrokeVerbSlide::Click : public ClickHandlerSlide::Click {
public:
    Click(int ptIdx) : fPtIdx(ptIdx) {}

    void doClick(SkPoint points[]) {
        if (fPtIdx >= 0) {
            points[fPtIdx] += fCurr - fPrev;
        } else {
            for (int i = 0; i < 4; ++i) {
                points[i] += fCurr - fPrev;
            }
        }
    }

private:
    int fPtIdx;
};

ClickHandlerSlide::Click* StrokeVerbSlide::onFindClickHandler(SkScalar x, SkScalar y,
                                                              skui::ModifierKey) {
    for (int i = 0; i < 4; ++i) {
        if (VerbType::kCubics != fVerbType && 2 == i) {
            continue;
        }
        if (fabs(x - fPoints[i].x()) < 20 && fabsf(y - fPoints[i].y()) < 20) {
            return new Click(i);
        }
    }
    return new Click(-1);
}

bool StrokeVerbSlide::onClick(ClickHandlerSlide::Click* click) {
    Click* myClick = (Click*)click;
    myClick->doClick(fPoints);
    this->updateAndInval();
    return true;
}

bool StrokeVerbSlide::onChar(SkUnichar unichar) {
        if (unichar >= '1' && unichar <= '4') {
            fVerbType = VerbType(unichar - '1');
            this->updateAndInval();
            return true;
        }
        float* valueToScale = nullptr;
        if (VerbType::kConics == fVerbType) {
            valueToScale = &fConicWeight;
        } else {
            valueToScale = &fStrokeWidth;
        }
        if (valueToScale) {
            if (unichar == '+') {
                *valueToScale *= 2;
                this->updateAndInval();
                return true;
            }
            if (unichar == '=') {
                *valueToScale *= 5/4.f;
                this->updateAndInval();
                return true;
            }
            if (unichar == '-') {
                *valueToScale *= 4/5.f;
                this->updateAndInval();
                return true;
            }
            if (unichar == '_') {
                *valueToScale *= .5f;
                this->updateAndInval();
                return true;
            }
        }
        if (unichar == 'D') {
            SkDebugf("    SkPoint fPoints[4] = {\n");
            SkDebugf("        {%ff, %ff},\n", fPoints[0].x(), fPoints[0].y());
            SkDebugf("        {%ff, %ff},\n", fPoints[1].x(), fPoints[1].y());
            SkDebugf("        {%ff, %ff},\n", fPoints[2].x(), fPoints[2].y());
            SkDebugf("        {%ff, %ff}\n", fPoints[3].x(), fPoints[3].y());
            SkDebugf("    };\n");
            return true;
        }
        if (unichar == 'J') {
            fStrokeJoin = (SkPaint::Join)((fStrokeJoin + 1) % 3);
            this->updateAndInval();
            return true;
        }
        if (unichar == 'C') {
            fStrokeCap = (SkPaint::Cap)((fStrokeCap + 1) % 3);
            this->updateAndInval();
            return true;
        }
        return false;
}

DEF_SLIDE(return new StrokeVerbSlide;)

#endif  // SK_SUPPORT_GPU
