package jdraw;

// Uebung Java Draw Editor
//
// Informatik 4/FHA
// Software Konstruktion/ETH
//

import javax.swing.*;

import jdraw.figures.*;
import jdraw.framework.*;
import jdraw.std.*;

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;

/**
 * The class Draw is the main class of the graphic editor. Its main
 * method creates a new JFrame and initializes it. Changes in the
 * configuration of the main window (e.g. new menus, tools etc.)
 * have to be added in this class.
 * <P>
 * The application can be started with the command
 * <PRE>
 * java jdraw.Draw
 * </PRE>
 *
 * @see DrawView
 *
 * @author  Dominik Gruntz
 * @version 2.1, 29.04.2002
 */
public class Draw {

	private static int windowCounter = 0;
	
	/**
	 * Starts the Graphic editor.
	 *
	 *    java jdraw.Draw
	 *
	 * Arguments are not yet interpreted.
	 */
	public static void main (String[] args){
		Draw d = new Draw(new StdDrawModel());
		d.rootFrame.setSize(600,400);
		d.rootFrame.setVisible(true);
	}

	private DrawView v;
	private int windowNr;
	private JFrame rootFrame;
	
	private java.util.List tools = new LinkedList();
	
	private Draw(DrawModel model){
		rootFrame = new JFrame("Draw Editor");		
		windowNr = windowCounter++;
		if(windowNr > 0)
			rootFrame.setTitle("<"+rootFrame.getTitle()+":"+windowNr+">");
		
	 	final JTextField statusField = new JTextField();
		final JMenuBar   menuBar     = new JMenuBar();
		
		// define the call-back DrawEditor interface to access 
		// the menuBar and the statusField
		DrawEditor editor = new DrawEditor(){
			public DrawView getView(){return v;}
			public void showStatus(String s){
				statusField.setText(s);
			}
			public void addMenu(JMenu m){
				menuBar.add(m);
				rootFrame.setJMenuBar(menuBar);
			}
			public void removeMenu(JMenu m){
				menuBar.remove(m);
				rootFrame.setJMenuBar(menuBar);
			}
			public void toolChanged(){
				checkTools();
			}
		};	
		
		v = new StdDrawView(editor, model, 300, 200);
		JScrollPane scrollPane = new JScrollPane(
			(JComponent)v, 
			JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
			JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		
		statusField.setEditable(false);
		
		JToolBar toolBar = new JToolBar();
		
		JPanel center = new JPanel(new BorderLayout());
		center.add(toolBar,    BorderLayout.NORTH);
		center.add(scrollPane, BorderLayout.CENTER);
		rootFrame.getContentPane().add(center,      BorderLayout.CENTER);
		rootFrame.getContentPane().add(statusField, BorderLayout.SOUTH);

		rootFrame.pack();
		rootFrame.setSize(300, 200);
		

		rootFrame.addWindowListener(
			new WindowAdapter(){
				public void windowClosing(WindowEvent e){
					close();
				}
			}
		);

		// Setup menu bar
		rootFrame.setJMenuBar(menuBar);

		JMenu file = new JMenu("File");
		menuBar.add(file);
		
		JMenu edit = new JMenu("Edit");
		menuBar.add(edit);
		
		JMenu figures = new JMenu("Figures");
		menuBar.add(figures);
		
		JMenu window = new JMenu("Window");
		menuBar.add(window);
		
		// FIGURE MENU
		///////////////
		
		// Get Defaulttool
		v.setDefaultTool();
		DrawTool selectionTool = v.getTool();
		
		// Add Selection Tool
		addFigureMenuEntry(figures, "Selection", selectionTool);
		addToolBarEntry   (toolBar, "Selection", selectionTool, "images/SELECTION.gif",  editor);

		figures.addSeparator();
		toolBar.addSeparator();
		
		// Add new figure tools here

		DrawTool rectangleTool = new RectangleTool(editor);
		addFigureMenuEntry(figures, "Rectangle", rectangleTool);
		addToolBarEntry   (toolBar, "Rectangle", rectangleTool, "images/RECTANGLE.gif",  editor);	

		DrawTool ellipseTool = new EllipseTool(editor);
		addFigureMenuEntry(figures, "Ellipse", ellipseTool);
		addToolBarEntry		(toolBar, "Ellipse", ellipseTool, "images/OVAL.gif", editor);

		DrawTool lineTool = new LineTool(editor);
		addFigureMenuEntry(figures, "Line", lineTool);
		addToolBarEntry		(toolBar, "Line", lineTool, "images/LINE.gif", editor);

		checkTools();
		
		// FILE MENU
		/////////////
		
		JMenuItem open = new JMenuItem("Open");
		file.add(open);
		open.setAccelerator(KeyStroke.getKeyStroke("control O"));
		open.addActionListener(
			new ActionListener(){
				public void actionPerformed(ActionEvent e){
					doOpen();
				}
			}
		);
		
		JMenuItem save = new JMenuItem("Save");
		save.setAccelerator(KeyStroke.getKeyStroke("control S"));
		file.add(save);
		save.addActionListener(
			new ActionListener(){
				public void actionPerformed(ActionEvent e){
					doSave();
				}
			}
		);
		
		JMenuItem exit = new JMenuItem("Exit");
		file.add(exit);
		exit.addActionListener(
			new ActionListener(){
				public void actionPerformed(ActionEvent e){
					System.exit(0);
				}
			}
		);
			
		
		// EDIT MENU
		////////////
		
		JMenuItem sa = new JMenuItem("SelectAll");
		sa.setAccelerator(KeyStroke.getKeyStroke("control A"));
		edit.add(sa);
		sa.addActionListener(
			new ActionListener(){
				public void actionPerformed(ActionEvent e){
					Iterator it = v.getModel().getFigures();
					while(it.hasNext()){
						v.addToSelection((Figure)it.next());
					}
					v.repaint();
				}
			}
		);
		
		edit.addSeparator();
		edit.add("Cut").setEnabled(false);
		edit.add("Copy").setEnabled(false);
		edit.add("Paste").setEnabled(false);
		
		edit.addSeparator();
		JMenuItem group = new JMenuItem("Group");
		group.setEnabled(true);
		group.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				DrawModel model = v.getModel();
				Set selection = v.getSelection();
				if (!selection.isEmpty()) {
					Figure g = new GroupFigure(selection);
					Iterator it = selection.iterator();
					while(it.hasNext()) {
						Figure f = (Figure)it.next();
						v.removeFromSelection(f);
						model.removeFigure(f);
					}
					model.addFigure(g);
					v.addToSelection(g);
				}
			}
		});
		edit.add(group);
		
		JMenuItem ungroup = new JMenuItem("Ungroup");
		ungroup.setEnabled(true);
		ungroup.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Set selection = v.getSelection();
				Iterator it = selection.iterator();
				while(it.hasNext()) {
					Figure g = (Figure)it.next();
					if (g instanceof GroupFigure) {
						DrawModel model = v.getModel();
						GroupFigure gf = (GroupFigure)g;
						v.removeFromSelection(gf);
						model.removeFigure(gf);
						
						Iterator iter = gf.unGroup().iterator();
						while(iter.hasNext()) {
							Figure f = (Figure)iter.next();
							model.addFigure(f);
							v.addToSelection(f);
						}
					}
				}
			}
		});
		edit.add(ungroup);
		
		edit.addSeparator();

		JMenu grid = new JMenu("Grid");
		edit.add(grid);
		
		// WINDOW MENU
		//////////////
		
		JMenuItem newWindow = new JMenuItem("New Window");
		window.add(newWindow);
		newWindow.addActionListener(
			new ActionListener(){
				public void actionPerformed(ActionEvent e){
					Draw d = new Draw(v.getModel());
					d.rootFrame.setSize(600,400);
					d.rootFrame.setVisible(true);
				}
			}
		);

	}
	
	private void addFigureMenuEntry(JMenu figures, String name, final DrawTool tool){
		final JMenuItem m = new JMenuItem(name);
		figures.add(m);
		m.addActionListener(
			new ActionListener(){
				public void actionPerformed(ActionEvent e){
					v.setTool(tool);
				}
			}
		);
	}
	
	private void addToolBarEntry(JToolBar toolbar, String name, DrawTool tool, 
									String iconName, DrawEditor editor){
		Icon icon = new ImageIcon(getClass().getResource(iconName));
		addToolBarEntry(toolbar, name, tool, icon, editor);
	}

	private void addToolBarEntry(JToolBar toolbar, String name, final DrawTool tool, 
									Icon icon, DrawEditor editor){
		jdraw.std.ToolButton button;
		button = new jdraw.std.ToolButton(name, icon, tool, editor);
		toolbar.add(button);
		tools.add(button);
		button.addActionListener(
			new ActionListener(){
				public void actionPerformed(ActionEvent e){
					v.setTool(tool);
				}
			}
		);
	}
	
	private void checkTools(){
		Iterator it = tools.iterator();
		while(it.hasNext()){
			Object x = it.next();
			if(x instanceof jdraw.std.ToolButton){
				((jdraw.std.ToolButton)x).checkState();
				((jdraw.std.ToolButton)x).repaint();
			}
		}
	}
	
	
	private void doOpen(){
		JFileChooser chooser = new JFileChooser(
			getClass().getResource("").getFile()
		);
		chooser.setDialogTitle("Open Graphic");
		chooser.setDialogType(JFileChooser.OPEN_DIALOG);
		chooser.setFileFilter(
			new javax.swing.filechooser.FileFilter(){
				public String getDescription(){return "JDraw Graphic (*.draw)";}
				public boolean accept(File f){return f.isDirectory() || f.getName().endsWith(".draw");}
			}
		);
		int res = chooser.showOpenDialog(rootFrame);
		
		if(res == JFileChooser.APPROVE_OPTION) {
			// read jdraw graphic
			System.out.println("read file " + chooser.getSelectedFile().getName());
		}
	}
	
	private void doSave(){
		JFileChooser chooser = new JFileChooser(
			getClass().getResource("").getFile()
		);
		chooser.setDialogTitle("Save Graphic");
		chooser.setDialogType(JFileChooser.SAVE_DIALOG);
		chooser.setFileFilter(
			new javax.swing.filechooser.FileFilter(){
				public String getDescription(){return "JDraw Graphic (*.draw)";}
				public boolean accept(File f){return f.getName().endsWith(".draw");}
			}
		);
		int res = chooser.showOpenDialog(rootFrame);
		
		if(res == JFileChooser.APPROVE_OPTION) {
			// save graphic
			System.out.println("save current graphic to file " +chooser.getSelectedFile().getName());
		}
	}
	
	void close(){
		if(windowNr == 0){
			System.exit(0);
		}
	}
}

