/*
 * 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::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::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)
{
    const SkIRect bounds = picture.cullRect().roundOut();
    RefPtr<JSONObject> pictureItem = JSONObject::create();
    pictureItem->setNumber("width", bounds.width());
    pictureItem->setNumber("height", bounds.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
