package com.github.czyzby.autumn.mvc.component.ui.controller.impl;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.scenes.scene2d.ui.Dialog;
import com.badlogic.gdx.scenes.scene2d.ui.Window;
import com.github.czyzby.autumn.mvc.component.ui.InterfaceService;
import com.github.czyzby.autumn.mvc.component.ui.controller.ViewDialogController;
import com.github.czyzby.autumn.mvc.component.ui.controller.ViewDialogShower;
import com.github.czyzby.autumn.mvc.stereotype.ViewDialog;
import com.github.czyzby.kiwi.util.common.Strings;
import com.github.czyzby.lml.parser.LmlParser;
import com.github.czyzby.lml.parser.action.ActionContainer;
import com.github.czyzby.lml.util.LmlUserObject;
import com.github.czyzby.lml.util.LmlUtilities;
/** Wraps around an object annotated with {@link com.github.czyzby.autumn.mvc.stereotype.ViewDialog}.
*
* @author MJ */
public class AnnotatedViewDialogController extends AbstractAnnotatedController implements ViewDialogController {
private final ViewDialog dialogData;
private final InterfaceService interfaceService;
private final ViewDialogShower shower;
private final ActionContainer actionContainer;
private final String id;
private Window dialog;
public AnnotatedViewDialogController(final ViewDialog dialogData, final Object wrappedObject,
final InterfaceService interfaceService) {
super(wrappedObject);
this.dialogData = dialogData;
this.interfaceService = interfaceService;
shower = wrappedObject instanceof ViewDialogShower ? (ViewDialogShower) wrappedObject : null;
actionContainer = wrappedObject instanceof ActionContainer ? (ActionContainer) wrappedObject : null;
id = Strings.isWhitespace(dialogData.id()) ? wrappedObject.getClass().getSimpleName() : dialogData.id();
}
@Override
public void show(final Stage stage) {
injectStage(stage);
if (dialog == null || !isCachingInstance()) {
prepareDialogInstance();
}
doBeforeShow();
showDialog(stage);
}
private void showDialog(final Stage stage) {
final LmlUserObject userObject = LmlUtilities.getOptionalLmlUserObject(dialog);
if (userObject != null && userObject.getStageAttacher() != null) {
userObject.getStageAttacher().attachToStage(dialog, stage);
} else if (dialog instanceof Dialog) {
((Dialog) dialog).show(stage);
} else {
// Simplified copy of Dialog#show:
stage.addActor(dialog);
dialog.setPosition(Math.round((stage.getWidth() - dialog.getWidth()) / 2f),
Math.round((stage.getHeight() - dialog.getHeight()) / 2f));
dialog.addAction(Actions.sequence(Actions.alpha(0), Actions.fadeIn(0.4f, Interpolation.fade)));
}
}
private void doBeforeShow() {
if (shower != null) {
shower.doBeforeShow(dialog);
}
}
/** @return true if an instance of the dialog is currently initiated and available. */
public boolean isInitiated() {
return dialog != null;
}
/** @return true if dialog actor instance is cached and reused on each showing. */
public boolean isCachingInstance() {
return dialogData.cacheInstance();
}
/** Creates instance of the managed dialog actor. */
public void prepareDialogInstance() {
final LmlParser parser = interfaceService.getParser();
if (actionContainer != null) {
parser.getData().addActionContainer(getId(), actionContainer);
}
dialog = (Window) parser.createView(wrappedObject, Gdx.files.internal(dialogData.value())).first();
if (actionContainer != null) {
parser.getData().removeActionContainer(getId());
}
}
@Override
public void destroyDialog() {
if (dialog != null) {
if (dialog.getStage() != null) {
if (dialog instanceof Dialog) {
((Dialog) dialog).hide();
} else {
// Simplified version of Dialog#hide:
dialog.addAction(
Actions.sequence(Actions.fadeOut(0.4f, Interpolation.fade), Actions.removeActor()));
}
}
dialog = null;
}
}
@Override
public String getId() {
return id;
}
}