import 'dart:math';

import 'package:flutter/material.dart';

class BoardPainter extends CustomPainter {
  const BoardPainter(this.currentTetrimino);

  final int currentTetrimino;

  void drawPixels(
    List<List<int>> pixels,
    Canvas canvas,
    double drawSize,
    Color pixelColor,
  ) {
    int blockWidth = 1;
    int blockHeight = 1;
    for (List<int> pixel in pixels) {
      int x = pixel[0] + 1;
      int y = pixel[1] + 1;
      if (x > blockWidth) {
        blockWidth = x;
      }
      if (y > blockHeight) {
        blockHeight = y;
      }
    }

    final double pixelSize = drawSize / (max(blockWidth, blockHeight) + 2);
    final double xOffset =
        (blockHeight > blockWidth) ? (blockHeight - blockWidth) * pixelSize / 2 : 0;
    final double yOffset =
        (blockWidth > blockHeight) ? (blockWidth - blockHeight) * pixelSize / 2 : 0;

    // Fill background
    final paintPixelBackground = Paint();
    paintPixelBackground.color = pixelColor;
    paintPixelBackground.style = PaintingStyle.fill;
    for (List<int> pixel in pixels) {
      final int x = pixel[0];
      final int y = pixel[1];
      final Rect pixelBackground = Rect.fromPoints(
          Offset(xOffset + pixelSize * (x + 1), yOffset + pixelSize * (y + 1)),
          Offset(xOffset + pixelSize * (x + 2), yOffset + pixelSize * (y + 2)));
      canvas.drawRect(pixelBackground, paintPixelBackground);
    }

    // Border lines
    final paintPixelBorder = Paint();
    paintPixelBorder.color = Colors.grey.shade200;
    paintPixelBorder.style = PaintingStyle.stroke;
    paintPixelBorder.strokeWidth = 4;
    for (List<int> pixel in pixels) {
      final int x = pixel[0];
      final int y = pixel[1];
      final Rect rectBackground = Rect.fromPoints(
          Offset(xOffset + pixelSize * (x + 1), yOffset + pixelSize * (y + 1)),
          Offset(xOffset + pixelSize * (x + 2), yOffset + pixelSize * (y + 2)));
      canvas.drawRect(rectBackground, paintPixelBorder);
    }
  }

  @override
  void paint(Canvas canvas, Size size) {
    final double drawSize = min(size.width, size.height);

    // Fill background
    final paintBackground = Paint();
    paintBackground.color = Colors.grey.shade800;
    paintBackground.style = PaintingStyle.fill;

    final Rect rectBackground =
        Rect.fromPoints(const Offset(0, 0), Offset(drawSize, drawSize));
    canvas.drawRect(rectBackground, paintBackground);

    // Add tetrimino
    switch (currentTetrimino) {
      // empty
      case 0:
        break;
      // straight
      case 1:
        drawPixels([
          [0, 0],
          [1, 0],
          [2, 0],
          [3, 0]
        ], canvas, drawSize, Colors.cyan);
        break;
      // square
      case 2:
        drawPixels([
          [0, 0],
          [0, 1],
          [1, 0],
          [1, 1]
        ], canvas, drawSize, Colors.amber);
        break;
      // T
      case 3:
        drawPixels([
          [0, 0],
          [1, 0],
          [2, 0],
          [1, 1]
        ], canvas, drawSize, Colors.purple);
        break;
      // L
      case 4:
        drawPixels([
          [0, 0],
          [0, 1],
          [0, 2],
          [1, 2]
        ], canvas, drawSize, Colors.deepOrange);
        break;
      // skew
      case 5:
        drawPixels([
          [0, 0],
          [0, 1],
          [1, 1],
          [1, 2]
        ], canvas, drawSize, Colors.green);
        break;
      default:
    }
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return false;
  }
}