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

  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;
  }

  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 = new BiIterator<Section>(_dataModel.sections);
    }
    if (values['feed'] != null && currentSection != null) {
      _feedIterator.jumpToValue(currentSection.findFeed(values['feed']));
    } else {
      _feedIterator = new BiIterator<Feed>(_sectionIterator.current.feeds);
    }
    if (values['article'] != null && currentFeed != null) {
      currentArticle.value = currentFeed.findArticle(values['article']);
      _articleIterator.jumpToValue(currentArticle.value);
    } else {
      _articleIterator =
          new 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 = new 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 = new 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 = new BiIterator<Feed>(
          _sectionIterator.current.feeds, _feedIterator.currentIndex.listeners);
      _articleIterator = new 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 = new 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 = new 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 = new BiIterator<Feed>(
        _sectionIterator.current.feeds, _feedIterator.currentIndex.listeners);
    _articleIterator = new BiIterator<Article>(_feedIterator.current.articles,
        _articleIterator.currentIndex.listeners);
  }

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