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

/**
 * Holds a number of child views.  As you switch between views, the old
 * view is pushed off to the side and the new view slides in from the other
 * side.
 */
class ConveyorView extends CompositeView {
  // TODO(jmesserly): some places use this property to know when the slide
  // transition is finished. It would be better to have an event that fires
  // when we're done sliding
  static const ANIMATE_SECONDS = 0.25;

  View targetView;
  // TODO(rnystrom): Should not be settable.
  View selectedView;
  // TODO(rnystrom): Hackish. Should use a real multicast event-like class.
  // Or just have it depend on an Observable to select a view and indicate
  // which view is selected? (e.g. the MVVM pattern)
  Function viewSelected;

  Timer animationTimer;

  ConveyorView()
      : animationTimer = null,
        super('conveyor-view', true) {}

  Element render() {
    final result = super.render();
    // TODO(rnystrom): Have to do this in render() because container doesn't
    // exist before then. Hack. Should find a cleaner solution. One of:
    // - Add a ctor param to CompositeView for container class name.
    // - Make ConveyorView contain a CompositeView instead of subclass.
    // - Add method to CompositeView to set class name.
    container.attributes['class'] = 'conveyor-view-container';
    return result;
  }

  void selectView(View targetView_, [bool animate = true]) {
    selectedView = targetView_;

    // Only animate if we're actually in the document now.
    if (isRendered) {
      adjustOffset(animate);
    }
  }

  void adjustOffset(bool animate) {
    int index = getIndexOfSelectedView();
    final durationSeconds = animate ? ANIMATE_SECONDS : 0.0;

    final style = container.style;
    // TODO(jacobr): modify setTransitionDuration so the input is always
    // specified in miliseconds rather than accepting a string.
    style.transitionDuration = '${durationSeconds}s';
    final xTranslationPercent = -index * 100;
    style.transform = 'translate3d(${xTranslationPercent}%, 0px, 0px)';

    if (animate) {
      animationTimer = new Timer(
          new Duration(milliseconds: ((durationSeconds * 1000).toInt())), () {
        _onAnimationEnd();
      });
    }
    // TODO(mattsh), we should set the visibility to hide everything but the
    // selected view.
  }

  int getIndexOfSelectedView() {
    for (int i = 0; i < childViews.length; i++) {
      if (childViews[i] == selectedView) {
        return i;
      }
    }
    throw "view not found";
  }

  /**
   * Adds a child view to the ConveyorView.  The views are stacked horizontally
   * in the order they are added.
   */
  View addChild(View view) {
    view.addClass('conveyor-item');
    view.transform = 'translate3d(${(childViews.length * 100)}%, 0, 0)';
    return super.addChild(view);
  }

  void _onAnimationEnd() {
    if (viewSelected != null) {
      viewSelected(selectedView);
    }
  }
}
