/*
 * 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 "include/core/SkBitmap.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorPriv.h"
#include "include/core/SkTypes.h"
#include "tools/skdiff/skdiff.h"

/*static*/ char const * const DiffRecord::ResultNames[DiffRecord::kResultCount] = {
    "EqualBits",
    "EqualPixels",
    "DifferentPixels",
    "DifferentSizes",
    "CouldNotCompare",
    "Unknown",
};

DiffRecord::Result DiffRecord::getResultByName(const char *name) {
    for (int result = 0; result < DiffRecord::kResultCount; ++result) {
        if (0 == strcmp(DiffRecord::ResultNames[result], name)) {
            return static_cast<DiffRecord::Result>(result);
        }
    }
    return DiffRecord::kResultCount;
}

static char const * const ResultDescriptions[DiffRecord::kResultCount] = {
    "contain exactly the same bits",
    "contain the same pixel values, but not the same bits",
    "have identical dimensions but some differing pixels",
    "have differing dimensions",
    "could not be compared",
    "not compared yet",
};

const char* DiffRecord::getResultDescription(DiffRecord::Result result) {
    return ResultDescriptions[result];
}

/*static*/ char const * const DiffResource::StatusNames[DiffResource::kStatusCount] = {
    "Decoded",
    "CouldNotDecode",

    "Read",
    "CouldNotRead",

    "Exists",
    "DoesNotExist",

    "Specified",
    "Unspecified",

    "Unknown",
};

DiffResource::Status DiffResource::getStatusByName(const char *name) {
    for (int status = 0; status < DiffResource::kStatusCount; ++status) {
        if (0 == strcmp(DiffResource::StatusNames[status], name)) {
            return static_cast<DiffResource::Status>(status);
        }
    }
    return DiffResource::kStatusCount;
}

static char const * const StatusDescriptions[DiffResource::kStatusCount] = {
    "decoded",
    "could not be decoded",

    "read",
    "could not be read",

    "found",
    "not found",

    "specified",
    "unspecified",

    "unknown",
};

const char* DiffResource::getStatusDescription(DiffResource::Status status) {
    return StatusDescriptions[status];
}

bool DiffResource::isStatusFailed(DiffResource::Status status) {
    return DiffResource::kCouldNotDecode_Status == status ||
           DiffResource::kCouldNotRead_Status == status ||
           DiffResource::kDoesNotExist_Status == status ||
           DiffResource::kUnspecified_Status == status ||
           DiffResource::kUnknown_Status == status;
}

bool DiffResource::getMatchingStatuses(char* selector, bool statuses[kStatusCount]) {
    if (!strcmp(selector, "any")) {
        for (int statusIndex = 0; statusIndex < kStatusCount; ++statusIndex) {
            statuses[statusIndex] = true;
        }
        return true;
    }

    for (int statusIndex = 0; statusIndex < kStatusCount; ++statusIndex) {
        statuses[statusIndex] = false;
    }

    static const char kDelimiterChar = ',';
    bool understood = true;
    while (true) {
        char* delimiterPtr = strchr(selector, kDelimiterChar);

        if (delimiterPtr) {
            *delimiterPtr = '\0';
        }

        if (!strcmp(selector, "failed")) {
            for (int statusIndex = 0; statusIndex < kStatusCount; ++statusIndex) {
                Status status = static_cast<Status>(statusIndex);
                statuses[statusIndex] |= isStatusFailed(status);
            }
        } else {
            Status status = getStatusByName(selector);
            if (status == kStatusCount) {
                understood = false;
            } else {
                statuses[status] = true;
            }
        }

        if (!delimiterPtr) {
            break;
        }

        *delimiterPtr = kDelimiterChar;
        selector = delimiterPtr + 1;
    }
    return understood;
}

static inline bool colors_match_thresholded(SkPMColor c0, SkPMColor c1, const int threshold) {
    int da = SkGetPackedA32(c0) - SkGetPackedA32(c1);
    int dr = SkGetPackedR32(c0) - SkGetPackedR32(c1);
    int dg = SkGetPackedG32(c0) - SkGetPackedG32(c1);
    int db = SkGetPackedB32(c0) - SkGetPackedB32(c1);

    return ((SkAbs32(da) <= threshold) &&
            (SkAbs32(dr) <= threshold) &&
            (SkAbs32(dg) <= threshold) &&
            (SkAbs32(db) <= threshold));
}

const SkPMColor PMCOLOR_WHITE = SkPreMultiplyColor(SK_ColorWHITE);
const SkPMColor PMCOLOR_BLACK = SkPreMultiplyColor(SK_ColorBLACK);

void compute_diff(DiffRecord* dr, DiffMetricProc diffFunction, const int colorThreshold) {
    const int w = dr->fComparison.fBitmap.width();
    const int h = dr->fComparison.fBitmap.height();
    if (w != dr->fBase.fBitmap.width() || h != dr->fBase.fBitmap.height()) {
        dr->fResult = DiffRecord::kDifferentSizes_Result;
        return;
    }

    int mismatchedPixels = 0;
    int totalMismatchA = 0;
    int totalMismatchR = 0;
    int totalMismatchG = 0;
    int totalMismatchB = 0;

    // Accumulate fractionally different pixels, then divide out
    // # of pixels at the end.
    dr->fWeightedFraction = 0;
    for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
            SkPMColor c0 = *dr->fBase.fBitmap.getAddr32(x, y);
            SkPMColor c1 = *dr->fComparison.fBitmap.getAddr32(x, y);
            SkPMColor outputDifference = diffFunction(c0, c1);
            uint32_t thisA = SkAbs32(SkGetPackedA32(c0) - SkGetPackedA32(c1));
            uint32_t thisR = SkAbs32(SkGetPackedR32(c0) - SkGetPackedR32(c1));
            uint32_t thisG = SkAbs32(SkGetPackedG32(c0) - SkGetPackedG32(c1));
            uint32_t thisB = SkAbs32(SkGetPackedB32(c0) - SkGetPackedB32(c1));
            totalMismatchA += thisA;
            totalMismatchR += thisR;
            totalMismatchG += thisG;
            totalMismatchB += thisB;
            // In HSV, value is defined as max RGB component.
            int value = MAX3(thisR, thisG, thisB);
            dr->fWeightedFraction += ((float) value) / 255;
            if (thisA > dr->fMaxMismatchA) {
                dr->fMaxMismatchA = thisA;
            }
            if (thisR > dr->fMaxMismatchR) {
                dr->fMaxMismatchR = thisR;
            }
            if (thisG > dr->fMaxMismatchG) {
                dr->fMaxMismatchG = thisG;
            }
            if (thisB > dr->fMaxMismatchB) {
                dr->fMaxMismatchB = thisB;
            }
            if (!colors_match_thresholded(c0, c1, colorThreshold)) {
                mismatchedPixels++;
                *dr->fDifference.fBitmap.getAddr32(x, y) = outputDifference;
                *dr->fWhite.fBitmap.getAddr32(x, y) = PMCOLOR_WHITE;
            } else {
                *dr->fDifference.fBitmap.getAddr32(x, y) = 0;
                *dr->fWhite.fBitmap.getAddr32(x, y) = PMCOLOR_BLACK;
            }
        }
    }
    if (0 == mismatchedPixels) {
        dr->fResult = DiffRecord::kEqualPixels_Result;
        return;
    }
    dr->fResult = DiffRecord::kDifferentPixels_Result;
    int pixelCount = w * h;
    dr->fFractionDifference = ((float) mismatchedPixels) / pixelCount;
    dr->fWeightedFraction /= pixelCount;
    dr->fTotalMismatchA = totalMismatchA;
    dr->fAverageMismatchA = ((float) totalMismatchA) / pixelCount;
    dr->fAverageMismatchR = ((float) totalMismatchR) / pixelCount;
    dr->fAverageMismatchG = ((float) totalMismatchG) / pixelCount;
    dr->fAverageMismatchB = ((float) totalMismatchB) / pixelCount;
}
