import '../color.dart';
import '../image.dart';
import '../draw/fill_rect.dart';

/// Use the top-left pixel of a block for the block color, used by [pixelate].
const int PIXELATE_UPPERLEFT = 0;
/// Use the average of the pixels within a block for the block color, used by
/// [pixelate].
const int PIXELATE_AVERAGE = 1;

/**
 * Pixelate the [src] image.
 *
 * [blockSize] determines the size of the pixelated blocks.
 * If [mode] is [PIXELATE_UPPERLEFT] then the upper-left corner of the block
 * will be used for the block color. Otherwise if [mode] is [PIXELATE_AVERAGE],
 * the average of all the pixels in the block will be used for the block color.
 */
Image pixelate(Image src, int blockSize, {int mode: PIXELATE_UPPERLEFT}) {
  if (blockSize <= 1) {
    return src;
  }

  int bs = blockSize - 1;

  switch (mode) {
    case PIXELATE_UPPERLEFT:
      for (int y = 0; y < src.height; y += blockSize) {
        for (int x = 0; x < src.width; x += blockSize) {
          if (src.boundsSafe(x, y)) {
            int c = src.getPixel(x, y);
            fillRect(src, x, y, x + bs, y + bs, c);
          }
        }
      }
      break;
    case PIXELATE_AVERAGE:
      for (int y = 0; y < src.height; y += blockSize) {
        for (int x = 0; x < src.width; x += blockSize) {
          int a = 0;
          int r = 0;
          int g = 0;
          int b = 0;
          int total = 0;

          for (int cy = 0; cy < blockSize; ++cy) {
            for (int cx = 0; cx < blockSize; ++cx) {
              if (!src.boundsSafe(x + cx, y + cy)) {
                continue;
              }
              int c = src.getPixel(x + cx, y + cy);
              a += getAlpha(c);
              r += getRed(c);
              g += getGreen(c);
              b += getBlue(c);
              total++;
            }
          }

          if (total > 0) {
            int c = getColor(r ~/ total, g ~/ total, b ~/ total, a ~/ total);
            fillRect(src, x, y, x + bs, y + bs, c);
          }
        }
      }
      break;
  }

  return src;
}
