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

// This example shows how to use process input events in the underlying render
// tree.

import 'package:flutter/material.dart'; // Imported just for its color palette.
import 'package:flutter/rendering.dart';

// Material design colors. :p
List<Color> _kColors = <Color>[
  Colors.teal,
  Colors.amber,
  Colors.purple,
  Colors.lightBlue,
  Colors.deepPurple,
  Colors.lime,
];

/// A simple model object for a dot that reacts to pointer pressure.
class Dot {
  Dot({ Color color }) : _paint = new Paint()..color = color;

  final Paint _paint;
  Offset position = Offset.zero;
  double radius = 0.0;

  void update(PointerEvent event) {
    position = event.position;
    radius = 5 + (95 * event.pressure);
  }

  void paint(Canvas canvas, Offset offset) {
    canvas.drawCircle(position + offset, radius, _paint);
  }
}

/// A render object that draws dots under each pointer.
class RenderDots extends RenderBox {
  RenderDots();

  /// State to remember which dots to paint.
  final Map<int, Dot> _dots = <int, Dot>{};

  /// Indicates that the size of this render object depends only on the
  /// layout constraints provided by the parent.
  @override
  bool get sizedByParent => true;

  /// By selecting the biggest value permitted by the incoming constraints
  /// during layout, this function makes this render object as large as
  /// possible (i.e., fills the entire screen).
  @override
  void performResize() {
    size = constraints.biggest;
  }

  /// Makes this render object hittable so that it receives pointer events.
  @override
  bool hitTestSelf(Offset position) => true;

  /// Processes pointer events by mutating state and invalidating its previous
  /// painting commands.
  @override
  void handleEvent(PointerEvent event, BoxHitTestEntry entry) {
    if (event is PointerDownEvent) {
      final Color color = _kColors[event.pointer.remainder(_kColors.length)];
      _dots[event.pointer] = new Dot(color: color)..update(event);
      // We call markNeedsPaint to indicate that our painting commands have
      // changed and that paint needs to be called before displaying a new frame
      // to the user. It's harmless to call markNeedsPaint multiple times
      // because the render tree will ignore redundant calls.
      markNeedsPaint();
    } else if (event is PointerUpEvent || event is PointerCancelEvent) {
      _dots.remove(event.pointer);
      markNeedsPaint();
    } else if (event is PointerMoveEvent) {
      _dots[event.pointer].update(event);
      markNeedsPaint();
    }
  }

  /// Issues new painting commands.
  @override
  void paint(PaintingContext context, Offset offset) {
    final Canvas canvas = context.canvas;
    // The "size" property indicates the size of that this render box was
    // alotted during layout. Here we paint our bounds white. Notice that we're
    // located at "offset" from the origin of the canvas' coordinate system.
    // Passing offset during the render tree's paint walk is an optimization to
    // avoid having to change the origin of the canvas's coordinate system too
    // often.
    canvas.drawRect(offset & size, new Paint()..color = const Color(0xFFFFFFFF));

    // We iterate through our model and paint each dot.
    for (Dot dot in _dots.values)
      dot.paint(canvas, offset);
  }
}

void main() {
  // Create some styled text to tell the user to interact with the app.
  final RenderParagraph paragraph = new RenderParagraph(
    const TextSpan(
      style: const TextStyle(color: Colors.black87),
      text: 'Touch me!',
    ),
    textDirection: TextDirection.ltr,
  );
  // A stack is a render object that layers its children on top of each other.
  // The bottom later is our RenderDots object, and on top of that we show the
  // text.
  final RenderStack stack = new RenderStack(
    textDirection: TextDirection.ltr,
    children: <RenderBox>[
      new RenderDots(),
      paragraph,
    ],
  );
  // The "parentData" field of a render object is controlled by the render
  // object's parent render object. Now that we've added the paragraph as a
  // child of the RenderStack, the paragraph's parentData field has been
  // populated with a StackParentData, which we can use to provide input to the
  // stack's layout algorithm.
  //
  // We use the StackParentData of the paragraph to position the text in the top
  // left corner of the screen.
  final StackParentData paragraphParentData = paragraph.parentData;
  paragraphParentData
    ..top = 40.0
    ..left = 20.0;

  // Finally, we attach the render tree we've built to the screen.
  new RenderingFlutterBinding(root: stack);
}
