package org.ripple.power.ui.graphics;
import java.util.ArrayList;
import java.util.HashMap;
import org.ripple.power.ui.graphics.geom.RectBox;
import org.ripple.power.timer.LTimer;
public class Cycle extends LObject {
public final static Cycle newSample(int type, float srcWidth,
float srcHeight) {
float width = 1;
float height = 1;
float offset = 0;
int padding = 0;
switch (type) {
case 0:
width = 100;
height = 40;
if (srcWidth < srcHeight) {
offset = 0;
} else {
offset = 8;
}
break;
case 1:
width = 30;
height = 30;
if (srcWidth < srcHeight) {
offset = 0;
} else {
offset = 6;
}
break;
case 2:
width = 80;
height = 80;
offset = 14;
padding = -15;
break;
case 3:
width = 100;
height = 100;
if (srcWidth < srcHeight) {
offset = -4;
}
break;
case 4:
width = 60;
height = 60;
offset = 12;
if (srcWidth < srcHeight) {
padding = -60;
} else {
padding = -80;
}
break;
case 5:
width = 60;
height = 60;
offset = 12;
if (srcWidth < srcHeight) {
padding = -60;
} else {
padding = -80;
}
break;
case 6:
width = 80;
height = 80;
if (srcWidth < srcHeight) {
offset = -2;
padding = -20;
} else {
padding = -30;
}
break;
default:
return null;
}
return Cycle.getSample(type, srcWidth, srcHeight, width, height,
offset, padding);
}
public final static Cycle getSample(int type, float srcWidth,
float srcHeight, float width, float height, float offset,
int padding) {
Cycle cycle = new Cycle();
float s = 1;
if (srcWidth > srcHeight) {
s = Math.max(srcWidth / width, srcHeight / height);
} else {
s = Math.min(srcWidth / width, srcHeight / height);
}
final float scale = s;
switch (type) {
case 0:
cycle.setColor(0xFF7B24);
cycle.setStepsPerFrame(1);
cycle.setTrailLength(1);
cycle.setPointDistance(0.10f);
cycle.setMultiplier(2);
cycle.addPath(Cycle.ARC, 10 * scale, 10 * scale, 10 * scale, -270,
-90);
cycle.addPath(Cycle.BEZIER, 10 * scale, 0 * scale, 40 * scale,
20 * scale, 20 * scale, 0, 30 * scale, 20 * scale);
cycle.addPath(Cycle.ARC, 40 * scale, 10 * scale, 10 * scale, 90,
-90);
cycle.addPath(Cycle.BEZIER, 40 * scale, 0 * scale, 10 * scale,
20 * scale, 30 * scale, 0, 20 * scale, 20 * scale);
break;
case 1:
cycle.setColor(0xD4FF00);
cycle.setStepType(1);
cycle.setDelay(55);
cycle.setStepsPerFrame(2);
cycle.setTrailLength(0.3f);
cycle.setPointDistance(0.1f);
cycle.addPath(Cycle.LINE, 0, 0, 30 * scale, 0);
cycle.addPath(Cycle.LINE, 30 * scale, 0 * scale, 30 * scale,
30 * scale);
cycle.addPath(Cycle.LINE, 30 * scale, 30 * scale, 0, 30 * scale);
cycle.addPath(Cycle.LINE, 0, 30 * scale, 0, 0);
break;
case 2:
cycle.setColor(0xFFA50000);
cycle.setStepsPerFrame(1);
cycle.setTrailLength(1);
cycle.setPointDistance(0.025f);
cycle.addPath(Cycle.ARC, 50 * scale, 50 * scale, 40 * scale, 0, 360);
break;
case 3:
cycle.setColor(0xFF2E82);
cycle.setDelay(60);
cycle.setStepType(1);
cycle.setStepsPerFrame(1);
cycle.setTrailLength(1);
cycle.setPointDistance(0.1f);
cycle.addPath(Cycle.LINE, 0, 20 * scale, 100 * scale, 20 * scale);
cycle.addPath(Cycle.LINE, 100 * scale, 20 * scale, 0, 20 * scale);
break;
case 4:
cycle.setStepsPerFrame(7);
cycle.setTrailLength(0.7f);
cycle.setPointDistance(0.01f);
cycle.setDelay(35);
cycle.addPath(Cycle.LINE, 20 * scale, 70 * scale, 50 * scale,
20 * scale);
cycle.addPath(Cycle.LINE, 50 * scale, 20 * scale, 80 * scale,
70 * scale);
cycle.addPath(Cycle.LINE, 80 * scale, 70 * scale, 20 * scale,
70 * scale);
break;
case 5:
cycle.setColor(0x05E2FF);
cycle.setStepsPerFrame(1);
cycle.setTrailLength(1);
cycle.setPointDistance(0.02f);
cycle.addPath(Cycle.ARC, 50 * scale, 50 * scale, 30 * scale, 0, 360);
break;
case 6:
cycle.setStepType(1);
cycle.setColor(LColor.yellow);
cycle.addPath(Cycle.LINE, 10 * scale, 10 * scale, 90 * scale,
10 * scale);
cycle.addPath(Cycle.LINE, 90 * scale, 10 * scale, 90 * scale,
90 * scale);
cycle.addPath(Cycle.LINE, 90 * scale, 90 * scale, 10 * scale,
90 * scale);
cycle.addPath(Cycle.LINE, 10 * scale, 90 * scale, 10 * scale,
10 * scale);
break;
default:
return null;
}
float size = Math.min(srcWidth / (1 / cycle.getPointDistance()),
srcHeight / (1 / cycle.getPointDistance()));
cycle.setPadding(padding);
cycle.setBlockWidth(size + offset);
cycle.setBlockHeight(size + offset);
cycle.setWidth(width * scale);
cycle.setHeight(height * scale);
return cycle;
}
public static final int OTHER = 0, DIM = 1, DEGREE = 2, RADIUS = 3;
public static final int BEZIER = 0, ARC = 1, LINE = 2;
protected float pointDistance;
protected float multiplier;
protected int frame, padding;
protected int stepType;
protected float trailLength, stepsPerFrame;
protected boolean isUpdate, isVisible, stopped;
protected ArrayList<Object[]> data;
protected static HashMap<Integer, float[]> signatures;
protected ArrayList<Progress> points;
private LTimer timer;
private LColor color;
private Progress last;
protected float alpha;
protected float blockWidth, blockHeight, blockHalfWidth, blockHalfHeight;
protected float width, height;
class Progress {
float x;
float y;
float progress;
public Progress(float x, float y, float p) {
this.x = x;
this.y = y;
this.progress = p;
}
}
public Cycle() {
this(0, 0);
}
public Cycle(int x, int y) {
this(x, y, 6, 6);
}
public Cycle(int x, int y, int w, int h) {
this(null, x, y, w, h);
}
public Cycle(ArrayList<Object[]> path, int x, int y, int w, int h) {
if (path != null) {
data.add(path.toArray());
isUpdate = true;
} else {
data = new ArrayList<Object[]>(10);
}
this.setLocation(x, y);
this.timer = new LTimer(25);
this.color = LColor.white;
this.points = new ArrayList<Progress>();
this.multiplier = 1;
this.pointDistance = 0.05f;
this.padding = 0;
this.stepType = 0;
this.stepsPerFrame = 1;
this.trailLength = 1;
this.alpha = 1;
this.blockWidth = w;
this.blockHeight = h;
this.blockHalfWidth = w / 2;
this.blockHalfHeight = h / 2;
if (signatures == null) {
signatures = new HashMap<Integer, float[]>(3);
signatures.put(ARC, new float[] { 1, 1, 3, 2, 2, 0 });
signatures.put(BEZIER, new float[] { 1, 1, 1, 1, 1, 1, 1, 1 });
signatures.put(LINE, new float[] { 1, 1, 1, 1 });
}
this.setup();
this.isVisible = true;
}
public void play() {
this.stopped = false;
}
public void iterateFrame() {
this.frame += this.stepsPerFrame;
if (this.frame >= this.points.size()) {
this.frame = 0;
}
}
public void stop() {
this.stopped = true;
}
public void setDelay(long delay) {
timer.setDelay(delay);
}
public long getDelay() {
return timer.getDelay();
}
public void addPath(int type, float... f) {
Object[] o = new Object[2];
o[0] = type;
o[1] = f;
data.add(o);
isUpdate = true;
}
private void setup() {
if (!isUpdate) {
return;
}
float[] args;
float value;
int index;
for (Object[] o : data) {
Integer type = (Integer) o[0];
args = (float[]) o[1];
for (int a = -1, al = args.length; ++a < al;) {
index = (int) signatures.get(type)[a];
value = args[a];
switch (index) {
case RADIUS:
value *= this.multiplier;
break;
case DIM:
value *= this.multiplier;
value += this.padding;
break;
case DEGREE:
value *= Math.PI / 180;
break;
}
args[a] = value;
}
callMethod(type, args);
}
this.isUpdate = false;
}
private final void step(LGraphics g, Progress e, int index, int frame,
LColor color, float alpha) {
switch (stepType) {
case 0:
g.fillOval((int) (x() + e.x - blockHalfWidth),
(int) (y() + e.y - blockHalfHeight), (int) blockWidth,
(int) blockHeight);
break;
case 1:
g.fillRect((int) (x() + e.x - blockHalfWidth),
(int) (y() + e.y - blockHalfHeight), (int) blockWidth,
(int) blockHeight);
break;
case 2:
if (last != null) {
int[] xs = { (int) (x() + last.x), (int) (x() + e.x) };
int[] ys = { (int) (y() + last.y), (int) (y() + e.y) };
g.drawPolygon(xs, ys, 2);
}
last = e;
break;
case 3:
if (last != null) {
g.drawLine((int) (x() + last.x), (int) (y() + last.y),
(int) (x() + e.x), (int) (y() + e.y));
}
last = e;
break;
case 4:
step(g, e.x, e.y, e.progress, index, frame, color, alpha);
break;
}
}
public void step(LGraphics g, float x, float y, float progress, int index,
int frame, LColor color, float alpha) {
}
public void update(long elapsedTime) {
if (timer.action(elapsedTime)) {
this.iterateFrame();
}
}
private final void callMethod(int index, float... f) {
float[] result;
for (float pd = this.pointDistance, t = pd; t <= 1; t += pd) {
t = Math.round(t * 1f / pd) / (1f / pd);
switch (index) {
case BEZIER:
result = bezier(t, f[0], f[1], f[2], f[3], f[4], f[5], f[6],
f[7]);
break;
case ARC:
result = arc(t, f[0], f[1], f[2], f[3], f[4]);
break;
case LINE:
result = line(t, f[0], f[1], f[2], f[3]);
break;
default:
result = new float[] { 0f, 0f };
}
points.add(new Progress(result[0], result[1], t));
}
}
private final float[] bezier(float t, float p0x, float p0y, float p1x,
float p1y, float c0x, float c0y, float c1x, float c1y) {
t = 1 - t;
float i = 1 - t, x = t * t, y = i * i, a = x * t, b = 3 * x * i, c = 3
* t * y, d = y * i;
return new float[] { a * p0x + b * c0x + c * c1x + d * p1x,
a * p0y + b * c0y + c * c1y + d * p1y };
}
private final float[] arc(float t, float cx, float cy, float radius,
float start, float end) {
float point = (end - start) * t + start;
return new float[] { (float) ((Math.cos(point) * radius) + cx),
(float) ((Math.sin(point) * radius) + cy) };
}
private final float[] line(float t, float sx, float sy, float ex, float ey) {
return new float[] { (ex - sx) * t + sx, (ey - sy) * t + sy };
}
public void createUI(LGraphics g) {
if (!isVisible) {
return;
}
this.setup();
int pointsLength = points.size();
Progress point;
int index;
int frameD;
int indexD;
float size = (pointsLength * this.trailLength);
for (float i = -1, l = size; ++i < l && !this.stopped;) {
index = (int) (frame + i);
if (index < pointsLength) {
point = points.get(index);
} else {
point = points.get(index - pointsLength);
}
this.alpha = (i / (l - 1));
frameD = frame / (pointsLength - 1);
indexD = (int) alpha;
if (alpha > 0 && alpha < 1) {
g.setAlpha(alpha);
}
g.setColor(color);
step(g, point, indexD, frameD, color, alpha);
g.resetColor();
if (alpha > 0 && alpha < 1) {
g.setAlpha(1);
}
}
}
public float getAlpha() {
return alpha;
}
public void setAlpha(float alpha) {
this.alpha = alpha;
}
public LColor getColor() {
return color;
}
public void setColor(LColor color) {
this.color = color;
}
public void setColor(int pixel) {
this.color = new LColor(pixel);
}
public ArrayList<Object[]> getData() {
return data;
}
public void setData(ArrayList<Object[]> data) {
this.data = data;
}
public int getFrame() {
return frame;
}
public void setFrame(int frame) {
this.frame = frame;
}
public boolean isUpdate() {
return isUpdate;
}
public void setUpdate(boolean isUpdate) {
this.isUpdate = isUpdate;
}
public Progress getLast() {
return last;
}
public void setLast(Progress last) {
this.last = last;
}
public float getMultiplier() {
return multiplier;
}
public void setMultiplier(float multiplier) {
this.multiplier = multiplier;
}
public int getPadding() {
return padding;
}
public void setPadding(int padding) {
this.padding = padding;
}
public float getPointDistance() {
return pointDistance;
}
public void setPointDistance(float pointDistance) {
this.pointDistance = pointDistance;
}
public ArrayList<Progress> getPoints() {
return points;
}
public void setPoints(ArrayList<Progress> points) {
this.points = points;
}
public float getStepsPerFrame() {
return stepsPerFrame;
}
public void setStepsPerFrame(float stepsPerFrame) {
this.stepsPerFrame = stepsPerFrame;
}
public int getStepType() {
return stepType;
}
public void setStepType(int stepType) {
this.stepType = stepType;
}
public boolean isStopped() {
return stopped;
}
public float getTrailLength() {
return trailLength;
}
public void setTrailLength(float trailLength) {
this.trailLength = trailLength;
}
public int getBlockHeight() {
return (int) blockHeight;
}
public void setBlockHeight(float blockHeight) {
this.blockHeight = blockHeight;
this.blockHalfHeight = blockHeight / 2;
}
public int getBlockWidth() {
return (int) blockWidth;
}
public void setBlockWidth(float blockWidth) {
this.blockWidth = blockWidth;
this.blockHalfWidth = blockWidth / 2;
}
public LImage getBitmap() {
return null;
}
public RectBox getCollisionBox() {
return getRect(x(), y(), (int) width, (int) height);
}
public void setWidth(float w) {
this.width = w;
}
public void setHeight(float h) {
this.height = h;
}
public int getWidth() {
return (int) height;
}
public int getHeight() {
return (int) width;
}
public boolean isVisible() {
return isVisible;
}
public void setVisible(boolean visible) {
this.isVisible = visible;
}
}