/*
* JAME 6.2.1
* http://jame.sourceforge.net
*
* Copyright 2001, 2016 Andrea Medeghini
*
* This file is part of JAME.
*
* JAME is an application for creating fractals and other graphics artifacts.
*
* JAME 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.
*
* JAME 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 JAME. If not, see <http://www.gnu.org/licenses/>.
*
*/
package net.sf.jame.contextfree.renderer.support;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CFContext {
private ArrayList<ShapeType> shapeTypes = new ArrayList<ShapeType>();
private ArrayList<CFRule> rules = new ArrayList<CFRule>();
private CFColor background = new CFColor(0, 0, 1, 1);
private float offsetX;
private float offsetY;
private float tileX;
private float tileY;
private float sizeX;
private float sizeY;
private boolean sized;
private boolean tiled;
private int loopStartShapeType;
private int loopEndShapeType;
public CFContext() {
loopStartShapeType = encodeShapeName("~~LOOPSTART~~");
loopEndShapeType = encodeShapeName("~~LOOPEND~~");
}
public CFColor getBackground() {
return background;
}
public void setBackground(CFColor background) {
this.background = background;
}
public void addRule(CFRule rule) {
if (rule.getInitialShapeType() < shapeTypes.size()) {
rules.add(rule);
int type = rule.hasPath() ? ShapeType.TYPE_PATH : ShapeType.TYPE_RULE;
shapeTypes.get(rule.getInitialShapeType()).setHasRules(true);
shapeTypes.get(rule.getInitialShapeType()).setType(type);
}
}
public CFRule findRule(int shapeType, double random) {
if (random >= 0 && random <= 1) {
CFRuleSpecifier rs = new CFRuleSpecifier(shapeType, random);
CFRule rule = lowerBound(rules, 0, rules.size() - 1, rs);
return rule;
} else {
return null;
}
}
private CFRule lowerBound(List<CFRule> list, int begin, int end, CFRuleSpecifier element) {
if (begin == end) {
CFRule rule = rules.get(begin);
if (element.getInitialShapeType() == rule.getInitialShapeType()) {
return rule;
} else {
return null;
}
}
int mid = (begin + end) / 2;
CFRule rule = rules.get(mid);
if (rule.compareTo(element) > 0) {
return lowerBound(rules, begin, mid, element);
} else {
return lowerBound(rules, mid + 1, end, element);
}
}
public void reloadRules() {
double[] unitweightsums = new double[shapeTypes.size()];
double[] weightsums = new double[shapeTypes.size()];
int[] rulescount = new int[shapeTypes.size()];
for (int i = 0; i < rules.size(); i++) {
CFRule rule = rules.get(i);
weightsums[rule.getInitialShapeType()] += rule.getWeight();
rulescount[rule.getInitialShapeType()] += 1;
}
for (int i = 0; i < rules.size(); i++) {
CFRule rule = rules.get(i);
double weight = rule.getWeight() / weightsums[rule.getInitialShapeType()];
unitweightsums[rule.getInitialShapeType()] += weight;
rulescount[rule.getInitialShapeType()] -= 1;
if (rulescount[rule.getInitialShapeType()] != 0) {
rule.setWeight(unitweightsums[rule.getInitialShapeType()]);
} else {
rule.setWeight(1);
}
}
Collections.sort(rules);
}
public int getRuleCount() {
return rules.size();
}
public boolean isSized() {
return sized;
}
public boolean isTiled() {
return tiled;
}
public void setTiled(AffineTransform tileTransform, float tileX, float tileY, boolean useTile, boolean useSize) {
this.offsetX = (float) tileTransform.getTranslateX();
this.offsetY = (float) tileTransform.getTranslateY();
this.sizeX = (float) tileTransform.getScaleX();
this.sizeY = (float) tileTransform.getScaleY();
this.tileX = tileX;
this.tileY = tileY;
tiled = useTile;
sized = useSize;
}
public float getTileX() {
return tileX;
}
public float getTileY() {
return tileY;
}
public float getSizeX() {
return sizeX;
}
public float getSizeY() {
return sizeY;
}
public float getOffsetX() {
return offsetX;
}
public float getOffsetY() {
return offsetY;
}
public String decodeShapeName(int shapeType) {
if (shapeType < shapeTypes.size()) {
return shapeTypes.get(shapeType).getName();
}
return "Unnamed shape";
}
public int encodeShapeName(String name) {
for (int i = 0; i < shapeTypes.size(); i++) {
if (name.equals(shapeTypes.get(i).getName())) {
return i;
}
}
shapeTypes.add(new ShapeType(name));
return shapeTypes.size() - 1;
}
public int getShapeType(String name) {
for (int i = 0; i < shapeTypes.size(); i++) {
if (name.equals(shapeTypes.get(i).getName())) {
return shapeTypes.get(i).getType();
}
}
return ShapeType.TYPE_NEW;
}
public int getShapeType(int shapeType) {
if (shapeType < shapeTypes.size()) {
return shapeTypes.get(shapeType).getType();
}
return ShapeType.TYPE_NEW;
}
public boolean shapeHasRule(int shapeType) {
if (shapeType < shapeTypes.size()) {
return shapeTypes.get(shapeType).hasRules();
}
return false;
}
public ShapeType shapeType(int shapeType) {
if (shapeType < shapeTypes.size()) {
return shapeTypes.get(shapeType);
}
return null;
}
public int getLoopStartShapeType() {
return loopStartShapeType;
}
public int getLoopEndShapeType() {
return loopEndShapeType;
}
}