/**
*
*/
package org.xmind.ui.datepicker;
import static java.util.Calendar.MONTH;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.widgets.Display;
public abstract class CalendarAnimation {
protected final IAnimationAdvisor advisor;
private Runnable callback;
protected IFigure newPanel;
protected Dimension oldSize;
protected List<DayFigure> oldDays = new ArrayList<DayFigure>(31);
protected List<DayFigure> newDays = new ArrayList<DayFigure>(31);
protected boolean hasNewPanel;
protected Rectangle oldInitConstraint;
protected Rectangle oldFinalConstraint;
protected Rectangle newInitConstraint;
protected Rectangle newFinalConstraint;
private Rectangle oldConstraint;
private Rectangle newConstraint;
private long start;
public CalendarAnimation(IAnimationAdvisor advisor) {
this.advisor = advisor;
}
public CalendarAnimation callback(Runnable callback) {
this.callback = callback;
return this;
}
public IFigure getNewPanel() {
return newPanel;
}
public void start() {
init();
start = System.currentTimeMillis();
Runnable step = new Runnable() {
public void run() {
int pass = (int) (System.currentTimeMillis() - start);
if (pass > advisor.getDuration()) {
end();
} else {
playback(pass);
Display.getCurrent().asyncExec(this);
}
}
};
Display.getCurrent().asyncExec(step);
}
private void init() {
this.oldSize = advisor.getPanel().getSize();
initOldDays();
newPanel = createNewPanel();
hasNewPanel = newPanel != advisor.getPanel();
if (hasNewPanel) {
advisor.getLayer().add(newPanel);
}
createNewDays();
initConstraint();
}
private void initOldDays() {
List dayFigures = advisor.getPanel().getChildren();
for (int i = 0; i < dayFigures.size(); i++) {
DayFigure dayFigure = (DayFigure) dayFigures.get(i);
advisor.initOldDay(dayFigure);
Calendar date = dayFigure.getDate();
int month = date.get(MONTH);
if (month == advisor.getOldMonth()) {
oldDays.add(dayFigure);
} else if (month == advisor.getNewMonth()) {
oldDayInNewMonth(dayFigure, date, month, i);
}
}
}
protected IFigure createNewPanel() {
return advisor.getPanel();
}
protected abstract void createNewDays();
protected void oldDayInNewMonth(DayFigure dayFigure, Calendar date,
int month, int index) {
}
protected abstract Rectangle createOldInitConstraint();
protected abstract Rectangle createOldFinalConstraint();
protected Rectangle createNewInitConstraint() {
return null;
}
protected Rectangle createNewFinalConstraint() {
return null;
}
private void initConstraint() {
hasNewPanel = newPanel != advisor.getPanel();
oldInitConstraint = createOldInitConstraint();
oldFinalConstraint = createOldFinalConstraint();
newInitConstraint = hasNewPanel ? createNewInitConstraint() : null;
newFinalConstraint = hasNewPanel ? createNewFinalConstraint() : null;
oldConstraint = oldInitConstraint.getCopy();
newConstraint = hasNewPanel ? newInitConstraint.getCopy() : null;
advisor.getLayer().setConstraint(advisor.getPanel(), oldConstraint);
if (hasNewPanel)
advisor.getLayer().setConstraint(newPanel, newConstraint);
}
private void playback(int elapsed) {
int duration = advisor.getDuration();
IFigure layer = advisor.getLayer();
oldConstraint.x = DatePicker.calc(oldInitConstraint.x,
oldFinalConstraint.x, elapsed, duration);
oldConstraint.y = DatePicker.calc(oldInitConstraint.y,
oldFinalConstraint.y, elapsed, duration);
layer.setConstraint(advisor.getPanel(), oldConstraint);
if (hasNewPanel) {
newConstraint.x = DatePicker.calc(newInitConstraint.x,
newFinalConstraint.x, elapsed, duration);
newConstraint.y = DatePicker.calc(newInitConstraint.y,
newFinalConstraint.y, elapsed, duration);
layer.setConstraint(newPanel, newConstraint);
}
for (DayFigure oldDay : oldDays) {
oldDay.setTextAlpha(DatePicker.calc(DatePicker.NORMAL_ALPHA,
DatePicker.SIBLING_MONTH_ALPHA, elapsed, duration));
}
for (DayFigure newDay : newDays) {
newDay.setTextAlpha(DatePicker.calc(DatePicker.SIBLING_MONTH_ALPHA,
DatePicker.NORMAL_ALPHA, elapsed, duration));
}
}
protected void end() {
removeOldDays();
updateNewPanel();
updateJobs();
if (callback != null)
callback.run();
}
protected void removeOldDays() {
}
private void updateNewPanel() {
List dayFigures = newPanel.getChildren();
for (int i = 0; i < dayFigures.size(); i++) {
DayFigure dayFigure = (DayFigure) dayFigures.get(i);
advisor.updateNewDay(dayFigure);
}
newPanel.invalidate();
advisor.getLayer().setConstraint(newPanel, null);
}
protected abstract void updateJobs();
}