/*
 * This file is part of the Poliqarp suite.
 * 
 * Copyright (C) 2004-2009 by Instytut Podstaw Informatyki Polskiej
 * Akademii Nauk (IPI PAN; Institute of Computer Science, Polish
 * Academy of Sciences; cf. www.ipipan.waw.pl).  All rights reserved.
 * 
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file gpl.txt included in the packaging
 * of this file.  (See http://www.gnu.org/licenses/translations.html for
 * unofficial translations.)
 * 
 * A commercial license is available from IPI PAN (contact
 * Michal.Ciesiolka@ipipan.waw.pl or ipi@ipipan.waw.pl for more
 * information).  Licensees holding a valid commercial license from IPI
 * PAN may use this file in accordance with that license.
 * 
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

package ipipan.poliqarp.gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.NoSuchElementException;
import javax.swing.*;

import ipipan.poliqarp.util.MRUCollection;

/**
 * The GUI's menu. This specialization of the <code>MultilingualMenuBar</code>
 * is responsible for creating the menu hierarchy used by the GUI and handling
 * actions triggered by its entries.
 */
public class PoliqarpMenuBar extends MultilingualMenuBar 
   implements ActionListener
{
   private static final int M_FILE = 100; 
   private static final int M_OPEN = 101;
   private static final int M_MRUMENU = 102;
   private static final int M_MRU = 1020;
   private static final int M_SAVE = 103;
   private static final int M_EXIT = 109;
   private static final int M_STATISTICS = 200;
   private static final int M_CORPUSSTATS = 201;
   private static final int M_SETTINGS = 300;
   private static final int M_LANGUAGE = 301;
   private static final int M_ENGLISH = 3011;
   private static final int M_POLISH = 3012;
   private static final int M_OPTIONS = 302;
   private static final int M_CONNECT = 303;
   private static final int M_HELP = 900;
   private static final int M_HELPSEARCH = 901;
   private static final int M_ABOUT = 909;

   private Application app;
   private JMenu recentMenu;
   
   private JMenuItem createMenuItem(boolean enabled) 
   {
      JMenuItem res = new JMenuItem();
      res.addActionListener(this);
      res.setEnabled(enabled);
      return res;
   }

   private JMenuItem createMenuItem(Icon icon) 
   {
      JMenuItem res = new JMenuItem(icon);
      res.addActionListener(this);
      return res;
   }

   private JMenuItem createMenuItem(int shortcut) 
   {
      JMenuItem res = new JMenuItem();
      res.setAccelerator(KeyStroke.getKeyStroke(shortcut, 0));
      res.addActionListener(this);
      return res;
   }

   private JMenuItem createMenuItem(KeyStroke shortcut) 
   {
      JMenuItem res = new JMenuItem();
      res.setAccelerator(shortcut);
      res.addActionListener(this);
      return res;
   }

   private JMenuItem createMenuItem(KeyStroke shortcut, Icon icon,
      boolean enabled) 
   {
      JMenuItem res = new JMenuItem(icon);
      res.setAccelerator(shortcut);
      res.addActionListener(this);
      res.setEnabled(enabled);
      return res;
   }

   /**
    * Handles actions generated by the elements of this menu, directing most
    * of the requests to the <code>Application</code>.
    */
   public void actionPerformed(ActionEvent e)
   {
      JMenuItem source = (JMenuItem)e.getSource();
      int command = Integer.parseInt(source.getActionCommand());
      switch (command) {
         case M_ENGLISH:
         case M_POLISH:
            String lang = (command == M_ENGLISH) ? "English" : "Polish";
            config.setLanguage(lang);
            app.updateLanguage();
            break;
         case M_HELPSEARCH:
            new HelpBrowser(app);
            break;
         case M_ABOUT:
            app.showAbout();
            break;
         case M_OPEN:
            app.createOpenDialog();
            break;
         case M_SAVE:
            app.createSaveDialog();
            break;
         case M_CORPUSSTATS:
            app.showCorpusStatistics();
            break;
         case M_OPTIONS:
            app.createConfigDialog();
            break;
         case M_CONNECT:
            app.connectToServer();
            break;
         case M_EXIT:
            app.exitCleanup();
            System.exit(0);
            break;
      }
      if (command >= M_MRU && command <= M_MRU + 9) 
         app.openMRU(command - M_MRU);
   }

   private Icon getJGoodiesIcon(String fileName)
   {
      return new ImageIcon(UIManager.getLookAndFeel().getClass().
         getResource("icons/" + fileName));
   }

   /**
    * Enables or disables the options in this menu bar that get activated 
    * when a corpus becomes opened.
    */
   public void activateCorpusOptions(boolean b)
   {
      getItem(M_CORPUSSTATS).setEnabled(b);
   }

   /**
    * Enables or disables the options in this menu bar that get activated 
    * when a query is executed.
    */
   public void activateQueryOptions(boolean b)
   {
      getItem(M_SAVE).setEnabled(b);
   }

   public void disableConnectionCmd()
   {
      getItem(M_CONNECT).setEnabled(false);
      getItem(M_OPEN).setEnabled(true);
      getItem(M_MRUMENU).setEnabled(true);
   }
   
   /**
    * Creates a Poliqarp menu bar.
    */
   public PoliqarpMenuBar(Application app) 
   {
      super(app.getConfig());
      this.app = app;
      
      JMenu menu, submenu;
      JRadioButtonMenuItem rbitem;
      String language = "";
      
      try {
         language = config.getConfigItem("language").toLowerCase();
      } catch (NoSuchElementException e) {};      
      
      menu = new JMenu();
      add(M_FILE, null, menu);
      {
         add(M_OPEN, menu, createMenuItem(KeyStroke.getKeyStroke(KeyEvent.VK_O,
            ActionEvent.CTRL_MASK), getJGoodiesIcon("TreeOpen.gif"), false));
         recentMenu = new JMenu();
         recentMenu.setEnabled(false);
         add(M_MRUMENU, menu, recentMenu);
         add(M_SAVE, menu, createMenuItem(
            KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK), 
            getJGoodiesIcon("FloppyDrive.gif"), false));
         menu.addSeparator();
         add(M_EXIT, menu, createMenuItem(true));
      }
      
      menu = new JMenu();
      add(M_STATISTICS, null, menu);
      {
         add(M_CORPUSSTATS, menu, createMenuItem(false));
      }
      
      menu = new JMenu();
      add(M_SETTINGS, null, menu);
      {
         submenu = new JMenu();
         add(M_LANGUAGE, menu, submenu);
         {
            ButtonGroup group = new ButtonGroup();
            rbitem = new JRadioButtonMenuItem();
            rbitem.setSelected(language.equals("english"));
            rbitem.addActionListener(this);
            group.add(rbitem);
            add(M_ENGLISH, submenu, rbitem);
            rbitem = new JRadioButtonMenuItem();
            rbitem.setSelected(language.equals("polish"));
            rbitem.addActionListener(this);
            group.add(rbitem);
            add(M_POLISH, submenu, rbitem);
         }
         add(M_OPTIONS, menu, createMenuItem(true));
         add(M_CONNECT, menu, createMenuItem(true));
      }
      
      getBar().add(Box.createHorizontalGlue());
   
      menu = new JMenu();
      add(M_HELP, null, menu);
      {
         add(M_HELPSEARCH, menu, createMenuItem(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0), null, true));
         menu.addSeparator();
         add(M_ABOUT, menu, createMenuItem(null, 
            PoliqarpIconFactory.loadIcon("info"), true));
      }

      updateMRU();
   }

   /**
    * Updates the 'most recently used corpora' sub-menu.
    */
   public void updateMRU()
   {
      int opt = 0;
      recentMenu.removeAll();
      for (String s : config.getMRU()) {
         JMenuItem item = new JMenuItem(s);
         item.setAccelerator(KeyStroke.getKeyStroke((opt + 1) % 10 + 48, 
            KeyEvent.CTRL_MASK | KeyEvent.ALT_MASK));
         item.addActionListener(this);
         addAllLang(M_MRU + opt, recentMenu, item);
         opt++;
      }
   }
}
