// 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 'dart:ui' show Shader;

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

Shader createShader(Rect bounds) {
  return const LinearGradient(
    begin: Alignment.topCenter,
    end: Alignment.bottomCenter,
    colors: <Color>[Color(0x00FFFFFF), Color(0xFFFFFFFF)],
    stops: <double>[0.1, 0.35],
  ).createShader(bounds);
}


void main() {
  testWidgets('Can be constructed', (WidgetTester tester) async {
    const Widget child = SizedBox(width: 100.0, height: 100.0);
    await tester.pumpWidget(const ShaderMask(child: child, shaderCallback: createShader));
  }, skip: isBrowser);

  testWidgets('Bounds rect includes offset', (WidgetTester tester) async {
    Rect shaderBounds;
    Shader recordShaderBounds(Rect bounds) {
      shaderBounds = bounds;
      return createShader(bounds);
    }

    final Widget widget = Align(
      alignment: Alignment.center,
      child: SizedBox(
        width: 400.0,
        height: 400.0,
        child: ShaderMask(
          shaderCallback: recordShaderBounds,
          child: const SizedBox(width: 100.0, height: 100.0),
        ),
      ),
    );
    await tester.pumpWidget(widget);

    // The shader bounds rectangle should reflect the position of the centered SizedBox.
    expect(shaderBounds, equals(const Rect.fromLTWH(0.0, 0.0, 400.0, 400.0)));
  }, skip: isBrowser);


  testWidgets('Bounds rect includes offset visual inspection', (WidgetTester tester) async {
    final Widget widgetBottomRight = Container(
      width: 400,
      height: 400,
      color: const Color(0xFFFFFFFF),
      child: RepaintBoundary(
        child: Align(
          alignment: Alignment.bottomRight,
          child: ShaderMask(
            shaderCallback: (Rect bounds) => const RadialGradient(
              center: Alignment.center,
              radius: 0.05,
              colors:  <Color>[Color(0xFFFF0000),  Color(0xFF00FF00)],
              tileMode: TileMode.mirror,
            ).createShader(bounds),
            child: Container(
              width: 100,
              height: 100,
              color: const Color(0xFFFFFFFF),
            ),
          ),
        ),
      ),
    );
    await tester.pumpWidget(widgetBottomRight);

    await expectLater(
      find.byType(RepaintBoundary),
      matchesGoldenFile('shader_mask.bounds.matches_bottom_right.png'),
    );

    final Widget widgetTopLeft = Container(
      width: 400,
      height: 400,
      color: const Color(0xFFFFFFFF),
      child: RepaintBoundary(
        child: Align(
          alignment: Alignment.topLeft,
          child: ShaderMask(
            shaderCallback: (Rect bounds) => const RadialGradient(
              center: Alignment.center,
              radius: 0.05,
              colors:  <Color>[Color(0xFFFF0000),  Color(0xFF00FF00)],
              tileMode: TileMode.mirror,
            ).createShader(bounds),
            child: Container(
              width: 100,
              height: 100,
              color: const Color(0xFFFFFFFF),
            ),
          ),
        ),
      ),
    );
    await tester.pumpWidget(widgetTopLeft);

    await expectLater(
      find.byType(RepaintBoundary),
      matchesGoldenFile('shader_mask.bounds.matches_top_left.png'),
    );
  }, skip: isBrowser);
}
