import 'package:ecosim/src/ecosim/models/boid.dart';
import 'package:flutter/rendering.dart';

import 'models/food.dart';
import 'models/poison.dart';
import '../seeking/models/pointer_indicator.dart';
import 'models/predator.dart';

// Painter for the Ecosystem Simulation
// Renders the simulation world with all the objects
// Defines the low level CustomPainter that is used
// in the Ecosystem Visualizer
class EcosystemSimulationPainter extends CustomPainter {
  final double x;
  final double y;
  final PointerIndicator pointerIndicator;
  final List<Boid> boids;
  final List<PredatorBoid> predators;
  final List<Food> foods;
  final List<Poison> poison;
  final Size screenSize;
  bool drawDebugInfos;

  EcosystemSimulationPainter({
    required this.pointerIndicator,
    required this.x,
    required this.y,
    required this.boids,
    required this.predators,
    required this.foods,
    required this.poison,
    required this.screenSize,
    required this.drawDebugInfos,
  });

  @override
  void paint(Canvas canvas, Size size) {
    // draw world objects
    for (var boid in boids) {
      boid.render(canvas);
      if (drawDebugInfos) boid.renderDebug(canvas);
    }

    for (var predator in predators) {
      predator.render(canvas);
      if (drawDebugInfos) predator.renderDebug(canvas);
    }

    for (var food in foods) {
      food.render(canvas);
    }

    for (var poison in poison) {
      poison.render(canvas);
    }

    // draw world border
    final white = Paint()
      ..color = const Color.fromARGB(255, 255, 255, 255)
      ..style = PaintingStyle.stroke;
    canvas.drawRect(
      Rect.fromCenter(
        center: Offset(screenSize.width / 2, screenSize.height / 2),
        // add 200 to the border as empty space around the border
        // it looks nicer with a small empty space between the simulation world
        // and the visualized world border
        width: screenSize.width + 200,
        height: screenSize.height + 200,
      ),
      white,
    );
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
