public boolean getDrawDipole() {
			return drawDipole;
		}

	}

	private class UndoableInsertion extends AbstractUndoableEdit {

		private String presentationName = "";
		private int undoID;

		public UndoableInsertion(int undoID, double x, double y) {
			switch (actionID) {
			case ADGB_ID:
				presentationName = "Inserting Particle";
				break;
			case DUPL_ID:
				presentationName = "Duplicating Particle";
				break;
			}
			this.undoID = undoID;
		}

		public String getPresentationName() {
			return presentationName;
		}

		public void undo() {
			super.undo();
			switch (undoID) {
			case UndoAction.INSERT_A_PARTICLE:
				nParticle--;
				if (!model.getRecorderDisabled())
					gb[nParticle].initializeMovieQ(-1);
				if (gb[nParticle].isSelected())
					setSelectedComponent(null);
				model.setNumberOfParticles(nParticle);
				break;
			}
			model.notifyChange();
			repaint();
		}

		public void redo() {
			super.redo();
			doNotFireUndoEvent = true;
			switch (undoID) {
			case UndoAction.INSERT_A_PARTICLE:
				if (!model.getRecorderDisabled())
					gb[nParticle].initializeMovieQ(model.getMovie().getCapacity());
				gb[nParticle].setSelected(true);
				nParticle++;
				model.setNumberOfParticles(nParticle);
				break;
			}
			doNotFireUndoEvent = false;
			model.notifyChange();
			repaint();
		}

	}

	private class UndoableDeletion extends AbstractUndoableEdit {

		private int undoID, nRemoved;
		private Layered[] removedLayers;

		public UndoableDeletion(int undoID, int nRemoved) {
			this.undoID = undoID;
			this.nRemoved = nRemoved;
		}

		public UndoableDeletion(int undoID, int nRemoved, Layered[] removedLayers) {
			this(undoID, nRemoved);
			this.removedLayers = removedLayers;
		}

		public String getPresentationName() {
			return "Deletion";
		}

		public void undo() {
			super.undo();
			switch (undoID) {
			case UndoAction.BLOCK_REMOVE:
				undoRemoveMarkedParticles(nRemoved);
				if (removedLayers != null) {
					for (Layered l : removedLayers)
						layerBasket.add(l);
					if (nRemoved <= 0 && removedLayers.length == 1)
						((ModelComponent) removedLayers[0]).setSelected(true);
				}
				break;
			}
			model.notifyChange();
			repaint();
		}

		public void redo() {
			super.redo();
			doNotFireUndoEvent = true;
			switch (undoID) {
			case UndoAction.BLOCK_REMOVE:
				List<Integer> list = new ArrayList<Integer>();
				int n = model.getNumberOfParticles();
				for (int i = 0; i < nRemoved; i++)
					list.add(n - 1 - i);
				removeMarkedParticles(list);
				if (removedLayers != null) {
					for (Layered l : removedLayers)
						layerBasket.remove(l);
				}
				break;
			}
			doNotFireUndoEvent = false;
			model.notifyChange();
			repaint();
		}

	}

	private class UndoableMoving extends AbstractUndoableEdit {

		private ModelComponent mc;
		private double x, y, theta;
		private String presentationName;

		UndoableMoving(ModelComponent mc) {
			this.mc = mc;
			switch (actionID) {
			case ROTA_ID:
				presentationName = "Rotation";
				if (mc instanceof GayBerneParticle)
					theta = ((GayBerneParticle) mc).getTheta();
				break;
			case SELE_ID:
				presentationName = "Translation";
				x = mc.getRx();
				y = mc.getRy();
				break;
			}
		}

		public void setPresentationName(String s) {
			presentationName = s;
		}

		public String getPresentationName() {
			return presentationName;
		}

		public void undo() {
			super.undo();
			mc.restoreState();
			mc.setSelected(true);
			model.notifyChange();
			repaint();
		}

		public void redo() {
			super.redo();
			doNotFireUndoEvent = true;
			if (presentationName.equals("Translation")) {
				if (mc instanceof GayBerneParticle) {
					((GayBerneParticle) mc).translateTo(x, y);
				} else if (mc instanceof Layered) {
					((Layered) mc).setLocation(x, y);
				}
			} else if (presentationName.equals("Rotation")) {
				if (mc instanceof GayBerneParticle) {
					((GayBerneParticle) mc).setTheta(theta);
					((GayBerneParticle) mc).setSelectedToRotate(true);
				}
			}
			doNotFireUndoEvent = false;
			mc.setSelected(true);
			model.notifyChange();
			repaint();
		}

	}

	private class UndoableResizing extends AbstractUndoableEdit {

		private ModelComponent mc;
		private double x, y;
		private String presentationName = "";

		UndoableResizing(ModelComponent mc) {
			this.mc = mc;
			if (mc instanceof GayBerneParticle) {
				switch (actionID) {
				case RESI_ID:
					x = ((GayBerneParticle) mc).getBreadth();
					y = ((GayBerneParticle) mc).getLength();
					presentationName = "Resizing Particle";
					break;
				case VELO_ID:
					x = ((GayBerneParticle) mc).getVx();
					y = ((GayBerneParticle) mc).getVy();
					presentationName = "Changing Velocity";
					break;
				case OMEG_ID:
					x = ((GayBerneParticle) mc).getOmega();
					presentationName = "Changing Angular Velocity";
					break;
				}
			}
		}

		public String getPresentationName() {
			return presentationName;
		}

		public void undo() {
			super.undo();
			mc.restoreState();
			mc.setSelected(true);
			model.notifyChange();
			repaint();
		}

		public void redo() {
			super.redo();
			doNotFireUndoEvent = true;
			if (mc instanceof GayBerneParticle) {
				if (presentationName.equals("Resizing Particle")) {
					((GayBerneParticle) mc).setBreadth(x);
					((GayBerneParticle) mc).setLength(y);
				} else if (presentationName.equals("Changing Velocity")) {
					((GayBerneParticle) mc).setVx(x);
					((GayBerneParticle) mc).setVy(y);
				} else if (presentationName.equals("Changing Angular Velocity")) {
					((GayBerneParticle) mc).setOmega(x);
				}
			}
			mc.setSelected(true);
			doNotFireUndoEvent = false;
			model.notifyChange();
			repaint();
		}