package calendar;

import org.gnu.gtk.Button;
import org.gnu.gtk.ButtonBoxStyle;
import org.gnu.gtk.Calendar;
import org.gnu.gtk.CalendarDisplayOptions;
import org.gnu.gtk.CheckButton;
import org.gnu.gtk.FontSelectionDialog;
import org.gnu.gtk.Frame;
import org.gnu.gtk.Gtk;
import org.gnu.gtk.HBox;
import org.gnu.gtk.HButtonBox;
import org.gnu.gtk.Label;
import org.gnu.gtk.VBox;
import org.gnu.gtk.VSeparator;
import org.gnu.gtk.Window;
import org.gnu.gtk.WindowType;
import org.gnu.gtk.event.ButtonEvent;
import org.gnu.gtk.event.ButtonListener;
import org.gnu.gtk.event.CalendarEvent;
import org.gnu.gtk.event.CalendarListener;
import org.gnu.gtk.event.LifeCycleEvent;
import org.gnu.gtk.event.LifeCycleListener;
import org.gnu.gtk.event.ToggleEvent;
import org.gnu.gtk.event.ToggleListener;
import org.gnu.gtk.GtkStockItem;
import org.gnu.pango.FontDescription;


public class CalendarExample {

	private String flags[] = { "Show Heading", "Show Day Names", "No Month Change", "Show Week Numbers" };

	private Label selected;
	private Label selectedDoubleClick;
	private Label month;
	private CheckButton[] toggle = new CheckButton[4];
	protected FontSelectionDialog fontsel;

	private boolean showHeading = false;
	private boolean showDayNames = false;
	private boolean noMonthChange = false;
	private boolean showWeekNumbers = false;

	private Calendar calendar;

	public CalendarExample() {

		Window window = new Window(WindowType.TOPLEVEL);
		window.setBorderWidth(5);
		window.setTitle("Calendar Example");
		window.addListener(new LifeCycleListener() {
			public void lifeCycleEvent(LifeCycleEvent event) {}
			public boolean lifeCycleQuery(LifeCycleEvent event) {
				if (event.isOfType(LifeCycleEvent.Type.DESTROY) || 
						event.isOfType(LifeCycleEvent.Type.DELETE)) {
						Gtk.mainQuit();
				}
				return false;
			}
		});

		VBox vbox = new VBox(false, 10);
		window.add(vbox);

		// The top part of the window, Calendar, flags, and fontsel.
		HBox hbox = new HBox(false, 10);
		vbox.packStart(hbox, true, true, 10);
		HButtonBox hbbox = new HButtonBox();
		hbox.packStart(hbbox, false, false, 10);
		hbbox.setLayout(ButtonBoxStyle.SPREAD);
		hbbox.setSpacing(5);

		// Calendar Widget
		Frame frame = new Frame("Calendar");
		hbbox.packStart(frame, true, true, 10);
		calendar = new Calendar();
		// setup the initial state of the calendar widget
		calendarSetFlags();
		calendar.markDay(19);
		calendar.addListener(new CalendarListener() {
			public void calendarEvent(CalendarEvent event) {
				if (event.isOfType(CalendarEvent.Type.MONTH_CHANGED_NEXT) ||
					event.isOfType(CalendarEvent.Type.MONTH_CHANGED_PREV)) {
					calendarMonthChanged();
				} else if (event.isOfType(CalendarEvent.Type.DAY_SELECTED)) {
					calendarDaySelected();
				} else if (event.isOfType(CalendarEvent.Type.DAY_SELECTED_DOUBLE_CLICK)) {
					calendarDaySelectedDoubleClick();
				}
			}
		});
		frame.add(calendar);

		VSeparator separator = new VSeparator();
		hbox.packStart(separator, false, true, 0);

		VBox vbox2 = new VBox(false, 10);
		hbox.packStart(vbox2, false, false, 10);

		frame = new Frame("Flags");
		vbox2.packStart(frame, true, true, 10);
		VBox vbox3 = new VBox(true, 5);
		frame.add(vbox3);

		for (int i = 0; i < 4; i++) {
			toggle[i] = new CheckButton(flags[i], false);
			toggle[i].addListener(new ToggleListener() {
				public void toggleEvent(ToggleEvent event) {
					calendarToggleFlag();
				}
			});
			vbox3.packStart(toggle[i], true, true, 0);
		}

		// Build the right font-button
		Button button = new Button("Font...", false);
		button.addListener(new ButtonListener() {
			public void buttonEvent(ButtonEvent event) {
				if (event.isOfType(ButtonEvent.Type.CLICK)) {
					calendarSelectFont();
				}
			}
		});
		vbox2.packStart(button, false, false, 0);

		// Build the signal-event part.
		frame = new Frame("Signal events");
		vbox.packStart(frame, true, true, 10);
		vbox2 = new VBox(true, 5);
		frame.add(vbox2);

		hbox = new HBox(false, 5);
		vbox2.packStart(hbox, false, true, 0);
		Label label = new Label("Day selected:");
		hbox.packStart(label, false, true, 0);
		selected = new Label("");
		hbox.packStart(selected, false, true, 0);

		hbox = new HBox(false, 5);
		vbox2.packStart(hbox, false, true, 0);
		label = new Label("Day selected double click:");
		hbox.packStart(label, false, true, 0);
		selectedDoubleClick = new Label("");
		hbox.packStart(selectedDoubleClick, false, true, 0);

		hbox = new HBox(false, 5);
		vbox2.packStart(hbox, false, true, 0);
		label = new Label("Month change:");
		hbox.packStart(label, false, true, 0);
		month = new Label("");
		hbox.packStart(month, false, true, 0);

		HButtonBox bbox = new HButtonBox();
		vbox.packStart(bbox, false, false, 0);
		bbox.setLayout(ButtonBoxStyle.END);

		button = new Button( GtkStockItem.CLOSE );
		button.addListener(new ButtonListener() {
			public void buttonEvent(ButtonEvent event) {
				if (event.isOfType(ButtonEvent.Type.CLICK)) {
					Gtk.mainQuit();
				}
			}
		});
		bbox.add(button);

		window.showAll();
	}

	public void calendarMonthChanged() {
		java.util.Calendar cal = calendar.getDate();
		month.setText(cal.getTime().toString());
	}

	public void calendarDaySelected() {
		java.util.Calendar cal = calendar.getDate();
		selected.setText(cal.getTime().toString());
	}

	public void calendarDaySelectedDoubleClick() {
		java.util.Calendar cal = calendar.getDate();
		selectedDoubleClick.setText(cal.getTime().toString());
	}

	public void calendarToggleFlag() {
		showHeading = toggle[0].getState();
		showDayNames = toggle[1].getState();
		noMonthChange = toggle[2].getState();
		showWeekNumbers = toggle[3].getState();

		calendarSetFlags();
	}

	public void calendarSelectFont() {
		fontsel = new FontSelectionDialog("Font Selection Dialog");
		Button okButton = fontsel.getOKButton();
		okButton.addListener(new ButtonListener() {
			public void buttonEvent(ButtonEvent event) {
				if (event.isOfType(ButtonEvent.Type.CLICK)) {
					calendarFontSelectionOK();
				}
			}
		});
		Button cancelButton = fontsel.getCancelButton();
		cancelButton.addListener(new ButtonListener() {
			public void buttonEvent(ButtonEvent event) {
				if (event.isOfType(ButtonEvent.Type.CLICK)) {
					fontsel.destroy();
				}
			}
		});

		fontsel.show();
	}

	public void calendarFontSelectionOK() {
		String fontname = fontsel.getFontName();
		if (fontname != null) {
			FontDescription fontDesc = new FontDescription(fontname);
			calendar.setFont(fontDesc);
		}
	}

	public void calendarSetFlags() {
		int options = 0;

		if (showHeading)
			options += (1 << 0);
		if (showDayNames)
			options += (1 << 1);
		if (noMonthChange)
			options += (1 << 2);
		if (showWeekNumbers)
			options += (1 << 3);

		calendar.setDisplayOptions(CalendarDisplayOptions.intern(options));
	}

	public static void main(String[] args) {
		// Initialize GTK 
		Gtk.init(args);
		new CalendarExample();
		Gtk.main();
	}
}
