package nl.uva.softwcons.qls.ui.style;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import nl.uva.softwcons.ql.ast.expression.identifier.Identifier;
import nl.uva.softwcons.ql.ast.form.Form;
import nl.uva.softwcons.ql.ast.type.Type;
import nl.uva.softwcons.qls.ast.segment.Page;
import nl.uva.softwcons.qls.ast.segment.Question;
import nl.uva.softwcons.qls.ast.segment.Section;
import nl.uva.softwcons.qls.ast.segment.SegmentValueVisitor;
import nl.uva.softwcons.qls.ast.stylesheet.Stylesheet;
import nl.uva.softwcons.qls.ast.stylesheet.StylesheetVisitor;
import nl.uva.softwcons.qls.ast.widgetstyle.StyledWidget;
import nl.uva.softwcons.qls.ast.widgetstyle.type.WidgetType;
import nl.uva.softwcons.qls.util.QuestionTypeCollector;
public class StylesheetResolver implements StylesheetVisitor<Void>, SegmentValueVisitor<Void, DefaultStylesMerged> {
private final Map<Identifier, WidgetType> questionWidgetType;
private final Map<Identifier, StyleBlock> questionStyle;
private final QuestionTypeCollector questionType;
public StylesheetResolver(final Stylesheet stylesheet, final Form form) {
this.questionStyle = new HashMap<>();
this.questionWidgetType = new HashMap<>();
this.questionType = new QuestionTypeCollector(form);
stylesheet.accept(this);
}
public Optional<WidgetType> getWidgetType(final Identifier id) {
return Optional.ofNullable(questionWidgetType.get(id));
}
public StyleBlock getStyle(final Identifier id) {
return questionStyle.get(id);
}
@Override
public Void visit(final Stylesheet stylesheet) {
stylesheet.getPages().forEach(page -> {
page.accept(this, new DefaultStylesMerged());
});
return null;
}
@Override
public Void visit(final Page page, final DefaultStylesMerged styles) {
page.getSegments().forEach(c -> {
c.accept(this, inheritStyles(page.getStyles(), styles));
});
return null;
}
@Override
public Void visit(final Question question, final DefaultStylesMerged styles) {
final StyleBlock styleScope = new StyleBlock(question.getStyledWidget().getWidgetStyle());
final Optional<WidgetType> widget = question.getStyledWidget().getWidgetType();
final Type type = questionType.get(question.getId());
final Identifier questionId = question.getId();
if (widget.isPresent()) {
questionWidgetType.put(questionId, widget.get());
questionStyle.put(questionId, styleScope.inherit(styles.getStyle(type)));
} else if (styles.contains(type)) {
questionWidgetType.put(questionId, styles.getWidget(type));
questionStyle.put(questionId, styles.getStyle(type));
}
return null;
}
@Override
public Void visit(final Section section, final DefaultStylesMerged styles) {
section.getContent().forEach(c -> {
c.accept(this, inheritStyles(section.getStyles(), styles));
});
return null;
}
private DefaultStylesMerged inheritStyles(final Map<Type, StyledWidget> styles,
final DefaultStylesMerged parentStyles) {
final DefaultStylesMerged mergedStyles = new DefaultStylesMerged(styles);
mergedStyles.applyParentStyles(parentStyles);
return mergedStyles;
}
}