/*
 * Copyright (C) 2022 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 m from 'mithril';
import {globals} from './globals';

interface ArgumentPopupArgs {
  onArgumentChange: (arg: string) => void;
  knownArguments: string[];
}

function longestString(array: string[]): string {
  if (array.length === 0) {
    return '';
  }

  let answer = array[0];
  for (let i = 1; i < array.length; i++) {
    if (array[i].length > answer.length) {
      answer = array[i];
    }
  }
  return answer;
}

// Component rendering popup for entering an argument name to use as a pivot.
export class ArgumentPopup implements m.ClassComponent<ArgumentPopupArgs> {
  argument = '';

  setArgument(attrs: ArgumentPopupArgs, arg: string) {
    this.argument = arg;
    attrs.onArgumentChange(arg);
    globals.rafScheduler.scheduleFullRedraw();
  }

  renderMatches(attrs: ArgumentPopupArgs): m.Child[] {
    const result: m.Child[] = [];

    for (const option of attrs.knownArguments) {
      // Would be great to have smarter fuzzy matching, but in the meantime
      // simple substring check should work fine.
      const index = option.indexOf(this.argument);

      if (index === -1) {
        continue;
      }

      if (result.length === 10) {
        break;
      }

      result.push(
          m('div',
            {
              onclick: () => {
                this.setArgument(attrs, option);
              },
            },
            option.substring(0, index),
            // Highlight the matching part with bold font
            m('strong', this.argument),
            option.substring(index + this.argument.length)));
    }

    return result;
  }

  view({attrs}: m.Vnode<ArgumentPopupArgs>): m.Child {
    return m(
        '.name-completion',
        m('input', {
          oncreate: (vnode: m.VnodeDOM) =>
              (vnode.dom as HTMLInputElement).focus(),
          oninput: (e: Event) => {
            const input = e.target as HTMLInputElement;
            this.setArgument(attrs, input.value);
          },
          value: this.argument,
        }),
        m('.arguments-popup-sizer', longestString(attrs.knownArguments)),
        this.renderMatches(attrs));
  }
}
