part of sprites;

/// A Sprite is a [Node] that renders a bitmap image to the screen.
class Sprite extends NodeWithSize with SpritePaint {

  /// The texture that the sprite will render to screen.
  ///
  /// If the texture is null, the sprite will be rendered as a red square
  /// marking the bounds of the sprite.
  ///
  ///     mySprite.texture = myTexture;
  Texture texture;

  /// If true, constrains the proportions of the image by scaling it down, if its proportions doesn't match the [size].
  ///
  ///     mySprite.constrainProportions = true;
  bool constrainProportions = false;

  Paint _cachedPaint = new Paint()
    ..setFilterQuality(FilterQuality.low)
    ..isAntiAlias = false;

  /// Creates a new sprite from the provided [texture].
  ///
  ///     var mySprite = new Sprite(myTexture)
  Sprite([this.texture]) : super(Size.zero) {
    if (texture != null) {
      size = texture.size;
      pivot = texture.pivot;
    } else {
      pivot = new Point(0.5, 0.5);
    }
  }

  /// Creates a new sprite from the provided [image].
  ///
  /// var mySprite = new Sprite.fromImage(myImage);
  Sprite.fromImage(Image image) : super(Size.zero) {
    assert(image != null);

    texture = new Texture(image);
    size = texture.size;

    pivot = new Point(0.5, 0.5);
  }

  void paint(PaintingCanvas canvas) {
    // Account for pivot point
    applyTransformForPivot(canvas);

    if (texture != null) {
      double w = texture.size.width;
      double h = texture.size.height;

      if (w <= 0 || h <= 0) return;

      double scaleX = size.width / w;
      double scaleY = size.height / h;

      if (constrainProportions) {
        // Constrain proportions, using the smallest scale and by centering the image
        if (scaleX < scaleY) {
          canvas.translate(0.0, (size.height - scaleX * h) / 2.0);
          scaleY = scaleX;
        } else {
          canvas.translate((size.width - scaleY * w) / 2.0, 0.0);
          scaleX = scaleY;
        }
      }

      canvas.scale(scaleX, scaleY);

      // Setup paint object for opacity and transfer mode
      _updatePaint(_cachedPaint);

      // Do actual drawing of the sprite
      texture.drawTexture(canvas, Point.origin, _cachedPaint);
    } else {
      // Paint a red square for missing texture
      canvas.drawRect(new Rect.fromLTRB(0.0, 0.0, size.width, size.height),
      new Paint()..color = new Color.fromARGB(255, 255, 0, 0));
    }
  }
}

abstract class SpritePaint {
  double _opacity = 1.0;

  /// The opacity of the sprite in the range 0.0 to 1.0.
  ///
  ///     mySprite.opacity = 0.5;
  double get opacity => _opacity;

  void set opacity(double opacity) {
    assert(opacity != null);
    assert(opacity >= 0.0 && opacity <= 1.0);
    _opacity = opacity;
  }

  /// The color to draw on top of the sprite, null if no color overlay is used.
  ///
  ///     // Color the sprite red
  ///     mySprite.colorOverlay = new Color(0x77ff0000);
  Color colorOverlay;

  /// The transfer mode used when drawing the sprite to screen.
  ///
  ///     // Add the colors of the sprite with the colors of the background
  ///     mySprite.transferMode = TransferMode.plusMode;
  TransferMode transferMode;

  void _updatePaint(Paint paint) {
    paint.color = new Color.fromARGB((255.0*_opacity).toInt(), 255, 255, 255);

    if (colorOverlay != null) {
      paint.setColorFilter(new ColorFilter.mode(colorOverlay, TransferMode.srcATop));
    }

    if (transferMode != null) {
      paint.setTransferMode(transferMode);
    }
  }
}
