package com.baselet.element.facet.specific;
import java.util.Arrays;
import java.util.List;
import com.baselet.control.SharedUtils;
import com.baselet.control.basics.geom.PointDouble;
import com.baselet.control.basics.geom.Rectangle;
import com.baselet.control.enums.AlignHorizontal;
import com.baselet.control.enums.LineType;
import com.baselet.diagram.draw.DrawHandler;
import com.baselet.diagram.draw.helper.ColorOwn;
import com.baselet.diagram.draw.helper.Style;
import com.baselet.diagram.draw.helper.StyleException;
import com.baselet.element.facet.FirstRunKeyValueFacet;
import com.baselet.element.facet.PropertiesParserState;
import com.baselet.element.sticking.polygon.PointDoubleStickingPolygonGenerator;
import com.baselet.element.sticking.polygon.SimpleStickingPolygonGenerator;
/**
* must be in first run, because the execution of Class.drawCommonContent() depends on the result of this facet
*/
public class TemplateClassFacet extends FirstRunKeyValueFacet {
public static final TemplateClassFacet INSTANCE = new TemplateClassFacet();
private TemplateClassFacet() {}
public static final int UPPER_SPACE = 3;
public static final int LOWER_SPACE = 3;
public static final int LEFT_SPACE = 12;
@Override
public KeyValue getKeyValue() {
return new KeyValue("template", new ValueInfo("text", "print template rectangle on top right corner"));
}
@Override
public void handleValue(String value, PropertiesParserState state) {
// only act after parsing
}
private static int round(double val) {
return SharedUtils.realignToGrid(false, val, true);
}
@Override
public void parsingFinished(PropertiesParserState state, List<String> handledLines) {
DrawHandler drawer = state.getDrawer();
int height = state.getGridElementSize().getHeight();
int width = state.getGridElementSize().getWidth();
if (handledLines.isEmpty()) {
drawer.drawRectangle(0, 0, width, height);
state.setStickingPolygonGenerator(SimpleStickingPolygonGenerator.INSTANCE);
}
else if (handledLines.size() == 1) {
List<PointDouble> points = TemplateClassFacet.drawTemplateClass(extractValue(handledLines.get(0)), drawer, state, height, width);
state.setStickingPolygonGenerator(new PointDoubleStickingPolygonGenerator(points));
}
else {
throw new StyleException("Only one class template is allowed");
}
}
private static List<PointDouble> drawTemplateClass(String templateClassText, DrawHandler drawer, PropertiesParserState state, int height, int width) {
Rectangle tR = calcTemplateRect(templateClassText, drawer, width);
int classTopEnd = round(tR.getHeight() / 2.0);
int classWidth = width - round(tR.getWidth() / 2.0);
PointDouble start = new PointDouble(0, classTopEnd);
List<PointDouble> p = Arrays.asList(
start,
new PointDouble(tR.getX(), classTopEnd),
new PointDouble(tR.getX(), 0),
new PointDouble(width, 0),
new PointDouble(width, tR.getHeight()),
new PointDouble(classWidth, tR.getHeight()),
new PointDouble(classWidth, height),
new PointDouble(0, height),
start);
// SET BUFFERS FOR REDUCED CLASS BORDER
state.getBuffer().setTopMin(tR.getHeight());
state.getBuffer().addToRight(width - classWidth);
// DRAW BACKGROUND RECT
Style style = drawer.getStyleClone();
drawer.setForegroundColor(ColorOwn.TRANSPARENT);
drawer.drawLines(p);
drawer.setStyle(style); // reset style to state before manipulations
// DRAW RIGHT RECT
drawer.setLineType(LineType.DASHED);
drawer.setBackgroundColor(ColorOwn.TRANSPARENT);
drawer.drawRectangle(tR);
drawer.setStyle(style); // reset style to state before manipulations
// DRAW PARTIAL CLASS BORDER
drawer.drawLines(p.get(1), p.get(0), p.get(7), p.get(6), p.get(5));
// DRAW TEMPLATE TEXT
drawer.print(templateClassText, width - drawer.getDistanceBorderToText(), tR.getHeight() - LOWER_SPACE, AlignHorizontal.RIGHT);
return p;
}
private static Rectangle calcTemplateRect(String templateClassText, DrawHandler drawer, int width) {
double templateHeight = drawer.textHeightMax() + UPPER_SPACE + LOWER_SPACE;
double templateWidth = drawer.textWidth(templateClassText) + LEFT_SPACE;
Rectangle tR = new Rectangle(width - templateWidth, 0.0, templateWidth, templateHeight);
return tR;
}
}