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

typedef void SelectHandler(String menuText);

/**
 * This implements a horizontal menu bar with a sliding triangle arrow
 * that points at the currently selected item.
 */
class SliderMenu extends View {
  static const int TRIANGLE_WIDTH = 24;

  // currently selected menu item
  Element selectedItem;

  // This holds the element where a touchstart occured.  (This is set
  // in touchstart, and cleared in touchend.)  If this is null, then a
  // touch operation is not in progress.
  // TODO(mattsh) - move this to a touch mixin
  Element touchItem;

  /**
   * Callback function that we call when the user chooses something from
   * the menu.  This is passed the menu item text.
   */
  SelectHandler onSelect;

  List<String> _menuItems;

  SliderMenu(this._menuItems, this.onSelect);

  Element render() {
    // Create a div for each menu item.
    final items = new StringBuffer();
    for (final item in _menuItems) {
      items.write('<div class="sm-item">$item</div>');
    }

    // Create a root node to hold this view.
    return new Element.html('''
        <div class="sm-root">
          <div class="sm-item-box">
            <div class="sm-item-filler"></div>
            $items
            <div class="sm-item-filler"></div>
          </div>
          <div class="sm-slider-box">
            <div class="sm-triangle"></div>
          </div>
        </div>
        ''');
  }

  void enterDocument() {
    // select the first item
    // todo(jacobr): too much actual work is performed in enterDocument.
    // Ideally, enterDocument should do nothing more than redecorate a view
    // and perhaps calculating the correct child sizes for edge cases that
    // cannot be handled by the browser layout engine.
    selectItem(node.querySelector('.sm-item'), false);

    // TODO(mattsh), abstract this somehow into a touch click mixin
    if (Device.supportsTouch) {
      node.onTouchStart.listen((event) {
        touchItem = itemOfTouchEvent(event);
        if (touchItem != null) {
          selectItemText(touchItem);
        }
        event.preventDefault();
      });
      node.onTouchEnd.listen((event) {
        if (touchItem != null) {
          if (itemOfTouchEvent(event) == touchItem) {
            selectItem(touchItem, true);
          } else {
            // the Touch target is somewhere other where than the touchstart
            // occured, so revert the selected menu text back to where it was
            // before the touchstart,
            selectItemText(selectedItem);
          }
          // touch operation has ended
          touchItem = null;
        }
        event.preventDefault();
      });
    } else {
      node.onClick.listen((event) => selectItem(event.target, true));
    }

    window.onResize.listen((Event event) => updateIndicator(false));
  }

  /**
   * Walks the parent chain of the first Touch target to find the first ancestor
   * that has sm-item class.
   */
  Element itemOfTouchEvent(event) {
    Node node = event.changedTouches[0].target;
    return itemOfNode(node);
  }

  Element itemOfNode(Node node) {
    // TODO(jmesserly): workaround for bug 5399957, document.parent == document
    while (node != null && node != document) {
      if (node is Element) {
        Element element = node;
        if (element.classes.contains('sm-item')) {
          return element;
        }
      }
      node = node.parent;
    }
    return null;
  }

  void selectItemText(Element item) {
    // unselect all menu items
    for (final sliderItem in node.querySelectorAll('.sm-item')) {
      sliderItem.classes.remove('sel');
    }

    // select the item the user clicked on
    item.classes.add('sel');
  }

  void selectItem(Element item, bool animate) {
    if (!item.classes.contains('sm-item')) {
      return;
    }

    selectedItem = item;
    selectItemText(item);
    updateIndicator(animate);
    onSelect(item.text);
  }

  void selectNext(bool animate) {
    final result = node.querySelector('.sm-item.sel').nextElementSibling;
    if (result != null) {
      selectItem(result, animate);
    }
  }

  void selectPrevious(bool animate) {
    final result = node.querySelector('.sm-item.sel').previousElementSibling;
    if (result != null) {
      selectItem(result, animate);
    }
  }

  /**
   * animate - if true, then animate the movement of the triangle slider
   */
  void updateIndicator(bool animate) {
    if (selectedItem != null) {
      // calculate where we want to put the triangle
      scheduleMicrotask(() {
        num x = selectedItem.offset.left +
            selectedItem.offset.width / 2 -
            TRIANGLE_WIDTH / 2;
        _moveIndicator(x, animate);
      });
    } else {
      _moveIndicator(0, animate);
    }
  }

  void _moveIndicator(num x, bool animate) {
    // find the slider filler (the div element to the left of the
    // triangle) set its width the push the triangle to where we want it.
    String duration = animate ? '.3s' : '0s';
    final triangle = node.querySelector('.sm-triangle');
    triangle.style.transitionDuration = duration;
    FxUtil.setWebkitTransform(triangle, x, 0);
  }
}
