/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.core.gui.workflow.editor.commands;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.gef.commands.Command;
import de.rcenvironment.core.component.workflow.model.api.WorkflowDescription;
import de.rcenvironment.core.component.workflow.model.api.WorkflowLabel;
import de.rcenvironment.core.gui.workflow.editor.handlers.AbstractWorkflowPartSendHandler;
import de.rcenvironment.core.gui.workflow.parts.WorkflowLabelPart;
/**
*
* Command that sends label forward or backward in the editor. Don't supply any labels that are already in the foreground (background).
*
* @author Jascha Riedel
*/
public class WorkflowLabelSendLayerwiseCommand extends Command {
private static final int MINUS_ONE = -1;
private final WorkflowDescription workflowDescription;
private final List<WorkflowLabel> selectedLabels;
private final AbstractWorkflowPartSendHandler.SendType sendType;
private Map<WorkflowLabel, Integer> previousState = new HashMap<WorkflowLabel, Integer>();
public WorkflowLabelSendLayerwiseCommand(WorkflowDescription workflowDescription,
List<WorkflowLabelPart> cleanSelectedLabelParts,
AbstractWorkflowPartSendHandler.SendType sendType) {
this.workflowDescription = workflowDescription;
selectedLabels = new ArrayList<WorkflowLabel>();
for (WorkflowLabelPart part : cleanSelectedLabelParts) {
selectedLabels.add((WorkflowLabel) part.getModel());
}
this.sendType = sendType;
}
@Override
public void execute() {
savePreviousState();
redo();
}
@Override
public void redo() {
orderSelectedLabels();
int[] zIndexList = getzIndexList(workflowDescription.getWorkflowLabels().size());
switch (sendType) {
case SEND_BACK:
sendSelectedArrayIndicesOneLayerBack(zIndexList);
break;
case SEND_FORWARD:
sendSelectedArrayIndicesOneLayerForward(zIndexList);
break;
case SEND_TO_BACKGROUND:
sendSelectedArrayIndicesToBackground(zIndexList);
break;
case SEND_TO_FOREGROUND:
sendSelectedArrayIndicesToForeground(zIndexList);
default:
break;
}
setNewzIndicesFromIndexList(zIndexList);
workflowDescription.firePropertyChange(WorkflowDescription.PROPERTY_LABEL);
}
@Override
public void undo() {
for (WorkflowLabel label : workflowDescription.getWorkflowLabels()) {
label.setZIndex(previousState.get(label));
}
workflowDescription.firePropertyChange(WorkflowDescription.PROPERTY_LABEL);
}
private void savePreviousState() {
for (WorkflowLabel label : workflowDescription.getWorkflowLabels()) {
previousState.put(label, label.getZIndex());
}
}
private void orderSelectedLabels() {
Collections.sort(selectedLabels, new Comparator<WorkflowLabel>() {
@Override
public int compare(WorkflowLabel arg0, WorkflowLabel arg1) {
if (arg0.getZIndex() < arg1.getZIndex()) {
return MINUS_ONE;
} else if (arg0.getZIndex() > arg1.getZIndex()) {
return 1;
} else {
return 0;
}
}
});
}
private int[] getzIndexList(int size) {
int[] returnList = new int[size];
for (int i = 0; i < size; i++) {
returnList[i] = i;
}
return returnList;
}
private void sendSelectedArrayIndicesOneLayerBack(int[] indexList) {
for (int i = 0; i < selectedLabels.size(); i++) {
if (selectedLabels.get(i).getZIndex() == i) {
continue;
}
int z = selectedLabels.get(i).getZIndex();
int tempZ = indexList[z];
indexList[z] = indexList[z - 1];
indexList[z - 1] = tempZ;
}
}
private void sendSelectedArrayIndicesOneLayerForward(int[] indexList) {
for (int i = selectedLabels.size() - 1; i >= 0; i--) {
WorkflowLabel selectedLabel = selectedLabels.get(i);
int z = selectedLabel.getZIndex();
if (z == workflowDescription.getWorkflowLabels().size() - 1 - (selectedLabels.size() - 1 - i)) {
continue;
}
if (z < workflowDescription.getWorkflowLabels().size() - 1) {
int tempZ = indexList[z];
indexList[z] = indexList[z + 1];
indexList[z + 1] = tempZ;
}
}
}
private void sendSelectedArrayIndicesToBackground(int[] indexList) {
for (int i = 0; i < selectedLabels.size(); i++) {
for (int j = selectedLabels.get(i).getZIndex(); j > i; j--) {
int tempZ = indexList[j];
indexList[j] = indexList[j - 1];
indexList[j - 1] = tempZ;
}
}
}
private void sendSelectedArrayIndicesToForeground(int[] indexList) {
for (int i = selectedLabels.size() - 1; i >= 0; i--) {
for (int j = selectedLabels.get(i).getZIndex(); j < indexList.length - selectedLabels.size() + i; j++) {
int tempZ = indexList[j];
indexList[j] = indexList[j + 1];
indexList[j + 1] = tempZ;
}
}
}
private void setNewzIndicesFromIndexList(int[] indexList) {
Map<WorkflowLabel, Integer> assignMap = new HashMap<>();
for (int i = 0; i < indexList.length; i++) {
for (WorkflowLabel label : workflowDescription.getWorkflowLabels()) {
if (label.getZIndex() == indexList[i]) {
assignMap.put(label, i);
break;
}
}
}
for (WorkflowLabel label : assignMap.keySet()) {
label.setZIndex(assignMap.get(label));
}
}
}