package org.docear.plugin.core.features;
import java.awt.Component;
import java.util.EventListener;
import javax.swing.event.EventListenerList;
import org.freeplane.features.map.IMapLifeCycleListener;
import org.freeplane.features.map.MapModel;
import org.freeplane.features.mode.Controller;
import org.freeplane.features.mode.ModeController;
import org.freeplane.features.ui.IMapViewChangeListener;
public class DocearLifeCycleObserver {
public static enum ViewEventType {
BEFORE_VIEW_CHANGED, AFTER_VIEW_CHANGED, AFTER_VIEW_CLOSED, AFTER_VIEW_CREATED
}
public static enum MapEventType {
CREATED, REMOVED, SAVED_AS, SAVED
}
private ListenerAdapter listenerAdapter = new ListenerAdapter();
private EventListenerList list = new EventListenerList();
/***********************************************************************************
* CONSTRUCTORS
**********************************************************************************/
public DocearLifeCycleObserver(ModeController modeController) {
modeController.getMapController().addMapLifeCycleListener(listenerAdapter);
Controller.getCurrentController().getMapViewManager().addMapViewChangeListener(listenerAdapter);
}
/***********************************************************************************
* METHODS
**********************************************************************************/
public void addMapLifeCycleListener(IMapLifeCycleListener l) {
list.add(InternalMapLifeCycleListenerWrapper.class, new InternalMapLifeCycleListenerWrapper(l));
}
public void removeMapLifeCycleListener(IMapLifeCycleListener l) {
list.remove(InternalMapLifeCycleListenerWrapper.class, new InternalMapLifeCycleListenerWrapper(l));
}
public void addMapViewChangeListener(IMapViewChangeListener l) {
list.add(InternalMapViewChangedListenerWrapper.class, new InternalMapViewChangedListenerWrapper(l));
}
public void removeMapViewChangeListener(IMapViewChangeListener l) {
list.remove(InternalMapViewChangedListenerWrapper.class, new InternalMapViewChangedListenerWrapper(l));
}
public void fireMapEvent(MapEventType type, MapModel map) {
InternalMapLifeCycleListenerWrapper[] listeners = list.getListeners(InternalMapLifeCycleListenerWrapper.class);
if(listeners == null) {
return;
}
for (int i = listeners.length-1; i >= 0; i -= 1) {
InternalMapLifeCycleListenerWrapper wrapper = listeners[i];
switch (type) {
case CREATED:
wrapper.getListener().onCreate(map);
break;
case REMOVED:
wrapper.getListener().onRemove(map);
break;
case SAVED:
wrapper.getListener().onSaved(map);
break;
case SAVED_AS:
wrapper.getListener().onSavedAs(map);
break;
}
}
}
public void fireViewEvent(ViewEventType type, Component oldView, Component newView) {
InternalMapViewChangedListenerWrapper[] listeners = list.getListeners(InternalMapViewChangedListenerWrapper.class);
if(listeners == null) {
return;
}
for (int i = listeners.length-1; i >= 0; i -= 1) {
InternalMapViewChangedListenerWrapper wrapper = listeners[i];
switch (type) {
case BEFORE_VIEW_CHANGED:
wrapper.getListener().beforeViewChange(oldView, newView);
break;
case AFTER_VIEW_CHANGED:
wrapper.getListener().afterViewChange(oldView, newView);
break;
case AFTER_VIEW_CREATED:
wrapper.getListener().afterViewCreated(newView);
break;
case AFTER_VIEW_CLOSED:
wrapper.getListener().afterViewClose(oldView);
break;
}
}
}
/***********************************************************************************
* REQUIRED METHODS FOR INTERFACES
**********************************************************************************/
private class InternalMapViewChangedListenerWrapper implements EventListener {
private final IMapViewChangeListener l;
public InternalMapViewChangedListenerWrapper(IMapViewChangeListener l) {
this.l = l;
}
public IMapViewChangeListener getListener() {
return l;
}
public int hashCode() {
return l.hashCode();
}
public boolean equals(Object o) {
if(o instanceof InternalMapViewChangedListenerWrapper) {
return l.equals(((InternalMapViewChangedListenerWrapper) o).getListener());
}
return super.equals(o);
}
}
private class InternalMapLifeCycleListenerWrapper implements EventListener {
private final IMapLifeCycleListener l;
public InternalMapLifeCycleListenerWrapper(IMapLifeCycleListener l) {
this.l = l;
}
public IMapLifeCycleListener getListener() {
return l;
}
public int hashCode() {
return l.hashCode();
}
public boolean equals(Object o) {
if(o instanceof InternalMapLifeCycleListenerWrapper) {
return l.equals(((InternalMapLifeCycleListenerWrapper) o).getListener());
}
return super.equals(o);
}
}
private class ListenerAdapter implements IMapLifeCycleListener, IMapViewChangeListener {
@Override
public void afterViewChange(Component oldView, Component newView) {
fireViewEvent(ViewEventType.AFTER_VIEW_CHANGED, oldView, newView);
}
@Override
public void afterViewClose(Component oldView) {
fireViewEvent(ViewEventType.AFTER_VIEW_CLOSED, oldView, null);
}
@Override
public void afterViewCreated(Component mapView) {
fireViewEvent(ViewEventType.AFTER_VIEW_CREATED, null, mapView);
}
@Override
public void beforeViewChange(Component oldView, Component newView) {
fireViewEvent(ViewEventType.BEFORE_VIEW_CHANGED, oldView, newView);
}
@Override
public void onCreate(MapModel map) {
fireMapEvent(MapEventType.CREATED, map);
}
@Override
public void onRemove(MapModel map) {
fireMapEvent(MapEventType.REMOVED, map);
}
@Override
public void onSavedAs(MapModel map) {
fireMapEvent(MapEventType.SAVED_AS, map);
}
@Override
public void onSaved(MapModel map) {
fireMapEvent(MapEventType.SAVED, map);
}
}
}