/*
 * Copyright 2006-2007 Queplix Corp.
 *
 * Licensed under the Queplix Public License, Version 1.1.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.queplix.com/solutions/commercial-open-source/queplix-public-license/
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 *
 */
package com.queplix.core.client.controls.datefield;

import java.util.Date;

/*
* Class helps to work with date and time
* @author Sultan Tezadov, Sergey Kozmin, Alexander Melnik
*/
public class DateHelper {
    public static int timeOffset;

    public static final int WEEK_LENGHT = 7;
    public static final int WEEK_PER_SCREEN = 6;

    public static final int DAY = 24 * 60 * 60 * 1000;

    public static Date[][] getCalendarDates(Date theDate) {
        Date[][] res = new Date[WEEK_PER_SCREEN][WEEK_LENGHT];
        Date tmp = getLastMondayOfTheMonth(theDate);
        for(int i = 0; i < WEEK_PER_SCREEN; i++) {
            for(int j = 0; j < WEEK_LENGHT; j++) {
                res[i][j] = (Date) tmp.clone();
                tmp.setTime(tmp.getTime() + DAY);
            }
        }
        return res;
    }

    private static Date getLastMondayOfTheMonth(Date theDate) {
        Date res = new Date(theDate.getYear(), theDate.getMonth(), 1);
        int lastMondayDate = 1;
        int month = res.getMonth();
        while(res.getMonth() == month) {
            if(res.getDay() == 1) {
                lastMondayDate = res.getDate();
            }
            res.setDate(res.getDate() + 1);
        }
        res = new Date(theDate.getYear(), theDate.getMonth(), lastMondayDate);
        return res;
    }

    public static CalendarScreen getCalendarDatesAsScreen(Date theDate) {
        Date firstOfMonth = getFirstMonthDate(theDate);
        Date firstOfNextMonth = new Date(theDate.getYear(),
                theDate.getMonth() + 1, 1);
        int firstOfMonthDay = getDayOfWeek(firstOfMonth);
        Date firstOfCalendar = new Date(firstOfMonth.getYear(),
                firstOfMonth.getMonth(), 2 - firstOfMonthDay);
        int[] dates = new int[WEEK_PER_SCREEN * WEEK_LENGHT];

        int lastMonthEnd = 0;
        int currentMonthEnd = 0;

        int k = 0;
        Date current = firstOfCalendar;
        for(int i = 0; i < WEEK_PER_SCREEN; i++) {
            for(int j = 0; j < WEEK_LENGHT; j++) {
                dates[k] = current.getDate();
                if(firstOfMonth.compareTo(current) == 0) {
                    lastMonthEnd = k;
                }
                if(firstOfNextMonth.compareTo(current) == 0) {
                    currentMonthEnd = k;
                }
                k++;
                current = new Date(firstOfCalendar.getYear(),
                        firstOfCalendar.getMonth(),
                        firstOfCalendar.getDate() + k);
            }
        }
        return new CalendarScreen(dates, lastMonthEnd, currentMonthEnd);
    }

    /**
     * Return day of week of the given date.
     * Monday is the first day of the week (1 for Monday and 7 for Sunday)
     */
    private static int getDayOfWeek(Date date) {
        int res = date.getDay();
        return (res == 0) ? WEEK_LENGHT:res;
    }

    public static Date getUserDate() {
        return new Date(System.currentTimeMillis() - timeOffset);
    }

    public static Date getFirstMonthDate(Date theDate) {
        return new Date(theDate.getYear(), theDate.getMonth(), 1);
    }

    public static Date getLastMonthDate(Date theDate) {
        return new Date(theDate.getYear(), theDate.getMonth() + 1, 0);
    }

    public static Date getFirstYearDate(Date theDate) {
        return new Date(theDate.getYear(), 0, 1);
    }

    public static Date getLastYearDate(Date theDate) {
        return new Date(theDate.getYear(), 11, 31);
    }

}