#include "DMUtil.h"

#include "SkColorPriv.h"
#include "SkPicture.h"
#include "SkPictureRecorder.h"

namespace DM {

SkString UnderJoin(const char* a, const char* b) {
    SkString s;
    s.appendf("%s_%s", a, b);
    return s;
}

SkString FileToTaskName(SkString filename) {
    for (size_t i = 0; i < filename.size(); i++) {
        if ('_' == filename[i]) { filename[i] = '-'; }
        if ('.' == filename[i]) { filename[i] = '_'; }
    }
    return filename;
}

SkPicture* RecordPicture(skiagm::GM* gm, SkBBHFactory* factory, bool skr) {
    const SkScalar w = SkIntToScalar(gm->getISize().width()),
                   h = SkIntToScalar(gm->getISize().height());
    SkPictureRecorder recorder;

    SkCanvas* canvas = skr ? recorder.EXPERIMENTAL_beginRecording(w, h, factory)
                           : recorder.  DEPRECATED_beginRecording(w, h, factory);
    canvas->concat(gm->getInitialTransform());
    gm->draw(canvas);
    canvas->flush();
    return recorder.endRecording();
}

void AllocatePixels(SkColorType ct, int width, int height, SkBitmap* bitmap) {
    bitmap->allocPixels(SkImageInfo::Make(width, height, ct, kPremul_SkAlphaType));
    bitmap->eraseColor(0x00000000);
}

void AllocatePixels(const SkBitmap& reference, SkBitmap* bitmap) {
    AllocatePixels(reference.colorType(), reference.width(), reference.height(), bitmap);
}

void DrawPicture(const SkPicture& picture, SkBitmap* bitmap) {
    SkASSERT(bitmap != NULL);
    SkCanvas canvas(*bitmap);
    canvas.drawPicture(&picture);
    canvas.flush();
}

static void unpack_565(uint16_t pixel, unsigned* r, unsigned* g, unsigned* b) {
    *r = SkGetPackedR16(pixel);
    *g = SkGetPackedG16(pixel);
    *b = SkGetPackedB16(pixel);
}

// Returns |a-b|.
static unsigned abs_diff(unsigned a, unsigned b) {
    return a > b ? a - b : b - a;
}

unsigned MaxComponentDifference(const SkBitmap& a, const SkBitmap& b) {
    if (a.info() != b.info()) {
        SkFAIL("Can't compare bitmaps of different shapes.");
    }

    unsigned max = 0;

    const SkAutoLockPixels lockA(a), lockB(b);
    if (a.info().colorType() == kRGB_565_SkColorType) {
        // 565 is special/annoying because its 3 components straddle 2 bytes.
        const uint16_t* aPixels = (const uint16_t*)a.getPixels();
        const uint16_t* bPixels = (const uint16_t*)b.getPixels();
        for (size_t i = 0; i < a.getSize() / 2; i++) {
            unsigned ar, ag, ab,
                     br, bg, bb;
            unpack_565(aPixels[i], &ar, &ag, &ab);
            unpack_565(bPixels[i], &br, &bg, &bb);
            max = SkTMax(max, abs_diff(ar, br));
            max = SkTMax(max, abs_diff(ag, bg));
            max = SkTMax(max, abs_diff(ab, bb));
        }
    } else {
        // Everything else we produce is byte aligned, so max component diff == max byte diff.
        const uint8_t* aBytes = (const uint8_t*)a.getPixels();
        const uint8_t* bBytes = (const uint8_t*)b.getPixels();
        for (size_t i = 0; i < a.getSize(); i++) {
            max = SkTMax(max, abs_diff(aBytes[i], bBytes[i]));
        }
    }

    return max;
}

bool BitmapsEqual(const SkBitmap& a, const SkBitmap& b) {
    if (a.info() != b.info()) {
        return false;
    }
    const SkAutoLockPixels lockA(a), lockB(b);
    return 0 == memcmp(a.getPixels(), b.getPixels(), a.getSize());
}

}  // namespace DM
