/*
 * Created on Apr 12, 2003
 *
 * To change this generated comment go to 
 * Window>Preferences>Java>Code Generation>Code Template
 */
package jdraw.std;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.*;

import jdraw.framework.DrawModel;
import jdraw.framework.DrawModelListener;
import jdraw.framework.*;

/**
 * @author Christoph
 */
public class StdDrawModel implements DrawModel, FigureListener {
	
	private List figures = new ArrayList();
	private List modelChangeListeners = new ArrayList();

	/**
	 * Adds a new figure to the draw model.
	 * @param f figure to be added to draw model.
	 */
	public void addFigure(Figure f) {
		if (!figures.contains(f)) {
			figures.add(f);
			f.addFigureListener(this);
			notifyDrawModelListeners(new DrawModelEvent(this, f, DrawModelEvent.FIGURE_ADDED));
		}
	}

	/**
	 * Removes a given figure from the draw model.
	 * @param f figure to be removed from draw model.
	 */
	public void removeFigure(Figure f) {
		if (figures.remove(f)) {
			f.removeFigureListener(this);
			notifyDrawModelListeners(new DrawModelEvent(this, f, DrawModelEvent.FIGURE_REMOVED));
		}
	}

	/**
	 * Returns an iterator which can be used to iterate over
	 * all figures of a draw model.
	 * @return iterator to iterate over the draw model
	 */
	public Iterator getFigures() {
		return figures.iterator();
	}

	/**
	 * Adds the specified model listener to receive model events from 
	 * this draw model. If listener is null, no exception is thrown and no 
	 * action is performed.
	 * @param listener the draw model listener.
	 * @see DrawModelListener
	 */
	public void addModelChangeListener(DrawModelListener listener) {
		modelChangeListeners.add(listener);
	}

	/**
	 * Removes the specified model listener so that it no longer receives
	 * model events from this draw model. This method performs no function, 
	 * nor does it throw an exception, if the listener specified by the 
	 * argument was not previously added to this figure. 
	 * If listener is null, no exception is thrown and no action is performed.
	 * @param listener the draw model listener.
	 * @see DrawModelListener
	 */
	public void removeModelChangeListener(DrawModelListener listener) {
		modelChangeListeners.remove(listener);
	}

	/**
	 * Listens to the FigureEvents of all figures contained in this model.
	 * Responds to any events by notifying all DrawModelListeners.
	 * 
	 * @param e a FigureEvent occurring in any Figure contained in this model.
	 * @see jdraw.framework.FigureListener#figureChanged(FigureEvent)
	 */
	public void figureChanged(FigureEvent e) {
		notifyDrawModelListeners(
			new DrawModelEvent(this, e.getFigure(), DrawModelEvent.FIGURE_CHANGED)
		);
	}

	private void notifyDrawModelListeners(DrawModelEvent e) {
		Iterator it = modelChangeListeners.iterator();
		while (it.hasNext()) {
			((DrawModelListener)it.next()).modelChanged(e);
		}
	}

	
	public void loadFigures(File f) {
		ObjectInputStream ois = null;
			try {
				ois = new ObjectInputStream(new FileInputStream(f));
				figures.clear();
				figures = (ArrayList)ois.readObject();
				
				for(Iterator it = figures.iterator(); it.hasNext();) {
					Figure fig = (Figure)it.next();
					fig.addFigureListener(this);
				}
					
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	}


	public void saveFigures(File f) {
		// save graphic
		ObjectOutputStream oos = null;
		try {
			oos = new ObjectOutputStream(new FileOutputStream(f));
			oos.writeObject(figures);
			oos.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
