/*
* funCKit - functional Circuit Kit
* Copyright (C) 2013 Lukas Elsner <open@mindrunner.de>
* Copyright (C) 2013 Peter Dahlberg <catdog2@tuxzone.org>
* Copyright (C) 2013 Julian Stier <mail@julian-stier.de>
* Copyright (C) 2013 Sebastian Vetter <mail@b4sti.eu>
* Copyright (C) 2013 Thomas Poxrucker <poxrucker_t@web.de>
* Copyright (C) 2013 Alexander Treml <alex.treml@directbox.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.sep2011.funckit.drawer;
import de.sep2011.funckit.drawer.action.ActionComposite;
import de.sep2011.funckit.drawer.action.ActiveAction;
import de.sep2011.funckit.drawer.action.ColorizeAction;
import de.sep2011.funckit.drawer.action.DebugAction;
import de.sep2011.funckit.drawer.action.DrawAction;
import de.sep2011.funckit.drawer.action.ErrorAction;
import de.sep2011.funckit.drawer.action.FancyShapeAction;
import de.sep2011.funckit.drawer.action.GhostAction;
import de.sep2011.funckit.drawer.action.InfoAction;
import de.sep2011.funckit.drawer.action.QueueAction;
import de.sep2011.funckit.drawer.action.SelectedAction;
import de.sep2011.funckit.drawer.action.SimpleShapeAction;
import de.sep2011.funckit.drawer.action.SimulationAction;
import de.sep2011.funckit.drawer.action.TextDelayAction;
import de.sep2011.funckit.drawer.action.TextInputLabelAction;
import de.sep2011.funckit.drawer.action.TextNameAction;
import de.sep2011.funckit.drawer.action.TextOutputLabelAction;
import de.sep2011.funckit.util.Log;
import java.util.LinkedHashMap;
import java.util.Map;
public class DecisionTable {
/**
* This map is the actual decision table, that gets created statically, so
* we have to initialize it just once (performance). In this map each {@link
* ElementState} is associated with a {@link DrawAction}, that is used to
* build a ready layout object for the {@link Element}, which is mapped by
* its <code>ElementState</code> to it.
*/
private static final Map<ElementState, DrawAction> decisionTable = new LinkedHashMap<ElementState, DrawAction>();
static {
/*
* Default action to add to all fancy drawings. Do NOT (NOT!) add any
* actions to this ActionComposite during constructing the decision
* table as this would modify the SAME object, that is used for all
* states using this default action!
*/
ActionComposite defaultAction = new ActionComposite()
.addAction(new FancyShapeAction())
.addAction(new ColorizeAction())
.addAction(new TextNameAction())
.addAction(new TextInputLabelAction());
ActionComposite additionalInfoAction = new ActionComposite()
.addAction(new TextDelayAction())
.addAction(new TextOutputLabelAction());
/* FancyDrawer: Normal */
ElementState e1 = addModeAction(ElementState.Mode.NORMAL, defaultAction, additionalInfoAction);
/* FancyDrawer: Normal & has info */
ElementState e1info = e1.clone().setHasInfo();
add(e1info, defaultAction, additionalInfoAction, new InfoAction());
/* FancyDrawer: Normal & has error */
ElementState e1error = e1.clone().setHasError(true);
add(e1error, defaultAction, additionalInfoAction, new ErrorAction());
/* FancyDrawer: Normal & is active */
ElementState e1active = e1.clone().setActive();
add(e1active, defaultAction, additionalInfoAction, new ActiveAction());
/* FancyDrawer: Normal & has info & has error */
ElementState e1infoError = e1info.clone().setHasError(true);
add(e1infoError, defaultAction, additionalInfoAction, new ErrorAction());
/* FancyDrawer: Normal & has info & is active */
ElementState e1infoActive = e1info.clone().setActive();
add(e1infoActive, defaultAction, additionalInfoAction, new InfoAction());
/* FancyDrawer: Normal & has error & is active */
ElementState e1errorActive = e1error.clone().setActive();
add(e1errorActive, defaultAction, additionalInfoAction, new ErrorAction());
/* FancyDrawer: Normal & simulated */
ElementState e1simulated = e1.clone().setSimulated(true);
add(e1simulated, defaultAction, additionalInfoAction, new SimulationAction());
/* FancyDrawer: Normal & simulated & active */
ElementState e1simulatedActive = e1simulated.clone().setActive();
add(e1simulatedActive, defaultAction, new SimulationAction(),
new QueueAction());
/* FancyDrawer: Selected */
ElementState e2 = addModeAction(
ElementState.Mode.SELECTED,
defaultAction,
additionalInfoAction,
new SelectedAction());
/* FancyDrawer: Selected & active */
ElementState e2active = e2.clone().setActive();
add(e2active, defaultAction, additionalInfoAction, new SelectedAction());
/* FancyDrawer: Selected & has error */
ElementState e2error = e2.clone().setHasError(true);
add(e2error, defaultAction, additionalInfoAction, new SelectedAction());
/* FancyDrawer: Selected & simulated */
ElementState e2simulated = e2.clone().setSimulated(true);
add(e2simulated, defaultAction, additionalInfoAction, new SimulationAction());
/* FancyDrawer: Selected & has error & active */
ElementState e2errorActive = e2error.clone().setActive();
add(e2errorActive, defaultAction, additionalInfoAction, new SelectedAction(),
new ErrorAction());
/* FancyDrawer: Selected & simulated & active */
ElementState e2simulatedActive = e2simulated.clone().setActive();
add(e2simulatedActive, defaultAction, new ActiveAction(), new SimulationAction(),
new QueueAction());
/* FancyDrawer: Ghost */
ElementState e3 = addModeAction(
ElementState.Mode.GHOST,
defaultAction,
additionalInfoAction,
new GhostAction());
/* FancyDrawer: Ghost & simulated */
ElementState e3ghostSimulated = e3.clone();
e3ghostSimulated.setSimulated(true);
add(e3ghostSimulated, defaultAction, additionalInfoAction, new GhostAction());
/* FancyDrawer: Ghost & error */
ElementState e3ghostError = e3.clone().setHasError(true);
add(e3ghostError, defaultAction, additionalInfoAction, new GhostAction(), new ErrorAction());
/* FancyDrawer: Ghost & error & simulated */
ElementState e3ghostErrorSimulated = e3ghostSimulated.clone()
.setHasError(true);
add(e3ghostErrorSimulated, defaultAction, additionalInfoAction, new GhostAction(),
new ErrorAction());
/*
* Default action to add to all simple drawings.
*/
defaultAction = new ActionComposite()
.addAction(new SimpleShapeAction())
.addAction(new ColorizeAction())
.addAction(new TextNameAction());
additionalInfoAction = new ActionComposite();
/* SimpleDrawer: Normal */
ElementState s1 = e1.clone().setSimple();
add(s1, defaultAction, additionalInfoAction);
/* SimpleDrawer: Normal & has info */
ElementState s1info = s1.clone().setHasInfo();
add(s1info, defaultAction, additionalInfoAction, new InfoAction());
/* SimpleDrawer: Normal & has error */
ElementState s1error = s1.clone().setHasError(true);
add(s1error, defaultAction, additionalInfoAction, new ErrorAction());
/* SimpleDrawer: Normal & is active */
ElementState s1active = s1.clone().setActive();
add(s1active, defaultAction, additionalInfoAction, new ActiveAction());
/* SimpleDrawer: Normal & has info & has error */
ElementState s1infoError = s1info.clone().setHasError(true);
add(s1infoError, defaultAction, additionalInfoAction, new ErrorAction());
/* SimpleDrawer: Normal & has info & is active */
ElementState s1infoActive = s1info.clone().setActive();
add(s1infoActive, defaultAction, additionalInfoAction, new InfoAction());
/* SimpleDrawer: Normal & has error & is active */
ElementState s1errorActive = s1error.clone().setActive();
add(s1errorActive, defaultAction, additionalInfoAction, new ErrorAction());
/* SimpleDrawer: Normal & simulated */
ElementState s1simulated = s1.clone().setSimulated(true);
add(s1simulated, defaultAction, additionalInfoAction, new SimulationAction());
/* SimpleDrawer: Normal & simulated & active */
ElementState s1simulatedActive = s1simulated.clone().setActive();
add(s1simulatedActive, defaultAction, additionalInfoAction, new ActiveAction(), new SimulationAction());
/* SimpleDrawer: Selected */
ElementState s2 = e2.clone().setSimple();
add(s2, defaultAction, additionalInfoAction, new SelectedAction());
/* SimpleDrawer: Selected & active */
ElementState s2active = s2.clone().setActive();
add(s2active, defaultAction, additionalInfoAction, new SelectedAction(),
new SimulationAction());
/* SimpleDrawer: Selected & simulated */
ElementState s2simulated = s2.clone().setSimulated(true);
add(s2simulated, defaultAction, additionalInfoAction, new SimulationAction());
/* SimpleDrawer: Selected & simulated & active */
ElementState s2simulatedActive = s2simulated.clone().setActive();
add(s2simulatedActive, defaultAction, additionalInfoAction, new ActiveAction(), new SimulationAction());
/* SimpleDrawer: Ghost */
ElementState s3 = e3.clone().setSimple();
add(s3, defaultAction, additionalInfoAction, new GhostAction());
/* SimpleDrawer: Ghost & simulated */
ElementState s3ghostSimulated = s3.clone().setSimulated(true);
add(s3ghostSimulated, additionalInfoAction, defaultAction, new GhostAction());
/* SimpleDrawer: Ghost & error */
ElementState s3ghostError = s3.clone().setHasError(true);
add(s3ghostError, defaultAction, additionalInfoAction, new GhostAction(), new ErrorAction());
/* SimpleDrawer: Ghost & error & simulated */
ElementState s3ghostErrorSimulated = s3ghostSimulated.clone()
.setHasError(true);
add(s3ghostErrorSimulated, additionalInfoAction, defaultAction, new GhostAction(),
new ErrorAction());
}
private static ElementState addModeAction(ElementState.Mode mode, DrawAction... actions) {
ElementState elementState = new ElementState();
elementState.setMode(mode);
ActionComposite action = new ActionComposite();
for (int i = 0, num = actions.length; i < num; i++) {
action.addAction(actions[i]);
}
decisionTable.put(elementState, action);
return elementState.clone();
}
private static void add(ElementState state, DrawAction... actions) {
ActionComposite c = new ActionComposite();
for (int i = 0, num = actions.length; i < num; i++) {
c.addAction(actions[i]);
}
decisionTable.put(state, c);
}
/**
* Returns a distinct {@link DrawAction} from our statically created
* decision table by using a given {@link ElementState} to identify it
* (distinct path in decision table / map).
*
* @param state Identifies state of element to resolve a {@link
* DrawAction}.
* @return The resolved DrawAction.
*/
public static DrawAction resolve(ElementState state) {
DrawAction action = decisionTable.get(state);
if (action == null) {
Log.gl().error(
"Undefined action in decision table for ElementState "
+ state);
action = new ActionComposite().addAction(new FancyShapeAction())
.addAction(new DebugAction());
}
return action;
}
}