/*
 * Copyright 2008, The Android Open Source Project
 *
 * 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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.
 */

// must include config.h first for webkit to fiddle with new/delete
#include "config.h"
#include "SkANP.h"

static ANPCanvas* anp_newCanvas(const ANPBitmap* bitmap) {
    SkBitmap bm;
    return new ANPCanvas(*SkANP::SetBitmap(&bm, *bitmap));
}

static void anp_deleteCanvas(ANPCanvas* canvas) {
    delete canvas;
}

static void anp_save(ANPCanvas* canvas) {
    canvas->skcanvas->save();
}

static void anp_restore(ANPCanvas* canvas) {
    canvas->skcanvas->restore();
}

static void anp_translate(ANPCanvas* canvas, float tx, float ty) {
    canvas->skcanvas->translate(SkFloatToScalar(tx), SkFloatToScalar(ty));
}

static void anp_scale(ANPCanvas* canvas, float sx, float sy) {
    canvas->skcanvas->scale(SkFloatToScalar(sx), SkFloatToScalar(sy));
}

static void anp_rotate(ANPCanvas* canvas, float degrees) {
    canvas->skcanvas->rotate(SkFloatToScalar(degrees));
}

static void anp_skew(ANPCanvas* canvas, float kx, float ky) {
    canvas->skcanvas->skew(SkFloatToScalar(kx), SkFloatToScalar(ky));
}

static void anp_clipRect(ANPCanvas* canvas, const ANPRectF* rect) {
    SkRect r;
    canvas->skcanvas->clipRect(*SkANP::SetRect(&r, *rect));
}

static void anp_clipPath(ANPCanvas* canvas, const ANPPath* path) {
    canvas->skcanvas->clipPath(*path);
}
static void anp_concat(ANPCanvas* canvas, const ANPMatrix* matrix) {
    canvas->skcanvas->concat(*matrix);
}

static void anp_getTotalMatrix(ANPCanvas* canvas, ANPMatrix* matrix) {
    const SkMatrix& src = canvas->skcanvas->getTotalMatrix();
    *matrix = *reinterpret_cast<const ANPMatrix*>(&src);
}

static bool anp_getLocalClipBounds(ANPCanvas* canvas, ANPRectF* r,
                                   bool antialias) {
    SkRect bounds;
    if (canvas->skcanvas->getClipBounds(&bounds,
                antialias ? SkCanvas::kAA_EdgeType : SkCanvas::kBW_EdgeType)) {
        SkANP::SetRect(r, bounds);
        return true;
    }
    return false;
}

static bool anp_getDeviceClipBounds(ANPCanvas* canvas, ANPRectI* r) {
    const SkRegion& clip = canvas->skcanvas->getTotalClip();
    if (!clip.isEmpty()) {
        SkANP::SetRect(r, clip.getBounds());
        return true;
    }
    return false;
}

static void anp_drawColor(ANPCanvas* canvas, ANPColor color) {
    canvas->skcanvas->drawColor(color);
}

static void anp_drawPaint(ANPCanvas* canvas, const ANPPaint* paint) {
    canvas->skcanvas->drawPaint(*paint);
}

static void anp_drawLine(ANPCanvas* canvas, float x0, float y0,
                         float x1, float y1, const ANPPaint* paint) {
    canvas->skcanvas->drawLine(SkFloatToScalar(x0), SkFloatToScalar(y0),
                           SkFloatToScalar(x1), SkFloatToScalar(y1), *paint);
}

static void anp_drawRect(ANPCanvas* canvas, const ANPRectF* rect,
                         const ANPPaint* paint) {
    SkRect  r;
    canvas->skcanvas->drawRect(*SkANP::SetRect(&r, *rect), *paint);
}

static void anp_drawOval(ANPCanvas* canvas, const ANPRectF* rect,
                         const ANPPaint* paint) {
    SkRect  r;
    canvas->skcanvas->drawOval(*SkANP::SetRect(&r, *rect), *paint);
}

static void anp_drawPath(ANPCanvas* canvas, const ANPPath* path,
                         const ANPPaint* paint) {
    canvas->skcanvas->drawPath(*path, *paint);
}

static void anp_drawText(ANPCanvas* canvas, const void* text, uint32_t length,
                         float x, float y, const ANPPaint* paint) {
    canvas->skcanvas->drawText(text, length,
                               SkFloatToScalar(x), SkFloatToScalar(y),
                               *paint);
}

static void anp_drawPosText(ANPCanvas* canvas, const void* text,
                uint32_t byteLength, const float xy[], const ANPPaint* paint) {
    canvas->skcanvas->drawPosText(text, byteLength,
                                  reinterpret_cast<const SkPoint*>(xy), *paint);
}

static void anp_drawBitmap(ANPCanvas* canvas, const ANPBitmap* bitmap,
                           float x, float y, const ANPPaint* paint) {
    SkBitmap    bm;
    canvas->skcanvas->drawBitmap(*SkANP::SetBitmap(&bm, *bitmap),
                                 SkFloatToScalar(x), SkFloatToScalar(y),
                                 paint);
}

static void anp_drawBitmapRect(ANPCanvas* canvas, const ANPBitmap* bitmap,
                              const ANPRectI* src, const ANPRectF* dst,
                               const ANPPaint* paint) {
    SkBitmap    bm;
    SkRect      dstR;
    SkIRect     srcR, *srcPtr = NULL;

    if (src) {
        srcPtr = SkANP::SetRect(&srcR, *src);
    }
    canvas->skcanvas->drawBitmapRect(*SkANP::SetBitmap(&bm, *bitmap), srcPtr,
                           *SkANP::SetRect(&dstR, *dst), paint);
}

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

#define ASSIGN(obj, name)   (obj)->name = anp_##name

void ANPCanvasInterfaceV0_Init(ANPInterface* value) {
    ANPCanvasInterfaceV0* i = reinterpret_cast<ANPCanvasInterfaceV0*>(value);

    ASSIGN(i, newCanvas);
    ASSIGN(i, deleteCanvas);
    ASSIGN(i, save);
    ASSIGN(i, restore);
    ASSIGN(i, translate);
    ASSIGN(i, scale);
    ASSIGN(i, rotate);
    ASSIGN(i, skew);
    ASSIGN(i, clipRect);
    ASSIGN(i, clipPath);
    ASSIGN(i, concat);
    ASSIGN(i, getTotalMatrix);
    ASSIGN(i, getLocalClipBounds);
    ASSIGN(i, getDeviceClipBounds);
    ASSIGN(i, drawColor);
    ASSIGN(i, drawPaint);
    ASSIGN(i, drawLine);
    ASSIGN(i, drawRect);
    ASSIGN(i, drawOval);
    ASSIGN(i, drawPath);
    ASSIGN(i, drawText);
    ASSIGN(i, drawPosText);
    ASSIGN(i, drawBitmap);
    ASSIGN(i, drawBitmapRect);
}
