const kYellow = 0xFFFF00FF;
const kRed = 0xFF0000FF;
const kBlue = 0x0000FFFF;
const kGreen = 0x00FF00FF;

function getColorName (color) {
  switch (color) {
    case kYellow:
      return "Yellow";
    case kRed:
      return "Red";
    case kBlue:
      return "Blue";
    case kGreen:
      return "Green";
  }
  return "#" + color.toString(16);
}

function toUInt32(pixelArray) {
  let p = pixelArray.data;
  return ((p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3]) >>> 0;
}

function flipMatrix(m) {
  return m.map(row => row.reverse());
}

function rotateMatrix(m, count) {
  for (var i = 0; i < count; ++i)
    m = m[0].map((val, index) => m.map(row => row[index]).reverse());
  return m;
}

function testFourColorsDecodeBuffer(buffer, mimeType, options = {}) {
  var decoder = new ImageDecoder(
      {data: buffer, type: mimeType, preferAnimation: options.preferAnimation});
  return decoder.decode().then(result => {
    assert_equals(result.image.displayWidth, 320);
    assert_equals(result.image.displayHeight, 240);
    if (options.preferAnimation !== undefined) {
      assert_greater_than(decoder.tracks.length, 1);
      assert_equals(
          options.preferAnimation, decoder.tracks.selectedTrack.animated);
    }
    if (options.yuvFormat !== undefined)
      assert_equals(result.image.format, options.yuvFormat);
    if (options.tolerance === undefined)
      options.tolerance = 0;

    let canvas = new OffscreenCanvas(
        result.image.displayWidth, result.image.displayHeight);
    let ctx = canvas.getContext('2d');
    ctx.drawImage(result.image, 0, 0);

    let top_left = ctx.getImageData(0, 0, 1, 1);
    let top_right = ctx.getImageData(result.image.displayWidth - 1, 0, 1, 1);
    let bottom_left = ctx.getImageData(0, result.image.displayHeight - 1, 1, 1);
    let left_corner = ctx.getImageData(
        result.image.displayWidth - 1, result.image.displayHeight - 1, 1, 1);

    assert_array_approx_equals(
        top_left.data, [0xFF, 0xFF, 0x00, 0xFF], options.tolerance,
        'top left corner is yellow');
    assert_array_approx_equals(
        top_right.data, [0xFF, 0x00, 0x00, 0xFF], options.tolerance,
        'top right corner is red');
    assert_array_approx_equals(
        bottom_left.data, [0x00, 0x00, 0xFF, 0xFF], options.tolerance,
        'bottom left corner is blue');
    assert_array_approx_equals(
        left_corner.data, [0x00, 0xFF, 0x00, 0xFF], options.tolerance,
        'bottom right corner is green');
  });
}

function testFourColorDecodeWithExifOrientation(orientation, canvas) {
  return ImageDecoder.isTypeSupported('image/jpeg').then(support => {
    assert_implements_optional(
        support, 'Optional codec image/jpeg not supported.');
    return fetch('four-colors.jpg')
        .then(response => {
          return response.arrayBuffer();
        })
        .then(buffer => {
          let u8buffer = new Uint8Array(buffer);
          u8buffer[0x1F] = orientation;  // Location derived via diff.
          let decoder = new ImageDecoder({data: u8buffer, type: 'image/jpeg'});
          return decoder.decode();
        })
        .then(result => {
          let respectOrientation = true;
          if (canvas)
            respectOrientation = canvas.style.imageOrientation != 'none';

          let expectedWidth = 320;
          let expectedHeight = 240;
          if (orientation > 4 && respectOrientation)
            [expectedWidth, expectedHeight] = [expectedHeight, expectedWidth];

          if (respectOrientation) {
            assert_equals(result.image.displayWidth, expectedWidth);
            assert_equals(result.image.displayHeight, expectedHeight);
          } else if (orientation > 4) {
            assert_equals(result.image.displayHeight, expectedWidth);
            assert_equals(result.image.displayWidth, expectedHeight);
          }

          if (!canvas) {
            canvas = new OffscreenCanvas(
                result.image.displayWidth, result.image.displayHeight);
          } else {
            canvas.width = expectedWidth;
            canvas.height = expectedHeight;
          }

          let ctx = canvas.getContext('2d');
          ctx.drawImage(result.image, 0, 0);

          let matrix = [
            [kYellow, kRed],
            [kBlue, kGreen],
          ];
          if (respectOrientation) {
            switch (orientation) {
              case 1:  // kOriginTopLeft, default
                break;
              case 2:  // kOriginTopRight, mirror along y-axis
                matrix = flipMatrix(matrix);
                break;
              case 3:  // kOriginBottomRight, 180 degree rotation
                matrix = rotateMatrix(matrix, 2);
                break;
              case 4:  // kOriginBottomLeft, mirror along the x-axis
                matrix = flipMatrix(rotateMatrix(matrix, 2));
                break;
              case 5:  // kOriginLeftTop, mirror along x-axis + 270 degree CW
                       // rotation
                matrix = flipMatrix(rotateMatrix(matrix, 1));
                break;
              case 6:  // kOriginRightTop, 90 degree CW rotation
                matrix = rotateMatrix(matrix, 1);
                break;
              case 7:  // kOriginRightBottom, mirror along x-axis + 90 degree CW
                       // rotation
                matrix = flipMatrix(rotateMatrix(matrix, 3));
                break;
              case 8:  // kOriginLeftBottom, 270 degree CW rotation
                matrix = rotateMatrix(matrix, 3);
                break;
              default:
                assert_between_inclusive(
                    orientation, 1, 8, 'unknown image orientation');
                break;
            };
          }

          verifyFourColorsImage(expectedWidth, expectedHeight, ctx, matrix);
        });
  });
}

function verifyFourColorsImage(width, height, ctx, matrix) {
  if (!matrix) {
    matrix = [
      [kYellow, kRed],
      [kBlue, kGreen],
    ];
  }

  let expectedTopLeft = matrix[0][0];
  let expectedTopRight = matrix[0][1];
  let expectedBottomLeft = matrix[1][0];
  let expectedBottomRight = matrix[1][1];

  let topLeft = toUInt32(ctx.getImageData(0, 0, 1, 1));
  let topRight = toUInt32(ctx.getImageData(width - 1, 0, 1, 1));
  let bottomLeft = toUInt32(ctx.getImageData(0, height - 1, 1, 1));
  let bottomRight = toUInt32(ctx.getImageData(width - 1, height - 1, 1, 1));

  assert_equals(getColorName(topLeft), getColorName(expectedTopLeft),
                            'top left corner');
  assert_equals(getColorName(topRight), getColorName(expectedTopRight),
                            'top right corner');
  assert_equals(getColorName(bottomLeft), getColorName(expectedBottomLeft),
                            'bottom left corner');
  assert_equals(getColorName(bottomRight), getColorName(expectedBottomRight),
                            'bottom right corner');
}
