package org.phenoscape.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.phenoscape.model.Character;
import org.phenoscape.model.DataSet;
import org.phenoscape.model.MultipleState;
import org.phenoscape.model.State;
import org.phenoscape.model.Taxon;
import org.phenoscape.model.MultipleState.MODE;
public class ConsolidationUtil {
public static Character createNewCharacterWithStates(Collection<State> states, Character currentCharacter, DataSet data) {
final Character newCharacter = new Character();
newCharacter.addStates(states);
for (Taxon taxon : data.getTaxa()) {
//FIXME some of this logic should be moved down into the model
final State stateValue = data.getStateForTaxon(taxon, currentCharacter);
if (stateValue instanceof MultipleState) {
final MultipleState multiple = (MultipleState)stateValue;
if (!Collections.disjoint(states, multiple.getStates())) {
final Set<State> statesForOldCharacter = new HashSet<State>(multiple.getStates());
statesForOldCharacter.removeAll(states);
final Set<State> statesForNewCharacter = new HashSet<State>(multiple.getStates());
statesForNewCharacter.retainAll(states);
if (statesForOldCharacter.isEmpty()) {
data.setStateForTaxon(taxon, currentCharacter, null);
} else if (statesForOldCharacter.size() == 1) {
data.setStateForTaxon(taxon, currentCharacter, statesForOldCharacter.iterator().next());
} else {
data.setStateForTaxon(taxon, currentCharacter, new MultipleState(statesForOldCharacter, multiple.getMode()));
}
if (statesForNewCharacter.isEmpty()) {
data.setStateForTaxon(taxon, newCharacter, null);
} else if (statesForNewCharacter.size() == 1) {
data.setStateForTaxon(taxon, newCharacter, statesForNewCharacter.iterator().next());
} else {
data.setStateForTaxon(taxon, newCharacter, new MultipleState(statesForNewCharacter, multiple.getMode()));
}
}
} else {
if (states.contains(stateValue)) {
data.setStateForTaxon(taxon, newCharacter, stateValue);
data.setStateForTaxon(taxon, currentCharacter, null);
}
}
}
currentCharacter.removeStates(states);
data.addCharacter(newCharacter);
return newCharacter;
}
public static State consolidateStates(Collection<State> states, Character currentCharacter, DataSet data) {
final State newState = new State();
final List<String> labels = new ArrayList<String>();
final List<String> comments = new ArrayList<String>();
final List<String> figures = new ArrayList<String>();
for (State state : states) {
labels.add(state.getLabel());
comments.add(state.getComment());
figures.add(state.getFigure());
}
newState.setLabel(StringUtils.stripToNull(org.obo.app.util.Collections.join(labels, "; ")));
newState.setComment(StringUtils.stripToNull(org.obo.app.util.Collections.join(comments, "; ")));
newState.setFigure(StringUtils.stripToNull(org.obo.app.util.Collections.join(figures, "; ")));
for (Taxon taxon : data.getTaxa()) {
//FIXME some of this logic should be moved down into the model
final State stateValue = data.getStateForTaxon(taxon, currentCharacter);
if (stateValue instanceof MultipleState) {
final MultipleState multiple = (MultipleState)stateValue;
if (!Collections.disjoint(states, multiple.getStates())) {
final Set<State> oldStates = new HashSet<State>(multiple.getStates());
oldStates.removeAll(states);
oldStates.add(newState);
if (oldStates.size() > 1) {
data.setStateForTaxon(taxon, currentCharacter, new MultipleState(oldStates, multiple.getMode()));
} else {
data.setStateForTaxon(taxon, currentCharacter, newState);
}
}
} else {
if (states.contains(stateValue)) {
data.setStateForTaxon(taxon, currentCharacter, newState);
}
}
}
currentCharacter.removeStates(states);
currentCharacter.addState(newState);
return newState;
}
public static Character consolidateCharacters(Collection<Character> characters, DataSet data) {
//FIXME some of this logic should be moved down into the model
final Character newCharacter = new Character();
final List<String> labels = new ArrayList<String>();
final List<String> comments = new ArrayList<String>();
final List<String> figures = new ArrayList<String>();
final List<String> discussions = new ArrayList<String>();
for (Character character : characters) {
labels.add(character.getLabel());
comments.add(character.getComment());
figures.add(character.getFigure());
discussions.add(character.getDiscussion());
newCharacter.addStates(character.getStates());
}
newCharacter.setLabel(StringUtils.stripToNull(org.obo.app.util.Collections.join(labels, "; ")));
newCharacter.setComment(StringUtils.stripToNull(org.obo.app.util.Collections.join(comments, "; ")));
newCharacter.setFigure(StringUtils.stripToNull(org.obo.app.util.Collections.join(figures, "; ")));
newCharacter.setDiscussion(StringUtils.stripToNull(org.obo.app.util.Collections.join(discussions, "; ")));
for (Taxon taxon : data.getTaxa()) {
final Set<State> statesForTaxon = new HashSet<State>();
for (Character character : characters) {
final State stateValue = data.getStateForTaxon(taxon, character);
if (stateValue instanceof MultipleState) {
statesForTaxon.addAll(((MultipleState)stateValue).getStates());
} else if (stateValue != null) {
statesForTaxon.add(stateValue);
}
}
final State newStateValue;
if (statesForTaxon.size() > 1) {
newStateValue = new MultipleState(statesForTaxon, MODE.POLYMORPHIC);
} else if (statesForTaxon.size() == 1) {
newStateValue = statesForTaxon.iterator().next();
} else {
newStateValue = null;
}
data.setStateForTaxon(taxon, newCharacter, newStateValue);
}
data.removeCharacters(characters);
int i = 0;
for (State state : newCharacter.getStates()) {
state.setSymbol("" + i);
i += 1;
}
data.addCharacter(newCharacter);
return newCharacter;
}
}