package sim;

import java.awt.*;
import java.awt.event.*;

import sim.util.DialogButton;
import sim.util.SimSeparator;
import sim.util.ImagePanel;

public class GridAttributes extends Dialog implements ActionListener {

	private SizeProperties properties;
	private ImagePanel iconHolder;
	private static Image ICON;

	public GridAttributes() {
		super(MainWindow.MAIN_WINDOW, "Properties");

		if (GridAttributes.ICON == null) {
			GridAttributes.ICON = GuiFileLink.getImage("sim/images/Grid.gif");
		}

		this.setLayout(new GridBagLayout());
		this.setModal(true);
		this.setResizable(false);

		Panel p = new Panel(new FlowLayout(FlowLayout.RIGHT, 10, 10));

		DialogButton b = new DialogButton("OK");
		b.addActionListener(this);
		p.add(b);
		b = new DialogButton("Cancel");
		b.addActionListener(this);
		p.add(b);

		GridBagConstraints c = new GridBagConstraints();
		c.gridx = 0;
		c.gridy = 2;
		c.gridwidth = 1;
		c.gridheight = 1;
		c.anchor = GridBagConstraints.EAST;
		c.fill = GridBagConstraints.NONE;

		this.add(p, c);

		this.properties = new SizeProperties();

		c.gridy = 1;
		c.insets = new Insets(10, 20, 40, 20);
		c.anchor = GridBagConstraints.CENTER;
		this.add(this.properties, c);

		p = new Panel(new FlowLayout(FlowLayout.LEFT, 10, 0));
		this.iconHolder = new ImagePanel(GridAttributes.ICON);
		p.add(this.iconHolder);
		p.add(new Label("Grid Properties", Label.LEFT));

		c.anchor = GridBagConstraints.WEST;
		c.insets = new Insets(0, 0, 0, 0);
		c.gridy = 0;

		this.add(p, c);

		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				setVisible(false);
			}
		});
	}

	public void setVisible(boolean visible) {
		if (visible) {
			this.properties.initialise();
		}

		super.setVisible(visible);
	}

	public void addNotify() {
		super.addNotify();

		int width = 40 + this.properties.getSize().width + this.getInsets().left + this.getInsets().right;
		int height = 70 + this.iconHolder.getPreferredSize().height + this.properties.getSize().height + DialogButton.HEIGHT + this.getInsets().top + this.getInsets().bottom;
		this.setSize(width, height);
		doLayout();

		this.setLocation(MainWindow.getMiddleOfScreen(this));
	}

	public void actionPerformed(ActionEvent e) {
		this.setVisible(false);

		if (((DialogButton) e.getSource()).getLabel().equals("OK")) {
			this.properties.ok();
		}
	}

	public void paint(Graphics g) {
		super.paint(g);

		Rectangle r = this.properties.getBounds();

		r.x = r.x - 10;
		r.y = r.y - 5;

		r.width = r.width + 20;
		r.height = r.height + 40;

		g.setColor(Color.white);
		g.drawLine(r.x, r.y, r.x + r.width - 2, r.y);
		g.drawLine(r.x, r.y, r.x, r.y + r.height - 2);

		g.setColor(Color.black);
		g.drawLine(r.x + r.width - 1, r.y, r.x + r.width - 1, r.y + r.height - 1);
		g.drawLine(r.x, r.y + r.height - 1, r.x + r.width - 1, r.y + r.height - 1);

		g.setColor(this.getBackground().darker());
		g.drawLine(r.x + r.width - 2, r.y + 1, r.x + r.width - 2, r.y + r.height - 2);
		g.drawLine(r.x + 1, r.y + r.height - 2, r.x + r.width - 2, r.y + r.height - 2);
	}

	private class SizeProperties extends Container implements ActionListener, FocusListener {

		private TextField editWidth = new TextField(10);
		private TextField editHeight = new TextField(10);
		private Label size = new Label("Size");
		private int oldWidth;
		private int oldHeight;

		public SizeProperties() {
			super();
			this.setLayout(new BorderLayout(0, 15));

			this.editWidth.addActionListener(this);
			this.editWidth.addFocusListener(this);

			this.editHeight.addActionListener(this);
			this.editHeight.addFocusListener(this);

			// configuration
			Panel big = new Panel(new BorderLayout(0, 15));
			Panel p = new Panel(new BorderLayout());
			p.add(this.size, BorderLayout.WEST);
			p.add(new SimSeparator(), BorderLayout.CENTER);
			big.add(p, BorderLayout.NORTH);

			Panel p2 = new Panel(new GridBagLayout());
			GridBagConstraints c = new GridBagConstraints();

			c.weightx = 1;
			c.weighty = 0;
			c.gridwidth = 1;
			c.gridheight = 1;
			c.gridy = 0;
			c.fill = GridBagConstraints.NONE;

			c.gridx = 0;
			c.anchor = GridBagConstraints.WEST;

			p = new Panel(new FlowLayout(FlowLayout.LEFT, 0, 0));
			p.add(new Label("Width"));
			p.add(this.editWidth);

			p2.add(p, c);

			c.gridx = 1;
			c.anchor = GridBagConstraints.EAST;

			p = new Panel(new FlowLayout(FlowLayout.LEFT, 0, 0));
			p.add(new Label("Height"));
			p.add(this.editHeight);

			p2.add(p, c);
			big.add(p2, BorderLayout.CENTER);

			this.add(big, BorderLayout.NORTH);
		}

		public void addNotify() {
			super.addNotify();
			this.setSize(290, this.editHeight.getPreferredSize().height + this.size.getPreferredSize().height + 15);
		}

		public void initialise() {
			this.oldHeight = CentralPanel.ACTIVE_GRID.getGridSize().height;
			this.oldWidth = CentralPanel.ACTIVE_GRID.getGridSize().width;

			this.editWidth.setText(Integer.toString(this.oldWidth));
			this.editHeight.setText(Integer.toString(this.oldHeight));
		}

		public void ok() {
			this.handeleWidthChange();
			this.handeleHeightChange();

			try {
				CentralPanel.ACTIVE_GRID.changeGridSize(this.oldWidth, this.oldHeight);
			} catch (SimException ex) {
				MainWindow.OK_WINDOW.setDescription("Can not change grid size");
				MainWindow.OK_WINDOW.setMessage(ex.getMessage());
				MainWindow.OK_WINDOW.setVisible(true);
			}
		}

		public void actionPerformed(ActionEvent e) {
			if (e.getSource() == this.editWidth) {
				this.handeleWidthChange();
			} else {
				this.handeleHeightChange();
			}
		}

		public void focusGained(FocusEvent e) {
		}

		public void focusLost(FocusEvent e) {
			if (e.getSource() == this.editWidth) {
				this.handeleWidthChange();
				this.editWidth.setText(this.editWidth.getText());
			} else {
				this.handeleHeightChange();
				this.editHeight.setText(this.editHeight.getText());
			}
		}

		private void handeleWidthChange() {
			int newWidth;

			try {
				newWidth = Integer.valueOf(this.editWidth.getText()).intValue();

				if (newWidth > 10) {
					this.oldWidth = newWidth;
				} else {
					this.editWidth.setText(Integer.toString(this.oldWidth));
				}
			} catch (NumberFormatException nfe) {
				this.editWidth.setText(Integer.toString(this.oldWidth));
			}
		}

		private void handeleHeightChange() {
			int newHeight;

			try {
				newHeight = Integer.valueOf(this.editHeight.getText()).intValue();

				if (newHeight > 10) {
					this.oldHeight = newHeight;
				} else {
					this.editHeight.setText(Integer.toString(this.oldHeight));
				}
			} catch (NumberFormatException nfe) {
				this.editHeight.setText(Integer.toString(this.oldHeight));
			}
		}

		public Dimension getPreferredSize() {
			return this.getSize();
		}

		public Dimension getMinimumSize() {
			return this.getSize();
		}

		public Dimension getMaximumSize() {
			return this.getSize();
		}
	}
}
