/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkData.h"
#include "SkDumpCanvas.h"
#include "SkImage.h"
#include "SkPatchUtils.h"
#include "SkPicture.h"
#include "SkPixelRef.h"
#include "SkRegion.h"
#include "SkRRect.h"
#include "SkString.h"
#include "SkTextBlob.h"
#include <stdarg.h>
#include <stdio.h>

// needed just to know that these are all subclassed from SkFlattenable
#include "SkShader.h"
#include "SkPathEffect.h"
#include "SkColorFilter.h"
#include "SkPathEffect.h"
#include "SkMaskFilter.h"

static void toString(const SkRect& r, SkString* str) {
    str->appendf("[%g,%g %g:%g]",
                 SkScalarToFloat(r.fLeft), SkScalarToFloat(r.fTop),
                 SkScalarToFloat(r.width()), SkScalarToFloat(r.height()));
}

static void toString(const SkIRect& r, SkString* str) {
    str->appendf("[%d,%d %d:%d]", r.fLeft, r.fTop, r.width(), r.height());
}

static void toString(const SkRRect& rrect, SkString* str) {
    SkRect r = rrect.getBounds();
    str->appendf("[%g,%g %g:%g]",
                 SkScalarToFloat(r.fLeft), SkScalarToFloat(r.fTop),
                 SkScalarToFloat(r.width()), SkScalarToFloat(r.height()));
    if (rrect.isOval()) {
        str->append("()");
    } else if (rrect.isSimple()) {
        const SkVector& rad = rrect.getSimpleRadii();
        str->appendf("(%g,%g)", rad.x(), rad.y());
    } else if (rrect.isComplex()) {
        SkVector radii[4] = {
            rrect.radii(SkRRect::kUpperLeft_Corner),
            rrect.radii(SkRRect::kUpperRight_Corner),
            rrect.radii(SkRRect::kLowerRight_Corner),
            rrect.radii(SkRRect::kLowerLeft_Corner),
        };
        str->appendf("(%g,%g %g,%g %g,%g %g,%g)",
                     radii[0].x(), radii[0].y(),
                     radii[1].x(), radii[1].y(),
                     radii[2].x(), radii[2].y(),
                     radii[3].x(), radii[3].y());
    }
}

static void dumpVerbs(const SkPath& path, SkString* str) {
    SkPath::Iter iter(path, false);
    SkPoint pts[4];
    for (;;) {
        switch (iter.next(pts, false)) {
            case SkPath::kMove_Verb:
                str->appendf(" M%g,%g", pts[0].fX, pts[0].fY);
                break;
            case SkPath::kLine_Verb:
                str->appendf(" L%g,%g", pts[0].fX, pts[0].fY);
                break;
            case SkPath::kQuad_Verb:
                str->appendf(" Q%g,%g,%g,%g", pts[1].fX, pts[1].fY,
                             pts[2].fX, pts[2].fY);
                break;
            case SkPath::kCubic_Verb:
                str->appendf(" C%g,%g,%g,%g,%g,%g", pts[1].fX, pts[1].fY,
                             pts[2].fX, pts[2].fY, pts[3].fX, pts[3].fY);
                break;
            case SkPath::kClose_Verb:
                str->append("X");
                break;
            case SkPath::kDone_Verb:
                return;
            case SkPath::kConic_Verb:
                SkASSERT(0);
                break;
        }
    }
}

static void toString(const SkPath& path, SkString* str) {
    if (path.isEmpty()) {
        str->append("path:empty");
    } else {
        toString(path.getBounds(), str);
#if 1
        SkString s;
        dumpVerbs(path, &s);
        str->append(s.c_str());
#endif
        str->append("]");
        str->prepend("path:[");
    }
}

static const char* toString(SkClipOp op) {
    static const char* gOpNames[] = {
        "DIFF", "SECT", "UNION", "XOR", "RDIFF", "REPLACE"
    };
    return gOpNames[static_cast<int>(op)];
}

static void toString(const SkRegion& rgn, SkString* str) {
    str->append("Region:[");
    toString(rgn.getBounds(), str);
    str->append("]");
    if (rgn.isComplex()) {
        str->append(".complex");
    }
}

static const char* toString(SkVertices::VertexMode vm) {
    static const char* gVMNames[] = {
        "TRIANGLES", "STRIP", "FAN"
    };
    return gVMNames[vm];
}

static const char* toString(SkCanvas::PointMode pm) {
    static const char* gPMNames[] = {
        "POINTS", "LINES", "POLYGON"
    };
    return gPMNames[pm];
}

static void toString(const void* text, size_t byteLen, SkPaint::TextEncoding enc,
                     SkString* str) {
    // FIXME: this code appears to be untested - and probably unused - and probably wrong
    switch (enc) {
        case SkPaint::kUTF8_TextEncoding:
            str->appendf("\"%.*s\"%s", (int)SkTMax<size_t>(byteLen, 32), (const char*) text,
                        byteLen > 32 ? "..." : "");
            break;
        case SkPaint::kUTF16_TextEncoding:
            str->appendf("\"%.*ls\"%s", (int)SkTMax<size_t>(byteLen, 32), (const wchar_t*) text,
                        byteLen > 64 ? "..." : "");
            break;
        case SkPaint::kUTF32_TextEncoding:
            str->appendf("\"%.*ls\"%s", (int)SkTMax<size_t>(byteLen, 32), (const wchar_t*) text,
                        byteLen > 128 ? "..." : "");
            break;
        case SkPaint::kGlyphID_TextEncoding:
            str->append("<glyphs>");
            break;

        default:
            SkASSERT(false);
            break;
    }
}

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

#define WIDE_OPEN   16384

SkDumpCanvas::SkDumpCanvas(Dumper* dumper) : INHERITED(WIDE_OPEN, WIDE_OPEN) {
    fNestLevel = 0;
    SkSafeRef(dumper);
    fDumper = dumper;
}

SkDumpCanvas::~SkDumpCanvas() {
    SkSafeUnref(fDumper);
}

void SkDumpCanvas::dump(Verb verb, const SkPaint* paint,
                        const char format[], ...) {
    static const size_t BUFFER_SIZE = 1024;

    char    buffer[BUFFER_SIZE];
    va_list args;
    va_start(args, format);
    vsnprintf(buffer, BUFFER_SIZE, format, args);
    va_end(args);

    if (fDumper) {
        fDumper->dump(this, verb, buffer, paint);
    }
}

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

void SkDumpCanvas::willSave() {
    this->dump(kSave_Verb, nullptr, "save()");
    this->INHERITED::willSave();
}

SkCanvas::SaveLayerStrategy SkDumpCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
    SkString str;
    str.printf("saveLayer(0x%X)", rec.fSaveLayerFlags);
    if (rec.fBounds) {
        str.append(" bounds");
        toString(*rec.fBounds, &str);
    }
    const SkPaint* paint = rec.fPaint;
    if (paint) {
        if (paint->getAlpha() != 0xFF) {
            str.appendf(" alpha:0x%02X", paint->getAlpha());
        }
        if (!paint->isSrcOver()) {
            str.appendf(" blendmode:%d", (int)paint->getBlendMode());
        }
    }
    this->dump(kSave_Verb, paint, str.c_str());
    return this->INHERITED::getSaveLayerStrategy(rec);
}

void SkDumpCanvas::willRestore() {
    this->dump(kRestore_Verb, nullptr, "restore");
    this->INHERITED::willRestore();
}

void SkDumpCanvas::didConcat(const SkMatrix& matrix) {
    SkString str;

    switch (matrix.getType()) {
        case SkMatrix::kTranslate_Mask:
            this->dump(kMatrix_Verb, nullptr, "translate(%g %g)",
                       SkScalarToFloat(matrix.getTranslateX()),
                       SkScalarToFloat(matrix.getTranslateY()));
            break;
        case SkMatrix::kScale_Mask:
            this->dump(kMatrix_Verb, nullptr, "scale(%g %g)",
                       SkScalarToFloat(matrix.getScaleX()),
                       SkScalarToFloat(matrix.getScaleY()));
            break;
        default:
            matrix.toString(&str);
            this->dump(kMatrix_Verb, nullptr, "concat(%s)", str.c_str());
            break;
    }

    this->INHERITED::didConcat(matrix);
}

void SkDumpCanvas::didSetMatrix(const SkMatrix& matrix) {
    SkString str;
    matrix.toString(&str);
    this->dump(kMatrix_Verb, nullptr, "setMatrix(%s)", str.c_str());
    this->INHERITED::didSetMatrix(matrix);
}

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

const char* SkDumpCanvas::EdgeStyleToAAString(ClipEdgeStyle edgeStyle) {
    return kSoft_ClipEdgeStyle == edgeStyle ? "AA" : "BW";
}

void SkDumpCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) {
    SkString str;
    toString(rect, &str);
    this->dump(kClip_Verb, nullptr, "clipRect(%s %s %s)", str.c_str(), toString(op),
               EdgeStyleToAAString(edgeStyle));
    this->INHERITED::onClipRect(rect, op, edgeStyle);
}

void SkDumpCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) {
    SkString str;
    toString(rrect, &str);
    this->dump(kClip_Verb, nullptr, "clipRRect(%s %s %s)", str.c_str(), toString(op),
               EdgeStyleToAAString(edgeStyle));
    this->INHERITED::onClipRRect(rrect, op, edgeStyle);
}

void SkDumpCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) {
    SkString str;
    toString(path, &str);
    this->dump(kClip_Verb, nullptr, "clipPath(%s %s %s)", str.c_str(), toString(op),
               EdgeStyleToAAString(edgeStyle));
    this->INHERITED::onClipPath(path, op, edgeStyle);
}

void SkDumpCanvas::onClipRegion(const SkRegion& deviceRgn, SkClipOp op) {
    SkString str;
    toString(deviceRgn, &str);
    this->dump(kClip_Verb, nullptr, "clipRegion(%s %s)", str.c_str(), toString(op));
    this->INHERITED::onClipRegion(deviceRgn, op);
}

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

void SkDumpCanvas::onDrawPaint(const SkPaint& paint) {
    this->dump(kDrawPaint_Verb, &paint, "drawPaint()");
}

void SkDumpCanvas::onDrawPoints(PointMode mode, size_t count,
                               const SkPoint pts[], const SkPaint& paint) {
    this->dump(kDrawPoints_Verb, &paint, "drawPoints(%s, %d)", toString(mode),
               count);
}

void SkDumpCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) {
    SkString str;
    toString(rect, &str);
    this->dump(kDrawOval_Verb, &paint, "drawOval(%s)", str.c_str());
}

void SkDumpCanvas::onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle,
                             bool useCenter, const SkPaint& paint) {
    SkString str;
    toString(rect, &str);
    this->dump(kDrawArc_Verb, &paint, "drawArc(%s, %g, %g, %d)", str.c_str(), startAngle,
               sweepAngle, useCenter);
}

void SkDumpCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
    SkString str;
    toString(rect, &str);
    this->dump(kDrawRect_Verb, &paint, "drawRect(%s)", str.c_str());
}

void SkDumpCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
    SkString str;
    toString(rrect, &str);
    this->dump(kDrawDRRect_Verb, &paint, "drawRRect(%s)", str.c_str());
}

void SkDumpCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
                                const SkPaint& paint) {
    SkString str0, str1;
    toString(outer, &str0);
    toString(inner, &str0);
    this->dump(kDrawRRect_Verb, &paint, "drawDRRect(%s,%s)",
               str0.c_str(), str1.c_str());
}

void SkDumpCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
    SkString str;
    toString(path, &str);
    this->dump(kDrawPath_Verb, &paint, "drawPath(%s)", str.c_str());
}

void SkDumpCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y,
                                const SkPaint* paint) {
    SkString str;
    bitmap.toString(&str);
    this->dump(kDrawBitmap_Verb, paint, "drawBitmap(%s %g %g)", str.c_str(),
               SkScalarToFloat(x), SkScalarToFloat(y));
}

void SkDumpCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
                                    const SkPaint* paint, SrcRectConstraint) {
    SkString bs, rs;
    bitmap.toString(&bs);
    toString(dst, &rs);
    // show the src-rect only if its not everything
    if (src && (src->fLeft > 0 || src->fTop > 0 ||
                src->fRight < SkIntToScalar(bitmap.width()) ||
                src->fBottom < SkIntToScalar(bitmap.height()))) {
        SkString ss;
        toString(*src, &ss);
        rs.prependf("%s ", ss.c_str());
    }

    this->dump(kDrawBitmap_Verb, paint, "drawBitmapRect(%s %s)", bs.c_str(), rs.c_str());
}

void SkDumpCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
                                    const SkRect& dst, const SkPaint* paint) {
    SkString str, centerStr, dstStr;
    bitmap.toString(&str);
    toString(center, &centerStr);
    toString(dst, &dstStr);
    this->dump(kDrawBitmap_Verb, paint, "drawBitmapNine(%s %s %s)", str.c_str(),
               centerStr.c_str(), dstStr.c_str());
}

void SkDumpCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) {
    SkString str;
    image->toString(&str);
    this->dump(kDrawBitmap_Verb, paint, "drawImage(%s %g %g)", str.c_str(),
               SkScalarToFloat(x), SkScalarToFloat(y));
}

void SkDumpCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
                                   const SkPaint* paint, SrcRectConstraint) {
    SkString bs, rs;
    image->toString(&bs);
    toString(dst, &rs);
    // show the src-rect only if its not everything
    if (src && (src->fLeft > 0 || src->fTop > 0 ||
                src->fRight < SkIntToScalar(image->width()) ||
                src->fBottom < SkIntToScalar(image->height()))) {
        SkString ss;
        toString(*src, &ss);
        rs.prependf("%s ", ss.c_str());
    }

    this->dump(kDrawBitmap_Verb, paint, "drawImageRectToRect(%s %s)",
               bs.c_str(), rs.c_str());
}

void SkDumpCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
                              const SkPaint& paint) {
    SkString str;
    toString(text, byteLength, paint.getTextEncoding(), &str);
    this->dump(kDrawText_Verb, &paint, "drawText(%s [%d] %g %g)", str.c_str(),
               byteLength, SkScalarToFloat(x), SkScalarToFloat(y));
}

void SkDumpCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
                                 const SkPaint& paint) {
    SkString str;
    toString(text, byteLength, paint.getTextEncoding(), &str);
    this->dump(kDrawText_Verb, &paint, "drawPosText(%s [%d] %g %g ...)",
               str.c_str(), byteLength, SkScalarToFloat(pos[0].fX),
               SkScalarToFloat(pos[0].fY));
}

void SkDumpCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
                                  SkScalar constY, const SkPaint& paint) {
    SkString str;
    toString(text, byteLength, paint.getTextEncoding(), &str);
    this->dump(kDrawText_Verb, &paint, "drawPosTextH(%s [%d] %g %g ...)",
               str.c_str(), byteLength, SkScalarToFloat(xpos[0]),
               SkScalarToFloat(constY));
}

void SkDumpCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
                                    const SkMatrix* matrix, const SkPaint& paint) {
    SkString str;
    toString(text, byteLength, paint.getTextEncoding(), &str);
    this->dump(kDrawText_Verb, &paint, "drawTextOnPath(%s [%d])",
               str.c_str(), byteLength);
}

void SkDumpCanvas::onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
                                     const SkRect* cull, const SkPaint& paint) {
    SkString str;
    toString(text, byteLength, paint.getTextEncoding(), &str);
    this->dump(kDrawText_Verb, &paint, "drawTextRSXform(%s [%d])",
               str.c_str(), byteLength);
}

void SkDumpCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
                                  const SkPaint& paint) {
    SkString str;
    toString(blob->bounds(), &str);
    this->dump(kDrawText_Verb, &paint, "drawTextBlob(%p) [%s]", blob, str.c_str());
    // FIXME: dump the actual blob content?
}

void SkDumpCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
                                 const SkPaint* paint) {
    this->dump(kDrawPicture_Verb, nullptr, "drawPicture(%p) %f:%f:%f:%f", picture,
               picture->cullRect().fLeft, picture->cullRect().fTop,
               picture->cullRect().fRight, picture->cullRect().fBottom);
    fNestLevel += 1;
    this->INHERITED::onDrawPicture(picture, matrix, paint);
    fNestLevel -= 1;
    this->dump(kDrawPicture_Verb, nullptr, "endPicture(%p) %f:%f:%f:%f", &picture,
               picture->cullRect().fLeft, picture->cullRect().fTop,
               picture->cullRect().fRight, picture->cullRect().fBottom);
}

void SkDumpCanvas::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode,
                                        const SkPaint& paint) {
    this->dump(kDrawVertices_Verb, &paint, "drawVertices(%s [%d] ...)",
               toString(vertices->mode()), vertices->vertexCount());
}

void SkDumpCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
                               const SkPoint texCoords[4], SkBlendMode,
                               const SkPaint& paint) {
    //dumps corner points and colors in clockwise order starting on upper-left corner
    this->dump(kDrawPatch_Verb, &paint, "drawPatch(Vertices{[%f, %f], [%f, %f], [%f, %f], [%f, %f]}\
              | Colors{[0x%x], [0x%x], [0x%x], [0x%x]} | TexCoords{[%f,%f], [%f,%f], [%f,%f], \
               [%f,%f]})",
              cubics[0].fX, cubics[0].fY,
              cubics[3].fX, cubics[3].fY,
              cubics[6].fX, cubics[6].fY,
              cubics[9].fX, cubics[9].fY,
              colors[0], colors[1], colors[2], colors[3],
              texCoords[0].x(), texCoords[0].y(), texCoords[1].x(), texCoords[1].y(),
              texCoords[2].x(), texCoords[2].y(), texCoords[3].x(), texCoords[3].y());
}

void SkDumpCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) {
    SkString str;
    toString(rect, &str);
    this->dump(kDrawAnnotation_Verb, nullptr, "drawAnnotation(%s \"%s\" (%zu))",
               str.c_str(), key, value ? value->size() : 0);
}

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

SkFormatDumper::SkFormatDumper(void (*proc)(const char*, void*), void* refcon) {
    fProc = proc;
    fRefcon = refcon;
}

static void appendPtr(SkString* str, const void* ptr, const char name[]) {
    if (ptr) {
        str->appendf(" %s:%p", name, ptr);
    }
}

static void appendFlattenable(SkString* str, const SkFlattenable* ptr,
                              const char name[]) {
    if (ptr) {
        str->appendf(" %s:%p", name, ptr);
    }
}

void SkFormatDumper::dump(SkDumpCanvas* canvas, SkDumpCanvas::Verb verb,
                          const char str[], const SkPaint* p) {
    SkString msg, tab;
    const int level = canvas->getNestLevel() + canvas->getSaveCount() - 1;
    SkASSERT(level >= 0);
    for (int i = 0; i < level; i++) {
#if 0
        tab.append("\t");
#else
        tab.append("    ");   // tabs are often too wide to be useful
#endif
    }
    msg.printf("%s%s", tab.c_str(), str);

    if (p) {
        msg.appendf(" color:0x%08X flags:%X", p->getColor(), p->getFlags());
        if (!p->isSrcOver()) {
            msg.appendf(" blendmode:%d", (int)p->getBlendMode());
        }
        appendFlattenable(&msg, p->getShader(), "shader");
        appendFlattenable(&msg, p->getPathEffect(), "pathEffect");
        appendFlattenable(&msg, p->getMaskFilter(), "maskFilter");
        appendFlattenable(&msg, p->getPathEffect(), "pathEffect");
        appendFlattenable(&msg, p->getColorFilter(), "filter");

        if (SkDumpCanvas::kDrawText_Verb == verb) {
            msg.appendf(" textSize:%g", SkScalarToFloat(p->getTextSize()));
            appendPtr(&msg, p->getTypeface(), "typeface");
        }

        if (p->getStyle() != SkPaint::kFill_Style) {
            msg.appendf(" strokeWidth:%g", SkScalarToFloat(p->getStrokeWidth()));
        }
    }

    fProc(msg.c_str(), fRefcon);
}

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

static void dumpToDebugf(const char text[], void*) {
    SkDebugf("%s\n", text);
}

SkDebugfDumper::SkDebugfDumper() : INHERITED(dumpToDebugf, nullptr) {}
