/*******************************************************************************
 * This file is part of GECAMed.
 * 
 * GECAMed is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License (L-GPL) as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * GECAMed 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 (L-GPL)
 * along with GECAMed.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * GECAMed is Copyrighted by the Centre de Recherche Public Henri Tudor (http://www.tudor.lu)
 * (c) CRP Henri Tudor, Luxembourg, 2008
 *******************************************************************************/
package lu.tudor.santec.gecamed.core.gui.widgets;

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.util.Collection;
import java.util.HashMap;

import javax.swing.AbstractAction;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JSeparator;

import lu.tudor.santec.gecamed.backup.gui.BackupAdminSettingsPlugin;
import lu.tudor.santec.gecamed.backup.gui.BackupDialog;
import lu.tudor.santec.gecamed.core.gui.GECAMedIconNames;
import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.gecamed.core.gui.IconFetcher;
import lu.tudor.santec.gecamed.core.gui.LoginScreen;
import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.core.gui.utils.LogFileViewer;
import lu.tudor.santec.gecamed.core.gui.utils.UpdateChecker;
import lu.tudor.santec.gecamed.core.gui.utils.UrlOpener;
import lu.tudor.santec.gecamed.core.gui.utils.script.ScriptTestDialog;
import lu.tudor.santec.gecamed.core.gui.widgets.autocompletion.AutoCompletionExportDialog;
import lu.tudor.santec.gecamed.core.gui.widgets.autocompletion.AutoCompletionImportDialog;
import lu.tudor.santec.gecamed.core.gui.widgets.hotkeys.HotKeyListDialog;
import lu.tudor.santec.gecamed.core.gui.widgets.incidentfileoverview.IncidentFileOverviewDialog;
import lu.tudor.santec.gecamed.core.utils.ManagerFactory;
import lu.tudor.santec.gecamed.esante.gui.IconNames;
import lu.tudor.santec.gecamed.esante.gui.utils.ESanteGuiUtils;
import lu.tudor.santec.gecamed.letter.gui.placeholders.ScriptingManager;
import lu.tudor.santec.gecamed.office.ejb.entity.beans.Physician;
import lu.tudor.santec.gecamed.usermanagement.ejb.entity.beans.GecamedUser;
import lu.tudor.santec.gecamed.usermanagement.ejb.session.beans.LoginBean;
import lu.tudor.santec.gecamed.usermanagement.ejb.session.interfaces.LoginInterface;
import lu.tudor.santec.gecamed.usermanagement.gui.AdminModule;
import lu.tudor.santec.i18n.Translatrix;

import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;

/**
 * The Menubar of GECAMed shown in the Mainframe
 * 
 * @author Johannes Hermen johannes.hermen(at)tudor.lu
 *
 * @Version
 * <br>$Log: MenuBar.java,v $
 * <br>Revision 1.56  2013-07-02 09:22:27  ferring
 * <br>Browsing URL changed
 * <br>
 * <br>Revision 1.55  2012-06-04 06:03:01  ferring
 * <br>file overview added in tools
 * <br>
 * <br>Revision 1.54  2011-09-06 05:36:46  ferring
 * <br>Option for testing that removed
 * <br>
 * <br>Revision 1.53  2011-09-06 05:24:57  ferring
 * <br>import - export order switched (now first export, than import)
 * <br>
 * <br>Revision 1.52  2011-09-02 13:06:32  ferring
 * <br>Auto completion ex- and import added
 * <br>
 * <br>Revision 1.51  2011-07-06 08:29:50  ferring
 * <br>changes for the examen clinique (mainly sub form component added)
 * <br>
 * <br>Revision 1.50  2010-04-26 13:20:41  hermen
 * <br>small improvements
 * <br>
 * <br>Revision 1.49  2010-04-26 12:44:35  hermen
 * <br>small improvements
 * <br>
 * <br>Revision 1.48  2010-04-20 07:24:39  hermen
 * <br>added show server log to tools menu
 * <br>
 * <br>Revision 1.47  2010-03-12 14:17:42  hermen
 * <br>cleanup of panel layouts and icons
 * <br>
 * <br>Revision 1.46  2009-05-08 07:59:27  hermen
 * <br>open help website on firstrun
 * <br>
 * <br>Revision 1.45  2009-03-16 14:17:27  hermen
 * <br>added patient incident statistics
 * <br>
 * <br>Revision 1.44  2009-03-10 15:27:52  hermen
 * <br>added view and stub bean for patient incident statistics
 * <br>
 * <br>Revision 1.43  2009-02-04 10:15:55  hermen
 * <br>added functionality to get all Users that are logged in on a GECAMed Server
 * <br>
 * <br>Revision 1.42  2008-12-05 15:13:08  hermen
 * <br>added menue entry for online manual and fixed printing of addressbook entries
 * <br>
 * <br>Revision 1.41  2008-10-01 07:47:47  hermen
 * <br>fixed: #184: Open addressbook when a template contains CONTACT placeholders
 * <br>
 * <br>Revision 1.40  2008-09-29 13:56:15  hermen
 * <br>improved debugging
 * <br>
 * <br>Revision 1.39  2008-09-25 09:43:06  heinemann
 * <br>fixed copyrights
 * <br>
 * <br>Revision 1.38  2008-09-24 11:54:08  heinemann
 * <br>added first run actions to gecamed. will disable all views except the ones of the admin tab for user, office and physician.
 * <br>Tabs are enabled, if an physican was saved.
 * <br>
 * <br>Revision 1.37  2008-06-03 13:34:16  hermen
 * <br>added tracing and some invokeLater's
 * <br>
 * <br>Revision 1.36  2008-05-28 12:02:48  hermen
 * <br>removed stacktrace on parsing empty settings, added enable/disable backup module
 * <br>
 * <br>Revision 1.35  2008-05-13 10:12:44  hermen
 * <br>updated searchdialog
 * <br>
 * <br>Revision 1.34  2008-05-13 09:51:25  hermen
 * <br>added contact search dialog
 * <br>
 * <br>Revision 1.33  2008-04-16 08:35:51  hermen
 * <br>fixed size of settings dialog
 * <br>
 * <br>Revision 1.32  2008-04-15 09:59:36  hermen
 * <br>added backup options
 * <br>
 * <br>Revision 1.31  2008-03-27 13:41:53  hermen
 * <br>added database backup dialog
 * <br>
 * <br>Revision 1.30  2008-03-26 13:46:26  hermen
 * <br>added backupdb menu entry
 * <br>
 * <br>Revision 1.29  2008-01-15 09:29:38  hermen
 * <br>updated Javadoc and refactured code
 * <br>
 * <br>Revision 1.28  2007-12-06 14:46:44  hermen
 * <br>updated Javadoc and refactured code
 * <br>
 *
 */
public class MenuBar extends JMenuBar
{
    //~ Static fields/initializers =============================================

    private static final long serialVersionUID = 1L;
    
    /**
	 * static logger for this class
	 */
	private static Logger logger = Logger.getLogger(MenuBar.class.getName());

    /**
     * the Menu to place in the Menubar 
     */
    private JMenu menu;
    
    /**
     * reference to the MainFrame
     */
    private MainFrame mainFrame;

	/**
	 * Menu where every Module is placed in. 
	 */
	private JMenu windowMenu;

	private BackupDialog backupDialog;
	
	private AutoCompletionImportDialog autocompletionImportDialog;
	private AutoCompletionExportDialog autocompletionExportDialog;

	private JMenu fileMenu;
	
	private HashMap<String, JMenu> menuHash = new HashMap<String, JMenu>();
	

    //~ Constructors ===========================================================
    /**
     * creates a new Menubar
     *
     * @param mainFrame a reference to the mainFrame of the Program to obtain all child-objects from
     */
    public MenuBar(MainFrame mainFrame)
    {
        this.mainFrame = mainFrame;

        // create all menues
        this.createFileMenu();

        // create the Window Menu
        this.windowMenu = new JMenu(Translatrix.getTranslationString("core.window")); //$NON-NLS-1$
        this.add(windowMenu);
        menuHash.put("core.window", windowMenu);
        
        // menu for tools entries
        this.createToolsMenu();
        
        // menu to access the setting dialogs
        this.createSettingMenu();
        
        // menu to access help and about
        this.createHelpMenu();
    }

    //~ Methods ================================================================
    
    
    
    /**
     * Disables all entries but the file menu
     */
    public void disabledAllButFile() {
    	/* ================================================== */
    	for (JMenu m : menuHash.values()) {
    		/* ------------------------------------------------------- */
    		m.setEnabled(false);
    		/* ------------------------------------------------------- */
    	}
    	menuHash.get("core.file").setEnabled(true);
    	/* ================================================== */
    }
    
    /**
     * Enables/Disables all menu entries
     * 
     * @param b
     */
    public void setAllEnabled(boolean b) {
    	/* ================================================== */
    	for (JMenu m : menuHash.values()) {
    		/* ------------------------------------------------------- */
    		m.setEnabled(b);
    		/* ------------------------------------------------------- */
    	}
    	/* ================================================== */
    }
    
    
    /**
     * create the File Menu
     */
    private void createFileMenu()
    {
        // create the File Menu
        this.fileMenu = new JMenu(Translatrix.getTranslationString("core.file")); 
        /* ------------------------------------------------------- */
        this.menuHash.put("core.file", fileMenu);
        /* ------------------------------------------------------- */
        // Exit action
        JMenuItem exitMenuItem = new JMenuItem(this.mainFrame.createTabAction(
                    Translatrix.getTranslationString("core.exit"), GECAMedModule.getMiniIcon(GECAMedIconNames.EXIT), 
                    MainFrame.CLOSE));
        this.fileMenu .add(exitMenuItem);
        this.add(this.fileMenu );
    }

    /**
     * create the Help Menu
     */
    private void createHelpMenu()
    {
        // create the Help Menu
        menu = new JMenu(Translatrix.getTranslationString("core.help")); 
       
        /* ------------------------------------------------------- */
        menuHash.put("core.help", menu);
        /* ------------------------------------------------------- */
        
        //  show project Website
        JMenuItem websiteMenuItem = new JMenuItem(new AbstractAction(Translatrix.getTranslationString("core.website"), //$NON-NLS-1$
        		GECAMedModule.getMiniIcon(GECAMedIconNames.SERVER)) {
					private static final long serialVersionUID = 1L;
					public void actionPerformed(ActionEvent e)
                    {
						if (!UrlOpener.openURL(MainFrame.HELP_WEBSITE))
							JOptionPane.showMessageDialog(MainFrame.getInstance(),
								MainFrame.HELP_WEBSITE,
								    "Error launching Browser",
								    JOptionPane.WARNING_MESSAGE);
                    }
                });
        menu.add(websiteMenuItem);
        
        //  show online manual
        JMenuItem manualMenuItem = new JMenuItem(new AbstractAction(Translatrix.getTranslationString("core.onlinemanual"), 
        		GECAMedModule.getMiniIcon(GECAMedIconNames.MANUAL)) {
					private static final long serialVersionUID = 1L;
					public void actionPerformed(ActionEvent e)
                    {
						if (!UrlOpener.openURL(MainFrame.HELP_HANDBOOK))
							JOptionPane.showMessageDialog(MainFrame.getInstance(),
								MainFrame.HELP_HANDBOOK,
								    "Error launching Browser",
								    JOptionPane.WARNING_MESSAGE);
                    }
                });
        menu.add(manualMenuItem);
        
        //  show bugtracking
        JMenuItem bugtrackMenuItem = new JMenuItem(new AbstractAction(Translatrix.getTranslationString("core.bugtrack"), //$NON-NLS-1$
        		GECAMedModule.getMiniIcon(GECAMedIconNames.BUG)) {
					private static final long serialVersionUID = 1L;
					public void actionPerformed(ActionEvent e)
                    {
						if (!UrlOpener.openURL( MainFrame.HELP_BUGTRACK + 
								"?reporter="+ErrorDialog.getBugReporter() +
								"&version="+System.getProperty("APP_VERSION")
								))
							JOptionPane.showMessageDialog(MainFrame.getInstance(),
								    MainFrame.HELP_BUGTRACK,
								    "Error launching Browser",
								    JOptionPane.WARNING_MESSAGE);
                    }
                });
        menu.add(bugtrackMenuItem);

        // show HotKeys
        JMenuItem hotkeysMenuItem = new JMenuItem(new AbstractAction(Translatrix.getTranslationString("core.hotkeys"), 
        		GECAMedModule.getMiniIcon(GECAMedIconNames.HOTKEYS)) {
						private static final long serialVersionUID = 1L;

					public void actionPerformed(ActionEvent e)
                    {
						new HotKeyListDialog();
                    }
                });
        menu.add(hotkeysMenuItem);
        
        try {
        	UpdateChecker.setDelaySec(15);
        	UpdateChecker.setUrl("http://gecamed.lu/updatemessage?do=export_html");
        	UpdateChecker.setDevUrl("http://gecamed.lu/updatemessage_dev?do=export_html");
        	
    		String databaseServer = "";
    		try {
    			databaseServer = ((LoginInterface) ManagerFactory.getRemote(LoginBean.class)).getDatabaseServerVersion();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
        	try {
        		UpdateChecker.setClientFile(new File(LoginScreen.USER_FOLDER.getAbsolutePath(), "servermessage.txt"));
        		UpdateChecker.setVersion(System.getProperty("APP_VERSION") + "_" + databaseServer);
        		UpdateChecker.setInfo(new String(Base64.encodeBase64URLSafeString(MainFrame.getCurrentUser().getLogin().getBytes())));
        		String office = new String(
        				Base64.encodeBase64URLSafeString(MainFrame.getCurrentOffice().getName().getBytes())) +
        				(MainFrame.getCurrentSite() != null ? "_" + Base64.encodeBase64URLSafeString(MainFrame.getCurrentSite().getName().getBytes()) :"");
        		UpdateChecker.setInfo2(office);				
			} catch (Exception e) {
				logger.info("Error creating Updatecheck info " + e.getMessage());
			}
        	// check once at program start
        	UpdateChecker udc = new UpdateChecker(mainFrame);
        	udc.checkUpdate(true, false, UpdateChecker.ACTION_CHECK_AUTO);
        	
        	JMenuItem updateMenuItem = new JMenuItem(new AbstractAction(Translatrix.getTranslationString("core.checkupdate"), 
        			GECAMedModule.getMiniIcon(GECAMedIconNames.SERVER)) {
        		private static final long serialVersionUID = 1L;
        		public void actionPerformed(ActionEvent e)
        		{
        			UpdateChecker udc = new UpdateChecker(mainFrame);
        			udc.checkUpdate(true, true, UpdateChecker.ACTION_CHECK_MANUAL);
        		}
        	});
        	
        	menu.add(updateMenuItem);
			
		} catch (Throwable e) {
			logger.info("Error creating Updatecheck info " + e.getMessage());
		}
        
        // show About eSante Website
        JMenuItem abouteSanteMenuItem = new JMenuItem(new AbstractAction(Translatrix.getTranslationString("core.aboutDSP"), 
        		ESanteGuiUtils.getIcon(IconNames.ESANTE_LOGO_SQUARE, IconFetcher.SMALLPIX)) {
						private static final long serialVersionUID = 1L;

					public void actionPerformed(ActionEvent e)
                    {
						if (!UrlOpener.openURL(MainFrame.ABOUT_ESANTE))
							JOptionPane.showMessageDialog(MainFrame.getInstance(),
								MainFrame.ABOUT_ESANTE,
								    "Error launching Browser",
								    JOptionPane.WARNING_MESSAGE);
                    }
                });
        menu.add(abouteSanteMenuItem);
        
        // show About Tab
        JMenuItem aboutMenuItem = new JMenuItem(new AbstractAction(Translatrix.getTranslationString("core.about"), 
        		GECAMedModule.getMiniIcon(GECAMedIconNames.INFO)) {
						private static final long serialVersionUID = 1L;

					public void actionPerformed(ActionEvent e)
                    {
                        new AboutDialog(mainFrame);
                    }
                });
        menu.add(aboutMenuItem);

        this.add(menu);
    }
    
    /**
     * create the Tools Menu
     */
    private void createToolsMenu()
    {
    	JMenuItem menuItem;
    	
        // create the Help Menu
        menu = new JMenu(Translatrix.getTranslationString("core.tools")); //$NON-NLS-1$
        /* ------------------------------------------------------- */
        menuHash.put("core.tools", menu);
        /* ------------------------------------------------------- */
        // show MessageDialog
        menuItem = new JMenuItem(new AbstractAction(
                    Translatrix.getTranslationString("core.sendMessage"), 
                    GECAMedModule.getMiniIcon(GECAMedIconNames.MESSAGE)) {

					private static final long serialVersionUID = 1L;

					public void actionPerformed(ActionEvent e)
                    {
                       MessageSendDialog.showDialog();
                    }
                });
        menu.add(menuItem);
        
        // show the incident file overview
        menuItem = new JMenuItem(new AbstractAction(
        		Translatrix.getTranslationString("core.incidentFileOverview"), 
                GECAMedModule.getMiniIcon(GECAMedIconNames.FILE))
		{
			private static final long	serialVersionUID	= 1L;

			public void actionPerformed(ActionEvent e)
			{
				IncidentFileOverviewDialog.showDialog();
			}
		});
        menu.add(menuItem);

        // show client logfile
        menuItem = new JMenuItem(new AbstractAction(
                    Translatrix.getTranslationString("core.showLogfile"),
                    GECAMedModule.getMiniIcon(GECAMedIconNames.EXPORT)) {

					private static final long serialVersionUID = 1L;

					public void actionPerformed(ActionEvent e)
                    {
						LogFileViewer.showLogFile(mainFrame, "client-log");
                    }
                });
        menu.add(menuItem);
        
        // show client logfile
        menuItem = new JMenuItem(new AbstractAction(
                    Translatrix.getTranslationString("core.showServerLogfile"),
                    GECAMedModule.getMiniIcon(GECAMedIconNames.EXPORT)) {

					private static final long serialVersionUID = 1L;

					public void actionPerformed(ActionEvent e)
                    {
					    try {
						String serverLog = ((LoginInterface) ManagerFactory.getRemote(LoginBean.class)).getServerLog();
						LogFileViewer.showLogFile(mainFrame, "server-log", serverLog, true);						
					    } catch (Exception e2) {
						e2.printStackTrace();
					    }
                    }
                });
        menu.add(menuItem);
        
        //      show dbbackup page
        BackupAdminSettingsPlugin backupSettings = new BackupAdminSettingsPlugin();
        MainFrame.getInstance().adminSettingsPanel.addPlugin(backupSettings);
        if ((Boolean)backupSettings.getValue(BackupAdminSettingsPlugin.BACKUP_ENABLED)) {
            backupDialog = new BackupDialog(mainFrame, backupSettings);
            menuItem = new JMenuItem(new AbstractAction(
                    Translatrix.getTranslationString("core.dbBackup"),
                    GECAMedModule.getMiniIcon(GECAMedIconNames.BACKUP_DB)) {

				private static final long serialVersionUID = 1L;
		
				public void actionPerformed(ActionEvent e)
		                    {
					try {
					    backupDialog.showDialog();
					} catch (Exception e1) {
					    e1.printStackTrace();
					}
		                    }
            });
            menu.add(menuItem);
        }
        
        menuItem = new JMenuItem(new AbstractAction(
        		"show online users", 
        		AdminModule.getSmallIcon(AdminModule.ICON_USERMANAGEMENT)) {
	
			private static final long serialVersionUID = 1L;
	
			public void actionPerformed(ActionEvent e)
			{
				Collection<GecamedUser> users = MainFrame.getOnlineUsers(null);
				StringBuffer sb = new StringBuffer("Online Users:\n");
				for (GecamedUser gecamedUser : users) {
					sb.append("  ").append(gecamedUser.toString()).append("\n");
				}
				Collection<Physician> physicians = MainFrame.getOnlinePhysicians(null);
				sb.append("\nOnline Physicians:\n");
				for (Physician phy : physicians) {
					sb.append("  ").append(phy.toString()).append("\n");
				}    
				JOptionPane.showMessageDialog(MainFrame.getInstance(), sb.toString());   
			}
		});
		menu.add(menuItem);
		
		if (ScriptingManager.showScriptTestButton())
		{
			// enable the script test function
			menuItem = new JMenuItem(new AbstractAction("Test JavaScript", 
					GECAMedModule.getSmallIcon(GECAMedIconNames.SCRIPT))
			{
				private static final long	serialVersionUID	= 1L;
				
				public void actionPerformed (ActionEvent e)
				{
					ScriptTestDialog.showDialog();
				}
			});
	        menu.add(menuItem);
		}
		
		menu.addSeparator();
		
		/* ---------------------------------------- */
		// 	IMPORT / EXPORT AUTOCOMPLETIONS
		/* ---------------------------------------- */
		
		menuItem = new JMenuItem(new AbstractAction(
				Translatrix.getTranslationString("MultiWordAutoCompletion.IO.exportAutocompletions"),
				GECAMedModule.getSmallIcon(GECAMedIconNames.EXPORT))
		{
			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e)
			{
				if (autocompletionExportDialog == null)
					autocompletionExportDialog = new AutoCompletionExportDialog();
				autocompletionExportDialog.setVisible(true);
			}
		});
		menu.add(menuItem);
		
		menuItem = new JMenuItem(new AbstractAction(
				Translatrix.getTranslationString("MultiWordAutoCompletion.IO.importAutocompletions"),
				GECAMedModule.getSmallIcon(GECAMedIconNames.IMPORT))
		{
			private static final long serialVersionUID = 1L;

			public void actionPerformed(ActionEvent e)
			{
				if (autocompletionImportDialog == null)
					autocompletionImportDialog = new AutoCompletionImportDialog();
				autocompletionImportDialog.setVisible(true);
			}
		});
		menu.add(menuItem);
		
		this.add(menu);
    }


	/**
     * create the Setting Menu
     */
    private void createSettingMenu()
    {
        // create the Setting Menu
        menu = new JMenu(Translatrix.getTranslationString("core.settings")); 
        /* ------------------------------------------------------- */
        menuHash.put("core.settings", menu);
        /* ------------------------------------------------------- */
        // show Setting Dialog
        JMenuItem settingMenuItem = new JMenuItem(new AbstractAction(
                    Translatrix.getTranslationString("core.settings"), 
                    GECAMedModule.getMiniIcon(GECAMedIconNames.SETTINGS)) {
			private static final long serialVersionUID = 1L;
			public void actionPerformed(ActionEvent e)
				{
        				    mainFrame.settingsPanel.setSize(700, 550);
        				    mainFrame.settingsPanel.setLocationRelativeTo(MainFrame.getInstance());
        				    mainFrame.settingsPanel.setVisible(true);
				}
                });
        menu.add(settingMenuItem);  
        
        this.add(menu);
    }

    
    public void addWindowEntry(JMenuItem item) {
    	windowMenu.add(item);
    }
    
    /**
     * @param seppl
     */
    public void addWindowEntry(JSeparator seppl) {
    	/* ================================================== */
    	windowMenu.add(seppl);
    	/* ================================================== */
    }
    
    /**
     * Add a menu entry per module
     * 
     * @param menu
     */
    public void addModuleMenu(JMenu menu) {
    	/* ================================================== */
    	int anz = this.getMenuCount();
    	this.add(menu, anz-3);
    	this.menuHash.put(menu.getText(), menu);
    	/* ================================================== */
    }
    

}
