package org.jblooming.agenda;
import org.jblooming.utilities.DateUtilities;
import java.util.Date;
import java.util.Locale;
/**
* @author Roberto Bicchierai rbicchierai@open-lab.com
* Date: 28-set-2005 : 9.54.16
*/
public class Scale {
public int fieldToLoop = CompanyCalendar.MONTH;
public int fieldIncrement = 1;
public ScaleType scaleName = null;
public String tickLabelDateFormat = "MMM";
public String tickLabelDateFormatCompact="MM";
public String superTickLabelScaleFormat = "yyyy";
public long millisInPeriod = 0;
public long startPointTime = new Date().getTime();
public long endPointTime = new Date().getTime();
public Date startPointDate = new Date();
public Date endPointDate = new Date();
private CompanyCalendar calS;
private CompanyCalendar calE;
public long millisInTick;
public enum ScaleType {
SCALE_1HOUR,SCALE_3HOUR, SCALE_6HOUR,SCALE_12HOUR, SCALE_1DAY, SCALE_1WEEK, SCALE_2WEEK, SCALE_1MONTH, SCALE_3MONTH, SCALE_1YEAR, SCALE_2YEAR,SCALE_5YEAR}
/**
* Private method use getScaleAndSynch
*
* @param scaleDescription
* @param fieldToLoop
* @param fieldIncrement
* @param tickLabelDateFormat
* @param tickLabelDateFormatCompact
* @param superTickLabelScaleFormat
* @param millisInPeriod
* @param locale
*/
private Scale(ScaleType scaleDescription, int fieldToLoop, int fieldIncrement, String tickLabelDateFormat, String tickLabelDateFormatCompact, String superTickLabelScaleFormat, long millisInPeriod, Locale locale) {
this.calE = new CompanyCalendar(locale);
this.calS = new CompanyCalendar(locale);
this.fieldToLoop = fieldToLoop;
this.fieldIncrement = fieldIncrement;
this.tickLabelDateFormat = tickLabelDateFormat;
this.superTickLabelScaleFormat = superTickLabelScaleFormat;
this.scaleName = scaleDescription;
this.millisInPeriod = millisInPeriod;
}
/**
* @param scaleLevel is the level require
* @param currentTimeInMillis is the current time
* @param synchExtremes if true set the extremes to the beginning and ending millisedond for the period.
* @param locale
* @return the scale
* e.g: in month scale if the
* current millis is the day 4 of may, if synchExtremes=true return start=1 may end=31 may. If currentTimeInMillis=false return start=19 april end=19 may
*/
public static Scale getScaleAndSynch(ScaleType scaleLevel, long currentTimeInMillis, boolean synchExtremes, Locale locale) {
Scale scale = getInstance(scaleLevel, locale);
scale.resynch(currentTimeInMillis, synchExtremes);
return scale;
}
public static Scale getScaleAndSynch(long min, long max, boolean synchExtremes, Locale locale) {
long currentTimeInMillis = (max + min) / 2;
Scale scale = getInstance(max - min, locale);
scale.resynch(currentTimeInMillis, synchExtremes);
// controllare che se l'intervallo ci sta in teoria, ci stia anche dopo la sincronizzazione
return scale;
}
public static ScaleType getNextScale(ScaleType scale) {
return getNextScale(scale, null);
}
public static ScaleType getNextScale(ScaleType scale, ScaleType maxScale) {
int pos = scale.ordinal();
int posm = ScaleType.values().length-1;
if (maxScale != null)
posm = maxScale.ordinal();
return ScaleType.values()[(pos < posm ? pos+1 :posm)];
}
public static ScaleType getPrevScale(ScaleType scale) {
return getPrevScale(scale, null);
}
public static ScaleType getPrevScale(ScaleType scale, ScaleType minScale) {
int pos = scale.ordinal();
int posm = 0;
if (minScale != null)
posm = minScale.ordinal();
return ScaleType.values()[(pos > posm ? pos - 1 : posm)];
}
// ------------------------------------------------- PRIVATE MOTHODS -------------------------------------------------
private static Scale getInstance(ScaleType scaleLevel, Locale locale) {
Scale scale = null;
if (ScaleType.SCALE_1HOUR.equals(scaleLevel)) scale = new Scale(ScaleType.SCALE_1HOUR, CompanyCalendar.MINUTE, 5, "mm", "mm", "HH:mm", CompanyCalendar.MILLIS_IN_HOUR, locale);
else if (ScaleType.SCALE_3HOUR.equals(scaleLevel)) scale = new Scale(ScaleType.SCALE_3HOUR, CompanyCalendar.MINUTE, 15, "HH:mm", "HH:mm", "EEEE dd MMMM yyyy", CompanyCalendar.MILLIS_IN_3_HOUR, locale);
else if (ScaleType.SCALE_6HOUR.equals(scaleLevel)) scale = new Scale(ScaleType.SCALE_6HOUR, CompanyCalendar.MINUTE, 30, "HH:mm", "HH", "EEEE dd MMMM yyyy", CompanyCalendar.MILLIS_IN_6_HOUR, locale);
else if (ScaleType.SCALE_12HOUR.equals(scaleLevel)) scale = new Scale(ScaleType.SCALE_12HOUR, CompanyCalendar.HOUR_OF_DAY, 1, "HH:mm", "HH", "EEEE dd MMMM yyyy", CompanyCalendar.MILLIS_IN_12_HOUR, locale);
else if (ScaleType.SCALE_1DAY.equals(scaleLevel)) scale = new Scale(ScaleType.SCALE_1DAY, CompanyCalendar.HOUR_OF_DAY, 2, "HH:mm", "HH", "EEEE dd MMMM yyyy", CompanyCalendar.MILLIS_IN_DAY, locale);
else if (ScaleType.SCALE_1WEEK.equals(scaleLevel)) scale = new Scale(ScaleType.SCALE_1WEEK, CompanyCalendar.DAY_OF_WEEK, 1, "EEE dd", "E dd", "MMMM yyyy", CompanyCalendar.MILLIS_IN_WEEK, locale);
else if (ScaleType.SCALE_2WEEK.equals(scaleLevel)) scale = new Scale(ScaleType.SCALE_2WEEK, CompanyCalendar.DAY_OF_WEEK, 1, "dd", "dd", "MMMM yyyy", CompanyCalendar.MILLIS_IN_2_WEEK, locale);
else if (ScaleType.SCALE_1MONTH.equals(scaleLevel)) scale = new Scale(ScaleType.SCALE_1MONTH, CompanyCalendar.DAY_OF_MONTH, 1, "dd", "dd", "MMMM yyyy", CompanyCalendar.MILLIS_IN_MONTH, locale);
else if (ScaleType.SCALE_3MONTH.equals(scaleLevel)) scale = new Scale(ScaleType.SCALE_3MONTH, CompanyCalendar.WEEK_OF_MONTH, 1, "dd MMM", "dd MM", "yyyy", CompanyCalendar.MILLIS_IN_3_MONTH, locale);
else if (ScaleType.SCALE_1YEAR.equals(scaleLevel)) scale = new Scale(ScaleType.SCALE_1YEAR, CompanyCalendar.MONTH, 1, "MMM yyyy", "MM", "yyyy", CompanyCalendar.MILLIS_IN_YEAR, locale);
else if (ScaleType.SCALE_2YEAR.equals(scaleLevel)) scale = new Scale(ScaleType.SCALE_2YEAR, CompanyCalendar.MONTH, 1, "MM yyyy", "MM", "yyyy", CompanyCalendar.MILLIS_IN_2_YEAR, locale);
else scale = new Scale(ScaleType.SCALE_5YEAR, CompanyCalendar.YEAR, 1, "MM yyyy", "MM", "yyyy", CompanyCalendar.MILLIS_IN_5_YEAR, locale); //(ScaleType.SCALE_2YEAR.equals(scaleLevel))
return scale;
}
private static Scale getInstance(long scaleLevel, Locale locale) {
Scale scale = null;
if (scaleLevel <= CompanyCalendar.MILLIS_IN_HOUR) scale = getInstance(ScaleType.SCALE_1HOUR, locale);
else if (scaleLevel <= CompanyCalendar.MILLIS_IN_3_HOUR) scale = getInstance(ScaleType.SCALE_3HOUR, locale);
else if (scaleLevel <= CompanyCalendar.MILLIS_IN_6_HOUR) scale = getInstance(ScaleType.SCALE_6HOUR, locale);
else if (scaleLevel <= CompanyCalendar.MILLIS_IN_12_HOUR) scale = getInstance(ScaleType.SCALE_12HOUR, locale);
else if (scaleLevel <= CompanyCalendar.MILLIS_IN_DAY) scale = getInstance(ScaleType.SCALE_1DAY, locale);
else if (scaleLevel <= CompanyCalendar.MILLIS_IN_WEEK) scale = getInstance(ScaleType.SCALE_1WEEK, locale);
else if (scaleLevel <= CompanyCalendar.MILLIS_IN_2_WEEK) scale = getInstance(ScaleType.SCALE_2WEEK, locale);
else if (scaleLevel <= CompanyCalendar.MILLIS_IN_MONTH) scale = getInstance(ScaleType.SCALE_1MONTH, locale);
else if (scaleLevel <= CompanyCalendar.MILLIS_IN_3_MONTH) scale = getInstance(ScaleType.SCALE_3MONTH, locale);
else if (scaleLevel <= CompanyCalendar.MILLIS_IN_YEAR) scale = getInstance(ScaleType.SCALE_1YEAR, locale);
else if (scaleLevel <= (CompanyCalendar.MILLIS_IN_YEAR *2 )) scale = getInstance(ScaleType.SCALE_2YEAR, locale);
else scale = getInstance(ScaleType.SCALE_5YEAR, locale);
return scale;
}
public long getMillisInTick() {
if (ScaleType.SCALE_1HOUR.equals(this.scaleName))
return CompanyCalendar.MILLIS_IN_MINUTE*this.fieldIncrement;
else if (ScaleType.SCALE_3HOUR.equals(this.scaleName))
return CompanyCalendar.MILLIS_IN_MINUTE*this.fieldIncrement;
else if (ScaleType.SCALE_6HOUR.equals(this.scaleName))
return CompanyCalendar.MILLIS_IN_MINUTE*this.fieldIncrement;
else if (ScaleType.SCALE_12HOUR.equals(this.scaleName))
return CompanyCalendar.MILLIS_IN_12_HOUR*this.fieldIncrement;
else if (ScaleType.SCALE_1DAY.equals(this.scaleName))
return CompanyCalendar.MILLIS_IN_12_HOUR*this.fieldIncrement;
else if (ScaleType.SCALE_1WEEK.equals(this.scaleName))
return CompanyCalendar.MILLIS_IN_DAY*this.fieldIncrement;
else if (ScaleType.SCALE_2WEEK.equals(this.scaleName))
return CompanyCalendar.MILLIS_IN_DAY*this.fieldIncrement;
else if (ScaleType.SCALE_1MONTH.equals(this.scaleName))
return CompanyCalendar.MILLIS_IN_DAY*this.fieldIncrement;
else if (ScaleType.SCALE_3MONTH.equals(this.scaleName))
return CompanyCalendar.MILLIS_IN_WEEK*this.fieldIncrement;
else if (ScaleType.SCALE_1YEAR.equals(this.scaleName))
return CompanyCalendar.MILLIS_IN_MONTH*this.fieldIncrement;
else if (ScaleType.SCALE_2YEAR.equals(this.scaleName))
return CompanyCalendar.MILLIS_IN_MONTH*this.fieldIncrement;
else
return CompanyCalendar.MILLIS_IN_MONTH*this.fieldIncrement;
}
private void resynch(long millis, boolean synchExtremes) {
if (synchExtremes)
synchExtremes(millis);
else {
moveExtremes(millis);
}
}
private void synchExtremes(long millis) {
long posS = 0;
long posE = 0;
calS.setTimeInMillis(millis);
calE.setTimeInMillis(millis);
if (millisInPeriod >= CompanyCalendar.MILLIS_IN_HOUR) { //"SCALE_1HOUR" wed 4 may 2005 9:45:30 --> 4 may 2005 9:00:00 --- wed 4 may 2005 10:00:00
calS.set(CompanyCalendar.MILLISECOND, 0);
calS.set(CompanyCalendar.SECOND, 0);
calS.set(CompanyCalendar.MINUTE, 0);
calE.setTimeInMillis(calS.getTimeInMillis());
calE.add(CompanyCalendar.HOUR_OF_DAY, 1);
calE.add(CompanyCalendar.MILLISECOND, -1);
}
if (millisInPeriod >= CompanyCalendar.MILLIS_IN_3_HOUR) { //SCALE_3HOUR wed 4 may 2005 9:45:30 --> wed 4 may 2005 9:00:00 --- wed 4 may 2005 12:00
int sex = (calS.get(CompanyCalendar.HOUR_OF_DAY) / 3) * 3;
calS.add(CompanyCalendar.HOUR_OF_DAY, sex - calS.get(CompanyCalendar.HOUR_OF_DAY));
calE.setTimeInMillis(calS.getTimeInMillis());
calE.add(CompanyCalendar.HOUR_OF_DAY, 3);
calE.add(CompanyCalendar.MILLISECOND, -1);
}
if (millisInPeriod >= CompanyCalendar.MILLIS_IN_6_HOUR) { //SCALE_6HOUR wed 4 may 2005 9:45:30 --> wed 4 may 2005 6:00 --- wed 4 may 2005 12:00
int sex = (calS.get(CompanyCalendar.HOUR_OF_DAY) / 6) * 6;
calS.add(CompanyCalendar.HOUR_OF_DAY, sex - calS.get(CompanyCalendar.HOUR_OF_DAY));
calE.setTimeInMillis(calS.getTimeInMillis());
calE.add(CompanyCalendar.HOUR_OF_DAY, 6);
calE.add(CompanyCalendar.MILLISECOND, -1);
}
if (millisInPeriod >= CompanyCalendar.MILLIS_IN_12_HOUR) { //SCALE_12HOUR wed 4 may 2005 9:45:30 --> wed 4 may 2005 0:00 --- wed 4 may 2005 12:00
int sex = (calS.get(CompanyCalendar.HOUR_OF_DAY) / 12) * 12;
calS.add(CompanyCalendar.HOUR_OF_DAY, sex - calS.get(CompanyCalendar.HOUR_OF_DAY));
calE.setTimeInMillis(calS.getTimeInMillis());
calE.add(CompanyCalendar.HOUR_OF_DAY, 12);
calE.add(CompanyCalendar.MILLISECOND, -1);
}
if (millisInPeriod >= CompanyCalendar.MILLIS_IN_DAY) { // SCALE_1DAY --> wed 4 may 2005 00:00 --- wed 4 may 2005 23:59:59.9999
calS.setAndGetTimeToDayStart();
calE.setAndGetTimeToDayEnd();
// store the day start,end
posS = calS.getTimeInMillis();
posE = calE.getTimeInMillis();
}
if (millisInPeriod >= CompanyCalendar.MILLIS_IN_WEEK) { // SCALE_1WEEK --> mon* 2 may 2005 00:00 --- sun* 8 may 2005 23:59:59.9999 *=according to settings
calS.set(CompanyCalendar.DAY_OF_WEEK, calE.getFirstDayOfWeek());
calE.set(CompanyCalendar.DAY_OF_WEEK, calE.getFirstDayOfWeek());
calE.add(CompanyCalendar.DAY_OF_WEEK, 6);
}
if (millisInPeriod >= CompanyCalendar.MILLIS_IN_2_WEEK) { // SCALE_2WEEK --> mon* 25 apr 2005 00:00 --- sun* 15 may 2005 23:59:59.9999 *=according to settings
calS.add(CompanyCalendar.DAY_OF_WEEK, -7);
calE.add(CompanyCalendar.DAY_OF_WEEK, 7);
}
if (millisInPeriod >= CompanyCalendar.MILLIS_IN_MONTH) { // SCALE_1MONTH
//reposition to start day
calS.setTimeInMillis(posS);
calE.setTimeInMillis(posS);
calS.set(CompanyCalendar.DAY_OF_MONTH, 1);
calE.set(CompanyCalendar.DAY_OF_MONTH, 1);
calE.add(CompanyCalendar.MONTH, 1);
calE.add(CompanyCalendar.MILLISECOND, -1);
}
if (millisInPeriod >= CompanyCalendar.MILLIS_IN_3_MONTH) { // SCALE_3MONTH
int sex = calS.get(CompanyCalendar.MONTH) / 3;
calS.set(CompanyCalendar.MONTH, sex * 3 + 1);
calE.set(CompanyCalendar.DAY_OF_MONTH, 1);
calE.set(CompanyCalendar.MONTH, sex * 3 + 4);
calE.add(CompanyCalendar.DAY_OF_MONTH, -1);
}
if (millisInPeriod >= CompanyCalendar.MILLIS_IN_YEAR) { // SCALE_1YEAR
calS.set(CompanyCalendar.MONTH, CompanyCalendar.JANUARY);
calS.set(CompanyCalendar.DAY_OF_MONTH, 1);
calE.set(CompanyCalendar.MONTH, CompanyCalendar.DECEMBER);
calE.set(CompanyCalendar.DAY_OF_MONTH, 31);
}
if (millisInPeriod >= CompanyCalendar.MILLIS_IN_2_YEAR) { // SCALE_2YEAR
calS.add(CompanyCalendar.YEAR, -1);
calE.add(CompanyCalendar.YEAR, 1);
}
if (millisInPeriod >= CompanyCalendar.MILLIS_IN_5_YEAR) { // SCALE_5YEAR
calS.add(CompanyCalendar.YEAR, -2);
calE.add(CompanyCalendar.YEAR, 3);
}
startPointTime = calS.getTimeInMillis();
startPointDate = calS.getTime();
endPointTime = calE.getTimeInMillis();
endPointDate = calE.getTime();
}
private void moveExtremes(long millis) {
calS.setTimeInMillis(millis - millisInPeriod / 2);
//calE.setTimeInMillis(millis + millisInPeriod / 2);
// in any case resynch to the tick
resetLesserFields(calS, fieldToLoop);
calE.setTimeInMillis(calS.getTimeInMillis() + millisInPeriod);
startPointTime = calS.getTimeInMillis();
startPointDate = calS.getTime();
endPointTime = calE.getTimeInMillis();
endPointDate = calE.getTime();
}
private void resetLesserFields(CompanyCalendar cc, int field) {
// ever reset millis and seconds
cc.set(CompanyCalendar.MILLISECOND, 0);
cc.set(CompanyCalendar.SECOND, 0);
// normalize the calendar to the less field step. E.g.: if the field is MINUTE and the increment is 15 9.34 -> 9.30
cc.set(field, (cc.get(field)/fieldIncrement)*fieldIncrement );
if (CompanyCalendar.MINUTE == field) {
} else if (CompanyCalendar.HOUR_OF_DAY == field) {
cc.set(CompanyCalendar.MINUTE, 0);
} else if (CompanyCalendar.DAY_OF_WEEK == field) {
cc.set(CompanyCalendar.MINUTE, 0);
cc.set(CompanyCalendar.HOUR_OF_DAY, 0);
} else if (CompanyCalendar.DAY_OF_MONTH == field) {
cc.set(CompanyCalendar.MINUTE, 0);
cc.set(CompanyCalendar.HOUR_OF_DAY, 0);
} else if (CompanyCalendar.WEEK_OF_MONTH == field) {
cc.set(CompanyCalendar.MINUTE, 0);
cc.set(CompanyCalendar.HOUR_OF_DAY, 0);
} else if (CompanyCalendar.MONTH == field) {
cc.set(CompanyCalendar.MINUTE, 0);
cc.set(CompanyCalendar.HOUR_OF_DAY, 0);
cc.set(CompanyCalendar.DAY_OF_MONTH, 1);
}
}
public Period getPeriod() {
return new Period(startPointTime,endPointTime);
}
public int getSuperScaleField(){
if (scaleName.equals(ScaleType.SCALE_1HOUR) )
return CompanyCalendar.HOUR_OF_DAY ;
else if (scaleName.equals(ScaleType.SCALE_3HOUR) ||
scaleName.equals(ScaleType.SCALE_6HOUR) ||
scaleName.equals(ScaleType.SCALE_12HOUR) )
return CompanyCalendar.DAY_OF_MONTH;
else if (scaleName.equals(ScaleType.SCALE_1DAY) ||
scaleName.equals(ScaleType.SCALE_1WEEK ) ||
scaleName.equals(ScaleType.SCALE_2WEEK ) )
return CompanyCalendar.MONTH ;
else if (scaleName.equals(ScaleType.SCALE_1MONTH) ||
scaleName.equals(ScaleType.SCALE_3MONTH ) ||
scaleName.equals(ScaleType.SCALE_1YEAR ) )
return CompanyCalendar.YEAR ;
else
return CompanyCalendar.YEAR;
}
}