package sim;

import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JOptionPane;

import sim.util.SimButton;
import sim.util.SimButtonListener;
import sim.util.DownloadDialog;
import sim.util.SimFileDialog;

public class SaveLoadShortcut extends Panel {

	//public static String LASTPATH = System.getProperty("user.dir");
	public static String LASTPATH;
	public static FileDialog FILEDIALOG;
	public static final GuiFileLink GUI_FILE_LINK = new GuiFileLink();
	private SaveLoadShortcutListener listener;
	protected boolean isFirstSave = true;

	public SaveLoadShortcut() {
		super();
		this.setLayout(new FlowLayout(FlowLayout.LEFT, 8, 0));
	}

	public void addNotify() {
		super.addNotify();
		this.listener = new SaveLoadShortcutListener(this);
	}

	public void setEnabled(boolean b) {
		MainWindow.MENU.NEW.setEnabled(b);
		MainWindow.MENU.OPEN.setEnabled(b);

		if (MainWindow.MASTER == null) {
			MainWindow.MENU.SAVE_AS.setEnabled(b);
			MainWindow.MENU.SAVE.setEnabled(b);
		}

		this.listener.setEnabled(b);
	}

	/* ==================================================================
	 Services provided to Menu
	 ================================================================ */
	public void createNew() {
		this.listener.createNew("Untitled.toy");
	}

	public void save() {
		this.listener.save();
		//this.saveImage(MainWindow.CENTRAL_PANEL.ACTIVE_GRID);
	}

	public void saveAs() {
		this.listener.saveAs();
	}

	public void load() {
		this.listener.load();
	}

	/* ==================================================================
	 Listener to handle mouse events
	 ================================================================= */
	public class SaveLoadShortcutListener extends SimButtonListener {

		private SimButton create;
		private SimButton save;
		private SimButton load;
		private DownloadDialog remoteDialog;
		private boolean buttonUpOnLastMouseDown;
		private String FILENAME;

		public SaveLoadShortcutListener(SaveLoadShortcut parent) {
			Panel p = new Panel(new FlowLayout(FlowLayout.LEFT, 0, 0));
			parent.add(p);

			this.buttonUpOnLastMouseDown = true;

			this.create = new SimButton("sim/images/New.png", "New", NorthPanel.BUBBLE_WAIT);
			this.create.setListener(this);
			p.add(this.create);

			this.save = new SimButton("sim/images/Save.png", "Save", NorthPanel.BUBBLE_WAIT);
			this.save.setListener(this);
			p.add(this.save);

			this.load = new SimButton("sim/images/Open.png", "Load", NorthPanel.BUBBLE_WAIT);
			this.load.setListener(this);
			p.add(this.load);

			if (MainWindow.MASTER == null) {
				SaveLoadShortcut.FILEDIALOG = new SimFileDialog(MainWindow.MAIN_WINDOW);
			} else {
				this.save.setEnabled(false);
				this.remoteDialog = new DownloadDialog(MainWindow.MASTER.getCodeBase().toString());
			}
		}

		public void setEnabled(boolean b) {
			this.create.setEnabled(b);
			this.load.setEnabled(b);

			if (MainWindow.MASTER == null) {
				this.save.setEnabled(b);
			}
		}

		public void actionPerformed(ActionEvent e) {
			SimButton ib = (SimButton) e.getSource();
			if (ib == this.create) {
				this.create.paintRaised();
				this.createNew("Untitled.toy");
			} else if (ib == this.save) {
				this.save.paintRaised();
				this.save();
			} else if (ib == this.load) {
				this.load.paintRaised();
				this.load();
			}
		}

		public void activate(SimButton ib) {
			ib.processActionEvent();
			ib.setArmed(false);
		}

		public void arm(SimButton ib) {
			ib.setArmed(true);
		}

		public void disarm(SimButton ib) {
			ib.setArmed(false);
		}

		public void mousePressed(MouseEvent event) {
			SimButton ib = (SimButton) event.getSource();
			if (ib.isEnabled()) {
				ib.paintInset();
				this.buttonUpOnLastMouseDown = ib.isRaised();
				this.arm(ib);
			}
		}

		public void mouseClicked(MouseEvent event) {
			SimButton ib = (SimButton) event.getSource();
			if (ib.isEnabled() && ib.isArmed()) {
				this.activate(ib);
			}
		}

		public void mouseReleased(MouseEvent event) {
			SimButton ib = (SimButton) event.getSource();
			Point pt = event.getPoint();

			if (ib.contains(pt.x, pt.y)) {
				this.mouseClicked(event);
			}
		}

		public void mouseDragged(MouseEvent event) {
			SimButton ib = (SimButton) event.getSource();
			if (ib.isEnabled() && ib.isArmed()) {
				Point loc = event.getPoint();

				if (ib.contains(loc.x, loc.y)) {
					if (this.buttonUpOnLastMouseDown) {
						if (!ib.isRaised()) {
							ib.paintRaised();
						}
					} else if (ib.isRaised()) {
						ib.paintInset();
					}
				} else {
					if (this.buttonUpOnLastMouseDown) {
						if (ib.isRaised()) {
							ib.paintInset();
						}
					} else if (!ib.isRaised()) {
						ib.paintRaised();
					}
				}
			}
		}

		private void newWithoutAsk(String fileName) {

			MainWindow.MAIN_WINDOW.setCursor(new Cursor(Cursor.WAIT_CURSOR));
			MainWindow.CENTRAL_PANEL.createGrid(fileName);
			NorthPanel.GRID_SHORTCUT.setGridVisibility(true);
			NorthPanel.GRID_SHORTCUT.setZoom("100%");
			MainWindow.MAIN_WINDOW.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
			CentralPanel.ACTIVE_GRID.setUnMod();
		}

		public void createNew(String fileName) {
			if (CentralPanel.ACTIVE_GRID.isModified()) {
				String title = "Confirm New";
				String msg = "Your changes have not been saved.\n"
						+ "Do you want continue?";

				Object[] options = {"Don't Save", "Cancel"};
				int confirm = JOptionPane.showOptionDialog(null,
						msg, title, JOptionPane.DEFAULT_OPTION,
						JOptionPane.WARNING_MESSAGE,
						null,
						options,
						options[1]);
				switch (confirm) {
					case 0:
						newWithoutAsk(fileName);
						break;
					case 1:
						break;
				}
			} else {
				newWithoutAsk(fileName);
			}
		}

		public void save() {
			if (isFirstSave) {
				saveAs();
			} else {
				MainWindow.MAIN_WINDOW.setCursor(new Cursor(Cursor.WAIT_CURSOR));

				try {
					if (WestPanel.MODE_CONTROL.getCurrnetActive() != WestPanel.MODE_CONTROL.getEditButton()) {
						WestPanel.MODE_CONTROL.switchToEditMode();
					} else {
						WestPanel.MODE_CONTROL.getEditHandler().deselect(true);
					}
					FILENAME = null;
					FILENAME = CentralPanel.ACTIVE_GRID.getName();

					try {
						BufferedWriter outStream = new BufferedWriter(new FileWriter(FILENAME));
						SaveLoadShortcut.GUI_FILE_LINK.save(outStream, CentralPanel.ACTIVE_GRID);
						outStream.close();
						CentralPanel.ACTIVE_GRID.setUnMod();
					} catch (IOException e) {
						throw (new SimException("can not open file"));
					}
				} catch (SimException exc) {
					MainWindow.OK_WINDOW.setDescription("Exception occur during saving");
					MainWindow.OK_WINDOW.setMessage(exc.getMessage());
					MainWindow.OK_WINDOW.setVisible(true);
				}

				MainWindow.MAIN_WINDOW.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
			}
		}

		public void saveAs() {
			MainWindow.MAIN_WINDOW.setCursor(new Cursor(Cursor.WAIT_CURSOR));

			try {
				if (WestPanel.MODE_CONTROL.getCurrnetActive() != WestPanel.MODE_CONTROL.getEditButton()) {
					WestPanel.MODE_CONTROL.switchToEditMode();
				} else {
					WestPanel.MODE_CONTROL.getEditHandler().deselect(true);
				}

				SaveLoadShortcut.FILEDIALOG.setDirectory(LASTPATH);
				SaveLoadShortcut.FILEDIALOG.setTitle("Save As");
				SaveLoadShortcut.FILEDIALOG.setMode(FileDialog.SAVE);
				SaveLoadShortcut.FILEDIALOG.setFile("*.toy");
				SaveLoadShortcut.FILEDIALOG.setVisible(true);

				FILENAME = null;
				FILENAME = SaveLoadShortcut.FILEDIALOG.getFile();

				if (FILENAME != null) {
					try {
						FILENAME = SaveLoadShortcut.FILEDIALOG.getDirectory() + FILENAME;
						LASTPATH = SaveLoadShortcut.FILEDIALOG.getDirectory();
						BufferedWriter outStream = new BufferedWriter(new FileWriter(FILENAME));
						SaveLoadShortcut.GUI_FILE_LINK.save(outStream, CentralPanel.ACTIVE_GRID);
						outStream.close();
						CentralPanel.ACTIVE_GRID.setName(FILENAME);
						MainWindow.MAIN_WINDOW.setTitle(MainWindow.PROGRAM_NAME + " - " + FILENAME);
						isFirstSave = false;
						CentralPanel.ACTIVE_GRID.setUnMod();
					} catch (IOException e) {
						throw (new SimException("can not open file"));
					}
				}
			} catch (SimException exc) {
				MainWindow.OK_WINDOW.setDescription("Exception occur during saving");
				MainWindow.OK_WINDOW.setMessage(exc.getMessage());
				MainWindow.OK_WINDOW.setVisible(true);
			}

			MainWindow.MAIN_WINDOW.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
		}

		public void load() {
			MainWindow.MAIN_WINDOW.setCursor(new Cursor(Cursor.WAIT_CURSOR));

			try {
				Reader inStream;

				if (MainWindow.MASTER == null) {
					SaveLoadShortcut.FILEDIALOG.setDirectory(LASTPATH);
					SaveLoadShortcut.FILEDIALOG.setTitle("Open");
					SaveLoadShortcut.FILEDIALOG.setMode(FileDialog.LOAD);
					SaveLoadShortcut.FILEDIALOG.setFile("*.toy");
//					FilenameFilter filter = new FilenameFilter() {
//						public boolean accept(File directory, String filename) {
//							return filename.endsWith(".toy");
//						}
//					};
//					SaveLoadShortcut.FILEDIALOG.setFilenameFilter(filter);
					SaveLoadShortcut.FILEDIALOG.setVisible(true);

					String inFile = SaveLoadShortcut.FILEDIALOG.getFile();

					if (inFile != null) {
						try {
							String path = SaveLoadShortcut.FILEDIALOG.getDirectory();
							String fileName = inFile;
							MainWindow.MAIN_WINDOW.setWorkspace(path, fileName);
							inFile = SaveLoadShortcut.FILEDIALOG.getDirectory() + inFile;
							LASTPATH = SaveLoadShortcut.FILEDIALOG.getDirectory();
							this.createNew(inFile);
							inStream = new BufferedReader(new FileReader(inFile));
							SaveLoadShortcut.GUI_FILE_LINK.load(inStream, CentralPanel.ACTIVE_GRID);
							inStream.close();
							CentralPanel.ACTIVE_GRID.setName(inFile);
							MainWindow.MAIN_WINDOW.setWorkspace(path, fileName);
							isFirstSave = false;
						} catch (IOException e) {
							throw (new SimException("can not open file"));
						}
					}
				} else {
					// handle internet dowloads
					this.remoteDialog.setVisible(true);
					FILENAME = null;
					FILENAME = this.remoteDialog.getFile();

					if (FILENAME != null) {
						try {
							this.createNew(FILENAME);
							FILENAME = this.remoteDialog.getURL() + FILENAME;
							inStream = new BufferedReader(new InputStreamReader((new URL(FILENAME)).openStream()));
							SaveLoadShortcut.GUI_FILE_LINK.load(inStream, CentralPanel.ACTIVE_GRID);
							inStream.close();
							CentralPanel.ACTIVE_GRID.setName(FILENAME);
							isFirstSave = false;
						} catch (MalformedURLException mue) {
							throw (new SimException("URL does not exist"));
						} catch (IOException e) {
							throw (new SimException("can not open file"));
						}
					}
				}
			} catch (SimException exc) {
				MainWindow.OK_WINDOW.setDescription("Exception occur during loading");
				MainWindow.OK_WINDOW.setMessage(exc.getMessage());
				MainWindow.OK_WINDOW.setVisible(true);
			}

			MainWindow.MAIN_WINDOW.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
		}
	}

	public void saveImage(Grid dPanel) {
		BufferedImage bImg = new BufferedImage(dPanel.getWidth(), dPanel.getWidth(), BufferedImage.TYPE_INT_RGB);
		Graphics2D cg = bImg.createGraphics();
		dPanel.paintAll(cg);
		try {
			if (ImageIO.write(bImg, "png", new File(MainWindow.WORKSPACE + "output_image.png"))) {
				System.out.println("-- saved");
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
