package org.fugazi.ql.gui; import org.fugazi.ql.ast.form.Form; import org.fugazi.ql.ast.form.form_data.QLFormDataStorage; import org.fugazi.ql.ast.statement.ComputedQuestion; import org.fugazi.ql.ast.statement.IfStatement; import org.fugazi.ql.ast.statement.Question; import org.fugazi.ql.evaluator.ValueStorage; import org.fugazi.ql.evaluator.expression_value.ExpressionValue; import org.fugazi.ql.gui.mediator.Colleague; import org.fugazi.ql.gui.mediator.IMediator; import org.fugazi.ql.gui.ui_element.ui_questions.UIComputedQuestion; import org.fugazi.ql.gui.ui_element.ui_questions.UIQuestion; import org.fugazi.ql.gui.ui_element.visitors.UIQuestionBuilder; import org.fugazi.ql.gui.widgets.WidgetsFactory; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; public class GUIBuilder implements IMediator { protected class QuestionsWithConditions extends LinkedHashMap<UIQuestion, List<IfStatement>> {} private final ValueStorage valueStorage; private final GUIEvaluator guiEvaluator; private final UIQuestionBuilder uiQuestionBuilder; protected final UIFormManager uiFormManager; protected QuestionsWithConditions questionsWithConditions = new QuestionsWithConditions(); private List<ComputedQuestion> computedQuestions = new ArrayList<>(); public GUIBuilder( Form _form, WidgetsFactory _widgetFactory, UIFormManager _uiFormManager) { this.valueStorage = new ValueStorage(); this.guiEvaluator = new GUIEvaluator(valueStorage); this.uiFormManager = _uiFormManager; this.uiQuestionBuilder = new UIQuestionBuilder(this, valueStorage, _widgetFactory); QLFormDataStorage formDataStorage = new QLFormDataStorage(_form); this.questionsWithConditions = this.createQuestionsWithConditions(formDataStorage); this.computedQuestions = formDataStorage.getComputedQuestions(); } @Override public void getChangeFromColleagues(Colleague _origin) { this.storeValue(_origin.getId(), _origin.getState()); this.checkComputedQuestions(this.computedQuestions); this.renderUI(); } public void renderUI() { this.updateForm(this.questionsWithConditions); this.uiFormManager.render(); } protected void updateForm(Map<UIQuestion, List<IfStatement>> _questionsWithConditionState) { for (UIQuestion uiQuestion : _questionsWithConditionState.keySet()) { if (this.isQuestionStateTrue(_questionsWithConditionState, uiQuestion)) { this.uiFormManager.addQuestion(uiQuestion); } else { this.uiFormManager.removeQuestion(uiQuestion); } } } private void checkComputedQuestions(List<ComputedQuestion> _computedQuestions) { for (ComputedQuestion computedQuestion : _computedQuestions) { this.updateComputedQuestion(computedQuestion); } } private QuestionsWithConditions createQuestionsWithConditions(QLFormDataStorage _formDataStorage) { QuestionsWithConditions questionsWithCondition = new QuestionsWithConditions(); // for idempotence. for (Question question : _formDataStorage.getAllQuestions()) { UIQuestion uiQuestion = this.createUiQuestion(question); this.storeValue(uiQuestion.getId(), uiQuestion.getState()); questionsWithCondition.put(uiQuestion, new ArrayList<>()); this.addIfStatementsToQuestion( _formDataStorage.getIfStatements(), question, questionsWithCondition); } return questionsWithCondition; } /** * ====================== * Helper Functions. * ====================== */ private void addIfStatementsToQuestion( List<IfStatement> _ifStatementsList, Question _question, QuestionsWithConditions _questionsWithConditions) { for (IfStatement ifStatement : _ifStatementsList) { if (ifStatement.getBody().contains(_question)) { UIQuestion uiQuestion = this.getUIQuestionById(_question.getIdName(), _questionsWithConditions); _questionsWithConditions.get(uiQuestion).add(ifStatement); } } } protected void updateComputedQuestion(ComputedQuestion _computedQuestion) { ExpressionValue result = this.guiEvaluator.evaluateComputedExpression(_computedQuestion); UIComputedQuestion uiComputedQuestion = (UIComputedQuestion) this.getUIQuestionById( _computedQuestion.getIdName(), this.questionsWithConditions); uiComputedQuestion.setComputedValue(result); } protected UIQuestion getUIQuestionById( String _id, QuestionsWithConditions _questionsWithConditions) { for (UIQuestion uiQuestion : _questionsWithConditions.keySet()) { if (_id.equals(uiQuestion.getId())) { return uiQuestion; } } return null; } protected boolean isQuestionStateTrue( Map<UIQuestion, List<IfStatement>> _questionsWithConditionState, UIQuestion _question) { boolean isTrue = true; for (IfStatement ifStatement : _questionsWithConditionState.get(_question)) { if (!this.guiEvaluator.evaluateIfStatement(ifStatement)) { isTrue = false; } } return isTrue; } protected void storeValue(String _id, ExpressionValue _value) { this.valueStorage.saveValue(_id, _value); } protected UIQuestion createUiQuestion(Question _question) { return _question.accept(this.uiQuestionBuilder); } }