// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

part of observable;

/// A change to an observable instance. */
class ChangeEvent {
  // TODO(sigmund): capture language issues around enums & create a canonical
  // Dart enum design.
  /// Type denoting an in-place update event. */
  static const UPDATE = 0;

  /// Type denoting an insertion event. */
  static const INSERT = 1;

  /// Type denoting a single-remove event. */
  static const REMOVE = 2;

  /// Type denoting events that affect the entire observable instance. For
  /// example, a list operation like clear or sort.
  static const GLOBAL = 3;

  /// The observable instance that changed. */
  final Observable target;

  /// Whether the change was an [INSERT], [REMOVE], or [UPDATE]. */
  final int type;

  /// The value after the change (or inserted value in a list). */
  final newValue;

  /// The value before the change (or removed value from a list). */
  final oldValue;

  /// Property that changed (null for list changes). */
  final String? propertyName;

  /// Index of the list operation. Insertions prepend in front of the given
  /// index (insert at 0 means an insertion at the beginning of the list).
  final int? index;

  /// Factory constructor for property change events. */
  ChangeEvent.property(
      this.target, this.propertyName, this.newValue, this.oldValue)
      : type = UPDATE,
        index = null;

  /// Factory constructor for list change events. */
  ChangeEvent.list(
      this.target, this.type, this.index, this.newValue, this.oldValue)
      : propertyName = null;

  /// Factory constructor for [GLOBAL] change events. */
  ChangeEvent.global(this.target)
      : type = GLOBAL,
        newValue = null,
        oldValue = null,
        propertyName = null,
        index = null;
}

/// A collection of change events on a single observable instance. */
class EventSummary {
  final Observable target;

  // TODO(sigmund): evolve this to track changes per property.
  List<ChangeEvent> events;

  EventSummary(this.target) : events = List<ChangeEvent>.empty();

  void addEvent(ChangeEvent e) {
    events.add(e);
  }

  /// Notify listeners of [target] and parents of [target] about all changes. */
  void notify() {
    if (events.isNotEmpty) {
      for (Observable? obj = target; obj != null; obj = obj.parent) {
        for (final listener in obj.listeners) {
          listener(this);
        }
      }
    }
  }
}

/// A listener of change events. */
typedef ChangeListener = void Function(EventSummary events);
