content: /*
   * Copyright 2010 Aalto University, ComNet
   * Released under GPLv3. See LICENSE.txt for details.
   */
  package gui;
  
  import gui.nodefilter.NodeMessageFilter;
  import gui.playfield.PlayField;
  import gui.playfield.NodeGraphic;
  
  import java.awt.Container;
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
  import java.awt.image.BufferedImage;
  import java.io.File;
  import java.io.IOException;
  
  import javax.imageio.ImageIO;
  import javax.swing.Box;
  import javax.swing.JCheckBoxMenuItem;
  import javax.swing.JMenu;
  import javax.swing.JMenuBar;
  import javax.swing.JMenuItem;
  import javax.swing.JOptionPane;
  
  import core.Settings;
  import core.SettingsError;
  
  /**
   * Menu bar of the simulator GUI
   *
   */
  @SuppressWarnings("serial")
  public class SimMenuBar extends JMenuBar implements ActionListener {
  	/** title of the about window */
  	public static final String ABOUT_TITLE = "about ONE";
  	/** GPLv3 license text for about window */
  	public static final String ABOUT_TEXT =
  	"Copyright (C) 2007-2011 Aalto University, Comnet\n\n"+
  	"This program is free software: you can redistribute it and/or modify\n"+
      "it under the terms of the GNU General Public License as published by\n"+
      "the Free Software Foundation, either version 3 of the License, or\n"+
      "(at your option) any later version.\n\n"+
      "This program is distributed in the hope that it will be useful,\n"+
      "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"+
      "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"+
      "GNU General Public License for more details.\n\n" +
      "You should have received a copy of the GNU General Public License\n"+
      "along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\n"+
      "Map data copyright: Maanmittauslaitos, 2007";
  
  	private JCheckBoxMenuItem enableBgImage;
  	private JCheckBoxMenuItem showNodeName;
  	private JCheckBoxMenuItem showNodeCoverage;
  	private JCheckBoxMenuItem showNodeConnections;
  	private JCheckBoxMenuItem showBuffer;
  
  	private JCheckBoxMenuItem enableMapGraphic;
  	private JCheckBoxMenuItem autoClearOverlay;
  	private JCheckBoxMenuItem focusOnClick;
  
  	private JMenuItem clearOverlay;
  	private JMenuItem addNodeMessageFilter;
  	private JMenuItem clearNodeFilters;
  
  	private JMenuItem about;
  	private PlayField field;
  	private NodeChooser chooser;
  
  	/** Show node name string -setting id ({@value})*/
  	public static final String SHOW_NODE_NAMESTR_S = "showNodeNameStrings";
  	/** Show node radio coverage -setting id ({@value})*/
  	public static final String SHOW_RADIO_COVERAGES_S = "showNodeRadioCoverages";
  	/** Show node connections -setting id ({@value})*/
  	public static final String SHOW_CONNECTIONS_S = "showNodeConnections";
  	/** Show nodes' messages -setting id ({@value})*/
  	public static final String SHOW_BUFFER_S = "showMessageBuffer";
  	/** Show node connections -setting id ({@value})*/
  	public static final String FOCUS_ON_CLICK_S = "focusOnClick";
  	/** The namespace where underlay image -related settings are found */
  	public static final String UNDERLAY_NS = "GUI.UnderlayImage";
  
  	public SimMenuBar(PlayField field, NodeChooser nodeChooser) {
  		this.field = field;
  		this.chooser = nodeChooser;
  		init();
  	}
  
  	private void init() {
  		JMenu pfMenu = new JMenu("Playfield options");
  		JMenu pfToolsMenu = new JMenu("Tools");
  		JMenu help = new JMenu("Help");
  		JMenu nodeFilters = new JMenu("Add node filter");
  		Settings settings = new Settings(UNDERLAY_NS);
  
  		if (settings.contains("fileName")) {
  			// create underlay image menu item only if filename is specified
  			enableBgImage = createCheckItem(pfMenu,"Show underlay image",
  					false, null);
  		}
  
  		settings.setNameSpace(gui.MainWindow.GUI_NS);
  
  		showNodeName = createCheckItem(pfMenu, "Show node name strings",
  				true, SHOW_NODE_NAMESTR_S);
  		showNodeCoverage = createCheckItem(pfMenu,
  				"Show node radio coverages", true, SHOW_RADIO_COVERAGES_S);
  		showNodeConnections = createCheckItem(pfMenu,
  				"Show node connections", true, SHOW_CONNECTIONS_S);
  		showBuffer = createCheckItem(pfMenu,
  				"Show message buffer", true, SHOW_BUFFER_S);
  		focusOnClick = createCheckItem(pfMenu,
  				"Focus to closest node on mouse click", false,FOCUS_ON_CLICK_S);
  
  		enableMapGraphic = createCheckItem(pfMenu,"Show map graphic",
  				true, null);
  		autoClearOverlay = createCheckItem(pfMenu, "Autoclear overlay",
  				true, null);
  		clearOverlay = createMenuItem(pfToolsMenu, "Clear overlays");
  
  
  		pfToolsMenu.addSeparator();
  		addNodeMessageFilter = createMenuItem(nodeFilters, "message filter");
  		pfToolsMenu.add(nodeFilters);
  		clearNodeFilters = createMenuItem(pfToolsMenu, "Clear node filters");
  
  		updatePlayfieldSettings();
  
  		about = createMenuItem(help,"about");
  		this.add(pfMenu);
  		this.add(pfToolsMenu);
  		this.add(Box.createHorizontalGlue());
  		this.add(help);
  	}
  
  	private JMenuItem createMenuItem(Container c, String txt) {
  		JMenuItem i = new JMenuItem(txt);
  		i.addActionListener(this);
  		c.add(i);
  		return i;
  	}
  
  	/**
  	 * Creates a new check box menu item to the given container
  	 * @param c The container
  	 * @param txt Text for the menu item
  	 * @param selected Is the check box selected (by default)
  	 * @param setting Name of the setting where the check-box-selected
  	 * true/false value is read from (if not found, the "selected" parameter
  	 * value is used). If null, no setting is read and the default is
  	 * used as such.
  	 * @return The created check box menu item
  	 */
  	private JCheckBoxMenuItem createCheckItem(Container c,String txt,
  			boolean selected, String setting) {
  		Settings s = new Settings(gui.MainWindow.GUI_NS);
  
  		JCheckBoxMenuItem i = new JCheckBoxMenuItem(txt);
  		if (setting == null) {
  			i.setSelected(selected);
  		} else {
  			i.setSelected(s.getBoolean(setting, selected));
  		}
  
  		i.addActionListener(this);
  		c.add(i);
  
  		return i;
  	}
  
  
  	private void updatePlayfieldSettings() {
  		NodeGraphic.setDrawNodeName(showNodeName.isSelected());
  		NodeGraphic.setDrawCoverage(showNodeCoverage.isSelected());
  		NodeGraphic.setDrawConnections(showNodeConnections.isSelected());
  		NodeGraphic.setDrawBuffer(showBuffer.isSelected());
  		field.setShowMapGraphic(enableMapGraphic.isSelected());
  		field.setAutoClearOverlay(autoClearOverlay.isSelected());
  		field.setFocusOnClick(focusOnClick.isSelected());
  	}
  
  	private String getFilterString(String message) {
  		return (String)JOptionPane.showInputDialog(
                  this, message, "Filter input", JOptionPane.PLAIN_MESSAGE);
  	}
  
  	public void actionPerformed(ActionEvent e) {
  		Object source = e.getSource();
  		if (source == enableBgImage) {
  			toggleUnderlayImage();
  		}
  		else if (source == this.showNodeName ||
  				source == this.showNodeCoverage ||
  				source == this.showNodeConnections ||
  				source == this.enableMapGraphic ||
  				source == this.autoClearOverlay ||
  				source == this.showBuffer ||
  				source == this.focusOnClick) {
  			updatePlayfieldSettings();
  		}
  
  		else if (source == this.clearOverlay) {
  			field.clearOverlays();
  		}
  		else if (source == addNodeMessageFilter) {
  			chooser.addFilter(
  					new NodeMessageFilter(getFilterString("Message ID")));
  		}
  		else if (source == clearNodeFilters) {
  			chooser.clearFilters();
  		}
  		else if (source == this.about) {
  			JOptionPane.showMessageDialog(this, ABOUT_TEXT, ABOUT_TITLE,
  					JOptionPane.INFORMATION_MESSAGE);
  		}
  	}
  
  	/**
  	 * Toggles the showing of underlay image. Image is read from the file only
  	 * when it is enabled to save some memory.
  	 */
  	private void toggleUnderlayImage() {
  		if (enableBgImage.isSelected()) {
  			String imgFile = null;
  			int[] offsets;
  			double scale, rotate;
  			BufferedImage image;
  			try {
  				Settings settings = new Settings(UNDERLAY_NS);
  				imgFile = settings.getSetting("fileName");
  				offsets = settings.getCsvInts("offset", 2);
  				scale = settings.getDouble("scale");
  				rotate = settings.getDouble("rotate");
  	            image = ImageIO.read(new File(imgFile));
  	        } catch (IOException ex) {
  		warn("Couldn't set underlay image " + imgFile + ". " +
  				ex.getMessage());
  		enableBgImage.setSelected(false);
  		return;
  	        }
  	        catch (SettingsError er) {
  		warn("Problem with the underlay image settings: " +
  				er.getMessage());
  		return;
  	        }
  			field.setUnderlayImage(image, offsets[0], offsets[1],
  					scale, rotate);
  		}
  		else {
  			// disable the image
  			field.setUnderlayImage(null, 0, 0, 0, 0);
  		}
  	}
  
  	private void warn(String txt) {
  		JOptionPane.showMessageDialog(null, txt, "warning",
  				JOptionPane.WARNING_MESSAGE);
  	}
  
  }
  