// 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/gestures.dart';
import 'package:flutter/material.dart';

/// Flutter code sample for [TapAndPanGestureRecognizer].

void main() {
  runApp(const TapAndDragToZoomApp());
}

class TapAndDragToZoomApp extends StatelessWidget {
  const TapAndDragToZoomApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Scaffold(
        body: Center(
          child: TapAndDragToZoomWidget(
            child: MyBoxWidget(),
          ),
        ),
      ),
    );
  }
}

class MyBoxWidget extends StatelessWidget {
  const MyBoxWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.blueAccent,
      height: 100.0,
      width: 100.0,
    );
  }
}

// This widget will scale its child up when it detects a drag up, after a
// double tap/click. It will scale the widget down when it detects a drag down,
// after a double tap. Dragging down and then up after a double tap/click will
// zoom the child in/out. The scale of the child will be reset when the drag ends.
class TapAndDragToZoomWidget extends StatefulWidget {
  const TapAndDragToZoomWidget({super.key, required this.child});

  final Widget child;

  @override
  State<TapAndDragToZoomWidget> createState() => _TapAndDragToZoomWidgetState();
}

class _TapAndDragToZoomWidgetState extends State<TapAndDragToZoomWidget> {
  final double scaleMultiplier = -0.0001;
  double _currentScale = 1.0;
  Offset? _previousDragPosition;

  static double _keepScaleWithinBounds(double scale) {
    const double minScale = 0.1;
    const double maxScale = 30;
    if (scale <= 0) {
      return minScale;
    }
    if (scale >= 30) {
      return maxScale;
    }
    return scale;
  }

  void _zoomLogic(Offset currentDragPosition) {
    final double dx = (_previousDragPosition!.dx - currentDragPosition.dx).abs();
    final double dy = (_previousDragPosition!.dy - currentDragPosition.dy).abs();

    if (dx > dy) {
      // Ignore horizontal drags.
      _previousDragPosition = currentDragPosition;
      return;
    }

    if (currentDragPosition.dy < _previousDragPosition!.dy) {
      // Zoom out on drag up.
      setState(() {
        _currentScale += currentDragPosition.dy * scaleMultiplier;
        _currentScale = _keepScaleWithinBounds(_currentScale);
      });
    } else {
      // Zoom in on drag down.
      setState(() {
        _currentScale -= currentDragPosition.dy * scaleMultiplier;
        _currentScale = _keepScaleWithinBounds(_currentScale);
      });
    }
    _previousDragPosition = currentDragPosition;
  }

  @override
  Widget build(BuildContext context) {
    return RawGestureDetector(
      gestures: <Type, GestureRecognizerFactory>{
        TapAndPanGestureRecognizer: GestureRecognizerFactoryWithHandlers<TapAndPanGestureRecognizer>(
          () => TapAndPanGestureRecognizer(),
          (TapAndPanGestureRecognizer instance) {
            instance
              ..onTapDown = (TapDragDownDetails details) {
                _previousDragPosition = details.globalPosition;
              }
              ..onDragStart = (TapDragStartDetails details) {
                if (details.consecutiveTapCount == 2) {
                  _zoomLogic(details.globalPosition);
                }
              }
              ..onDragUpdate = (TapDragUpdateDetails details) {
                if (details.consecutiveTapCount == 2) {
                  _zoomLogic(details.globalPosition);
                }
              }
              ..onDragEnd = (TapDragEndDetails details) {
                if (details.consecutiveTapCount == 2) {
                  setState(() {
                    _currentScale = 1.0;
                  });
                  _previousDragPosition = null;
                }
              };
          }
        ),
      },
      child: Transform.scale(
        scale: _currentScale,
        child: widget.child,
      ),
    );
  }
}
