/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef SKY_ENGINE_PLATFORM_GRAPHICS_LOGGINGCANVAS_H_
#define SKY_ENGINE_PLATFORM_GRAPHICS_LOGGINGCANVAS_H_

#include "sky/engine/platform/JSONValues.h"
#include "sky/engine/platform/graphics/InterceptingCanvas.h"

namespace blink {

class LoggingCanvas : public InterceptingCanvas {
public:
    LoggingCanvas(int width, int height);
    PassRefPtr<JSONArray> log();

    virtual void drawPaint(const SkPaint&) override;
    virtual void drawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override;
    virtual void drawRect(const SkRect&, const SkPaint&) override;
    virtual void drawOval(const SkRect&, const SkPaint&) override;
    virtual void drawRRect(const SkRRect&, const SkPaint&) override;
    virtual void drawPath(const SkPath&, const SkPaint&) override;
    virtual void drawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPaint* = 0) override;
    virtual void drawBitmapRectToRect(const SkBitmap&, const SkRect* src, const SkRect& dst, const SkPaint*, DrawBitmapRectFlags) override;
    virtual void drawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst, const SkPaint*) override;
    virtual void drawSprite(const SkBitmap&, int left, int top, const SkPaint* = 0) override;
    virtual void drawVertices(VertexMode vmode, int vertexCount, const SkPoint vertices[], const SkPoint texs[],
        const SkColor colors[], SkXfermode* xmode, const uint16_t indices[], int indexCount, const SkPaint&) override;
    virtual void drawData(const void* data, size_t length) override;
    virtual void beginCommentGroup(const char* description) override;
    virtual void addComment(const char* keyword, const char* value) override;
    virtual void endCommentGroup() override;

    virtual void onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint&) override;
    virtual void onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, const SkPaint&) override;
    virtual void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkPaint&) override;
    virtual void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkPaint&) override;
    virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath&, const SkMatrix*, const SkPaint&) override;
    virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) override;
    virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) override;
    virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) override;
    virtual void onClipRegion(const SkRegion&, SkRegion::Op) override;
    virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*);
    virtual void didSetMatrix(const SkMatrix&) override;
    virtual void didConcat(const SkMatrix&) override;
    virtual void willSave() override;
    SaveLayerStrategy willSaveLayer(const SkRect* bounds, const SkPaint*, SaveFlags) override;
    virtual void willRestore() override;

private:
    RefPtr<JSONArray> m_log;
    friend class AutoLogger;

    struct VerbParams {
        String name;
        unsigned pointCount;
        unsigned pointOffset;

        VerbParams(const String& name, unsigned pointCount, unsigned pointOffset)
            : name(name)
            , pointCount(pointCount)
            , pointOffset(pointOffset) { }
    };

    PassRefPtr<JSONObject> addItem(const String& name);
    PassRefPtr<JSONObject> addItemWithParams(const String& name);
    PassRefPtr<JSONObject> objectForSkRect(const SkRect&);
    PassRefPtr<JSONObject> objectForSkIRect(const SkIRect&);
    String pointModeName(PointMode);
    PassRefPtr<JSONObject> objectForSkPoint(const SkPoint&);
    PassRefPtr<JSONArray> arrayForSkPoints(size_t count, const SkPoint points[]);
    PassRefPtr<JSONObject> objectForSkPicture(const SkPicture&);
    PassRefPtr<JSONObject> objectForRadius(const SkRRect& rrect, SkRRect::Corner);
    String rrectTypeName(SkRRect::Type);
    String radiusName(SkRRect::Corner);
    PassRefPtr<JSONObject> objectForSkRRect(const SkRRect&);
    String fillTypeName(SkPath::FillType);
    String convexityName(SkPath::Convexity);
    String verbName(SkPath::Verb);
    VerbParams segmentParams(SkPath::Verb);
    PassRefPtr<JSONObject> objectForSkPath(const SkPath&);
    String colorTypeName(SkColorType);
    PassRefPtr<JSONObject> objectForBitmapData(const SkBitmap&);
    PassRefPtr<JSONObject> objectForSkBitmap(const SkBitmap&);
    PassRefPtr<JSONObject> objectForSkShader(const SkShader&);
    String stringForSkColor(const SkColor&);
    void appendFlagToString(String* flagsString, bool isSet, const String& name);
    String stringForSkPaintFlags(const SkPaint&);
    String filterLevelName(SkPaint::FilterLevel);
    String textAlignName(SkPaint::Align);
    String strokeCapName(SkPaint::Cap);
    String strokeJoinName(SkPaint::Join);
    String styleName(SkPaint::Style);
    String textEncodingName(SkPaint::TextEncoding);
    String hintingName(SkPaint::Hinting);
    PassRefPtr<JSONObject> objectForSkPaint(const SkPaint&);
    PassRefPtr<JSONArray> arrayForSkMatrix(const SkMatrix&);
    PassRefPtr<JSONArray> arrayForSkScalars(size_t n, const SkScalar scalars[]);
    String regionOpName(SkRegion::Op);
    String saveFlagsToString(SkCanvas::SaveFlags);
    String textEncodingCanonicalName(SkPaint::TextEncoding);
    String stringForUTFText(const void* text, size_t length, SkPaint::TextEncoding);
    String stringForText(const void* text, size_t byteLength, const SkPaint&);
};

} // namespace blink

#endif  // SKY_ENGINE_PLATFORM_GRAPHICS_LOGGINGCANVAS_H_
