package com.peterhi.ui.newbars;
import java.text.MessageFormat;
import java.util.concurrent.TimeUnit;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.jdesktop.core.animation.timing.Animator;
import org.jdesktop.core.animation.timing.Animator.Builder;
import org.jdesktop.core.animation.timing.TimingTarget;
import org.jdesktop.core.animation.timing.TimingTargetAdapter;
import org.jdesktop.core.animation.timing.interpolators.AccelerationInterpolator;
class StripItemContext {
private final StripItem owner;
private StripItemState state;
private RGB foreground;
private RGB background;
private Animator backgroundAnimator;
private Animator offsetAnimator;
private int offset;
public StripItemContext(StripItem owner) {
this.owner = owner;
this.state = StripItemState.DEFAULT;
}
public StripItem getOwner() {
return owner;
}
public StripItemState getState() {
return state;
}
public void setState(final StripItemState value, boolean animate) {
if (value == null) {
throw new NullPointerException();
}
if (state == value) {
return;
}
if (!checkTransition(state, value)) {
return;
}
foreground = value.getForeground();
if (animate) {
if (backgroundAnimator != null) {
backgroundAnimator.cancel();
backgroundAnimator = null;
}
TimingTarget timingTarget = new TimingTargetAdapter() {
private final RGB from = getBackground();
private final RGB to = value.getBackground();
@Override
public void timingEvent(Animator source, double fraction) {
double doubleRed = to.red - from.red;
double doubleGreen = to.green - from.green;
double doubleBlue = to.blue - from.blue;
doubleRed = from.red + doubleRed * fraction;
doubleGreen = from.green + doubleGreen * fraction;
doubleBlue = from.blue + doubleBlue * fraction;
int intRed = (int )Math.round(doubleRed);
int intGreen = (int )Math.round(doubleGreen);
int intBlue = (int )Math.round(doubleBlue);
background = new RGB(intRed, intGreen, intBlue);
repaint();
}
@Override
public void end(Animator source) {
background = new RGB(to.red, to.green, to.blue);
repaint();
}
};
Builder builder = new Builder();
builder.addTarget(timingTarget);
builder.setInterpolator(new AccelerationInterpolator(0, 0.9));
builder.setDuration(160, TimeUnit.MILLISECONDS);
backgroundAnimator = builder.build();
backgroundAnimator.start();
} else {
background = value.getBackground();
repaint();
}
state = value;
}
public RGB getForeground() {
if (foreground == null) {
return owner.getState().getForeground();
}
return foreground;
}
public RGB getBackground() {
if (background == null) {
return owner.getState().getBackground();
}
return background;
}
public int getOffset() {
return offset;
}
public void setOffset(final int value, boolean animate, final Runnable end) {
if (offset == value) {
return;
}
if (animate) {
if (offsetAnimator != null) {
offsetAnimator.cancel();
offsetAnimator = null;
}
TimingTarget timingTarget = new TimingTargetAdapter() {
private final int from = offset;
private final int to = value;
@Override
public void timingEvent(Animator source, double fraction) {
double doubleValue = to - from;
doubleValue = from + doubleValue * fraction;
int intValue = (int )Math.round(doubleValue);
repaint(offset, intValue);
offset = intValue;
}
@Override
public void end(Animator source) {
repaint(offset, to);
offset = to;
if (end != null) {
end.run();
}
}
};
Builder builder = new Builder();
builder.addTarget(timingTarget);
builder.setInterpolator(new AccelerationInterpolator(0, 0.9));
builder.setDuration(250, TimeUnit.MILLISECONDS);
offsetAnimator = builder.build();
offsetAnimator.start();
} else {
repaint(offset, value);
offset = value;
}
}
public Animator getOffsetAnimator() {
return offsetAnimator;
}
public void setOffsetAnimator(Animator value) {
offsetAnimator = value;
}
private boolean checkTransition(StripItemState from, StripItemState to) {
if (from == null || to == null) {
throw new NullPointerException();
}
if (from == to) {
return false;
}
if (from == StripItemState.DEFAULT && to == StripItemState.FOCUSED) {
return true;
}
if (from == StripItemState.DEFAULT && to == StripItemState.PRESSED) {
return true;
}
if (from == StripItemState.FOCUSED && to == StripItemState.DEFAULT) {
return true;
}
if (from == StripItemState.FOCUSED && to == StripItemState.PRESSED) {
return true;
}
if (from == StripItemState.PRESSED && to == StripItemState.SELECTED) {
return true;
}
if (from == StripItemState.PRESSED && to == StripItemState.FOCUSED) {
return true;
}
if (from == StripItemState.PRESSED && to == StripItemState.DRAGGED) {
return true;
}
if (from == StripItemState.SELECTED && to == StripItemState.PRESSED) {
return true;
}
if (from == StripItemState.SELECTED && to == StripItemState.DEFAULT) {
return true;
}
if (from == StripItemState.DRAGGED && to == StripItemState.SELECTED) {
return true;
}
if (from == StripItemState.DRAGGED && to == StripItemState.DEFAULT) {
return true;
}
throw new IllegalStateException(MessageFormat.format("Illegal state transition ({0} ==> {1}).", from, to));
}
private void repaint() {
repaint(offset, offset);
}
private void repaint(int oldOffset, int newOffset) {
Rectangle bounds = owner.getBounds();
if (oldOffset != newOffset) {
owner.getParent().redraw(bounds.x + oldOffset, bounds.y, bounds.width, bounds.height, true);
}
owner.getParent().redraw(bounds.x + newOffset, bounds.y, bounds.width, bounds.height, true);
}
}