
// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import * as m from 'mithril';
import {getErrorMessage} from '../common/errors';

import {globals} from './globals';
import {
  KeyboardLayoutMap,
  nativeKeyboardLayoutMap,
  NotSupportedError,
} from './keyboard_layout_map';
import {showModal} from './modal';
import {KeyMapping} from './pan_and_zoom_handler';
import {Spinner} from './widgets/spinner';

export function toggleHelp() {
  globals.logging.logEvent('User Actions', 'Show help');
  showHelp();
}

function keycap(glyph: m.Children): m.Children {
  return m('.keycap', glyph);
}

// A fallback keyboard map based on the QWERTY keymap. Converts keyboard event
// codes to their associated glyphs on an English QWERTY keyboard.
class EnglishQwertyKeyboardLayoutMap implements KeyboardLayoutMap {
  get(code: string): string {
    // Converts 'KeyX' -> 'x'
    return code.replace(/^Key([A-Z])$/, '$1').toLowerCase();
  }
}

class KeyMappingsHelp implements m.ClassComponent {
  private keyMap?: KeyboardLayoutMap;

  oninit() {
    nativeKeyboardLayoutMap()
        .then((keyMap: KeyboardLayoutMap) => {
          this.keyMap = keyMap;
          globals.rafScheduler.scheduleFullRedraw();
        })
        .catch((e) => {
          if (e instanceof NotSupportedError ||
              getErrorMessage(e).includes('SecurityError')) {
            // Keyboard layout is unavailable. Since showing the keyboard
            // mappings correct for the user's keyboard layout is a nice-to-
            // have, and users with non-QWERTY layouts are usually aware of the
            // fact that the are using non-QWERTY layouts, we resort to showing
            // English QWERTY mappings as a best-effort approach.
            // The alternative would be to show key mappings for all keyboard
            // layouts which is not feasible.
            this.keyMap = new EnglishQwertyKeyboardLayoutMap();
            globals.rafScheduler.scheduleFullRedraw();
          } else {
            // Something unexpected happened. Either the browser doesn't conform
            // to the keyboard API spec, or the keyboard API spec has changed!
            throw e;
          }
        });
  }

  view(_: m.Vnode): m.Children {
    const ctrlOrCmd =
        window.navigator.platform.indexOf('Mac') !== -1 ? 'Cmd' : 'Ctrl';

    return m(
        '.help',
        m('h2', 'Navigation'),
        m(
            'table',
            m(
                'tr',
                m('td',
                  this.codeToKeycap(KeyMapping.KEY_ZOOM_IN),
                  '/',
                  this.codeToKeycap(KeyMapping.KEY_ZOOM_OUT)),
                m('td', 'Zoom in/out'),
                ),
            m(
                'tr',
                m('td',
                  this.codeToKeycap(KeyMapping.KEY_PAN_LEFT),
                  '/',
                  this.codeToKeycap(KeyMapping.KEY_PAN_RIGHT)),
                m('td', 'Pan left/right'),
                ),
            ),
        m('h2', 'Mouse Controls'),
        m('table',
          m('tr', m('td', 'Click'), m('td', 'Select event')),
          m('tr', m('td', 'Ctrl + Scroll wheel'), m('td', 'Zoom in/out')),
          m('tr', m('td', 'Click + Drag'), m('td', 'Select area')),
          m('tr', m('td', 'Shift + Click + Drag'), m('td', 'Pan left/right'))),
        m('h2', 'Making SQL queries from the viewer page'),
        m('table',
          m('tr',
            m('td', keycap(':'), ' in the (empty) search box'),
            m('td', 'Switch to query input')),
          m('tr', m('td', keycap('Enter')), m('td', 'Execute query')),
          m('tr',
            m('td', keycap('Ctrl'), ' + ', keycap('Enter')),
            m('td',
              'Execute query and pin output ' +
                  '(output will not be replaced by regular query input)'))),
        m('h2', 'Making SQL queries from the query page'),
        m('table',
          m('tr',
            m('td', keycap('Ctrl'), ' + ', keycap('Enter')),
            m('td', 'Execute query')),
          m('tr',
            m('td',
              keycap('Ctrl'),
              ' + ',
              keycap('Enter'),
              ' (with selection)'),
            m('td', 'Execute selection'))),
        m('h2', 'Other'),
        m(
            'table',
            m('tr',
              m('td', keycap('f'), ' (with event selected)'),
              m('td', 'Scroll + zoom to current selection')),
            m('tr',
              m('td', keycap('['), '/', keycap(']'), ' (with event selected)'),
              m('td',
                'Select next/previous slice that is connected by a flow.',
                m('br'),
                'If there are multiple flows,' +
                    'the one that is in focus (bold) is selected')),
            m('tr',
              m('td',
                keycap(ctrlOrCmd),
                ' + ',
                keycap('['),
                '/',
                keycap(']'),
                ' (with event selected)'),
              m('td', 'Switch focus to another flow')),
            m('tr',
              m('td', keycap('m'), ' (with event or area selected)'),
              m('td', 'Mark the area (temporarily)')),
            m('tr',
              m('td',
                keycap('Shift'),
                ' + ',
                keycap('m'),
                ' (with event or area selected)'),
              m('td', 'Mark the area (persistently)')),
            m('tr',
              m('td', keycap(ctrlOrCmd), ' + ', keycap('a')),
              m('td', 'Select all')),
            m('tr',
              m('td', keycap(ctrlOrCmd), ' + ', keycap('b')),
              m('td', 'Toggle display of sidebar')),
            m('tr', m('td', keycap('?')), m('td', 'Show help')),
            ));
  }

  private codeToKeycap(code: string): m.Children {
    if (this.keyMap) {
      return keycap(this.keyMap.get(code));
    } else {
      return keycap(m(Spinner));
    }
  }
}

function showHelp() {
  showModal({
    title: 'Perfetto Help',
    content: () => m(KeyMappingsHelp),
    buttons: [],
  });
}
