// 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';

import 'rendering_tester.dart';

void main() {
  TestRenderingFlutterBinding.ensureInitialized();

  test('RenderSliverOpacity does not composite if it is transparent', () {
    final RenderSliverOpacity renderSliverOpacity = RenderSliverOpacity(
      opacity: 0.0,
      sliver: RenderSliverToBoxAdapter(
        child: RenderSizedBox(const Size(1.0, 1.0)), // size doesn't matter
      ),
    );

    final RenderViewport root = RenderViewport(
      crossAxisDirection: AxisDirection.right,
      offset: ViewportOffset.zero(),
      cacheExtent: 250.0,
      children: <RenderSliver>[renderSliverOpacity],
    );

    layout(root, phase: EnginePhase.composite);
    expect(renderSliverOpacity.needsCompositing, false);
  });

  test('RenderSliverOpacity does composite if it is opaque', () {
    final RenderSliverOpacity renderSliverOpacity = RenderSliverOpacity(
      sliver: RenderSliverToBoxAdapter(
        child: RenderSizedBox(const Size(1.0, 1.0)), // size doesn't matter
      ),
    );

    final RenderViewport root = RenderViewport(
      crossAxisDirection: AxisDirection.right,
      offset: ViewportOffset.zero(),
      cacheExtent: 250.0,
      children: <RenderSliver>[renderSliverOpacity],
    );

    layout(root, phase: EnginePhase.composite);
    expect(renderSliverOpacity.needsCompositing, true);
  });
  test('RenderSliverOpacity reuses its layer', () {
    final RenderSliverOpacity renderSliverOpacity = RenderSliverOpacity(
      opacity: 0.5,
      sliver: RenderSliverToBoxAdapter(
        child: RenderSizedBox(const Size(1.0, 1.0)), // size doesn't matter
      ),
    );

    final RenderViewport root = RenderViewport(
      crossAxisDirection: AxisDirection.right,
      offset: ViewportOffset.zero(),
      cacheExtent: 250.0,
      children: <RenderSliver>[renderSliverOpacity],
    );

    expect(renderSliverOpacity.debugLayer, null);
    layout(root, phase: EnginePhase.paint, constraints: BoxConstraints.tight(const Size(10, 10)));
    final ContainerLayer layer = renderSliverOpacity.debugLayer!;
    expect(layer, isNotNull);

    // Mark for repaint otherwise pumpFrame is a noop.
    renderSliverOpacity.markNeedsPaint();
    expect(renderSliverOpacity.debugNeedsPaint, true);
    pumpFrame(phase: EnginePhase.paint);
    expect(renderSliverOpacity.debugNeedsPaint, false);
    expect(renderSliverOpacity.debugLayer, same(layer));
  });

  test('RenderSliverAnimatedOpacity does not composite if it is transparent', () async {
    final Animation<double> opacityAnimation = AnimationController(
      vsync: FakeTickerProvider(),
    )..value = 0.0;

    final RenderSliverAnimatedOpacity renderSliverAnimatedOpacity = RenderSliverAnimatedOpacity(
      opacity: opacityAnimation,
      sliver: RenderSliverToBoxAdapter(
        child: RenderSizedBox(const Size(1.0, 1.0)), // size doesn't matter
      ),
    );

    final RenderViewport root = RenderViewport(
      crossAxisDirection: AxisDirection.right,
      offset: ViewportOffset.zero(),
      cacheExtent: 250.0,
      children: <RenderSliver>[renderSliverAnimatedOpacity],
    );

    layout(root, phase: EnginePhase.composite);
    expect(renderSliverAnimatedOpacity.needsCompositing, false);
  });

  test('RenderSliverAnimatedOpacity does composite if it is partially opaque', () {
    final Animation<double> opacityAnimation = AnimationController(
      vsync: FakeTickerProvider(),
    )..value = 0.5;

    final RenderSliverAnimatedOpacity renderSliverAnimatedOpacity = RenderSliverAnimatedOpacity(
      opacity: opacityAnimation,
      sliver: RenderSliverToBoxAdapter(
        child: RenderSizedBox(const Size(1.0, 1.0)), // size doesn't matter
      ),
    );

    final RenderViewport root = RenderViewport(
      crossAxisDirection: AxisDirection.right,
      offset: ViewportOffset.zero(),
      cacheExtent: 250.0,
      children: <RenderSliver>[renderSliverAnimatedOpacity],
    );

    layout(root, phase: EnginePhase.composite);
    expect(renderSliverAnimatedOpacity.needsCompositing, true);
  });

  test('RenderSliverAnimatedOpacity does not composite if it is opaque', () {
    final Animation<double> opacityAnimation = AnimationController(
      vsync: FakeTickerProvider(),
    )..value = 1.0;

    final RenderSliverAnimatedOpacity renderSliverAnimatedOpacity = RenderSliverAnimatedOpacity(
      opacity: opacityAnimation,
      sliver: RenderSliverToBoxAdapter(
        child: RenderSizedBox(const Size(1.0, 1.0)), // size doesn't matter
      ),
    );

    final RenderViewport root = RenderViewport(
      crossAxisDirection: AxisDirection.right,
      offset: ViewportOffset.zero(),
      cacheExtent: 250.0,
      children: <RenderSliver>[renderSliverAnimatedOpacity],
    );

    layout(root, phase: EnginePhase.composite);
    expect(renderSliverAnimatedOpacity.needsCompositing, false);
  });

  test('RenderSliverAnimatedOpacity reuses its layer', () {
    final Animation<double> opacityAnimation = AnimationController(
      vsync: FakeTickerProvider(),
    )..value = 0.5;  // must not be 0 or 1.0. Otherwise, it won't create a layer

    final RenderSliverAnimatedOpacity renderSliverAnimatedOpacity = RenderSliverAnimatedOpacity(
      opacity: opacityAnimation,
      sliver: RenderSliverToBoxAdapter(
        child: RenderSizedBox(const Size(1.0, 1.0)), // size doesn't matter
      ),
    );

    final RenderViewport root = RenderViewport(
      crossAxisDirection: AxisDirection.right,
      offset: ViewportOffset.zero(),
      cacheExtent: 250.0,
      children: <RenderSliver>[renderSliverAnimatedOpacity],
    );

    expect(renderSliverAnimatedOpacity.debugLayer, null);
    layout(root, phase: EnginePhase.paint, constraints: BoxConstraints.tight(const Size(10, 10)));
    final ContainerLayer layer = renderSliverAnimatedOpacity.debugLayer!;
    expect(layer, isNotNull);

    // Mark for repaint otherwise pumpFrame is a noop.
    renderSliverAnimatedOpacity.markNeedsPaint();
    expect(renderSliverAnimatedOpacity.debugNeedsPaint, true);
    pumpFrame(phase: EnginePhase.paint);
    expect(renderSliverAnimatedOpacity.debugNeedsPaint, false);
    expect(renderSliverAnimatedOpacity.debugLayer, same(layer));
  });
}
