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

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