/*******************************************************************************
 * Copyright (c) 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.bpel.common.ui.calendar;

import java.text.DateFormatSymbols;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import org.eclipse.bpel.common.ui.Messages;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Region;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;


/**
 * Creates a control that allows the user to select a date from a visual 
 * calendar control.  The control displays a month in a given year as well as
 * a list of days for that month.  Users can select a date by clicking on a day
 * or navigating around the calendar with the arrow keys.
 * 
 * The text graphic below outlines the key features of the calendar control.
 * 
 * <pre>
 *  |-----------------------|
 *  | <|    Month Year   |> |
 *  |-----------------------|
 *  |  S  M  T  W  T  F  S  |
 *  | |------------------|  |
 *  | |                  |  |
 *  | |                  |  |
 *  | |       Days       |  |
 *  | |                  |  |
 *  | |                  |  |
 *  | |------------------|  |
 *  |-----------------------|
 * </pre>
 *
 * These features include:
 *  <ul>
 *		<li> arrow buttons to move to the previous/next month
 *		<li> a title showing the month and year that is displayed in the calendar
 *		<li> a list of the names of each day of the week
 *		<li> a day matrix allowing the user to select days in the current month
 *			 or the last/first days of the next/previous month.
 *	</ul>
 *
 * The length of the day names can be set to a long name (3 characters long) or a 
 * short name (1 character long).  The setLongDayNames provides this functionality.
 */
public class CalendarControl extends Canvas {
	/** The dayMargin size when long day names are used */
	private static final int LONG_DAY_MARGIN = 1;
	
	/** The dayMargin size when short day names are used */
	private static final int SHORT_DAY_MARGIN = 5;

	/** The default number of rows to display in the calendar*/
	private static final int ROW_COUNT = 6;
	
	/** The number of pixels off the edge of the title the next/previous 
	 * arrows will be drawn*/
	private static final int ARROW_OFFSET = 5;
	
	/** The number of pixels between rows in the day matrix */
	private static final int ROW_SPACING = 5;
	
	/** The width of the line separating each column in the day matrix */
	private static final int LINE_WIDTH = 1;
	
	/** The margin size around the days of the week */
	private static final int DAY_MARGIN = 3;	
	
	/** The margin size around the month name*/
	private static final int MONTH_MARGIN = 4;
		
	Calendar calendar = Calendar.getInstance();
	
	private ArrayList<SelectionListener> selectionListeners = new ArrayList<SelectionListener>();
	private CalendarPainter painter;
	private CalendarMouseAdapter mouseListener;
		
	int cellWidth;
	int cellHeight;
	int titleHeight;
	int width;
	int height;
	int lineStart;
	int lineEnd;
	int dayOfMonthMin;
	int dayOfMonthMax; 
	int dayOfWeekMax;
	int startDayOfWeek; 
	int lastDayOfPreviousMonth;
	int[] previousMonth;
	int[] nextMonth;
	
	String title;
	String[] days;
	private String[] months;

	/** The width used to separate day names */
	private int dayMargin;

	/** The selected day of the month */
	int day;
	
	public CalendarControl(Composite parent) {
		super(parent, SWT.NO_BACKGROUND);

		initializeControlContents();
		hookControlListener();
				
		updateVisuals();
	}
	
	public void setTimeZone(String tz) {
		calendar.setTimeZone(TimeZone.getTimeZone(tz));
	}
	
	private void initializeControlContents() {		
		dayOfWeekMax = calendar.getActualMaximum(Calendar.DAY_OF_WEEK);
		
		DateFormatSymbols symbols = new DateFormatSymbols();
		months = symbols.getMonths();
		setLongDayNames(true);
	
		GC gc = new GC(this);
		Point dayMax = findMaximumSize(gc, days);
		Point monthMax = findMaximumSize(gc, months);
		gc.dispose();
		
		cellWidth = dayMax.x + (dayMargin * 2) + LINE_WIDTH;
		cellHeight = dayMax.y + ROW_SPACING;
		
		titleHeight = monthMax.y + (MONTH_MARGIN * 2);
		
		width = dayOfWeekMax * cellWidth;
		
		height = (MONTH_MARGIN * 2) + monthMax.y
			+ (DAY_MARGIN * 2) + dayMax.y
			+ ROW_COUNT * (dayMax.y + ROW_SPACING);
		
		lineStart = titleHeight + dayMax.y + (DAY_MARGIN * 2);
		lineEnd = lineStart + ((dayMax.y + ROW_SPACING) * 6);
		
		// Calculate the length of the lines that make up
		// the triangle button.
		int lineLength = titleHeight - (ARROW_OFFSET * 2); 
		
		// Calculate points of previous button polygon
		previousMonth = new int[6];
		previousMonth[0] = ARROW_OFFSET;
		previousMonth[1] = titleHeight / 2;
		previousMonth[2] = ARROW_OFFSET + (lineLength / 2);
		previousMonth[3] = ARROW_OFFSET;
		previousMonth[4] = ARROW_OFFSET + (lineLength / 2);
		previousMonth[5] = ARROW_OFFSET + lineLength;
		
		// Calculate points of next button polygon
		nextMonth = new int[6];
		nextMonth[0] = width - ARROW_OFFSET;
		nextMonth[1] = titleHeight / 2;
		nextMonth[2] = width - ARROW_OFFSET - (lineLength / 2);
		nextMonth[3] = ARROW_OFFSET;
		nextMonth[4] = width - ARROW_OFFSET - (lineLength / 2);
		nextMonth[5] = ARROW_OFFSET + lineLength;
	}
	
	private void hookControlListener() {
		addKeyListener(new CalendarKeyAdapter());
		
		mouseListener = new CalendarMouseAdapter();
		addMouseListener(mouseListener);
		
		painter = new CalendarPainter(getDisplay());
		addPaintListener(painter);
	}

	private Point findMaximumSize(GC gc, String[] displayStrings) {
		Point max = new Point(0, 0);
		for (int i = 0; i < displayStrings.length; i++) {
			Point size = gc.stringExtent(displayStrings[i]);			
			if (size.x > max.x) {
				max.x = size.x;
			}
			if (size.y > max.y) {
				max.y = size.y;
			}
		}
		return max;
	}
	
	int getMatrixIndex(int x, int y) {
		if (lineStart <= y && lineEnd >= y && x >= 0 && x <= width) {
			int row = (y - lineStart) / cellHeight;
			int col = x / cellWidth;
			
			return (row * dayOfWeekMax) + col + 1;	
		}
		return -1;
	}
	
	void changeMonth(boolean next) {
		if (day > dayOfMonthMax) {
			day = dayOfMonthMax;
		} else if (day < dayOfMonthMin) {
			day = dayOfMonthMin;
		}
		
		if (next) {
			calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
		} else {
			calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
		}
		updateVisuals();
	}
		
	void updateVisuals() {		
		// Set calendar to first day of month so no wrapping occurs
		// whem the month is set
		calendar.set(Calendar.DAY_OF_MONTH, dayOfMonthMin);
		
		// Find first and last days of month
		dayOfMonthMin = calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
		dayOfMonthMax = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
		
		// Find the day which the first of the month falls on
		calendar.set(Calendar.DAY_OF_MONTH, dayOfMonthMin);
		startDayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);

		// Find the last day of the previous month
		calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
		lastDayOfPreviousMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
		calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
						
		// Reset the day of the month.  If the day is greater
		// than the last day in the month (i.e. current day is 31
		// and switched to a month with 30 days), set day to the
		// last day of the month.
		if (day > dayOfMonthMax) {
			day = dayOfMonthMax;
		}

		// Cache new title and title width
		title = NLS.bind(Messages.CalendarControl_title, (new Object[] { months[calendar.get(Calendar.MONTH)], String.valueOf(calendar.get(Calendar.YEAR)) })); 
		
		// Redraw the calendar
		CalendarControl.this.redraw();
	}
	
	void fireSelectionChanged() {
		Event e = new Event();
		e.widget = this;
		e.data = getSelectedDate();
		
		for (int i = 0; i < selectionListeners.size(); i++) {
			SelectionListener listener = selectionListeners.get(i);
			SelectionEvent se = new SelectionEvent(e);
			listener.widgetSelected(se);
			
			if (!se.doit) break;
		}
	}
	
	/**
	 * Adds the listener to the collection of listeners who will be notified when the 
	 * receiver's selection changes, by sending it one of the messages defined in the 
	 * SelectionListener interface.
	 * 
	 * @param listener the listener which should be notified 
	 */
	public void addSelectionListener(SelectionListener listener) {
		if (listener != null && !selectionListeners.contains(listener)) {
			selectionListeners.add(listener);
		}
	}
	
	/**
	 * Removes the listener from the collection of listeners who will be notified when
	 * the receiver's selection changes. 
	 * 
	 * @param listener the listener which should no longer be notified 
	 */
	public void removeSelectionListener(SelectionListener listener) {
		if (listener != null) {
			selectionListeners.remove(listener);
		}
	}
	
	/**
	 * Returns the date selected in the calendar control.
	 * 
	 * @return the date selected in the calendar control.
	 */
	public Date getSelectedDate() {
		calendar.set(Calendar.DAY_OF_MONTH, day);
		Date date = calendar.getTime();
		calendar.set(Calendar.DAY_OF_MONTH, dayOfMonthMin);
		
		return date;
	}
	
	/**
	 * Sets the date that is selected in the calendar control. If the date is null
	 * the current date will be used as the selected date.
	 * 
	 * @param the new selected date for the calendar.
	 */
	public void setSelectedDate(Date selectedDate) {
		if (selectedDate == null) {
			selectedDate = new Date();
		}
		calendar.setTime(selectedDate);
		
		day = calendar.get(Calendar.DAY_OF_MONTH);
		
		updateVisuals();
	}
	
	/**
	 * Determines whether the calendar is set to use short or long 
	 * day names.
	 * 
	 * A short day name is the first character of a day name.  For example,
	 * the short day name for Saturday would be S. Long day names are a compressed 
	 * form of the full day name. For example, the long day name for Saturday would
	 * be Sat.
	 * 
	 * @return Returns true if the calendar is displaying long names or false if it
	 * 		   is displaying short names.
	 */
	public boolean isLongDayNames() {
		return dayMargin == LONG_DAY_MARGIN;
	}
	
	/**
	 * Configures the calendar to use either short or long day names.
	 * 
	 * @param useLongDayNames If useLongDayNames is true, the calendar will display
	 * 						  long day names, else it will display short day names.
	 */
	public void setLongDayNames(boolean useLongDayNames) {
		DateFormatSymbols symbols = new DateFormatSymbols();
		days = symbols.getShortWeekdays();
		
		if (useLongDayNames) {
			dayMargin = LONG_DAY_MARGIN;
		} else {
			dayMargin = SHORT_DAY_MARGIN;
			
			for (int i = 0; i < days.length; i++) {
				if (days[i].length() != 0) {
					days[i] = days[i].substring(0, 1);	
				}
			}
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.swt.widgets.Widget#dispose()
	 */
	@Override
	public void dispose() {	
		painter.dispose();
		mouseListener.dispose();
		
		super.dispose();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.swt.widgets.Control#computeSize(int, int, boolean)
	 */
	@Override
	public Point computeSize(int wHint, int hHint, boolean changed) {
		return new Point(width, height);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.swt.widgets.Control#computeSize(int, int)
	 */
	@Override
	public Point computeSize(int wHint, int hHint) {
		return new Point(width, height);
	}
	

	/**
	 * Responsible for handling all keyboard events of the calendar. The following
	 * are a list of commands the key adapter listens for and their associated actions.
	 * 
	 * <ul>
	 * 	<li>Shift+Left - Change the calendar month to the previous month.
	 *  <li>Shift+Right - Change the calendar month to the next month.
	 *  <li>Up/Down - Move the day selection in the calendar up or down.
	 *  <li>Left/Right - Move the day selection in the calendar left or right.
	 * </ul>
	 * 
	 * If the new day that is selected is in the next/previous month, the calendar will
	 * change its display to show that month.
	 */
	private class CalendarKeyAdapter extends KeyAdapter {
		@Override
		public void keyPressed(KeyEvent e) {
			int dayChange = 0;
			int monthChange = 0;
			
			switch (e.keyCode) {
				case SWT.ARROW_UP:
					if (day - dayOfWeekMax >= dayOfMonthMin) {
						dayChange -= dayOfWeekMax;
					} else {
						calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
						int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); 
						calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
						
						day = (day - dayOfWeekMax) + lastDay;

						monthChange = -1;
					}
					break;
				case SWT.ARROW_DOWN:
					if (day + dayOfWeekMax <= dayOfMonthMax) {
						dayChange += dayOfWeekMax;
					} else {
						day = (day + dayOfWeekMax) - dayOfMonthMax;
						monthChange = 1;
					}
					break;
				case SWT.ARROW_LEFT:
					if ((e.stateMask & SWT.SHIFT) != 0) {
						changeMonth(false);
					} else {
						if (day != dayOfMonthMin) {
							dayChange--;
						} else {
							calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
							day = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); 
							calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
							
							monthChange = -1;
						}
					}
					break;
				case SWT.ARROW_RIGHT:
					if ((e.stateMask & SWT.SHIFT) != 0) {
						changeMonth(true);
					} else {
						if (day != dayOfMonthMax) {
							dayChange++;
						} else {
							day = dayOfMonthMin;
							monthChange = 1;
						}	
					}
					break;
			}
			
			if (dayChange != 0) {
				day += dayChange;
				CalendarControl.this.redraw();
			}
			
			if (monthChange != 0) {
				calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + monthChange);
				updateVisuals();
			}
			
			if (dayChange != 0 || monthChange != 0) {
				fireSelectionChanged();
			}
		}
	}
	
	/**
	 * Responsible for handling all mouse events of the calendar.  The mouse adapter 
	 * implements the following behaviour:
	 * 
	 * <ul>
	 * 	<li>On mouse down on the left/right arrows in the title, the month displayed
	 * 		on the calendar will shift to the previous/next month.
	 * 	<li>On mouse down on a day, the day that is clicked is selected.
	 * </ul>  
	 * 
	 * Note: dispose must be called on this object to release operating system 
	 * 		 resources.
	 */
	private class CalendarMouseAdapter extends MouseAdapter {
		private Region previousRegion;
		private Region nextRegion;
		
		public CalendarMouseAdapter() {
			previousRegion = new Region();
			previousRegion.add(previousMonth);
			
			nextRegion = new Region();
			nextRegion.add(nextMonth);
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
		 */
		@Override
		public void mouseDown(MouseEvent e) {
			boolean selectionChanged = false;
			
			if (e.y > lineStart && e.y < lineEnd) {
				int offset = (startDayOfWeek == calendar.getFirstDayOfWeek()) ? dayOfWeekMax : 0;
				
				int selectedDay = getMatrixIndex(e.x, e.y) - startDayOfWeek + 1 - offset;
				if (selectedDay > dayOfMonthMax) {
					day = selectedDay - dayOfMonthMax;
					changeMonth(true);
				} else if (selectedDay < dayOfMonthMin) {
					calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
					day = calendar.getActualMaximum(Calendar.DAY_OF_MONTH) + selectedDay;
					calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
					changeMonth(false);
				} else {
					day = selectedDay;
				}
				
				selectionChanged = true;
				CalendarControl.this.redraw();
			} else if (nextRegion.contains(e.x, e.y)) {
				calendar.set(Calendar.MONTH,
						calendar.get(Calendar.MONTH) + 1);
				updateVisuals();
				selectionChanged = true;
			} else if (previousRegion.contains(e.x, e.y)) {
				calendar.set(Calendar.MONTH, 
						calendar.get(Calendar.MONTH) - 1);
				updateVisuals();
				selectionChanged = true;
			}
			
			if (selectionChanged) {
				fireSelectionChanged();
			}
		}
		
		public void dispose() {
			if (previousRegion != null) {
				previousRegion.dispose();
				previousRegion = null;
			}
			
			if (nextRegion != null) {
				nextRegion.dispose();
				nextRegion = null;
			}
		}
	}
	
	/**
	 * The paint listener for the control.  It is responsible for drawing the 
	 * calendar control on the canvas.  It is also responsible for creating and
	 * disposing of the resources (i.e. colours, fonts, images) that are required
	 * for drawing the control.
	 * 
	 * Note: dispose must be called on this object to release operating system 
	 * 		 resources.
	 */
	private class CalendarPainter implements PaintListener {

		private int currentDay;
		private int currentMonth;
		private int currentYear;
		
		private Color background;
		private Color foreground;
		private Color titleBackground;
		private Color titleForeground;
		private Color lineForeground;
		private Color disabledForeground;
		private Font currentDayFont;
		private Image buffer;
				
		public CalendarPainter(Display display) {
			currentDay = calendar.get(Calendar.DAY_OF_MONTH);
			currentMonth = calendar.get(Calendar.MONTH);
			currentYear = calendar.get(Calendar.YEAR);
			
			foreground = display.getSystemColor(SWT.COLOR_LIST_FOREGROUND);
			background = display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
			titleBackground = display.getSystemColor(SWT.COLOR_LIST_SELECTION);
			titleForeground = display.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT);
			
			// FIXME The SWT.COLOR_GRAY should be replaced with the disabled color for text.
			//		 Bug 72207 requests this color constant (https://bugs.eclipse.org/bugs/show_bug.cgi?id=72207)
			lineForeground = display.getSystemColor(SWT.COLOR_GRAY);
			disabledForeground = display.getSystemColor(SWT.COLOR_GRAY);
			currentDayFont = createBoldFont(getFont());
			
			buffer = new Image(display, width, height);
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent)
		 */
		public void paintControl(PaintEvent e) {
			GC gc = new GC(buffer);
			gc.setBackground(background);
			gc.setForeground(foreground);
			gc.fillRectangle(0, 0, width, height);
			
			drawMonthName(gc);
			drawDayNames(gc);
			
			int predayCount = (startDayOfWeek == calendar.getFirstDayOfWeek()) ? dayOfWeekMax : startDayOfWeek - 1;
			
			drawDayRange(gc, 0, lastDayOfPreviousMonth - predayCount + 1, predayCount, true);				
			drawDayRange(gc, predayCount, dayOfMonthMin, dayOfMonthMax, false);
			drawDayRange(gc, dayOfMonthMax + predayCount, 1, (ROW_COUNT * dayOfWeekMax) - predayCount - dayOfMonthMax, true);
			
			drawDayLines(gc);
			
			e.gc.drawImage(buffer, 0, 0);
			gc.dispose();
		}
		
		public void dispose() {
			if (currentDayFont != null) {
				currentDayFont.dispose();
				currentDayFont = null;
			}
			
			if (buffer != null) {
				buffer.dispose();
				buffer = null;
			}
		}
		
		private void drawMonthName(GC gc) {
			Color gcBackground = gc.getBackground();
			Color gcForeground = gc.getForeground();

			// Draw title rectangle and month name
			gc.setBackground(titleBackground);
			gc.setForeground(titleForeground);		
			gc.fillRectangle(0, 0, width, titleHeight);
			gc.drawString(title, (width - gc.stringExtent(title).x) / 2, MONTH_MARGIN);
			gc.setBackground(gcBackground);
			gc.setForeground(gcForeground);

			// Draw next/previous month arrows
			gc.fillPolygon(previousMonth);
			gc.fillPolygon(nextMonth);
		}
		
		private void drawDayNames(GC gc) {
			int x = 0;
			int y = titleHeight + DAY_MARGIN;

			int i = calendar.getFirstDayOfWeek();
			do {
				if (days[i] != null && days[i].length() != 0) {
					Point size = gc.stringExtent(days[i]);
					
					gc.drawString(days[i], ((cellWidth - size.x) / 2) + 1 + x, y);
					x += cellWidth;
				}
				i = (i + 1) % days.length;
			} while (i != calendar.getFirstDayOfWeek());
		}
		
		private void drawDayRange(GC gc, int index, int startDay, int length, boolean disabled) {
			int x = (index % dayOfWeekMax) * cellWidth;
			int y = (index / dayOfWeekMax) * cellHeight + lineStart;
			int dayOfWeek = (index % dayOfWeekMax) + 1;
			
			Color gcBackground = gc.getBackground();
			Color gcForeground = gc.getForeground();
			Font gcFont = gc.getFont();
					
			if (disabled) {
				gc.setForeground(disabledForeground);
			}
			
			for (int i = startDay; i < startDay + length; i++) {
				String displayString = String.valueOf(i);
				
				if (!disabled && i == day) {
					gc.setBackground(titleBackground);
					gc.setForeground(titleForeground);
				}
				if (!disabled && currentDay == i && currentMonth == calendar.get(Calendar.MONTH) && currentYear == calendar.get(Calendar.YEAR)) {
					gc.setFont(currentDayFont);
				}
				
				Point size = gc.stringExtent(displayString);			
				gc.drawString(displayString, ((cellWidth - size.x) / 2) + 1 + x, y);

				if (!disabled && i == day) {
					gc.setBackground(gcBackground);
					gc.setForeground(gcForeground);
				}
				if (!disabled && currentDay == i && currentMonth == calendar.get(Calendar.MONTH) && currentYear == calendar.get(Calendar.YEAR)) {
					gc.setFont(gcFont);
				}
				
				if (dayOfWeek % dayOfWeekMax == 0 && i != dayOfMonthMax) {
					y += cellHeight;
					x = 0;
				} else {
					x += cellWidth;
				}
				dayOfWeek = (dayOfWeek + 1) % dayOfWeekMax;
			}
			
			if (disabled) {
				gc.setForeground(gcForeground);	
			}
		}
		
		private void drawDayLines(GC gc) {
			int x = cellWidth;
			Color gcForeground = gc.getForeground();
			
			gc.setForeground(lineForeground);
			for (int i = 1; i < dayOfWeekMax; i++) {
				gc.drawLine(x, lineStart, x, lineEnd);
				x += cellWidth;
			}
			gc.setForeground(gcForeground);
		}
		
		private Font createBoldFont(Font font) {
			FontData[] data = font.getFontData();
			for (int i = 0; i < data.length; i++) {
				data[i].setStyle(data[i].getStyle() | SWT.BOLD);
			}
			return new Font(Display.getCurrent(), data);
		}
	}
}