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

// TODO(jacobr): there is a lot of dead code in this class. Checking is as is
// and then doing a large pass to remove functionality that doesn't make sense
// given the UI layout.

/// Front page of Swarm.
// TODO(jacobr): this code now needs a large refactoring.
// Suggested refactorings:
//  Move animation specific code into helper classes.
class FrontView extends CompositeView {
  final Swarm swarm;

  /// View containing all UI anchored to the top of the page. */
  CompositeView topView;

  /// View containing all UI anchored to the left side of the page. */
  CompositeView bottomView;
  HeaderView headerView;
  SliderMenu sliderMenu;

  /// When the user is viewing a story, the data source for that story is
  /// detached from the section and shown at the bottom of the screen. This keeps
  /// track of that so we can restore it later.
  DataSourceView detachedView;

  /// Map from section title to the View that shows this section.  This
  /// is populated lazily.
  StoryContentView storyView;
  bool nextPrevShown;

  ConveyorView sections;

  /// The set of keys that produce a given behavior (going down one story,
  /// navigating to the column to the right, etc).
  //TODO(jmesserly): we need a key code enumeration
  final Set downKeyPresses;
  final Set upKeyPresses;
  final Set rightKeyPresses;
  final Set leftKeyPresses;
  final Set openKeyPresses;
  final Set backKeyPresses;
  final Set nextPageKeyPresses;
  final Set previousPageKeyPresses;

  FrontView(this.swarm)
      : downKeyPresses = {74 /*j*/, 40 /*down*/},
        upKeyPresses = {75 /*k*/, 38 /*up*/},
        rightKeyPresses = {39 /*right*/, 68 /*d*/, 76 /*l*/},
        leftKeyPresses = {37 /*left*/, 65 /*a*/, 72 /*h*/},
        openKeyPresses = {13 /*enter*/, 79 /*o*/},
        backKeyPresses = {8 /*delete*/, 27 /*escape*/},
        nextPageKeyPresses = {78 /*n*/},
        previousPageKeyPresses = {80 /*p*/},
        nextPrevShown = false,
        super('front-view fullpage') {
    topView = CompositeView('top-view', false, false, false);

    headerView = HeaderView(swarm);
    topView.addChild(headerView);

    sliderMenu = SliderMenu(swarm.sections.sectionTitles, (sectionTitle) {
      swarm.state.moveToNewSection(sectionTitle);
      _onSectionSelected(sectionTitle);
      // Start with no articles selected.
      swarm.state.selectedArticle.value = null;
    });
    topView.addChild(sliderMenu);
    addChild(topView);

    bottomView = CompositeView('bottom-view', false, false, false);
    addChild(bottomView);

    sections = ConveyorView();
    sections.viewSelected = _onSectionTransitionEnded;
  }

  SectionView get currentSection {
    var view = sections.selectedView;
    // TODO(jmesserly): this code works around a bug in the DartC --optimize
    if (view == null) {
      view = sections.childViews[0];
      sections.selectView(view);
    }
    return view;
  }

  @override
  void afterRender(Element node) {
    _createSectionViews();
    attachWatch(swarm.state.currentArticle, (e) {
      _refreshCurrentArticle();
    });
    attachWatch(swarm.state.storyMaximized, (e) {
      _refreshMaximized();
    });
  }

  void _refreshCurrentArticle() {
    if (!swarm.state.inMainView) {
      _animateToStory(swarm.state.currentArticle.value);
    } else {
      _animateToMainView();
    }
  }

  /// Animates back from the story view to the main grid view.
  void _animateToMainView() {
    sliderMenu.removeClass('hidden');
    storyView.addClass('hidden-story');
    currentSection.storyMode = false;

    headerView.startTransitionToMainView();

    currentSection.dataSourceView
        .reattachSubview(detachedView.source, detachedView, true);

    storyView.node.onTransitionEnd.first.then((e) {
      currentSection.hidden = false;
      // TODO(rnystrom): Should move this "mode" into SwarmState and have
      // header view respond to change events itself.
      removeChild(storyView);
      storyView = null;
      detachedView.removeClass('sel');
      detachedView = null;
    });
  }

  void _animateToStory(Article item) {
    final source = item.dataSource;

    if (detachedView != null && detachedView.source != source) {
      // Ignore spurious item selection clicks that occur while a data source
      // is already selected.  These are likely clicks that occur while an
      // animation is in progress.
      return;
    }

    if (storyView != null) {
      // Remove the old story. This happens if we're already in the Story View
      // and the user has clicked to see a new story.
      removeChild(storyView);

      // Create the new story view and place in the frame.
      storyView = addChild(StoryContentView(swarm, item));
    } else {
      // We are animating from the main view to the story view.
      // TODO(jmesserly): make this code better
      final view = currentSection.findView(source);

      final newPosition =
          FxUtil.computeRelativePosition(view.node, bottomView.node);
      currentSection.dataSourceView.detachSubview(view.source);
      detachedView = view;

      FxUtil.setPosition(view.node, newPosition);
      bottomView.addChild(view);
      view.addClass('sel');
      currentSection.storyMode = true;

      // Create the new story view.
      storyView = StoryContentView(swarm, item);
      Timer(const Duration(milliseconds: 0), () {
        _animateDataSourceToMinimized();

        sliderMenu.addClass('hidden');
        // Make the fancy sliding into the window animation.
        Timer(const Duration(milliseconds: 0), () {
          storyView.addClass('hidden-story');
          addChild(storyView);
          Timer(const Duration(milliseconds: 0), () {
            storyView.removeClass('hidden-story');
          });
          headerView.endTransitionToStoryView();
        });
      });
    }
  }

  void _refreshMaximized() {
    if (swarm.state.storyMaximized.value) {
      _animateDataSourceToMaximized();
    } else {
      _animateDataSourceToMinimized();
    }
  }

  void _animateDataSourceToMaximized() {
    FxUtil.setWebkitTransform(topView.node, 0, -HeaderView.HEIGHT);
    if (detachedView != null) {
      FxUtil.setWebkitTransform(
          detachedView.node, 0, -DataSourceView.TAB_ONLY_HEIGHT);
    }
  }

  void _animateDataSourceToMinimized() {
    if (detachedView != null) {
      FxUtil.setWebkitTransform(detachedView.node, 0, 0);
      FxUtil.setWebkitTransform(topView.node, 0, 0);
    }
  }

  /// Called when the animation to switch to a section has completed.
  void _onSectionTransitionEnded(SectionView selectedView) {
    // Show the section and hide the others.
    for (SectionView view in sections.childViews) {
      if (view == selectedView) {
        // Always refresh the sources in case they've changed.
        view.showSources();
      } else {
        // Only show the current view for performance.
        view.hideSources();
      }
    }
  }

  /// Called when the user chooses a section on the SliderMenu.  Hides
  /// all views except the one they want to see.
  void _onSectionSelected(String sectionTitle) {
    final section = swarm.sections.findSection(sectionTitle);
    // Find the view for this section.
    for (SectionView view in sections.childViews) {
      if (view.section == section) {
        // Have the conveyor show it.
        sections.selectView(view);
        break;
      }
    }
  }

  /// Create SectionViews for each Section in the app and add them to the
  /// conveyor. Note that the SectionViews won't actually populate or load data
  /// sources until they are shown in response to [:_onSectionSelected():].
  void _createSectionViews() {
    for (final section in swarm.sections) {
      final viewFactory = DataSourceViewFactory(swarm);
      final sectionView = SectionView(swarm, section, viewFactory);

      // TODO(rnystrom): Hack temp. Access node to make sure SectionView has
      // rendered and created scroller. This can go away when event registration
      // is being deferred.
      sectionView.node;

      sections.addChild(sectionView);
    }
    addChild(sections);
  }

  /// Controls the logic of how to respond to keypresses and then update the
  /// UI accordingly.
  void processKeyEvent(KeyboardEvent e) {
    int code = e.keyCode;
    if (swarm.state.inMainView) {
      // Option 1: We're in the Main Grid mode.
      if (!swarm.state.hasArticleSelected) {
        // Then a key has been pressed. Select the first item in the
        // top left corner.
        swarm.state.goToFirstArticleInSection();
      } else if (rightKeyPresses.contains(code)) {
        // Store original state that is needed if we need to move
        // to the next section.
        swarm.state.goToNextFeed();
      } else if (leftKeyPresses.contains(code)) {
        // Store original state that is needed if we need to move
        // to the next section.
        swarm.state.goToPreviousFeed();
      } else if (downKeyPresses.contains(code)) {
        swarm.state.goToNextSelectedArticle();
      } else if (upKeyPresses.contains(code)) {
        swarm.state.goToPreviousSelectedArticle();
      } else if (openKeyPresses.contains(code)) {
        // View a story in the larger Story View.
        swarm.state.selectStoryAsCurrent();
      } else if (nextPageKeyPresses.contains(code)) {
        swarm.state.goToNextSection(sliderMenu);
      } else if (previousPageKeyPresses.contains(code)) {
        swarm.state.goToPreviousSection(sliderMenu);
      }
    } else {
      // Option 2: We're in Story Mode. In this mode, the user can move up
      // and down through stories, which automatically loads the next story.
      if (downKeyPresses.contains(code)) {
        swarm.state.goToNextArticle();
      } else if (upKeyPresses.contains(code)) {
        swarm.state.goToPreviousArticle();
      } else if (backKeyPresses.contains(code)) {
        // Move back to the main grid view.
        swarm.state.clearCurrentArticle();
      }
    }
  }
}

/// Transitions the app back to the main screen. */
void _backToMain(SwarmState state) {
  if (state.currentArticle.value != null) {
    state.clearCurrentArticle();
    state.storyTextMode.value = true;
    state.pushToHistory();
  }
}

/// A back button that sends the user back to the front page. */
class SwarmBackButton extends View {
  Swarm swarm;

  SwarmBackButton(this.swarm);

  @override
  Element render() => Element.html('<div class="back-arrow button"></div>');

  @override
  void afterRender(Element node) {
    addOnClick((e) {
      _backToMain(swarm.state);
    });
  }
}

/// Top view constaining the title and standard buttons. */
class HeaderView extends CompositeView {
  // TODO(jacobr): make this value be coupled with the CSS file.
  static const HEIGHT = 80;
  Swarm swarm;

  View _title;
  View _infoButton;
  View _configButton;
  View _refreshButton;
  SwarmBackButton _backButton;
  View _infoDialog;
  View _configDialog;

  // For (text/web) article view controls
  View _webBackButton;
  View _webForwardButton;
  View _newWindowButton;

  HeaderView(this.swarm) : super('header-view') {
    _backButton = addChild(SwarmBackButton(swarm));
    _title = addChild(View.div('app-title', 'Swarm'));
    _configButton = addChild(View.div('config button'));
    _refreshButton = addChild(View.div('refresh button'));
    _infoButton = addChild(View.div('info-button button'));

    // TODO(rnystrom): No more web/text mode (it's just text) so get rid of
    // these.
    _webBackButton = addChild(WebBackButton());
    _webForwardButton = addChild(WebForwardButton());
    _newWindowButton = addChild(View.div('new-window-button button'));
  }

  @override
  void afterRender(Element node) {
    // Respond to changes to whether the story is being shown as text or web.
    attachWatch(swarm.state.storyTextMode, (e) {
      refreshWebStoryButtons();
    });

    _title.addOnClick((e) {
      _backToMain(swarm.state);
    });

    // Wire up the events.
    _configButton.addOnClick((e) {
      // Bring up the config dialog.
      if (_configDialog == null) {
        // TODO(terry): Cleanup, HeaderView shouldn't be tangled with main view.
        _configDialog = ConfigHintDialog(swarm.frontView, () {
          swarm.frontView.removeChild(_configDialog);
          _configDialog = null;

          // TODO: Need to push these to the server on a per-user basis.
          // Update the storage now.
          swarm.sections.refresh();
        });

        swarm.frontView.addChild(_configDialog);
      }
      // TODO(jimhug): Graceful redirection to reader.
    });

    // On click of the refresh button, refresh the swarm.
    _refreshButton.addOnClick(EventBatch.wrap((e) {
      swarm.refresh();
    }));

    // On click of the info button, show Dart info page in new window/tab.
    _infoButton.addOnClick((e) {
      // Bring up the config dialog.
      if (_infoDialog == null) {
        // TODO(terry): Cleanup, HeaderView shouldn't be tangled with main view.
        _infoDialog = HelpDialog(swarm.frontView, () {
          swarm.frontView.removeChild(_infoDialog);
          _infoDialog = null;

          swarm.sections.refresh();
        });

        swarm.frontView.addChild(_infoDialog);
      }
    });

    // On click of the new window button, show web article in new window/tab.
    _newWindowButton.addOnClick((e) {
      String currentArticleSrcUrl = swarm.state.currentArticle.value.srcUrl;
      window.open(currentArticleSrcUrl, '_blank');
    });

    startTransitionToMainView();
  }

  /// Refreshes whether or not the buttons specific to the display of a story in
  /// the web perspective are visible.
  void refreshWebStoryButtons() {
    bool webButtonsHidden = true;

    if (swarm.state.currentArticle.value != null) {
      // Set if web buttons are hidden
      webButtonsHidden = swarm.state.storyTextMode.value;
    }

    _webBackButton.hidden = webButtonsHidden;
    _webForwardButton.hidden = webButtonsHidden;
    _newWindowButton.hidden = webButtonsHidden;
  }

  void startTransitionToMainView() {
    _title.removeClass('in-story');
    _backButton.removeClass('in-story');

    _configButton.removeClass('in-story');
    _refreshButton.removeClass('in-story');
    _infoButton.removeClass('in-story');

    refreshWebStoryButtons();
  }

  void endTransitionToStoryView() {
    _title.addClass('in-story');
    _backButton.addClass('in-story');

    _configButton.addClass('in-story');
    _refreshButton.addClass('in-story');
    _infoButton.addClass('in-story');
  }
}

/// A back button for the web view of a story that is equivalent to clicking
/// "back" in the browser. */
// TODO(rnystrom): We have nearly identical versions of this littered through
// the sample apps. Should consolidate into one.
class WebBackButton extends View {
  WebBackButton();

  @override
  Element render() {
    return Element.html('<div class="web-back-button button"></div>');
  }

  @override
  void afterRender(Element node) {
    addOnClick((e) {
      back();
    });
  }

  /// Equivalent to [window.history.back] */
  static void back() {
    window.history.back();
  }
}

/// A back button for the web view of a story that is equivalent to clicking
/// "forward" in the browser. */
// TODO(rnystrom): We have nearly identical versions of this littered through
// the sample apps. Should consolidate into one.
class WebForwardButton extends View {
  WebForwardButton();

  @override
  Element render() {
    return Element.html('<div class="web-forward-button button"></div>');
  }

  @override
  void afterRender(Element node) {
    addOnClick((e) {
      forward();
    });
  }

  /// Equivalent to [window.history.forward] */
  static void forward() {
    window.history.forward();
  }
}

/// A factory that creates a view for data sources.
class DataSourceViewFactory implements ViewFactory<Feed> {
  Swarm swarm;

  DataSourceViewFactory(this.swarm);

  @override
  View newView(Feed data) => DataSourceView(data, swarm);

  @override
  int get width => ArticleViewLayout.getSingleton().width;
  @override
  int get height => null; // Width for this view isn't known.
}

/// A view for the items from a single data source.
/// Shows a title and a list of items.
class DataSourceView extends CompositeView {
  // TODO(jacobr): make this value be coupled with the CSS file.
  static const TAB_ONLY_HEIGHT = 34;

  final Feed source;
  VariableSizeListView<Article> itemsView;

  DataSourceView(this.source, Swarm swarm) : super('query') {
    // TODO(jacobr): make the title a view or decide it is sane for a subclass
    // of component view to manually add some DOM cruft.
    node.nodes.add(Element.html('<h2>${source.title}</h2>'));

    // TODO(jacobr): use named arguments when available.
    itemsView = addChild(VariableSizeListView<Article>(
        source.articles,
        ArticleViewFactory(swarm),
        true,
        /* scrollable */
        true,
        /* vertical */
        swarm.state.currentArticle,
        /* selectedItem */
        !Device.supportsTouch /* snapToArticles */,
        false /* paginate */,
        true /* removeClippedViews */,
        !Device.supportsTouch /* showScrollbar */));
    itemsView.addClass('story-section');

    node.nodes.add(Element.html('<div class="query-name-shadow"></div>'));

    // Clicking the view (i.e. its title area) unmaximizes to show the entire
    // view.
    node.onMouseDown.listen((e) {
      swarm.state.storyMaximized.value = false;
    });
  }
}

/// A button that toggles between states. */
class ToggleButton extends View {
  EventListeners onChanged;
  List<String> states;

  ToggleButton(this.states) : onChanged = EventListeners();

  @override
  Element render() => Element.tag('button');

  @override
  void afterRender(Element node) {
    state = states[0];
    node.onClick.listen((event) {
      toggle();
    });
  }

  String get state {
    final currentState = node.innerHtml;
    assert(states.contains(currentState));
    return currentState;
  }

  set state(String state) {
    assert(states.contains(state));
    node.innerHtml = state;
    onChanged.fire(null);
  }

  void toggle() {
    final oldState = state;
    int index = states.indexOf(oldState, 0);
    index = (index + 1) % states.length;
    state = states[index];
  }
}

/// A factory that creates a view for generic items.
class ArticleViewFactory implements VariableSizeViewFactory<Article> {
  Swarm swarm;

  ArticleViewLayout layout;
  ArticleViewFactory(this.swarm) : layout = ArticleViewLayout.getSingleton();

  @override
  View newView(Article item) => ArticleView(item, swarm, layout);

  @override
  int getWidth(Article item) => layout.width;
  @override
  int getHeight(Article item) => layout.computeHeight(item);
}

class ArticleViewMetrics {
  final int height;
  final int titleLines;
  final int bodyLines;

  const ArticleViewMetrics(this.height, this.titleLines, this.bodyLines);
}

class ArticleViewLayout {
  // TODO(terry): clean this up once we have a framework for sharing constants
  // between JS and CSS. See bug #5405307.
  static const IPAD_WIDTH = 257;
  static const DESKTOP_WIDTH = 297;
  static const CHROME_OS_WIDTH = 317;
  static const TITLE_MARGIN_LEFT = 257 - 150;
  static const BODY_MARGIN_LEFT = 257 - 221;
  static const LINE_HEIGHT = 18;
  static const TITLE_FONT = 'bold 13px arial,sans-serif';
  static const BODY_FONT = '13px arial,sans-serif';
  static const TOTAL_MARGIN = 16 * 2 + 70;
  static const MIN_TITLE_HEIGHT = 36;
  static const MAX_TITLE_LINES = 2;
  static const MAX_BODY_LINES = 4;

  MeasureText measureTitleText;
  MeasureText measureBodyText;

  int width;
  static ArticleViewLayout _singleton;
  ArticleViewLayout()
      : measureBodyText = MeasureText(BODY_FONT),
        measureTitleText = MeasureText(TITLE_FONT) {
    num screenWidth = window.screen.width;
    width = DESKTOP_WIDTH;
  }

  static ArticleViewLayout getSingleton() {
    _singleton ??= ArticleViewLayout();
    return _singleton;
  }

  int computeHeight(Article item) {
    if (item == null) {
      // TODO(jacobr): find out why this is happening..
      print('Null item encountered.');
      return 0;
    }

    return computeLayout(item, null, null).height;
  }

  /// titleContainer and snippetContainer may be null in which case the size is
  /// computed but no actual layout is performed.
  ArticleViewMetrics computeLayout(
      Article item, StringBuffer titleBuffer, StringBuffer snippetBuffer) {
    int titleWidth = width - BODY_MARGIN_LEFT;

    if (item.hasThumbnail) {
      titleWidth = width - TITLE_MARGIN_LEFT;
    }

    final titleLines = measureTitleText.addLineBrokenText(
        titleBuffer, item.title, titleWidth, MAX_TITLE_LINES);
    final bodyLines = measureBodyText.addLineBrokenText(
        snippetBuffer, item.textBody, width - BODY_MARGIN_LEFT, MAX_BODY_LINES);

    int height = bodyLines * LINE_HEIGHT + TOTAL_MARGIN;

    if (bodyLines == 0) {
      height = 92;
    }

    return ArticleViewMetrics(height, titleLines, bodyLines);
  }
}

/// A view for a generic item.
class ArticleView extends View {
  // Set to false to make inspecting the HTML more pleasant...
  static const SAVE_IMAGES = false;

  final Article item;
  final Swarm swarm;
  final ArticleViewLayout articleLayout;

  ArticleView(this.item, this.swarm, this.articleLayout);

  @override
  Element render() {
    Element node;

    final byline = item.author.isNotEmpty ? item.author : item.dataSource.title;
    final date = DateUtils.toRecentTimeString(item.date);

    String storyClass = 'story no-thumb';
    String thumbnail = '';

    if (item.hasThumbnail) {
      storyClass = 'story';
      thumbnail = '<img src="${item.thumbUrl}"></img>';
    }

    final title = StringBuffer();
    final snippet = StringBuffer();

    // Note: also populates title and snippet elements.
    final metrics = articleLayout.computeLayout(item, title, snippet);

    node = Element.html('''
<div class="$storyClass">
  $thumbnail
  <div class="title">$title</div>
  <div class="byline">$byline</div>
  <div class="dateline">$date</div>
  <div class="snippet">$snippet</div>
</div>''');

    // Remove the snippet entirely if it's empty. This keeps it from taking up
    // space and pushing the padding down.
    if ((item.textBody == null) || (item.textBody.trim() == '')) {
      node.querySelector('.snippet').remove();
    }

    return node;
  }

  @override
  void afterRender(Element node) {
    // Select this view's item.
    addOnClick((e) {
      // Mark the item as read, so it shows as read in other views
      item.unread.value = false;

      final oldArticle = swarm.state.currentArticle.value;
      swarm.state.currentArticle.value = item;
      swarm.state.storyTextMode.value = true;
      if (oldArticle == null) {
        swarm.state.pushToHistory();
      }
    });

    watch(swarm.state.currentArticle, (e) {
      if (!swarm.state.inMainView) {
        swarm.state.markCurrentAsRead();
      }
      _refreshSelected(swarm.state.currentArticle);
      //TODO(efortuna): add in history stuff while reading articles?
    });

    watch(swarm.state.selectedArticle, (e) {
      _refreshSelected(swarm.state.selectedArticle);
      _updateViewForSelectedArticle();
    });

    watch(item.unread, (e) {
      // TODO(rnystrom): Would be nice to do:
      //     node.classes.set('story-unread', item.unread.value)
      if (item.unread.value) {
        node.classes.add('story-unread');
      } else {
        node.classes.remove('story-unread');
      }
    });
  }

  /// Notify the view to jump to a different area if we are selecting an
  /// article that is currently outside of the visible area.
  void _updateViewForSelectedArticle() {
    Article selArticle = swarm.state.selectedArticle.value;
    if (swarm.state.hasArticleSelected) {
      // Ensure that the selected article is visible in the view.
      if (!swarm.state.inMainView) {
        // Story View.
        swarm.frontView.detachedView.itemsView.showView(selArticle);
      } else {
        if (swarm.frontView.currentSection.inCurrentView(selArticle)) {
          // Scroll horizontally if needed.
          swarm.frontView.currentSection.dataSourceView
              .showView(selArticle.dataSource);
          DataSourceView dataView =
              swarm.frontView.currentSection.findView(selArticle.dataSource);
          if (dataView != null) {
            dataView.itemsView.showView(selArticle);
          }
        }
      }
    }
  }

  String getDataUriForImage(final img) {
    // TODO(hiltonc,jimhug) eval perf of this vs. reusing one canvas element
    final CanvasElement canvas =
        CanvasElement(height: img.height, width: img.width);

    final CanvasRenderingContext2D ctx = canvas.getContext("2d");
    ctx.drawImageScaled(img, 0, 0, img.width, img.height);

    return canvas.toDataUrl("image/png");
  }

  /// Update this view's selected appearance based on the currently selected
  /// Article.
  void _refreshSelected(curItem) {
    if (curItem.value == item) {
      addClass('sel');
    } else {
      removeClass('sel');
    }
  }

  void _saveToStorage(String thumbUrl, ImageElement img) {
    // TODO(jimhug): Reimplement caching of images.
  }
}

/// An internal view of a story as text. In other words, the article is shown
/// in-place as opposed to as an embedded web-page.
class StoryContentView extends View {
  final Swarm swarm;
  final Article item;

  View _pagedStory;

  StoryContentView(this.swarm, this.item);

  @override
  get childViews => [_pagedStory];

  @override
  Element render() {
    final storyContent =
        Element.html('<div class="story-content">${item.htmlBody}</div>');
    for (Element element in storyContent.querySelectorAll(
        "iframe, script, style, object, embed, frameset, frame")) {
      element.remove();
    }
    _pagedStory = PagedContentView(View.fromNode(storyContent));

    // Modify all links to open in new windows....
    // TODO(jacobr): would it be better to add an event listener on click that
    // intercepts these instead?
    for (AnchorElement anchor in storyContent.querySelectorAll('a')) {
      anchor.target = '_blank';
    }

    final date = DateUtils.toRecentTimeString(item.date);
    final container = Element.html('''
      <div class="story-view">
        <div class="story-text-view">
          <div class="story-header">
            <a class="story-title" href="${item.srcUrl}" target="_blank">
              ${item.title}</a>
            <div class="story-byline">
              ${item.author} - ${item.dataSource.title}
            </div>
            <div class="story-dateline">$date</div>
          </div>
          <div class="paged-story"></div>
          <div class="spacer"></div>
        </div>
      </div>''');

    container.querySelector('.paged-story').replaceWith(_pagedStory.node);

    return container;
  }
}

class SectionView extends CompositeView {
  final Section section;
  final Swarm swarm;
  final DataSourceViewFactory _viewFactory;
  final View loadingText;
  ListView<Feed> dataSourceView;
  PageNumberView pageNumberView;
  final PageState pageState;

  SectionView(this.swarm, this.section, this._viewFactory)
      : loadingText = View.html('<div class="loading-section"></div>'),
        pageState = PageState(),
        super('section-view') {
    addChild(loadingText);
  }

  /// Hides the loading text, reloads the data sources, and shows them.
  void showSources() {
    loadingText.node.style.display = 'none';

    // Lazy initialize the data source view.
    if (dataSourceView == null) {
      // TODO(jacobr): use named arguments when available.
      dataSourceView = ListView<Feed>(
          section.feeds,
          _viewFactory,
          true /* scrollable */,
          false /* vertical */,
          null /* selectedItem */,
          true /* snapToItems */,
          true /* paginate */,
          true /* removeClippedViews */,
          false,
          /* showScrollbar */
          pageState);
      dataSourceView.addClass("data-source-view");
      addChild(dataSourceView);

      pageNumberView = addChild(PageNumberView(pageState));

      node.style.opacity = '1';
    } else {
      addChild(dataSourceView);
      addChild(pageNumberView);
      node.style.opacity = '1';
    }

    // TODO(jacobr): get rid of this call to reconfigure when it is not needed.
    dataSourceView.scroller.reconfigure(() {});
  }

  /// Hides the data sources and shows the loading text.
  void hideSources() {
    if (dataSourceView != null) {
      node.style.opacity = '0.6';
      removeChild(dataSourceView);
      removeChild(pageNumberView);
    }

    loadingText.node.style.display = 'block';
  }

  set storyMode(bool inStoryMode) {
    if (inStoryMode) {
      addClass('hide-all-queries');
    } else {
      removeClass('hide-all-queries');
    }
  }

  /// Find the [DataSourceView] in this SectionView that's displaying the given
  /// [Feed].
  DataSourceView findView(Feed dataSource) {
    return dataSourceView.getSubview(dataSourceView.findIndex(dataSource));
  }

  bool inCurrentView(Article article) {
    return dataSourceView.findIndex(article.dataSource) != null;
  }
}
