String[] monthNames = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
String[] weekDays = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
ArrayList<MonthDay> holidays;
float topLabelMargin = 100;
float calendarWidth = width - plannerWidth - (margin * 2);
float calendarHeight = height - (margin * 2) - topLabelMargin;
textFont(createFont("ArialMT-48", 12));
textAlign(CENTER, CENTER);
holidays = new ArrayList<MonthDay>();
holidays.add(new Holiday("New Year's Day", 1, 1));
holidays.add(new Holiday("Independence\nDay", 7, 4));
holidays.add(new Holiday("Halloween", 10, 31));
holidays.add(new Holiday("Veterans' Day", 11, 11));
holidays.add(new Holiday("Christmas", 12, 25));
holidays.add(new MonthDay() {
public String getName() {return "Martin Luther\nKing Jr. Day";}
public int getMonth() {return 1;}
public int getDay() {return getDayInMonth(currentYear, currentMonth, 2, 3);}
holidays.add(new MonthDay() {
public String getName() {return "Presidents' Day";}
public int getMonth() {return 2;}
public int getDay() {return getDayInMonth(currentYear, currentMonth, 2, 3);}
holidays.add(new MonthDay() {
public String getName() {return "Mothers' Day";}
public int getMonth() {return 5;}
public int getDay() {return getDayInMonth(currentYear, currentMonth, 1, 2);}
holidays.add(new MonthDay() {
public String getName() {return "Fathers' Day";}
public int getMonth() {return 6;}
public int getDay() {return getDayInMonth(currentYear, currentMonth, 1, 3);}
holidays.add(new MonthDay() {
public String getName() {return "Memorial Day";}
public int getMonth() {return 5;}
public int getDay() {return lastDayInMonth(currentYear, currentMonth, 2);}
holidays.add(new MonthDay() {
public String getName() {return "Labor Day";}
public int getMonth() {return 9;}
public int getDay() {return getDayInMonth(currentYear, currentMonth, 2, 1);}
holidays.add(new MonthDay() {
public String getName() {return "Columbus Day";}
public int getMonth() {return 10;}
public int getDay() {return getDayInMonth(currentYear, currentMonth, 2, 2);}
holidays.add(new MonthDay() {
public String getName() {return "Thanksgiving";}
public int getMonth() {return 11;}
public int getDay() {return getDayInMonth(currentYear, currentMonth, 5, 4);}
currentMonth = month() - 1;
String monthName = monthNames[currentMonth];
int daysInMonth = int(monthDays[currentMonth]);
if(currentMonth == 1 && isLeapYear(currentYear)) daysInMonth ++;
String dayOfWeekName = "";
if(currentMonth == month() - 1 && currentYear == year()) {
dayOfWeek = int((new Date()).getDay());
dayOfWeekName = weekDays[dayOfWeek];
date.setYear(currentYear);
date.setMonth(currentMonth);
int startingDayOfMonth = date.getDay();
String startingDayOfMonthName = weekDays[startingDayOfMonth];
int numRows = ceil((startingDayOfMonth + daysInMonth) / 7);
calendarWidth = width - plannerWidth - (margin * 2);
calendarHeight = height - (margin * 2) - topLabelMargin;
float boxWidth = (calendarWidth - (6 * spacing)) / 7;
float boxHeight = (calendarHeight - ((numRows - 1) * spacing)) / numRows;
if(mouseInArrowRange()) {
if(mouseOverArrow(-1) || mouseOverArrow(-2)) fill(255);
triangle((width - plannerWidth) / 2 - (width - plannerWidth) / 10 * 3.5, margin + topLabelMargin / 10 * 3, (width - plannerWidth) / 2 - (width - plannerWidth) / 10 * 3, margin + topLabelMargin / 10 * 2, (width - plannerWidth) / 2 - (width - plannerWidth) / 10 * 3, margin + topLabelMargin / 10 * 4);
if(mouseOverArrow(1) || mouseOverArrow(2)) fill(255);
triangle((width - plannerWidth) / 2 + (width - plannerWidth) / 10 * 3.5, margin + topLabelMargin / 10 * 3, (width - plannerWidth) / 2 + (width - plannerWidth) / 10 * 3, margin + topLabelMargin / 10 * 2, (width - plannerWidth) / 2 + (width - plannerWidth) / 10 * 3, margin + topLabelMargin / 10 * 4);
if(mouseOverArrow(-2)) fill(255);
triangle((width - plannerWidth) / 2 - (width - plannerWidth) / 10 * 4.1, margin + topLabelMargin / 10 * 3, (width - plannerWidth) / 2 - (width - plannerWidth) / 10 * 3.6, margin + topLabelMargin / 10 * 2, (width - plannerWidth) / 2 - (width - plannerWidth) / 10 * 3.6, margin + topLabelMargin / 10 * 4);
if(mouseOverArrow(2)) fill(255);
triangle((width - plannerWidth) / 2 + (width - plannerWidth) / 10 * 4.1, margin + topLabelMargin / 10 * 3, (width - plannerWidth) / 2 + (width - plannerWidth) / 10 * 3.6, margin + topLabelMargin / 10 * 2, (width - plannerWidth) / 2 + (width - plannerWidth) / 10 * 3.6, margin + topLabelMargin / 10 * 4);
text(monthName + " " + currentYear, (width - plannerWidth) / 2, margin + topLabelMargin / 10 * 3);
for(int i = 0; i < weekDays.length; i ++)
text(weekDays[i], margin + (spacing * i) + (boxWidth * i) + boxWidth / 2, margin + topLabelMargin / 10 * 7);
line(margin, margin + topLabelMargin / 10 * 8.5, width - plannerWidth - margin, margin + topLabelMargin / 10 * 8.5);
float xoff = startingDayOfMonth;
for(int i = 0; i < daysInMonth; i ++) {
String curDayOfWeekName = weekDays[xoff];
float x = margin + (spacing * xoff) + (boxWidth * xoff);
float y = margin + topLabelMargin + (spacing * yoff) + (boxHeight * yoff);
rect(x + 3, y + 3, boxWidth, boxHeight);
if((i + 1) == dayOfMonth) fill(255);
rect(x, y, boxWidth, boxHeight);
text(i + 1, x + boxWidth / 2, y + boxHeight / 2);
for(MonthDay holiday : holidays) {
if(currentMonth + 1 == holiday.getMonth() && i + 1 == holiday.getDay()) {
text(holiday.getName(), x + boxWidth / 2, y + boxHeight / 20 * 17 - (textAscent() + textAscent()) * yH);
if(overTodayButton()) fill(255);
text("Today", (width - plannerWidth) / 2, height - margin / 2);
if(mousePressed && overTodayButton()) goToToday();
rect(width - plannerWidth + 3, margin + topLabelMargin + 3, plannerWidth - margin, height - margin * 2 - topLabelMargin);
rect(width - plannerWidth, margin + topLabelMargin, plannerWidth - margin, height - margin * 2 - topLabelMargin);
boolean mouseOverArrow(int arrow) {
return (mouseInArrowRange() && mouseX > ((width - plannerWidth) / 2 - (width - plannerWidth) / 10 * 4.1) && (mouseX < (width - plannerWidth) / 2 - (width - plannerWidth) / 10 * 3.6));
return (mouseInArrowRange() && mouseX > ((width - plannerWidth) / 2 - (width - plannerWidth) / 10 * 3.5) && (mouseX < (width - plannerWidth) / 2 - (width - plannerWidth) / 10 * 3));
return (mouseInArrowRange() && mouseX < ((width - plannerWidth) / 2 + (width - plannerWidth) / 10 * 3.5) && (mouseX > (width - plannerWidth) / 2 + (width - plannerWidth) / 10 * 3));
return (mouseInArrowRange() && mouseX < ((width - plannerWidth) / 2 + (width - plannerWidth) / 10 * 4.1) && (mouseX > (width - plannerWidth) / 2 + (width - plannerWidth) / 10 * 3.6));
boolean mouseInArrowRange() {
return (mouseY > (margin + topLabelMargin / 10 * 2) && mouseY < (margin + topLabelMargin / 10 * 4));
boolean isLeapYear(int year) {
if(year % 400 == 0) return true;
else if(year % 100 == 0) return false;
else if(year % 4 == 0) return true;
if(mouseInArrowRange()) {
if(mouseOverArrow(-2)) currentYear --;
if(mouseOverArrow(2)) currentYear ++;
int getDayInMonth(int year, int month, int dayOfWeek, int num) {
int startingDayOfMonth = date.getDay();
return 7 * (dayOfWeek > startingDayOfMonth ? num - 1 : num) + (dayOfWeek) - startingDayOfMonth;
int lastDayInMonth(int year, int month, int dayOfWeek) {
int daysInMonth = int(monthDays[month]);
if(month == 1 && isLeapYear(year)) daysInMonth ++;
date.setDate(daysInMonth);
int lastDayOfMonth = date.getDay();
return daysInMonth - (lastDayOfMonth - dayOfWeek) - (dayOfWeek - 1 > lastDayOfMonth ? 7 : 0) - 1;
currentMonth = month() - 1;
return (currentYear == year() && currentMonth == month() - 1);
boolean overTodayButton() {
float textHeight = textAscent() + textDescent() + 20;
return (mouseX > (width - plannerWidth) / 2 - textWidth / 2 && mouseX < (width - plannerWidth) / 2 + textWidth / 2 && mouseY > height - margin / 2 - textHeight / 2 && mouseY < height - margin / 2 + textHeight / 2);
boolean overPlannerScroller() {
return (mouseY > margin + topLabelMargin && mouseY < margin + topLabelMargin + calendarHeight && mouseX > width - plannerWidth - 15 && mouseX < width - plannerWidth + 5);
class Holiday extends MonthDay {
Holiday(String n, int m, int d) {
abstract class MonthDay {