// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('InvertColors',  (WidgetTester tester) async {
    await tester.pumpWidget(const RepaintBoundary(
      child: SizedBox(
        width: 200.0,
        height: 200.0,
        child: InvertColorTestWidget(
          color: Color.fromRGBO(255, 0, 0, 1.0),
        ),
      ),
    ));

    await expectLater(
      find.byType(RepaintBoundary),
      matchesGoldenFile('invert_colors_test.0.png'),
    );
  }, skip: isBrowser);

  testWidgets('InvertColors and ColorFilter',  (WidgetTester tester) async {
    await tester.pumpWidget(const RepaintBoundary(
      child: SizedBox(
        width: 200.0,
        height: 200.0,
        child: InvertColorTestWidget(
          color: Color.fromRGBO(255, 0, 0, 1.0),
          filter: ColorFilter.mode(Color.fromRGBO(0, 255, 0, 0.5), BlendMode.plus),
        ),
      ),
    ));

    await expectLater(
      find.byType(RepaintBoundary),
      matchesGoldenFile('invert_colors_test.1.png'),
    );
  }, skip: isBrowser);
}

// Draws a rectangle sized by the parent widget with [color], [colorFilter],
// and [invertColors] applied for testing the invert colors.
class InvertColorTestWidget extends LeafRenderObjectWidget {
  const InvertColorTestWidget({
    this.color,
    this.filter,
    Key key,
  }) : super(key: key);

  final Color color;
  final ColorFilter filter;

  @override
  RenderInvertColorTest createRenderObject(BuildContext context) {
    return RenderInvertColorTest(color, filter);
  }
  @override
  void updateRenderObject(BuildContext context, covariant RenderInvertColorTest renderObject) {
    renderObject
      ..color = color
      ..filter = filter;
  }

}

class RenderInvertColorTest extends RenderProxyBox {
  RenderInvertColorTest(this._color, this._filter);

  Color get color => _color;
  Color _color;
  set color(Color value) {
    if (color == value)
      return;
    _color = value;
    markNeedsPaint();
  }


  ColorFilter get filter => _filter;
  ColorFilter _filter;
  set filter(ColorFilter value) {
    if (filter == value)
      return;
    _filter = value;
    markNeedsPaint();
  }

  @override
  void paint(PaintingContext context, Offset offset) {
    final Paint paint = Paint()
      ..style = PaintingStyle.fill
      ..color = color
      ..colorFilter = filter
      ..invertColors = true;
    context.canvas.drawRect(offset & size, paint);
  }
}
