/*
 * 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/SkStream.h"
#include "include/core/SkTime.h"
#include "tools/skdiff/skdiff.h"
#include "tools/skdiff/skdiff_html.h"

/// Make layout more consistent by scaling image to 240 height, 360 width,
/// or natural size, whichever is smallest.
static int compute_image_height(int height, int width) {
    int retval = 240;
    if (height < retval) {
        retval = height;
    }
    float scale = (float) retval / height;
    if (width * scale > 360) {
        scale = (float) 360 / width;
        retval = static_cast<int>(height * scale);
    }
    return retval;
}

static void print_table_header(SkFILEWStream* stream,
                               const int matchCount,
                               const int colorThreshold,
                               const RecordArray& differences,
                               const SkString &baseDir,
                               const SkString &comparisonDir,
                               bool doOutputDate = false) {
    stream->writeText("<table>\n");
    stream->writeText("<tr><th>");
    stream->writeText("select image</th>\n<th>");
    if (doOutputDate) {
        SkTime::DateTime dt;
        SkTime::GetDateTime(&dt);
        stream->writeText("SkDiff run at ");
        stream->writeDecAsText(dt.fHour);
        stream->writeText(":");
        if (dt.fMinute < 10) {
            stream->writeText("0");
        }
        stream->writeDecAsText(dt.fMinute);
        stream->writeText(":");
        if (dt.fSecond < 10) {
            stream->writeText("0");
        }
        stream->writeDecAsText(dt.fSecond);
        stream->writeText("<br>");
    }
    stream->writeDecAsText(matchCount);
    stream->writeText(" of ");
    stream->writeDecAsText(differences.size());
    stream->writeText(" diffs matched ");
    if (colorThreshold == 0) {
        stream->writeText("exactly");
    } else {
        stream->writeText("within ");
        stream->writeDecAsText(colorThreshold);
        stream->writeText(" color units per component");
    }
    stream->writeText(".<br>");
    stream->writeText("</th>\n<th>");
    stream->writeText("every different pixel shown in white");
    stream->writeText("</th>\n<th>");
    stream->writeText("color difference at each pixel");
    stream->writeText("</th>\n<th>baseDir: ");
    stream->writeText(baseDir.c_str());
    stream->writeText("</th>\n<th>comparisonDir: ");
    stream->writeText(comparisonDir.c_str());
    stream->writeText("</th>\n");
    stream->writeText("</tr>\n");
}

static void print_pixel_count(SkFILEWStream* stream, const DiffRecord& diff) {
    stream->writeText("<br>(");
    stream->writeDecAsText(static_cast<int>(diff.fFractionDifference *
                                            diff.fBase.fBitmap.width() *
                                            diff.fBase.fBitmap.height()));
    stream->writeText(" pixels)");
/*
    stream->writeDecAsText(diff.fWeightedFraction *
                           diff.fBaseWidth *
                           diff.fBaseHeight);
    stream->writeText(" weighted pixels)");
*/
}

static void print_checkbox_cell(SkFILEWStream* stream, const DiffRecord& diff) {
    stream->writeText("<td><input type=\"checkbox\" name=\"");
    stream->writeText(diff.fBase.fFilename.c_str());
    stream->writeText("\" checked=\"yes\"></td>");
}

static void print_label_cell(SkFILEWStream* stream, const DiffRecord& diff) {
    char metricBuf [20];

    stream->writeText("<td><b>");
    stream->writeText(diff.fBase.fFilename.c_str());
    stream->writeText("</b><br>");
    switch (diff.fResult) {
      case DiffRecord::kEqualBits_Result:
        SkDEBUGFAIL("should not encounter DiffRecord with kEqualBits here");
        return;
      case DiffRecord::kEqualPixels_Result:
        SkDEBUGFAIL("should not encounter DiffRecord with kEqualPixels here");
        return;
      case DiffRecord::kDifferentSizes_Result:
        stream->writeText("Image sizes differ</td>");
        return;
      case DiffRecord::kDifferentPixels_Result:
        sprintf(metricBuf, "%.4f%%", 100 * diff.fFractionDifference);
        stream->writeText(metricBuf);
        stream->writeText(" of pixels differ");
        stream->writeText("\n  (");
        sprintf(metricBuf, "%.4f%%", 100 * diff.fWeightedFraction);
        stream->writeText(metricBuf);
        stream->writeText(" weighted)");
        // Write the actual number of pixels that differ if it's < 1%
        if (diff.fFractionDifference < 0.01) {
            print_pixel_count(stream, diff);
        }
        stream->writeText("<br>");
        if (SkScalarRoundToInt(diff.fAverageMismatchA) > 0) {
          stream->writeText("<br>Average alpha channel mismatch ");
          stream->writeDecAsText(SkScalarRoundToInt(diff.fAverageMismatchA));
        }

        stream->writeText("<br>Max alpha channel mismatch ");
        stream->writeDecAsText(SkScalarRoundToInt(diff.fMaxMismatchA));

        stream->writeText("<br>Total alpha channel mismatch ");
        stream->writeDecAsText(static_cast<int>(diff.fTotalMismatchA));

        stream->writeText("<br>");
        stream->writeText("<br>Average color mismatch ");
        stream->writeDecAsText(SkScalarRoundToInt(MAX3(diff.fAverageMismatchR,
                                                       diff.fAverageMismatchG,
                                                       diff.fAverageMismatchB)));
        stream->writeText("<br>Max color mismatch ");
        stream->writeDecAsText(MAX3(diff.fMaxMismatchR,
                                    diff.fMaxMismatchG,
                                    diff.fMaxMismatchB));
        stream->writeText("</td>");
        break;
      case DiffRecord::kCouldNotCompare_Result:
        stream->writeText("Could not compare.<br>base: ");
        stream->writeText(DiffResource::getStatusDescription(diff.fBase.fStatus));
        stream->writeText("<br>comparison: ");
        stream->writeText(DiffResource::getStatusDescription(diff.fComparison.fStatus));
        stream->writeText("</td>");
        return;
      default:
        SkDEBUGFAIL("encountered DiffRecord with unknown result type");
        return;
    }
}

static void print_image_cell(SkFILEWStream* stream, const SkString& path, int height) {
    stream->writeText("<td><a href=\"");
    stream->writeText(path.c_str());
    stream->writeText("\"><img src=\"");
    stream->writeText(path.c_str());
    stream->writeText("\" height=\"");
    stream->writeDecAsText(height);
    stream->writeText("px\"></a></td>");
}

static void print_link_cell(SkFILEWStream* stream, const SkString& path, const char* text) {
    stream->writeText("<td><a href=\"");
    stream->writeText(path.c_str());
    stream->writeText("\">");
    stream->writeText(text);
    stream->writeText("</a></td>");
}

static void print_diff_resource_cell(SkFILEWStream* stream, const DiffResource& resource,
                                     const SkString& relativePath, bool local) {
    SkString fullPath = resource.fFullPath;
    if (resource.fBitmap.empty()) {
        if (DiffResource::kCouldNotDecode_Status == resource.fStatus) {
            if (local && !resource.fFilename.isEmpty()) {
                print_link_cell(stream, resource.fFilename, "N/A");
                return;
            }
            if (!fullPath.isEmpty()) {
                if (!fullPath.startsWith(PATH_DIV_STR)) {
                    fullPath.prepend(relativePath);
                }
                print_link_cell(stream, fullPath, "N/A");
                return;
            }
        }
        stream->writeText("<td>N/A</td>");
        return;
    }

    int height = compute_image_height(resource.fBitmap.height(), resource.fBitmap.width());
    if (local) {
        print_image_cell(stream, resource.fFilename, height);
        return;
    }
    if (!fullPath.startsWith(PATH_DIV_STR)) {
        fullPath.prepend(relativePath);
    }
    print_image_cell(stream, fullPath, height);
}

static void print_diff_row(SkFILEWStream* stream, const DiffRecord& diff, const SkString& relativePath) {
    stream->writeText("<tr>\n");
    print_checkbox_cell(stream, diff);
    print_label_cell(stream, diff);
    print_diff_resource_cell(stream, diff.fWhite, relativePath, true);
    print_diff_resource_cell(stream, diff.fDifference, relativePath, true);
    print_diff_resource_cell(stream, diff.fBase, relativePath, false);
    print_diff_resource_cell(stream, diff.fComparison, relativePath, false);
    stream->writeText("</tr>\n");
    stream->flush();
}

void print_diff_page(const int matchCount,
                     const int colorThreshold,
                     const RecordArray& differences,
                     const SkString& baseDir,
                     const SkString& comparisonDir,
                     const SkString& outputDir) {

    SkASSERT(!baseDir.isEmpty());
    SkASSERT(!comparisonDir.isEmpty());
    SkASSERT(!outputDir.isEmpty());

    SkString outputPath(outputDir);
    outputPath.append("index.html");
    //SkFILEWStream outputStream ("index.html");
    SkFILEWStream outputStream(outputPath.c_str());

    // Need to convert paths from relative-to-cwd to relative-to-outputDir
    // FIXME this doesn't work if there are '..' inside the outputDir

    bool isPathAbsolute = false;
    // On Windows or Linux, a path starting with PATH_DIV_CHAR is absolute.
    if (outputDir.size() > 0 && PATH_DIV_CHAR == outputDir[0]) {
        isPathAbsolute = true;
    }
#ifdef SK_BUILD_FOR_WIN
    // On Windows, absolute paths can also start with "x:", where x is any
    // drive letter.
    if (outputDir.size() > 1 && ':' == outputDir[1]) {
        isPathAbsolute = true;
    }
#endif

    SkString relativePath;
    if (!isPathAbsolute) {
        unsigned int ui;
        for (ui = 0; ui < outputDir.size(); ui++) {
            if (outputDir[ui] == PATH_DIV_CHAR) {
                relativePath.append(".." PATH_DIV_STR);
            }
        }
    }

    outputStream.writeText(
        "<html>\n<head>\n"
        "<script src=\"https://ajax.googleapis.com/ajax/"
        "libs/jquery/1.7.2/jquery.min.js\"></script>\n"
        "<script type=\"text/javascript\">\n"
        "function generateCheckedList() {\n"
        "var boxes = $(\":checkbox:checked\");\n"
        "var fileCmdLineString = '';\n"
        "var fileMultiLineString = '';\n"
        "for (var i = 0; i < boxes.length; i++) {\n"
        "fileMultiLineString += boxes[i].name + '<br>';\n"
        "fileCmdLineString += boxes[i].name + '&nbsp;';\n"
        "}\n"
        "$(\"#checkedList\").html(fileCmdLineString + "
        "'<br><br>' + fileMultiLineString);\n"
        "}\n"
        "</script>\n</head>\n<body>\n");
    print_table_header(&outputStream, matchCount, colorThreshold, differences,
                       baseDir, comparisonDir);
    int i;
    for (i = 0; i < differences.size(); i++) {
        const DiffRecord& diff = differences[i];

        switch (diff.fResult) {
          // Cases in which there is no diff to report.
          case DiffRecord::kEqualBits_Result:
          case DiffRecord::kEqualPixels_Result:
            continue;
          // Cases in which we want a detailed pixel diff.
          case DiffRecord::kDifferentPixels_Result:
          case DiffRecord::kDifferentSizes_Result:
          case DiffRecord::kCouldNotCompare_Result:
            print_diff_row(&outputStream, diff, relativePath);
            continue;
          default:
            SkDEBUGFAIL("encountered DiffRecord with unknown result type");
            continue;
        }
    }
    outputStream.writeText(
        "</table>\n"
        "<input type=\"button\" "
        "onclick=\"generateCheckedList()\" "
        "value=\"Create Rebaseline List\">\n"
        "<div id=\"checkedList\"></div>\n"
        "</body>\n</html>\n");
    outputStream.flush();
}
