// 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.

import 'dart:math' as math;

import 'package:flutter/material.dart';

class ExampleDragTarget extends StatefulWidget {
  @override
  ExampleDragTargetState createState() => new ExampleDragTargetState();
}

class ExampleDragTargetState extends State<ExampleDragTarget> {
  Color _color = Colors.grey[500];

  void _handleAccept(Color data) {
    setState(() {
      _color = data;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new DragTarget<Color>(
      onAccept: _handleAccept,
      builder: (BuildContext context, List<Color> data, List<Color> rejectedData) {
        return new Container(
          height: 100.0,
          margin: new EdgeInsets.all(10.0),
          decoration: new BoxDecoration(
            border: new Border.all(
              width: 3.0,
              color: data.isEmpty ? Colors.white : Colors.blue[500]
            ),
            backgroundColor: data.isEmpty ? _color : Colors.grey[200]
          )
        );
      }
    );
  }
}

class Dot extends StatefulWidget {
  Dot({ Key key, this.color, this.size, this.child, this.tappable: false }) : super(key: key);

  final Color color;
  final double size;
  final Widget child;
  final bool tappable;

  @override
  DotState createState() => new DotState();
}
class DotState extends State<Dot> {
  int taps = 0;

  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      onTap: config.tappable ? () { setState(() { taps += 1; }); } : null,
      child: new Container(
        width: config.size,
        height: config.size,
        decoration: new BoxDecoration(
          backgroundColor: config.color,
          border: new Border.all(width: taps.toDouble()),
          shape: BoxShape.circle
        ),
        child: config.child
      )
    );
  }
}

class ExampleDragSource extends StatelessWidget {
  ExampleDragSource({
    Key key,
    this.color,
    this.heavy: false,
    this.under: true,
    this.child
  }) : super(key: key);

  final Color color;
  final bool heavy;
  final bool under;
  final Widget child;

  static const double kDotSize = 50.0;
  static const double kHeavyMultiplier = 1.5;
  static const double kFingerSize = 50.0;

  @override
  Widget build(BuildContext context) {
    double size = kDotSize;
    if (heavy)
      size *= kHeavyMultiplier;

    Widget contents = new DefaultTextStyle(
      style: Theme.of(context).textTheme.body1.copyWith(textAlign: TextAlign.center),
      child: new Dot(
        color: color,
        size: size,
        child: new Center(child: child)
      )
    );

    Widget feedback = new Opacity(
      opacity: 0.75,
      child: contents
    );

    Offset feedbackOffset;
    DragAnchor anchor;
    if (!under) {
      feedback = new Transform(
        transform: new Matrix4.identity()
                     ..translate(-size / 2.0, -(size / 2.0 + kFingerSize)),
        child: feedback
      );
      feedbackOffset = const Offset(0.0, -kFingerSize);
      anchor = DragAnchor.pointer;
    } else {
      feedbackOffset = Offset.zero;
      anchor = DragAnchor.child;
    }

    if (heavy) {
      return new LongPressDraggable<Color>(
        data: color,
        child: contents,
        feedback: feedback,
        feedbackOffset: feedbackOffset,
        dragAnchor: anchor
      );
    } else {
      return new Draggable<Color>(
        data: color,
        child: contents,
        feedback: feedback,
        feedbackOffset: feedbackOffset,
        dragAnchor: anchor
      );
    }
  }
}

class DashOutlineCirclePainter extends CustomPainter {
  const DashOutlineCirclePainter();

  static const int segments = 17;
  static const double deltaTheta = math.PI * 2 / segments; // radians
  static const double segmentArc = deltaTheta / 2.0; // radians
  static const double startOffset = 1.0; // radians

  @override
  void paint(Canvas canvas, Size size) {
    final double radius = size.shortestSide / 2.0;
    final Paint paint = new Paint()
      ..color = const Color(0xFF000000)
      ..style = PaintingStyle.stroke
      ..strokeWidth = radius / 10.0;
    final Path path = new Path();
    final Rect box = Point.origin & size;
    for (double theta = 0.0; theta < math.PI * 2.0; theta += deltaTheta)
      path.addArc(box, theta + startOffset, segmentArc);
    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(DashOutlineCirclePainter oldPainter) => false;
}

class MovableBall extends StatelessWidget {
  MovableBall(this.position, this.ballPosition, this.callback);

  final int position;
  final int ballPosition;
  final ValueChanged<int> callback;

  static final GlobalKey kBallKey = new GlobalKey();
  static const double kBallSize = 50.0;

  @override
  Widget build(BuildContext context) {
    Widget ball = new DefaultTextStyle(
      style: Theme.of(context).textTheme.body1.copyWith(
        textAlign: TextAlign.center,
        color: Colors.white
      ),
      child: new Dot(
        key: kBallKey,
        color: Colors.blue[700],
        size: kBallSize,
        tappable: true,
        child: new Center(child: new Text('BALL'))
      )
    );
    Widget dashedBall = new Container(
      width: kBallSize,
      height: kBallSize,
      child: new CustomPaint(
        painter: const DashOutlineCirclePainter()
      )
    );
    if (position == ballPosition) {
      return new Draggable<bool>(
        data: true,
        child: ball,
        childWhenDragging: dashedBall,
        feedback: ball,
        maxSimultaneousDrags: 1
      );
    } else {
      return new DragTarget<bool>(
        onAccept: (bool data) { callback(position); },
        builder: (BuildContext context, List<bool> accepted, List<bool> rejected) {
          return dashedBall;
        }
      );
    }
  }
}

class DragAndDropApp extends StatefulWidget {
  @override
  DragAndDropAppState createState() => new DragAndDropAppState();
}

class DragAndDropAppState extends State<DragAndDropApp> {
  int position = 1;

  void moveBall(int newPosition) {
    setState(() { position = newPosition; });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Drag and Drop Flutter Demo')
      ),
      body: new Column(
        children: <Widget>[
          new Flexible(
            child: new Row(
              children: <Widget>[
                new ExampleDragSource(
                  color: Colors.yellow[300],
                  under: true,
                  heavy: false,
                  child: new Text('under')
                ),
                new ExampleDragSource(
                  color: Colors.green[300],
                  under: false,
                  heavy: true,
                  child: new Text('long-press above')
                ),
                new ExampleDragSource(
                  color: Colors.indigo[300],
                  under: false,
                  heavy: false,
                  child: new Text('above')
                ),
              ],
              crossAxisAlignment: CrossAxisAlignment.center,
              mainAxisAlignment: MainAxisAlignment.spaceAround
            )
          ),
          new Flexible(
            child: new Row(
              children: <Widget>[
                new Flexible(child: new ExampleDragTarget()),
                new Flexible(child: new ExampleDragTarget()),
                new Flexible(child: new ExampleDragTarget()),
                new Flexible(child: new ExampleDragTarget()),
              ]
            )
          ),
          new Flexible(
            child: new Row(
              children: <Widget>[
                new MovableBall(1, position, moveBall),
                new MovableBall(2, position, moveBall),
                new MovableBall(3, position, moveBall),
              ],
              mainAxisAlignment: MainAxisAlignment.spaceAround
            )
          ),
        ]
      )
    );
  }
}

void main() {
  runApp(new MaterialApp(
    title: 'Drag and Drop Flutter Demo',
    routes: <String, WidgetBuilder>{
     '/': (BuildContext context) => new DragAndDropApp()
    }
  ));
}
