/*
 *******************************************************************************
 * Copyright (C) 1996-2003, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/demo/holiday/HolidayCalendarDemo.java,v $ 
 * $Date: 2003/06/03 18:49:27 $ 
 * $Revision: 1.11 $
 *
 *****************************************************************************************
 */

package com.ibm.icu.dev.demo.holiday;

import java.awt.*;
import java.awt.event.*;

import com.ibm.icu.text.SimpleDateFormat;
import java.text.DateFormatSymbols;
import com.ibm.icu.util.SimpleTimeZone;
import java.util.Locale;
import java.util.Vector;
import java.util.Date;

import com.ibm.icu.util.*;
import com.ibm.icu.dev.demo.impl.*;

/**
 * CalendarDemo demonstrates how Calendar works.
 */
public class HolidayCalendarDemo extends DemoApplet 
{
    /**
     * The main function which defines the behavior of the CalendarDemo
     * applet when an applet is started.
     */
    public static void main(String argv[]) {

        new HolidayCalendarDemo().showDemo();
    }

    /* This creates a CalendarFrame for the demo applet. */
    public Frame createDemoFrame(DemoApplet applet) {
        return new CalendarFrame(applet);
    }

	/**
	* A Frame is a top-level window with a title. The default layout for a frame
	* is BorderLayout.  The CalendarFrame class defines the window layout of
	* CalendarDemo.
	*/
	private static class CalendarFrame extends Frame implements ActionListener,
                                                                ItemListener
	{
    	private static final String creditString = "";

    	private static final boolean DEBUG = false;

    	private Locale curLocale = Locale.US;

    	private DemoApplet applet;

    	private static final Locale[] calendars = {
        	//new Locale("de","AT"),
        	Locale.CANADA,
        	Locale.CANADA_FRENCH,
        	Locale.FRANCE,
        	Locale.GERMANY,
        	new Locale("iw","IL"),
        	new Locale("el","GR"),
        	//new Locale("es","MX"),
        	Locale.UK,
        	Locale.US,
    	};
    	private static final Locale[] displays = {
        	Locale.CANADA,
        	Locale.UK,
        	Locale.US,
        	Locale.FRANCE,
        	Locale.CANADA_FRENCH,
        	//new Locale("de","AT"),
        	Locale.GERMAN,
        	new Locale("el","GR"),
        	//new Locale("iw","IL"),
        	new Locale("es","MX"),
    	};

    	/**
    	* Constructs a new CalendarFrame that is initially invisible.
    	*/
    	public CalendarFrame(DemoApplet applet)
    	{
        	super("Calendar Demo");
        	this.applet = applet;
        	init();
        	start();
        	enableEvents(WindowEvent.WINDOW_CLOSING);
    	}

    	/**
    	* Initializes the applet. You never need to call this directly, it
    	* is called automatically by the system once the applet is created.
    	*/
    	public void init()
    	{
        	// Get G7 locales only for demo purpose. To get all the locales
        	// supported, switch to calling Calendar.getAvailableLocales().
        	// commented
        	locales = displays;

        	buildGUI();
    	}

    	//------------------------------------------------------------
    	// package private
    	//------------------------------------------------------------
    	void addWithFont(Container container, Component foo, Font font) {
        	if (font != null)
            	foo.setFont(font);
        	container.add(foo);
    	}

    	/**
    	* Called to start the applet. You never need to call this method
    	* directly, it is called when the applet's document is visited.
    	*/
    	public void start()
    	{
        	// do nothing
    	}

    	private Choice          localeMenu;
    	private Choice          displayMenu;
    	private Locale[]        locales;

    	private Label           monthLabel;
    	private Button          prevYear;
    	private Button          prevMonth;
    	private Button          gotoToday;
    	private Button          nextMonth;
    	private Button          nextYear;
    	private CalendarPanel   calendarPanel;

    	private static final Locale kFirstLocale = Locale.US;

    	private static void add(Container container, Component component,
                            	GridBagLayout g, GridBagConstraints c)
    	{
        	g.setConstraints(component, c);
        	container.add(component);
    	}

    	public void buildGUI()
    	{
        	setBackground(DemoUtility.bgColor);
        	setLayout(new BorderLayout(10,10));

        	// Label for the demo's title
        	Label titleLabel = new Label("Calendar Demo", Label.CENTER);
        	titleLabel.setFont(DemoUtility.titleFont);

        	// Label for the current month name
        	monthLabel = new Label("", Label.LEFT);
        	monthLabel.setFont(new Font(DemoUtility.titleFont.getName(),
                                    	DemoUtility.titleFont.getStyle(),
                                    	(DemoUtility.titleFont.getSize() * 3)/2));

        	// Make the locale popup menus
        	localeMenu= new Choice();
        	localeMenu.addItemListener(this);
        	int selectMe = 0;
        	
        	for (int i = 0; i < calendars.length; i++) {
            	if (i > 0 &&
                    	calendars[i].getCountry().equals(calendars[i-1].getCountry()) ||
                	i < calendars.length - 1 &&
                    	calendars[i].getCountry().equals(calendars[i+1].getCountry()))
            	{
                	localeMenu.addItem(calendars[i].getDisplayCountry() + " (" +
                                	calendars[i].getDisplayLanguage() + ")");
            	} else {
                	localeMenu.addItem( calendars[i].getDisplayCountry() );
            	}
            	
            	if (calendars[i].equals(kFirstLocale)) {
                	selectMe = i;
            	}
        	}
        	
        	localeMenu.setBackground(DemoUtility.choiceColor);
        	localeMenu.select(selectMe);

        	displayMenu = new Choice();
        	displayMenu.addItemListener(this);
        	
        	selectMe = 0;
        	for (int i = 0; i < locales.length; i++) {
            	if (i > 0 &&
                    	locales[i].getLanguage().equals(locales[i-1].getLanguage()) ||
                	i < locales.length - 1 &&
                    	locales[i].getLanguage().equals(locales[i+1].getLanguage()))
            	{
                	displayMenu.addItem( locales[i].getDisplayName() );
            	} else {
                	displayMenu.addItem( locales[i].getDisplayLanguage());
            	}
            	
            	if (locales[i].equals(kFirstLocale)) {
            	    selectMe = i;
            	}
        	}
        	
        	displayMenu.setBackground(DemoUtility.choiceColor);
        	displayMenu.select(selectMe);

        	// Make all the next/previous/today buttons
        	prevYear = new Button("<<");
        	prevYear.addActionListener(this);
        	prevMonth = new Button("<");
        	prevMonth.addActionListener(this);
        	gotoToday = new Button("Today");
        	gotoToday.addActionListener(this);
        	nextMonth = new Button(">");
        	nextMonth.addActionListener(this);
        	nextYear = new Button(">>");
        	nextYear.addActionListener(this);

        	// The month name and the control buttons are bunched together
        	Panel monthPanel = new Panel();
        	{
            	GridBagLayout g = new GridBagLayout();
            	GridBagConstraints c = new GridBagConstraints();
            	monthPanel.setLayout(g);

            	c.weightx = 1;
            	c.weighty = 1;

            	c.gridwidth = 1;
            	c.fill = GridBagConstraints.HORIZONTAL;
            	c.gridwidth = GridBagConstraints.REMAINDER;
            	add(monthPanel, monthLabel, g, c);

            	c.gridwidth = 1;
            	add(monthPanel, prevYear, g, c);
            	add(monthPanel, prevMonth, g, c);
            	add(monthPanel, gotoToday, g, c);
            	add(monthPanel, nextMonth, g, c);
            	c.gridwidth = GridBagConstraints.REMAINDER;
            	add(monthPanel, nextYear, g, c);
        	}

        	// Stick the menu and buttons in a little "control panel"
        	Panel menuPanel = new Panel();
        	{
            	GridBagLayout g = new GridBagLayout();
            	GridBagConstraints c = new GridBagConstraints();
            	menuPanel.setLayout(g);

            	c.weightx = 1;
            	c.weighty = 1;

            	c.fill = GridBagConstraints.HORIZONTAL;

            	c.gridwidth = GridBagConstraints.RELATIVE;
            	Label l1 = new Label("Holidays");
            	l1.setFont(DemoUtility.labelFont);
            	add(menuPanel, l1, g, c);

            	c.gridwidth = GridBagConstraints.REMAINDER;
            	add(menuPanel, localeMenu, g, c);

            	c.gridwidth = GridBagConstraints.RELATIVE;
            	Label l2 = new Label("Display:");
            	l2.setFont(DemoUtility.labelFont);
            	add(menuPanel, l2, g, c);

            	c.gridwidth = GridBagConstraints.REMAINDER;
            	add(menuPanel, displayMenu, g, c);
        	}

        	// The title, buttons, etc. go in a panel at the top of the window
        	Panel topPanel = new Panel();
        	{
            	topPanel.setLayout(new BorderLayout());

            	//topPanel.add("North", titleLabel);
            	topPanel.add("Center", monthPanel);
            	topPanel.add("East", menuPanel);
        	}
        	add("North", topPanel);

        	// The copyright notice goes at the bottom of the window
        	Label copyright = new Label(DemoUtility.copyright1, Label.LEFT);
        	copyright.setFont(DemoUtility.creditFont);
        	add("South", copyright);

        	// Now create the big calendar panel and stick it in the middle
        	calendarPanel = new CalendarPanel( kFirstLocale );
        	add("Center", calendarPanel);

        	updateMonthName();
    	}

    	private void updateMonthName()
    	{
        	SimpleDateFormat f = new SimpleDateFormat("MMMM yyyyy",
                                                    	calendarPanel.getDisplayLocale());
        	f.setCalendar(calendarPanel.getCalendar());
        	f.setTimeZone(new SimpleTimeZone(0, "UTC"));        // JDK 1.1.2 workaround
        	monthLabel.setText( f.format( calendarPanel.firstOfMonth() ));
    	}
    	
    	/**
    	* Handles the event. Returns true if the event is handled and should not
    	* be passed to the parent of this component. The default event handler
    	* calls some helper methods to make life easier on the programmer.
    	*/
    	public void actionPerformed(ActionEvent e)
    	{
    	    Object obj = e.getSource();
    	    
    	    // *** Button events are handled here.
        	if (obj instanceof Button) {
            	if (obj == nextMonth) {
                	calendarPanel.add(Calendar.MONTH, +1);
            	}
            	else
            	if (obj == prevMonth) {
                	calendarPanel.add(Calendar.MONTH, -1);
            	}
            	else
            	if (obj == prevYear) {
                	calendarPanel.add(Calendar.YEAR, -1);
            	}
            	else
            	if (obj == nextYear) {
                	calendarPanel.add(Calendar.YEAR, +1);
            	}
            	else
            	if (obj == gotoToday) {
                	calendarPanel.set( new Date() );
            	}
            	updateMonthName();
        	}
    	}
    	
    	public void itemStateChanged(ItemEvent e)
        {
            Object obj = e.getSource();
            if (obj == localeMenu) {
            	calendarPanel.setCalendarLocale(calendars[localeMenu.getSelectedIndex()]);
            	updateMonthName();
        	}
        	else 
        	    if (obj == displayMenu) {
            	    calendarPanel.setDisplayLocale(locales[displayMenu.getSelectedIndex()]);
            	    updateMonthName();
            	}
        }
        
        /**
    	* Print out the error message while debugging this program.
    	*/
    	public void errorText(String s)
    	{
        	if (DEBUG)
        	{
            	System.out.println(s);
        	}
    	}
    	
    	protected void processWindowEvent(WindowEvent e)
        {
            System.out.println("event " + e);
            if (e.getID() == WindowEvent.WINDOW_CLOSING) {
            	this.hide();
            	this.dispose();

            	if (applet != null) {
            	    applet.demoClosed();
            	} else {
                    System.exit(0);
            	}
        	}
        }
	}


	private static class CalendarPanel extends Canvas {

    	public CalendarPanel( Locale locale ) {
        	set(locale, locale, new Date());
    	}

    	public void setCalendarLocale(Locale locale) {
        	set(locale, fDisplayLocale, fCalendar.getTime());
    	}

    	public void setDisplayLocale(Locale locale) {
        	set(fCalendarLocale, locale, fCalendar.getTime());
    	}

    	public void set(Date date) {
        	set(fCalendarLocale, fDisplayLocale, date);
    	}

    	public void set(Locale loc, Locale display, Date date)
    	{
        	if (fCalendarLocale == null || !loc.equals(fCalendarLocale)) {
            	fCalendarLocale = loc;
            	fCalendar = Calendar.getInstance(fCalendarLocale);
            	fAllHolidays = Holiday.getHolidays(fCalendarLocale);
        	}
        	if (fDisplayLocale == null || !display.equals(fDisplayLocale)) {
            	fDisplayLocale = display;
            	fSymbols = new DateFormatSymbols(fDisplayLocale);
        	}

        	fStartOfMonth = date;

        	dirty = true;
        	repaint();
    	}

    	public void add(int field, int delta)
    	{
        	synchronized(fCalendar) {
            	fCalendar.setTime(fStartOfMonth);
            	fCalendar.add(field, delta);
            	fStartOfMonth = fCalendar.getTime();
        	}
        	dirty = true;
        	repaint();
    	}

    	public com.ibm.icu.util.Calendar getCalendar() {
        	return fCalendar;
    	}

    	public Locale getCalendarLocale() {
        	return fCalendarLocale;
    	}

    	public Locale getDisplayLocale() {
        	return fDisplayLocale;
    	}


    	public Date firstOfMonth() {
        	return fStartOfMonth;
    	}

    	private Date startOfMonth(Date dateInMonth)
    	{
        	synchronized(fCalendar) {
            	fCalendar.setTime(dateInMonth);             // TODO: synchronization

            	int era = fCalendar.get(Calendar.ERA);
            	int year = fCalendar.get(Calendar.YEAR);
            	int month = fCalendar.get(Calendar.MONTH);

            	fCalendar.clear();
            	fCalendar.set(Calendar.ERA, era);
            	fCalendar.set(Calendar.YEAR, year);
            	fCalendar.set(Calendar.MONTH, month);
            	fCalendar.set(Calendar.DATE, 1);

            	return fCalendar.getTime();
        	}
    	}

    	private void calculate()
    	{
        	//
        	// As a workaround for JDK 1.1.3 and below, where Calendars and time
        	// zones are a bit goofy, always set my calendar's time zone to UTC.
        	// You would think I would want to do this in the "set" function above,
        	// but if I do that, the program hangs when this class is loaded,
        	// perhaps due to some sort of static initialization ordering problem.
        	// So I do it here instead.
        	//
        	fCalendar.setTimeZone(new SimpleTimeZone(0, "UTC"));

        	Calendar c = (Calendar)fCalendar.clone(); // Temporary copy

        	fStartOfMonth = startOfMonth(fStartOfMonth);

        	// Stash away a few useful constants for this calendar and display
        	minDay = c.getMinimum(Calendar.DAY_OF_WEEK);
        	daysInWeek = c.getMaximum(Calendar.DAY_OF_WEEK) - minDay + 1;

        	firstDayOfWeek = Calendar.getInstance(fDisplayLocale).getFirstDayOfWeek();

        	// Stash away a Date for the start of this month

        	// Find the day of week of the first day in this month
        	c.setTime(fStartOfMonth);
        	firstDayInMonth = c.get(Calendar.DAY_OF_WEEK);

        	// Now find the # of days in the month
        	c.roll(Calendar.DATE, false);
        	daysInMonth = c.get(Calendar.DATE);

        	// Finally, find the end of the month, i.e. the start of the next one
        	c.roll(Calendar.DATE, true);
        	c.add(Calendar.MONTH, 1);
        	c.getTime();        // JDK 1.1.2 bug workaround
        	c.add(Calendar.SECOND, -1);
        	Date endOfMonth = c.getTime();

        	//
        	// Calculate the number of full or partial weeks in this month.
        	// To do this I can just reuse the code that calculates which
        	// calendar cell contains a given date.
        	//
        	numWeeks = dateToCell(daysInMonth).y - dateToCell(1).y + 1;

        	// Remember which holidays fall on which days in this month,
        	// to save the trouble of having to do it later
        	fHolidays.setSize(0);

        	for (int h = 0; h < fAllHolidays.length; h++)
        	{
            	Date d = fStartOfMonth;
            	while ( (d = fAllHolidays[h].firstBetween(d, endOfMonth) ) != null)
            	{
                	c.setTime(d);
                	fHolidays.addElement( new HolidayInfo(c.get(Calendar.DATE),
                                        	fAllHolidays[h],
                                        	fAllHolidays[h].getDisplayName(fDisplayLocale) ));

                	d.setTime( d.getTime() + 1000 );    // "d++"
            	}
        	}
        	dirty = false;
    	}

    	static final int INSET = 2;

    	/*
    	* Convert from the day number within a month (1-based)
    	* to the cell coordinates on the calendar (0-based)
    	*/
    	private void dateToCell(int date, Point pos)
    	{
        	int cell = (date + firstDayInMonth - firstDayOfWeek - minDay);
        	if (firstDayInMonth < firstDayOfWeek) {
            	cell += daysInWeek;
        	}

        	pos.x = cell % daysInWeek;
        	pos.y = cell / daysInWeek;
    	}
    	private Point dateToCell(int date) {
        	Point p = new Point(0,0);
        	dateToCell(date, p);
        	return p;
    	}

    	public void paint(Graphics g) {

        	if (dirty) {
            	calculate();
        	}

        	Point cellPos = new Point(0,0);     // Temporary variable
        	Dimension d = getSize();

        	g.setColor(DemoUtility.bgColor);
        	g.fillRect(0,0,d.width,d.height);

        	// Draw the day names at the top
        	g.setColor(Color.black);
        	g.setFont(DemoUtility.labelFont);
        	FontMetrics fm = g.getFontMetrics();
        	int labelHeight = fm.getHeight() + INSET * 2;

        	int v = fm.getAscent() + INSET;
        	for (int i = 0; i < daysInWeek; i++) {
            	int dayNum = (i + minDay + firstDayOfWeek - 2) % daysInWeek + 1;
            	String dayName = fSymbols.getWeekdays()[dayNum];

            	int h = (int) (d.width * (i + 0.5)) / daysInWeek;
            	h -= fm.stringWidth(dayName) / 2;

            	g.drawString(dayName, h, v);
        	}

        	double cellHeight = (d.height - labelHeight - 1) / numWeeks;
        	double cellWidth = (double)(d.width - 1) / daysInWeek;

        	// Draw a white background in the part of the calendar
        	// that displays this month.
        	// First figure out how much of the first week should be shaded.
        	{
            	g.setColor(Color.white);
            	dateToCell(1, cellPos);
            	int width = (int)(cellPos.x*cellWidth);  // Width of unshaded area

            	g.fillRect((int)(width), labelHeight ,
                    	(int)(d.width - width), (int)cellHeight);

            	// All of the intermediate weeks get shaded completely
            	g.fillRect(0, (int)(labelHeight + cellHeight),
                        	d.width, (int)(cellHeight * (numWeeks - 2)));

            	// Now figure out the last week.
            	dateToCell(daysInMonth, cellPos);
            	width = (int)((cellPos.x+1)*cellWidth);  // Width of shaded area

            	g.fillRect(0, (int)(labelHeight + (numWeeks-1) * cellHeight),
                        	width, (int)(cellHeight));

        	}
        	// Draw the X/Y grid lines
        	g.setColor(Color.black);
        	for (int i = 0; i <= numWeeks; i++) {
            	int y = (int)(labelHeight + i * cellHeight);
            	g.drawLine(0, y, d.width - 1, y);
        	}
        	for (int i = 0; i <= daysInWeek; i++) {
            	int x = (int)(i * cellWidth);
            	g.drawLine(x, labelHeight, x, d.height - 1);
        	}

        	// Now loop through all of the days in the month, figure out where
        	// they go in the grid, and draw the day # for each one
        	Font numberFont = new Font("Helvetica",Font.PLAIN,12);
        	// not used Font holidayFont = DemoUtility.creditFont;

        	Calendar c = (Calendar)fCalendar.clone();
        	c.setTime(fStartOfMonth);

        	for (int i = 1, h = 0; i <= daysInMonth; i++) {
            	g.setFont(numberFont);
            	g.setColor(Color.black);
            	fm = g.getFontMetrics();

            	dateToCell(i, cellPos);
            	int x = (int)((cellPos.x + 1) * cellWidth);
            	int y = (int)(cellPos.y * cellHeight + labelHeight);

            	StringBuffer buffer = new StringBuffer();
            	buffer.append(i);
            	String dayNum = buffer.toString();

            	x = x - INSET - fm.stringWidth(dayNum);
            	y = y + fm.getAscent() + INSET;

            	g.drawString(dayNum, x, y);

            	// See if any of the holidays land on this day....
            	HolidayInfo info = null;
            	int count = 0;

            	// Coordinates of lower-left corner of cell.
            	x = (int)((cellPos.x) * cellWidth);
            	y = (int)((cellPos.y+1) * cellHeight) + labelHeight;

            	while (h < fHolidays.size() &&
                    	(info = (HolidayInfo)fHolidays.elementAt(h)).date <= i)
            	{
                	if (info.date == i) {
                    	// Draw the holiday here.
                    	g.setFont(numberFont);
                    	g.setColor(Color.red);

                    	DemoTextBox box = new DemoTextBox(g, info.name, (int)(cellWidth - INSET));
                    	box.draw(g, x + INSET, y - INSET - box.getHeight());

                    	y -= (box.getHeight() + INSET);
                    	count++;
                	}
                	h++;
            	}
        	}
    	}

    	// Important state variables
    	private Locale              fCalendarLocale;    // Whose calendar
    	private Calendar            fCalendar;          // Calendar for calculations

    	private Locale              fDisplayLocale;     // How to display it
    	private DateFormatSymbols   fSymbols;           // Symbols for drawing

    	private Date                fStartOfMonth;      // 00:00:00 on first day of month

    	// Cached calculations to make drawing faster.
    	private transient int minDay;           // Minimum legal day #
    	private transient int daysInWeek;       // # of days in a week
    	private transient int firstDayOfWeek;   // First day to display in week
    	private transient int numWeeks;         // # full or partial weeks in month
    	private transient int daysInMonth;      // # days in this month
    	private transient int firstDayInMonth;  // Day of week of first day in month

    	private transient Holiday[] fAllHolidays;
    	private transient Vector    fHolidays = new Vector(5,5);

    	private transient boolean dirty = true;
	}

	private static class HolidayInfo {
    	public HolidayInfo(int date, Holiday holiday, String name) {
        	this.date = date;
        	this.holiday = holiday;
        	this.name = name;
    	}

    	public Holiday holiday;
    	public int date;
    	public String name;
	}
}

