// 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 = new Set.from([74 /*j*/, 40 /*down*/]),
        upKeyPresses = new Set.from([75 /*k*/, 38 /*up*/]),
        rightKeyPresses = new Set.from([39 /*right*/, 68 /*d*/, 76 /*l*/]),
        leftKeyPresses = new Set.from([37 /*left*/, 65 /*a*/, 72 /*h*/]),
        openKeyPresses = new Set.from([13 /*enter*/, 79 /*o*/]),
        backKeyPresses = new Set.from([8 /*delete*/, 27 /*escape*/]),
        nextPageKeyPresses = new Set.from([78 /*n*/]),
        previousPageKeyPresses = new Set.from([80 /*p*/]),
        nextPrevShown = false,
        super('front-view fullpage') {
    topView = new CompositeView('top-view', false, false, false);

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

    sliderMenu = new 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 = new CompositeView('bottom-view', false, false, false);
    addChild(bottomView);

    sections = new 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;
  }

  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(new 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 = new StoryContentView(swarm, item);
      new Timer(const Duration(milliseconds: 0), () {
        _animateDataSourceToMinimized();

        sliderMenu.addClass('hidden');
        // Make the fancy sliding into the window animation.
        new Timer(const Duration(milliseconds: 0), () {
          storyView.addClass('hidden-story');
          addChild(storyView);
          new 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 = new DataSourceViewFactory(swarm);
      final sectionView = new 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);

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

  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(new 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(new WebBackButton());
    _webForwardButton = addChild(new WebForwardButton());
    _newWindowButton = addChild(View.div('new-window-button button'));
  }

  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 (this._configDialog == null) {
        // TODO(terry): Cleanup, HeaderView shouldn't be tangled with main view.
        this._configDialog = new ConfigHintDialog(swarm.frontView, () {
          swarm.frontView.removeChild(this._configDialog);
          this._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(this._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 (this._infoDialog == null) {
        // TODO(terry): Cleanup, HeaderView shouldn't be tangled with main view.
        this._infoDialog = new HelpDialog(swarm.frontView, () {
          swarm.frontView.removeChild(this._infoDialog);
          this._infoDialog = null;

          swarm.sections.refresh();
        });

        swarm.frontView.addChild(this._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();

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

  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();

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

  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) {}

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

  int get width => ArticleViewLayout.getSingleton().width;
  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(new Element.html('<h2>${source.title}</h2>'));

    // TODO(jacobr): use named arguments when available.
    itemsView = addChild(new VariableSizeListView<Article>(
        source.articles,
        new 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(new 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 = new EventListeners();

  Element render() => new Element.tag('button');

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

  String get state {
    final currentState = node.innerHtml;
    assert(states.indexOf(currentState, 0) >= 0);
    return currentState;
  }

  void set state(String state) {
    assert(states.indexOf(state, 0) >= 0);
    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();

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

  int getWidth(Article item) => layout.width;
  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 = new MeasureText(BODY_FONT),
        measureTitleText = new MeasureText(TITLE_FONT) {
    num screenWidth = window.screen.width;
    width = DESKTOP_WIDTH;
  }

  static ArticleViewLayout getSingleton() {
    if (_singleton == null) {
      _singleton = new 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 new 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);

  Element render() {
    Element node;

    final byline = item.author.length > 0 ? 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 = new StringBuffer();
    final snippet = new StringBuffer();

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

    node = new 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;
  }

  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 =
        new 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);

  get childViews => [_pagedStory];

  Element render() {
    final storyContent =
        new 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 = new PagedContentView(new 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 = new 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 = new View.html('<div class="loading-section"></div>'),
        pageState = new 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 = new 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(new 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;
  }
}
