package sim;

import sim.credit.AboutWindow;
import sim.util.WaitDialog;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;

public class SimMenuBar extends MenuBar {

	//File Menu
	public static MenuItem NEW = new MenuItem("New");
	public static MenuItem OPEN = new MenuItem("Open...");
	public static MenuItem SAVE = new MenuItem("Save");
	public static MenuItem SAVE_AS = new MenuItem("Save As...");
	private static MenuItem EXIT = new MenuItem("Exit");
	//Edit Menu
	public static MenuItem DELETE = new MenuItem("Delete");
	public static MenuItem ROTATE_LEFT = new MenuItem("Rotate Left");
	public static MenuItem ROTATE_RIGHT = new MenuItem("Rotate Right");
	public static Menu ANGLES;
	public static MenuItem FLIP_HORIZONTAL = new MenuItem("Flip Horizontal");
	public static MenuItem FLIP_VERTICAL = new MenuItem("Flip Vertical");
	public static MenuItem PROPERTY = new MenuItem("Properties");
	//Grid Menu
	public static CheckboxMenuItem VIEW_GRID = new CheckboxMenuItem("Show grid", true);
	private static Menu ZOOM = new Menu("Zoom...");
	public static MenuItem ATTRIBUTE = new MenuItem("Attributes");
	//Run Menu
	public static MenuItem RUN = new MenuItem("Run");
	public static MenuItem PAUSE = new MenuItem("Pause");
	public static MenuItem STOP = new MenuItem("Stop");
	public static MenuItem STEP = new MenuItem("Step");
	public static MenuItem TIME_STEP = new MenuItem("Time Step");
	public static MenuItem SIM_PROPERTY = new MenuItem("Simulation Properties");
	//Control Center
	public static MenuItem CONTROL_CENTER = new MenuItem("Control Center (BETA)");
	//VHDL
	public static MenuItem VHDL = new MenuItem("Export to VHDL (BETA)");	
	//Help Menu
	private static MenuItem ABOUT = new MenuItem("About...");

	public SimMenuBar() {
		super();

		// File Menu

		Menu temp = new Menu("File");
		ActionListener al = new FileMenuListener();

		if (MainWindow.MASTER != null) {
			SimMenuBar.SAVE.setEnabled(false);
			SimMenuBar.SAVE_AS.setEnabled(false);
		}

		SimMenuBar.NEW.addActionListener(al);
		SimMenuBar.OPEN.addActionListener(al);
		SimMenuBar.SAVE.addActionListener(al);
		SimMenuBar.SAVE_AS.addActionListener(al);
		SimMenuBar.EXIT.addActionListener(al);

		temp.add(SimMenuBar.NEW);
		temp.add(SimMenuBar.OPEN);
		temp.add(SimMenuBar.SAVE);
		temp.add(SimMenuBar.SAVE_AS);
		temp.addSeparator();
		temp.add(SimMenuBar.EXIT);

		this.add(temp);


		// Edit Menu

		temp = new Menu("Edit");

		al = new AnglesMenuListener();
		MenuItem mi;

		SimMenuBar.ANGLES = new Menu("Rotate to...");

		mi = new MenuItem("0");
		mi.addActionListener(al);
		SimMenuBar.ANGLES.add(mi);

		mi = new MenuItem("90");
		mi.addActionListener(al);
		SimMenuBar.ANGLES.add(mi);

		mi = new MenuItem("180");
		mi.addActionListener(al);
		SimMenuBar.ANGLES.add(mi);

		mi = new MenuItem("270");
		mi.addActionListener(al);
		SimMenuBar.ANGLES.add(mi);

		al = new EditMenuListener();

		SimMenuBar.DELETE.addActionListener(al);
		SimMenuBar.ROTATE_LEFT.addActionListener(al);
		SimMenuBar.ROTATE_RIGHT.addActionListener(al);
		SimMenuBar.FLIP_HORIZONTAL.addActionListener(al);
		SimMenuBar.FLIP_VERTICAL.addActionListener(al);
		SimMenuBar.PROPERTY.addActionListener(al);

		SimMenuBar.DELETE.setEnabled(false);
		SimMenuBar.ANGLES.setEnabled(false);
		SimMenuBar.ROTATE_LEFT.setEnabled(false);
		SimMenuBar.ROTATE_RIGHT.setEnabled(false);
		SimMenuBar.FLIP_HORIZONTAL.setEnabled(false);
		SimMenuBar.FLIP_VERTICAL.setEnabled(false);
		SimMenuBar.PROPERTY.setEnabled(false);

		temp.add(SimMenuBar.DELETE);
		temp.addSeparator();
		temp.add(SimMenuBar.ROTATE_RIGHT);
		temp.add(SimMenuBar.ROTATE_LEFT);
		temp.add(SimMenuBar.ANGLES);
		temp.addSeparator();
		temp.add(SimMenuBar.FLIP_VERTICAL);
		temp.add(SimMenuBar.FLIP_HORIZONTAL);
		temp.addSeparator();
		temp.add(SimMenuBar.PROPERTY);

		this.add(temp);


		// Grid Menu

		temp = new Menu("Grid");
		al = new GridMenuListener();

		SimMenuBar.VIEW_GRID.addItemListener((ItemListener) al);
		SimMenuBar.ATTRIBUTE.addActionListener(al);

		MenuItem sub = new MenuItem("50%");
		sub.addActionListener(al);
		SimMenuBar.ZOOM.add(sub);
		sub = new MenuItem("75%");
		sub.addActionListener(al);
		SimMenuBar.ZOOM.add(sub);
		sub = new MenuItem("100%");
		sub.addActionListener(al);
		SimMenuBar.ZOOM.add(sub);
		sub = new MenuItem("150%");
		sub.addActionListener(al);
		SimMenuBar.ZOOM.add(sub);
		sub = new MenuItem("200%");
		sub.addActionListener(al);
		SimMenuBar.ZOOM.add(sub);

		temp.add(SimMenuBar.VIEW_GRID);
		temp.add(SimMenuBar.ZOOM);
		temp.addSeparator();
		temp.add(SimMenuBar.ATTRIBUTE);

		this.add(temp);


		// Run Menu

		temp = new Menu("Run");
		al = new RunMenuListener();

		SimMenuBar.STOP.setEnabled(false);
		SimMenuBar.PAUSE.setEnabled(false);

		SimMenuBar.RUN.addActionListener(al);
		SimMenuBar.PAUSE.addActionListener(al);
		SimMenuBar.STOP.addActionListener(al);
		SimMenuBar.STEP.addActionListener(al);
		SimMenuBar.TIME_STEP.addActionListener(al);
		SimMenuBar.SIM_PROPERTY.addActionListener(al);

		temp.add(SimMenuBar.RUN);
		temp.add(SimMenuBar.PAUSE);
		temp.add(SimMenuBar.STOP);
		temp.add(SimMenuBar.STEP);
		temp.add(SimMenuBar.TIME_STEP);
		temp.addSeparator();
		temp.add(SimMenuBar.SIM_PROPERTY);

		this.add(temp);

		// Control Center Menu
		temp = new Menu("Control Center");
		al = new ControlMenuListener();

		SimMenuBar.CONTROL_CENTER.addActionListener(al);

		temp.add(SimMenuBar.CONTROL_CENTER);

		this.add(temp);

		//VHDL
		temp = new Menu("VHDL");
		al = new VHDLMenuListener();
		
		SimMenuBar.VHDL.addActionListener(al);
		
		temp.add(SimMenuBar.VHDL);
		this.add(temp);
		
		// Help menu

		temp = new Menu("Help");
		al = new HelpMenuListener();

		SimMenuBar.ABOUT.addActionListener(al);
		temp.add(SimMenuBar.ABOUT);
		this.add(temp);
	}

	private class FileMenuListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			MenuItem source = (MenuItem) e.getSource();

			if (source == SimMenuBar.NEW) {
				NorthPanel.STORE_SHORTCUT.createNew();
			} else if (source == SimMenuBar.OPEN) {
				NorthPanel.STORE_SHORTCUT.load();
			} else if (source == SimMenuBar.SAVE) {
				NorthPanel.STORE_SHORTCUT.save();
			} else if (source == SimMenuBar.SAVE_AS) {
				NorthPanel.STORE_SHORTCUT.saveAs();
			} else if (source == SimMenuBar.EXIT) {
				MainWindow.MAIN_WINDOW.exit();
			}
		}
	}

	private class EditMenuListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			MenuItem source = (MenuItem) e.getSource();

			if (source == SimMenuBar.DELETE) {
				NorthPanel.EDIT_SHORTCUT.deleteSelected();
			} else if (source == SimMenuBar.ROTATE_LEFT) {
				NorthPanel.EDIT_SHORTCUT.rotateLeft();
			} else if (source == SimMenuBar.ROTATE_RIGHT) {
				NorthPanel.EDIT_SHORTCUT.rotateRight();
			} else if (source == SimMenuBar.FLIP_HORIZONTAL) {
				NorthPanel.EDIT_SHORTCUT.flipHorizontal();
			} else if (source == SimMenuBar.FLIP_VERTICAL) {
				NorthPanel.EDIT_SHORTCUT.flipVertical();
			} else if (source == SimMenuBar.PROPERTY) {
				NorthPanel.EDIT_SHORTCUT.showProperties();
			}
		}
	}

	private class AnglesMenuListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			MenuItem source = (MenuItem) e.getSource();

			if (source.getLabel().equals("0")) {
				NorthPanel.EDIT_SHORTCUT.rotateTo(0);
			} else if (source.getLabel().equals("90")) {
				NorthPanel.EDIT_SHORTCUT.rotateTo(90);
			} else if (source.getLabel().equals("180")) {
				NorthPanel.EDIT_SHORTCUT.rotateTo(180);
			} else if (source.getLabel().equals("270")) {
				NorthPanel.EDIT_SHORTCUT.rotateTo(270);
			}
		}
	}

	private class RunMenuListener implements ActionListener {

		private SimulationProperties simDialog = new SimulationProperties();

		public void actionPerformed(ActionEvent e) {
			MenuItem source = (MenuItem) e.getSource();

			if (source == SimMenuBar.RUN) {
				NorthPanel.RUN_SHORTCUT.play();
			} else if (source == SimMenuBar.PAUSE) {
				NorthPanel.RUN_SHORTCUT.pause();
			} else if (source == SimMenuBar.STOP) {
				NorthPanel.RUN_SHORTCUT.stop();
			} else if (source == SimMenuBar.STEP) {
				NorthPanel.RUN_SHORTCUT.singleStep();
			} else if (source == SimMenuBar.TIME_STEP) {
				NorthPanel.RUN_SHORTCUT.timeStep();
			} else if (source == SimMenuBar.SIM_PROPERTY) {
				if (MainWindow.MENU.PAUSE.isEnabled()) {
					NorthPanel.RUN_SHORTCUT.pause();
				}

				this.simDialog.setVisible(true);
			}
		}
	}

	private class GridMenuListener implements ActionListener, ItemListener {

		private GridAttributes gridDialog = new GridAttributes();

		public void actionPerformed(ActionEvent e) {
			MenuItem source = (MenuItem) e.getSource();

			if (source == SimMenuBar.ATTRIBUTE) {
				this.gridDialog.setVisible(true);
			} else {
				NorthPanel.GRID_SHORTCUT.setZoom(source.getLabel());
			}
		}

		public void itemStateChanged(ItemEvent e) {
			NorthPanel.GRID_SHORTCUT.setGridVisibility(SimMenuBar.VIEW_GRID.getState());
		}
	}

	private class ControlMenuListener implements ActionListener {

		private ControlCenter control;

		public void actionPerformed(ActionEvent e) {
			MenuItem source = (MenuItem) e.getSource();

			if (source == SimMenuBar.CONTROL_CENTER) {
				control = new ControlCenter();
				control.setVisible(true);
			}
		}
	}
	
	private class VHDLMenuListener implements ActionListener {
		private VHDLExporter exporter;
		
		public void actionPerformed(ActionEvent e) {
			MenuItem source = (MenuItem) e.getSource();
			
			if (source == SimMenuBar.VHDL) {
				exporter = new VHDLExporter();
				try {
					exporter.Export();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		}
	}

	private class HelpMenuListener implements ActionListener {

		//private AboutWindow aboutDialog = new AboutWindow();
		private AboutWindow aboutDialog = new AboutWindow();

		public void actionPerformed(ActionEvent e) {
			this.aboutDialog.setVisible(true);
		}
	}
}
