package zeta;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
public class WorkloadScheduler {
public WorkloadScheduler(String activeAt) {
if (activeAt != null && activeAt.length() > 0) {
final String[] dayOfWeek = { "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su" };
final int[] calendarDayOfWeek = { Calendar.MONDAY, Calendar.TUESDAY, Calendar.WEDNESDAY, Calendar.THURSDAY, Calendar.FRIDAY, Calendar.SATURDAY, Calendar.SUNDAY };
for (int i = 0; i < 7; ++i) {
List timeframes = new ArrayList(8);
int pos = 0;
while (true) {
int[] res = timeframe(activeAt, pos, dayOfWeek[i]);
pos = res[0];
if (pos == 0) {
break;
}
if (checkTimeframe(res[1], res[2], res[3], res[4])) {
addTimeframe(timeframes, res[1], res[2], res[3], res[4]);
}
}
int l = timeframes.size();
if (l > 0) {
int k = calendarDayOfWeek[i];
this.activeAt[k] = new int[2*l];
for (int j = 0; j < l; ++j) {
int[] tf = (int[])timeframes.get(j);
this.activeAt[k][2*j] = (tf[0] << 6) | tf[1];
this.activeAt[k][2*j+1] = (tf[2] << 6) | tf[3];
}
alwaysActive = false;
}
}
}
}
public boolean isAlwaysActive() {
return alwaysActive;
}
public boolean isActive() {
if (alwaysActive) {
return true;
}
Calendar rightNow = Calendar.getInstance();
int dayOfWeek = rightNow.get(Calendar.DAY_OF_WEEK);
if (activeAt[dayOfWeek] == null) {
return false;
}
int time = (rightNow.get(Calendar.HOUR_OF_DAY) << 6) | rightNow.get(Calendar.MINUTE);
int l = activeAt[dayOfWeek].length;
for (int i = 1; i < l; i += 2) {
if (time >= activeAt[dayOfWeek][i-1]) {
if (time < activeAt[dayOfWeek][i]) {
return true;
}
} else {
return false;
}
}
return false;
}
public long getTimeMillisToNextTimeframe() {
if (alwaysActive) {
return -1;
}
Calendar rightNow = Calendar.getInstance();
int dayOfWeek = rightNow.get(Calendar.DAY_OF_WEEK);
if (activeAt[dayOfWeek] != null) {
int l = activeAt[dayOfWeek].length;
if (l > 0) {
int time = (rightNow.get(Calendar.HOUR_OF_DAY) << 6) | rightNow.get(Calendar.MINUTE);
for (int i = 1; i < l; i += 2) {
if (time >= activeAt[dayOfWeek][i-1]) {
if (time < activeAt[dayOfWeek][i]) {
long t = ((activeAt[dayOfWeek][i] >>> 6)-rightNow.get(Calendar.HOUR_OF_DAY))*60 + (activeAt[dayOfWeek][i]&63)-rightNow.get(Calendar.MINUTE);
return (t*60-rightNow.get(Calendar.SECOND))*1000;
}
} else {
long t = ((activeAt[dayOfWeek][i-1] >>> 6)-rightNow.get(Calendar.HOUR_OF_DAY))*60 + (activeAt[dayOfWeek][i-1]&63)-rightNow.get(Calendar.MINUTE);
return (t*60-rightNow.get(Calendar.SECOND))*1000;
}
}
}
}
long time = 60*(24-rightNow.get(Calendar.HOUR_OF_DAY))-rightNow.get(Calendar.MINUTE);
return (time*60-rightNow.get(Calendar.SECOND))*1000;
}
private static boolean checkTimeframe(int startHour, int startMinute, int stopHour, int stopMinute) {
if (startHour < 0 || startHour > 23 || stopHour < 0 || stopHour > 23) {
ZetaInfo.write("A timestamp will be ignored since hour is not between 0 and 23.");
return false;
}
if (startMinute < 0 || startMinute > 59 || stopMinute < 0 || stopMinute > 59) {
ZetaInfo.write("A timestamp will be ignored since minutes are not between 0 and 59.");
return false;
}
if ((stopHour != 0 || stopMinute != 0) && (stopHour < startHour || stopHour == startHour && stopMinute <= startMinute)) {
ZetaInfo.write("Timeframe " + startHour + ((startMinute >= 10)? ":" + startMinute : ":0" + startMinute)
+ '-' + stopHour + ((stopMinute >= 10)? ":" + stopMinute : ":0" + stopMinute) + " is not correct defined and will be ignored.");
return false;
}
return true;
}
private static void addTimeframe(List timeframes, int startHour, int startMinute, int stopHour, int stopMinute) {
if (stopHour == 0 && stopMinute == 0) {
stopHour = 24;
}
int i = 0;
for (int l = timeframes.size(); i < l; ++i) {
int[] timeframe = (int[])timeframes.get(i);
if (startHour < timeframe[0] || startHour == timeframe[0] && startMinute < timeframe[1]) {
if (stopHour < timeframe[0] || stopHour == timeframe[0] && stopMinute < timeframe[1]) {
break;
} else {
ZetaInfo.write("Timeframe " + startHour + ((startMinute >= 10)? ":" + startMinute : ":0" + startMinute)
+ '-' + stopHour + ((stopMinute >= 10)? ":" + stopMinute : ":0" + stopMinute) + " will be ignored since it overlaps a previous timeframe.");
return;
}
} else if (startHour < timeframe[2] || startHour == timeframe[2] && startMinute <= timeframe[3]) {
ZetaInfo.write("Timeframe " + startHour + ((startMinute >= 10)? ":" + startMinute : ":0" + startMinute)
+ '-' + stopHour + ((stopMinute >= 10)? ":" + stopMinute : ":0" + stopMinute) + " will be ignored since it overlaps a previous timeframe.");
return;
}
}
timeframes.add(i, new int[] { startHour, startMinute, stopHour, stopMinute });
}
private static int[] timeframe(String activeAt, int pos, String dayOfWeek) {
int startHour = 0;
int startMin = 0;
int stopHour = 0;
int stopMin = 0;
int i = activeAt.indexOf(dayOfWeek, pos);
pos = 0;
if (i >= 0) {
int l = activeAt.length();
int j = i+dayOfWeek.length();
if (j < l) {
while (j < l && Character.isDigit(activeAt.charAt(j))) {
startHour = 10*startHour + Character.digit(activeAt.charAt(j), 10);
++j;
}
if (++j < l && activeAt.charAt(j-1) == ':') {
while (j < l && Character.isDigit(activeAt.charAt(j))) {
startMin = 10*startMin + Character.digit(activeAt.charAt(j), 10);
++j;
}
if (++j < l && activeAt.charAt(j-1) == '-') {
while (j < l && Character.isDigit(activeAt.charAt(j))) {
stopHour = 10*stopHour + Character.digit(activeAt.charAt(j), 10);
++j;
}
if (j < l && activeAt.charAt(j) == ':') {
while (++j < l && Character.isDigit(activeAt.charAt(j))) {
stopMin = 10*stopMin + Character.digit(activeAt.charAt(j), 10);
}
pos = j;
} else {
startHour = startMin = stopHour = 0;
}
} else {
startHour = startMin = 0;
}
} else {
startHour = 0;
}
}
}
return new int[] { pos, startHour, startMin, stopHour, stopMin };
}
private boolean alwaysActive = true;
private final int MAX_DAY = Math.max(Math.max(Math.max(Math.max(Math.max(Math.max(Calendar.SUNDAY, Calendar.MONDAY), Calendar.TUESDAY), Calendar.WEDNESDAY), Calendar.THURSDAY), Calendar.FRIDAY), Calendar.SATURDAY)+1;
private int[][] activeAt = new int[MAX_DAY][MAX_DAY];
}