package net.sf.lab3f.gwt.calendar.client;
import java.util.Date;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.ChangeListenerCollection;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.SourcesChangeEvents;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.Window;
public class Main extends Composite
implements ClickListener, SourcesChangeEvents {
private class NavBar extends Composite implements ClickListener {
public final DockPanel bar = new DockPanel();
public final Button prevMonth = new Button("<", this);
public final Button prevYear = new Button("<<", this);
public final Button nextYear = new Button(">>", this);
public final Button nextMonth = new Button(">", this);
public final HTML title = new HTML();
private final Main calendar;
public NavBar(Main calendar) {
this.calendar = calendar;
setWidget(bar);
bar.setStyleName("navbar");
title.setStyleName("header");
HorizontalPanel prevButtons = new HorizontalPanel();
prevButtons.add(prevMonth);
// prevButtons.add(prevYear);
HorizontalPanel nextButtons = new HorizontalPanel();
// nextButtons.add(nextYear);
nextButtons.add(nextMonth);
prevMonth.setStyleName("cldrNav");
nextMonth.setStyleName("cldrNav");
title.setStyleName("cldrTitle");
bar.add(prevButtons, DockPanel.WEST);
bar.setCellHorizontalAlignment(prevButtons, DockPanel.ALIGN_LEFT);
bar.add(nextButtons, DockPanel.EAST);
bar.setCellHorizontalAlignment(nextButtons, DockPanel.ALIGN_RIGHT);
bar.add(title, DockPanel.CENTER);
bar.setVerticalAlignment(DockPanel.ALIGN_MIDDLE);
bar.setCellHorizontalAlignment(title, HasAlignment.ALIGN_CENTER);
bar.setCellVerticalAlignment(title, HasAlignment.ALIGN_MIDDLE);
// bar.setCellWidth(title, "0%");
}
public void onClick(Widget sender) {
if (sender == prevMonth) {
calendar.prevMonth();
} else if (sender == prevYear) {
calendar.prevYear();
} else if (sender == nextYear) {
calendar.nextYear();
} else if (sender == nextMonth) {
calendar.nextMonth();
}
}
}
private static class CellHTML extends HTML {
private int day;
public CellHTML(String text, int day) {
super(text);
this.day = day;
}
public int getDay() {
return day;
}
}
private final NavBar navbar = new NavBar(this);
private final DockPanel outer = new DockPanel();
private final Grid grid = new Grid(7, 7) {
public boolean clearCell(int row, int column) {
boolean retValue = super.clearCell(row, column);
Element td = getCellFormatter().getElement(row, column);
DOM.setInnerHTML(td, "");
return retValue;
}
};
private Date date = new Date();
private ChangeListenerCollection changeListeners;
private String[] days = new String[] { "Sunday", "Monday", "Tuesday",
"Wednesday", "Thursday", "Friday", "Saturday" };
private String[] months = new String[] { "January", "February", "March",
"April", "May", "June", "July", "August", "September", "October",
"November", "December" };
private int selectedDay = -1;
public Main() {
setWidget(outer);
Constants cnst = (Constants) com.google.gwt.core.client.GWT.create(Constants.class);
days = new String[]{cnst.day1(), cnst.day2(), cnst.day3(), cnst.day4(), cnst.day5(), cnst.day6(), cnst.day7()};
months = new String[]{cnst.month1(), cnst.month2(), cnst.month3(), cnst.month4(), cnst.month5(), cnst.month6(), cnst.month7(), cnst.month8(), cnst.month9(), cnst.month10(), cnst.month11(), cnst.month12()};
grid.setStyleName("table");
grid.setCellSpacing(0);
outer.add(navbar, DockPanel.NORTH);
outer.add(grid, DockPanel.CENTER);
drawCalendar();
setStyleName("CalendarWidget");
}
private void drawCalendar() {
int year = getYear();
int month = getMonth();
int day = getDay();
setHeaderText(year, month);
grid.getRowFormatter().setStyleName(0, "weekheader");
for (int i = 0; i < days.length; i++) {
grid.getCellFormatter().setStyleName(0, i, "days");
grid.setText(0, i, days[i].substring(0, 3));
}
Date now = new Date();
int sameDay = now.getDate();
int today = (now.getMonth() == month && now.getYear()+1900 == year) ? sameDay : 0;
int firstDay = new Date(year - 1900, month, 1).getDay() - 1;
if(firstDay == -1) firstDay = 6;
int numOfDays = getDaysInMonth(year, month);
int r = 1;
int d = 1;
boolean b = false;
while(r < 7){
for(int i = 0; i < 7; i++){
b = (r == 1 && i == firstDay) || (d > 1 && d <= numOfDays);
if(!b){
grid.getCellFormatter().setStyleName(r, i, "empty");
grid.setHTML(r, i, " ");
}
else{
HTML html = new CellHTML("<span>" + d + "</span>", d);
html.addClickListener(this);
grid.getCellFormatter().setStyleName(r, i, "cell");
if((d == today && selectedDay == -1) || d == selectedDay) {
grid.getCellFormatter().addStyleName(r, i, "today");
} else if (d == sameDay) {
grid.getCellFormatter().addStyleName(r, i, "day");
}
grid.setWidget(r, i, html);
d++;
}
}
r++;
}
/*
int j = 0;
for (int i = 1; i < 6; i++) {
for (int k = 0; k < 7; k++, j++) {
int displayNum = (j - firstDay + 1);
if (j < firstDay || displayNum > numOfDays) {
grid.getCellFormatter().setStyleName(i, k, "empty");
grid.setHTML(i, k, " ");
} else {
HTML html = new CellHTML(
"<span>" + String.valueOf(displayNum) + "</span>",
displayNum);
html.addClickListener(this);
grid.getCellFormatter().setStyleName(i, k, "cell");
if ((displayNum == today && selectedDay == -1) || displayNum == selectedDay) {
grid.getCellFormatter().addStyleName(i, k, "today");
} else if (displayNum == sameDay) {
grid.getCellFormatter().addStyleName(i, k, "day");
}
grid.setWidget(i, k, html);
}
}
}
*/
}
protected void setHeaderText(int year, int month) {
navbar.title.setText(months[month] + ", " + year);
}
private int getDaysInMonth(int year, int month) {
switch (month) {
case 1:
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
return 29; // leap year
else
return 28;
case 3:
return 30;
case 5:
return 30;
case 8:
return 30;
case 10:
return 30;
default:
return 31;
}
}
public void prevMonth() {
int month = getMonth() - 1;
if (month < 0) {
setDate(getYear() - 1, 11, getDay());
} else {
setMonth(month);
}
drawCalendar();
}
public void nextMonth() {
int month = getMonth() + 1;
if (month > 11) {
setDate(getYear() + 1, 0, getDay());
} else {
setMonth(month);
}
drawCalendar();
}
public void prevYear() {
setYear(getYear() - 1);
drawCalendar();
}
public void nextYear() {
setYear(getYear() + 1);
drawCalendar();
}
private void setDate(int year, int month, int day) {
date = new Date(year - 1900, month, day);
}
private void setYear(int year) {
date.setYear(year - 1900);
}
private void setMonth(int month) {
date.setMonth(month);
}
public int getYear() {
return 1900 + date.getYear();
}
public int getMonth() {
return date.getMonth();
}
public int getDay() {
return date.getDate();
}
public Date getDate() {
return date;
}
public void onClick(Widget sender) {
CellHTML cell = (CellHTML)sender;
setDate(getYear(), getMonth(), cell.getDay());
selectedDay = cell.getDay();
drawCalendar();
cell.setStyleName("today");
if (changeListeners != null) {
changeListeners.fireChange(this);
}
}
public void addChangeListener(ChangeListener listener) {
if (changeListeners == null)
changeListeners = new ChangeListenerCollection();
changeListeners.add(listener);
}
public void removeChangeListener(ChangeListener listener) {
if (changeListeners != null)
changeListeners.remove(listener);
}
}
/*
CalendarWidget.css:
.CalendarWidget {
border: 1px solid #ACA899;
}
.CalendarWidget .navbar {
width: 100%;
background-color: #C3D9FF;
vertical-align: middle;
border-bottom: 1px solid #ACA899;
}
.CalendarWidget .navbar .gwt-Button {
padding-left: 5px;
padding-right: 5px;
}
.CalendarWidget .table {
font: 10pt sans-serif;
text-align: center;
}
.CalendarWidget .weekheader {
background-color: #ACA899;
}
.CalendarWidget .weekheader .days {
width: 3em;
}
.CalendarWidget .cell {
cursor:pointer;
}
.CalendarWidget .cell .gwt-HTML {
border: 1px solid #ACA899;
}
.CalendarWidget .cell .gwt-HTML span {
width: 100%;
height: 100%;
line-height: 2em;
}
.CalendarWidget .today .gwt-HTML {
background-color: #C3D9FF;
}
.CalendarWidget .day .gwt-HTML {
border: 1px solid #C3D9FF;
}
*/