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


#include "SkDrawCommand.h"
#include "SkObjectParser.h"

// TODO(chudy): Refactor into non subclass model.

SkDrawCommand::SkDrawCommand() {
    fVisible = true;
}

SkDrawCommand::~SkDrawCommand() {
    fInfo.deleteAll();
}

const char* SkDrawCommand::GetCommandString(DrawType type) {
    switch (type) {
        case UNUSED: SkDEBUGFAIL("DrawType UNUSED\n"); break;
        case DRAW_CLEAR: return "Clear";
        case CLIP_PATH: return "Clip Path";
        case CLIP_REGION: return "Clip Region";
        case CLIP_RECT: return "Clip Rect";
        case CLIP_RRECT: return "Clip RRect";
        case CONCAT: return "Concat";
        case DRAW_BITMAP: return "Draw Bitmap";
        case DRAW_BITMAP_MATRIX: return "Draw Bitmap Matrix";
        case DRAW_BITMAP_NINE: return "Draw Bitmap Nine";
        case DRAW_BITMAP_RECT_TO_RECT: return "Draw Bitmap Rect";
        case DRAW_DATA: return "Draw Data";
        case DRAW_OVAL: return "Draw Oval";
        case DRAW_PAINT: return "Draw Paint";
        case DRAW_PATH: return "Draw Path";
        case DRAW_PICTURE: return "Draw Picture";
        case DRAW_POINTS: return "Draw Points";
        case DRAW_POS_TEXT: return "Draw Pos Text";
        case DRAW_POS_TEXT_H: return "Draw Pos Text H";
        case DRAW_RECT: return "Draw Rect";
        case DRAW_RRECT: return "Draw RRect";
        case DRAW_SPRITE: return "Draw Sprite";
        case DRAW_TEXT: return "Draw Text";
        case DRAW_TEXT_ON_PATH: return "Draw Text On Path";
        case DRAW_VERTICES: return "Draw Vertices";
        case RESTORE: return "Restore";
        case ROTATE: return "Rotate";
        case SAVE: return "Save";
        case SAVE_LAYER: return "Save Layer";
        case SCALE: return "Scale";
        case SET_MATRIX: return "Set Matrix";
        case SKEW: return "Skew";
        case TRANSLATE: return "Translate";
        case NOOP: return "NoOp";
        default:
            SkDebugf("DrawType error 0x%08x\n", type);
            SkASSERT(0);
            break;
    }
    SkDEBUGFAIL("DrawType UNUSED\n");
    return NULL;
}

SkString SkDrawCommand::toString() {
    return SkString(GetCommandString(fDrawType));
}

Clear::Clear(SkColor color) {
    this->fColor = color;
    this->fDrawType = DRAW_CLEAR;
    this->fInfo.push(SkObjectParser::CustomTextToString("No Parameters"));
}

void Clear::execute(SkCanvas* canvas) {
    canvas->clear(this->fColor);
}

ClipPath::ClipPath(const SkPath& path, SkRegion::Op op, bool doAA, SkBitmap& bitmap) {
    this->fPath = &path;
    this->fOp = op;
    this->fDoAA = doAA;
    this->fDrawType = CLIP_PATH;
    this->fBitmap = bitmap;

    this->fInfo.push(SkObjectParser::PathToString(path));
    this->fInfo.push(SkObjectParser::RegionOpToString(op));
    this->fInfo.push(SkObjectParser::BoolToString(doAA));
}

void ClipPath::execute(SkCanvas* canvas) {
    canvas->clipPath(*this->fPath, this->fOp, this->fDoAA);
}

const SkBitmap* ClipPath::getBitmap() const {
    return &fBitmap;
}

ClipRegion::ClipRegion(const SkRegion& region, SkRegion::Op op) {
    this->fRegion = &region;
    this->fOp = op;
    this->fDrawType = CLIP_REGION;

    this->fInfo.push(SkObjectParser::RegionToString(region));
    this->fInfo.push(SkObjectParser::RegionOpToString(op));
}

void ClipRegion::execute(SkCanvas* canvas) {
    canvas->clipRegion(*this->fRegion, this->fOp);
}

ClipRect::ClipRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
    this->fRect = &rect;
    this->fOp = op;
    this->fDoAA = doAA;
    this->fDrawType = CLIP_RECT;

    this->fInfo.push(SkObjectParser::RectToString(rect));
    this->fInfo.push(SkObjectParser::RegionOpToString(op));
    this->fInfo.push(SkObjectParser::BoolToString(doAA));
}

void ClipRect::execute(SkCanvas* canvas) {
    canvas->clipRect(*this->fRect, this->fOp, this->fDoAA);
}

ClipRRect::ClipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
    this->fRRect = rrect;
    this->fOp = op;
    this->fDoAA = doAA;
    this->fDrawType = CLIP_RRECT;

    this->fInfo.push(SkObjectParser::RRectToString(rrect));
    this->fInfo.push(SkObjectParser::RegionOpToString(op));
    this->fInfo.push(SkObjectParser::BoolToString(doAA));
}

void ClipRRect::execute(SkCanvas* canvas) {
    canvas->clipRRect(this->fRRect, this->fOp, this->fDoAA);
}

Concat::Concat(const SkMatrix& matrix) {
    this->fMatrix = &matrix;
    this->fDrawType = CONCAT;

    this->fInfo.push(SkObjectParser::MatrixToString(matrix));
}

void Concat::execute(SkCanvas* canvas) {
    canvas->concat(*this->fMatrix);
}

DrawBitmap::DrawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
        const SkPaint* paint, SkBitmap& resizedBitmap) {
    this->fBitmap = &bitmap;
    this->fLeft = left;
    this->fTop = top;
    this->fPaint = paint;
    this->fDrawType = DRAW_BITMAP;
    this->fResizedBitmap = resizedBitmap;

    this->fInfo.push(SkObjectParser::BitmapToString(bitmap));
    this->fInfo.push(SkObjectParser::ScalarToString(left, "SkScalar left: "));
    this->fInfo.push(SkObjectParser::ScalarToString(top, "SkScalar top: "));
    if (NULL != paint) {
        this->fInfo.push(SkObjectParser::PaintToString(*paint));
    }
}

void DrawBitmap::execute(SkCanvas* canvas) {
    canvas->drawBitmap(*this->fBitmap, this->fLeft, this->fTop, this->fPaint);
}

const SkBitmap* DrawBitmap::getBitmap() const {
    return &fResizedBitmap;
}

DrawBitmapMatrix::DrawBitmapMatrix(const SkBitmap& bitmap,
        const SkMatrix& matrix, const SkPaint* paint, SkBitmap& resizedBitmap) {
    this->fBitmap = &bitmap;
    this->fMatrix = &matrix;
    this->fPaint = paint;
    this->fDrawType = DRAW_BITMAP_MATRIX;
    this->fResizedBitmap = resizedBitmap;

    this->fInfo.push(SkObjectParser::BitmapToString(bitmap));
    this->fInfo.push(SkObjectParser::MatrixToString(matrix));
    if (NULL != paint) {
        this->fInfo.push(SkObjectParser::PaintToString(*paint));
    }
}

void DrawBitmapMatrix::execute(SkCanvas* canvas) {
    canvas->drawBitmapMatrix(*this->fBitmap, *this->fMatrix, this->fPaint);
}

const SkBitmap* DrawBitmapMatrix::getBitmap() const {
    return &fResizedBitmap;
}

DrawBitmapNine::DrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
        const SkRect& dst, const SkPaint* paint, SkBitmap& resizedBitmap) {
    this->fBitmap = &bitmap;
    this->fCenter = &center;
    this->fDst = &dst;
    this->fPaint = paint;
    this->fDrawType = DRAW_BITMAP_NINE;
    this->fResizedBitmap = resizedBitmap;

    this->fInfo.push(SkObjectParser::BitmapToString(bitmap));
    this->fInfo.push(SkObjectParser::IRectToString(center));
    this->fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
    if (NULL != paint) {
        this->fInfo.push(SkObjectParser::PaintToString(*paint));
    }
}

void DrawBitmapNine::execute(SkCanvas* canvas) {
    canvas->drawBitmapNine(*this->fBitmap, *this->fCenter, *this->fDst, this->fPaint);
}

const SkBitmap* DrawBitmapNine::getBitmap() const {
    return &fResizedBitmap;
}

DrawBitmapRect::DrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
        const SkRect& dst, const SkPaint* paint, SkBitmap& resizedBitmap) {
    this->fBitmap = &bitmap;
    this->fSrc = src;
    this->fDst = &dst;
    if (NULL != paint) {
        this->fPaint = *paint;
        this->fPaintPtr = &this->fPaint;
    } else {
        this->fPaintPtr = NULL;
    }
    this->fDrawType = DRAW_BITMAP_RECT_TO_RECT;
    this->fResizedBitmap = resizedBitmap;

    this->fInfo.push(SkObjectParser::BitmapToString(bitmap));
    if (NULL != src) {
        this->fInfo.push(SkObjectParser::RectToString(*src, "Src: "));
    }
    this->fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
    if (NULL != paint) {
        this->fInfo.push(SkObjectParser::PaintToString(*paint));
    }
}

void DrawBitmapRect::execute(SkCanvas* canvas) {
    canvas->drawBitmapRectToRect(*this->fBitmap, this->fSrc, *this->fDst, this->fPaintPtr);
}

const SkBitmap* DrawBitmapRect::getBitmap() const {
    return &fResizedBitmap;
}

DrawData::DrawData(const void* data, size_t length) {
    this->fData = data;
    this->fLength = length;
    this->fDrawType = DRAW_DATA;
    // TODO(chudy): See if we can't display data and length.
}

void DrawData::execute(SkCanvas* canvas) {
    canvas->drawData(this->fData, this->fLength);
}

DrawOval::DrawOval(const SkRect& oval, const SkPaint& paint) {
    this->fOval = &oval;
    this->fPaint = &paint;
    this->fDrawType = DRAW_OVAL;

    this->fInfo.push(SkObjectParser::RectToString(oval));
    this->fInfo.push(SkObjectParser::PaintToString(paint));
}

void DrawOval::execute(SkCanvas* canvas) {
    canvas->drawOval(*this->fOval, *this->fPaint);
}

DrawPaint::DrawPaint(const SkPaint& paint) {
    this->fPaint = &paint;
    this->fDrawType = DRAW_PAINT;

    this->fInfo.push(SkObjectParser::PaintToString(paint));
}

void DrawPaint::execute(SkCanvas* canvas) {
    canvas->drawPaint(*this->fPaint);
}

DrawPath::DrawPath(const SkPath& path, const SkPaint& paint, SkBitmap& bitmap) {
    this->fPath = &path;
    this->fPaint = &paint;
    this->fBitmap = bitmap;
    this->fDrawType = DRAW_PATH;

    this->fInfo.push(SkObjectParser::PathToString(path));
    this->fInfo.push(SkObjectParser::PaintToString(paint));
}

void DrawPath::execute(SkCanvas* canvas) {
    canvas->drawPath(*this->fPath, *this->fPaint);
}

const SkBitmap* DrawPath::getBitmap() const {
    return &fBitmap;
}

DrawPicture::DrawPicture(SkPicture& picture) {
    this->fPicture = &picture;
    this->fDrawType = DRAW_PICTURE;
    this->fInfo.push(SkObjectParser::CustomTextToString("To be implemented."));
}

void DrawPicture::execute(SkCanvas* canvas) {
    canvas->drawPicture(*this->fPicture);
}

DrawPoints::DrawPoints(SkCanvas::PointMode mode, size_t count,
        const SkPoint pts[], const SkPaint& paint) {
    this->fMode = mode;
    this->fCount = count;
    this->fPts = pts;
    this->fPaint = &paint;
    this->fDrawType = DRAW_POINTS;

    this->fInfo.push(SkObjectParser::PointsToString(pts, count));
    this->fInfo.push(SkObjectParser::ScalarToString(SkIntToScalar((unsigned int)count),
                                                    "Points: "));
    this->fInfo.push(SkObjectParser::PointModeToString(mode));
    this->fInfo.push(SkObjectParser::PaintToString(paint));
}

void DrawPoints::execute(SkCanvas* canvas) {
    canvas->drawPoints(this->fMode, this->fCount, this->fPts, *this->fPaint);
}

DrawPosText::DrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
        const SkPaint& paint) {
    this->fText = text;
    this->fByteLength = byteLength;
    this->fPos = pos;
    this->fPaint = &paint;
    this->fDrawType = DRAW_POS_TEXT;

    this->fInfo.push(SkObjectParser::TextToString(text, byteLength));
    // TODO(chudy): Test that this works.
    this->fInfo.push(SkObjectParser::PointsToString(pos, 1));
    this->fInfo.push(SkObjectParser::PaintToString(paint));
}

void DrawPosText::execute(SkCanvas* canvas) {
    canvas->drawPosText(this->fText, this->fByteLength, this->fPos, *this->fPaint);
}


DrawPosTextH::DrawPosTextH(const void* text, size_t byteLength,
        const SkScalar xpos[], SkScalar constY, const SkPaint& paint) {
    this->fText = text;
    this->fByteLength = byteLength;
    this->fXpos = xpos;
    this->fConstY = constY;
    this->fPaint = &paint;
    this->fDrawType = DRAW_POS_TEXT_H;

    this->fInfo.push(SkObjectParser::TextToString(text, byteLength));
    this->fInfo.push(SkObjectParser::ScalarToString(xpos[0], "XPOS: "));
    this->fInfo.push(SkObjectParser::ScalarToString(constY, "SkScalar constY: "));
    this->fInfo.push(SkObjectParser::PaintToString(paint));
}

void DrawPosTextH::execute(SkCanvas* canvas) {
    canvas->drawPosTextH(this->fText, this->fByteLength, this->fXpos, this->fConstY,
            *this->fPaint);
}

DrawRectC::DrawRectC(const SkRect& rect, const SkPaint& paint) {
    this->fRect = &rect;
    this->fPaint = &paint;
    this->fDrawType = DRAW_RECT;

    this->fInfo.push(SkObjectParser::RectToString(rect));
    this->fInfo.push(SkObjectParser::PaintToString(paint));
}

void DrawRectC::execute(SkCanvas* canvas) {
    canvas->drawRect(*this->fRect, *this->fPaint);
}

DrawRRect::DrawRRect(const SkRRect& rrect, const SkPaint& paint) {
    this->fRRect = rrect;
    this->fPaint = &paint;
    this->fDrawType = DRAW_RRECT;

    this->fInfo.push(SkObjectParser::RRectToString(rrect));
    this->fInfo.push(SkObjectParser::PaintToString(paint));
}

void DrawRRect::execute(SkCanvas* canvas) {
    canvas->drawRRect(this->fRRect, *this->fPaint);
}

DrawSprite::DrawSprite(const SkBitmap& bitmap, int left, int top,
        const SkPaint* paint, SkBitmap& resizedBitmap) {
    this->fBitmap = &bitmap;
    this->fLeft = left;
    this->fTop = top;
    this->fPaint = paint;
    this->fDrawType = DRAW_SPRITE;
    this->fResizedBitmap = resizedBitmap;

    this->fInfo.push(SkObjectParser::BitmapToString(bitmap));
    this->fInfo.push(SkObjectParser::IntToString(left, "Left: "));
    this->fInfo.push(SkObjectParser::IntToString(top, "Top: "));
}

void DrawSprite::execute(SkCanvas* canvas) {
    canvas->drawSprite(*this->fBitmap, this->fLeft, this->fTop, this->fPaint);
}

const SkBitmap* DrawSprite::getBitmap() const {
    return &fResizedBitmap;
}

DrawTextC::DrawTextC(const void* text, size_t byteLength, SkScalar x, SkScalar y,
        const SkPaint& paint) {
    this->fText = text;
    this->fByteLength = byteLength;
    this->fX = x;
    this->fY = y;
    this->fPaint = &paint;
    this->fDrawType = DRAW_TEXT;

    this->fInfo.push(SkObjectParser::TextToString(text, byteLength));
    this->fInfo.push(SkObjectParser::ScalarToString(x, "SkScalar x: "));
    this->fInfo.push(SkObjectParser::ScalarToString(y, "SkScalar y: "));
    this->fInfo.push(SkObjectParser::PaintToString(paint));
}

void DrawTextC::execute(SkCanvas* canvas) {
    canvas->drawText(this->fText, this->fByteLength, this->fX, this->fY, *this->fPaint);
}

DrawTextOnPath::DrawTextOnPath(const void* text, size_t byteLength,
        const SkPath& path, const SkMatrix* matrix, const SkPaint& paint) {
    this->fText = text;
    this->fByteLength = byteLength;
    this->fPath = &path;
    this->fMatrix = matrix;
    this->fPaint = &paint;
    this->fDrawType = DRAW_TEXT_ON_PATH;

    this->fInfo.push(SkObjectParser::TextToString(text, byteLength));
    this->fInfo.push(SkObjectParser::PathToString(path));
    if (matrix) this->fInfo.push(SkObjectParser::MatrixToString(*matrix));
    this->fInfo.push(SkObjectParser::PaintToString(paint));
}

void DrawTextOnPath::execute(SkCanvas* canvas) {
    canvas->drawTextOnPath(this->fText, this->fByteLength, *this->fPath,
            this->fMatrix, *this->fPaint);
}

DrawVertices::DrawVertices(SkCanvas::VertexMode vmode, int vertexCount,
        const SkPoint vertices[], const SkPoint texs[], const SkColor colors[],
        SkXfermode* xfermode, const uint16_t indices[], int indexCount,
        const SkPaint& paint) {
    this->fVmode = vmode;
    this->fVertexCount = vertexCount;
    this->fTexs = texs;
    this->fColors = colors;
    this->fXfermode = xfermode;
    this->fIndices = indices;
    this->fIndexCount = indexCount;
    this->fPaint = &paint;
    this->fDrawType = DRAW_VERTICES;
    // TODO(chudy)
    this->fInfo.push(SkObjectParser::CustomTextToString("To be implemented."));
}

void DrawVertices::execute(SkCanvas* canvas) {
    canvas->drawVertices(this->fVmode, this->fVertexCount, this->fVertices,
            this->fTexs, this->fColors, this->fXfermode, this->fIndices,
            this->fIndexCount, *this->fPaint);
}

Restore::Restore() {
    this->fDrawType = RESTORE;
    this->fInfo.push(SkObjectParser::CustomTextToString("No Parameters"));
}

void Restore::execute(SkCanvas* canvas) {
    canvas->restore();
}

void Restore::trackSaveState(int* state) {
    (*state)--;
}

Rotate::Rotate(SkScalar degrees) {
    this->fDegrees = degrees;
    this->fDrawType = ROTATE;

    this->fInfo.push(SkObjectParser::ScalarToString(degrees, "SkScalar degrees: "));
}

void Rotate::execute(SkCanvas* canvas) {
    canvas->rotate(this->fDegrees);
}

Save::Save(SkCanvas::SaveFlags flags) {
    this->fFlags = flags;
    this->fDrawType = SAVE;
    this->fInfo.push(SkObjectParser::SaveFlagsToString(flags));
}

void Save::execute(SkCanvas* canvas) {
    canvas->save(this->fFlags);
}

void Save::trackSaveState(int* state) {
    (*state)++;
}

SaveLayer::SaveLayer(const SkRect* bounds, const SkPaint* paint,
        SkCanvas::SaveFlags flags) {
    this->fBounds = bounds;
    this->fPaint = paint;
    this->fFlags = flags;
    this->fDrawType = SAVE_LAYER;

    if (bounds) this->fInfo.push(SkObjectParser::RectToString(*bounds, "Bounds: "));
    if (paint) this->fInfo.push(SkObjectParser::PaintToString(*paint));
    this->fInfo.push(SkObjectParser::SaveFlagsToString(flags));
}

void SaveLayer::execute(SkCanvas* canvas) {
    canvas->saveLayer(this->fBounds, this->fPaint, this->fFlags);
}

void SaveLayer::trackSaveState(int* state) {
    (*state)++;
}

Scale::Scale(SkScalar sx, SkScalar sy) {
    this->fSx = sx;
    this->fSy = sy;
    this->fDrawType = SCALE;

    this->fInfo.push(SkObjectParser::ScalarToString(sx, "SkScalar sx: "));
    this->fInfo.push(SkObjectParser::ScalarToString(sy, "SkScalar sy: "));
}

void Scale::execute(SkCanvas* canvas) {
    canvas->scale(this->fSx, this->fSy);
}

SetMatrix::SetMatrix(const SkMatrix& matrix) {
    this->fMatrix = matrix;
    this->fDrawType = SET_MATRIX;

    this->fInfo.push(SkObjectParser::MatrixToString(matrix));
}

void SetMatrix::execute(SkCanvas* canvas) {
    canvas->setMatrix(this->fMatrix);
}

Skew::Skew(SkScalar sx, SkScalar sy) {
    this->fSx = sx;
    this->fSy = sy;
    this->fDrawType = SKEW;

    this->fInfo.push(SkObjectParser::ScalarToString(sx, "SkScalar sx: "));
    this->fInfo.push(SkObjectParser::ScalarToString(sy, "SkScalar sy: "));
}

void Skew::execute(SkCanvas* canvas) {
    canvas->skew(this->fSx, this->fSy);
}

Translate::Translate(SkScalar dx, SkScalar dy) {
    this->fDx = dx;
    this->fDy = dy;
    this->fDrawType = TRANSLATE;

    this->fInfo.push(SkObjectParser::ScalarToString(dx, "SkScalar dx: "));
    this->fInfo.push(SkObjectParser::ScalarToString(dy, "SkScalar dy: "));
}

void Translate::execute(SkCanvas* canvas) {
    canvas->translate(this->fDx, this->fDy);
}
