package org.docear.plugin.core.features;
import java.awt.event.ActionEvent;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.docear.plugin.core.event.DocearEvent;
import org.docear.plugin.core.event.DocearEventType;
import org.docear.plugin.core.event.IDocearEventListener;
import org.freeplane.core.extension.IExtension;
import org.freeplane.core.resources.ResourceController;
import org.freeplane.core.ui.AFreeplaneAction;
import org.freeplane.core.ui.SelectableAction;
import org.freeplane.core.ui.components.OneTouchCollapseResizer;
import org.freeplane.core.ui.components.OneTouchCollapseResizer.ComponentCollapseListener;
import org.freeplane.core.ui.components.ResizeEvent;
import org.freeplane.features.mode.Controller;
import org.freeplane.features.mode.ModeController;
import org.freeplane.plugin.workspace.WorkspaceController;
public class DocearMaximizeMapHandler implements IExtension, IDocearEventListener, ComponentCollapseListener {
private static final String MAPVIEW_MAXIMIZED_PROPERTY = "mapview_maximized";
private volatile boolean IS_IN_TOGGLE = false;
private final Map<OneTouchCollapseResizer, Boolean> lastStateMap = new LinkedHashMap<OneTouchCollapseResizer, Boolean>();
/***********************************************************************************
* CONSTRUCTORS
**********************************************************************************/
private DocearMaximizeMapHandler(ModeController modeController) {
ResourceController.getResourceController().setProperty(MAPVIEW_MAXIMIZED_PROPERTY, "false");
WorkspaceController.replaceAction(modeController, new ToggleMapMaximizedAction());
}
/***********************************************************************************
* METHODS
* @return
**********************************************************************************/
public static DocearMaximizeMapHandler installMode(ModeController modeController) {
DocearMaximizeMapHandler handler = modeController.getExtension(DocearMaximizeMapHandler.class);
if(handler == null) {
handler = new DocearMaximizeMapHandler(modeController);
modeController.addExtension(DocearMaximizeMapHandler.class, handler);
}
return handler;
}
public static DocearMaximizeMapHandler getModeHandler() {
return getModeHandler(Controller.getCurrentModeController());
}
public static DocearMaximizeMapHandler getModeHandler(ModeController modeController) {
return modeController.getExtension(DocearMaximizeMapHandler.class);
}
public void addCollapsableResizer(OneTouchCollapseResizer resizer) {
if(resizer == null) {
return;
}
synchronized (lastStateMap) {
if(!lastStateMap.containsKey(resizer)) {
lastStateMap.put(resizer, resizer.isExpanded());
resizer.addCollapseListener(this);
}
}
}
public void removeCollapsableResizer(OneTouchCollapseResizer resizer) {
if(resizer == null) {
return;
}
synchronized (lastStateMap) {
if(lastStateMap.remove(resizer) != null) {
resizer.removeCollapseListener(this);
}
}
}
public boolean isMapMaximizeEnabled() {
return Boolean.parseBoolean(ResourceController.getResourceController().getProperty(MAPVIEW_MAXIMIZED_PROPERTY, "false"));
}
public void toggleMaximized() {
Boolean max = !isMapMaximizeEnabled();
setMapMaximized(max);
ResourceController.getResourceController().setProperty(MAPVIEW_MAXIMIZED_PROPERTY, Boolean.toString(max));
}
private void setMapMaximized(boolean maximized) {
IS_IN_TOGGLE = true;
try {
synchronized (lastStateMap) {
boolean expand = !maximized;
for (Entry<OneTouchCollapseResizer, Boolean> entry : lastStateMap.entrySet()) {
if(!expand) {
entry.getKey().setExpanded(false);
}
else {
if(entry.getValue()) {
entry.getKey().setExpanded(true);
}
}
}
}
}
finally {
IS_IN_TOGGLE = false;
}
}
private void updateState(OneTouchCollapseResizer resizer) {
if(IS_IN_TOGGLE) {
return;
}
synchronized (lastStateMap) {
Boolean b = lastStateMap.get(resizer);
if(b != null && b != resizer.isExpanded()) {
lastStateMap.put(resizer, resizer.isExpanded());
}
}
}
/***********************************************************************************
* REQUIRED METHODS FOR INTERFACES
**********************************************************************************/
@Override
public void componentCollapsed(ResizeEvent event) {
updateState((OneTouchCollapseResizer)event.getSource());
}
@Override
public void componentExpanded(ResizeEvent event) {
updateState((OneTouchCollapseResizer)event.getSource());
}
@Override
public void handleEvent(DocearEvent event) {
if(event.getType() == DocearEventType.APPLICATION_CLOSING) {
setMapMaximized(false);
}
else if(event.getType() == DocearEventType.APPLICATION_CLOSING_ABORTED) {
setMapMaximized(isMapMaximizeEnabled());
}
}
@SelectableAction(checkOnPropertyChange = MAPVIEW_MAXIMIZED_PROPERTY)
public class ToggleMapMaximizedAction extends AFreeplaneAction {
private static final long serialVersionUID = -2014522604202908914L;
public static final String KEY = "ToggleMapMaximizedAction";
/***********************************************************************************
* CONSTRUCTORS
**********************************************************************************/
public ToggleMapMaximizedAction() {
super(KEY);
}
/***********************************************************************************
* METHODS
**********************************************************************************/
@Override
public boolean isSelected() {
return isMapMaximizeEnabled();
}
/***********************************************************************************
* REQUIRED METHODS FOR INTERFACES
**********************************************************************************/
@Override
public void actionPerformed(ActionEvent e) {
toggleMaximized();
}
}
}