/*
 *******************************************************************************
 * Copyright (C) 1996-2014, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */

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

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Canvas;
import java.awt.Choice;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowEvent;
import java.text.DateFormatSymbols;
import java.util.Date;
import java.util.Locale;
import java.util.Vector;

import com.ibm.icu.dev.demo.impl.DemoApplet;
import com.ibm.icu.dev.demo.impl.DemoTextBox;
import com.ibm.icu.dev.demo.impl.DemoUtility;
import com.ibm.icu.text.DateTimePatternGenerator;
import com.ibm.icu.text.SimpleDateFormat;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.Holiday;

/**
 * CalendarDemo demonstrates how Calendar works.
 */
public class HolidayCalendarDemo extends DemoApplet 
{
    /**
     * For serialization
     */
    private static final long serialVersionUID = 4546085430817359372L;

    /**
     * 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
    {
        /**
         * For serialization
         */
        private static final long serialVersionUID = -7023296782393042761L;

        private static final boolean DEBUG = false;

        //private Locale curLocale = Locale.US; // unused

        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()
        {
            final Locale displayLocale = calendarPanel.getDisplayLocale();
            final String pattern = DateTimePatternGenerator.
                    getInstance(displayLocale).getBestPattern("MMMMy");
            SimpleDateFormat f = new SimpleDateFormat(pattern,
                                                        displayLocale);
            f.setCalendar(calendarPanel.getCalendar());
            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 {

        /**
         * For serialization
         */
        private static final long serialVersionUID = 1521099412250120821L;

        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()
        {
            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)
                {
                    if(d.after(endOfMonth)) {
                        throw new InternalError("Error: for " + fAllHolidays[h].getDisplayName()+
                                "  #" + h + "/"+fAllHolidays.length+": " + d +" is after end of month " + endOfMonth);
                    }
                    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;

                // 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);
                    }
                    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;
    }
}

