package controler;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;

/**
 * @author martin
 * Simple calendar
 */
public class SimpleCal {
	/*properties*/
	private final Calendar _cal;
	private final SimpleCal _fst;

	/*constructor*/
	/**
	 * private constructor
	 * use static factory
	 * @param month
	 */
	private SimpleCal(final Calendar month){
		_cal = month;
		if(getDay() == 1)
			_fst = this;
		else
			_fst = onDay(1);
	}

	/*static factory*/
	/**
	 * static factory from todays date
	 * @return new SimpleCal set on today date
	 */
	public static SimpleCal fromToday(){
		return new SimpleCal(new GregorianCalendar());
	}
	/**
	 * static factory from given date
	 * @param day as int
	 * @param month as int
	 * @param year as int
	 * @return new SimpleCal set on given date
	 */
	public static SimpleCal fromDayMonthYear(int day, int month, int year){
		return new SimpleCal(new GregorianCalendar(year, month, day));
	}

	/*getter*/

	/**
	 * getter
	 * @return day of month
	 */
	public int getDay(){
		return _cal.get(Calendar.DAY_OF_MONTH);
	}

	/**
	 * getter
	 * @return month number
	 */
	public int getMonth(){
		return _cal.get(Calendar.MONTH);
	}

	/**
	 * getter
	 * @return year as int
	 */
	public int getYear(){
		return _cal.get(Calendar.YEAR);
	}

	/**
	 * getter
	 * @return week day number
	 */
	public int weekDay(){
		return _cal.get(Calendar.DAY_OF_WEEK);
	}

	/*immutator*/

	/**
	 * change day
	 * @param nuday as int
	 * @return new simplecal with new day
	 */
	public SimpleCal onDay(int nuday){
		return SimpleCal.fromDayMonthYear(nuday,getMonth(), getYear());
	}

	/**
	 * change month
	 * @param numonth as int
	 * @return new simplecal with new month
	 */
	public SimpleCal onMonth(int numonth){
		return SimpleCal.fromDayMonthYear(getDay(),numonth, getYear());
	}

	/**
	 * change year
	 * @param nuyear as int
	 * @return new simplecal with new year
	 */
	public SimpleCal onYear(int nuyear){
		return SimpleCal.fromDayMonthYear(getDay(),getMonth(), nuyear);
	}

	/*construct calendar*/
	/**
	 * getter
	 * @return weekday of the first of the month
	 */
	public int firstWeekDay(){
		return _fst.weekDay();
	}

	/**
	 * getter
	 * @return number of the in the current month
	 */
	public int lastMonthDay(){
		return _cal.getActualMaximum(Calendar.DAY_OF_MONTH);
	}

	//create DAY object
	/**
	 * mapping the month into a table
	 * @param col as int column
	 * @param row as int row
	 * @return day number
	 */
	public Integer getDayAt(int col, int row){
    	int day = row*7 + col+1 - firstWeekDay()+1;
    	if (day < 1 || (day > lastMonthDay()))
    		return null;
        return day;
	}

	/*static function*/
	private static final SimpleDateFormat dayFmt = new SimpleDateFormat("EEEE dd MMMM yyyy");
	private static final SimpleDateFormat timeFmt = new SimpleDateFormat("HH:mm");
	private static final java.text.DateFormatSymbols token = new java.text.DateFormatSymbols();

	public static String getDateStr(final Calendar cal){
		return dayFmt.format(cal.getTime());
	}
	public static String getClockStr(final Calendar cal){
		return timeFmt.format(cal.getTime());
	}
	public static String getWeekDayStr(int i){
		return token.getWeekdays()[i];
	}
	public static String getMonthStr(int i){
		return token.getMonths()[i+1];
	}

	/*test*/
	public static void main(String[] args) {
		SimpleCal c = SimpleCal.fromToday();
		System.out.println(SimpleCal.getMonthStr(c.getMonth()));
		for (int i=1;i<=7;i++)
			System.out.print(SimpleCal.getWeekDayStr(i) + "|");
		System.out.println();
		for (int row=0;row<6;row++){
			for (int col=0;col<7;col++)
				System.out.print(c.getDayAt(col,row) + "|");
			System.out.println();
		}


	}

}
