<?php

$file = trim(preg_replace("'[\\\\/]+'", "/", (dirname(__FILE__)."/lang/".LANGUAGE_ID."/component.php")));
__IncludeLang($file);

define("CLD_MARKSUN", 1);

/**
 * Опция отображения календаря. Определяет, отмечать ли субботы и воскресенья с 
 * помощью CSS класса.
 */
define("CLD_MARKSATSUN", 2);

/**
 * Опция отображения календаря. Определяет, считать ли первым днём недели 
 * понедельник или воскресенье. По-умолчанию первым считается воскресенье.
 */
define("CLD_MONDAYS", 2);

/**
 * Опция отображения календаря. Определяет, использовать ли переносы строки 
 * в генерируемом HTML коде. Необходимо только для отладки. По-умолчанию 
 * переносы выключены.
 */
define("CLD_BREAKS", 8);
if (!class_exists('FranchiseCalendar')) {
	class FranchiseCalendar {
		
		var $change_days = "N";
		
		var $monthsRes = array();
		/**
		 * Массив для хранения праздничных дней с датами.
		 * @var array
		 * @see addUDateHoliday(), addDateHoliday(), removeUDateLink(), 
		 * removeDateLink(), removedateHolidays()
		 * @access private
		 */
		var $dateHolidays = array();
		
		/**
		 * Массив для хранения предпраздничных дней с датами.
		 * @var array
		 * @see addUDateTitle(), addDateTitle(), removeUDateTitle(), 
		 * removeDateTitle(), removedatePreHolidays()
		 * @access private
		 */
		var $datePreHolidays = array();
		
		/**
		 * Массив для хранения рабочих дней с датами.
		 * @var array
		 * @see addUDateTitle(), addDateTitle(), removeUDateTitle(), 
		 * removeDateTitle(), removedatePreHolidays()
		 * @access private
		 */
		var $dateWorkdays = array();
		
		
		/**
		 * Язык, на котором будут отображаться названия месяцев и дней недели 
		 * в календаре. Значение переменной должно соответствовать одному 
		 * из индексов в массивах $MONTHES и $DOWS.
		 * @var string
		 * @see setLang()
		 * @access private
		 */
		var $lng = true;
		var $showTitle= true;
		var $showYear= false;
		var $today = false;
		var $addMonthChange=false;
		
		/**
		 * Префикс, используемый для имён всех CSS классов
		 * @var string
		 * @see setCssPrefix()
		 * @access private
		 */
		var $cssPrefix;
		
		/**
		 * Опции отображения календаря. Значение переменной задаётся с помощью
		 *  констант CLD_*, перечислямых через двоичное OR.
		 * @var int
		 * @see setOptions()
		 * @access private
		 */
		var $options = false;
		
		/**
		 * Конструктор
		 * @access public
		 * @param string $_lng Язык, на котором будут выводиться названия дней 
		 * недели и месяцев. После создания объекта он может быть переопределён 
		 * с помощью метода setLang().
		 * @param int $_options Параметры календаря, задаваемые через двоичное OR 
		 * (см. константы CLD_*). После создания объекта, опции можно 
		 * переопределять методом setOptions().
		 * @param int $_cssPrefix Префикс, используемый для имён всех CSS классов. 
		 * После создания объекта он может быть переопределён с помощью метода 
		 * setCssPrefix().
		 * @see setLang(), setOptions(), setCssPrefix()
		 */
		function Calendar($_lng = 'ru', $_options = false, $_cssPrefix = '') {
			// global $DOWS;
			// if(!isset($DOWS[$_lng])) {
				// trigger_error("Undefined language was specified.", E_USER_WARNING);
				// return false;
			// }
			// $this->dows = $DOWS[$_lng];
			// $this->setLang($_lng);
			$this->setOptions($_options);
			$this->setCssPrefix($_cssPrefix);
		}
		
		function getMonthsRes() {
			return $this->monthsRes;
		}
		
		/**
		 * Задаёт язык отображения названий дней недели и месяцев в календаре.
		 * @param string $_lng Код языка. Указанное значение должно соответствовать 
		 * индексам в глобальных массивах $DOWS и $MONTHES. По-умолчанию 
		 * используется английский.
		 * @return bool В зависимости от того, корректный ли задан код языка, метод 
		 * возвращает true или false.
		 */
		function setLang($_lng) {
			global $MONTHES;
			global $DOWS;
			if(isset($MONTHES[$_lng]) && isset($DOWS[$_lng])) {
				$this->lng = $_lng;
				return true;
			} else {
				trigger_error("Calendar language not defined: '".$_lng."'", 
					E_USER_WARNING);
				return false;
			}
		}
		
		/**
		 * Задаёт параметры календаря, перечисляемые через двоичное OR 
		 * (см. константы CLD_*).
		 * @param string $_options Параметры, заданные через двоичное OR.
		 * @return void
		 * @example $clndr->setOptions(CLD_MONDAYS | CLD_MARKSATSUN)
		 */
		function setOptions($_options) {
			$this->options = $_options;
		}
		
		/**
		 * Задаёт префикс, используемый для имён всех CSS классов. С помощью 
		 * этого метода, можно изменять стилевое оформление календаря в рантайме.
		 * @param string $_cssPrefix Строковое значение, с которого начинаются все 
		 * CSS классы.
		 * @return void
		 */
		function setCssPrefix($_cssPrefix) {
			$this->cssPrefix = $_cssPrefix;
		}
		
		/**
		 * Добавляет гиперссылку для заданной даты. Если ссылка была уже задана, 
		 * она будет переопределена.
		 * @access public
		 * @param int $_date Дата в формате Unix timestamp, к которой будет 
		 * привязана ссылка. Можно задавать "неточную" дату - значение часов, минут 
		 * и секунд игнорируется.
		 * @param string $_url Ссылка
		 * @return void
		 * @see addDateHoliday(), removeUDateLink(), removeDateLink(), 
		 * removedateHolidays()
		 */
		function addUDateHoliday($_date, $_title) {
			$d = getdate($_date);
			$curMonth = (int)$d["mon"];
			$curYear=$d["year"];	
			$d = mktime(0, 0, 0, $d["mon"], $d["mday"], $d["year"]);
			$this->dateHolidays[$d] = $_title;	
			$wDay=date("w",$d);			
			if($wDay==6)
			{
				if ($this->change_days=='N')
				{
					if(!$this->dateHolidays[$d-24*60*60] && !$this->datePreHolidays[$d-24*60*60] && !$this->dateWorkdays[$d-24*60*60])
					{	
						$this->dateHolidays[$d-24*60*60] = $_title;
						$newMonth=(int)date("m",$d-24*60*60);
						$newYear=(int)date("Y",$d-24*60*60);
						if($curMonth!=$newMonth && $curYear==$newYear)
						{	
							$this->genMonth($this->monthsRes[$newMonth]['DAY_START'], $newMonth, $curYear);
						}
						if(!$this->dateHolidays[$d-2*24*60*60] && !$this->datePreHolidays[$d-2*24*60*60] && !$this->dateWorkdays[$d-2*24*60*60])
						{
							$this->addUDatePreHoliday($d-2*24*60*60,$_title)	;
							$newMonth=(int)date("m",$d-2*24*60*60);
							$newYear=(int)date("Y",$d-2*24*60*60);
							if($curMonth!=$newMonth && $curYear==$newYear)
							{	
								$this->genMonth($this->monthsRes[$newMonth]['DAY_START'], $newMonth, $curYear);
							}
						}
					}
				}
				else
				{
					$this->dateHolidays[$d] = $_title;
					$this->addUDatePreHoliday($d-24*60*60,$_title);
				}
				
				
			}	
			elseif($wDay==0)
			{			
				if ($this->change_days=='N')
				{
					if(!$this->dateHolidays[$d+24*60*60] && !$this->datePreHolidays[$d+24*60*60] && !$this->dateWorkdays[$d+24*60*60])
					{
						$this->dateHolidays[$d+24*60*60] = $_title;
					}
				}
				else
				{
					$this->dateHolidays[$d] = $_title;
				}
			}
			else
			{			
				if(!$this->dateHolidays[$d-24*60*60] && !$this->datePreHolidays[$d-24*60*60] && !$this->dateWorkdays[$d-24*60*60])
				{
					$this->addUDatePreHoliday($d-24*60*60,$_title);
					$newMonth=(int)date("m",$d-24*60*60);
					$newYear=(int)date("Y",$d-24*60*60);
					if($curMonth!=$newMonth && $curYear==$newYear)
					{	
						$this->genMonth($this->monthsRes[$newMonth]['DAY_START'], $newMonth, $curYear);
					}
				}
			}
		}
		function addUToday($_date, $_title) {
			$d = getdate($_date);
			$curMonth = (int)$d["mon"];
			$curYear=$d["year"];	
			$d = mktime(0, 0, 0, $d["mon"], $d["mday"], $d["year"]);
			$this->today[$d] = $_title;			
		}
		
		/**
		 * Добавляет гиперссылку для заданной даты. Отличается от addUDateHoliday 
		 * только форматом, в котором определяется дата. Если ссылка была уже 
		 * задана, она будет переопределена.
		 * @access public
		 * @param int $_day Число
		 * @param int $_month Месяц
		 * @param int $_year Год
		 * @param string $_url Ссылка
		 * @see addUDateHoliday(), removeUDateLink(), removeDateLink(), 
		 * removedateHolidays()
		 */
		function addDateHoliday($_day, $_month, $_year, $_title) {
			$this->addUDateHoliday(mktime(0, 0, 0, $_month, $_day, $_year), $_title);
			return true;
		}
		
		function addToday($_day, $_month, $_year, $_title) {
			$this->addUToday(mktime(0, 0, 0, $_month, $_day, $_year), $_title);
			return true;
		}
		
		/**
		 * Удаляет ссылку для заданной даты (если она определена).
		 * @access public
		 * @param int $_date Дата, для которой необходимо удалить ссылку (имеет 
		 * значение год, месяц и день)
		 * @see addUDateHoliday(), addDateHoliday(), removeDateLink(), removedateHolidays()
		 * @return void
		 */
		function removeUDateHoliday($_date) {
			$d = gethate($_date);
			$d = mktime(0, 0, 0, $d["mon"], $d["mday"], $d["year"]);
			unset($this->dateHolidays[$d]);
		}
		
		/**
		 * Удаляет ссылку для заданной даты (если она определена). Отличается 
		 * от removeUDateLink только форматом, в котором определяется дата. 
		 * @access public
		 * @param int $_day Число
		 * @param int $_month Месяц
		 * @param int $_year Год
		 * @see addUDateHoliday(), addDateHoliday(), removeUDateLink(), removedateHolidays()
		 * @return void
		 */
		function removeDateHoliday($_day, $_month, $_year) {
			$this->removeUDateHoliday(mktime(0, 0, 0, $_month, $_day, $_year));
		}
		
		/**
		 * Удаляет все определённые ссылки.
		 * @access public
		 * @see addUDateHoliday(), addDateHoliday(), removeUDateLink(), removeDateLink()
		 * @return void
		 */
		function removeHolidays() {
			$this->dateHolidays = array();
		}
		
		/**
		 * Добавляет хинт для заданной даты. Если хинт был уже задан, он будет 
		 * переопределен.
		 * @access public
		 * @param int $_date Дата в формате Unix timestamp, к которой будет 
		 * привязан хинт. Можно задавать "неточную" дату, значение часов, минут 
		 * и секунд игнорируется.
		 * @param string $_title Текст хинта
		 * @return void
		 */
		function addUDatePreHoliday($_date, $_title) {
			$d = getdate($_date);
			$d = mktime(0, 0, 0, $d["mon"], $d["mday"], $d["year"]);
			$this->datePreHolidays[$d] = $_title;
		}
		
		/**
		 * Добавляет хинт для заданной даты. Отличается от addUDateTitle только 
		 * форматом, в котором определяется дата.
		 * @access public
		 * @param int $_day Число
		 * @param int $_month Месяц
		 * @param int $_year Год
		 * @param string $_title Текст хинта
		 * @return void
		 */
		function addDatePreHoliday($_day, $_month, $_year, $_title) {
			$this->addUDatePreHoliday(mktime(0, 0, 0, $_month, $_day, $_year), $_title);
		}
		
		/**
		 * Удаляет хинт для заданной даты (если он определен).
		 * @access public
		 * @param int $_date Дата, для которой необходимо удалить ссылку 
		 * (имеет значение год, месяц и день)
		 * @return void
		 */
		function removeUDatePreHoliday($_date) {
			$d = getdate($_date);
			$d = mktime(0, 0, 0, $d["mon"], $d["mday"], $d["year"]);
			unset($this->datePreHolidays[$d]);
		}
		
		/**
		 * Удаляет хинт для заданной даты (если он определен). Отличается 
		 * от removeUDateTitle только форматом, в котором определяется дата.
		 * @access public
		 * @param int $_day Число
		 * @param int $_month Месяц
		 * @param int $_year Год
		 * @return void
		 */
		function removeDatePreHoliday($_day, $_month, $_year) {
			$this->removeUDatePreHoliday(mktime(0, 0, 0, $_month, $_day, $_year));
		}
		
		/**
		 * Удаляет все определённые хинты.
		 * @access public
		 * @return void
		 */
		function removePreHolidays() {
			$this->datePreHolidays = array();
		}	
		
		

		
		/**
		 * Добавляет хинт для заданной даты. Если хинт был уже задан, он будет 
		 * переопределен.
		 * @access public
		 * @param int $_date Дата в формате Unix timestamp, к которой будет 
		 * привязан хинт. Можно задавать "неточную" дату, значение часов, минут 
		 * и секунд игнорируется.
		 * @param string $_title Текст хинта
		 * @return void
		 */
		function addUDateWorkday($_date, $_title) {
			$d = getdate($_date);
			$d = mktime(0, 0, 0, $d["mon"], $d["mday"], $d["year"]);
			$this->dateWorkdays[$d] = $_title;
		}
		
		/**
		 * Добавляет хинт для заданной даты. Отличается от addUDateTitle только 
		 * форматом, в котором определяется дата.
		 * @access public
		 * @param int $_day Число
		 * @param int $_month Месяц
		 * @param int $_year Год
		 * @param string $_title Текст хинта
		 * @return void
		 */
		function addDateWorkday($_day, $_month, $_year, $_title) {
			$this->addUDateWorkday(mktime(0, 0, 0, $_month, $_day, $_year), $_title);
		}
		
		/**
		 * Удаляет хинт для заданной даты (если он определен).
		 * @access public
		 * @param int $_date Дата, для которой необходимо удалить ссылку 
		 * (имеет значение год, месяц и день)
		 * @return void
		 */
		function removeUDateWorkday($_date) {
			$d = getdate($_date);
			$d = mktime(0, 0, 0, $d["mon"], $d["mday"], $d["year"]);
			unset($this->dateWorkdays[$d]);
		}
		
		/**
		 * Удаляет хинт для заданной даты (если он определен). Отличается 
		 * от removeUDateTitle только форматом, в котором определяется дата.
		 * @access public
		 * @param int $_day Число
		 * @param int $_month Месяц
		 * @param int $_year Год
		 * @return void
		 */
		function removeDateWorkday($_day, $_month, $_year) {
			$this->removeUDateWorkday(mktime(0, 0, 0, $_month, $_day, $_year));
		}
		
		/**
		 * Удаляет все определённые хинты.
		 * @access public
		 * @return void
		 */
		function removeWorkdays() {
			$this->dateWorkdays = array();
		}	
			
		/**
		 * Генерирует HTML код для заданного месяца. Дата задаётся в формате Unix 
		 * tiestamp.
		 * @access public
		 * @param int $_date Месяц, для которого необходимо сгенерировать
		 * календарь, задаваемый формате Unix timestamp (значение года, само собой, 
		 * тоже имеет значение; часы, минуты и секунды - игнорируются)
		 * @param bool $_mark Флаг, определяющий необходимость выделить текущую 
		 * дату. По-умолчанию, текущая дата не выделяется.
		 * @return string Сгенерированный HTML код
		 */
		function genUMonth($_date, $_mark = false) {
			$MONTHES = array(
				'en' => array('January', 'February', 'March', 'April', 'May', 'June', 
					'July', 'August', 'September', 'October', 'November', 'December'),
				'ru' => array(GetMessage("MONTH_1"), GetMessage("MONTH_2"), GetMessage("MONTH_3"), GetMessage("MONTH_4"), GetMessage("MONTH_5"),GetMessage("MONTH_6"), 
					GetMessage("MONTH_7"), GetMessage("MONTH_8"), GetMessage("MONTH_9"),GetMessage("MONTH_10"), GetMessage("MONTH_11"), GetMessage("MONTH_12"))
			);
			$DOWS = array(
					'en' => array('Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'),
					'ru' => array(GetMessage("calend_su"), GetMessage("calend_mo"), GetMessage("calend_tu"), GetMessage("calend_we"), GetMessage("calend_th"), GetMessage("calend_fr"), GetMessage("calend_sa"))
			);
			$d = getdate($_date);
			$month = $d["mon"];
			$day = $d["mday"];
			$year = $d["year"];
			$wDay = date('w', mktime(0, 0, 0, $month, 1, $year));
			$curMonth=date("m");
			if($curMonth!=$month && $this->addMonthChange)
				$style=' style="display:none;"';
			else
				$style="";			
			$res[] = '<table border="0" cellspacing="1" cellpadding="0" class="'.
				$this->cssPrefix.'month" '.$style.' id="month'.$month.'">';		
			
			$monthes = (isset($MONTHES[$this->lng]))?
				$MONTHES[$this->lng]:date('F', $_date);		
			
			$dows = $DOWS[$this->lng];
			//print_r($DOWS);exit;
			// строка-заголовок с названием месяца
			$left_t='';
			$right_t='';
			if ($this->showTitle)
			{	
				if (file_exists($_SERVER['DOCUMENT_ROOT'].'/bitrix/templates/'.SITE_TEMPLATE_ID.'/images/right_t.png'))
					$rightImg='/bitrix/templates/'.SITE_TEMPLATE_ID.'/images/right_t.png';
				else
					$rightImg='/bitrix/components/franchise/franchise.calendar/templates/.default/images/left_t.png';
				if (file_exists($_SERVER['DOCUMENT_ROOT'].'/bitrix/templates/'.SITE_TEMPLATE_ID.'/images/left_t.png'))
					$leftImg='/bitrix/templates/'.SITE_TEMPLATE_ID.'/images/left_t.png';
				else
					$leftImg='/bitrix/components/franchise/franchise.calendar/templates/.default/images/left_t.png';
				if($month!=1 && $this->addMonthChange)
					$left_t='<a class="left_t" href="javascript:void(0);" onClick="$(\'.month\').css(\'display\',\'none\');$(\'#month'.($month - 1).'\').css(\'display\',\'\');" rel="nofollow" title="'.$monthes[$month - 2].'"><img style="padding-bottom:2px" src="'.$leftImg.'" alt="<"/></a>';
				if($month!=12 && $this->addMonthChange)
					$right_t='<a class="right_t" href="javascript:void(0);" onClick="$(\'.month\').css(\'display\',\'none\');$(\'#month'.($month+1).'\').css(\'display\',\'\');" rel="nofollow" title="'.$monthes[$month].'"><img style="padding-bottom:2px" src="'.$rightImg.'" alt=">"/></a>';
				$tmpHeadr='<tr><td colspan="7" class="'.$this->cssPrefix.'montitle">'.$left_t.$monthes[$month - 1];
				if ($this->showYear)
					$tmpHeadr.=' '.$year;
				$tmpHeadr.=$right_t.'</td></tr>';
				$res[] = $tmpHeadr;
			}
			
			// опции отображения календаря
			$mondayIsFirst = true;
			$markSat = ($this->options & CLD_MARKSATSUN);
			$markSun = ($this->options & CLD_MARKSUN) || 
				($this->options & CLD_MARKSATSUN);
			
			if($mondayIsFirst) {
				$sunday = array_shift($dows);
				array_push($dows, $sunday);
				$wDay = $wDay?($wDay - 1):6;
			}
			
			// строка-заголовок с названиями дней недели
			$tmp = array();
			for($i = 0; $i < 7; $i++) {
				// опционально выделение суббот и/или воскресенья с помощю 
				// специальных CSS классов
				$weekEnd = (($i == 6) || ($i == 5))?'marked':'';
				// определяем имя CSS класса для следующей ячейки
				$tmp[] = '<th class="glav-c '.$weekEnd.'">'.$dows[$i].'</th>';
			}
			
			// опредляем, нужен ли разделитель для строк HTML кода
			$s = ($this->options & CLD_BREAKS)?"\n":'';
			$res[] = '<tr>'.implode($s, $tmp).'</tr>
			<tr class="line">	
						<td colspan="7">
						</td>
			</tr>';
			
			// значение понадобиться для вычисления количества пробелов вконце 
			// таблицы
			$spacesNum = $wDay;
			
			// пробелы перед первым числом
			$tmp = '<tr>';
			for($i = 0; $i < $wDay; $i++) {
				$weekEnd = (($i == 6) || ($i == 5))?'marked':'';
				$tmp .= '<td>&nbsp;</td>';
			}
			$res[] = $tmp;
			
			// счётчик недель
			$wcnt = 0;
			
			for($i = 1, $striper = $wDay % 2; $i <= date('t', $_date); 
				$i++, $striper = !$striper) {
				
				// отмечаем текущий день, если надо
				$today = $_mark && ($i == $day);
				
				// добавляем линки
				$d = mktime(0, 0, 0, $month, $i, $year);
				$dayClass='';
				$spanTitle="";
				$HolidaysSet = isset($this->dateHolidays[$d]);
				$PreHolidaysSet = isset($this->datePreHolidays[$d]);
				$WorkdaysSet = isset($this->dateWorkdays[$d]);
				$todaySet = isset($this->today[$d]);
				if($HolidaysSet) {
					$dayClass='red-c';
					$spanClass='datelink';
					$spanTitle=$this->dateHolidays[$d];				
				} elseif($PreHolidaysSet) {
					$dayClass='green-c';
					$spanClass='titleddate';
					$spanTitle = $this->datePreHolidays[$d];
				} elseif($WorkdaysSet) {
					$dayClass='white-c';
					$spanClass='titleddate';
					$spanTitle = $this->dateWorkdays[$d];
				}
				if($todaySet)
				{
					$dayClass.=' today';
					$spanTitle=$this->today[$d]." ".$spanTitle;
				}
				if($HolidaysSet || $PreHolidaysSet || $todaySet )
				{
					$dayCode = '<span class="'.$this->cssPrefix.$spanClass.'" title="'.$spanTitle.'">'.$i.'</span>';
				}
				else
					$dayCode = $i;
				// далее $wDay используется в качестве определителя дня недели,
				// для выделения суббот и воскресений, и переноса строк
				$wDay = ($wDay + 1) % 7;
				// определяем, нужно ли отметить субботу и/или воскресенье
				$weekEnd = (($wDay == 6) || ($wDay == 0))?'marked':'';
				
				$res[] = '<td class="'.$dayClass.' '.$weekEnd.'">'.$dayCode.'</td>';
				if(!$wDay) {
					$res[] = '</tr><tr>';
					$wcnt++;
					$striper = true;
				}
			}
			
			// пробелы в конце
			$spacesNum = (7 - ($spacesNum + $i) % 7) % 7 + 1;
			$tmp = '';
			for($i = 0; $i < $spacesNum; $i++, $striper = !$striper) {
				$tmp .= '<td>&nbsp;</td>';
			}
			$res[] = $tmp.'</tr>';
			
			// вне зависимости от количества недель в месяце, выравниваем высоту 
			// до 6 строк
			/*if($wcnt < 5) {
				$res[] = '<tr><td class="'.$this->cssPrefix.
					'dark">&nbsp;</td><td class="'.$this->cssPrefix.
					'light">&nbsp;</td><td class="'.$this->cssPrefix.
					'dark">&nbsp;</td><td class="'.$this->cssPrefix.
					'light">&nbsp;</td><td class="'.$this->cssPrefix.
					'dark">&nbsp;</td><td class="'.$this->cssPrefix.
					'light">&nbsp;</td><td class="'.$this->cssPrefix.
					'dark">&nbsp;</td></tr>';
			}*/
			
			$res[] = '</table>';
			
			$this->monthsRes[$month]['HTML']=implode($s, $res);
			$this->monthsRes[$month]['DAY_START']=$day;
			//return implode($s, $res);
		}
		
		function genMonth($_day, $_month, $_year) {
			$this->genUMonth(mktime(0, 0, 0, $_month, is_numeric($_day)?$_day:1, $_year), is_numeric($_day)?true:false);
			//return $this->genUMonth(mktime(0, 0, 0, $_month, is_numeric($_day)?$_day:1, $_year), is_numeric($_day)?true:false);
		}
		
		function genUYear($_date, $_mark = false, $_width = 3) {
			$year = date('Y', $_date);
			$mMonth = date('n', $_date);
			
			$res[] = '<table border="0" cellspacing="0" cellpadding="10" class="'.
				$this->cssPrefix.'year">';
			$res[] = '<tr><th colspan="'.$_width.'" class="'.$this->cssPrefix.
				'yeartitle"><big>'.$year.'</big></th></tr>';
			$res[] = '<tr>';
			
			for($i = 1; $i <= 12; $i++) {
				if($mMonth == $i) {
					$monthHtml = $this->genUMonth($_date, $_mark);
				} else {
					$monthHtml = $this->genUMonth(mktime(0, 0, 0, $i, 1, $year));
				}
				$res[] = '<td valign="top" class="'.$this->cssPrefix.
					(($i % $_width)?'monthcell':'monthlastcell').'">'.$monthHtml.
					'</td>';
				if(!($i % $_width)) {
					$res[] = '</tr><tr>';
				}
			}
			
			$res[] = $tmp.'</tr>';
			$res[] = '</table>';
			
			// опредляем, нужен ли разделитель для строк HTML кода
			$s = ($this->options & CLD_BREAKS)?"\n":'';
			return implode($s, $res);
		}

		function genYear($_day, $_month, $_year, $_mark = false, $_width = 3) {
			return $this->genUYear(mktime(0, 0, 0, is_numeric($_month)?$_month:1, 
			is_numeric($_day)?$_day:1, $_year), $_mark, $_width);
		}
	}
}
?>