
/*
 * Copyright 2017-present Open Networking Foundation

 * 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 $ from 'jquery';
import * as _ from 'lodash';
import {IXosSidePanelService} from '../side-panel/side-panel.service';

export interface IXosKeyboardShortcutService {
  keyMapping: IXosKeyboardShortcutMap;
  registerKeyBinding(binding: IXosKeyboardShortcutBinding, target?: string);
  setup(): void;
}

export interface IXosKeyboardShortcutMap {
  global: IXosKeyboardShortcutBinding[];
  view: IXosKeyboardShortcutBinding[];
}

export interface IXosKeyboardShortcutBinding {
  key: string;
  cb: any;
  modifiers?: string[];
  label?: string;
  description?: string;
  onInput?: boolean;
}

export class XosKeyboardShortcut implements IXosKeyboardShortcutService {
  static $inject = ['$log', '$transitions', 'XosSidePanel'];
  public keyMapping: IXosKeyboardShortcutMap = {
    global: [],
    view: []
  };
  public allowedModifiers: string[] = ['meta', 'alt', 'shift', 'control'];
  public activeModifiers: string[] = [];

  private toggleKeyBindingPanel = (): void => {
    if (!this.isPanelOpen) {
      this.XosSidePanel.injectComponent('xosKeyBindingPanel');
      this.isPanelOpen = true;
    }
    else {
      this.XosSidePanel.removeInjectedComponents();
      this.isPanelOpen = false;
    }
  };

  /* tslint:disable */
  public baseBindings: IXosKeyboardShortcutBinding[] = [
    {
      key: 'slash',
      label: '/',
      description: 'Toggle Shortcut Panel',
      cb: this.toggleKeyBindingPanel,
    },
    {
      key: 'esc',
      label: 'Esc',
      cb: (event) => {
        // NOTE removing focus from input elements on Esc
        event.target.blur();
      },
      onInput: true
    }
  ];
  /* tslint:enable */

  private isPanelOpen: boolean;

  constructor(
    private $log: ng.ILogService,
    $transitions: any,
    private XosSidePanel: IXosSidePanelService
  ) {
    this.keyMapping.global = this.keyMapping.global.concat(this.baseBindings);

    $transitions.onStart({ to: '**' }, (transtion) => {
      // delete view keys before that a new view is loaded
        this.$log.debug(`[XosKeyboardShortcut] Deleting view keys`);
        this.keyMapping.view = [];
    });
  }


  public setup(): void {
    this.$log.info(`[XosKeyboardShortcut] Setup`);
    $('body').on('keydown', (e) => {

      const pressedKey = this.whatKey(e.which);
      if (!pressedKey) {
        return;
      }

      if (this.allowedModifiers.indexOf(e.key) > -1) {
        this.addActiveModifierKey(e.key);
        return;
      }

      // NOTE e.key change if we are using some modifiers (eg: Alt) while getting the value from the keyCode works
      const binding = this.findBindedShortcut(pressedKey);
      if (angular.isDefined(binding) && angular.isFunction(binding.cb)) {
        // NOTE disable binding if they come from an input or textarea
        // if not different specified
        const t = e.target.tagName.toLowerCase();
        if ((t === 'input' || t === 'textarea') && !binding.onInput) {
          return;
        }
        binding.cb(e);
        e.preventDefault();
      }
    });

    $('body').on('keyup', (e) => {
      if (this.allowedModifiers.indexOf(e.key) > -1) {
        this.removeActiveModifierKey(e.key);
        return;
      }
    });
  }

  public registerKeyBinding(binding: IXosKeyboardShortcutBinding, target: string = 'view'): void {

    if (target !== 'global' && target !== 'view') {
      throw new Error('[XosKeyboardShortcut] A shortcut can be registered with scope "global" or "view" only');
    }

    binding.key = binding.key.toLowerCase();
    if (_.find(this.keyMapping.global, {key: binding.key, modifiers: binding.modifiers}) || _.find(this.keyMapping.view, {key: binding.key, modifiers: binding.modifiers})) {
      this.$log.warn(`[XosKeyboardShortcut] A shortcut for key "${binding.key}" has already been registered`);
      return;
    }

    this.$log.debug(`[XosKeyboardShortcut] Registering binding for key: ${binding.key}`);
    this.keyMapping[target].push(binding);
  }

  private addActiveModifierKey(key: string) {
    if (this.activeModifiers.indexOf(key) === -1) {
      this.activeModifiers.push(key);
    }
  }

  private removeActiveModifierKey(key: string) {
    _.remove(this.activeModifiers, k => k === key);
  }

  private findBindedShortcut(key: string): IXosKeyboardShortcutBinding {
    const globalTargets =  _.filter(this.keyMapping.global, {key: key.toLowerCase()});

    const localTargets = _.filter(this.keyMapping.view, {key: key.toLowerCase()});

    let targets = globalTargets.concat(localTargets);

    if (targets.length === 0) {
      return;
    }

    // NOTE remove targets that does not match modifiers
    targets = _.filter(targets, (t: IXosKeyboardShortcutBinding) => {
      if (this.activeModifiers.length === 0) {
        return true;
      }
      else if (t.modifiers && _.difference(t.modifiers, this.activeModifiers).length === 0) {
        return true;
      }
      return false;
    });

    return targets[0];
  }

  private whatKey(code: number) {
    switch (code) {
      case 8: return 'delete';
      case 9: return 'tab';
      case 13: return 'enter';
      case 16: return 'shift';
      case 17: return 'control';
      case 18: return 'alt';
      case 27: return 'esc';
      case 32: return 'space';
      case 37: return 'leftArrow';
      case 38: return 'upArrow';
      case 39: return 'rightArrow';
      case 40: return 'downArrow';
      case 91: return 'meta';
      case 186: return 'semicolon';
      case 187: return 'equals';
      case 188: return 'comma';
      case 189: return 'dash';
      case 190: return 'dot';
      case 191: return 'slash';
      case 192: return 'backQuote';
      case 219: return 'openBracket';
      case 220: return 'backSlash';
      case 221: return 'closeBracket';
      case 222: return 'quote';
      default:
        if ((code >= 48 && code <= 57) ||
          (code >= 65 && code <= 90)) {
          return String.fromCharCode(code);
        } else if (code >= 112 && code <= 123) {
          return 'F' + (code - 111);
        }
        return null;
  }
}

}
