<!--
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-->
<import src="/sky/framework/elements/sky-element.sky" />
<sky-element>
<template>
  <style>
    #container {
      height: -webkit-fill-available;
    }
    #input-box {
      position: absolute;
      left: 0;
      top: 0;
      z-index: 10;
      width: 100%;
      height: 100%;
      opacity: 0;
    }
    #output-box {
      position: absolute;
      left: 0;
      top: 0;
      z-index: 0;
      width: 100%;
      height: 100%;
      background-color: black;
      color: rgb(255, 191, 0);
      font-family: 'Courier', 'monospace';
      font-size: small;
    }
    .line {
      height: 1em;
      white-space: nowrap;
    }
  </style>
  <div id="container">
    <div id="input-box" contenteditable />
    <div id="output-box" />
  </div>
  </div>
</template>
<script>
import 'dart:async';
import 'dart:core';
import 'dart:sky';
import 'package:mojo/services/terminal/public/interfaces/terminal_client.mojom.dart' as terminal;
import 'package:sky/framework/embedder.dart';
import 'terminal_display.dart';
import 'terminal_file_impl.dart';

// Implements the <terminal> element, which implements a "terminal display". Has
// an |url| attribute, whose value should be a Mojo app that provides the
// |terminal.TerminalClient| service.
@Tagname('terminal')
class TerminalDisplayImpl extends SkyElement implements TerminalDisplay {
  Element _inputBox;
  Element _outputBox;
  int _maxLines;

  // Queue of unconsumed input (keystrokes), with the head at index 0.
  // Keystrokes end up here if there's no reader (i.e., |getChar()|) pending,
  // i.e., if |_readerQueue| is empty. Invariant: At most one of |_inputQueue|
  // and |_readerQueue| may be nonempty at any given time.
  List<int> _inputQueue;

  // Queue of things waiting for input, with the head at index 0. If a keystroke
  // is received and this is nonempty, the head is given that keystroke (and
  // dequeued).
  List<Completer<int>> _readerQueue;

  TerminalDisplayImpl()
      : _inputQueue = new List<int>(),
        _readerQueue = new List<Completer<int>>() {
  }

  void shadowRootReady() {
    _inputBox = shadowRoot.getElementById('input-box');
    _inputBox.addEventListener('keydown', _handleKeyDown);
    _inputBox.addEventListener('keypress', _handleKeyPress);
    _inputBox.addEventListener('wheel', _handleWheel);
    _outputBox = shadowRoot.getElementById('output-box');

    // Hack to allow |_newLine()| to work.
    _maxLines = 100;

    // Initialize with the first line.
    _newLine();

    // Actually compute the maximum number of lines.
    // TODO(vtl): Recompute on resize.
    _maxLines = _outputBox.clientHeight ~/ _outputBox.firstChild.offsetHeight;

    var url = getAttribute('url');
    if (url != null) {
      connect(url);
    }
  }

  void _handleKeyDown(KeyboardEvent event) {
    // TODO(vtl): In general, our key handling is a total hack (due in part to
    // sky's keyboard support being incomplete) -- e.g., we shouldn't have to
    // make our div contenteditable. We have to intercept backspace (^H) here,
    // since we won't actually get a keypress event for it. (Possibly, we should
    // only handle keydown instead of keypress, but then we'd have to handle
    // shift, etc. ourselves.)
    if (event.key == 8) {
      _enqueueChar(8);
      event.preventDefault();
    }
  }

  void _handleKeyPress(KeyboardEvent event) {
    if (event.charCode != 0) {
      _enqueueChar(event.charCode);
    }
    event.preventDefault();
  }

  void _handleWheel(WheelEvent event) {
    _outputBox.dispatchEvent(event);
  }

  void _enqueueChar(int charCode) {
    // TODO(vtl): Add "echo" mode; do |putChar(event.charCode);| if echo is on.

    if (_readerQueue.isEmpty) {
      _inputQueue.add(charCode);
    } else {
      _readerQueue.removeAt(0).complete(charCode);
    }
  }

  void _backspace() {
    var oldText = _outputBox.lastChild.textContent;
    if (oldText.length > 0) {
      _outputBox.lastChild.textContent = oldText.substring(0,
                                                           oldText.length - 1);
    }
  }

  void _newLine() {
    var line = document.createElement('div');
    line.setAttribute('class', 'line');
    _outputBox.appendChild(line);

    // Scroll if necessary.
    var children = _outputBox.getChildNodes();
    if (children.length > _maxLines) {
      children = new List.from(children.skip(children.length - _maxLines));
      _outputBox.setChildren(children);
    }
  }

  void _clear() {
    _outputBox.setChildren([]);
    _newLine();
  }

  void connect(String url) {
    var terminalClient = new terminal.TerminalClientProxy.unbound();
    embedder.connectToService(url, terminalClient);
    terminalClient.ptr.connectToTerminal(new TerminalFileImpl(this).stub);
    terminalClient.close();
  }

  void putString(String s) {
    for (var i = 0; i < s.length; i++) {
      putChar(s.codeUnitAt(i));
    }
  }

  // |TerminalDisplay| implementation:

  @override
  void putChar(int byte) {
    // Fast-path for printable chars.
    if (byte >= 32) {
      _outputBox.lastChild.textContent += new String.fromCharCode(byte);
      return;
    }

    switch (byte) {
      case 8:  // BS (^H).
        _backspace();
        break;
      case 10:  // LF ('\n').
        _newLine();  // TODO(vtl): LF and CR should be separated.
        break;
      case 12:  // FF (^L).
        _clear();
        break;
      case 13:  // CR ('\r').
        _newLine();  // TODO(vtl): LF and CR should be separated.
        break;
      default:
        // Should beep or something.
        break;
    }
  }

  @override
  Future<int> getChar() async {
    if (_inputQueue.isNotEmpty) {
      return new Future.value(_inputQueue.removeAt(0));
    }

    var completer = new Completer<int>();
    _readerQueue.add(completer);
    return completer.future;
  }
}

_init(script) => register(script, TerminalDisplayImpl);
</script>
</sky-element>
