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

// @dart = 2.9

part of swarmlib;

/// The top-level class for the UI state. UI state is essentially a "model" from
/// the view's perspective but whose data just describes the UI itself. It
/// contains data like the currently selected story, etc.
// TODO(jimhug): Split the two classes here into framework and app-specific.
class SwarmState extends UIState {
  /// Core data source for the app. */
  final Sections _dataModel;

  /// Which article the user is currently viewing, or null if they aren't
  /// viewing an Article.
  final ObservableValue<Article> currentArticle;

  /// Which article the user currently has selected (for traversing articles
  /// via keyboard shortcuts).
  final ObservableValue<Article> selectedArticle;

  /// True if the story view is maximized and the top and bottom UI elements
  /// are hidden.
  final ObservableValue<bool> storyMaximized;

  /// True if the maximized story, if any, is being displayed in text mode
  /// rather than as an embedded web-page.
  final ObservableValue<bool> storyTextMode;

  /// Which article the user currently has selected (by keyboard shortcuts),
  /// or null if an article isn't selected by the keyboard.
  BiIterator<Article> _articleIterator;

  /// Which feed is currently selected (for keyboard shortcuts).
  BiIterator<Feed> _feedIterator;

  /// Which section is currently selected (for keyboard shortcuts).
  BiIterator<Section> _sectionIterator;

  SwarmState(this._dataModel)
      : currentArticle = ObservableValue<Article>(null),
        selectedArticle = ObservableValue<Article>(null),
        storyMaximized = ObservableValue<bool>(false),
        storyTextMode = ObservableValue<bool>(true) {
    startHistoryTracking();
    // TODO(efortuna): consider having this class just hold observable
    // currentIndecies instead of iterators with observablevalues..
    _sectionIterator = BiIterator<Section>(_dataModel.sections);
    _feedIterator = BiIterator<Feed>(_sectionIterator.current.feeds);
    _articleIterator = BiIterator<Article>(_feedIterator.current.articles);

    currentArticle.addChangeListener((e) {
      _articleIterator.jumpToValue(currentArticle.value);
    });
  }

  /// Registers an event to fire on any state change
  ///
  /// TODO(jmesserly): fix this so we don't have to enumerate all of our fields
  /// again. One idea here is UIState becomes Observable, Observables have
  /// parents and notifications bubble up the parent chain.
  void addChangeListener(ChangeListener listener) {
    _sectionIterator.currentIndex.addChangeListener(listener);
    _feedIterator.currentIndex.addChangeListener(listener);
    _articleIterator.currentIndex.addChangeListener(listener);
    currentArticle.addChangeListener(listener);
  }

  @override
  Map<String, String> toHistory() {
    final data = {};
    data['section'] = currentSection.id;
    data['feed'] = currentFeed.id;
    if (currentArticle.value != null) {
      data['article'] = currentArticle.value.id;
    }
    return data;
  }

  @override
  void loadFromHistory(Map values) {
    // TODO(jimhug): There's a better way of doing this...
    if (values['section'] != null) {
      _sectionIterator
          .jumpToValue(_dataModel.findSectionById(values['section']));
    } else {
      _sectionIterator = BiIterator<Section>(_dataModel.sections);
    }
    if (values['feed'] != null && currentSection != null) {
      _feedIterator.jumpToValue(currentSection.findFeed(values['feed']));
    } else {
      _feedIterator = BiIterator<Feed>(_sectionIterator.current.feeds);
    }
    if (values['article'] != null && currentFeed != null) {
      currentArticle.value = currentFeed.findArticle(values['article']);
      _articleIterator.jumpToValue(currentArticle.value);
    } else {
      _articleIterator = BiIterator<Article>(_feedIterator.current.articles);
      currentArticle.value = null;
    }

    storyMaximized.value = false;
  }

  /// Move the currentArticle pointer to the next item in the Feed.
  void goToNextArticle() {
    currentArticle.value = _articleIterator.next();
    selectedArticle.value = _articleIterator.current;
  }

  /// Move the currentArticle pointer to the previous item in the Feed.
  void goToPreviousArticle() {
    currentArticle.value = _articleIterator.previous();
    selectedArticle.value = _articleIterator.current;
  }

  /// Move the selectedArticle pointer to the next item in the Feed.
  void goToNextSelectedArticle() {
    selectedArticle.value = _articleIterator.next();
  }

  /// Move the selectedArticle pointer to the previous item in the Feed.
  void goToPreviousSelectedArticle() {
    selectedArticle.value = _articleIterator.previous();
  }

  /// Move the pointers for selectedArticle to point to the next
  /// Feed.
  void goToNextFeed() {
    var newFeed = _feedIterator.next();
    int oldIndex = _articleIterator.currentIndex.value;

    _articleIterator = BiIterator<Article>(
        newFeed.articles, _articleIterator.currentIndex.listeners);

    _articleIterator.currentIndex.value = oldIndex;
    selectedArticle.value = _articleIterator.current;
  }

  /// Move the pointers for selectedArticle to point to the previous
  /// DataSource.
  void goToPreviousFeed() {
    var newFeed = _feedIterator.previous();
    int oldIndex = _articleIterator.currentIndex.value;

    _articleIterator = BiIterator<Article>(
        newFeed.articles, _articleIterator.currentIndex.listeners);
    _articleIterator.currentIndex.value = oldIndex;
    selectedArticle.value = _articleIterator.current;
  }

  /// Move to the next section (page) of feeds in the UI.
  /// @param index the previous index (how far down in a given feed)
  /// from the Source we are moving from.
  /// This method takes sliderMenu in the event that it needs to move
  /// to a previous section, it can notify the UI to update.
  void goToNextSection(SliderMenu sliderMenu) {
    //TODO(efortuna): move sections?
    var oldSection = currentSection;
    int oldIndex = _articleIterator.currentIndex.value;
    sliderMenu.selectNext(true);
    // This check prevents our selector from wrapping around when we try to
    // go to the "next section", but we're already at the last section.
    if (oldSection != _sectionIterator.current) {
      _feedIterator = BiIterator<Feed>(
          _sectionIterator.current.feeds, _feedIterator.currentIndex.listeners);
      _articleIterator = BiIterator<Article>(_feedIterator.current.articles,
          _articleIterator.currentIndex.listeners);
      _articleIterator.currentIndex.value = oldIndex;
      selectedArticle.value = _articleIterator.current;
    }
  }

  /// Move to the previous section (page) of feeds in the UI.
  /// @param index the previous index (how far down in a given feed)
  /// from the Source we are moving from.
  /// @param oldSection the original starting section (before the slider
  /// menu moved)
  /// This method takes sliderMenu in the event that it needs to move
  /// to a previous section, it can notify the UI to update.
  void goToPreviousSection(SliderMenu sliderMenu) {
    //TODO(efortuna): don't pass sliderMenu here. Just update in view!
    var oldSection = currentSection;
    int oldIndex = _articleIterator.currentIndex.value;
    sliderMenu.selectPrevious(true);

    // This check prevents our selector from wrapping around when we try to
    // go to the "previous section", but we're already at the first section.
    if (oldSection != _sectionIterator.current) {
      _feedIterator = BiIterator<Feed>(
          _sectionIterator.current.feeds, _feedIterator.currentIndex.listeners);
      // Jump to back of feed set if we are moving backwards through sections.
      _feedIterator.currentIndex.value = _feedIterator.list.length - 1;
      _articleIterator = BiIterator<Article>(_feedIterator.current.articles,
          _articleIterator.currentIndex.listeners);
      _articleIterator.currentIndex.value = oldIndex;
      selectedArticle.value = _articleIterator.current;
    }
  }

  /// Set the selected story as the current story (for viewing in the larger
  /// Story View.)
  void selectStoryAsCurrent() {
    currentArticle.value = _articleIterator.current;
    selectedArticle.value = _articleIterator.current;
  }

  /// Remove our currentArticle selection, to move back to the Main Grid view.
  void clearCurrentArticle() {
    currentArticle.value = null;
  }

  /// Set the selectedArticle as the first item in that section (UI page).
  void goToFirstArticleInSection() {
    selectedArticle.value = _articleIterator.current;
  }

  /// Returns true if the UI is currently in the Story View state.
  bool get inMainView => currentArticle.value == null;

  /// Returns true if we currently have an Article selected (for keyboard
  /// shortcuts browsing).
  bool get hasArticleSelected => selectedArticle.value != null;

  /// Mark the current article as read
  bool markCurrentAsRead() {
    currentArticle.value.unread.value = false;
  }

  /// The user has moved to a new section (page). This can occur either
  /// if the user clicked on a section page, or used keyboard shortcuts.
  /// The default behavior is to move to the first article in the first
  /// column. The location of the selected item depends on the previous
  /// selected item location if the user used keyboard shortcuts. These
  /// are manipulated in goToPrevious/NextSection().
  void moveToNewSection(String sectionTitle) {
    _sectionIterator.currentIndex.value =
        _dataModel.findSectionIndex(sectionTitle);
    _feedIterator = BiIterator<Feed>(
        _sectionIterator.current.feeds, _feedIterator.currentIndex.listeners);
    _articleIterator = BiIterator<Article>(_feedIterator.current.articles,
        _articleIterator.currentIndex.listeners);
  }

  Section get currentSection => _sectionIterator.current;
  Feed get currentFeed => _feedIterator.current;
}
