package com.baselet.element;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import com.baselet.element.facet.common.GroupFacet;
import com.baselet.element.interfaces.GridElement;
public abstract class Selector {
private void selectHelper(boolean applyAfterAction, Collection<GridElement> elements) {
for (GridElement e : expand(elements)) {
if (!getSelectedElements().contains(e)) {
getSelectedElements().add(e);
doAfterSelect(e);
}
}
if (applyAfterAction) {
doAfterSelectionChanged();
}
}
private void deselectHelper(boolean applyAfterAction, Collection<GridElement> elements) {
for (GridElement e : expand(elements)) {
Iterator<GridElement> iter = getSelectedElements().iterator();
while (iter.hasNext()) {
if (iter.next().equals(e)) {
iter.remove();
doAfterDeselect(e);
}
}
}
if (applyAfterAction) {
doAfterSelectionChanged();
}
}
private List<GridElement> expand(Collection<GridElement> elements) {
Map<Integer, Collection<GridElement>> map = Selector.createGroupElementMap(getAllElements());
List<GridElement> elemenentsWithGroups = new ArrayList<GridElement>();
// add grouped elements BEFORE the really selected elements, to make sure the last element stays the same (because its content will be shown in the property panel)
for (GridElement e : elements) {
if (e.getGroup() != null) {
Collection<GridElement> set = map.get(e.getGroup());
if (set != null) { // TODO set can be null in standalone version because getAllElements is empty (eg if grouped elements are selected when diagram is closed)
for (GridElement g : set) {
if (g != e) {
elemenentsWithGroups.add(g);
}
}
}
}
}
elemenentsWithGroups.addAll(elements);
return elemenentsWithGroups;
}
public void select(GridElement element) {
select(Arrays.asList(element));
}
public void deselect(GridElement element) {
deselect(Arrays.asList(element));
}
public abstract List<GridElement> getSelectedElements();
public boolean isSelected(GridElement ge) {
return getSelectedElements().contains(ge);
}
public boolean isSelectedOnly(GridElement ge) {
return getSelectedElements().size() == 1 && isSelected(ge);
}
public void selectOnly(GridElement element) {
selectOnly(Arrays.asList(element));
}
public void selectOnly(Collection<GridElement> elements) {
deselectHelper(false, getSelectedElements());
selectHelper(true, elements);
}
public void select(Collection<GridElement> elements) {
selectHelper(true, elements);
}
public void deselect(Collection<GridElement> elements) {
deselectHelper(true, elements);
}
public void deselectAll() {
deselect(getSelectedElements());
}
public void deselectAllWithoutAfterAction() {
deselectHelper(false, getSelectedElements());
}
public void doAfterDeselect(GridElement e) {
e.getComponent().afterModelUpdate();
}
public void doAfterSelectionChanged() {
// hook method
}
public void doAfterSelect(GridElement e) {
e.getComponent().afterModelUpdate();
}
public void moveToLastPosInList(GridElement element) {
List<GridElement> elements = getSelectedElements();
elements.remove(element);
elements.add(element);
}
public Integer getUnusedGroup() {
return getUnusedGroupId(createGroupElementMap(getAllElements()).keySet());
}
public abstract List<GridElement> getAllElements();
public static void replaceGroupsWithNewGroups(Collection<GridElement> elements, Selector selector) {
Set<Integer> usedIds = new HashSet<Integer>(createGroupElementMap(selector.getAllElements()).keySet());
Map<Integer, Collection<GridElement>> groupedElements = createGroupElementMap(elements);
for (Entry<Integer, Collection<GridElement>> entry : groupedElements.entrySet()) {
Integer unusedId = getUnusedGroupId(usedIds);
usedIds.add(unusedId);
for (GridElement e : entry.getValue()) {
e.setProperty(GroupFacet.KEY, unusedId);
}
}
}
public static Integer getUnusedGroupId(Collection<Integer> usedGroups) {
Integer newGroup;
if (usedGroups.isEmpty()) {
newGroup = 1;
}
else {
newGroup = Collections.max(usedGroups) + 1;
}
return newGroup;
}
public static Map<Integer, Collection<GridElement>> createGroupElementMap(Collection<GridElement> elements) {
Map<Integer, Collection<GridElement>> returnmap = new HashMap<Integer, Collection<GridElement>>();
for (GridElement e : elements) {
if (e.getGroup() != null) {
Collection<GridElement> elementsWithGroup = returnmap.get(e.getGroup());
if (elementsWithGroup == null) {
elementsWithGroup = new ArrayList<GridElement>();
returnmap.put(e.getGroup(), elementsWithGroup);
}
elementsWithGroup.add(e);
}
}
return returnmap;
}
}