package de.urszeidler.shr5.ecp.editor.pages.generator;
import java.math.BigDecimal;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.util.EObjectValidator;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.wb.swt.ResourceManager;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import de.urszeidler.eclipse.shr5.AbstraktPersona;
import de.urszeidler.eclipse.shr5.Credstick;
import de.urszeidler.eclipse.shr5.CredstickTransaction;
import de.urszeidler.eclipse.shr5.Lifestyle;
import de.urszeidler.eclipse.shr5.PersonaFertigkeit;
import de.urszeidler.eclipse.shr5.PersonaFertigkeitsGruppe;
import de.urszeidler.eclipse.shr5.Shr5Factory;
import de.urszeidler.eclipse.shr5.Spezies;
import de.urszeidler.eclipse.shr5.util.ShadowrunTools;
import de.urszeidler.eclipse.shr5Management.Changes;
import de.urszeidler.eclipse.shr5Management.CharacterDiary;
import de.urszeidler.eclipse.shr5Management.CharacterGenerator;
import de.urszeidler.eclipse.shr5Management.CharacterGeneratorSystem;
import de.urszeidler.eclipse.shr5Management.GeneratorState;
import de.urszeidler.eclipse.shr5Management.KarmaGenerator;
import de.urszeidler.eclipse.shr5Management.LifestyleToStartMoney;
import de.urszeidler.eclipse.shr5Management.ManagedCharacter;
import de.urszeidler.eclipse.shr5Management.PersonaChange;
import de.urszeidler.eclipse.shr5Management.PlayerCharacter;
import de.urszeidler.eclipse.shr5Management.Shr5RuleGenerator;
import de.urszeidler.eclipse.shr5Management.Shr5System;
import de.urszeidler.eclipse.shr5Management.Shr5managementFactory;
import de.urszeidler.eclipse.shr5Management.Shr5managementPackage;
import de.urszeidler.eclipse.shr5Management.util.ShadowrunManagmentTools;
import de.urszeidler.emf.commons.ui.util.EmfFormBuilder.ReferenceManager;
import de.urszeidler.shr5.ecp.Activator;
import de.urszeidler.shr5.ecp.editor.pages.AbstractShr5Page;
import de.urszeidler.shr5.ecp.editor.pages.Messages;
import de.urszeidler.shr5.ecp.editor.pages.PrintPreviewPage;
import de.urszeidler.shr5.ecp.editor.pages.character.AbstraktPersonaPage;
import de.urszeidler.shr5.ecp.editor.pages.character.CharacterAdvancementPage;
import de.urszeidler.shr5.ecp.editor.pages.character.ManagedCharacterPage;
import de.urszeidler.shr5.ecp.printer.PersonaPrinter;
import de.urszeidler.shr5.ecp.service.ValidationService;
import de.urszeidler.shr5.ecp.util.ShadowrunEditingTools;
import de.urszeidler.shr5.gameplay.dice.IniDice;
/**
* The basic page for the generators.
*
* @author urs
*/
public abstract class AbstractGeneratorPage extends AbstractShr5Page<CharacterGenerator<?>> implements Adapter {
public static final String PERSONA_PRINTER = "persona.printer"; //$NON-NLS-1$
public static final String PERSONA_ADVANCEMENT = "persona.advancement"; //$NON-NLS-1$
public static final String PERSONA_INVENTAR = "persona.inventar"; //$NON-NLS-1$
public static final String PERSONA = "persona"; //$NON-NLS-1$
public static final String COMMITED = "character-commited";//$NON-NLS-1$
private Image decoratorImage = ResourceManager.getPluginImage("de.urszeidler.shr5.ecp", "images/stcksync_ov.gif"); //$NON-NLS-1$ //$NON-NLS-2$
protected Map<Object, Object> context;
protected ValidationService validationService;
protected IPreferenceStore store;
private boolean validating;
public AbstractGeneratorPage(String id, String title) {
super(id, title);
}
public AbstractGeneratorPage(FormEditor editor, String id, String title) {
super(editor, id, title);
}
public AbstractGeneratorPage(FormEditor editor, String id, String title, ReferenceManager manager) {
super(editor, id, title, manager);
}
/**
* Update the given decorator with the given text when the feature is in the set.
*
* @param newSet
* @param featureID
* @param decoration
* @param textToShow
*/
protected void updateDecorator(Set<Integer> newSet, Object featureID, ControlDecoration decoration, String textToShow) {
if (decoration.getControl().isDisposed())
return;
if (newSet.contains(featureID)) {
decoration.setDescriptionText(textToShow);
decoration.setImage(decoratorImage);
decoration.setShowHover(true);
// decoration.showHoverText(textToShow);
} else if (decoration.getImage() != null) {
decoration.setDescriptionText(""); //$NON-NLS-1$
// decoration.setImage(null);
}
}
/**
* Validates the changes and update the gui.
*/
protected abstract void validateChange();
public Notifier getTarget() {
return null;
}
public boolean isAdapterForType(Object type) {
return false;
}
/**
* Handles the events from the generator.
*/
public void notifyChanged(Notification notification) {
Object feature = notification.getFeature();
if (feature == null)
return;
if (Shr5managementPackage.Literals.CHARACTER_GENERATOR__STATE.equals(feature))
return;
if (Shr5managementPackage.Literals.CHARACTER_GENERATOR__CURRENT_INSTRUCTION.equals(feature))
return;
if (Shr5managementPackage.Literals.CHARACTER_GENERATOR__CHARACTER.equals(feature))
return;
if (!notificationIsRequierd(notification))
return;
if (validating)
return;
validating = true;
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
validateChange();
validating = false;
}
});
// validateChange();
// validating = false;
}
protected abstract boolean notificationIsRequierd(Notification notification);
@Override
public void setTarget(Notifier newTarget) {
}
@Override
public void initialize(FormEditor editor) {
super.initialize(editor);
if (editor.getSite() != null) {
validationService = (ValidationService)editor.getSite().getService(ValidationService.class);
store = Activator.getDefault().getPreferenceStore();
}
}
/**
* Create the managed character.
*
* @param selectableType the type of the persona
* @param spezies the spezies to set to the persona
* @param createPlayer thre for a player character
* @param object the generator
* @return
*/
protected ManagedCharacter createManagedCharacter(EClass selectableType, Spezies spezies, boolean createPlayer, CharacterGenerator<?> object) {
ManagedCharacter playerCharacter;
if (createPlayer) {
playerCharacter = Shr5managementFactory.eINSTANCE.createPlayerCharacter();
CharacterDiary diary = Shr5managementFactory.eINSTANCE.createCharacterDiary();
((PlayerCharacter)playerCharacter).setDiary(diary);
} else
playerCharacter = Shr5managementFactory.eINSTANCE.createNonPlayerCharacter();
int edge = 0;// metaType.getSpecialPoints();
AbstraktPersona persona = ShadowrunTools.createPersona(spezies, selectableType, edge);
playerCharacter.setPersona(persona);
persona.setName(object.getCharacterName());
object.setState(GeneratorState.PERSONA_CREATED);
object.getSelectedGroup().getMembers().add(playerCharacter);
object.setCharacter(playerCharacter);
return playerCharacter;
}
/**
* Clears the character from the generator.
*/
protected void resetCharacter(CharacterGenerator<?> object) {
boolean openConfirm = MessageDialog.openConfirm(getSite().getShell(), Messages.AbstractGeneratorPage_dlg_reset_titel,
Messages.AbstractGeneratorPage_dlg_reset_message);
if (!openConfirm)
return;
if (object.getSelectedGroup() != null)
object.getSelectedGroup().getMembers().remove(object.getCharacter());
ManagedCharacter character = object.getCharacter();
if (character != null)
character.setChracterSource(null);
object.setCharacter(null);
object.setState(GeneratorState.NEW);
EcoreUtil.delete(character);
removePages();
validateChange();
}
protected void addPersonaPage(ManagedCharacter playerCharacter) {
try {
removePages();
CharacterGenerator<?> chracterSource = playerCharacter.getChracterSource();
if (chracterSource instanceof KarmaGenerator) {
this.getEditor().addPage(
1,
new AbstraktPersonaPage(this.getEditor(), PERSONA, Messages.ShadowrunEditor_page_persona, playerCharacter,
getEditingDomain(), mananger));
} else {
this.getEditor().addPage(
1,
new AbstraktPersonaPage(this.getEditor(), PERSONA, Messages.ShadowrunEditor_page_persona, playerCharacter.getPersona(),
getEditingDomain(), mananger));
}
this.getEditor().addPage(
2,
new ManagedCharacterPage(this.getEditor(), PERSONA_INVENTAR, Messages.ShadowrunEditor_page_character, playerCharacter,
getEditingDomain(), mananger));
this.getEditor().addPage(
3,
new CharacterAdvancementPage(this.getEditor(), PERSONA_ADVANCEMENT, Messages.ShadowrunEditor_page_advacement, playerCharacter,
getEditingDomain(), mananger));
this.getEditor().addPage(
4,
new PrintPreviewPage(this.getEditor(), PERSONA_PRINTER, Messages.ShadowrunEditor_page_character_sheet, PersonaPrinter
.getInstance().createPrintFactory(playerCharacter)));
} catch (PartInitException e1) {
e1.printStackTrace();
};
}
/**
*
*/
private void removePages() {
if (this.getEditor().findPage(PERSONA_PRINTER) != null)
this.getEditor().removePage(4);
if (this.getEditor().findPage(PERSONA_ADVANCEMENT) != null)
this.getEditor().removePage(3);
if (this.getEditor().findPage(PERSONA_INVENTAR) != null)
this.getEditor().removePage(2);
if (this.getEditor().findPage(PERSONA) != null)
this.getEditor().removePage(1);
}
protected void updateGeneratorState(Diagnostic diagnostic, CharacterGenerator<?> generator) {
if (EObjectValidator.DIAGNOSTIC_SOURCE.equals(diagnostic.getSource())) {
if (diagnostic.getCode() == EObjectValidator.EOBJECT__EVERY_MULTIPCITY_CONFORMS) {
Object object2 = diagnostic.getData().get(1);
if (Shr5managementPackage.Literals.CHARACTER_GENERATOR__SELECTED_GROUP.equals(object2)) {
generator.setState(GeneratorState.NEW);
} else if (Shr5managementPackage.Literals.CHARACTER_GENERATOR__CHARACTER.equals(object2))
generator.setState(GeneratorState.READY_FOR_CREATION);
}
}
}
/**
* Creates the lifestyle to money dialog.
*
* @param calcResourcesLeft
* @param lifestyleToMoney
* @return
*/
protected InputDialog createLifestyle2MoneyDialog(final int calcResourcesLeft, LifestyleToStartMoney lifestyleToMoney) {
final int numberOfW = lifestyleToMoney.getNumberOfW();
final int moneyFactor = lifestyleToMoney.getMoneyFactor();
IniDice iniDice = new IniDice();
int ini = iniDice.ini(0, numberOfW);
int money = moneyFactor * ini;
int m = money + calcResourcesLeft;
String dialogMessage = String.format(Messages.AbstractGeneratorPage_dlg_lifestyle_message, numberOfW, moneyFactor, calcResourcesLeft);
IInputValidator validator = new IInputValidator() {
@Override
public String isValid(String newText) {
try {
int max = calcResourcesLeft + (6 * numberOfW * moneyFactor);
int value = Integer.parseInt(newText);
if (value > max)
return String.format(Messages.AbstractGeneratorPage_dlg_lifestyle_to_much, value, max);
if (value < 0)
return Messages.AbstractGeneratorPage_dlg_lifestyle_less;
} catch (Exception e) {
return String.format(Messages.AbstractGeneratorPage_dlg_lifestyle_no_number, newText);
}
return null;
}
};
InputDialog inputDialog = new InputDialog(getSite().getShell(), Messages.AbstractGeneratorPage_dlg_lifestyle_titel, dialogMessage,
m + "", validator); //$NON-NLS-1$
return inputDialog;
}
protected boolean openDefaultCommitMessageDialog() {
boolean openConfirm = MessageDialog.openConfirm(getSite().getShell(), Messages.AbstractGeneratorPage_dlg_commit_titel,
Messages.AbstractGeneratorPage_dlg_commit_message);
return openConfirm;
}
/**
* @param calcResourcesLeft
* @param startMoney
* @return
*/
protected int lifeStyleToStartMoneyDialog(final int calcResourcesLeft, int startMoney, Shr5RuleGenerator<? extends Shr5System> object2) {
Credstick credstick = ShadowrunManagmentTools.findFirstCedstick(object2.getCharacter().getInventar());
Lifestyle choosenLifestyle = object2.getCharacter().getChoosenLifestyle();
Shr5System shr5System = object2.getGenerator();
EList<LifestyleToStartMoney> lifestyleToStartMoney = shr5System.getLifestyleToStartMoney();
LifestyleToStartMoney lifestyleToMoney = ShadowrunEditingTools.getLifestyleToMoney(choosenLifestyle, lifestyleToStartMoney);
if (lifestyleToMoney != null) {
InputDialog inputDialog = createLifestyle2MoneyDialog(calcResourcesLeft, lifestyleToMoney);
int open = inputDialog.open();
if (open != InputDialog.OK)
return -1;
String value = inputDialog.getValue();
startMoney = Integer.parseInt(value);
if (credstick != null) {
CredstickTransaction transaction = Shr5Factory.eINSTANCE.createCredstickTransaction();
transaction.setAmount(new BigDecimal(startMoney));
transaction.setDescription(String.format(Messages.Shr5GeneratorPage_initial_transaction_message0, startMoney));
credstick.getTransactionlog().add(transaction);
}
}
return startMoney;
}
/**
* @param object2 the generator object to move
*/
protected void moveGeneratorToCharacterCommit(CharacterGenerator<? extends CharacterGeneratorSystem> object2) {
cleanCharacterBeforeCommit(object2.getCharacter());
CompoundCommand command = new CompoundCommand();
command.append(SetCommand.create(getEditingDomain(), object2, Shr5managementPackage.Literals.CHARACTER_GENERATOR__STATE,
GeneratorState.COMMITED));
command.append(SetCommand.create(getEditingDomain(), object2.getCharacter(), Shr5managementPackage.Literals.MANAGED_CHARACTER__GENERATOR_SRC,
object2));
getEditingDomain().getCommandStack().execute(command);
}
/**
* Remove all unnessesary editing fragments.
*
* @param character
*/
protected void cleanCharacterBeforeCommit(ManagedCharacter character) {
if(character==null)
return;
EList<Changes> changes = character.getChanges();
ImmutableList<PersonaChange> list = FluentIterable.from(character.getChanges()).filter(new Predicate<Changes>() {
@Override
public boolean apply(Changes input) {
return input.getDateApplied()!=null;
}
}).filter(PersonaChange.class)
.filter(new Predicate<PersonaChange>() {
@Override
public boolean apply(PersonaChange input) {
return input.getTo()<=input.getFrom();
}
}).toList();
changes.removeAll(list);
AbstraktPersona ap = character.getPersona();
if(ap!=null){
EList<PersonaFertigkeitsGruppe> fertigkeitsGruppen = ap.getFertigkeitsGruppen();
ImmutableList<PersonaFertigkeitsGruppe> list2 = FluentIterable.from(ap.getFertigkeitsGruppen()).filter(new Predicate<PersonaFertigkeitsGruppe>() {
@Override
public boolean apply(PersonaFertigkeitsGruppe input) {
return input.getStufe()==0;
}
}).toList();
fertigkeitsGruppen.removeAll(list2);
EList<PersonaFertigkeit> fertigkeiten = ap.getFertigkeiten();
ImmutableList<PersonaFertigkeit> list3 = FluentIterable.from(ap.getFertigkeiten()).filter(new Predicate<PersonaFertigkeit>() {
@Override
public boolean apply(PersonaFertigkeit input) {
return input.getStufe()==0;
}
}).toList();
fertigkeiten.removeAll(list3);
}
}
}