/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "Sample.h"

#include "SkCanvas.h"
#include "SkPath.h"
#include "SkRandom.h"
#include "SkRRect.h"
#include "SkTime.h"

// Implementation in C++ of Mozilla Canvas2D benchmark Canvas Clock Test
// See https://code.google.com/p/skia/issues/detail?id=1626

#define USE_PATH 1

class ClockView : public Sample {
public:
    ClockView() {}

protected:
    bool onQuery(Sample::Event* evt) override {
        if (Sample::TitleQ(*evt)) {
            Sample::TitleR(evt, "Clock");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }

    void onDrawContent(SkCanvas* canvas) override {
        SkPaint paintFill;
        SkPaint paintStroke;
        SkPath  path;

        canvas->save();
        canvas->translate(150, 150);
        canvas->scale(0.4f, 0.4f);
        canvas->rotate(-180.f/2.f);

        paintFill.setAntiAlias(true);
        paintFill.setColor(SK_ColorBLACK);
        paintStroke.setAntiAlias(true);
        paintStroke.setStyle(SkPaint::kStroke_Style);
        paintStroke.setColor(SK_ColorBLACK);
        paintStroke.setStrokeWidth(8);
        paintStroke.setStrokeCap(SkPaint::kRound_Cap);

        // Hour marks
        SkRect rect;
#ifndef USE_PATH
        rect = SkRect::MakeLTRB(200-4, -4, 240+4, 4);
        SkRRect rrect;
        SkVector radii[4] = {{4,4}, {4,4}, {4,4}, {4,4}};
        rrect.setRectRadii(rect, radii);
#endif
        canvas->save();
        for (int i=0;i<12;i++){
            canvas->rotate(180.f/6.f);
#ifdef USE_PATH
            path.reset();
            path.moveTo(200,0);
            path.lineTo(240,0);
            canvas->drawPath(path, paintStroke);
#else
            canvas->drawRRect(rrect, paintFill);
#endif
        }
        canvas->restore();

        // Minute marks
        canvas->save();
#ifdef USE_PATH
        paintStroke.setStrokeWidth(5);
#else
        rect = SkRect::MakeLTRB(231.5f, -2.5f, 242.5, 2.5f);
        radii[0] = SkPoint::Make(2.5f,2.5f);
        radii[1] = SkPoint::Make(2.5f,2.5f);
        radii[2] = SkPoint::Make(2.5f,2.5f);
        radii[3] = SkPoint::Make(2.5f,2.5f);
        rrect.setRectRadii(rect, radii);
#endif
        for (int i=0;i<60;i++){
            if (i%5 == 0) {
                canvas->rotate(180.f/30.f);
                continue;
            }
#ifdef USE_PATH
            path.reset();
            path.moveTo(234,0);
            path.lineTo(240,0);
            canvas->drawPath(path, paintStroke);
#else
            canvas->drawRRect(rrect, paintFill);
#endif
            canvas->rotate(180.f/30.f);
        }
        canvas->restore();

        SkTime::DateTime time;
        SkTime::GetDateTime(&time);
        time.fHour = time.fHour >= 12 ? time.fHour-12 : time.fHour;
        paintFill.setColor(SK_ColorBLACK);

        // Write hours
        canvas->save();
        canvas->rotate(time.fHour*(180.f/6.f) + time.fMinute*(180.f/360.f)
                       + time.fSecond*(180.f/21600.f) );
#ifdef USE_PATH
        paintStroke.setStrokeWidth(14);
        path.reset();
        path.moveTo(-20,0);
        path.lineTo(80,0);
        canvas->drawPath(path, paintStroke);
#else
        rect = SkRect::MakeLTRB(-20-7, -7, 80+7, 7);
        radii[0] = SkPoint::Make(7,7);
        radii[1] = SkPoint::Make(7,7);
        radii[2] = SkPoint::Make(7,7);
        radii[3] = SkPoint::Make(7,7);
        rrect.setRectRadii(rect, radii);
        canvas->drawRRect(rrect, paintFill);
#endif
        canvas->restore();

        // Write minutes
        canvas->save();
        canvas->rotate(time.fMinute*(180.f/30.f)
                       + time.fSecond*(180.f/1800.f) );
#ifdef USE_PATH
        paintStroke.setStrokeWidth(10);
        path.reset();
        path.moveTo(-56,0);
        path.lineTo(224,0);
        canvas->drawPath(path, paintStroke);
#else
        rect = SkRect::MakeLTRB(-56-5, -5, 224+5, 5);
        radii[0] = SkPoint::Make(5,5);
        radii[1] = SkPoint::Make(5,5);
        radii[2] = SkPoint::Make(5,5);
        radii[3] = SkPoint::Make(5,5);
        rrect.setRectRadii(rect, radii);
        canvas->drawRRect(rrect, paintFill);
#endif
        canvas->restore();

        // Write seconds
        canvas->save();
        canvas->rotate(time.fSecond*(180.f/30.f));
        paintFill.setColor(0xffd40000);
        paintStroke.setColor(0xffd40000);
        paintStroke.setStrokeWidth(6);
#ifdef USE_PATH
        path.reset();
        path.moveTo(-60,0);
        path.lineTo(166,0);
        canvas->drawPath(path, paintStroke);
#else
        rect = SkRect::MakeLTRB(-60-3, -3, 166+3, 3);
        radii[0] = SkPoint::Make(3,3);
        radii[1] = SkPoint::Make(3,3);
        radii[2] = SkPoint::Make(3,3);
        radii[3] = SkPoint::Make(3,3);
        rrect.setRectRadii(rect, radii);
        canvas->drawRRect(rrect, paintFill);
#endif
        rect = SkRect::MakeLTRB(-20, -20, 20, 20);
#ifdef USE_PATH
        path.reset();
        path.arcTo(rect, 0, 0, false);
        path.addOval(rect, SkPath::kCCW_Direction);
        path.arcTo(rect, 360, 0, true);
        canvas->drawPath(path, paintFill);
#else
        canvas->drawOval(rect, paintFill);
#endif
        rect = SkRect::MakeLTRB(-20+190, -20, 20+190, 20);
#ifdef USE_PATH
        path.reset();
        path.arcTo(rect, 0, 0, false);
        path.addOval(rect, SkPath::kCCW_Direction);
        path.arcTo(rect, 360, 0, true);
        canvas->drawPath(path, paintStroke);
#else
        canvas->drawOval(rect, paintStroke);
#endif
        paintFill.setColor(0xff505050);
#ifdef USE_PATH
        rect = SkRect::MakeLTRB(-6, -6, 6, 6);
        path.arcTo(rect, 0, 0, false);
        path.addOval(rect, SkPath::kCCW_Direction);
        path.arcTo(rect, 360, 0, true);
        canvas->drawPath(path, paintFill);
#else
        canvas->drawOval(rect, paintFill);
        rect = SkRect::MakeLTRB(-6, -6, 6, 6);
        canvas->drawOval(rect, paintFill);
#endif
        canvas->restore();

        paintStroke.setStrokeWidth(18);
        paintStroke.setColor(0xff325FA2);
        rect = SkRect::MakeLTRB(-284, -284, 284, 284);
#ifdef USE_PATH
        path.reset();
        path.arcTo(rect, 0, 0, false);
        path.addOval(rect, SkPath::kCCW_Direction);
        path.arcTo(rect, 360, 0, true);
        canvas->drawPath(path, paintStroke);
#else
        canvas->drawOval(rect, paintStroke);
#endif

        canvas->restore();
    }

    bool onAnimate(const SkAnimTimer&) override {
        return true;
    }

private:

    typedef Sample INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

DEF_SAMPLE( return new ClockView(); )
