/*
 * 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 "samplecode/Sample.h"
#include "src/core/SkGeometry.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 StrokeVerbView : public Sample {
    void onOnceBeforeDraw() override { this->updatePath(); }
    void onDrawContent(SkCanvas*) override;

    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey) override;
    bool onClick(Sample::Click*) override;
    bool onChar(SkUnichar) override;
    SkString name() override { return SkString("StrokeVerb"); }

    class Click;

    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 StrokeVerbView::onDrawContent(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 StrokeVerbView::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 StrokeVerbView::Click : public Sample::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;
};

Sample::Click* StrokeVerbView::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 StrokeVerbView::onClick(Sample::Click* click) {
    Click* myClick = (Click*)click;
    myClick->doClick(fPoints);
    this->updateAndInval();
    return true;
}

bool StrokeVerbView::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 == '+' || 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_SAMPLE(return new StrokeVerbView;)

#endif  // SK_SUPPORT_GPU
