Project: AceWiki
// This file is part of AceWiki.
// Copyright 2008-2012, AceWiki developers. 
//  
// AceWiki is free software: you can redistribute it and/or modify it under the terms of the GNU 
// Lesser General Public License as published by the Free Software Foundation, either version 3 of 
// the License, or (at your option) any later version. 
//  
// AceWiki is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
// even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
// Lesser General Public License for more details. 
//  
// You should have received a copy of the GNU Lesser General Public License along with AceWiki. If 
// not, see http://www.gnu.org/licenses/. 
 
package ch.uzh.ifi.attempto.aceeditor; 
 
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
 
import nextapp.echo.app.Component; 
import nextapp.echo.app.event.ActionEvent; 
import nextapp.echo.app.event.ActionListener; 
import ch.uzh.ifi.attempto.ape.FunctionWords; 
import ch.uzh.ifi.attempto.base.ConcreteOption; 
import ch.uzh.ifi.attempto.base.NextTokenOptions; 
import ch.uzh.ifi.attempto.echocomp.CheckBox; 
import ch.uzh.ifi.attempto.echocomp.MessageWindow; 
import ch.uzh.ifi.attempto.echocomp.TextField; 
import ch.uzh.ifi.attempto.preditor.MenuEntry; 
import ch.uzh.ifi.attempto.preditor.PreditorWindow; 
import ch.uzh.ifi.attempto.preditor.DefaultMenuCreator; 
import ch.uzh.ifi.attempto.preditor.SpecialMenuItem; 
import ch.uzh.ifi.attempto.preditor.WordEditorForm; 
import ch.uzh.ifi.attempto.preditor.WordEditorWindow; 
 
/**
 * This is the menu creator class for the ACE Editor. 
 *  
 * @author Tobias Kuhn 
 */
 
class ACEEditorMenuCreator extends DefaultMenuCreator implements ActionListener { 
 
 private static final long serialVersionUID = -1357779780345075117L
  
 private static Map<String, String> cats; 
 private static List<String> extCats; 
 private static List<String> menuGroupOrdering; 
 private LexiconHandler lexiconHandler; 
 private ACEEditor editor; 
 private PreditorWindow preditorWindow; 
  
 static { 
  cats = new HashMap<String, String>(); 
  cats.put("noun_sg""noun"); 
  cats.put("noun_pl""noun"); 
  cats.put("prop_sg""proper name"); 
  cats.put("propdef_sg""proper name"); 
  cats.put("iv_finsg""intransitive verb"); 
  cats.put("iv_infpl""intransitive verb"); 
  cats.put("tv_finsg""transitive verb"); 
  cats.put("tv_infpl""transitive verb"); 
  cats.put("tv_pp""passive verb"); 
  cats.put("adj_itr""adjective"); 
  cats.put("adj_itr_comp""adjective"); 
  cats.put("adj_itr_sup""adjective"); 
  cats.put("adj_tr""transitive adjective"); 
  cats.put("adj_tr_comp""transitive adjective"); 
  cats.put("adv""adverb"); 
  cats.put("adv_comp""adverb"); 
  cats.put("adv_sup""adverb"); 
  cats.put("prep""preposition"); 
  extCats = new ArrayList<String>(cats.keySet()); 
   
  cats.put("adj_prep""preposition"); 
  cats.put("pron""reference"); 
  cats.put("def_noun_sg""reference"); 
  cats.put("ref""reference"); 
  cats.put("var""new variable"); 
  cats.put("num""function word"); 
   
  menuGroupOrdering = new ArrayList<String>(); 
  menuGroupOrdering.add("function word"); 
  menuGroupOrdering.add("proper name"); 
  menuGroupOrdering.add("noun"); 
  menuGroupOrdering.add("adjective"); 
  menuGroupOrdering.add("transitive adjective"); 
  menuGroupOrdering.add("intransitive verb"); 
  menuGroupOrdering.add("transitive verb"); 
  menuGroupOrdering.add("passive verb"); 
  menuGroupOrdering.add("adverb"); 
  menuGroupOrdering.add("preposition"); 
  menuGroupOrdering.add("new variable"); 
  menuGroupOrdering.add("reference"); 
 
 
 ACEEditorMenuCreator(ACEEditor editor, LexiconHandler lexiconHandler) { 
  this.editor = editor; 
  this.lexiconHandler = lexiconHandler; 
   
  setColorShift("proper name"60); 
  setColorShift("noun"100); 
  setColorShift("adjective"160); 
  setColorShift("transitive adjective"180); 
  setColorShift("intransitive verb"200); 
  setColorShift("transitive verb"220); 
  setColorShift("passive verb"220); 
  setColorShift("adverb"260); 
  setColorShift("preposition"290); 
  setColorShift("new variable"320); 
  setColorShift("reference"320); 
 
  
 void setPreditorWindow(PreditorWindow preditorWindow) { 
  this.preditorWindow = preditorWindow; 
 
  
 public List<String> getMenuGroupOrdering() { 
  return menuGroupOrdering; 
 
 
 public MenuEntry createMenuEntry(ConcreteOption option) { 
  String n = option.getCategoryName(); 
  if (n == null) { 
   return new MenuEntry(option, "function word"); 
  else if (cats.keySet().contains(n)) { 
   return new MenuEntry(option, cats.get(n)); 
  else { 
   return new MenuEntry(option, "function word"); 
  
 
 
 public List<SpecialMenuItem> createSpecialMenuItems(NextTokenOptions options) { 
  List<SpecialMenuItem> items = new ArrayList<SpecialMenuItem>(); 
  Map<String, String> m = new HashMap<String, String>(); 
  for (String s : extCats) { 
   if (options.containsCategory(s)) { 
    String menuGroup = cats.get(s); 
    if (m.containsKey(menuGroup)) { 
     m.put(menuGroup, m.get(menuGroup) + s + ":"); 
    else { 
     m.put(menuGroup, "new:" + s + ":"); 
    
   
  
  if (!editor.isLexiconImmutable()) { 
   for (String menuGroup : m.keySet()) { 
    items.add(new SpecialMenuItem( 
      "new..."
      menuGroup, 
      m.get(menuGroup), 
      this 
     )); 
   
  
  return items; 
 
  
 public void actionPerformed(ActionEvent e) { 
   
  String c = e.getActionCommand(); 
  if (c.startsWith("new:")) { 
   WordEditorWindow wew = new WordEditorWindow("New Word", c, 500300); 
   if (c.matches(".*:prop.*")) { 
    WordEditorForm pane = new WordEditorForm("Proper Name", wew, this); 
    pane.addRow("proper name"new TextField(), ""true); 
    pane.addRow("... used with \"the\""new CheckBox(), ""false); 
    wew.addTab(pane); 
    editor.showWindow(wew); 
   else if (c.matches(".*:noun_.*")) { 
    WordEditorForm pane = new WordEditorForm("Noun", wew, this); 
    pane.addRow("singular"new TextField(), ""true); 
    pane.addRow("plural"new TextField(), ""true); 
    wew.addTab(pane); 
    editor.showWindow(wew); 
   else if (c.matches(".*:iv_.*")) { 
    WordEditorForm pane = new WordEditorForm("Intransitive Verb", wew, this); 
    pane.addRow("third singular"new TextField(), ""true); 
    pane.addRow("bare infinitive"new TextField(), ""true); 
    wew.addTab(pane); 
    editor.showWindow(wew); 
   else if (c.matches(".*:tv_.*")) { 
    WordEditorForm pane = new WordEditorForm("Transitive Verb", wew, this); 
    pane.addRow("third singular"new TextField(), ""true); 
    pane.addRow("bare infinitive"new TextField(), ""true); 
    pane.addRow("past participle"new TextField(), ""false); 
    wew.addTab(pane); 
    editor.showWindow(wew); 
   else if (c.matches(".*:adj_itr.*")) { 
    WordEditorForm pane = new WordEditorForm("Intransitive Adjective", wew, this); 
    pane.addRow("positive"new TextField(), ""true); 
    pane.addRow("comparative"new TextField(), ""false); 
    pane.addRow("superlative"new TextField(), ""false); 
    wew.addTab(pane); 
    editor.showWindow(wew); 
   else if (c.matches(".*:adj_tr.*")) { 
    WordEditorForm pane = new WordEditorForm("Transitive Adjective", wew, this); 
    pane.addRow("positive"new TextField(), ""true); 
    pane.addRow("comparative"new TextField(), ""false); 
    wew.addTab(pane); 
    editor.showWindow(wew); 
   else if (c.matches(".*:adv.*")) { 
    WordEditorForm pane = new WordEditorForm("Adverb", wew, this); 
    pane.addRow("positive"new TextField(), ""true); 
    pane.addRow("comparative"new TextField(), ""false); 
    pane.addRow("superlative"new TextField(), ""false); 
    wew.addTab(pane); 
    editor.showWindow(wew); 
   else if (c.matches(".*:prep:.*")) { 
    WordEditorForm pane = new WordEditorForm("Preposition", wew, this); 
    pane.addRow("preposition"new TextField(), ""true); 
    wew.addTab(pane); 
    editor.showWindow(wew); 
   
  
   
  if (e.getSource() instanceof WordEditorWindow) { 
   WordEditorWindow wew = (WordEditorWindow) e.getSource(); 
   if (e.getActionCommand().equals("OK")) { 
     
    for (String s : wew.getCurrentTab().getRequiredTextFieldContents()) { 
     if (s.matches("(\\s|_)*")) { 
      editor.showWindow(new MessageWindow( 
        "Error"
        "A required word form is missing."
        wew, 
        "OK" 
       )); 
      return
     
    
     
    List<String> w = new ArrayList<String>(); 
    for (Component comp : wew.getCurrentTab().getFormElements()) { 
     if (!(comp instanceof TextField)) continue
     String t = ((TextField) comp).getText().replaceAll("(\\s|_)+""_"
       .replaceAll("(^_|_$)"""); 
      
     if (FunctionWords.isFunctionWord(t)) { 
      editor.showWindow(new MessageWindow( 
        "Error"
        "This is a function word that cannot be redefined: '" + t + "'"
        wew, 
        "OK" 
       )); 
      return
     else if (t.length() > 0 && !t.matches("[a-zA-Z][a-zA-Z0-9_-]*")) { 
      editor.showWindow(new MessageWindow( 
        "Error"
        "This is not a valid word: '" + t + "'"
        wew, 
        "OK" 
       )); 
      return
     else if (!t.equals("") && w.contains(t)) { 
      editor.showWindow(new MessageWindow( 
        "Error"
        "All word forms must be distinct."
        wew, 
        "OK" 
       )); 
      return
     else if (lexiconHandler.getWordsByText(t).size() > 0) { 
      editor.showWindow(new MessageWindow( 
        "Error"
        "This word is already used in the lexicon: '" + t + "'"
        wew, 
        "OK" 
       )); 
      return
     
     w.add(t); 
    
     
    Word word = null
    c = wew.getType(); 
    if (c.matches(".*:prop_sg:.*")) { 
     if (((CheckBox) wew.getCurrentTab().getFormElements().get(1)).isSelected()) { 
      word = new Word("pndef_sg('" + w.get(0) + "','" + w.get(0) + "',undef)."); 
     else { 
      word = new Word("pn_sg('" + w.get(0) + "','" + w.get(0) + "',undef)."); 
     
     lexiconHandler.addWord(word); 
    else if (c.matches(".*:noun_.*")) { 
     Word wordsg = new Word("noun_sg('" + w.get(0) + "','" + w.get(0) + "',undef)."); 
     Word wordpl = new Word("noun_pl('" + w.get(1) + "','" + w.get(0) + "',undef)."); 
     if (c.matches(".*:noun_sg:.*")) { 
      word = wordsg; 
     else { 
      word = wordpl; 
     
     lexiconHandler.addWord(wordsg); 
     lexiconHandler.addWord(wordpl); 
    else if (c.matches(".*:iv_.*")) { 
     Word wordsg = new Word("iv_finsg('" + w.get(0) + "','" + w.get(1) + "')."); 
     Word wordpl = new Word("iv_infpl('" + w.get(1) + "','" + w.get(1) + "')."); 
     if (c.matches(".*:iv_finsg:.*")) { 
      word = wordsg; 
     else { 
      word = wordpl; 
     
     lexiconHandler.addWord(wordsg); 
     lexiconHandler.addWord(wordpl); 
    else if (c.matches(".*:tv_.*")) { 
     Word wordsg = new Word("tv_finsg('" + w.get(0) + "','" + w.get(1) + "')."); 
     Word wordpl = new Word("tv_infpl('" + w.get(1) + "','" + w.get(1) + "')."); 
     Word wordpp = null
     if (!w.get(2).equals("")) { 
      wordpp = new Word("tv_pp('" + w.get(2) + "','" + w.get(1) + "')."); 
     
     if (c.matches(".*:tv_finsg:.*")) { 
      word = wordsg; 
     else if (c.matches(".*:tv_infpl:.*")) { 
      word = wordpl; 
     else { 
      word = wordpp; 
     
     if (word == null) { 
      editor.showWindow(new MessageWindow( 
        "Error"
        "The word form to be used is missing."
        wew, 
        "OK" 
       )); 
      return
     
     lexiconHandler.addWord(wordsg); 
     lexiconHandler.addWord(wordpl); 
     lexiconHandler.addWord(wordpp); 
    else if (c.matches(".*:adj_itr.*")) { 
     word = new Word("adj_itr('" + w.get(0) + "','" + w.get(0) + "')."); 
     lexiconHandler.addWord(word); 
     if (!w.get(1).equals("")) { 
      lexiconHandler.addWord("adj_itr_comp('" + w.get(1) + "','" + w.get(0) + "')."); 
     
     if (!w.get(2).equals("")) { 
      lexiconHandler.addWord("adj_itr_sup('" + w.get(2) + "','" + w.get(0) + "')."); 
     
    else if (c.matches(".*:adj_tr.*")) { 
     String prep = w.get(0).replaceFirst("^.*[_-]([a-zA-Z0-9]+)$""$1"); 
     word = new Word("adj_tr('" + w.get(0) + "','" + w.get(0) + "', '" + prep + "')."); 
     if (prep.equals(w.get(0))) { 
      editor.showWindow(new MessageWindow( 
        "Error"
        "Transitive adjectives must end with a preposition (e.g. '...-for')."
        wew, 
        "OK" 
       )); 
      return
     
     if (!w.get(1).equals("")) { 
      String prepc = w.get(1).replaceFirst("^.*[_-]([a-zA-Z0-9]+)$""$1"); 
      if (prepc.equals(w.get(1))) { 
       editor.showWindow(new MessageWindow( 
         "Error"
         "Transitive adjectives must end with a preposition (e.g. '...-for')."
         wew, 
         "OK" 
        )); 
       return
      
      if (!prep.equals(prepc)) { 
       editor.showWindow(new MessageWindow( 
         "Error"
         "Positive and comparative form must end with the same preposition."
         wew, 
         "OK" 
        )); 
       return
      
     
     lexiconHandler.addWord(word); 
     if (!w.get(1).equals("")) { 
      lexiconHandler.addWord("adj_tr_comp('" + w.get(1) + "','" + w.get(0) + "', '" + prep + "')."); 
     
    else if (c.matches(".*:adv.*")) { 
     word = new Word("adv('" + w.get(0) + "','" + w.get(0) + "')."); 
     lexiconHandler.addWord(word); 
     if (!w.get(1).equals("")) { 
      lexiconHandler.addWord("adv_comp('" + w.get(1) + "','" + w.get(0) + "')."); 
     
     if (!w.get(2).equals("")) { 
      lexiconHandler.addWord("adv_sup('" + w.get(2) + "','" + w.get(0) + "')."); 
     
    else if (c.matches(".*:prep:.*")) { 
     word = new Word("prep('" + w.get(0) + "','" + w.get(0) + "')."); 
     lexiconHandler.addWord(word); 
    
     
    if (word != null) { 
     preditorWindow.addTextElement(word.getTextElement()); 
    
   
   editor.removeWindow(wew); 
  
 
 
}