"use strict";

/*
Todo:
- limit the view based on prefix matches
- highlight matching substrings
*/

// Don't let events bubble up
Event.prototype.halt = function () {
  this.stopPropagation();
  this.preventDefault();
};

// http://www.nlpado.de/~sebastian/software/ner_german.shtml
// http://www.cnts.ua.ac.be/conll2003/ner/
var namedEntities = [
  ["I-LOC",  "I-LOC",  "Location"],
  ["I-MISC", "I-MISC", "Miscellaneous"],
  ["I-ORG",  "I-ORG",  "Organization"],
  ["I-PER",  "I-PER",  "Person"]
];

// http://www.ids-mannheim.de/cosmas2/projekt/referenz/stts/morph.html
// http://nachhalt.sfb632.uni-potsdam.de/owl-docu/stts.html
var sttsArray = [
  // "$.", "$(", "$,"
  ["ADJA","ADJA", "Attributive Adjective"],
  ["ADJD","ADJD", "Predicative Adjective"],
  ["ADV","ADV", "Adverb"],
  ["APPO","APPO", "Postposition"],
  ["APPR","APPR", "Preposition"],
  ["APPRART","APPRART", "Preposition with Determiner"],
  ["APZR","APZR","Right Circumposition"],
  ["ART","ART", "Determiner"],
  ["CARD","CARD", "Cardinal Number"],
  ["FM","FM", "Foreign Material"],
  ["ITJ","ITJ", "Interjection"],
  ["KOKOM","KOKOM", "Comparison Particle"],
  ["KON","KON", "Coordinating Conjuncion"],
  ["KOUI","KOUI", "Subordinating Conjunction with 'zu'"],
  ["KOUS","KOUS", "Subordinating Conjunction with Sentence"],
  ["NE","NE", "Named Entity"],
  ["NN","NN", "Normal Nomina"],
  ["PAV", "PAV", "Pronominal Adverb"],
  ["PDAT","PDAT","Attributive Demonstrative Pronoun"],
  ["PDS","PDS", "Substitutive Demonstrative Pronoun"],
  ["PIAT","PIAT", "Attributive Indefinite Pronoun without Determiner"],
  ["PIDAT","PIDAT", "Attributive Indefinite Pronoun with Determiner"],
  ["PIS","PIS", "Substitutive Indefinite Pronoun"],
  ["PPER","PPER", "Personal Pronoun"],
  ["PPOSAT","PPOSAT", "Attributive Possessive Pronoun"],
  ["PPOSS","PPOSS", "Substitutive Possessive Pronoun"],
  ["PRELAT","PRELAT", "Attributive Relative Pronoun"],
  ["PRELS","PRELS", "Substitutive Relative Pronoun"],
  ["PRF","PRF", "Reflexive Pronoun"],
  ["PROAV","PROAV", "Pronominal Adverb"],
  ["PTKA","PTKA","Particle with Adjective"],
  ["PTKANT","PTKANT", "Answering Particle"],
  ["PTKNEG","PTKNEG", "Negation Particle"],
  ["PTKVZ","PTKVZ", "Separated Verbal Particle"],
  ["PTKZU","PTKZU", "'zu' Particle"],
  ["PWAT","PWAT", "Attributive Interrogative Pronoun"],
  ["PWAV","PWAV", "Adverbial Interrogative Pronoun"],
  ["PWS","PWS", "Substitutive Interrogative Pronoun"],
  ["TRUNC","TRUNC","Truncated"],
  ["VAFIN","VAFIN", "Auxiliary Finite Verb"],
  ["VAINF","VAINF", "Auxiliary Infinite Verb"],
  ["VAIMP","VAIMP", "Auxiliary Finite Imperative Verb"],
  ["VAPP","VAPP", "Auxiliary Perfect Participle"],
  ["VMFIN","VMFIN", "Modal Finite Verb"],
  ["VMINF","VMINF", "Modal Infinite Verb"],
  ["VMPP","VMPP", "Modal Perfect Participle"],
  ["VVFIN","VVFIN","Finite Verb"],
  ["VVIMP","VVIMP", "Finite Imperative Verb"],
  ["VVINF","VVINF", "Infinite Verb"],
  ["VVIZU","VVIZU", "Infinite Verb with 'zu'"],
  ["VVPP","VVPP", "Perfect Participle"],
  ["XY", "XY", "Non-Word"]
];

var mateSttsArray = sttsArray.slice(0);
mateSttsArray.push(
  ["<root-POS>","<root-POS>","Root Part of Speech"]
);


var hintArray = {
  "-" : [
    ["Connexor",   "cnx/"],
    ["CoreNLP",    "corenlp/"],
    ["Mate",       "mate/"],
    ["OpenNLP",    "opennlp/"],
    ["TreeTagger", "tt/"],
    ["Xerox Parser", "xip/"]
  ],
  "corenlp/" : [
    ["Named Entity", "ne=" , "Combined"],
    ["Named Entity", "ne_dewac_175m_600=" , "ne_dewac_175m_600"],
    ["Named Entity", "ne_hgc_175m_600=",    "ne_hgc_175m_600"]
  ],
  "corenlp/ne=" : namedEntities,
  "corenlp/ne_dewac_175m_600=" : namedEntities,
  "corenlp/ne_hgc_175m_600=" : namedEntities,
  "cnx/" : [
    ["Constituency", "c="],
    ["Lemma", "l="],
    ["Morphology", "m="],
    ["Part-of-Speech", "p="],
    ["Syntax", "syn="]
  ],
  "cnx/c=" : [
    ["np", "np", "Nominal Phrase"]
  ],
  // http://www.ids-mannheim.de/cosmas2/projekt/referenz/connexor/morph.html
  "cnx/m=" : [
    ["Abbr","Abbr", "Nouns: Abbreviation"],
    ["CMP","CMP", "Adjective: Comparative"],
    ["IMP", "IMP", "Mood: Imperative"],
    ["IND", "IND", "Mood: Indicative"],
    ["INF", "INF", "Infinitive"],
    ["ORD","ORD", "Numeral: Ordinal"],
    ["PAST", "PAST", "Tense: past"],
    ["PCP", "PCP", "Participle"],
    ["PERF", "PERF", "Perfective Participle"],
    ["PL","PL", "Nouns: Plural"],
    ["PRES", "PRES", "Tense: present"],
    ["PROG", "PROG", "Progressive Participle"],
    ["Prop","Prop", "Nouns: Proper Noun"],
    ["SUB", "SUB", "Mood: Subjunctive"],
    ["SUP","SUP", "Adjective: Superlative"]
  ],
  // http://www.ids-mannheim.de/cosmas2/projekt/referenz/connexor/morph.html
  "cnx/p=" : [
    ["A", "A", "Adjective"],
    ["ADV", "ADV", "Adverb"],
    ["CC", "CC", "Coordination Marker"],
    ["CS", "CS", "Clause Marker"],
    ["DET", "DET", "Determiner"],
    ["INTERJ", "INTERJ", "Interjection"],
    ["N", "N", "Noun"],
    ["NUM", "NUM", "Numeral"],
    ["PREP", "PREP", "Preposition"],
    ["PRON", "PRON", "Pro-Nominal"],
    ["V", "V", "Verb"]
  ],
  // http://www.ids-mannheim.de/cosmas2/projekt/referenz/connexor/syntax.html
  "cnx/syn=" : [
    ["@ADVL", "@ADVL", "Adverbial Head"],
    ["@AUX", "@AUX", "Auxiliary Verb"],
    ["@CC", "@CC", "Coordination"]
    ["@MAIN", "@MAIN", "Main Verb"],
    ["@NH", "@NH", "Nominal Head"],
    ["@POSTMOD", "@POSTMOD", "Postmodifier"],
    ["@PREMARK", "@PREMARK", "Preposed Marker"],
    ["@PREMOD", "@POSTMOD", "Premodifier"]
  ],
  "opennlp/" : [
    ["Part-of-Speech", "p="]
  ],
  "opennlp/p=" : sttsArray,
  "xip/" : [
    ["Constituency", "c="],
    // Inactive: ["Dependency", "d="],
    ["Lemma", "l="],
    ["Part-of-Speech", "p="],
  ],
  // "xip/c=" : [],
  // Inactive: "xip/d=" : [],
  // "xip/p=" : [],
  "tt/" : [
    ["Lemma", "l="],
    ["Part-of-Speech", "p="]
  ],
  "tt/p=" : sttsArray,
  "mate/" : [
    // Inactive: "d" : ["d=", "Dependency"],
    ["Lemma", "l="],
    ["Morphology", "m="],
    ["Part-of-Speech", "p="]
  ],
  // Inactive: mate/d=
  "mate/p=" : mateSttsArray,
  "mate/m=" : [
    ["Case", "case:"],
    ["Degree", "degree:"],
    ["Gender", "gender:"],
    ["Mood", "mood:"],
    ["Number", "number:"],
    ["Person", "person:"],
    ["Tense","tense:"],
    ["No type", "<no-type>"]
  ],
  "mate/m=case:" : [
    ["acc", "acc", "Accusative"],
    ["dat","dat", "Dative"],
    ["gen", "gen","Genitive"],
    ["nom","nom", "Nominative"],
    ["*","*", "Undefined"]
  ],
  "mate/m=degree:" : [
    ["comp","comp", "Comparative"],
    ["pos","pos", "Positive"],
    ["sup","sup", "Superative"]
  ],
  "mate/m=gender:" : [
    ["fem", "fem", "Feminium"],
    ["masc", "masc", "Masculinum"],
    ["neut","neut", "Neuter"],
    ["*","*","Undefined"]
  ],
  "mate/m=mood:" : [
    ["imp","imp", "Imperative"],
    ["ind","ind", "Indicative"],
    ["subj","subj", "Subjunctive"]
  ],
  "mate/m=number:" : [
    ["pl","pl","Plural"],
    ["sg","sg","Singular"],
    ["*","*","Undefined"]
  ],
  "mate/m=person:" : [
    ["1","1", "First Person"],
    ["2","2", "Second Person"],
    ["3","3", "Third Person"]
  ],
  "mate/m=tense:" : [
    ["past","past", "Past"],
    ["pres","pres", "Present"]
  ]
};


/**
 * Analyze strings for prefixes
 */
var PrefixAnalyzer = {
  _regex : new RegExp(
    "(?:^|[^a-zA-Z0-9])" +    // Anchor
    "((?:[-a-zA-Z0-9]+?)\/" + // Foundry
    "(?:" +
    "(?:[^=:]+?)=" +          // Layer
    "(?:(?:[^:]+?):)?" +      // Key
    ")?" +
    ")$"),
  analyze : function (text) {
    if (!this._regex.exec(text))
      return undefined;
    return RegExp.$1
  }
};

/**
 * Event handling after a key pressed
 */
function updateKey (that, e) {
  var menu = that.menu();
  switch (e.key) {
  case 'Esc':
    // Hide menu
    menu.hide();
    break;
  case 'Down':
    e.halt(); // No event propagation

    // Menu is not active
    if (!menu.active) {
      that.popUp()
    }
    // Menu is active
    else {
      that.removePrefix();
      menu.next();
    };

    break;
  case "Up":
    if (!menu.active)
      break;
    e.halt(); // No event propagation
    that.removePrefix();
    menu.prev();
    break;
  case "Enter":
    if (!menu.active)
      break;
    e.halt(); // No event propagation
    that.insertText(menu.getActiveItem().getAction());
    that.removePrefix();

    // Remove menu
    menu.hide();

    // Fill this with the correct value
    // Todo: This is redundant with click function
    var show;
    if ((show = that.analyzeContext()) !== "-") {
      menu.show(show);
      menu.update(
        e.target.getBoundingClientRect().right
      );
    };

    break;
  default:
    if (!menu.active)
      break;

    // key stroke is not a character
    if (e.key.length != 1) {

      // Key stroke is not a text modifying key
      if (e.key !== 'Shift' &&
          e.key !== 'Up'    &&
          e.key !== 'Down'  &&
          e.key !== 'Enter' &&
	  e.key !== 'Alt'   &&
	  e.key !== 'AltGraph' &&
	  e.key !== 'CapsLock') {
	that.insertPrefix();
	menu.hide();
      };
      break;
    };

    e.halt(); // No event propagation
    
    // Try to identify prefix
    if (menu.skipToPrefix(e.key))
      break;

    // Prefix not found
    that.insertPrefix();
    menu.hide();
  };
};

// new hint object
var Hint = {
  _search   : undefined,   // Return the search element
  _mirror   : undefined,   // Return the mirror element
  _menu     : undefined,
  _analyzer : undefined,
  firstTry  : true,
  menu : function () {
    // In case this wasn't defined yet
    if (this._menu === undefined) {
      this._menu = Object.create(Menu).init();
      this._mirror.appendChild(this._menu.getElement());
    };
    return this._menu;
  },

  // Initialize the object
  init : function () {
    this._search = document.getElementById("q-field");
    this._mirror = document.createElement("div");
    this._mirror.setAttribute("id", "searchMirror");
    this._mirror.appendChild(document.createElement("span"));
    document.getElementsByTagName("body")[0].appendChild(this._mirror);

    this._analyzer = Object.create(PrefixAnalyzer);

    // Update positional information, in case the windows size changes    
    var that = this;
    window.onresize = function () { that.reposition() };

    // Add event listener for key pressed down
    this._search.addEventListener(
      "keydown",
      function (e) {
	updateKey(that, e)
      },
      false
    );

    // Reposition the mirror
    this.reposition();

    // Return object for chaining
    return this;
  },

  // Popup method
  popUp : function () {
    if (this.active)
      return;

    // Reposition hint list on first try
    if (this.firstTry)
      this.reposition().firstTry = false;

    // Update view
    this.update();

    // Fill this with the correct value
    if (this.menu().show(this.analyzeContext()))
      this.update(
        this._search.getBoundingClientRect().right
      );
    else
      this.hide();

    this._search.focus();
  },

  // Reposition the mirror object
  reposition : function () {

    // Update style properties
    var searchRect  = this._search.getBoundingClientRect();
    var searchStyle = window.getComputedStyle(this._search, null);
    var mStyle = this._mirror.style;
    mStyle.left = searchRect.left + "px";
    mStyle.top  = searchRect.bottom + "px";
    mStyle.borderLeftColor = "transparent";
    mStyle.height          = "1px";
    mStyle.paddingLeft     = searchStyle.getPropertyValue("padding-left");
    mStyle.marginLeft      = searchStyle.getPropertyValue("margin-left");
    mStyle.borderLeftWidth = searchStyle.getPropertyValue("border-left-width");
    mStyle.borderLeftStyle = searchStyle.getPropertyValue("border-left-style");
    mStyle.fontSize        = searchStyle.getPropertyValue("font-size");
    mStyle.fontFamily      = searchStyle.getPropertyValue("font-family");
    return this;
  },

  // Reposition the menu object
  update : function () {
    var s = this._search;
    var start = s.selectionStart;
    this._mirror.firstChild.textContent = s.value.substring(0, start);
  },

  analyzeContext : function () {
    var context = this._splitInputText()[0];
    if (context === undefined || context.length === 0)
      return "-";
    context = this._analyzer.analyze(context);
    if (context === undefined || context.length === 0)
      return "-";

    return context;
  },

  _splitInputText : function () {
    var s = this._search;
    var value = s.value;
    var start = s.selectionStart;
    var begin = value.substring(0, start);
    var end   = value.substring(start, value.length);
    return new Array(begin, end);
  },

  // Insert text at the current cursor position
  insertText : function (text) {
    var s = this._search;
    var splitText = this._splitInputText();
    s.value          = splitText[0] + text + splitText[1];
    s.selectionStart = (splitText[0] + text).length
    s.selectionEnd   = s.selectionStart;
    this._mirror.firstChild.textContent = splitText[0] + text;
  },

  // Remove stored prefix 
  removePrefix : function () {
    this.menu()._prefix = undefined;
  },

  // Insert stored prefix at current cursor position
  insertPrefix : function () {
    if (this.menu()._prefix === undefined)
      return;
    this.insertText(this.menu()._prefix);
  }
};


/**
* Menu list
*/
var Menu = {
  active     : false,
  _element   : undefined,
  _position  : 0,   // Position of menu item
  _offset    : 0,   // Visual offset for chosen highlight
  _size      : 8,  // Number of items to be shown
  _items     : [],  // Items for menu
  _name      : undefined,
  _prefix    : undefined,
  getElement : function () {
    return this._element;
  },
  init : function () {
    this._element = document.createElement("ul");

    // Add onclick event
    this._element.addEventListener("click", chooseHint, false);

    this._element.style.opacity = 0;
    this.active = false;
    this._setDefaults();
    return this;
  },
  update : function (searchRightPosition) {
    var infoRightPosition = this._element.getBoundingClientRect().right;
    if (infoRightPosition > searchRightPosition) {
      this._element.style.marginLeft = '-' + (infoRightPosition - searchRightPosition) + 'px';
    };
    return this;
  },
  next : function () {
    if (!this.active)
      return;
    this._clearView();
    this._position++;

    // In case the list is bigger than the view
    if (this._items.length > this._size) {
      if (this._position >= this._items.length) {
	// Roll to top
	this._offset = 0;
	this._position = 0;
	this._showItems(0);
      }
      else if (this._position >= (this._size + this._offset)) {
	// Roll down
	this._element.removeChild(this._element.firstChild);
	this._offset++;
	this._element.appendChild(this.getItem(this._position).getElement());
      };
    }
    else if (this._position >= this._items.length) {
      this._position = 0;
    };
    this._updateView();
  },
  prev : function () {
    if (!this.active)
      return;
    this._clearView();
    this._position--;

    // In case the list is bigger than the view
    if (this._items.length > this._size) {
      if (this._position < 0) {
	// roll to bottom
	this._setToLast();
	this._offset = (this._position - this._size) + 1;
	this._showLastItems();
      }
      else if (this._position < this._offset) {
	// roll up
	this._element.removeChild(this._element.lastChild);
	this._offset--;
	this._element.insertBefore(
	  this.getItem(this._position).getElement(),
	  this._element.firstChild
	);
      };
    }
    else if (this._position < 0) {
      this._setToLast();
    };
    this._updateView();
  },
  skipToPrefix : function (prefix) {
    if (this._prefix === undefined)
      this._prefix = prefix.toLocaleLowerCase();
    else
      this._prefix += prefix.toLocaleLowerCase();

    var pos = 0;
    var found = false;
    var good = -1;
    var test;
    for (; pos < this._items.length; pos++) {
      if ((test = this.getItem(pos).getLCName().indexOf(this._prefix)) !== -1) {
	if (test === 0) {
	  found = true;
	  break;
	};
	good = pos;
      };
    };

    // Perfect prefix
    if (found)
      return this.skipToPos(pos);
    // At least infix
    else if (good !== -1)
      return this.skipToPos(good);
    // No
    return false;
  },
  skipToPos : function (index) {
    if (!this.active)
      return false;
    if (index < 0 || index >= this._items.length)
      return false;

    this._clearView();
    this._position = index;

    if (index < this._offset || index >= (this._offset + this._size)) {

      // Index is in the final frame
      if (index >= (this._items.length - this._size)) {
	this._offset = this._items.length - this._size;
	this._showLastItems();
      }

      // Index is in the final frame
      else {
	this._offset = index;
	this._showItems(index);
      };
    };

    // Activate new position
    this._updateView();
    return true;
  },
  show : function (name) {
    // The element is already given
    if (this._name !== name) {

      // Todo: store hints in hash

      // Delete items
      this._items.length = 0;

      var items = hintArray[name];

      // Hints not found
      if (items === undefined)
	return false;

      var i;
      for (i in items) {
	var item = Object.create(MenuItem).init(items[i]);
	this._items.push(item);
      };

      // Add classes for rolling menus
      this.getItem(0).getElement().classList.add("no-more");
      this.getItem(i).getElement().classList.add("no-more");

      this._name = name;
    };
    this._showItems(0);
    this._element.style.opacity = 1;
    this._setDefaults();
    this.active = true;
    this._updateView();
    return true;
  },
  hide : function () {
    this._element.style.opacity = 0;
    if (this.active)
      this.getActiveItem().deactivate();
    this._setDefaults();
    this.active = false;
  },
  getActiveItem : function () {
    return this._items[this._position];
  },
  getItem : function (index) {
    return this._items[index];
  },
  getPrefix : function () {
    return this._prefix;
  },
  _setDefaults : function () {
    this._offset = 0;
    this._position = 0;
    this._prefix = undefined;
  },
  // Remove all visible list items
  _deleteMenu : function () {
    var child;
    while (child = this._element.firstChild)
      this._element.removeChild(child);
  },
  _clearView : function () {
    var active = this.getActiveItem();
    if (active !== undefined)
      active.deactivate();
  },
  _updateView : function () {
    var active = this.getActiveItem();
    if (active !== undefined)
      active.activate();
  },

  // Make all list items visible starting at a certain offset
  _showItems : function (offset) {
    this._deleteMenu();
    for (var i = offset; i < this._size + offset; i++) {
      if (i >= this._items.length)
	break;
      this._element.appendChild(
	this._items[i].getElement()
      )
    };
  },

  // Make all final list items visible
  _showLastItems : function () {
    this._deleteMenu();
    for (var i = (this._items.length - 1); i >= (this._items.length - this._size); i--) {
      if (i < 0)
	break;
      if (!this._element.firstChild)
	this._element.appendChild(this._items[i].getElement());
      else
	this._element.insertBefore(
	  this._items[i].getElement(),
	  this._element.firstChild
	);
    };
  },
  _setToLast : function () {
    this._position = this._items.length - 1;
  }
};

function chooseHint (e) {
  var element = e.target;
  while (element.nodeName == "STRONG" || element.nodeName == "SPAN") {
    element = element.parentNode;
  };

  if (element === undefined || element.nodeName != "LI")
    return;

  var action = element.getAttribute('data-action');
  hint.insertText(action);
  var menu = hint.menu();
  menu.hide();

  // Fill this with the correct value
  var show;
  if ((show = hint.analyzeContext()) !== "-") {
    menu.show(show);
    menu.update(
      hint._search.getBoundingClientRect().right
    );
  };

  hint._search.focus();
};

var MenuItem = {
  _name    : undefined,
  _lcname  : undefined,
  _desc    : undefined,
  _element : undefined,
  _action  : "",
  activate : function () {
    this._element.classList.add("active");
  },
  deactivate : function () {
    this._element.classList.remove("active");
  },
  // Initialize this item
  init : function (param) {
    this._name = param[0];
    this._action = param[1];
    this._lcname = this._name.toLocaleLowerCase();

    if (param.length > 2) {
      this._desc = param[2];
      this._lcname += " " + this._desc.toLocaleLowerCase();
    };

    return this;
  },

  // Created element of this item
  getElement : function () {
    if (this._element !== undefined)
      return this._element;

    var li = document.createElement("li");

    li.setAttribute("data-action", this._action);

    var name = document.createElement("strong");

    name.appendChild(document.createTextNode(this._name));
    li.appendChild(name);
    if (this._desc !== undefined) {
      var desc = document.createElement("span");
      desc.appendChild(document.createTextNode(this._desc));
      li.appendChild(desc);
    };
    this._element = li;
    return this._element;
  },

  // Name of this item
  getName : function () {
    return this._name;
  },

  getLCName : function () {
    return this._lcname;
  },

  // Description of this item
  getDesc : function () {
    return this._desc;
  },


  getAction : function () {
    return this._action;
  }
};
