/*
 * Copyright 2017 Google LLC
 *
 * 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 defined(SK_GANESH)

#include "include/core/SkCanvas.h"
#include "include/core/SkFont.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPathBuilder.h"
#include "src/core/SkGeometry.h"
#include "tools/fonts/FontToolUtils.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, {fPoints, 4}, pointsPaint);
    } else {
        canvas->drawPoints(SkCanvas::kPoints_PointMode, {fPoints, 2}, pointsPaint);
        canvas->drawPoints(SkCanvas::kPoints_PointMode, {fPoints + 3, 1}, pointsPaint);
    }

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

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

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  // defined(SK_GANESH)
