/*
 *******************************************************************************
 * Copyright (C) 1997-2000, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/demo/calendar/Attic/CalendarPanel.java,v $ 
 * $Date: 2000/10/19 00:27:16 $ 
 * $Revision: 1.6 $
 *
 *****************************************************************************************
 */

package com.ibm.demo.calendar;

import com.ibm.demo.*;

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
//import java.util.*;
import java.net.*;
import java.io.*;

//import java.text.DateFormat;
import com.ibm.text.DateFormat;
//import java.util.SimpleTimeZone;
import com.ibm.util.SimpleTimeZone;
//import java.util.*;
import java.util.Date;
import java.util.Locale;

import com.ibm.util.*;
import com.ibm.text.*;

class CalendarPanel extends Canvas {

    public CalendarPanel( Locale locale ) {
        setLocale(locale);
    }

    public void setLocale(Locale locale) {
        if (fDisplayLocale == null || !fDisplayLocale.equals(locale)) {
            fDisplayLocale = locale;
            dirty = true;

            for (int i = 0; i < fCalendar.length; i++) {
                if (fCalendar[i] != null) {
                    fSymbols[i] = new DateFormatSymbols(fCalendar[i],
                                                        fDisplayLocale);
                }
            }
            String lang = locale.getLanguage();
            leftToRight = !(lang.equals("iw") || lang.equals("ar"));

            repaint();
        }
    }

    public void setDate(Date date) {
        fStartOfMonth = date;
        dirty = true;
        repaint();
    }

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

    public void setColor(int index, Color c) {
        fColor[index] = c;
        repaint();
    }

    public void setCalendar(int index, Calendar c) {
        Date date = (fCalendar[index] == null) ? new Date()
                                               : fCalendar[index].getTime();

        fCalendar[index] = c;
        fCalendar[index].setTime(date);

        fSymbols[index] = new DateFormatSymbols(c, fDisplayLocale);
        dirty = true;
        repaint();
    }

    public Calendar getCalendar(int index) {
        return fCalendar[index];
    }

    public Locale getDisplayLocale() {
        return fDisplayLocale;
    }

    public Date firstOfMonth() {
        return fStartOfMonth;
    }

    private Date startOfMonth(Date dateInMonth)
    {
        synchronized(fCalendar) {
            fCalendar[0].setTime(dateInMonth);

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

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

            return fCalendar[0].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[0].setTimeZone(new SimpleTimeZone(0, "UTC"));

        Calendar c = (Calendar)fCalendar[0].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);
        int firstWeek = c.get(Calendar.WEEK_OF_MONTH);

        // 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();
        int lastWeek = c.get(Calendar.WEEK_OF_MONTH);

        // Calculate the number of full or partial weeks in this month.
        numWeeks = lastWeek - firstWeek + 1;

        dirty = false;
    }

    static final int XINSET = 4;
    static final int YINSET = 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 = this.getSize();

        g.setColor(Color.lightGray);
        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() + YINSET * 2;

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


            double h;
            if (leftToRight) {
                h = d.width*(i + 0.5) / daysInWeek;
            } else {
                h = d.width*(daysInWeek - i - 0.5) / daysInWeek;
            }
            h -= fm.stringWidth(dayName) / 2;

            g.drawString(dayName, (int)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

            if (leftToRight) {
                g.fillRect((int)(width), labelHeight ,
                           d.width - width, (int)cellHeight);
            } else {
                g.fillRect(0, labelHeight ,
                           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

            if (leftToRight) {
                g.fillRect(0, (int)(labelHeight + (numWeeks-1) * cellHeight),
                           width, (int)cellHeight);
            } else {
                g.fillRect(d.width - width, (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

        // Figure out the date of the first cell in the calendar display
        int cell = (1 + firstDayInMonth - firstDayOfWeek - minDay);
        if (firstDayInMonth < firstDayOfWeek) {
            cell += daysInWeek;
        }

        Calendar c = (Calendar)fCalendar[0].clone();
        c.setTime(fStartOfMonth);
        c.add(Calendar.DATE, -cell);

        StringBuffer buffer = new StringBuffer();

        for (int row = 0; row < numWeeks; row++) {
            for (int col = 0; col < daysInWeek; col++) {

                g.setFont(DemoUtility.numberFont);
                g.setColor(Color.black);
                fm = g.getFontMetrics();

                int cellx;
                if (leftToRight) {
                    cellx = (int)((col) * cellWidth);
                } else {
                    cellx = (int)((daysInWeek - col - 1) * cellWidth);
                }

                int celly = (int)(row * cellHeight + labelHeight);

                for (int i = 0; i < 2; i++) {
                    fCalendar[i].setTime(c.getTime());

                    int date = fCalendar[i].get(Calendar.DATE);
                    buffer.setLength(0);
                    buffer.append(date);
                    String dayNum = buffer.toString();

                    int x;

                    if (leftToRight) {
                        x = cellx + (int)cellWidth - XINSET - fm.stringWidth(dayNum);
                    } else {
                        x = cellx + XINSET;
                    }
                    int y = celly + + fm.getAscent() + YINSET + i * fm.getHeight();

                    if (fColor[i] != null) {
                        g.setColor(fColor[i]);
                    }
                    g.drawString(dayNum, x, y);

                    if (date == 1 || row == 0 && col == 0) {
                        g.setFont(DemoUtility.numberFont);
                        String month = fSymbols[i].getMonths()[
                                            fCalendar[i].get(Calendar.MONTH)];

                        if (leftToRight) {
                            x = cellx + XINSET;
                        } else {
                            x = cellx + (int)cellWidth - XINSET - fm.stringWidth(month);
                        }
                        g.drawString(month, x, y);
                    }
                }

                c.add(Calendar.DATE, 1);
            }
        }
    }

    // Important state variables
    private Calendar[]          fCalendar = new Calendar[4];
    private Color[]             fColor = new Color[4];

    private Locale              fDisplayLocale;
    private DateFormatSymbols[] fSymbols = new DateFormatSymbols[4];

    private Date                fStartOfMonth = new Date();     // 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 boolean   leftToRight;

    private transient boolean dirty = true;
}
