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

// @dart = 2.8

import 'package:flutter/foundation.dart';

import 'framework.dart';

/// A key can be used to persist the widget state in storage after
/// the destruction and will be restored when recreated.
///
/// Each key with its value plus the ancestor chain of other PageStorageKeys need to
/// be unique within the widget's closest ancestor [PageStorage]. To make it possible for a
/// saved value to be found when a widget is recreated, the key's value must
/// not be objects whose identity will change each time the widget is created.
///
/// See also:
///
///  * [PageStorage], which is the closet ancestor for [PageStorageKey].
class PageStorageKey<T> extends ValueKey<T> {
  /// Creates a [ValueKey] that defines where [PageStorage] values will be saved.
  const PageStorageKey(T value) : super(value);
}

@immutable
class _StorageEntryIdentifier {
  const _StorageEntryIdentifier(this.keys)
    : assert(keys != null);

  final List<PageStorageKey<dynamic>> keys;

  bool get isNotEmpty => keys.isNotEmpty;

  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType)
      return false;
    return other is _StorageEntryIdentifier
        && listEquals<PageStorageKey<dynamic>>(other.keys, keys);
  }

  @override
  int get hashCode => hashList(keys);

  @override
  String toString() {
    return 'StorageEntryIdentifier(${keys?.join(":")})';
  }
}

/// A storage bucket associated with a page in an app.
///
/// Useful for storing per-page state that persists across navigations from one
/// page to another.
class PageStorageBucket {
  static bool _maybeAddKey(BuildContext context, List<PageStorageKey<dynamic>> keys) {
    final Widget widget = context.widget;
    final Key key = widget.key;
    if (key is PageStorageKey)
      keys.add(key);
    return widget is! PageStorage;
  }

  List<PageStorageKey<dynamic>> _allKeys(BuildContext context) {
    final List<PageStorageKey<dynamic>> keys = <PageStorageKey<dynamic>>[];
    if (_maybeAddKey(context, keys)) {
      context.visitAncestorElements((Element element) {
        return _maybeAddKey(element, keys);
      });
    }
    return keys;
  }

  _StorageEntryIdentifier _computeIdentifier(BuildContext context) {
    return _StorageEntryIdentifier(_allKeys(context));
  }

  Map<Object, dynamic> _storage;

  /// Write the given data into this page storage bucket using the
  /// specified identifier or an identifier computed from the given context.
  /// The computed identifier is based on the [PageStorageKey]s
  /// found in the path from context to the [PageStorage] widget that
  /// owns this page storage bucket.
  ///
  /// If an explicit identifier is not provided and no [PageStorageKey]s
  /// are found, then the `data` is not saved.
  void writeState(BuildContext context, dynamic data, { Object identifier }) {
    _storage ??= <Object, dynamic>{};
    if (identifier != null) {
      _storage[identifier] = data;
    } else {
      final _StorageEntryIdentifier contextIdentifier = _computeIdentifier(context);
      if (contextIdentifier.isNotEmpty)
        _storage[contextIdentifier] = data;
    }
  }

  /// Read given data from into this page storage bucket using the specified
  /// identifier or an identifier computed from the given context.
  /// The computed identifier is based on the [PageStorageKey]s
  /// found in the path from context to the [PageStorage] widget that
  /// owns this page storage bucket.
  ///
  /// If an explicit identifier is not provided and no [PageStorageKey]s
  /// are found, then null is returned.
  dynamic readState(BuildContext context, { Object identifier }) {
    if (_storage == null)
      return null;
    if (identifier != null)
      return _storage[identifier];
    final _StorageEntryIdentifier contextIdentifier = _computeIdentifier(context);
    return contextIdentifier.isNotEmpty ? _storage[contextIdentifier] : null;
  }
}

/// Establish a subtree in which widgets can opt into persisting states after
/// being destroyed.
///
/// [PageStorage] is used to save and restore values that can outlive the widget.
/// For example, when multiple pages are grouped in tabs, when a page is
/// switched out, its widget is destroyed and its state is lost. By adding a
/// [PageStorage] at the root and adding a [PageStorageKey] to each page, some of the
/// page's state (e.g. the scroll position of a [Scrollable] widget) will be stored
/// automatically in its closest ancestor [PageStorage], and restored when it's
/// switched back.
///
/// Usually you don't need to explicitly use a [PageStorage], since it's already
/// included in routes.
///
/// [PageStorageKey] is used by [Scrollable] if [ScrollController.keepScrollOffset]
/// is enabled to save their [ScrollPosition]s. When more than one
/// scrollable ([ListView], [SingleChildScrollView], [TextField], etc.) appears
/// within the widget's closest ancestor [PageStorage] (such as within the same route),
/// if you want to save all of their positions independently,
/// you should give each of them unique [PageStorageKey]s, or set some of their
/// `keepScrollOffset` false to prevent saving.
///
/// {@tool dartpad --template=freeform}
///
/// This sample shows how to explicitly use a [PageStorage] to
/// store the states of its children pages. Each page includes a scrollable
/// list, whose position is preserved when switching between the tabs thanks to
/// the help of [PageStorageKey].
///
/// ```dart imports
/// import 'package:flutter/material.dart';
/// ```
///
/// ```dart main
/// void main() => runApp(MyApp());
/// ```
///
/// ```dart
/// class MyApp extends StatelessWidget {
///   @override
///   Widget build(BuildContext context) {
///     return MaterialApp(
///       home: MyHomePage(),
///     );
///   }
/// }
///
/// class MyHomePage extends StatefulWidget {
///   @override
///   _MyHomePageState createState() => _MyHomePageState();
/// }
///
/// class _MyHomePageState extends State<MyHomePage> {
///   final List<Widget> pages = <Widget>[
///     ColorBoxPage(
///       key: PageStorageKey('pageOne'),
///     ),
///     ColorBoxPage(
///       key: PageStorageKey('pageTwo'),
///     )
///   ];
///   int currentTab = 0;
///   final PageStorageBucket _bucket = PageStorageBucket();
///
///   @override
///   Widget build(BuildContext context) {
///     return Scaffold(
///       appBar: AppBar(
///         title: Text("Persistence Example"),
///       ),
///       body: PageStorage(
///         child: pages[currentTab],
///         bucket: _bucket,
///       ),
///       bottomNavigationBar: BottomNavigationBar(
///         currentIndex: currentTab,
///         onTap: (int index) {
///           setState(() {
///             currentTab = index;
///           });
///         },
///         items: <BottomNavigationBarItem>[
///           BottomNavigationBarItem(
///             icon: Icon(Icons.home),
///             label: 'page 1',
///           ),
///           BottomNavigationBarItem(
///             icon: Icon(Icons.settings),
///             label: 'page2',
///           ),
///         ],
///       ),
///     );
///   }
/// }
///
/// class ColorBoxPage extends StatelessWidget {
///   ColorBoxPage({
///     Key key,
///   }) : super(key: key);
///
///   @override
///   Widget build(BuildContext context) {
///     return ListView.builder(
///       itemExtent: 250.0,
///       itemBuilder: (context, index) => Container(
///         padding: EdgeInsets.all(10.0),
///         child: Material(
///           color: index % 2 == 0 ? Colors.cyan : Colors.deepOrange,
///           child: Center(
///             child: Text(index.toString()),
///           ),
///         ),
///       ),
///     );
///   }
/// }
/// ```
/// {@end-tool}
///
/// See also:
///
///  * [ModalRoute], which includes this class.
class PageStorage extends StatelessWidget {
  /// Creates a widget that provides a storage bucket for its descendants.
  ///
  /// The [bucket] argument must not be null.
  const PageStorage({
    Key key,
    @required this.bucket,
    @required this.child,
  }) : assert(bucket != null),
       super(key: key);

  /// The widget below this widget in the tree.
  ///
  /// {@macro flutter.widgets.child}
  final Widget child;

  /// The page storage bucket to use for this subtree.
  final PageStorageBucket bucket;

  /// The bucket from the closest instance of this class that encloses the given context.
  ///
  /// Returns null if none exists.
  ///
  /// Typical usage is as follows:
  ///
  /// ```dart
  /// PageStorageBucket bucket = PageStorage.of(context);
  /// ```
  static PageStorageBucket of(BuildContext context) {
    final PageStorage widget = context.findAncestorWidgetOfExactType<PageStorage>();
    return widget?.bucket;
  }

  @override
  Widget build(BuildContext context) => child;
}
