/*
 * 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.
 */

#include "sky/engine/config.h"
#include "sky/engine/platform/graphics/LoggingCanvas.h"

#include "platform/image-encoders/skia/PNGImageEncoder.h"
#include "sky/engine/wtf/HexNumber.h"
#include "sky/engine/wtf/text/Base64.h"
#include "sky/engine/wtf/text/TextEncoding.h"
#include "third_party/skia/include/core/SkPicture.h"

namespace blink {

class AutoLogger {
public:
    explicit AutoLogger(LoggingCanvas*);
    PassRefPtr<JSONObject> logItem(const String& name);
    PassRefPtr<JSONObject> logItemWithParams(const String& name);
    ~AutoLogger();

private:
    LoggingCanvas* m_canvas;
    RefPtr<JSONObject> m_logItem;
};

AutoLogger::AutoLogger(LoggingCanvas* loggingCanvas) : m_canvas(loggingCanvas)
{
    loggingCanvas->m_depthCount++;
}

PassRefPtr<JSONObject> AutoLogger::logItem(const String& name)
{
    RefPtr<JSONObject> item = JSONObject::create();
    item->setString("method", name);
    m_logItem = item;
    return item.release();
}

PassRefPtr<JSONObject> AutoLogger::logItemWithParams(const String& name)
{
    RefPtr<JSONObject> item = logItem(name);
    RefPtr<JSONObject> params = JSONObject::create();
    item->setObject("params", params);
    return params.release();
}

AutoLogger::~AutoLogger()
{
    m_canvas->m_depthCount--;
    if (!m_canvas->m_depthCount)
        m_canvas->m_log->pushObject(m_logItem);
}

LoggingCanvas::LoggingCanvas(int width, int height) : InterceptingCanvas(width, height)
{
    m_log = JSONArray::create();
}

void LoggingCanvas::drawPaint(const SkPaint& paint)
{
    AutoLogger logger(this);
    logger.logItemWithParams("drawPaint")->setObject("paint", objectForSkPaint(paint));
    this->SkCanvas::drawPaint(paint);
}

void LoggingCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("drawPoints");
    params->setString("pointMode", pointModeName(mode));
    params->setArray("points", arrayForSkPoints(count, pts));
    params->setObject("paint", objectForSkPaint(paint));
    this->SkCanvas::drawPoints(mode, count, pts, paint);
}

void LoggingCanvas::drawRect(const SkRect& rect, const SkPaint& paint)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("drawRect");
    params->setObject("rect", objectForSkRect(rect));
    params->setObject("paint", objectForSkPaint(paint));
    this->SkCanvas::drawRect(rect, paint);
}

void LoggingCanvas::drawOval(const SkRect& oval, const SkPaint& paint)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("drawOval");
    params->setObject("oval", objectForSkRect(oval));
    params->setObject("paint", objectForSkPaint(paint));
    this->SkCanvas::drawOval(oval, paint);
}

void LoggingCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("drawRRect");
    params->setObject("rrect", objectForSkRRect(rrect));
    params->setObject("paint", objectForSkPaint(paint));
    this->SkCanvas::drawRRect(rrect, paint);
}

void LoggingCanvas::drawPath(const SkPath& path, const SkPaint& paint)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("drawPath");
    params->setObject("path", objectForSkPath(path));
    params->setObject("paint", objectForSkPaint(paint));
    this->SkCanvas::drawPath(path, paint);
}

void LoggingCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, const SkPaint* paint)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("drawBitmap");
    params->setNumber("left", left);
    params->setNumber("top", top);
    params->setObject("bitmap", objectForSkBitmap(bitmap));
    params->setObject("paint", objectForSkPaint(*paint));
    this->SkCanvas::drawBitmap(bitmap, left, top, paint);
}

void LoggingCanvas::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, const SkPaint* paint, DrawBitmapRectFlags flags)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("drawBitmapRectToRect");
    params->setObject("bitmap", objectForSkBitmap(bitmap));
    params->setObject("src", objectForSkRect(*src));
    params->setObject("dst", objectForSkRect(dst));
    params->setObject("paint", objectForSkPaint(*paint));
    params->setNumber("flags", flags);
    this->SkCanvas::drawBitmapRectToRect(bitmap, src, dst, paint, flags);
}

void LoggingCanvas::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m, const SkPaint* paint)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("drawBitmapMatrix");
    params->setObject("bitmap", objectForSkBitmap(bitmap));
    params->setArray("matrix", arrayForSkMatrix(m));
    params->setObject("paint", objectForSkPaint(*paint));
    this->SkCanvas::drawBitmapMatrix(bitmap, m, paint);
}

void LoggingCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, const SkPaint* paint)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("drawBitmapNine");
    params->setObject("bitmap", objectForSkBitmap(bitmap));
    params->setObject("center", objectForSkIRect(center));
    params->setObject("dst", objectForSkRect(dst));
    params->setObject("paint", objectForSkPaint(*paint));
    this->SkCanvas::drawBitmapNine(bitmap, center, dst, paint);
}

void LoggingCanvas::drawSprite(const SkBitmap& bitmap, int left, int top, const SkPaint* paint)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("drawSprite");
    params->setObject("bitmap", objectForSkBitmap(bitmap));
    params->setNumber("left", left);
    params->setNumber("top", top);
    params->setObject("paint", objectForSkPaint(*paint));
    this->SkCanvas::drawSprite(bitmap, left, top, paint);
}

void LoggingCanvas::drawVertices(VertexMode vmode, int vertexCount, const SkPoint vertices[], const SkPoint texs[], const SkColor colors[], SkXfermode* xmode,
    const uint16_t indices[], int indexCount, const SkPaint& paint)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("drawVertices");
    params->setObject("paint", objectForSkPaint(paint));
    this->SkCanvas::drawVertices(vmode, vertexCount, vertices, texs, colors, xmode, indices, indexCount, paint);
}

void LoggingCanvas::drawData(const void* data, size_t length)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("drawData");
    params->setNumber("length", length);
    this->SkCanvas::drawData(data, length);
}

void LoggingCanvas::beginCommentGroup(const char* description)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("beginCommentGroup");
    params->setString("description", description);
    this->SkCanvas::beginCommentGroup(description);
}

void LoggingCanvas::addComment(const char* keyword, const char* value)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("addComment");
    params->setString("key", keyword);
    params->setString("value", value);
    this->SkCanvas::addComment(keyword, value);
}

void LoggingCanvas::endCommentGroup()
{
    AutoLogger logger(this);
    logger.logItem("endCommentGroup");
    this->SkCanvas::endCommentGroup();
}

void LoggingCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("drawDRRect");
    params->setObject("outer", objectForSkRRect(outer));
    params->setObject("inner", objectForSkRRect(inner));
    params->setObject("paint", objectForSkPaint(paint));
    this->SkCanvas::onDrawDRRect(outer, inner, paint);
}

void LoggingCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, const SkPaint& paint)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("drawText");
    params->setString("text", stringForText(text, byteLength, paint));
    params->setNumber("x", x);
    params->setNumber("y", y);
    params->setObject("paint", objectForSkPaint(paint));
    this->SkCanvas::onDrawText(text, byteLength, x, y, paint);
}

void LoggingCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkPaint& paint)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("drawPosText");
    params->setString("text", stringForText(text, byteLength, paint));
    size_t pointsCount = paint.countText(text, byteLength);
    params->setArray("pos", arrayForSkPoints(pointsCount, pos));
    params->setObject("paint", objectForSkPaint(paint));
    this->SkCanvas::onDrawPosText(text, byteLength, pos, paint);
}

void LoggingCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkPaint& paint)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("drawPosTextH");
    params->setString("text", stringForText(text, byteLength, paint));
    size_t pointsCount = paint.countText(text, byteLength);
    params->setArray("xpos", arrayForSkScalars(pointsCount, xpos));
    params->setNumber("constY", constY);
    params->setObject("paint", objectForSkPaint(paint));
    this->SkCanvas::onDrawPosTextH(text, byteLength, xpos, constY, paint);
}

void LoggingCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, const SkMatrix* matrix, const SkPaint& paint)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("drawTextOnPath");
    params->setString("text", stringForText(text, byteLength, paint));
    params->setObject("path", objectForSkPath(path));
    params->setArray("matrix", arrayForSkMatrix(*matrix));
    params->setObject("paint", objectForSkPaint(paint));
    this->SkCanvas::onDrawTextOnPath(text, byteLength, path, matrix, paint);
}

void LoggingCanvas::onPushCull(const SkRect& cullRect)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("pushCull");
    params->setObject("cullRect", objectForSkRect(cullRect));
    this->SkCanvas::onPushCull(cullRect);
}

void LoggingCanvas::onPopCull()
{
    AutoLogger logger(this);
    logger.logItem("popCull");
    this->SkCanvas::onPopCull();
}

void LoggingCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle style)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("clipRect");
    params->setObject("rect", objectForSkRect(rect));
    params->setString("SkRegion::Op", regionOpName(op));
    params->setBoolean("softClipEdgeStyle", kSoft_ClipEdgeStyle == style);
    this->SkCanvas::onClipRect(rect, op, style);
}

void LoggingCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle style)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("clipRRect");
    params->setObject("rrect", objectForSkRRect(rrect));
    params->setString("SkRegion::Op", regionOpName(op));
    params->setBoolean("softClipEdgeStyle", kSoft_ClipEdgeStyle == style);
    this->SkCanvas::onClipRRect(rrect, op, style);
}

void LoggingCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle style)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("clipPath");
    params->setObject("path", objectForSkPath(path));
    params->setString("SkRegion::Op", regionOpName(op));
    params->setBoolean("softClipEdgeStyle", kSoft_ClipEdgeStyle == style);
    this->SkCanvas::onClipPath(path, op, style);
}

void LoggingCanvas::onClipRegion(const SkRegion& region, SkRegion::Op op)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("clipRegion");
    params->setString("op", regionOpName(op));
    this->SkCanvas::onClipRegion(region, op);
}

void LoggingCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
{
    AutoLogger logger(this);
    logger.logItemWithParams("drawPicture")->setObject("picture", objectForSkPicture(*picture));
    this->SkCanvas::onDrawPicture(picture, matrix, paint);
}

void LoggingCanvas::didSetMatrix(const SkMatrix& matrix)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("setMatrix");
    params->setArray("matrix", arrayForSkMatrix(matrix));
    this->SkCanvas::didSetMatrix(matrix);
}

void LoggingCanvas::didConcat(const SkMatrix& matrix)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params;

    switch (matrix.getType()) {
    case SkMatrix::kTranslate_Mask:
        params = logger.logItemWithParams("translate");
        params->setNumber("dx", matrix.getTranslateX());
        params->setNumber("dy", matrix.getTranslateY());
        break;

    case SkMatrix::kScale_Mask:
        params = logger.logItemWithParams("scale");
        params->setNumber("scaleX", matrix.getScaleX());
        params->setNumber("scaleY", matrix.getScaleY());
        break;

    default:
        params = logger.logItemWithParams("concat");
        params->setArray("matrix", arrayForSkMatrix(matrix));
    }
    this->SkCanvas::didConcat(matrix);
}

void LoggingCanvas::willSave()
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItem("save");
    this->SkCanvas::willSave();
}

SkCanvas::SaveLayerStrategy LoggingCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags)
{
    AutoLogger logger(this);
    RefPtr<JSONObject> params = logger.logItemWithParams("saveLayer");
    if (bounds)
        params->setObject("bounds", objectForSkRect(*bounds));
    params->setObject("paint", objectForSkPaint(*paint));
    params->setString("saveFlags", saveFlagsToString(flags));
    return this->SkCanvas::willSaveLayer(bounds, paint, flags);
}

void LoggingCanvas::willRestore()
{
    AutoLogger logger(this);
    logger.logItem("restore");
    this->SkCanvas::willRestore();
}

PassRefPtr<JSONArray> LoggingCanvas::log()
{
    return m_log;
}

PassRefPtr<JSONObject> LoggingCanvas::objectForSkRect(const SkRect& rect)
{
    RefPtr<JSONObject> rectItem = JSONObject::create();
    rectItem->setNumber("left", rect.left());
    rectItem->setNumber("top", rect.top());
    rectItem->setNumber("right", rect.right());
    rectItem->setNumber("bottom", rect.bottom());
    return rectItem.release();
}

PassRefPtr<JSONObject> LoggingCanvas::objectForSkIRect(const SkIRect& rect)
{
    RefPtr<JSONObject> rectItem = JSONObject::create();
    rectItem->setNumber("left", rect.left());
    rectItem->setNumber("top", rect.top());
    rectItem->setNumber("right", rect.right());
    rectItem->setNumber("bottom", rect.bottom());
    return rectItem.release();
}

String LoggingCanvas::pointModeName(PointMode mode)
{
    switch (mode) {
    case SkCanvas::kPoints_PointMode: return "Points";
    case SkCanvas::kLines_PointMode: return "Lines";
    case SkCanvas::kPolygon_PointMode: return "Polygon";
    default:
        ASSERT_NOT_REACHED();
        return "?";
    };
}

PassRefPtr<JSONObject> LoggingCanvas::objectForSkPoint(const SkPoint& point)
{
    RefPtr<JSONObject> pointItem = JSONObject::create();
    pointItem->setNumber("x", point.x());
    pointItem->setNumber("y", point.y());
    return pointItem.release();
}

PassRefPtr<JSONArray> LoggingCanvas::arrayForSkPoints(size_t count, const SkPoint points[])
{
    RefPtr<JSONArray> pointsArrayItem = JSONArray::create();
    for (size_t i = 0; i < count; ++i)
        pointsArrayItem->pushObject(objectForSkPoint(points[i]));
    return pointsArrayItem.release();
}

PassRefPtr<JSONObject> LoggingCanvas::objectForSkPicture(const SkPicture& picture)
{
    RefPtr<JSONObject> pictureItem = JSONObject::create();
    pictureItem->setNumber("width", picture.width());
    pictureItem->setNumber("height", picture.height());
    return pictureItem.release();
}

PassRefPtr<JSONObject> LoggingCanvas::objectForRadius(const SkRRect& rrect, SkRRect::Corner corner)
{
    RefPtr<JSONObject> radiusItem = JSONObject::create();
    SkVector radius = rrect.radii(corner);
    radiusItem->setNumber("xRadius", radius.x());
    radiusItem->setNumber("yRadius", radius.y());
    return radiusItem.release();
}

String LoggingCanvas::rrectTypeName(SkRRect::Type type)
{
    switch (type) {
    case SkRRect::kEmpty_Type: return "Empty";
    case SkRRect::kRect_Type: return "Rect";
    case SkRRect::kOval_Type: return "Oval";
    case SkRRect::kSimple_Type: return "Simple";
    case SkRRect::kNinePatch_Type: return "Nine-patch";
    case SkRRect::kComplex_Type: return "Complex";
    default:
        ASSERT_NOT_REACHED();
        return "?";
    };
}

String LoggingCanvas::radiusName(SkRRect::Corner corner)
{
    switch (corner) {
    case SkRRect::kUpperLeft_Corner: return "upperLeftRadius";
    case SkRRect::kUpperRight_Corner: return "upperRightRadius";
    case SkRRect::kLowerRight_Corner: return "lowerRightRadius";
    case SkRRect::kLowerLeft_Corner: return "lowerLeftRadius";
    default:
        ASSERT_NOT_REACHED();
        return "?";
    }
}

PassRefPtr<JSONObject> LoggingCanvas::objectForSkRRect(const SkRRect& rrect)
{
    RefPtr<JSONObject> rrectItem = JSONObject::create();
    rrectItem->setString("type", rrectTypeName(rrect.type()));
    rrectItem->setNumber("left", rrect.rect().left());
    rrectItem->setNumber("top", rrect.rect().top());
    rrectItem->setNumber("right", rrect.rect().right());
    rrectItem->setNumber("bottom", rrect.rect().bottom());
    for (int i = 0; i < 4; ++i)
        rrectItem->setObject(radiusName((SkRRect::Corner) i), objectForRadius(rrect, (SkRRect::Corner) i));
    return rrectItem.release();
}

String LoggingCanvas::fillTypeName(SkPath::FillType type)
{
    switch (type) {
    case SkPath::kWinding_FillType: return "Winding";
    case SkPath::kEvenOdd_FillType: return "EvenOdd";
    case SkPath::kInverseWinding_FillType: return "InverseWinding";
    case SkPath::kInverseEvenOdd_FillType: return "InverseEvenOdd";
    default:
        ASSERT_NOT_REACHED();
        return "?";
    };
}

String LoggingCanvas::convexityName(SkPath::Convexity convexity)
{
    switch (convexity) {
    case SkPath::kUnknown_Convexity: return "Unknown";
    case SkPath::kConvex_Convexity: return "Convex";
    case SkPath::kConcave_Convexity: return "Concave";
    default:
        ASSERT_NOT_REACHED();
        return "?";
    };
}

String LoggingCanvas::verbName(SkPath::Verb verb)
{
    switch (verb) {
    case SkPath::kMove_Verb: return "Move";
    case SkPath::kLine_Verb: return "Line";
    case SkPath::kQuad_Verb: return "Quad";
    case SkPath::kConic_Verb: return "Conic";
    case SkPath::kCubic_Verb: return "Cubic";
    case SkPath::kClose_Verb: return "Close";
    case SkPath::kDone_Verb: return "Done";
    default:
        ASSERT_NOT_REACHED();
        return "?";
    };
}

LoggingCanvas::VerbParams LoggingCanvas::segmentParams(SkPath::Verb verb)
{
    switch (verb) {
    case SkPath::kMove_Verb: return VerbParams("Move", 1, 0);
    case SkPath::kLine_Verb: return VerbParams("Line", 1, 1);
    case SkPath::kQuad_Verb: return VerbParams("Quad", 2, 1);
    case SkPath::kConic_Verb: return VerbParams("Conic", 2, 1);
    case SkPath::kCubic_Verb: return VerbParams("Cubic", 3, 1);
    case SkPath::kClose_Verb: return VerbParams("Close", 0, 0);
    case SkPath::kDone_Verb: return VerbParams("Done", 0, 0);
    default:
        ASSERT_NOT_REACHED();
        return VerbParams("?", 0, 0);
    };
}

PassRefPtr<JSONObject> LoggingCanvas::objectForSkPath(const SkPath& path)
{
    RefPtr<JSONObject> pathItem = JSONObject::create();
    pathItem->setString("fillType", fillTypeName(path.getFillType()));
    pathItem->setString("convexity", convexityName(path.getConvexity()));
    pathItem->setBoolean("isRect", path.isRect(0));
    SkPath::Iter iter(path, false);
    SkPoint points[4];
    RefPtr<JSONArray> pathPointsArray = JSONArray::create();
    for (SkPath::Verb verb = iter.next(points, false); verb != SkPath::kDone_Verb; verb = iter.next(points, false)) {
        VerbParams verbParams = segmentParams(verb);
        RefPtr<JSONObject> pathPointItem = JSONObject::create();
        pathPointItem->setString("verb", verbParams.name);
        ASSERT(verbParams.pointCount + verbParams.pointOffset <= WTF_ARRAY_LENGTH(points));
        pathPointItem->setArray("points", arrayForSkPoints(verbParams.pointCount, points + verbParams.pointOffset));
        if (SkPath::kConic_Verb == verb)
            pathPointItem->setNumber("conicWeight", iter.conicWeight());
        pathPointsArray->pushObject(pathPointItem);
    }
    pathItem->setArray("pathPoints", pathPointsArray);
    pathItem->setObject("bounds", objectForSkRect(path.getBounds()));
    return pathItem.release();
}

String LoggingCanvas::colorTypeName(SkColorType colorType)
{
    switch (colorType) {
    case kUnknown_SkColorType: return "None";
    case kAlpha_8_SkColorType: return "A8";
    case kIndex_8_SkColorType: return "Index8";
    case kRGB_565_SkColorType: return "RGB565";
    case kARGB_4444_SkColorType: return "ARGB4444";
    case kN32_SkColorType: return "ARGB8888";
    default:
        ASSERT_NOT_REACHED();
        return "?";
    };
}

PassRefPtr<JSONObject> LoggingCanvas::objectForBitmapData(const SkBitmap& bitmap)
{
    RefPtr<JSONObject> dataItem = JSONObject::create();
    Vector<unsigned char> output;
    PNGImageEncoder::encode(bitmap, &output);
    dataItem->setString("base64", WTF::base64Encode(reinterpret_cast<char*>(output.data()), output.size()));
    dataItem->setString("mimeType", "image/png");
    return dataItem.release();
}

PassRefPtr<JSONObject> LoggingCanvas::objectForSkBitmap(const SkBitmap& bitmap)
{
    RefPtr<JSONObject> bitmapItem = JSONObject::create();
    bitmapItem->setNumber("width", bitmap.width());
    bitmapItem->setNumber("height", bitmap.height());
    bitmapItem->setString("config", colorTypeName(bitmap.colorType()));
    bitmapItem->setBoolean("opaque", bitmap.isOpaque());
    bitmapItem->setBoolean("immutable", bitmap.isImmutable());
    bitmapItem->setBoolean("volatile", bitmap.isVolatile());
    bitmapItem->setNumber("genID", bitmap.getGenerationID());
    bitmapItem->setObject("data", objectForBitmapData(bitmap));
    return bitmapItem.release();
}

PassRefPtr<JSONObject> LoggingCanvas::objectForSkShader(const SkShader& shader)
{
    RefPtr<JSONObject> shaderItem = JSONObject::create();
    const SkMatrix localMatrix = shader.getLocalMatrix();
    if (!localMatrix.isIdentity())
        shaderItem->setArray("localMatrix", arrayForSkMatrix(localMatrix));
    return shaderItem.release();
}

String LoggingCanvas::stringForSkColor(const SkColor& color)
{
    String colorString = "#";
    appendUnsignedAsHex(color, colorString);
    return colorString;
}

void LoggingCanvas::appendFlagToString(String* flagsString, bool isSet, const String& name)
{
    if (!isSet)
        return;
    if (flagsString->length())
        flagsString->append("|");
    flagsString->append(name);
}

String LoggingCanvas::stringForSkPaintFlags(const SkPaint& paint)
{
    if (!paint.getFlags())
        return "none";
    String flagsString = "";
    appendFlagToString(&flagsString, paint.isAntiAlias(), "AntiAlias");
    appendFlagToString(&flagsString, paint.isDither(), "Dither");
    appendFlagToString(&flagsString, paint.isUnderlineText(), "UnderlinText");
    appendFlagToString(&flagsString, paint.isStrikeThruText(), "StrikeThruText");
    appendFlagToString(&flagsString, paint.isFakeBoldText(), "FakeBoldText");
    appendFlagToString(&flagsString, paint.isLinearText(), "LinearText");
    appendFlagToString(&flagsString, paint.isSubpixelText(), "SubpixelText");
    appendFlagToString(&flagsString, paint.isDevKernText(), "DevKernText");
    appendFlagToString(&flagsString, paint.isLCDRenderText(), "LCDRenderText");
    appendFlagToString(&flagsString, paint.isEmbeddedBitmapText(), "EmbeddedBitmapText");
    appendFlagToString(&flagsString, paint.isAutohinted(), "Autohinted");
    appendFlagToString(&flagsString, paint.isVerticalText(), "VerticalText");
    appendFlagToString(&flagsString, paint.getFlags() & SkPaint::kGenA8FromLCD_Flag, "GenA8FromLCD");
    return flagsString;
}

String LoggingCanvas::filterLevelName(SkPaint::FilterLevel filterLevel)
{
    switch (filterLevel) {
    case SkPaint::kNone_FilterLevel: return "None";
    case SkPaint::kLow_FilterLevel: return "Low";
    case SkPaint::kMedium_FilterLevel: return "Medium";
    case SkPaint::kHigh_FilterLevel: return "High";
    default:
        ASSERT_NOT_REACHED();
        return "?";
    };
}

String LoggingCanvas::textAlignName(SkPaint::Align align)
{
    switch (align) {
    case SkPaint::kLeft_Align: return "Left";
    case SkPaint::kCenter_Align: return "Center";
    case SkPaint::kRight_Align: return "Right";
    default:
        ASSERT_NOT_REACHED();
        return "?";
    };
}

String LoggingCanvas::strokeCapName(SkPaint::Cap cap)
{
    switch (cap) {
    case SkPaint::kButt_Cap: return "Butt";
    case SkPaint::kRound_Cap: return "Round";
    case SkPaint::kSquare_Cap: return "Square";
    default:
        ASSERT_NOT_REACHED();
        return "?";
    };
}

String LoggingCanvas::strokeJoinName(SkPaint::Join join)
{
    switch (join) {
    case SkPaint::kMiter_Join: return "Miter";
    case SkPaint::kRound_Join: return "Round";
    case SkPaint::kBevel_Join: return "Bevel";
    default:
        ASSERT_NOT_REACHED();
        return "?";
    };
}

String LoggingCanvas::styleName(SkPaint::Style style)
{
    switch (style) {
    case SkPaint::kFill_Style: return "Fill";
    case SkPaint::kStroke_Style: return "Stroke";
    case SkPaint::kStrokeAndFill_Style: return "StrokeAndFill";
    default:
        ASSERT_NOT_REACHED();
        return "?";
    };
}

String LoggingCanvas::textEncodingName(SkPaint::TextEncoding encoding)
{
    switch (encoding) {
    case SkPaint::kUTF8_TextEncoding: return "UTF-8";
    case SkPaint::kUTF16_TextEncoding: return "UTF-16";
    case SkPaint::kUTF32_TextEncoding: return "UTF-32";
    case SkPaint::kGlyphID_TextEncoding: return "GlyphID";
    default:
        ASSERT_NOT_REACHED();
        return "?";
    };
}

String LoggingCanvas::hintingName(SkPaint::Hinting hinting)
{
    switch (hinting) {
    case SkPaint::kNo_Hinting: return "None";
    case SkPaint::kSlight_Hinting: return "Slight";
    case SkPaint::kNormal_Hinting: return "Normal";
    case SkPaint::kFull_Hinting: return "Full";
    default:
        ASSERT_NOT_REACHED();
        return "?";
    };
}

PassRefPtr<JSONObject> LoggingCanvas::objectForSkPaint(const SkPaint& paint)
{
    RefPtr<JSONObject> paintItem = JSONObject::create();
    paintItem->setNumber("textSize", paint.getTextSize());
    paintItem->setNumber("textScaleX", paint.getTextScaleX());
    paintItem->setNumber("textSkewX", paint.getTextSkewX());
    if (SkShader* shader = paint.getShader())
        paintItem->setObject("shader", objectForSkShader(*shader));
    paintItem->setString("color", stringForSkColor(paint.getColor()));
    paintItem->setNumber("strokeWidth", paint.getStrokeWidth());
    paintItem->setNumber("strokeMiter", paint.getStrokeMiter());
    paintItem->setString("flags", stringForSkPaintFlags(paint));
    paintItem->setString("filterLevel", filterLevelName(paint.getFilterLevel()));
    paintItem->setString("textAlign", textAlignName(paint.getTextAlign()));
    paintItem->setString("strokeCap", strokeCapName(paint.getStrokeCap()));
    paintItem->setString("strokeJoin", strokeJoinName(paint.getStrokeJoin()));
    paintItem->setString("styleName", styleName(paint.getStyle()));
    paintItem->setString("textEncoding", textEncodingName(paint.getTextEncoding()));
    paintItem->setString("hinting", hintingName(paint.getHinting()));
    return paintItem.release();
}

PassRefPtr<JSONArray> LoggingCanvas::arrayForSkMatrix(const SkMatrix& matrix)
{
    RefPtr<JSONArray> matrixArray = JSONArray::create();
    for (int i = 0; i < 9; ++i)
        matrixArray->pushNumber(matrix[i]);
    return matrixArray.release();
}

PassRefPtr<JSONArray> LoggingCanvas::arrayForSkScalars(size_t n, const SkScalar scalars[])
{
    RefPtr<JSONArray> scalarsArray = JSONArray::create();
    for (size_t i = 0; i < n; ++i)
        scalarsArray->pushNumber(scalars[i]);
    return scalarsArray.release();
}

String LoggingCanvas::regionOpName(SkRegion::Op op)
{
    switch (op) {
    case SkRegion::kDifference_Op: return "kDifference_Op";
    case SkRegion::kIntersect_Op: return "kIntersect_Op";
    case SkRegion::kUnion_Op: return "kUnion_Op";
    case SkRegion::kXOR_Op: return "kXOR_Op";
    case SkRegion::kReverseDifference_Op: return "kReverseDifference_Op";
    case SkRegion::kReplace_Op: return "kReplace_Op";
    default: return "Unknown type";
    };
}

String LoggingCanvas::saveFlagsToString(SkCanvas::SaveFlags flags)
{
    String flagsString = "";
    if (flags & SkCanvas::kHasAlphaLayer_SaveFlag)
        flagsString.append("kHasAlphaLayer_SaveFlag ");
    if (flags & SkCanvas::kFullColorLayer_SaveFlag)
        flagsString.append("kFullColorLayer_SaveFlag ");
    if (flags & SkCanvas::kClipToLayer_SaveFlag)
        flagsString.append("kClipToLayer_SaveFlag ");
    return flagsString;
}

String LoggingCanvas::textEncodingCanonicalName(SkPaint::TextEncoding encoding)
{
    String name = textEncodingName(encoding);
    if (encoding == SkPaint::kUTF16_TextEncoding || encoding == SkPaint::kUTF32_TextEncoding)
        name.append("LE");
    return name;
}

String LoggingCanvas::stringForUTFText(const void* text, size_t length, SkPaint::TextEncoding encoding)
{
    return WTF::TextEncoding(textEncodingCanonicalName(encoding)).decode((const char*)text, length);
}

String LoggingCanvas::stringForText(const void* text, size_t byteLength, const SkPaint& paint)
{
    SkPaint::TextEncoding encoding = paint.getTextEncoding();
    switch (encoding) {
    case SkPaint::kUTF8_TextEncoding:
    case SkPaint::kUTF16_TextEncoding:
    case SkPaint::kUTF32_TextEncoding:
        return stringForUTFText(text, byteLength, encoding);
    case SkPaint::kGlyphID_TextEncoding: {
        WTF::Vector<SkUnichar> dataVector(byteLength / 2);
        SkUnichar* textData = dataVector.data();
        paint.glyphsToUnichars(static_cast<const uint16_t*>(text), byteLength / 2, textData);
        return WTF::UTF32LittleEndianEncoding().decode(reinterpret_cast<const char*>(textData), byteLength * 2);
    }
    default:
        ASSERT_NOT_REACHED();
        return "?";
    }
}

} // namespace blink
