/*
 * ICESOFT COMMERCIAL SOURCE CODE LICENSE V 1.1
 *
 * The contents of this file are subject to the ICEsoft Commercial Source
 * Code License Agreement V1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of the
 * License at
 * http://www.icesoft.com/license/commercial-source-v1.1.html
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations under
 * the License.
 *
 * Copyright 2009-2015 ICEsoft Technologies Canada, Corp. All Rights Reserved.
 */
package com.icesoft.faces.facelets.component.util;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;

/**
 * Utility Bean to centralize the date/locale/timezone code.
 *
 * @author ICEfaces Technologies Inc.
 */
public class CalendarViewUtil implements Serializable {

    private TimeZone scheduleTimeZone;

    private static final String MONTH_FORMATTER = "MMMMM";
    private static final String DAY_FORMATTER = "EEEEE";
    private static final String SHORT_DAY_FORMATTER = "E";
    private static final String WEEK_DAY_FORMATTER = "EEE d";

    private SimpleDateFormat timeFormatter =
            new SimpleDateFormat("h:mm a");

    private SimpleDateFormat midNightFormatter =
            new SimpleDateFormat("a");

    // Calendars used to retrieve a Date set to the specific DAY_OF_WEEK
    private static Calendar SUNDAY;
    private static Calendar MONDAY;
    private static Calendar TUESDAY;
    private static Calendar WEDNESDAY;
    private static Calendar THURSDAY;
    private static Calendar FRIDAY;
    private static Calendar SATURDAY;

    // By using Calendar to retrieve a Date object set to the designated
    // DAY_OF_WEEK, we can use an f:convertDateTime tag with the appropriate
    // FORMATTER in the GUI, and locale changes will update the language of 
    // these Strings automatically.
    // This saves us from putting days of the week Strings in a properties file.
    static {
        Calendar sundayCalendar = new GregorianCalendar();
        sundayCalendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        SUNDAY = sundayCalendar;
        Calendar mondayCalendar = new GregorianCalendar();
        mondayCalendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        MONDAY = mondayCalendar;
        Calendar tuesdayCalendar = new GregorianCalendar();
        tuesdayCalendar.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
        TUESDAY = tuesdayCalendar;
        Calendar wednesdayCalendar = new GregorianCalendar();
        wednesdayCalendar.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);
        WEDNESDAY = wednesdayCalendar;
        Calendar thursdayCalendar = new GregorianCalendar();
        thursdayCalendar.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
        THURSDAY = thursdayCalendar;
        Calendar fridayCalendar = new GregorianCalendar();
        fridayCalendar.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
        FRIDAY = fridayCalendar;
        Calendar saturdayCalendar = new GregorianCalendar();
        saturdayCalendar.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
        SATURDAY = saturdayCalendar;
    }

    public static final int DEFAULT_START_HOUR = 7;
    public static final int DEFAULT_HOURS_IN_DAY = 12;
    public static final int ALL_DAY_START_HOUR = 0;
    public static final int ALL_DAY_HOURS_IN_DAY = 24;

    private int startHour = DEFAULT_START_HOUR;
    private int hoursInDay = DEFAULT_HOURS_IN_DAY;

    public CalendarViewUtil() {
        if (scheduleTimeZone == null) {
            // Default to server TimeZone
            scheduleTimeZone = TimeZone.getDefault();
            timeFormatter.setTimeZone(scheduleTimeZone);
            midNightFormatter.setTimeZone(scheduleTimeZone);
        }
    }

    /**
     * This method is called from faces-config if the timeZoneId
     * managed-property is present.
     * <p/>
     * It will override the server TimeZone which is the default.
     *
     * @param timeZoneId of the current session, passed in through faces-config
     */
    public void setTimeZoneId(String timeZoneId) {
        scheduleTimeZone = TimeZone.getTimeZone(timeZoneId);
        timeFormatter.setTimeZone(scheduleTimeZone);
        midNightFormatter.setTimeZone(scheduleTimeZone);
    }

    public Calendar getLocalizedCalendar() {
        return Calendar.getInstance(scheduleTimeZone);
    }

    public String getLocalizedTime(Calendar calendar) {
        // todo: get locale - not required, done in CalendarEvent constructor
        return timeFormatter.format(calendar.getTime());
    }

    public String getLocalizedMidnight(Calendar calendar) {
        // todo: get locale - not required, done in CalendarEvent constructor
        return midNightFormatter.format(calendar.getTime());
    }

    public TimeZone getScheduleTimeZone() {
        return scheduleTimeZone;
    }

    public int getStartHour() {
        return startHour;
    }

    public void setStartHour(int startHour) {
        this.startHour = startHour;
    }

    public int getHoursInDay() {
        return hoursInDay;
    }

    public void setHoursInDay(int hoursInDay) {
        this.hoursInDay = hoursInDay;
    }

    public String getMONTH_FORMATTER() {
        return MONTH_FORMATTER;
    }

    public String getDAY_FORMATTER() {
        return DAY_FORMATTER;
    }

    public String getSHORT_DAY_FORMATTER() {
        return SHORT_DAY_FORMATTER;
    }

    public String getWEEK_DAY_FORMATTER() {
        return WEEK_DAY_FORMATTER;
    }

    public Calendar getSUNDAY() {
        return SUNDAY;
    }

    public Calendar getMONDAY() {
        return MONDAY;
    }

    public Calendar getTUESDAY() {
        return TUESDAY;
    }

    public Calendar getWEDNESDAY() {
        return WEDNESDAY;
    }

    public Calendar getTHURSDAY() {
        return THURSDAY;
    }

    public Calendar getFRIDAY() {
        return FRIDAY;
    }

    public Calendar getSATURDAY() {
        return SATURDAY;
    }

}