<?php
// Modification log
// (date)       (author)    (activity/purpose)
//
// Todo
// (date)       (author)    (activity/purpose)
//

assert_options(ASSERT_WARNING0);
require_once 
'classes/XML/class.XmlNode.php';

/**
 * Enumeration of months
 * @access public
 */
define('M_JANUARY''1');
define('M_FEBRUARY''2');
define('M_MARCH''3');
define('M_APRIL''4');
define('M_MAY''5');
define('M_JUNE''6');
define('M_JULY''7');
define('M_AUGUST''8');
define('M_SEPTEMBER''9');
define('M_OCTOBER''10');
define('M_NOVEMBER''11');
define('M_DECEMBER''12');


/**
 * Creates the basic date values etc for a specified month
 *
 * This class creates a basic representation of a month, providing the dates of the days
 * each week, and the weeknumbers of each week.
 *
 * @author Tommy Gildseth <tommy@akili.no>;
 * @author Akili AS <post@akili.no>;
 * @copyright Akili AS, Sept 2003
 * @access public
 * @package Calendar
 */
class Month
    
{
    
//{{{ Class variables
    /**
     * @var integer $_month The number of the month from 1 - 12, of the month the
     *                      object refers to.
     * @access private
     */
    
var $_month;

    
/**
     * @var integer $_year The year the month object refers to
     * @access private
     */
    
var $_year;

    
/**
     * @var array   $_week A 2d array containing the weeks of the month
     * @access private
     */
    
var $_week = array();

    
/**
     * @var array   $_weekNum A 2d array containing the weeks of the month
     * @access private
     */
    
var $_weekNum = array();

    
//}}}

    //{{{Constructor
    /**
     * Constructor for the Month class.
     *
     * @param   integer $month  The month which should be displayed.
     * @param   integer $year   The year which contains the month
     * @access public
     */
    
function Month$month$year )
        {
        
$this->_month $month;
        
$this->_year $year;
        
$this->_createMonth($month$year);
        }
//}}}end Constructor

    //{{{ _createMonth
    /**
     * Does the job of calculating the days of the month
     *
     * Creates a 2d array to keep each week, with the days dates as the second
     * dimension, and an array containing the week numbers of the weeks in $month
     *
     * @param   integer $month  The month which should be displayed.
     * @param   integer $year   The year which should be displayed
     * @access private
     */
    
function _createMonth$month$year )
        {
        
//Get timestamp for first and last day of the month
        
$firstDayTS mktime 000$month1$year);
        
$lastDayTS mktime 000$month+10$year);

        
//Get weeknumber of first week of the month
        
$week date('W'$firstDayTS);

        
//Get weekday number of first and last day of the month(ie Mon=1, Tues=2 etc etc.)
        //PHP actually thinks sunday is day number 0 and not 7 so we need to rectify
        //this "mistake".
        
$firstDay date('w'$firstDayTS);
        
$firstDay = ($firstDay == '0')?7:$firstDay;
        
$lastDay date('w'$lastDayTS);
        
$lastDay = ($lastDay == '0')?7:$lastDay;

        
//Find how many days from the first week belong to the previous month.
        
$firstDay = ($firstDay-1) * (-1);
        
//mktime ( int hour, int minute, int second, int month, int day, int year [, int is_dst])
        
$daysInMonth date('t'$firstDayTS);
        while(
$firstDay $daysInMonth)
            {
            if (
$week >= 52)
                
$week $week date('W'mktime 000$month$firstDay+7$year));
            
$this->_weekNum[] = $week++;
            
$this->_createWeek($firstDay,
                               
$month,
                               
$year);
            
$firstDay += 7;
            }
        }
//}}}end _createMonth

    //{{{ _createWeek
    /**
     * Create an array containing the dates of the days in the week starting at $from
     *
     * @param   integer $from   The day of the month which the weeks first day is on.
     * @param   integer $month  The month containing this week
     * @param   integer $year   The year containing this week
     * @access private
     */
    
function _createWeek$from$month$year )
        {
        
$daysInMonth date('t'mktime 000$month1$year));
        
$daysInPrevMonth date('t'mktime 000$month0$year));

        
$dayNumbers = array();
        for (
$i 1$i <= 7; ++$i)
            {
            if ((
$from +$i) < 1//If previous month
                
{
                
//$from is a negative number, therefor + and not -
                
$day $daysInPrevMonth $from $i;
                }
            else if ((
$from +$i) > $daysInMonth//If next month
                
{
                
$day $from $i $daysInMonth;
                }
            else
                {
                
$day $from+$i;
                }
            
$dayNumbers[] = $day;
            }
        
$this->_week[] = $dayNumbers;
        }
//}}}end _createWeek

    
function getMonth( )
        {
        return 
$this->_month;
        }

    function 
getYear( )
        {
        return 
$this->_year;
        }

    function 
getWeeks( )
        {
        return 
$this->_week;
        }

    function 
getWeekNum( )
        {
        return 
$this->_weekNum;
        }

    function 
getRootNode( )
        {
        
$root = new XmlNode('month');
        
$root->addChild('.', new XmlNode('nr'null$this->_month));
        
$root->addChild('.', new XmlNode('year'null$this->_year));

        
$weeks count($this->_week);
        for (
$i 0$i $weeks; ++$i)
            {
            
$week = new XmlNode('week');
            
$week->addChild('.', new XmlNode('nr'null$this->_weekNum[$i]));
            foreach(
$this->_week[$i] as $dayNr)
                {
                
$day = new XmlNode('day');
                
$day->addChild('.', new XmlNode('nr'null$dayNr));
                
$day->addChild('.', new XmlNode('ts',
                                                
null,
                                                
mktime(0,0,0,
                                                       
$this->_month,
                                                       
$dayNr,
                                                       
$this->_year)));
                
$week->addChild('.'$day);
                unset(
$day);
                }

            
$root->addChild('.'$week);
            unset (
$week);
            }
        return 
$root;
        }

    function 
getXmlMonth( )
        {
        
$root $this->getRootNode();
        return 
$root->getXmlString();
        }
    }
?>