Index: /tags/calendar/0.9.3/setup/phpgw_alarm_pt-br.lang
===================================================================
--- /tags/calendar/0.9.3/setup/phpgw_alarm_pt-br.lang	(revision 204)
+++ /tags/calendar/0.9.3/setup/phpgw_alarm_pt-br.lang	(revision 204)
@@ -0,0 +1,22 @@
+Title	calendar	pt-br	Título
+Description	calendar	pt-br	Descrição
+External Participants	calendar	es-es	Participantes Externos
+Category	calendar	pt-br	Categoria
+Location	calendar	pt-br	Lugar
+Start Date/Time	calendar	pt-br	Data/Hora Início
+End Date/Time	calendar	pt-br	Data/Hora de Término
+Low	calendar	pt-br	Baixa
+Normal	calendar	pt-br	Normal
+High	calendar	pt-br	Alta
+Priority	calendar	pt-br	Prioridade
+Created By	calendar	pt-br	Criado por
+Updated	calendar	pt-br	Atualizado
+Access	calendar	pt-br	Acesso
+Groups	calendar	pt-br	Grupos
+Participants	calendar	pt-br	Participantes
+Alarm for %1 at %2 in %3	calendar	pt-br	Alarme para %1 em %2 na %3
+Here is your requested alarm.	calendar	pt-br	Aqui está seu alarme solicitado.
+You have a meeting scheduled for %1	calendar	pt-br	Você possui um compromisso agendado para %1.
+Your meeting scheduled for %1 has been canceled	calendar	pt-br	Seu compromisso agendado para %1 foi cancelado.
+Your meeting that had been scheduled for %1 has been rescheduled to %2	calendar	pt-br	Seu compromisso que havia sido agendado para %1 foi reagendado para %2
+
Index: /tags/calendar/0.9.3/setup/setup.inc.php
===================================================================
--- /tags/calendar/0.9.3/setup/setup.inc.php	(revision 361)
+++ /tags/calendar/0.9.3/setup/setup.inc.php	(revision 361)
@@ -0,0 +1,55 @@
+<?php
+	/**************************************************************************\
+	* eGroupWare - Calendar                                                    *
+	* http://www.egroupware.org                                                *
+	* --------------------------------------------                             *
+	*  This program is free software; you can redistribute it and/or modify it *
+	*  under the terms of the GNU General Public License as published by the   *
+	*  Free Software Foundation; either version 2 of the License, or (at your  *
+	*  option) any later version.                                              *
+	\**************************************************************************/
+
+
+	$setup_info['calendar']['name']    = 'calendar';
+	$setup_info['calendar']['version'] = '0.9.23';
+	$setup_info['calendar']['app_order'] = 3;
+	$setup_info['calendar']['enable']  = 1;
+
+	$setup_info['calendar']['author'] = 'Mark Peters';
+	$setup_info['calendar']['license']  = 'GPL';
+	$setup_info['calendar']['description'] =
+		'Powerful calendar with meeting request system and ACL security.';
+	$setup_info['calendar']['note'] =
+		'Bassed on Webcalendar by <a href="http://www.radix.net/~cknudsen" target="_blank">Craig Knudsen</a>.<p>
+		';
+	$setup_info['calendar']['maintainer'] = array(
+		'name'  => 'Ralf Becker',
+		'email' => 'RalfBecker@outdoor-training.de'
+	);
+
+	$setup_info['calendar']['tables'][] = 'phpgw_cal';
+	$setup_info['calendar']['tables'][] = 'phpgw_cal_holidays';
+	$setup_info['calendar']['tables'][] = 'phpgw_cal_repeats';
+	$setup_info['calendar']['tables'][] = 'phpgw_cal_user';
+	$setup_info['calendar']['tables'][] = 'phpgw_cal_extra';
+
+	/* The hooks this app includes, needed for hooks registration */
+	$setup_info['calendar']['hooks'][] = 'add_def_prefs';
+	$setup_info['calendar']['hooks'][] = 'admin';
+	$setup_info['calendar']['hooks'][] = 'deleteaccount';
+	$setup_info['calendar']['hooks'][] = 'email';
+	$setup_info['calendar']['hooks'][] = 'home';
+	$setup_info['calendar']['hooks'][] = 'home_day';
+	$setup_info['calendar']['hooks'][] = 'home_month';
+	$setup_info['calendar']['hooks'][] = 'home_week';
+	$setup_info['calendar']['hooks'][] = 'home_year';
+	$setup_info['calendar']['hooks'][] = 'manual';
+	$setup_info['calendar']['hooks'][] = 'preferences';
+	$setup_info['calendar']['hooks'][] = 'settings';
+	$setup_info['calendar']['hooks'][] = 'sidebox_menu';
+
+	/* Dependencies for this app to work */
+	$setup_info['calendar']['depends'][] = array(
+		 'appname' => 'phpgwapi',
+		 'versions' => Array('0.9.14','0.9.15','0.9.16','1.0.00', '1.0.0.007')
+	);
Index: /tags/calendar/0.9.3/setup/default_records.inc.php
===================================================================
--- /tags/calendar/0.9.3/setup/default_records.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/setup/default_records.inc.php	(revision 2)
@@ -0,0 +1,15 @@
+<?php
+	/**************************************************************************\
+	* eGroupWare - Setup / Calendar                                            *
+	* http://www.egroupware.org                                                *
+	* --------------------------------------------                             *
+	*  This program is free software; you can redistribute it and/or modify it *
+	*  under the terms of the GNU General Public License as published by the   *
+	*  Free Software Foundation; either version 2 of the License, or (at your  *
+	*  option) any later version.                                              *
+	\**************************************************************************/
+
+
+	// enable auto-loading of holidays from localhost by default
+	$oProc->query("INSERT INTO phpgw_config (config_app, config_name, config_value) VALUES ('phpgwapi','auto_load_holidays','True')");
+	$oProc->query("INSERT INTO phpgw_config (config_app, config_name, config_value) VALUES ('phpgwapi','holidays_url_path','localhost')");
Index: /tags/calendar/0.9.3/setup/tables_baseline.inc.php
===================================================================
--- /tags/calendar/0.9.3/setup/tables_baseline.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/setup/tables_baseline.inc.php	(revision 2)
@@ -0,0 +1,71 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare                                                               *
+  * http://www.egroupware.org                                                *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	$phpgw_baseline = array(
+		"webcal_entry" => array(
+			"fd" => array(
+				"cal_id" => array("type" => "auto", "nullable" => false),
+				"cal_group_id" => array("type" => "int", "precision" => 4),
+				"cal_create_by" => array("type" => "varchar", "precision" => 25, "nullable" => false),
+				"cal_date" => array("type" => "int", "precision" => 4, "nullable" => false, "default" => "0"),
+				"cal_time" => array("type" => "int", "precision" => 4),
+				"cal_mod_date" => array("type" => "int", "precision" => 4),
+				"cal_mod_time" => array("type" => "int", "precision" => 4),
+				"cal_duration" => array("type" => "int", "precision" => 4, "nullable" => false, "default" => "0"),
+				"cal_priority" => array("type" => "int", "precision" => 4, "default" => "2"),
+				"cal_type" => array("type" => "varchar", "precision" => 10),
+				"cal_access" => array("type" => "char", "precision" => 10),
+				"cal_name" => array("type" => "varchar", "precision" => 80, "nullable" => false),
+				"cal_description" => array("type" => "text"),
+				"cal_ex_participants" => array("type" => "text")
+			),
+			"pk" => array("cal_id"),
+			"fk" => array(),
+			"ix" => array(),
+			"uc" => array()
+		),
+		"webcal_entry_repeats" => array(
+			"fd" => array(
+				"cal_id" => array("type" => "int", "precision" => 4, "nullable" => false, "default" => "0"),
+				"cal_type" => array("type" => "varchar", "precision" => 20, "nullable" => false, "default" => "daily"),
+				"cal_end" => array("type" => "int", "precision" => 4),
+				"cal_frequency" => array("type" => "int", "precision" => 4, "default" => "1"),
+				"cal_days" => array("type" => "char", "precision" => 7)
+			),
+			"pk" => array(),
+			"fk" => array(),
+			"ix" => array(),
+			"uc" => array()
+		),
+		"webcal_entry_user" => array(
+			"fd" => array(
+				"cal_id" => array("type" => "int", "precision" => 4, "nullable" => false, "default" => "0"),
+				"cal_login" => array("type" => "varchar", "precision" => 25, "nullable" => false),
+				"cal_status" => array("type" => "char", "precision" => 1, "default" => "A")
+			),
+			"pk" => array("cal_id", "cal_login"),
+			"fk" => array(),
+			"ix" => array(),
+			"uc" => array()
+		),
+		"webcal_entry_groups" => array(
+			"fd" => array(
+				"cal_id" => array("type" => "int", "precision" => 4),
+				"groups" => array("type" => "varchar", "precision" => 255)
+			),
+			"pk" => array(),
+			"fk" => array(),
+			"ix" => array(),
+			"uc" => array()
+		)
+	);
+?>
Index: /tags/calendar/0.9.3/setup/tables_current.inc.php
===================================================================
--- /tags/calendar/0.9.3/setup/tables_current.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/setup/tables_current.inc.php	(revision 2)
@@ -0,0 +1,93 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare                                                               *
+  * http://www.egroupware.org                                                *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	$phpgw_baseline = array(
+		'phpgw_cal' => array(
+			'fd' => array(
+				'cal_id' => array('type' => 'auto','nullable' => False),
+				'uid' => array('type' => 'varchar','precision' => '255','nullable' => False),
+				'owner' => array('type' => 'int','precision' => '8','nullable' => False),
+				'category' => array('type' => 'varchar','precision' => '30','nullable' => True),
+				'groups' => array('type' => 'varchar','precision' => '255','nullable' => True),
+				'datetime' => array('type' => 'int','precision' => '8','nullable' => True),
+				'mdatetime' => array('type' => 'int','precision' => '8','nullable' => True),
+				'edatetime' => array('type' => 'int','precision' => '8','nullable' => True),
+				'priority' => array('type' => 'int','precision' => '8','nullable' => False,'default' => '2'),
+				'cal_type' => array('type' => 'varchar','precision' => '10','nullable' => True),
+				'is_public' => array('type' => 'int','precision' => '8','nullable' => False,'default' => '1'),
+				'title' => array('type' => 'varchar','precision' => '80','nullable' => False,'default' => '1'),
+				'description' => array('type' => 'text','nullable' => True),
+				'location' => array('type' => 'varchar','precision' => '255','nullable' => True),
+				'reference' => array('type' => 'int','precision' => '8','nullable' => False,'default' => '0'),
+				'ex_participants' => array('type' => 'text','nullable' => True),
+			),
+			'pk' => array('cal_id'),
+			'fk' => array(),
+			'ix' => array(),
+			'uc' => array()
+		),
+		'phpgw_cal_holidays' => array(
+			'fd' => array(
+				'hol_id' => array('type' => 'auto','nullable' => False),
+				'locale' => array('type' => 'char','precision' => '2','nullable' => False),
+				'name' => array('type' => 'varchar','precision' => '50','nullable' => False),
+				'mday' => array('type' => 'int','precision' => '8','nullable' => False,'default' => '0'),
+				'month_num' => array('type' => 'int','precision' => '8','nullable' => False,'default' => '0'),
+				'occurence' => array('type' => 'int','precision' => '8','nullable' => False,'default' => '0'),
+				'dow' => array('type' => 'int','precision' => '8','nullable' => False,'default' => '0'),
+				'observance_rule' => array('type' => 'int','precision' => '8','nullable' => False,'default' => '0')
+			),
+			'pk' => array('hol_id'),
+			'fk' => array(),
+			'ix' => array(),
+			'uc' => array()
+		),
+		'phpgw_cal_repeats' => array(
+			'fd' => array(
+				'cal_id' => array('type' => 'int','precision' => '8','nullable' => False),
+				'recur_type' => array('type' => 'int','precision' => '8','nullable' => False),
+				'recur_use_end' => array('type' => 'int','precision' => '8','nullable' => True,'default' => '0'),
+				'recur_enddate' => array('type' => 'int','precision' => '8','nullable' => True),
+				'recur_interval' => array('type' => 'int','precision' => '8','nullable' => True,'default' => '1'),
+				'recur_data' => array('type' => 'int','precision' => '8','nullable' => True,'default' => '1'),
+				'recur_exception' => array('type' => 'varchar','precision' => '255','nullable' => True,'default' => '')
+			),
+			'pk' => array(),
+			'fk' => array(),
+			'ix' => array(),
+			'uc' => array()
+		),
+		'phpgw_cal_user' => array(
+			'fd' => array(
+				'cal_id' => array('type' => 'int','precision' => '8','nullable' => False,'default' => '0'),
+				'cal_login' => array('type' => 'int','precision' => '8','nullable' => False,'default' => '0'),
+				'cal_status' => array('type' => 'char','precision' => '1','nullable' => True,'default' => 'A'),
+				'cal_type' => array('type' => 'varchar','precision' => '1','nullable' => False,'default' => 'u')
+			),
+			'pk' => array('cal_id','cal_login'),
+			'fk' => array(),
+			'ix' => array(),
+			'uc' => array()
+		),
+		'phpgw_cal_extra' => array(
+			'fd' => array(
+				'cal_id' => array('type' => 'int','precision' => '4','nullable' => False),
+				'cal_extra_name' => array('type' => 'varchar','precision' => '40','nullable' => False),
+				'cal_extra_value' => array('type' => 'varchar','precision' => '255','nullable' => False,'default' => '')
+			),
+			'pk' => array('cal_id','cal_extra_name'),
+			'fk' => array(),
+			'ix' => array(),
+			'uc' => array()
+		)
+	);
+?>
Index: /tags/calendar/0.9.3/setup/tables_update.inc.php
===================================================================
--- /tags/calendar/0.9.3/setup/tables_update.inc.php	(revision 361)
+++ /tags/calendar/0.9.3/setup/tables_update.inc.php	(revision 361)
@@ -0,0 +1,54 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Setup                                                       *
+  * http://www.egroupware.org                                                *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+	function addSpecialColumn($table,$column, $attrs){
+		$result = $GLOBALS['phpgw_setup']->db->metadata($table);
+		if($result){
+			foreach($result as $idx => $col){
+				if($col['name'] == $column)
+					return;
+			}
+		}		
+		$GLOBALS['phpgw_setup']->db->query("ALTER TABLE ".$table." ADD COLUMN ".$column." ".$attrs);
+	}  
+	$test[] = '0.9.2';
+	function calendar_upgrade0_9_2()
+	{
+		$GLOBALS['setup_info']['calendar']['currentver'] = '0.9.17';
+		return $GLOBALS['setup_info']['calendar']['currentver'];
+	}
+	$test[] = '0.9.17';
+	function calendar_upgrade0_9_17()
+	{
+		$GLOBALS['setup_info']['calendar']['currentver'] = '0.9.21';
+		return $GLOBALS['setup_info']['calendar']['currentver'];
+	}
+	$test[] = '0.9.20';
+	function calendar_upgrade0_9_20()
+	{
+		$GLOBALS['setup_info']['calendar']['currentver'] = '0.9.21';
+		return $GLOBALS['setup_info']['calendar']['currentver'];
+	}	
+	$test[] = '0.9.21';
+	function calendar_upgrade0_9_21()
+	{
+		addSpecialColumn("phpgw_cal","last_status","char(1) DEFAULT 'N'::bpchar");
+		addSpecialColumn("phpgw_cal","last_update","int8 DEFAULT (date_part('epoch'::text, ('now'::text)::timestamp(3) with time zone) * (1000)::double precision)");
+		$GLOBALS['setup_info']['calendar']['currentver'] = '0.9.22';
+		return $GLOBALS['setup_info']['calendar']['currentver'];
+	}	
+	$test[] = '0.9.22';
+	function calendar_upgrade0_9_22()
+	{
+		$GLOBALS['setup_info']['calendar']['currentver'] = '0.9.23';
+		return $GLOBALS['setup_info']['calendar']['currentver'];
+	}
+
+?>
Index: /tags/calendar/0.9.3/setup/phpgw_alarm_es-es.lang
===================================================================
--- /tags/calendar/0.9.3/setup/phpgw_alarm_es-es.lang	(revision 204)
+++ /tags/calendar/0.9.3/setup/phpgw_alarm_es-es.lang	(revision 204)
@@ -0,0 +1,18 @@
+Title	calendar	es-es	Titulo
+Description	calendar	es-es	descripción
+External Participants	calendar	es-es	Participantes Externos
+Category	calendar	es-es	Categoria
+Location	calendar	es-es	Lugar
+Start Date/Time	calendar	es-es	Fecha/Hora Inicio
+End Date/Time	calendar	es-es	La fecha/hora de finalización
+Low	calendar	es-es	Baixa
+Normal	calendar	es-es	Normal
+High	calendar	es-es	Alta
+Priority	calendar	es-es	Prioridad
+Created By	calendar	es-es	Creado por
+Updated	calendar	es-es	Actualizado
+Access	calendar	es-es	Acesso
+Groups	calendar	es-es	Grupos
+Participants	calendar	es-es	Participantes
+here is your requested alarm.	calendar	es-es	Aquí está la alarma solicitada.
+Alarm for %1 at %2 in %3	calendar	es-es	Alarma para %1 en %2 in %3
Index: /tags/calendar/0.9.3/doc/change_log.txt
===================================================================
--- /tags/calendar/0.9.3/doc/change_log.txt	(revision 56)
+++ /tags/calendar/0.9.3/doc/change_log.txt	(revision 56)
@@ -0,0 +1,51 @@
+Esse arquivo descreve todas as correções, alterações e novas implementações do 
+módulo Agenda de Eventos, e a partir da versão 29/11/2006 [calendar 0.9.17]
+Nilton Emilio Buhrer Neto.
+
+--------------------------- NOTA IMPORTANTE --------------------------
+
+A partir de Agosto de 2007, todos os registros de bugs aqui relatados foram
+transferidos para o site do ExpressoLivre, no Wiki-Trac do módulo.
+Vide: http://www.expressolivre.org/dev/wiki/calendar/changelog
+
+----------------------------------------------------------------------
+27/07/2007 - [0.9.2]
+- Implementação de funcionalidade no hook_admin. O administrador poderá 
+escolher entre 2 tipos de visualização da árvore ldap, na seleção de usuários 
+em um compromisso: o primeiro mostra o 1º nível de OUs somente, com busca 
+recursiva. Já o segundo, mostra todos os N níveis com busca no mesmo nível.
+
+04/07/2007 - [0.9.2]
+- Correção de bug referente ao envio de mensagens pela Agenda. Houve uma modificação 
+na maneira de se enviar emails pelo módulo, porém apresentou problemas. Agora está ok.
+Onde pegava valores de configuração da $_SESSION foi alterado para pegar do $_GLOBALS.
+
+02/07/2007 - [0.9.2]
+- Adicionado suporte ao espanhol.
+
+05/06/2007 - [0.9.2]
+- Adicionando funcionalidade de adicionar eventos externos, pelo email
+- Corrigido problema de carregar os usuários da organização selecionada, ao criar um compromisso.
+
+22/05/2007 - [0.9.2]
+- Adicionando/corrigindo funcionalidade de exportar vcard de todos os eventos
+
+22/05/2007 - [0.9.2]
+- Adicionando funcionalidade de exportar vcard de eventos externos
+
+03/05/2007 - [0.9.2]
+- Corrigido bug. Caso o horário do alarme seja mais antigo que a data atual não pode ser adicionada.
+
+03/05/2007 - [0.9.2]
+- Corrigido bug que possibilita adicionar 2 alarmes no mesmo evento no mesmo horário.
+
+02/05/2007 - [0.9.2]
+- Corrigindo bug que mostra todos os alarmes de um evento
+independente do dono. Agora só mostra os eventos do dono.
+
+30/04/2007 - [0.9.2]
+- Ajustado o layout da versão de impressão do calendário.
+
+27/02/2007 - [0.9.2]
+- Corrigido problema que enviava mensagem de aviso de compromisso, com assunto vazio,
+em compromissos que tinham somente participantes externos.
Index: /tags/calendar/0.9.3/doc/rfc2445.txt
===================================================================
--- /tags/calendar/0.9.3/doc/rfc2445.txt	(revision 2)
+++ /tags/calendar/0.9.3/doc/rfc2445.txt	(revision 2)
@@ -0,0 +1,8291 @@
+
+
+
+
+
+
+Network Working Group                                         F. Dawson
+Request for Comments: 2445                                        Lotus
+Category: Standards Track                                  D. Stenerson
+                                                              Microsoft
+                                                          November 1998
+
+
+     Internet Calendaring and Scheduling Core Object Specification
+                              (iCalendar)
+
+Status of this Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (1998).  All Rights Reserved.
+
+Abstract
+
+   There is a clear need to provide and deploy interoperable calendaring
+   and scheduling services for the Internet. Current group scheduling
+   and Personal Information Management (PIM) products are being extended
+   for use across the Internet, today, in proprietary ways. This memo
+   has been defined to provide the definition of a common format for
+   openly exchanging calendaring and scheduling information across the
+   Internet.
+
+   This memo is formatted as a registration for a MIME media type per
+   [RFC 2048]. However, the format in this memo is equally applicable
+   for use outside of a MIME message content type.
+
+   The proposed media type value is 'text/calendar'. This string would
+   label a media type containing calendaring and scheduling information
+   encoded as text characters formatted in a manner outlined below.
+
+   This MIME media type provides a standard content type for capturing
+   calendar event, to-do and journal entry information. It also can be
+   used to convey free/busy time information. The content type is
+   suitable as a MIME message entity that can be transferred over MIME
+   based email systems, using HTTP or some other Internet transport. In
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                     [Page 1]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   addition, the content type is useful as an object for interactions
+   between desktop applications using the operating system clipboard,
+   drag/drop or file systems capabilities.
+
+   This memo is based on the earlier work of the vCalendar specification
+   for the exchange of personal calendaring and scheduling information.
+   In order to avoid confusion with this referenced work, this memo is
+   to be known as the iCalendar specification.
+
+   This memo defines the format for specifying iCalendar object methods.
+   An iCalendar object method is a set of usage constraints for the
+   iCalendar object. For example, these methods might define scheduling
+   messages that request an event be scheduled, reply to an event
+   request, send a cancellation notice for an event, modify or replace
+   the definition of an event, provide a counter proposal for an
+   original event request, delegate an event request to another
+   individual, request free or busy time, reply to a free or busy time
+   request, or provide similar scheduling messages for a to-do or
+   journal entry calendar component. The iCalendar Transport-indendent
+   Interoperability Protocol (iTIP) defined in [ITIP] is one such
+   scheduling protocol.
+
+Table of Contents
+
+   1 Introduction.....................................................5
+   2 Basic Grammar and Conventions....................................6
+    2.1 Formatting Conventions .......................................7
+    2.2 Related Memos ................................................8
+    2.3 International Considerations .................................8
+   3 Registration Information.........................................8
+    3.1 Content Type .................................................8
+    3.2 Parameters ...................................................9
+    3.3 Content Header Fields .......................................10
+    3.4 Encoding Considerations .....................................10
+    3.5 Security Considerations .....................................10
+    3.6 Interoperability Considerations .............................11
+    3.7 Applications Which Use This Media Type ......................11
+    3.8 Additional Information ......................................11
+    3.9 Magic Numbers ...............................................11
+    3.10 File Extensions ............................................11
+    3.11 Contact for Further Information: ...........................12
+    3.12 Intended Usage .............................................12
+    3.13 Authors/Change Controllers .................................12
+   4 iCalendar Object Specification..................................13
+    4.1 Content Lines ...............................................13
+     4.1.1 List and Field Separators ................................16
+     4.1.2 Multiple Values ..........................................16
+     4.1.3 Binary Content ...........................................16
+
+
+
+Dawson & Stenerson          Standards Track                     [Page 2]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     4.1.4 Character Set ............................................17
+    4.2 Property Parameters .........................................17
+     4.2.1 Alternate Text Representation ............................18
+     4.2.2 Common Name ..............................................19
+     4.2.3 Calendar User Type .......................................20
+     4.2.4 Delegators ...............................................20
+     4.2.5 Delegatees ...............................................21
+     4.2.6 Directory Entry Reference ................................21
+     4.2.7 Inline Encoding ..........................................22
+     4.2.8 Format Type ..............................................23
+     4.2.9 Free/Busy Time Type ......................................23
+     4.2.10 Language ................................................24
+     4.2.11 Group or List Membership ................................25
+     4.2.12 Participation Status ....................................25
+     4.2.13 Recurrence Identifier Range .............................27
+     4.2.14 Alarm Trigger Relationship ..............................27
+     4.2.15 Relationship Type .......................................28
+     4.2.16 Participation Role ......................................29
+     4.2.17 RSVP Expectation ........................................29
+     4.2.18 Sent By .................................................30
+     4.2.19 Time Zone Identifier ....................................30
+     4.2.20 Value Data Types ........................................32
+    4.3 Property Value Data Types ...................................32
+     4.3.1 Binary ...................................................33
+     4.3.2 Boolean ..................................................33
+     4.3.3 Calendar User Address ....................................34
+     4.3.4 Date .....................................................34
+     4.3.5 Date-Time ................................................35
+     4.3.6 Duration .................................................37
+     4.3.7 Float ....................................................38
+     4.3.8 Integer ..................................................38
+     4.3.9 Period of Time ...........................................39
+     4.3.10 Recurrence Rule .........................................40
+     4.3.11 Text ....................................................45
+     4.3.12 Time ....................................................47
+     4.3.13 URI .....................................................49
+     4.3.14 UTC Offset ..............................................49
+    4.4 iCalendar Object ............................................50
+    4.5 Property ....................................................51
+    4.6 Calendar Components .........................................51
+     4.6.1 Event Component ..........................................52
+     4.6.2 To-do Component ..........................................55
+     4.6.3 Journal Component ........................................56
+     4.6.4 Free/Busy Component ......................................58
+     4.6.5 Time Zone Component ......................................60
+     4.6.6 Alarm Component ..........................................67
+    4.7 Calendar Properties .........................................73
+     4.7.1 Calendar Scale ...........................................73
+
+
+
+Dawson & Stenerson          Standards Track                     [Page 3]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     4.7.2 Method ...................................................74
+     4.7.3 Product Identifier .......................................75
+     4.7.4 Version ..................................................76
+    4.8 Component Properties ........................................77
+     4.8.1 Descriptive Component Properties .........................77
+       4.8.1.1 Attachment ...........................................77
+       4.8.1.2 Categories ...........................................78
+       4.8.1.3 Classification .......................................79
+       4.8.1.4 Comment ..............................................80
+       4.8.1.5 Description ..........................................81
+       4.8.1.6 Geographic Position ..................................82
+       4.8.1.7 Location .............................................84
+       4.8.1.8 Percent Complete .....................................85
+       4.8.1.9 Priority .............................................85
+       4.8.1.10 Resources ...........................................87
+       4.8.1.11 Status ..............................................88
+       4.8.1.12 Summary .............................................89
+     4.8.2 Date and Time Component Properties .......................90
+       4.8.2.1 Date/Time Completed ..................................90
+       4.8.2.2 Date/Time End ........................................91
+       4.8.2.3 Date/Time Due ........................................92
+       4.8.2.4 Date/Time Start ......................................93
+       4.8.2.5 Duration .............................................94
+       4.8.2.6 Free/Busy Time .......................................95
+       4.8.2.7 Time Transparency ....................................96
+     4.8.3 Time Zone Component Properties ...........................97
+       4.8.3.1 Time Zone Identifier .................................97
+       4.8.3.2 Time Zone Name .......................................98
+       4.8.3.3 Time Zone Offset From ................................99
+       4.8.3.4 Time Zone Offset To .................................100
+       4.8.3.5 Time Zone URL .......................................101
+     4.8.4 Relationship Component Properties .......................102
+       4.8.4.1 Attendee ............................................102
+       4.8.4.2 Contact .............................................104
+       4.8.4.3 Organizer ...........................................106
+       4.8.4.4 Recurrence ID .......................................107
+       4.8.4.5 Related To ..........................................109
+       4.8.4.6 Uniform Resource Locator ............................110
+       4.8.4.7 Unique Identifier ...................................111
+     4.8.5 Recurrence Component Properties .........................112
+       4.8.5.1 Exception Date/Times ................................112
+       4.8.5.2 Exception Rule ......................................114
+       4.8.5.3 Recurrence Date/Times ...............................115
+       4.8.5.4 Recurrence Rule .....................................117
+     4.8.6 Alarm Component Properties ..............................126
+       4.8.6.1 Action ..............................................126
+       4.8.6.2 Repeat Count ........................................126
+       4.8.6.3 Trigger .............................................127
+
+
+
+Dawson & Stenerson          Standards Track                     [Page 4]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     4.8.7 Change Management Component Properties ..................129
+       4.8.7.1 Date/Time Created ...................................129
+       4.8.7.2 Date/Time Stamp .....................................130
+       4.8.7.3 Last Modified .......................................131
+       4.8.7.4 Sequence Number .....................................131
+     4.8.8 Miscellaneous Component Properties ......................133
+       4.8.8.1 Non-standard Properties .............................133
+       4.8.8.2 Request Status ......................................134
+   5 iCalendar Object Examples......................................136
+   6 Recommended Practices..........................................140
+   7 Registration of Content Type Elements..........................141
+    7.1 Registration of New and Modified iCalendar Object Methods ..141
+    7.2 Registration of New Properties .............................141
+     7.2.1 Define the property .....................................142
+     7.2.2 Post the Property definition ............................143
+     7.2.3 Allow a comment period ..................................143
+     7.2.4 Submit the property for approval ........................143
+    7.3 Property Change Control ....................................143
+   8 References.....................................................144
+   9 Acknowledgments................................................145
+   10 Authors' and Chairs' Addresses................................146
+   11 Full Copyright Statement......................................148
+
+1 Introduction
+
+   The use of calendaring and scheduling has grown considerably in the
+   last decade. Enterprise and inter-enterprise business has become
+   dependent on rapid scheduling of events and actions using this
+   information technology. However, the longer term growth of
+   calendaring and scheduling, is currently limited by the lack of
+   Internet standards for the message content types that are central to
+   these knowledgeware applications. This memo is intended to progress
+   the level of interoperability possible between dissimilar calendaring
+   and scheduling applications. This memo defines a MIME content type
+   for exchanging electronic calendaring and scheduling information. The
+   Internet Calendaring and Scheduling Core Object Specification, or
+   iCalendar, allows for the capture and exchange of information
+   normally stored within a calendaring and scheduling application; such
+   as a Personal Information Manager (PIM) or a Group Scheduling
+   product.
+
+   The iCalendar format is suitable as an exchange format between
+   applications or systems. The format is defined in terms of a MIME
+   content type. This will enable the object to be exchanged using
+   several transports, including but not limited to SMTP, HTTP, a file
+   system, desktop interactive protocols such as the use of a memory-
+   based clipboard or drag/drop interactions, point-to-point
+   asynchronous communication, wired-network transport, or some form of
+
+
+
+Dawson & Stenerson          Standards Track                     [Page 5]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   unwired transport such as infrared might also be used.
+
+   The memo also provides for the definition of iCalendar object methods
+   that will map this content type to a set of messages for supporting
+   calendaring and scheduling operations such as requesting, replying
+   to, modifying, and canceling meetings or appointments, to-dos and
+   journal entries. The iCalendar object methods can be used to define
+   other calendaring and scheduling operations such a requesting for and
+   replying with free/busy time data. Such a scheduling protocol is
+   defined in the iCalendar Transport-independent Interoperability
+   Protocol (iTIP) defined in [ITIP].
+
+   The memo also includes a formal grammar for the content type based on
+   the Internet ABNF defined in [RFC 2234]. This ABNF is required for
+   the implementation of parsers and to serve as the definitive
+   reference when ambiguities or questions arise in interpreting the
+   descriptive prose definition of the memo.
+
+2 Basic Grammar and Conventions
+
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" and
+   "OPTIONAL" in this document are to be interoperated as described in
+   [RFC 2119].
+
+   This memo makes use of both a descriptive prose and a more formal
+   notation for defining the calendaring and scheduling format.
+
+   The notation used in this memo is the ABNF notation of [RFC 2234].
+   Readers intending on implementing this format defined in this memo
+   should be familiar with this notation in order to properly interpret
+   the specifications of this memo.
+
+   All numeric and hexadecimal values used in this memo are given in
+   decimal notation.
+
+   All names of properties, property parameters, enumerated property
+   values and property parameter values are case-insensitive. However,
+   all other property values are case-sensitive, unless otherwise
+   stated.
+
+        Note: All indented editorial notes, such as this one, are
+        intended to provide the reader with additional information. The
+        information is not essential to the building of an
+        implementation conformant with this memo. The information is
+        provided to highlight a particular feature or characteristic of
+        the memo.
+
+
+
+
+Dawson & Stenerson          Standards Track                     [Page 6]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   The format for the iCalendar object is based on the syntax of the
+   [RFC 2425] content type. While the iCalendar object is not a profile
+   of the [RFC 2425] content type, it does reuse a number of the
+   elements from the [RFC 2425] specification.
+
+2.1 Formatting Conventions
+
+   The mechanisms defined in this memo are defined in prose. Many of the
+   terms used to describe these have common usage that is different than
+   the standards usage of this memo. In order to reference within this
+   memo elements of the calendaring and scheduling model, core object
+   (this memo) or interoperability protocol [ITIP] some formatting
+   conventions have been used. Calendaring and scheduling roles are
+   referred to in quoted-strings of text with the first character of
+   each word in upper case. For example, "Organizer" refers to a role of
+   a "Calendar User" within the scheduling protocol defined by [ITIP].
+   Calendar components defined by this memo are referred to with
+   capitalized, quoted-strings of text. All calendar components start
+   with the letter "V". For example, "VEVENT" refers to the event
+   calendar component, "VTODO" refers to the to-do calendar component
+   and "VJOURNAL" refers to the daily journal calendar component.
+   Scheduling methods defined by [ITIP] are referred to with
+   capitalized, quoted-strings of text. For example, "REQUEST" refers to
+   the method for requesting a scheduling calendar component be created
+   or modified, "REPLY" refers to the method a recipient of a request
+   uses to update their status with the "Organizer" of the calendar
+   component.
+
+   The properties defined by this memo are referred to with capitalized,
+   quoted-strings of text, followed by the word "property". For example,
+   "ATTENDEE" property refers to the iCalendar property used to convey
+   the calendar address of a calendar user. Property parameters defined
+   by this memo are referred to with lowercase, quoted-strings of text,
+   followed by the word "parameter". For example, "value" parameter
+   refers to the iCalendar property parameter used to override the
+   default data type for a property value. Enumerated values defined by
+   this memo are referred to with capitalized text, either alone or
+   followed by the word "value". For example, the "MINUTELY" value can
+   be used with the "FREQ" component of the "RECUR" data type to specify
+   repeating components based on an interval of one minute or more.
+
+
+
+
+
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                     [Page 7]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+2.2 Related Memos
+
+   Implementers will need to be familiar with several other memos that,
+   along with this memo, form a framework for Internet calendaring and
+   scheduling standards. This memo, [ICAL], specifies a core
+   specification of objects, data types, properties and property
+   parameters.
+
+   [ITIP] - specifies an interoperability protocol for scheduling
+   between different implementations;
+
+   [IMIP] specifies an Internet email binding for [ITIP].
+
+   This memo does not attempt to repeat the specification of concepts or
+   definitions from these other memos. Where possible, references are
+   made to the memo that provides for the specification of these
+   concepts or definitions.
+
+2.3 International Considerations
+
+   In the rest of this document, descriptions of characters are of the
+   form "character name (codepoint)", where "codepoint" is from the US-
+   ASCII character set. The "character name" is the authoritative
+   description; (codepoint) is a reference to that character in US-ASCII
+   or US-ASCII compatible sets (for example the ISO-8859-x family, UTF-
+   8, ISO-2022-xx, KOI8-R). If a non-US-ASCII compatible character set
+   is used, appropriate code-point from that character set MUST be
+   chosen instead. Use of non-US-ASCII-compatible character sets is NOT
+   recommended.
+
+3  Registration Information
+
+   The Calendaring and Scheduling Core Object Specification is intended
+   for use as a MIME content type. However, the implementation of the
+   memo is in no way limited solely as a MIME content type.
+
+3.1 Content Type
+
+   The following text is intended to register this memo as the MIME
+   content type "text/calendar".
+
+     To: ietf-types@uninett.no
+
+     Subject: Registration of MIME content type text/calendar.
+
+     MIME media type name: text
+
+     MIME subtype name: calendar
+
+
+
+Dawson & Stenerson          Standards Track                     [Page 8]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+3.2 Parameters
+
+   Required parameters: none
+
+   Optional parameters: charset, method, component and optinfo
+
+   The "charset" parameter is defined in [RFC 2046] for other body
+   parts. It is used to identify the default character set used within
+   the body part.
+
+   The "method" parameter is used to convey the iCalendar object method
+   or transaction semantics for the calendaring and scheduling
+   information. It also is an identifier for the restricted set of
+   properties and values that the iCalendar object consists of. The
+   parameter is to be used as a guide for applications interpreting the
+   information contained within the body part. It SHOULD NOT be used to
+   exclude or require particular pieces of information unless the
+   identified method definition specifically calls for this behavior.
+   Unless specifically forbidden by a particular method definition, a
+   text/calendar content type can contain any set of properties
+   permitted by the Calendaring and Scheduling Core Object
+   Specification. The "method" parameter MUST be the same value as that
+   specified in the "METHOD" component property in the iCalendar object.
+   If one is present, the other MUST also be present.
+
+   The value for the "method" parameter is defined as follows:
+
+        method  = 1*(ALPHA / DIGIT / "-")
+        ; IANA registered iCalendar object method
+
+   The "component" parameter conveys the type of iCalendar calendar
+   component within the body part. If the iCalendar object contains more
+   than one calendar component type, then multiple component parameters
+   MUST be specified.
+
+   The value for the "component" parameter is defined as follows:
+
+        component       = ("VEVENT" / "VTODO" / "VJOURNAL" / "VFREEBUSY"
+                        / "VTIMEZONE" / x-name / iana-token)
+
+   The "optinfo" parameter conveys optional information about the
+   iCalendar object within the body part. This parameter can only
+   specify semantics already specified by the iCalendar object and that
+   can be otherwise determined by parsing the body part. In addition,
+   the optional information specified by this parameter MUST be
+   consistent with that information specified by the iCalendar object.
+   For example, it can be used to convey the "Attendee" response status
+   to a meeting request. The parameter value consists of a string value.
+
+
+
+Dawson & Stenerson          Standards Track                     [Page 9]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   The parameter can be specified multiple times.
+
+   This parameter MAY only specify semantics already specified by the
+   iCalendar object and that can be otherwise determined by parsing the
+   body part.
+
+   The value for the "optinfo" parameter is defined as follows:
+
+        optinfo = infovalue / qinfovalue
+
+        infovalue       = iana-token / x-name
+
+        qinfovalue      = DQUOTE (infovalue) DQUOTE
+
+3.3 Content Header Fields
+
+   Optional content header fields: Any header fields defined by [RFC
+   2045].
+
+3.4 Encoding Considerations
+
+   This MIME content type can contain 8bit characters, so the use of
+   quoted-printable or BASE64 MIME content-transfer-encodings might be
+   necessary when iCalendar objects are transferred across protocols
+   restricted to the 7bit repertoire. Note that a text valued property
+   in the content entity can also have content encoding of special
+   characters using a BACKSLASH character (US-ASCII decimal 92)
+   escapement technique. This means that content values can end up
+   encoded twice.
+
+3.5 Security Considerations
+
+   SPOOFING - - In this memo, the "Organizer" is the only person
+   authorized to make changes to an existing "VEVENT", "VTODO",
+   "VJOURNAL" calendar component and redistribute the updates to the
+   "Attendees". An iCalendar object that maliciously changes or cancels
+   an existing "VEVENT", "VTODO" or "VJOURNAL" or "VFREEBUSY" calendar
+   component might be constructed by someone other than the "Organizer"
+   and sent to the "Attendees". In addition in this memo, other than the
+   "Organizer", an "Attendee" of a "VEVENT", "VTODO", "VJOURNAL"
+   calendar component is the only other person authorized to update any
+   parameter associated with their "ATTENDEE" property and send it to
+   the "Organizer". An iCalendar object that maliciously changes the
+   "ATTENDEE" parameters can be constructed by someone other than the
+   real "Attendee" and sent to the "Organizer".
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 10]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   PROCEDURAL ALARMS - - An iCalendar object can be created that
+   contains a "VEVENT" and "VTODO" calendar component with "VALARM"
+   calendar components. The "VALARM" calendar component can be of type
+   PROCEDURE and can have an attachment containing some sort of
+   executable program. Implementations that incorporate these types of
+   alarms are subject to any virus or malicious attack that might occur
+   as a result of executing the attachment.
+
+   ATTACHMENTS - - An iCalendar object can include references to Uniform
+   Resource Locators that can be programmed resources.
+
+   Implementers and users of this memo should be aware of the network
+   security implications of accepting and parsing such information. In
+   addition, the security considerations observed by implementations of
+   electronic mail systems should be followed for this memo.
+
+3.6 Interoperability Considerations
+
+   This MIME content type is intended to define a common format for
+   conveying calendaring and scheduling information between different
+   systems. It is heavily based on the earlier [VCAL] industry
+   specification.
+
+3.7 Applications Which Use This Media Type
+
+   This content-type is designed for widespread use by Internet
+   calendaring and scheduling applications. In addition, applications in
+   the workflow and document management area might find this content-
+   type applicable. The [ITIP] and [IMIP] Internet protocols directly
+   use this content-type also. Future work on an Internet calendar
+   access protocol will utilize this content-type too.
+
+3.8 Additional Information
+
+   This memo defines this content-type.
+
+3.9 Magic Numbers
+
+   None.
+
+3.10 File Extensions
+
+   The file extension of "ics" is to be used to designate a file
+   containing (an arbitrary set of) calendaring and scheduling
+   information consistent with this MIME content type.
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 11]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   The file extension of "ifb" is to be used to designate a file
+   containing free or busy time information consistent with this MIME
+   content type.
+
+   Macintosh file type codes: The file type code of "iCal" is to be used
+   in Apple MacIntosh operating system environments to designate a file
+   containing calendaring and scheduling information consistent with
+   this MIME media type.
+
+   The file type code of "iFBf" is to be used in Apple MacIntosh
+   operating system environments to designate a file containing free or
+   busy time information consistent with this MIME media type.
+
+3.11 Contact for Further Information:
+
+   Frank Dawson
+   6544 Battleford Drive
+   Raleigh, NC 27613-3502
+   919-676-9515 (Telephone)
+   919-676-9564 (Data/Facsimile)
+   Frank_Dawson@Lotus.com (Internet Mail)
+
+   Derik Stenerson
+   One Microsoft Way
+   Redmond, WA  98052-6399
+   425-936-5522 (Telephone)
+   425-936-7329 (Facsimile)
+   deriks@microsoft.com (Internet Mail)
+
+3.12 Intended Usage
+
+   COMMON
+
+3.13 Authors/Change Controllers
+
+   Frank Dawson
+   6544 Battleford Drive
+   Raleigh, NC 27613-3502
+   919-676-9515 (Telephone)
+   919-676-9564 (Data/Facsimile)
+   Frank_Dawson@Lotus.com (Internet Mail)
+
+   Derik Stenerson
+   One Microsoft Way
+   Redmond, WA  98052-6399
+   425-936-5522 (Telephone)
+   425-936-7329 (Facsimile)
+   deriks@microsoft.com (Internet Mail)
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 12]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+4 iCalendar Object Specification
+
+   The following sections define the details of a Calendaring and
+   Scheduling Core Object Specification. This information is intended to
+   be an integral part of the MIME content type registration. In
+   addition, this information can be used independent of such content
+   registration. In particular, this memo has direct applicability for
+   use as a calendaring and scheduling exchange format in file-, memory-
+   or network-based transport mechanisms.
+
+4.1 Content Lines
+
+   The iCalendar object is organized into individual lines of text,
+   called content lines. Content lines are delimited by a line break,
+   which is a CRLF sequence (US-ASCII decimal 13, followed by US-ASCII
+   decimal 10).
+
+   Lines of text SHOULD NOT be longer than 75 octets, excluding the line
+   break. Long content lines SHOULD be split into a multiple line
+   representations using a line "folding" technique. That is, a long
+   line can be split between any two characters by inserting a CRLF
+   immediately followed by a single linear white space character (i.e.,
+   SPACE, US-ASCII decimal 32 or HTAB, US-ASCII decimal 9). Any sequence
+   of CRLF followed immediately by a single linear white space character
+   is ignored (i.e., removed) when processing the content type.
+
+   For example the line:
+
+     DESCRIPTION:This is a long description that exists on a long line.
+
+   Can be represented as:
+
+     DESCRIPTION:This is a lo
+      ng description
+       that exists on a long line.
+
+   The process of moving from this folded multiple line representation
+   to its single line representation is called "unfolding". Unfolding is
+   accomplished by removing the CRLF character and the linear white
+   space character that immediately follows.
+
+   When parsing a content line, folded lines MUST first be unfolded
+   according to the unfolding procedure described above. When generating
+   a content line, lines longer than 75 octets SHOULD be folded
+   according to the folding procedure described above.
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 13]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   The content information associated with an iCalendar object is
+   formatted using a syntax similar to that defined by [RFC 2425]. That
+   is, the content information consists of CRLF-separated content lines.
+
+   The following notation defines the lines of content in an iCalendar
+   object:
+
+     contentline        = name *(";" param ) ":" value CRLF
+        ; This ABNF is just a general definition for an initial parsing
+        ; of the content line into its property name, parameter list,
+        ; and value string
+
+     ; When parsing a content line, folded lines MUST first
+        ; be unfolded according to the unfolding procedure
+        ; described above. When generating a content line, lines
+        ; longer than 75 octets SHOULD be folded according to
+        ; the folding procedure described above.
+
+     name               = x-name / iana-token
+
+     iana-token = 1*(ALPHA / DIGIT / "-")
+     ; iCalendar identifier registered with IANA
+
+     x-name             = "X-" [vendorid "-"] 1*(ALPHA / DIGIT / "-")
+     ; Reservered for experimental use. Not intended for use in
+     ; released products.
+
+     vendorid   = 3*(ALPHA / DIGIT)     ;Vendor identification
+
+     param              = param-name "=" param-value
+                          *("," param-value)
+        ; Each property defines the specific ABNF for the parameters
+        ; allowed on the property. Refer to specific properties for
+        ; precise parameter ABNF.
+
+     param-name = iana-token / x-token
+
+     param-value        = paramtext / quoted-string
+
+     paramtext  = *SAFE-CHAR
+
+     value      = *VALUE-CHAR
+
+     quoted-string      = DQUOTE *QSAFE-CHAR DQUOTE
+
+     NON-US-ASCII       = %x80-F8
+     ; Use restricted by charset parameter
+     ; on outer MIME object (UTF-8 preferred)
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 14]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     QSAFE-CHAR = WSP / %x21 / %x23-7E / NON-US-ASCII
+     ; Any character except CTLs and DQUOTE
+
+     SAFE-CHAR  = WSP / %x21 / %x23-2B / %x2D-39 / %x3C-7E
+                / NON-US-ASCII
+     ; Any character except CTLs, DQUOTE, ";", ":", ","
+
+     VALUE-CHAR = WSP / %x21-7E / NON-US-ASCII
+     ; Any textual character
+
+     CR = %x0D
+     ; carriage return
+
+     LF = %x0A
+     ; line feed
+
+     CRLF       = CR LF
+     ; Internet standard newline
+
+     CTL        = %x00-08 / %x0A-1F / %x7F
+        ; Controls
+
+     ALPHA      = %x41-5A / %x61-7A   ; A-Z / a-z
+
+     DIGIT      = %x30-39
+        ; 0-9
+
+     DQUOTE     = %x22
+        ; Quotation Mark
+
+     WSP        = SPACE / HTAB
+
+     SPACE      = %x20
+
+     HTAB       = %x09
+
+   The property value component of a content line has a format that is
+   property specific. Refer to the section describing each property for
+   a definition of this format.
+
+   All names of properties, property parameters, enumerated property
+   values and property parameter values are case-insensitive. However,
+   all other property values are case-sensitive, unless otherwise
+   stated.
+
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 15]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+4.1.1 List and Field Separators
+
+   Some properties and parameters allow a list of values. Values in a
+   list of values MUST be separated by a COMMA character (US-ASCII
+   decimal 44). There is no significance to the order of values in a
+   list. For those parameter values (such as those that specify URI
+   values) that are specified in quoted-strings, the individual quoted-
+   strings are separated by a COMMA character (US-ASCII decimal 44).
+
+   Some property values are defined in terms of multiple parts. These
+   structured property values MUST have their value parts separated by a
+   SEMICOLON character (US-ASCII decimal 59).
+
+   Some properties allow a list of parameters. Each property parameter
+   in a list of property parameters MUST be separated by a SEMICOLON
+   character (US-ASCII decimal 59).
+
+   Property parameters with values containing a COLON, a SEMICOLON or a
+   COMMA character MUST be placed in quoted text.
+
+   For example, in the following properties a SEMICOLON is used to
+   separate property parameters from each other, and a COMMA is used to
+   separate property values in a value list.
+
+     ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT:MAILTO:
+      jsmith@host.com
+
+     RDATE;VALUE=DATE:19970304,19970504,19970704,19970904
+
+4.1.2 Multiple Values
+
+   Some properties defined in the iCalendar object can have multiple
+   values. The general rule for encoding multi-valued items is to simply
+   create a new content line for each value, including the property
+   name. However, it should be noted that some properties support
+   encoding multiple values in a single property by separating the
+   values with a COMMA character (US-ASCII decimal 44). Individual
+   property definitions should be consulted for determining whether a
+   specific property allows multiple values and in which of these two
+   forms.
+
+4.1.3 Binary Content
+
+   Binary content information in an iCalendar object SHOULD be
+   referenced using a URI within a property value. That is the binary
+   content information SHOULD be placed in an external MIME entity that
+   can be referenced by a URI from within the iCalendar object. In
+   applications where this is not feasible, binary content information
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 16]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   can be included within an iCalendar object, but only after first
+   encoding it into text using the "BASE64" encoding method defined in
+   [RFC 2045]. Inline binary contact SHOULD only be used in applications
+   whose special circumstances demand that an iCalendar object be
+   expressed as a single entity. A property containing inline binary
+   content information MUST specify the "ENCODING" property parameter.
+   Binary content information placed external to the iCalendar object
+   MUST be referenced by a uniform resource identifier (URI).
+
+   The following example specifies an "ATTACH" property that references
+   an attachment external to the iCalendar object with a URI reference:
+
+     ATTACH:http://xyz.com/public/quarterly-report.doc
+
+   The following example specifies an "ATTACH" property with inline
+   binary encoded content information:
+
+     ATTACH;FMTTYPE=image/basic;ENCODING=BASE64;VALUE=BINARY:
+      MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcNAQEEBQAwdzELMAkGA1U
+      EBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENvbW11bmljYXRpb25zIE
+        <...remainder of "BASE64" encoded binary data...>
+
+4.1.4 Character Set
+
+   There is not a property parameter to declare the character set used
+   in a property value. The default character set for an iCalendar
+   object is UTF-8 as defined in [RFC 2279].
+
+   The "charset" Content-Type parameter can be used in MIME transports
+   to specify any other IANA registered character set.
+
+4.2 Property Parameters
+
+   A property can have attributes associated with it. These "property
+   parameters" contain meta-information about the property or the
+   property value. Property parameters are provided to specify such
+   information as the location of an alternate text representation for a
+   property value, the language of a text property value, the data type
+   of the property value and other attributes.
+
+   Property parameter values that contain the COLON (US-ASCII decimal
+   58), SEMICOLON (US-ASCII decimal 59) or COMMA (US-ASCII decimal 44)
+   character separators MUST be specified as quoted-string text values.
+   Property parameter values MUST NOT contain the DOUBLE-QUOTE (US-ASCII
+   decimal 22) character. The DOUBLE-QUOTE (US-ASCII decimal 22)
+   character is used as a delimiter for parameter values that contain
+   restricted characters or URI text. For example:
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 17]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     DESCRIPTION;ALTREP="http://www.wiz.org":The Fall'98 Wild Wizards
+       Conference - - Las Vegas, NV, USA
+
+   Property parameter values that are not in quoted strings are case
+   insensitive.
+
+   The general property parameters defined by this memo are defined by
+   the following notation:
+
+     parameter  = altrepparam           ; Alternate text representation
+                / cnparam               ; Common name
+                / cutypeparam           ; Calendar user type
+                / delfromparam          ; Delegator
+                / deltoparam            ; Delegatee
+                / dirparam              ; Directory entry
+                / encodingparam         ; Inline encoding
+                / fmttypeparam          ; Format type
+                / fbtypeparam           ; Free/busy time type
+                / languageparam         ; Language for text
+                / memberparam           ; Group or list membership
+                / partstatparam         ; Participation status
+                / rangeparam            ; Recurrence identifier range
+                / trigrelparam          ; Alarm trigger relationship
+                / reltypeparam          ; Relationship type
+                / roleparam             ; Participation role
+                / rsvpparam             ; RSVP expectation
+                / sentbyparam           ; Sent by
+                / tzidparam             ; Reference to time zone object
+                / valuetypeparam        ; Property value data type
+                / ianaparam
+        ; Some other IANA registered iCalendar parameter.
+                / xparam
+        ; A non-standard, experimental parameter.
+
+     ianaparam  = iana-token "=" param-value *("," param-value)
+
+     xparam     =x-name "=" param-value *("," param-value)
+
+4.2.1 Alternate Text Representation
+
+   Parameter Name: ALTREP
+
+   Purpose: To specify an alternate text representation for the property
+   value.
+
+   Format Definition: The property parameter is defined by the following
+   notation:
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 18]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     altrepparam        = "ALTREP" "=" DQUOTE uri DQUOTE
+
+   Description: The parameter specifies a URI that points to an
+   alternate representation for a textual property value. A property
+   specifying this parameter MUST also include a value that reflects the
+   default representation of the text value. The individual URI
+   parameter values MUST each be specified in a quoted-string.
+
+   Example:
+
+     DESCRIPTION;ALTREP="CID:<part3.msg.970415T083000@host.com>":Project
+       XYZ Review Meeting will include the following agenda items: (a)
+       Market Overview, (b) Finances, (c) Project Management
+
+   The "ALTREP" property parameter value might point to a "text/html"
+   content portion.
+
+     Content-Type:text/html
+     Content-Id:<part3.msg.970415T083000@host.com>
+
+     <html><body>
+     <p><b>Project XYZ Review Meeting</b> will include the following
+     agenda items:<ol><li>Market
+     Overview</li><li>Finances</li><li>Project Management</li></ol></p>
+     </body></html>
+
+4.2.2 Common Name
+
+   Parameter Name: CN
+
+   Purpose: To specify the common name to be associated with the
+   calendar user specified by the property.
+
+   Format Definition: The property parameter is defined by the following
+   notation:
+
+     cnparam    = "CN" "=" param-value
+
+   Description: This parameter can be specified on properties with a
+   CAL-ADDRESS value type. The parameter specifies the common name to be
+   associated with the calendar user specified by the property. The
+   parameter value is text. The parameter value can be used for display
+   text to be associated with the calendar address specified by the
+   property.
+
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 19]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Example:
+
+     ORGANIZER;CN="John Smith":MAILTO:jsmith@host.com
+
+4.2.3 Calendar User Type
+
+   Parameter Name: CUTYPE
+
+   Purpose: To specify the type of calendar user specified by the
+   property.
+
+   Format Definition: The property parameter is defined by the following
+   notation:
+
+     cutypeparam        = "CUTYPE" "="
+                         ("INDIVIDUAL"          ; An individual
+                        / "GROUP"               ; A group of individuals
+                        / "RESOURCE"            ; A physical resource
+                        / "ROOM"                ; A room resource
+                        / "UNKNOWN"             ; Otherwise not known
+                        / x-name                ; Experimental type
+                        / iana-token)           ; Other IANA registered
+                                                ; type
+     ; Default is INDIVIDUAL
+
+   Description: This parameter can be specified on properties with a
+   CAL-ADDRESS value type. The parameter identifies the type of calendar
+   user specified by the property. If not specified on a property that
+   allows this parameter, the default is INDIVIDUAL.
+
+   Example:
+
+     ATTENDEE;CUTYPE=GROUP:MAILTO:ietf-calsch@imc.org
+
+4.2.4 Delegators
+
+   Parameter Name: DELEGATED-FROM
+
+   Purpose: To specify the calendar users that have delegated their
+   participation to the calendar user specified by the property.
+
+   Format Definition: The property parameter is defined by the following
+   notation:
+
+     delfromparam       = "DELEGATED-FROM" "=" DQUOTE cal-address DQUOTE
+                          *("," DQUOTE cal-address DQUOTE)
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 20]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Description: This parameter can be specified on properties with a
+   CAL-ADDRESS value type. This parameter can be specified on a property
+   that has a value type of calendar address. This parameter specifies
+   those calendar uses that have delegated their participation in a
+   group scheduled event or to-do to the calendar user specified by the
+   property. The value MUST be a MAILTO URI as defined in [RFC 1738].
+   The individual calendar address parameter values MUST each be
+   specified in a quoted-string.
+
+   Example:
+
+     ATTENDEE;DELEGATED-FROM="MAILTO:jsmith@host.com":MAILTO:
+      jdoe@host.com
+
+4.2.5 Delegatees
+
+   Parameter Name: DELEGATED-TO
+
+   Purpose: To specify the calendar users to whom the calendar user
+   specified by the property has delegated participation.
+
+   Format Definition: The property parameter is defined by the following
+   notation:
+
+     deltoparam = "DELEGATED-TO" "=" DQUOTE cal-address DQUOTE
+                  *("," DQUOTE cal-address DQUOTE)
+
+   Description: This parameter can be specified on properties with a
+   CAL-ADDRESS value type. This parameter specifies those calendar users
+   whom have been delegated participation in a group scheduled event or
+   to-do by the calendar user specified by the property. The value MUST
+   be a MAILTO URI as defined in [RFC 1738]. The individual calendar
+   address parameter values MUST each be specified in a quoted-string.
+
+   Example:
+
+     ATTENDEE;DELEGATED-TO="MAILTO:jdoe@host.com","MAILTO:jqpublic@
+      host.com":MAILTO:jsmith@host.com
+
+4.2.6 Directory Entry Reference
+
+   Parameter Name: DIR
+
+   Purpose: To specify reference to a directory entry associated with
+   the calendar user specified by the property.
+
+   Format Definition: The property parameter is defined by the following
+   notation:
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 21]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     dirparam   = "DIR" "=" DQUOTE uri DQUOTE
+
+   Description: This parameter can be specified on properties with a
+   CAL-ADDRESS value type. The parameter specifies a reference to the
+   directory entry associated with the calendar user specified by the
+   property. The parameter value is a URI. The individual URI parameter
+   values MUST each be specified in a quoted-string.
+
+   Example:
+
+     ORGANIZER;DIR="ldap://host.com:6666/o=eDABC%20Industries,c=3DUS??
+      (cn=3DBJim%20Dolittle)":MAILTO:jimdo@host1.com
+
+4.2.7 Inline Encoding
+
+   Parameter Name: ENCODING
+
+   Purpose: To specify an alternate inline encoding for the property
+   value.
+
+   Format Definition: The property parameter is defined by the following
+   notation:
+
+     encodingparam      = "ENCODING" "="
+                          ("8BIT"
+        ; "8bit" text encoding is defined in [RFC 2045]
+                        / "BASE64"
+        ; "BASE64" binary encoding format is defined in [RFC 2045]
+                        / iana-token
+        ; Some other IANA registered iCalendar encoding type
+                        / x-name)
+        ; A non-standard, experimental encoding type
+
+   Description: The property parameter identifies the inline encoding
+   used in a property value. The default encoding is "8BIT",
+   corresponding to a property value consisting of text. The "BASE64"
+   encoding type corresponds to a property value encoded using the
+   "BASE64" encoding defined in [RFC 2045].
+
+   If the value type parameter is ";VALUE=BINARY", then the inline
+   encoding parameter MUST be specified with the value
+   ";ENCODING=BASE64".
+
+
+
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 22]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Example:
+
+     ATTACH;FMTYPE=IMAGE/JPEG;ENCODING=BASE64;VALUE=BINARY:MIICajC
+      CAdOgAwIBAgICBEUwDQYJKoZIhvcNAQEEBQAwdzELMAkGA1UEBhMCVVMxLDA
+      qBgNVBAoTI05ldHNjYXBlIENvbW11bmljYXRpb25zIENvcnBvcmF0aW9uMRw
+      <...remainder of "BASE64" encoded binary data...>
+
+4.2.8 Format Type
+
+   Parameter Name: FMTTYPE
+
+   Purpose: To specify the content type of a referenced object.
+
+   Format Definition: The property parameter is defined by the following
+   notation:
+
+     fmttypeparam       = "FMTTYPE" "=" iana-token
+                                        ; A IANA registered content type
+                                     / x-name
+                                        ; A non-standard content type
+
+   Description: This parameter can be specified on properties that are
+   used to reference an object. The parameter specifies the content type
+   of the referenced object. For example, on the "ATTACH" property, a
+   FTP type URI value does not, by itself, necessarily convey the type
+   of content associated with the resource. The parameter value MUST be
+   the TEXT for either an IANA registered content type or a non-standard
+   content type.
+
+     Example:
+
+      ATTACH;FMTTYPE=application/binary:ftp://domain.com/pub/docs/
+       agenda.doc
+
+4.2.9 Free/Busy Time Type
+
+   Parameter Name: FBTYPE
+
+   Purpose: To specify the free or busy time type.
+
+   Format Definition: The property parameter is defined by the following
+   notation:
+
+     fbtypeparam        = "FBTYPE" "=" ("FREE" / "BUSY"
+                        / "BUSY-UNAVAILABLE" / "BUSY-TENTATIVE"
+                        / x-name
+        ; Some experimental iCalendar data type.
+                        / iana-token)
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 23]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+        ; Some other IANA registered iCalendar data type.
+
+   Description: The parameter specifies the free or busy time type. The
+   value FREE indicates that the time interval is free for scheduling.
+   The value BUSY indicates that the time interval is busy because one
+   or more events have been scheduled for that interval. The value
+   BUSY-UNAVAILABLE indicates that the time interval is busy and that
+   the interval can not be scheduled. The value BUSY-TENTATIVE indicates
+   that the time interval is busy because one or more events have been
+   tentatively scheduled for that interval. If not specified on a
+   property that allows this parameter, the default is BUSY.
+
+   Example: The following is an example of this parameter on a FREEBUSY
+   property.
+
+     FREEBUSY;FBTYPE=BUSY:19980415T133000Z/19980415T170000Z
+
+4.2.10 Language
+
+   Parameter Name: LANGUAGE
+
+   Purpose: To specify the language for text values in a property or
+   property parameter.
+
+   Format Definition: The property parameter is defined by the following
+   notation:
+
+     languageparam =    "LANGUAGE" "=" language
+
+     language = <Text identifying a language, as defined in [RFC 1766]>
+
+   Description: This parameter can be specified on properties with a
+   text value type. The parameter identifies the language of the text in
+   the property or property parameter value. The value of the "language"
+   property parameter is that defined in [RFC 1766].
+
+   For transport in a MIME entity, the Content-Language header field can
+   be used to set the default language for the entire body part.
+   Otherwise, no default language is assumed.
+
+   Example:
+
+     SUMMARY;LANGUAGE=us-EN:Company Holiday Party
+
+     LOCATION;LANGUAGE=en:Germany
+     LOCATION;LANGUAGE=no:Tyskland
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 24]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   The following example makes use of the Quoted-Printable encoding in
+   order to represent non-ASCII characters.
+
+     LOCATION;LANGUAGE=da:K=F8benhavn
+     LOCATION;LANGUAGE=en:Copenhagen
+
+4.2.11  Group or List Membership
+
+   Parameter Name: MEMBER
+
+   Purpose: To specify the group or list membership of the calendar user
+   specified by the property.
+
+   Format Definition: The property parameter is defined by the following
+   notation:
+
+     memberparam        = "MEMBER" "=" DQUOTE cal-address DQUOTE
+                          *("," DQUOTE cal-address DQUOTE)
+
+   Description: This parameter can be specified on properties with a
+   CAL-ADDRESS value type. The parameter identifies the groups or list
+   membership for the calendar user specified by the property. The
+   parameter value either a single calendar address in a quoted-string
+   or a COMMA character (US-ASCII decimal 44) list of calendar
+   addresses, each in a quoted-string. The individual calendar address
+   parameter values MUST each be specified in a quoted-string.
+
+   Example:
+
+     ATTENDEE;MEMBER="MAILTO:ietf-calsch@imc.org":MAILTO:jsmith@host.com
+
+     ATTENDEE;MEMBER="MAILTO:projectA@host.com","MAILTO:projectB@host.
+      com":MAILTO:janedoe@host.com
+
+4.2.12 Participation Status
+
+   Parameter Name: PARTSTAT
+
+   Purpose: To specify the participation status for the calendar user
+   specified by the property.
+
+   Format Definition: The property parameter is defined by the following
+   notation:
+
+     partstatparam      = "PARTSTAT" "="
+                         ("NEEDS-ACTION"        ; Event needs action
+                        / "ACCEPTED"            ; Event accepted
+                        / "DECLINED"            ; Event declined
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 25]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+                        / "TENTATIVE"           ; Event tentatively
+                                                ; accepted
+                        / "DELEGATED"           ; Event delegated
+                        / x-name                ; Experimental status
+                        / iana-token)           ; Other IANA registered
+                                                ; status
+     ; These are the participation statuses for a "VEVENT". Default is
+     ; NEEDS-ACTION
+     partstatparam      /= "PARTSTAT" "="
+                         ("NEEDS-ACTION"        ; To-do needs action
+                        / "ACCEPTED"            ; To-do accepted
+                        / "DECLINED"            ; To-do declined
+                        / "TENTATIVE"           ; To-do tentatively
+                                                ; accepted
+                        / "DELEGATED"           ; To-do delegated
+                        / "COMPLETED"           ; To-do completed.
+                                                ; COMPLETED property has
+                                                ;date/time completed.
+                        / "IN-PROCESS"          ; To-do in process of
+                                                ; being completed
+                        / x-name                ; Experimental status
+                        / iana-token)           ; Other IANA registered
+                                                ; status
+     ; These are the participation statuses for a "VTODO". Default is
+     ; NEEDS-ACTION
+
+     partstatparam      /= "PARTSTAT" "="
+                         ("NEEDS-ACTION"        ; Journal needs action
+                        / "ACCEPTED"            ; Journal accepted
+                        / "DECLINED"            ; Journal declined
+                        / x-name                ; Experimental status
+                        / iana-token)           ; Other IANA registered
+                                                ; status
+     ; These are the participation statuses for a "VJOURNAL". Default is
+     ; NEEDS-ACTION
+
+   Description: This parameter can be specified on properties with a
+   CAL-ADDRESS value type. The parameter identifies the participation
+   status for the calendar user specified by the property value. The
+   parameter values differ depending on whether they are associated with
+   a group scheduled "VEVENT", "VTODO" or "VJOURNAL". The values MUST
+   match one of the values allowed for the given calendar component. If
+   not specified on a property that allows this parameter, the default
+   value is NEEDS-ACTION.
+
+   Example:
+
+     ATTENDEE;PARTSTAT=DECLINED:MAILTO:jsmith@host.com
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 26]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+4.2.13  Recurrence Identifier Range
+
+   Parameter Name: RANGE
+
+   Purpose: To specify the effective range of recurrence instances from
+   the instance specified by the recurrence identifier specified by the
+   property.
+
+   Format Definition: The property parameter is defined by the following
+   notation:
+
+     rangeparam = "RANGE" "=" ("THISANDPRIOR"
+        ; To specify all instances prior to the recurrence identifier
+                / "THISANDFUTURE")
+        ; To specify the instance specified by the recurrence identifier
+        ; and all subsequent recurrence instances
+
+   Description: The parameter can be specified on a property that
+   specifies a recurrence identifier. The parameter specifies the
+   effective range of recurrence instances that is specified by the
+   property. The effective range is from the recurrence identified
+   specified by the property. If this parameter is not specified an
+   allowed property, then the default range is the single instance
+   specified by the recurrence identifier value of the property. The
+   parameter value can be "THISANDPRIOR" to indicate a range defined by
+   the recurrence identified value of the property and all prior
+   instances. The parameter value can also be "THISANDFUTURE" to
+   indicate a range defined by the recurrence identifier and all
+   subsequent instances.
+
+   Example:
+
+     RECURRENCE-ID;RANGE=THISANDPRIOR:19980401T133000Z
+
+4.2.14 Alarm Trigger Relationship
+
+   Parameter Name: RELATED
+
+   Purpose: To specify the relationship of the alarm trigger with
+   respect to the start or end of the calendar component.
+
+   Format Definition: The property parameter is defined by the following
+   notation:
+
+     trigrelparam       = "RELATED" "="
+                         ("START"       ; Trigger off of start
+                        / "END")        ; Trigger off of end
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 27]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Description: The parameter can be specified on properties that
+   specify an alarm trigger with a DURATION value type. The parameter
+   specifies whether the alarm will trigger relative to the start or end
+   of the calendar component. The parameter value START will set the
+   alarm to trigger off the start of the calendar component; the
+   parameter value END will set the alarm to trigger off the end of the
+   calendar component. If the parameter is not specified on an allowable
+   property, then the default is START.
+
+   Example:
+
+     TRIGGER;RELATED=END:PT5M
+
+4.2.15 Relationship Type
+
+   Parameter Name: RELTYPE
+
+   Purpose: To specify the type of hierarchical relationship associated
+   with the calendar component specified by the property.
+
+   Format Definition: The property parameter is defined by the following
+   notation:
+
+     reltypeparam       = "RELTYPE" "="
+                         ("PARENT"      ; Parent relationship. Default.
+                        / "CHILD"       ; Child relationship
+                        / "SIBLING      ; Sibling relationship
+                        / iana-token    ; Some other IANA registered
+                                        ; iCalendar relationship type
+                        / x-name)       ; A non-standard, experimental
+                                        ; relationship type
+
+   Description: This parameter can be specified on a property that
+   references another related calendar. The parameter specifies the
+   hierarchical relationship type of the calendar component referenced
+   by the property. The parameter value can be PARENT, to indicate that
+   the referenced calendar component is a superior of calendar
+   component; CHILD to indicate that the referenced calendar component
+   is a subordinate of the calendar component; SIBLING to indicate that
+   the referenced calendar component is a peer of the calendar
+   component. If this parameter is not specified on an allowable
+   property, the default relationship type is PARENT.
+
+   Example:
+
+     RELATED-TO;RELTYPE=SIBLING:<19960401-080045-4000F192713@host.com>
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 28]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+4.2.16 Participation Role
+
+   Parameter Name: ROLE
+
+   Purpose: To specify the participation role for the calendar user
+   specified by the property.
+
+   Format Definition: The property parameter is defined by the following
+   notation:
+
+     roleparam  = "ROLE" "="
+                 ("CHAIR"               ; Indicates chair of the
+                                        ; calendar entity
+                / "REQ-PARTICIPANT"     ; Indicates a participant whose
+                                        ; participation is required
+                / "OPT-PARTICIPANT"     ; Indicates a participant whose
+                                        ; participation is optional
+                / "NON-PARTICIPANT"     ; Indicates a participant who is
+                                        ; copied for information
+                                        ; purposes only
+                / x-name                ; Experimental role
+                / iana-token)           ; Other IANA role
+     ; Default is REQ-PARTICIPANT
+
+   Description: This parameter can be specified on properties with a
+   CAL-ADDRESS value type. The parameter specifies the participation
+   role for the calendar user specified by the property in the group
+   schedule calendar component. If not specified on a property that
+   allows this parameter, the default value is REQ-PARTICIPANT.
+
+   Example:
+
+     ATTENDEE;ROLE=CHAIR:MAILTO:mrbig@host.com
+
+4.2.17  RSVP Expectation
+
+   Parameter Name: RSVP
+
+   Purpose: To specify whether there is an expectation of a favor of a
+   reply from the calendar user specified by the property value.
+
+   Format Definition: The property parameter is defined by the following
+   notation:
+
+     rsvpparam = "RSVP" "=" ("TRUE" / "FALSE")
+     ; Default is FALSE
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 29]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Description: This parameter can be specified on properties with a
+   CAL-ADDRESS value type. The parameter identifies the expectation of a
+   reply from the calendar user specified by the property value. This
+   parameter is used by the "Organizer" to request a participation
+   status reply from an "Attendee" of a group scheduled event or to-do.
+   If not specified on a property that allows this parameter, the
+   default value is FALSE.
+
+   Example:
+
+     ATTENDEE;RSVP=TRUE:MAILTO:jsmith@host.com
+
+4.2.18  Sent By
+
+   Parameter Name: SENT-BY
+
+   Purpose: To specify the calendar user that is acting on behalf of the
+   calendar user specified by the property.
+
+   Format Definition: The property parameter is defined by the following
+   notation:
+
+     sentbyparam        = "SENT-BY" "=" DQUOTE cal-address DQUOTE
+
+   Description: This parameter can be specified on properties with a
+   CAL-ADDRESS value type. The parameter specifies the calendar user
+   that is acting on behalf of the calendar user specified by the
+   property. The parameter value MUST be a MAILTO URI as defined in [RFC
+   1738]. The individual calendar address parameter values MUST each be
+   specified in a quoted-string.
+
+   Example:
+
+     ORGANIZER;SENT-BY:"MAILTO:sray@host.com":MAILTO:jsmith@host.com
+
+4.2.19 Time Zone Identifier
+
+   Parameter Name: TZID
+
+   Purpose: To specify the identifier for the time zone definition for a
+   time component in the property value.
+
+   Format Definition: This property parameter is defined by the
+   following notation:
+
+     tzidparam  = "TZID" "=" [tzidprefix] paramtext CRLF
+
+     tzidprefix = "/"
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 30]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Description: The parameter MUST be specified on the "DTSTART",
+   "DTEND", "DUE", "EXDATE" and "RDATE" properties when either a DATE-
+   TIME or TIME value type is specified and when the value is not either
+   a UTC or a "floating" time. Refer to the DATE-TIME or TIME value type
+   definition for a description of UTC and "floating time" formats. This
+   property parameter specifies a text value which uniquely identifies
+   the "VTIMEZONE" calendar component to be used when evaluating the
+   time portion of the property. The value of the TZID property
+   parameter will be equal to the value of the TZID property for the
+   matching time zone definition. An individual "VTIMEZONE" calendar
+   component MUST be specified for each unique "TZID" parameter value
+   specified in the iCalendar object.
+
+   The parameter MUST be specified on properties with a DATE-TIME value
+   if the DATE-TIME is not either a UTC or a "floating" time.
+
+   The presence of the SOLIDUS character (US-ASCII decimal 47) as a
+   prefix, indicates that this TZID represents a unique ID in a globally
+   defined time zone registry (when such registry is defined).
+
+        Note: This document does not define a naming convention for time
+        zone identifiers. Implementers may want to use the naming
+        conventions defined in existing time zone specifications such as
+        the public-domain Olson database [TZ]. The specification of
+        globally unique time zone identifiers is not addressed by this
+        document and is left for future study.
+
+   The following are examples of this property parameter:
+
+     DTSTART;TZID=US-Eastern:19980119T020000
+
+     DTEND;TZID=US-Eastern:19980119T030000
+
+   The TZID property parameter MUST NOT be applied to DATE-TIME or TIME
+   properties whose time values are specified in UTC.
+
+   The use of local time in a DATE-TIME or TIME value without the TZID
+   property parameter is to be interpreted as a local time value,
+   regardless of the existence of "VTIMEZONE" calendar components in the
+   iCalendar object.
+
+   For more information see the sections on the data types DATE-TIME and
+   TIME.
+
+
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 31]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+4.2.20 Value Data Types
+
+   Parameter Name: VALUE
+
+   Purpose: To explicitly specify the data type format for a property
+   value.
+
+   Format Definition: The "VALUE" property parameter is defined by the
+   following notation:
+
+     valuetypeparam = "VALUE" "=" valuetype
+
+     valuetype  = ("BINARY"
+                / "BOOLEAN"
+                / "CAL-ADDRESS"
+                / "DATE"
+                / "DATE-TIME"
+                / "DURATION"
+                / "FLOAT"
+                / "INTEGER"
+                / "PERIOD"
+                / "RECUR"
+                / "TEXT"
+                / "TIME"
+                / "URI"
+                / "UTC-OFFSET"
+                / x-name
+                ; Some experimental iCalendar data type.
+                / iana-token)
+                ; Some other IANA registered iCalendar data type.
+
+   Description: The parameter specifies the data type and format of the
+   property value. The property values MUST be of a single value type.
+   For example, a "RDATE" property cannot have a combination of DATE-
+   TIME and TIME value types.
+
+   If the property's value is the default value type, then this
+   parameter need not be specified. However, if the property's default
+   value type is overridden by some other allowable value type, then
+   this parameter MUST be specified.
+
+4.3 Property Value Data Types
+
+   The properties in an iCalendar object are strongly typed. The
+   definition of each property restricts the value to be one of the
+   value data types, or simply value types, defined in this section. The
+   value type for a property will either be specified implicitly as the
+   default value type or will be explicitly specified with the "VALUE"
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 32]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   parameter. If the value type of a property is one of the alternate
+   valid types, then it MUST be explicitly specified with the "VALUE"
+   parameter.
+
+4.3.1   Binary
+
+   Value Name: BINARY
+
+   Purpose: This value type is used to identify properties that contain
+   a character encoding of inline binary data. For example, an inline
+   attachment of an object code might be included in an iCalendar
+   object.
+
+   Formal Definition: The value type is defined by the following
+   notation:
+
+     binary     = *(4b-char) [b-end]
+     ; A "BASE64" encoded character string, as defined by [RFC 2045].
+
+     b-end      = (2b-char "==") / (3b-char "=")
+
+     b-char = ALPHA / DIGIT / "+" / "/"
+
+   Description: Property values with this value type MUST also include
+   the inline encoding parameter sequence of ";ENCODING=BASE64". That
+   is, all inline binary data MUST first be character encoded using the
+   "BASE64" encoding method defined in [RFC 2045]. No additional content
+   value encoding (i.e., BACKSLASH character encoding) is defined for
+   this value type.
+
+   Example: The following is an abridged example of a "BASE64" encoded
+   binary value data.
+
+     ATTACH;VALUE=BINARY;ENCODING=BASE64:MIICajCCAdOgAwIBAgICBEUwDQY
+      JKoZIhvcNAQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlI
+      ENvbW11bmljYXRpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZv
+        <...remainder of "BASE64" encoded binary data...>
+
+4.3.2   Boolean
+
+   Value Name: BOOLEAN
+
+   Purpose: This value type is used to identify properties that contain
+   either a "TRUE" or "FALSE" Boolean value.
+
+   Formal Definition: The value type is defined by the following
+   notation:
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 33]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     boolean    = "TRUE" / "FALSE"
+
+   Description: These values are case insensitive text. No additional
+   content value encoding (i.e., BACKSLASH character encoding) is
+   defined for this value type.
+
+   Example: The following is an example of a hypothetical property that
+   has a BOOLEAN value type:
+
+   GIBBERISH:TRUE
+
+4.3.3   Calendar User Address
+
+   Value Name: CAL-ADDRESS
+
+   Purpose: This value type is used to identify properties that contain
+   a calendar user address.
+
+   Formal Definition: The value type is as defined by the following
+   notation:
+
+     cal-address        = uri
+
+   Description: The value is a URI as defined by [RFC 1738] or any other
+   IANA registered form for a URI. When used to address an Internet
+   email transport address for a calendar user, the value MUST be a
+   MAILTO URI, as defined by [RFC 1738]. No additional content value
+   encoding (i.e., BACKSLASH character encoding) is defined for this
+   value type.
+
+   Example:
+
+     ATTENDEE:MAILTO:jane_doe@host.com
+
+4.3.4 Date
+
+   Value Name: DATE
+
+   Purpose: This value type is used to identify values that contain a
+   calendar date.
+
+   Formal Definition: The value type is defined by the following
+   notation:
+
+     date               = date-value
+
+     date-value         = date-fullyear date-month date-mday
+     date-fullyear      = 4DIGIT
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 34]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     date-month         = 2DIGIT        ;01-12
+     date-mday          = 2DIGIT        ;01-28, 01-29, 01-30, 01-31
+                                        ;based on month/year
+
+   Description: If the property permits, multiple "date" values are
+   specified as a COMMA character (US-ASCII decimal 44) separated list
+   of values. The format for the value type is expressed as the [ISO
+   8601] complete representation, basic format for a calendar date. The
+   textual format specifies a four-digit year, two-digit month, and
+   two-digit day of the month. There are no separator characters between
+   the year, month and day component text.
+
+   No additional content value encoding (i.e., BACKSLASH character
+   encoding) is defined for this value type.
+
+   Example: The following represents July 14, 1997:
+
+     19970714
+
+4.3.5   Date-Time
+
+   Value Name: DATE-TIME
+
+   Purpose: This value type is used to identify values that specify a
+   precise calendar date and time of day.
+
+   Formal Definition: The value type is defined by the following
+   notation:
+
+     date-time  = date "T" time ;As specified in the date and time
+                                ;value definitions
+
+   Description: If the property permits, multiple "date-time" values are
+   specified as a COMMA character (US-ASCII decimal 44) separated list
+   of values. No additional content value encoding (i.e., BACKSLASH
+   character encoding) is defined for this value type.
+
+   The "DATE-TIME" data type is used to identify values that contain a
+   precise calendar date and time of day. The format is based on the
+   [ISO 8601] complete representation, basic format for a calendar date
+   and time of day. The text format is a concatenation of the "date",
+   followed by the LATIN CAPITAL LETTER T character (US-ASCII decimal
+   84) time designator, followed by the "time" format.
+
+   The "DATE-TIME" data type expresses time values in three forms:
+
+   The form of date and time with UTC offset MUST NOT be used. For
+   example, the following is not valid for a date-time value:
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 35]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     DTSTART:19980119T230000-0800       ;Invalid time format
+
+   FORM #1: DATE WITH LOCAL TIME
+
+   The date with local time form is simply a date-time value that does
+   not contain the UTC designator nor does it reference a time zone. For
+   example, the following represents Janurary 18, 1998, at 11 PM:
+
+     DTSTART:19980118T230000
+
+   Date-time values of this type are said to be "floating" and are not
+   bound to any time zone in particular. They are used to represent the
+   same hour, minute, and second value regardless of which time zone is
+   currently being observed. For example, an event can be defined that
+   indicates that an individual will be busy from 11:00 AM to 1:00 PM
+   every day, no matter which time zone the person is in. In these
+   cases, a local time can be specified. The recipient of an iCalendar
+   object with a property value consisting of a local time, without any
+   relative time zone information, SHOULD interpret the value as being
+   fixed to whatever time zone the ATTENDEE is in at any given moment.
+   This means that two ATTENDEEs, in different time zones, receiving the
+   same event definition as a floating time, may be participating in the
+   event at different actual times. Floating time SHOULD only be used
+   where that is the reasonable behavior.
+
+   In most cases, a fixed time is desired. To properly communicate a
+   fixed time in a property value, either UTC time or local time with
+   time zone reference MUST be specified.
+
+   The use of local time in a DATE-TIME value without the TZID property
+   parameter is to be interpreted as floating time, regardless of the
+   existence of "VTIMEZONE" calendar components in the iCalendar object.
+
+   FORM #2: DATE WITH UTC TIME
+
+   The date with UTC time, or absolute time, is identified by a LATIN
+   CAPITAL LETTER Z suffix character (US-ASCII decimal 90), the UTC
+   designator, appended to the time value. For example, the following
+   represents January 19, 1998, at 0700 UTC:
+
+     DTSTART:19980119T070000Z
+
+   The TZID property parameter MUST NOT be applied to DATE-TIME
+   properties whose time values are specified in UTC.
+
+   FORM #3: DATE WITH LOCAL TIME AND TIME ZONE REFERENCE
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 36]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   The date and local time with reference to time zone information is
+   identified by the use the TZID property parameter to reference the
+   appropriate time zone definition. TZID is discussed in detail in the
+   section on Time Zone. For example, the following represents 2 AM in
+   New York on Janurary 19, 1998:
+
+          DTSTART;TZID=US-Eastern:19980119T020000
+
+   Example: The following represents July 14, 1997, at 1:30 PM in New
+   York City in each of the three time formats, using the "DTSTART"
+   property.
+
+     DTSTART:19970714T133000            ;Local time
+     DTSTART:19970714T173000Z           ;UTC time
+     DTSTART;TZID=US-Eastern:19970714T133000    ;Local time and time
+                        ; zone reference
+
+   A time value MUST ONLY specify 60 seconds when specifying the
+   periodic "leap second" in the time value. For example:
+
+     COMPLETED:19970630T235960Z
+
+4.3.6   Duration
+
+   Value Name: DURATION
+
+   Purpose: This value type is used to identify properties that contain
+   a duration of time.
+
+   Formal Definition: The value type is defined by the following
+   notation:
+
+     dur-value  = (["+"] / "-") "P" (dur-date / dur-time / dur-week)
+
+     dur-date   = dur-day [dur-time]
+     dur-time   = "T" (dur-hour / dur-minute / dur-second)
+     dur-week   = 1*DIGIT "W"
+     dur-hour   = 1*DIGIT "H" [dur-minute]
+     dur-minute = 1*DIGIT "M" [dur-second]
+     dur-second = 1*DIGIT "S"
+     dur-day    = 1*DIGIT "D"
+
+   Description: If the property permits, multiple "duration" values are
+   specified by a COMMA character (US-ASCII decimal 44) separated list
+   of values. The format is expressed as the [ISO 8601] basic format for
+   the duration of time. The format can represent durations in terms of
+   weeks, days, hours, minutes, and seconds.
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 37]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   No additional content value encoding (i.e., BACKSLASH character
+   encoding) are defined for this value type.
+
+   Example: A duration of 15 days, 5 hours and 20 seconds would be:
+
+     P15DT5H0M20S
+
+   A duration of 7 weeks would be:
+
+     P7W
+
+4.3.7   Float
+
+   Value Name: FLOAT
+
+   Purpose: This value type is used to identify properties that contain
+   a real number value.
+
+   Formal Definition: The value type is defined by the following
+   notation:
+
+     float      = (["+"] / "-") 1*DIGIT ["." 1*DIGIT]
+
+   Description: If the property permits, multiple "float" values are
+   specified by a COMMA character (US-ASCII decimal 44) separated list
+   of values.
+
+   No additional content value encoding (i.e., BACKSLASH character
+   encoding) is defined for this value type.
+
+   Example:
+
+     1000000.0000001
+     1.333
+     -3.14
+
+4.3.8 Integer
+
+     Value Name:INTEGER
+
+     Purpose: This value type is used to identify properties that contain
+     a signed integer value.
+
+     Formal Definition: The value type is defined by the following
+     notation:
+
+     integer    = (["+"] / "-") 1*DIGIT
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 38]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     Description: If the property permits, multiple "integer" values are
+     specified by a COMMA character (US-ASCII decimal 44) separated list
+     of values. The valid range for "integer" is -2147483648 to
+     2147483647. If the sign is not specified, then the value is assumed
+     to be positive.
+
+     No additional content value encoding (i.e., BACKSLASH character
+     encoding) is defined for this value type.
+
+     Example:
+
+     1234567890
+     -1234567890
+     +1234567890
+     432109876
+
+4.3.9 Period of Time
+
+   Value Name: PERIOD
+
+   Purpose: This value type is used to identify values that contain a
+   precise period of time.
+
+   Formal Definition: The data type is defined by the following
+   notation:
+
+     period     = period-explicit / period-start
+
+     period-explicit = date-time "/" date-time
+     ; [ISO 8601] complete representation basic format for a period of
+     ; time consisting of a start and end. The start MUST be before the
+     ; end.
+
+     period-start = date-time "/" dur-value
+     ; [ISO 8601] complete representation basic format for a period of
+     ; time consisting of a start and positive duration of time.
+
+   Description: If the property permits, multiple "period" values are
+   specified by a COMMA character (US-ASCII decimal 44) separated list
+   of values. There are two forms of a period of time. First, a period
+   of time is identified by its start and its end. This format is
+   expressed as the [ISO 8601] complete representation, basic format for
+   "DATE-TIME" start of the period, followed by a SOLIDUS character
+   (US-ASCII decimal 47), followed by the "DATE-TIME" of the end of the
+   period. The start of the period MUST be before the end of the period.
+   Second, a period of time can also be defined by a start and a
+   positive duration of time. The format is expressed as the [ISO 8601]
+   complete representation, basic format for the "DATE-TIME" start of
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 39]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   the period, followed by a SOLIDUS character (US-ASCII decimal 47),
+   followed by the [ISO 8601] basic format for "DURATION" of the period.
+
+   Example: The period starting at 18:00:00 UTC, on January 1, 1997 and
+   ending at 07:00:00 UTC on January 2, 1997 would be:
+
+     19970101T180000Z/19970102T070000Z
+
+   The period start at 18:00:00 on January 1, 1997 and lasting 5 hours
+   and 30 minutes would be:
+
+     19970101T180000Z/PT5H30M
+
+   No additional content value encoding (i.e., BACKSLASH character
+   encoding) is defined for this value type.
+
+4.3.10 Recurrence Rule
+
+   Value Name: RECUR
+
+   Purpose: This value type is used to identify properties that contain
+   a recurrence rule specification.
+
+   Formal Definition: The value type is defined by the following
+   notation:
+
+     recur      = "FREQ"=freq *(
+
+                ; either UNTIL or COUNT may appear in a 'recur',
+                ; but UNTIL and COUNT MUST NOT occur in the same 'recur'
+
+                ( ";" "UNTIL" "=" enddate ) /
+                ( ";" "COUNT" "=" 1*DIGIT ) /
+
+                ; the rest of these keywords are optional,
+                ; but MUST NOT occur more than once
+
+                ( ";" "INTERVAL" "=" 1*DIGIT )          /
+                ( ";" "BYSECOND" "=" byseclist )        /
+                ( ";" "BYMINUTE" "=" byminlist )        /
+                ( ";" "BYHOUR" "=" byhrlist )           /
+                ( ";" "BYDAY" "=" bywdaylist )          /
+                ( ";" "BYMONTHDAY" "=" bymodaylist )    /
+                ( ";" "BYYEARDAY" "=" byyrdaylist )     /
+                ( ";" "BYWEEKNO" "=" bywknolist )       /
+                ( ";" "BYMONTH" "=" bymolist )          /
+                ( ";" "BYSETPOS" "=" bysplist )         /
+                ( ";" "WKST" "=" weekday )              /
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 40]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+                ( ";" x-name "=" text )
+                )
+
+     freq       = "SECONDLY" / "MINUTELY" / "HOURLY" / "DAILY"
+                / "WEEKLY" / "MONTHLY" / "YEARLY"
+
+     enddate    = date
+     enddate    =/ date-time            ;An UTC value
+
+     byseclist  = seconds / ( seconds *("," seconds) )
+
+     seconds    = 1DIGIT / 2DIGIT       ;0 to 59
+
+     byminlist  = minutes / ( minutes *("," minutes) )
+
+     minutes    = 1DIGIT / 2DIGIT       ;0 to 59
+
+     byhrlist   = hour / ( hour *("," hour) )
+
+     hour       = 1DIGIT / 2DIGIT       ;0 to 23
+
+     bywdaylist = weekdaynum / ( weekdaynum *("," weekdaynum) )
+
+     weekdaynum = [([plus] ordwk / minus ordwk)] weekday
+
+     plus       = "+"
+
+     minus      = "-"
+
+     ordwk      = 1DIGIT / 2DIGIT       ;1 to 53
+
+     weekday    = "SU" / "MO" / "TU" / "WE" / "TH" / "FR" / "SA"
+     ;Corresponding to SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY,
+     ;FRIDAY, SATURDAY and SUNDAY days of the week.
+
+     bymodaylist = monthdaynum / ( monthdaynum *("," monthdaynum) )
+
+     monthdaynum = ([plus] ordmoday) / (minus ordmoday)
+
+     ordmoday   = 1DIGIT / 2DIGIT       ;1 to 31
+
+     byyrdaylist = yeardaynum / ( yeardaynum *("," yeardaynum) )
+
+     yeardaynum = ([plus] ordyrday) / (minus ordyrday)
+
+     ordyrday   = 1DIGIT / 2DIGIT / 3DIGIT      ;1 to 366
+
+     bywknolist = weeknum / ( weeknum *("," weeknum) )
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 41]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     weeknum    = ([plus] ordwk) / (minus ordwk)
+
+     bymolist   = monthnum / ( monthnum *("," monthnum) )
+
+     monthnum   = 1DIGIT / 2DIGIT       ;1 to 12
+
+     bysplist   = setposday / ( setposday *("," setposday) )
+
+     setposday  = yeardaynum
+
+   Description: If the property permits, multiple "recur" values are
+   specified by a COMMA character (US-ASCII decimal 44) separated list
+   of values. The value type is a structured value consisting of a list
+   of one or more recurrence grammar parts. Each rule part is defined by
+   a NAME=VALUE pair. The rule parts are separated from each other by
+   the SEMICOLON character (US-ASCII decimal 59). The rule parts are not
+   ordered in any particular sequence. Individual rule parts MUST only
+   be specified once.
+
+   The FREQ rule part identifies the type of recurrence rule. This rule
+   part MUST be specified in the recurrence rule. Valid values include
+   SECONDLY, to specify repeating events based on an interval of a
+   second or more; MINUTELY, to specify repeating events based on an
+   interval of a minute or more; HOURLY, to specify repeating events
+   based on an interval of an hour or more; DAILY, to specify repeating
+   events based on an interval of a day or more; WEEKLY, to specify
+   repeating events based on an interval of a week or more; MONTHLY, to
+   specify repeating events based on an interval of a month or more; and
+   YEARLY, to specify repeating events based on an interval of a year or
+   more.
+
+   The INTERVAL rule part contains a positive integer representing how
+   often the recurrence rule repeats. The default value is "1", meaning
+   every second for a SECONDLY rule, or every minute for a MINUTELY
+   rule, every hour for an HOURLY rule, every day for a DAILY rule,
+   every week for a WEEKLY rule, every month for a MONTHLY rule and
+   every year for a YEARLY rule.
+
+   The UNTIL rule part defines a date-time value which bounds the
+   recurrence rule in an inclusive manner. If the value specified by
+   UNTIL is synchronized with the specified recurrence, this date or
+   date-time becomes the last instance of the recurrence. If specified
+   as a date-time value, then it MUST be specified in an UTC time
+   format. If not present, and the COUNT rule part is also not present,
+   the RRULE is considered to repeat forever.
+
+   The COUNT rule part defines the number of occurrences at which to
+   range-bound the recurrence. The "DTSTART" property value, if
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 42]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   specified, counts as the first occurrence.
+
+   The BYSECOND rule part specifies a COMMA character (US-ASCII decimal
+   44) separated list of seconds within a minute. Valid values are 0 to
+   59. The BYMINUTE rule part specifies a COMMA character (US-ASCII
+   decimal 44) separated list of minutes within an hour. Valid values
+   are 0 to 59. The BYHOUR rule part specifies a COMMA character (US-
+   ASCII decimal 44) separated list of hours of the day. Valid values
+   are 0 to 23.
+
+   The BYDAY rule part specifies a COMMA character (US-ASCII decimal 44)
+   separated list of days of the week; MO indicates Monday; TU indicates
+   Tuesday; WE indicates Wednesday; TH indicates Thursday; FR indicates
+   Friday; SA indicates Saturday; SU indicates Sunday.
+
+   Each BYDAY value can also be preceded by a positive (+n) or negative
+   (-n) integer. If present, this indicates the nth occurrence of the
+   specific day within the MONTHLY or YEARLY RRULE. For example, within
+   a MONTHLY rule, +1MO (or simply 1MO) represents the first Monday
+   within the month, whereas -1MO represents the last Monday of the
+   month. If an integer modifier is not present, it means all days of
+   this type within the specified frequency. For example, within a
+   MONTHLY rule, MO represents all Mondays within the month.
+
+   The BYMONTHDAY rule part specifies a COMMA character (ASCII decimal
+   44) separated list of days of the month. Valid values are 1 to 31 or
+   -31 to -1. For example, -10 represents the tenth to the last day of
+   the month.
+
+   The BYYEARDAY rule part specifies a COMMA character (US-ASCII decimal
+   44) separated list of days of the year. Valid values are 1 to 366 or
+   -366 to -1. For example, -1 represents the last day of the year
+   (December 31st) and -306 represents the 306th to the last day of the
+   year (March 1st).
+
+   The BYWEEKNO rule part specifies a COMMA character (US-ASCII decimal
+   44) separated list of ordinals specifying weeks of the year. Valid
+   values are 1 to 53 or -53 to -1. This corresponds to weeks according
+   to week numbering as defined in [ISO 8601]. A week is defined as a
+   seven day period, starting on the day of the week defined to be the
+   week start (see WKST). Week number one of the calendar year is the
+   first week which contains at least four (4) days in that calendar
+   year. This rule part is only valid for YEARLY rules. For example, 3
+   represents the third week of the year.
+
+        Note: Assuming a Monday week start, week 53 can only occur when
+        Thursday is January 1 or if it is a leap year and Wednesday is
+        January 1.
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 43]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   The BYMONTH rule part specifies a COMMA character (US-ASCII decimal
+   44) separated list of months of the year. Valid values are 1 to 12.
+
+   The WKST rule part specifies the day on which the workweek starts.
+   Valid values are MO, TU, WE, TH, FR, SA and SU. This is significant
+   when a WEEKLY RRULE has an interval greater than 1, and a BYDAY rule
+   part is specified. This is also significant when in a YEARLY RRULE
+   when a BYWEEKNO rule part is specified. The default value is MO.
+
+   The BYSETPOS rule part specifies a COMMA character (US-ASCII decimal
+   44) separated list of values which corresponds to the nth occurrence
+   within the set of events specified by the rule. Valid values are 1 to
+   366 or -366 to -1. It MUST only be used in conjunction with another
+   BYxxx rule part. For example "the last work day of the month" could
+   be represented as:
+
+     RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1
+
+   Each BYSETPOS value can include a positive (+n) or negative (-n)
+   integer. If present, this indicates the nth occurrence of the
+   specific occurrence within the set of events specified by the rule.
+
+   If BYxxx rule part values are found which are beyond the available
+   scope (ie, BYMONTHDAY=30 in February), they are simply ignored.
+
+   Information, not contained in the rule, necessary to determine the
+   various recurrence instance start time and dates are derived from the
+   Start Time (DTSTART) entry attribute. For example,
+   "FREQ=YEARLY;BYMONTH=1" doesn't specify a specific day within the
+   month or a time. This information would be the same as what is
+   specified for DTSTART.
+
+   BYxxx rule parts modify the recurrence in some manner. BYxxx rule
+   parts for a period of time which is the same or greater than the
+   frequency generally reduce or limit the number of occurrences of the
+   recurrence generated. For example, "FREQ=DAILY;BYMONTH=1" reduces the
+   number of recurrence instances from all days (if BYMONTH tag is not
+   present) to all days in January. BYxxx rule parts for a period of
+   time less than the frequency generally increase or expand the number
+   of occurrences of the recurrence. For example,
+   "FREQ=YEARLY;BYMONTH=1,2" increases the number of days within the
+   yearly recurrence set from 1 (if BYMONTH tag is not present) to 2.
+
+   If multiple BYxxx rule parts are specified, then after evaluating the
+   specified FREQ and INTERVAL rule parts, the BYxxx rule parts are
+   applied to the current set of evaluated occurrences in the following
+   order: BYMONTH, BYWEEKNO, BYYEARDAY, BYMONTHDAY, BYDAY, BYHOUR,
+   BYMINUTE, BYSECOND and BYSETPOS; then COUNT and UNTIL are evaluated.
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 44]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Here is an example of evaluating multiple BYxxx rule parts.
+
+     DTSTART;TZID=US-Eastern:19970105T083000
+     RRULE:FREQ=YEARLY;INTERVAL=2;BYMONTH=1;BYDAY=SU;BYHOUR=8,9;
+      BYMINUTE=30
+
+   First, the "INTERVAL=2" would be applied to "FREQ=YEARLY" to arrive
+   at "every other year". Then, "BYMONTH=1" would be applied to arrive
+   at "every January, every other year". Then, "BYDAY=SU" would be
+   applied to arrive at "every Sunday in January, every other year".
+   Then, "BYHOUR=8,9" would be applied to arrive at "every Sunday in
+   January at 8 AM and 9 AM, every other year". Then, "BYMINUTE=30"
+   would be applied to arrive at "every Sunday in January at 8:30 AM and
+   9:30 AM, every other year". Then, lacking information from RRULE, the
+   second is derived from DTSTART, to end up in "every Sunday in January
+   at 8:30:00 AM and 9:30:00 AM, every other year". Similarly, if the
+   BYMINUTE, BYHOUR, BYDAY, BYMONTHDAY or BYMONTH rule part were
+   missing, the appropriate minute, hour, day or month would have been
+   retrieved from the "DTSTART" property.
+
+   No additional content value encoding (i.e., BACKSLASH character
+   encoding) is defined for this value type.
+
+   Example: The following is a rule which specifies 10 meetings which
+   occur every other day:
+
+     FREQ=DAILY;COUNT=10;INTERVAL=2
+
+   There are other examples specified in the "RRULE" specification.
+
+4.3.11 Text
+
+   Value Name: TEXT
+
+   Purpose This value type is used to identify values that contain human
+   readable text.
+
+   Formal Definition: The character sets supported by this revision of
+   iCalendar are UTF-8 and US ASCII thereof. The applicability to other
+   character sets is for future work. The value type is defined by the
+   following notation.
+
+     text       = *(TSAFE-CHAR / ":" / DQUOTE / ESCAPED-CHAR)
+     ; Folded according to description above
+
+     ESCAPED-CHAR = "\\" / "\;" / "\," / "\N" / "\n")
+        ; \\ encodes \, \N or \n encodes newline
+        ; \; encodes ;, \, encodes ,
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 45]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     TSAFE-CHAR = %x20-21 / %x23-2B / %x2D-39 / %x3C-5B
+                  %x5D-7E / NON-US-ASCII
+        ; Any character except CTLs not needed by the current
+        ; character set, DQUOTE, ";", ":", "\", ","
+
+     Note: Certain other character sets may require modification of the
+     above definitions, but this is beyond the scope of this document.
+
+   Description: If the property permits, multiple "text" values are
+   specified by a COMMA character (US-ASCII decimal 44) separated list
+   of values.
+
+   The language in which the text is represented can be controlled by
+   the "LANGUAGE" property parameter.
+
+   An intentional formatted text line break MUST only be included in a
+   "TEXT" property value by representing the line break with the
+   character sequence of BACKSLASH (US-ASCII decimal 92), followed by a
+   LATIN SMALL LETTER N (US-ASCII decimal 110) or a LATIN CAPITAL LETTER
+   N (US-ASCII decimal 78), that is "\n" or "\N".
+
+   The "TEXT" property values may also contain special characters that
+   are used to signify delimiters, such as a COMMA character for lists
+   of values or a SEMICOLON character for structured values. In order to
+   support the inclusion of these special characters in "TEXT" property
+   values, they MUST be escaped with a BACKSLASH character. A BACKSLASH
+   character (US-ASCII decimal 92) in a "TEXT" property value MUST be
+   escaped with another BACKSLASH character. A COMMA character in a
+   "TEXT" property value MUST be escaped with a BACKSLASH character
+   (US-ASCII decimal 92). A SEMICOLON character in a "TEXT" property
+   value MUST be escaped with a BACKSLASH character (US-ASCII decimal
+   92).  However, a COLON character in a "TEXT" property value SHALL NOT
+   be escaped with a BACKSLASH character.Example: A multiple line value
+   of:
+
+     Project XYZ Final Review
+     Conference Room - 3B
+     Come Prepared.
+
+   would be represented as:
+
+     Project XYZ Final Review\nConference Room - 3B\nCome Prepared.
+
+
+
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 46]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+4.3.12 Time
+
+   Value Name: TIME
+
+   Purpose: This value type is used to identify values that contain a
+   time of day.
+
+   Formal Definition: The data type is defined by the following
+   notation:
+
+     time               = time-hour time-minute time-second [time-utc]
+
+     time-hour          = 2DIGIT        ;00-23
+     time-minute        = 2DIGIT        ;00-59
+     time-second        = 2DIGIT        ;00-60
+     ;The "60" value is used to account for "leap" seconds.
+
+     time-utc   = "Z"
+
+   Description: If the property permits, multiple "time" values are
+   specified by a COMMA character (US-ASCII decimal 44) separated list
+   of values. No additional content value encoding (i.e., BACKSLASH
+   character encoding) is defined for this value type.
+
+   The "TIME" data type is used to identify values that contain a time
+   of day. The format is based on the [ISO 8601] complete
+   representation, basic format for a time of day. The text format
+   consists of a two-digit 24-hour of the day (i.e., values 0-23), two-
+   digit minute in the hour (i.e., values 0-59), and two-digit seconds
+   in the minute (i.e., values 0-60). The seconds value of 60 MUST only
+   to be used to account for "leap" seconds. Fractions of a second are
+   not supported by this format.
+
+   In parallel to the "DATE-TIME" definition above, the "TIME" data type
+   expresses time values in three forms:
+
+   The form of time with UTC offset MUST NOT be used. For example, the
+   following is NOT VALID for a time value:
+
+     230000-0800        ;Invalid time format
+
+   FORM #1 LOCAL TIME
+
+   The local time form is simply a time value that does not contain the
+   UTC designator nor does it reference a time zone. For example, 11:00
+   PM:
+
+     230000
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 47]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Time values of this type are said to be "floating" and are not bound
+   to any time zone in particular. They are used to represent the same
+   hour, minute, and second value regardless of which time zone is
+   currently being observed. For example, an event can be defined that
+   indicates that an individual will be busy from 11:00 AM to 1:00 PM
+   every day, no matter which time zone the person is in. In these
+   cases, a local time can be specified. The recipient of an iCalendar
+   object with a property value consisting of a local time, without any
+   relative time zone information, SHOULD interpret the value as being
+   fixed to whatever time zone the ATTENDEE is in at any given moment.
+   This means that two ATTENDEEs may participate in the same event at
+   different UTC times; floating time SHOULD only be used where that is
+   reasonable behavior.
+
+   In most cases, a fixed time is desired. To properly communicate a
+   fixed time in a property value, either UTC time or local time with
+   time zone reference MUST be specified.
+
+   The use of local time in a TIME value without the TZID property
+   parameter is to be interpreted as a local time value, regardless of
+   the existence of "VTIMEZONE" calendar components in the iCalendar
+   object.
+
+   FORM #2: UTC TIME
+
+   UTC time, or absolute time, is identified by a LATIN CAPITAL LETTER Z
+   suffix character (US-ASCII decimal 90), the UTC designator, appended
+   to the time value. For example, the following represents 07:00 AM
+   UTC:
+
+     070000Z
+
+   The TZID property parameter MUST NOT be applied to TIME properties
+   whose time values are specified in UTC.
+
+   FORM #3: LOCAL TIME AND TIME ZONE REFERENCE
+
+   The local time with reference to time zone information form is
+   identified by the use the TZID property parameter to reference the
+   appropriate time zone definition. TZID is discussed in detail in the
+   section on Time Zone.
+
+   Example: The following represents 8:30 AM in New York in Winter, five
+   hours behind UTC, in each of the three formats using the "X-
+   TIMEOFDAY" non-standard property:
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 48]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     X-TIMEOFDAY:083000
+
+     X-TIMEOFDAY:133000Z
+
+     X-TIMEOFDAY;TZID=US-Eastern:083000
+
+4.3.13 URI
+
+   Value Name: URI
+
+   Purpose: This value type is used to identify values that contain a
+   uniform resource identifier (URI) type of reference to the property
+   value.
+
+   Formal Definition: The data type is defined by the following
+   notation:
+
+     uri        = <As defined by any IETF RFC>
+
+   Description: This data type might be used to reference binary
+   information, for values that are large, or otherwise undesirable to
+   include directly in the iCalendar object.
+
+   The URI value formats in RFC 1738, RFC 2111 and any other IETF
+   registered value format can be specified.
+
+   Any IANA registered URI format can be used. These include, but are
+   not limited to, those defined in RFC 1738 and RFC 2111.
+
+   When a property parameter value is a URI value type, the URI MUST be
+   specified as a quoted-string value.
+
+   No additional content value encoding (i.e., BACKSLASH character
+   encoding) is defined for this value type.
+
+   Example: The following is a URI for a network file:
+
+     http://host1.com/my-report.txt
+
+4.3.14 UTC Offset
+
+   Value Name: UTC-OFFSET
+
+   Purpose: This value type is used to identify properties that contain
+   an offset from UTC to local time.
+
+   Formal Definition: The data type is defined by the following
+   notation:
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 49]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     utc-offset = time-numzone  ;As defined above in time data type
+
+     time-numzone       = ("+" / "-") time-hour time-minute [time-
+     second]
+
+   Description: The PLUS SIGN character MUST be specified for positive
+   UTC offsets (i.e., ahead of UTC). The value of "-0000" and "-000000"
+   are not allowed. The time-second, if present, may not be 60; if
+   absent, it defaults to zero.
+
+   No additional content value encoding (i.e., BACKSLASH character
+   encoding) is defined for this value type.
+
+   Example: The following UTC offsets are given for standard time for
+   New York (five hours behind UTC) and Geneva (one hour ahead of UTC):
+
+     -0500
+
+     +0100
+
+4.4 iCalendar Object
+
+   The Calendaring and Scheduling Core Object is a collection of
+   calendaring and scheduling information. Typically, this information
+   will consist of a single iCalendar object. However, multiple
+   iCalendar objects can be sequentially grouped together. The first
+   line and last line of the iCalendar object MUST contain a pair of
+   iCalendar object delimiter strings. The syntax for an iCalendar
+   object is as follows:
+
+     icalobject = 1*("BEGIN" ":" "VCALENDAR" CRLF
+                  icalbody
+                  "END" ":" "VCALENDAR" CRLF)
+
+   The following is a simple example of an iCalendar object:
+
+     BEGIN:VCALENDAR
+     VERSION:2.0
+     PRODID:-//hacksw/handcal//NONSGML v1.0//EN
+     BEGIN:VEVENT
+     DTSTART:19970714T170000Z
+     DTEND:19970715T035959Z
+     SUMMARY:Bastille Day Party
+     END:VEVENT
+     END:VCALENDAR
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 50]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+4.5 Property
+
+   A property is the definition of an individual attribute describing a
+   calendar or a calendar component. A property takes the form defined
+   by the "contentline" notation defined in section 4.1.1.
+
+   The following is an example of a property:
+
+     DTSTART:19960415T133000Z
+
+   This memo imposes no ordering of properties within an iCalendar
+   object.
+
+   Property names, parameter names and enumerated parameter values are
+   case insensitive. For example, the property name "DUE" is the same as
+   "due" and "Due", DTSTART;TZID=US-Eastern:19980714T120000 is the same
+   as DtStart;TzID=US-Eastern:19980714T120000.
+
+4.6 Calendar Components
+
+   The body of the iCalendar object consists of a sequence of calendar
+   properties and one or more calendar components. The calendar
+   properties are attributes that apply to the calendar as a whole. The
+   calendar components are collections of properties that express a
+   particular calendar semantic. For example, the calendar component can
+   specify an event, a to-do, a journal entry, time zone information, or
+   free/busy time information, or an alarm.
+
+   The body of the iCalendar object is defined by the following
+   notation:
+
+     icalbody   = calprops component
+
+     calprops   = 2*(
+
+                ; 'prodid' and 'version' are both REQUIRED,
+                ; but MUST NOT occur more than once
+
+                prodid /version /
+
+                ; 'calscale' and 'method' are optional,
+                ; but MUST NOT occur more than once
+
+                calscale        /
+                method          /
+
+                x-prop
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 51]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+                )
+
+     component  = 1*(eventc / todoc / journalc / freebusyc /
+                / timezonec / iana-comp / x-comp)
+
+     iana-comp  = "BEGIN" ":" iana-token CRLF
+
+                  1*contentline
+
+                  "END" ":" iana-token CRLF
+
+     x-comp     = "BEGIN" ":" x-name CRLF
+
+                  1*contentline
+
+                  "END" ":" x-name CRLF
+
+   An iCalendar object MUST include the "PRODID" and "VERSION" calendar
+   properties. In addition, it MUST include at least one calendar
+   component. Special forms of iCalendar objects are possible to publish
+   just busy time (i.e., only a "VFREEBUSY" calendar component) or time
+   zone (i.e., only a "VTIMEZONE" calendar component) information. In
+   addition, a complex iCalendar object is possible that is used to
+   capture a complete snapshot of the contents of a calendar (e.g.,
+   composite of many different calendar components). More commonly, an
+   iCalendar object will consist of just a single "VEVENT", "VTODO" or
+   "VJOURNAL" calendar component.
+
+4.6.1 Event Component
+
+   Component Name: "VEVENT"
+
+   Purpose: Provide a grouping of component properties that describe an
+   event.
+
+   Format Definition: A "VEVENT" calendar component is defined by the
+   following notation:
+
+     eventc     = "BEGIN" ":" "VEVENT" CRLF
+                  eventprop *alarmc
+                  "END" ":" "VEVENT" CRLF
+
+     eventprop  = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                class / created / description / dtstart / geo /
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 52]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+                last-mod / location / organizer / priority /
+                dtstamp / seq / status / summary / transp /
+                uid / url / recurid /
+
+                ; either 'dtend' or 'duration' may appear in
+                ; a 'eventprop', but 'dtend' and 'duration'
+                ; MUST NOT occur in the same 'eventprop'
+
+                dtend / duration /
+
+                ; the following are optional,
+                ; and MAY occur more than once
+
+                attach / attendee / categories / comment /
+                contact / exdate / exrule / rstatus / related /
+                resources / rdate / rrule / x-prop
+
+                )
+
+   Description: A "VEVENT" calendar component is a grouping of component
+   properties, and possibly including "VALARM" calendar components, that
+   represents a scheduled amount of time on a calendar. For example, it
+   can be an activity; such as a one-hour long, department meeting from
+   8:00 AM to 9:00 AM, tomorrow. Generally, an event will take up time
+   on an individual calendar. Hence, the event will appear as an opaque
+   interval in a search for busy time. Alternately, the event can have
+   its Time Transparency set to "TRANSPARENT" in order to prevent
+   blocking of the event in searches for busy time.
+
+   The "VEVENT" is also the calendar component used to specify an
+   anniversary or daily reminder within a calendar. These events have a
+   DATE value type for the "DTSTART" property instead of the default
+   data type of DATE-TIME. If such a "VEVENT" has a "DTEND" property, it
+   MUST be specified as a DATE value also. The anniversary type of
+   "VEVENT" can span more than one date (i.e, "DTEND" property value is
+   set to a calendar date after the "DTSTART" property value).
+
+   The "DTSTART" property for a "VEVENT" specifies the inclusive start
+   of the event. For recurring events, it also specifies the very first
+   instance in the recurrence set. The "DTEND" property for a "VEVENT"
+   calendar component specifies the non-inclusive end of the event. For
+   cases where a "VEVENT" calendar component specifies a "DTSTART"
+   property with a DATE data type but no "DTEND" property, the events
+   non-inclusive end is the end of the calendar date specified by the
+   "DTSTART" property. For cases where a "VEVENT" calendar component
+   specifies a "DTSTART" property with a DATE-TIME data type but no
+   "DTEND" property, the event ends on the same calendar date and time
+   of day specified by the "DTSTART" property.
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 53]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   The "VEVENT" calendar component cannot be nested within another
+   calendar component. However, "VEVENT" calendar components can be
+   related to each other or to a "VTODO" or to a "VJOURNAL" calendar
+   component with the "RELATED-TO" property.
+
+   Example: The following is an example of the "VEVENT" calendar
+   component used to represent a meeting that will also be opaque to
+   searches for busy time:
+
+     BEGIN:VEVENT
+     UID:19970901T130000Z-123401@host.com
+     DTSTAMP:19970901T1300Z
+     DTSTART:19970903T163000Z
+     DTEND:19970903T190000Z
+     SUMMARY:Annual Employee Review
+     CLASS:PRIVATE
+     CATEGORIES:BUSINESS,HUMAN RESOURCES
+     END:VEVENT
+
+   The following is an example of the "VEVENT" calendar component used
+   to represent a reminder that will not be opaque, but rather
+   transparent, to searches for busy time:
+
+     BEGIN:VEVENT
+     UID:19970901T130000Z-123402@host.com
+     DTSTAMP:19970901T1300Z
+     DTSTART:19970401T163000Z
+     DTEND:19970402T010000Z
+     SUMMARY:Laurel is in sensitivity awareness class.
+     CLASS:PUBLIC
+     CATEGORIES:BUSINESS,HUMAN RESOURCES
+     TRANSP:TRANSPARENT
+     END:VEVENT
+
+   The following is an example of the "VEVENT" calendar component used
+   to represent an anniversary that will occur annually. Since it takes
+   up no time, it will not appear as opaque in a search for busy time;
+   no matter what the value of the "TRANSP" property indicates:
+
+     BEGIN:VEVENT
+     UID:19970901T130000Z-123403@host.com
+     DTSTAMP:19970901T1300Z
+     DTSTART:19971102
+     SUMMARY:Our Blissful Anniversary
+     CLASS:CONFIDENTIAL
+     CATEGORIES:ANNIVERSARY,PERSONAL,SPECIAL OCCASION
+     RRULE:FREQ=YEARLY
+     END:VEVENT
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 54]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+4.6.2 To-do Component
+
+   Component Name: VTODO
+
+   Purpose: Provide a grouping of calendar properties that describe a
+   to-do.
+
+   Formal Definition: A "VTODO" calendar component is defined by the
+   following notation:
+
+     todoc      = "BEGIN" ":" "VTODO" CRLF
+                  todoprop *alarmc
+                  "END" ":" "VTODO" CRLF
+
+     todoprop   = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                class / completed / created / description / dtstamp /
+                dtstart / geo / last-mod / location / organizer /
+                percent / priority / recurid / seq / status /
+                summary / uid / url /
+
+                ; either 'due' or 'duration' may appear in
+                ; a 'todoprop', but 'due' and 'duration'
+                ; MUST NOT occur in the same 'todoprop'
+
+                due / duration /
+
+                ; the following are optional,
+                ; and MAY occur more than once
+                attach / attendee / categories / comment / contact /
+                exdate / exrule / rstatus / related / resources /
+                rdate / rrule / x-prop
+
+                )
+
+   Description: A "VTODO" calendar component is a grouping of component
+   properties and possibly "VALARM" calendar components that represent
+   an action-item or assignment. For example, it can be used to
+   represent an item of work assigned to an individual; such as "turn in
+   travel expense today".
+
+   The "VTODO" calendar component cannot be nested within another
+   calendar component. However, "VTODO" calendar components can be
+   related to each other or to a "VTODO" or to a "VJOURNAL" calendar
+   component with the "RELATED-TO" property.
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 55]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   A "VTODO" calendar component without the "DTSTART" and "DUE" (or
+   "DURATION") properties specifies a to-do that will be associated with
+   each successive calendar date, until it is completed.
+
+   Example: The following is an example of a "VTODO" calendar component:
+
+     BEGIN:VTODO
+     UID:19970901T130000Z-123404@host.com
+     DTSTAMP:19970901T1300Z
+     DTSTART:19970415T133000Z
+     DUE:19970416T045959Z
+     SUMMARY:1996 Income Tax Preparation
+     CLASS:CONFIDENTIAL
+     CATEGORIES:FAMILY,FINANCE
+     PRIORITY:1
+     STATUS:NEEDS-ACTION
+     END:VTODO
+
+4.6.3 Journal Component
+
+   Component Name: VJOURNAL
+
+   Purpose: Provide a grouping of component properties that describe a
+   journal entry.
+
+   Formal Definition: A "VJOURNAL" calendar component is defined by the
+   following notation:
+
+     journalc   = "BEGIN" ":" "VJOURNAL" CRLF
+                  jourprop
+                  "END" ":" "VJOURNAL" CRLF
+
+     jourprop   = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                class / created / description / dtstart / dtstamp /
+                last-mod / organizer / recurid / seq / status /
+                summary / uid / url /
+
+                ; the following are optional,
+                ; and MAY occur more than once
+
+                attach / attendee / categories / comment /
+                contact / exdate / exrule / related / rdate /
+                rrule / rstatus / x-prop
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 56]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+                )
+
+   Description: A "VJOURNAL" calendar component is a grouping of
+   component properties that represent one or more descriptive text
+   notes associated with a particular calendar date. The "DTSTART"
+   property is used to specify the calendar date that the journal entry
+   is associated with. Generally, it will have a DATE value data type,
+   but it can also be used to specify a DATE-TIME value data type.
+   Examples of a journal entry include a daily record of a legislative
+   body or a journal entry of individual telephone contacts for the day
+   or an ordered list of accomplishments for the day. The "VJOURNAL"
+   calendar component can also be used to associate a document with a
+   calendar date.
+
+   The "VJOURNAL" calendar component does not take up time on a
+   calendar. Hence, it does not play a role in free or busy time
+   searches - - it is as though it has a time transparency value of
+   TRANSPARENT. It is transparent to any such searches.
+
+   The "VJOURNAL" calendar component cannot be nested within another
+   calendar component. However, "VJOURNAL" calendar components can be
+   related to each other or to a "VEVENT" or to a "VTODO" calendar
+   component, with the "RELATED-TO" property.
+
+   Example: The following is an example of the "VJOURNAL" calendar
+   component:
+
+     BEGIN:VJOURNAL
+     UID:19970901T130000Z-123405@host.com
+     DTSTAMP:19970901T1300Z
+     DTSTART;VALUE=DATE:19970317
+     SUMMARY:Staff meeting minutes
+     DESCRIPTION:1. Staff meeting: Participants include Joe\, Lisa
+       and Bob. Aurora project plans were reviewed. There is currently
+       no budget reserves for this project. Lisa will escalate to
+       management. Next meeting on Tuesday.\n
+       2. Telephone Conference: ABC Corp. sales representative called
+       to discuss new printer. Promised to get us a demo by Friday.\n
+       3. Henry Miller (Handsoff Insurance): Car was totaled by tree.
+       Is looking into a loaner car. 654-2323 (tel).
+     END:VJOURNAL
+
+
+
+
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 57]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+4.6.4 Free/Busy Component
+
+   Component Name: VFREEBUSY
+
+   Purpose: Provide a grouping of component properties that describe
+   either a request for free/busy time, describe a response to a request
+   for free/busy time or describe a published set of busy time.
+
+   Formal Definition: A "VFREEBUSY" calendar component is defined by the
+   following notation:
+
+     freebusyc  = "BEGIN" ":" "VFREEBUSY" CRLF
+                  fbprop
+                  "END" ":" "VFREEBUSY" CRLF
+
+     fbprop     = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                contact / dtstart / dtend / duration / dtstamp /
+                organizer / uid / url /
+
+                ; the following are optional,
+                ; and MAY occur more than once
+
+                attendee / comment / freebusy / rstatus / x-prop
+
+                )
+
+   Description: A "VFREEBUSY" calendar component is a grouping of
+   component properties that represents either a request for, a reply to
+   a request for free or busy time information or a published set of
+   busy time information.
+
+   When used to request free/busy time information, the "ATTENDEE"
+   property specifies the calendar users whose free/busy time is being
+   requested; the "ORGANIZER" property specifies the calendar user who
+   is requesting the free/busy time; the "DTSTART" and "DTEND"
+   properties specify the window of time for which the free/busy time is
+   being requested; the "UID" and "DTSTAMP" properties are specified to
+   assist in proper sequencing of multiple free/busy time requests.
+
+   When used to reply to a request for free/busy time, the "ATTENDEE"
+   property specifies the calendar user responding to the free/busy time
+   request; the "ORGANIZER" property specifies the calendar user that
+   originally requested the free/busy time; the "FREEBUSY" property
+   specifies the free/busy time information (if it exists); and the
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 58]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   "UID" and "DTSTAMP" properties are specified to assist in proper
+   sequencing of multiple free/busy time replies.
+
+   When used to publish busy time, the "ORGANIZER" property specifies
+   the calendar user associated with the published busy time; the
+   "DTSTART" and "DTEND" properties specify an inclusive time window
+   that surrounds the busy time information; the "FREEBUSY" property
+   specifies the published busy time information; and the "DTSTAMP"
+   property specifies the date/time that iCalendar object was created.
+
+   The "VFREEBUSY" calendar component cannot be nested within another
+   calendar component. Multiple "VFREEBUSY" calendar components can be
+   specified within an iCalendar object. This permits the grouping of
+   Free/Busy information into logical collections, such as monthly
+   groups of busy time information.
+
+   The "VFREEBUSY" calendar component is intended for use in iCalendar
+   object methods involving requests for free time, requests for busy
+   time, requests for both free and busy, and the associated replies.
+
+   Free/Busy information is represented with the "FREEBUSY" property.
+   This property provides a terse representation of time periods. One or
+   more "FREEBUSY" properties can be specified in the "VFREEBUSY"
+   calendar component.
+
+   When present in a "VFREEBUSY" calendar component, the "DTSTART" and
+   "DTEND" properties SHOULD be specified prior to any "FREEBUSY"
+   properties. In a free time request, these properties can be used in
+   combination with the "DURATION" property to represent a request for a
+   duration of free time within a specified window of time.
+
+   The recurrence properties ("RRULE", "EXRULE", "RDATE", "EXDATE") are
+   not permitted within a "VFREEBUSY" calendar component. Any recurring
+   events are resolved into their individual busy time periods using the
+   "FREEBUSY" property.
+
+   Example: The following is an example of a "VFREEBUSY" calendar
+   component used to request free or busy time information:
+
+     BEGIN:VFREEBUSY
+     ORGANIZER:MAILTO:jane_doe@host1.com
+     ATTENDEE:MAILTO:john_public@host2.com
+     DTSTART:19971015T050000Z
+     DTEND:19971016T050000Z
+     DTSTAMP:19970901T083000Z
+     END:VFREEBUSY
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 59]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   The following is an example of a "VFREEBUSY" calendar component used
+   to reply to the request with busy time information:
+
+     BEGIN:VFREEBUSY
+     ORGANIZER:MAILTO:jane_doe@host1.com
+     ATTENDEE:MAILTO:john_public@host2.com
+     DTSTAMP:19970901T100000Z
+     FREEBUSY;VALUE=PERIOD:19971015T050000Z/PT8H30M,
+      19971015T160000Z/PT5H30M,19971015T223000Z/PT6H30M
+     URL:http://host2.com/pub/busy/jpublic-01.ifb
+     COMMENT:This iCalendar file contains busy time information for
+       the next three months.
+     END:VFREEBUSY
+
+   The following is an example of a "VFREEBUSY" calendar component used
+   to publish busy time information.
+
+     BEGIN:VFREEBUSY
+     ORGANIZER:jsmith@host.com
+     DTSTART:19980313T141711Z
+     DTEND:19980410T141711Z
+     FREEBUSY:19980314T233000Z/19980315T003000Z
+     FREEBUSY:19980316T153000Z/19980316T163000Z
+     FREEBUSY:19980318T030000Z/19980318T040000Z
+     URL:http://www.host.com/calendar/busytime/jsmith.ifb
+     END:VFREEBUSY
+
+4.6.5 Time Zone Component
+
+   Component Name: VTIMEZONE
+
+   Purpose: Provide a grouping of component properties that defines a
+   time zone.
+
+   Formal Definition: A "VTIMEZONE" calendar component is defined by the
+   following notation:
+
+     timezonec  = "BEGIN" ":" "VTIMEZONE" CRLF
+
+                  2*(
+
+                  ; 'tzid' is required, but MUST NOT occur more
+                  ; than once
+
+                tzid /
+
+                  ; 'last-mod' and 'tzurl' are optional,
+                but MUST NOT occur more than once
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 60]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+                last-mod / tzurl /
+
+                  ; one of 'standardc' or 'daylightc' MUST occur
+                ..; and each MAY occur more than once.
+
+                standardc / daylightc /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                  x-prop
+
+                  )
+
+                  "END" ":" "VTIMEZONE" CRLF
+
+     standardc  = "BEGIN" ":" "STANDARD" CRLF
+
+                  tzprop
+
+                  "END" ":" "STANDARD" CRLF
+
+     daylightc  = "BEGIN" ":" "DAYLIGHT" CRLF
+
+                  tzprop
+
+                  "END" ":" "DAYLIGHT" CRLF
+
+     tzprop     = 3*(
+
+                ; the following are each REQUIRED,
+                ; but MUST NOT occur more than once
+
+                dtstart / tzoffsetto / tzoffsetfrom /
+
+                ; the following are optional,
+                ; and MAY occur more than once
+
+                comment / rdate / rrule / tzname / x-prop
+
+                )
+
+   Description: A time zone is unambiguously defined by the set of time
+   measurement rules determined by the governing body for a given
+   geographic area. These rules describe at a minimum the base  offset
+   from UTC for the time zone, often referred to as the Standard Time
+   offset. Many locations adjust their Standard Time forward or backward
+   by one hour, in order to accommodate seasonal changes in number of
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 61]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   daylight hours, often referred to as Daylight  Saving Time. Some
+   locations adjust their time by a fraction of an hour. Standard Time
+   is also known as Winter Time. Daylight Saving Time is also known as
+   Advanced Time, Summer Time, or Legal Time in certain countries. The
+   following table shows the changes in time zone rules in effect for
+   New York City starting from 1967. Each line represents a description
+   or rule for a particular observance.
+
+     Effective Observance Rule
+
+     Date       (Date/Time)             Offset  Abbreviation
+
+     1967-*     last Sun in Oct, 02:00  -0500   EST
+
+     1967-1973  last Sun in Apr, 02:00  -0400   EDT
+
+     1974-1974  Jan 6,  02:00           -0400   EDT
+
+     1975-1975  Feb 23, 02:00           -0400   EDT
+
+     1976-1986  last Sun in Apr, 02:00  -0400   EDT
+
+     1987-*     first Sun in Apr, 02:00 -0400   EDT
+
+        Note: The specification of a global time zone registry is not
+        addressed by this document and is left for future study.
+        However, implementers may find the Olson time zone database [TZ]
+        a useful reference. It is an informal, public-domain collection
+        of time zone information, which is currently being maintained by
+        volunteer Internet participants, and is used in several
+        operating systems. This database contains current and historical
+        time zone information for a wide variety of locations around the
+        globe; it provides a time zone identifier for every unique time
+        zone rule set in actual use since 1970, with historical data
+        going back to the introduction of standard time.
+
+   Interoperability between two calendaring and scheduling applications,
+   especially for recurring events, to-dos or journal entries, is
+   dependent on the ability to capture and convey date and time
+   information in an unambiguous format. The specification of current
+   time zone information is integral to this behavior.
+
+   If present, the "VTIMEZONE" calendar component defines the set of
+   Standard Time and Daylight Saving Time observances (or rules) for a
+   particular time zone for a given interval of time. The "VTIMEZONE"
+   calendar component cannot be nested within other calendar components.
+   Multiple "VTIMEZONE" calendar components can exist in an iCalendar
+   object. In this situation, each "VTIMEZONE" MUST represent a unique
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 62]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   time zone definition. This is necessary for some classes of events,
+   such as airline flights, that start in one time zone and end in
+   another.
+
+   The "VTIMEZONE" calendar component MUST be present if the iCalendar
+   object contains an RRULE that generates dates on both sides of a time
+   zone shift (e.g. both in Standard Time and Daylight Saving Time)
+   unless the iCalendar object intends to convey a floating time (See
+   the section "4.1.10.11 Time" for proper interpretation of floating
+   time). It can be present if the iCalendar object does not contain
+   such a RRULE. In addition, if a RRULE is present, there MUST be valid
+   time zone information for all recurrence instances.
+
+   The "VTIMEZONE" calendar component MUST include the "TZID" property
+   and at least one definition of a standard or daylight component. The
+   standard or daylight component MUST include the "DTSTART",
+   "TZOFFSETFROM" and "TZOFFSETTO" properties.
+
+   An individual "VTIMEZONE" calendar component MUST be specified for
+   each unique "TZID" parameter value specified in the iCalendar object.
+
+   Each "VTIMEZONE" calendar component consists of a collection of one
+   or more sub-components that describe the rule for a particular
+   observance (either a Standard Time or a Daylight Saving Time
+   observance). The "STANDARD" sub-component consists of a collection of
+   properties that describe Standard Time. The "DAYLIGHT" sub-component
+   consists of a collection of properties that describe Daylight Saving
+   Time. In general this collection of properties consists of:
+
+        - the first onset date-time for the observance
+
+        - the last onset date-time for the observance, if a last onset
+          is known.
+
+        - the offset to be applied for the observance
+
+        - a rule that describes the day and time when the observance
+          takes effect
+
+        - an optional name for the observance
+
+   For a given time zone, there may be multiple unique definitions of
+   the observances over a period of time. Each observance is described
+   using either a "STANDARD" or "DAYLIGHT" sub-component. The collection
+   of these sub-components is used to describe the time zone for a given
+   period of time. The offset to apply at any given time is found by
+   locating the observance that has the last onset date and time before
+   the time in question, and using the offset value from that
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 63]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   observance.
+
+   The top-level properties in a "VTIMEZONE" calendar component are:
+
+   The mandatory "TZID" property is a text value that uniquely
+   identifies the VTIMZONE calendar component within the scope of an
+   iCalendar object.
+
+   The optional "LAST-MODIFIED" property is a UTC value that specifies
+   the date and time that this time zone definition was last updated.
+
+   The optional "TZURL" property is url value that points to a published
+   VTIMEZONE definition. TZURL SHOULD refer to a resource that is
+   accessible by anyone who might need to interpret the object. This
+   SHOULD NOT normally be a file: URL or other URL that is not widely-
+   accessible.
+
+   The collection of properties that are used to define the STANDARD and
+   DAYLIGHT sub-components include:
+
+   The mandatory "DTSTART" property gives the effective onset date and
+   local time for the time zone sub-component definition. "DTSTART" in
+   this usage MUST be specified as a local DATE-TIME value.
+
+   The mandatory "TZOFFSETFROM" property gives the UTC offset which is
+   in use when the onset of this time zone observance begins.
+   "TZOFFSETFROM" is combined with "DTSTART" to define the effective
+   onset for the time zone sub-component definition. For example, the
+   following represents the time at which the observance of Standard
+   Time took effect in Fall 1967 for New York City:
+
+     DTSTART:19671029T020000
+
+     TZOFFSETFROM:-0400
+
+   The mandatory "TZOFFSETTO " property gives the UTC offset for the
+   time zone sub-component (Standard Time or Daylight Saving Time) when
+   this observance is in use.
+
+   The optional "TZNAME" property is the customary name for the time
+   zone. It may be specified multiple times, to allow for specifying
+   multiple language variants of the time zone names. This could be used
+   for displaying dates.
+
+   If specified, the onset for the observance defined by the time zone
+   sub-component is defined by either the "RRULE" or "RDATE" property.
+   If neither is specified, only one sub-component can be specified in
+   the "VTIMEZONE" calendar component and it is assumed that the single
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 64]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   observance specified is always in effect.
+
+   The "RRULE" property defines the recurrence rule for the onset of the
+   observance defined by this time zone sub-component. Some specific
+   requirements for the usage of RRULE for this purpose include:
+
+        - If observance is known to have an effective end date, the
+        "UNTIL" recurrence rule parameter MUST be used to specify the
+        last valid onset of this observance (i.e., the UNTIL date-time
+        will be equal to the last instance generated by the recurrence
+        pattern). It MUST be specified in UTC time.
+
+        - The "DTSTART" and the "TZOFFSETTO" properties MUST be used
+        when generating the onset date-time values (instances) from the
+        RRULE.
+
+   Alternatively, the "RDATE" property can be used to define the onset
+   of the observance by giving the individual onset date and times.
+   "RDATE" in this usage MUST be specified as a local DATE-TIME value in
+   UTC time.
+
+   The optional "COMMENT" property is also allowed for descriptive
+   explanatory text.
+
+   Example: The following are examples of the "VTIMEZONE" calendar
+   component:
+
+   This is an example showing time zone information for the Eastern
+   United States using "RDATE" property. Note that this is only suitable
+   for a recurring event that starts on or later than April 6, 1997 at
+   03:00:00 EDT (i.e., the earliest effective transition date and time)
+   and ends no later than April 7, 1998 02:00:00 EST (i.e., latest valid
+   date and time for EST in this scenario). For example, this can be
+   used for a recurring event that occurs every Friday, 8am-9:00 AM,
+   starting June 1, 1997, ending December 31, 1997.
+
+     BEGIN:VTIMEZONE
+     TZID:US-Eastern
+     LAST-MODIFIED:19870101T000000Z
+     BEGIN:STANDARD
+     DTSTART:19971026T020000
+     RDATE:19971026T020000
+     TZOFFSETFROM:-0400
+     TZOFFSETTO:-0500
+     TZNAME:EST
+     END:STANDARD
+     BEGIN:DAYLIGHT
+     DTSTART:19971026T020000
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 65]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     RDATE:19970406T020000
+     TZOFFSETFROM:-0500
+     TZOFFSETTO:-0400
+     TZNAME:EDT
+     END:DAYLIGHT
+     END:VTIMEZONE
+
+   This is a simple example showing the current time zone rules for the
+   Eastern United States using a RRULE recurrence pattern. Note that
+   there is no effective end date to either of the Standard Time or
+   Daylight Time rules. This information would be valid for a recurring
+   event starting today and continuing indefinitely.
+
+     BEGIN:VTIMEZONE
+     TZID:US-Eastern
+     LAST-MODIFIED:19870101T000000Z
+     TZURL:http://zones.stds_r_us.net/tz/US-Eastern
+     BEGIN:STANDARD
+     DTSTART:19671029T020000
+     RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+     TZOFFSETFROM:-0400
+     TZOFFSETTO:-0500
+     TZNAME:EST
+     END:STANDARD
+     BEGIN:DAYLIGHT
+     DTSTART:19870405T020000
+     RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+     TZOFFSETFROM:-0500
+     TZOFFSETTO:-0400
+     TZNAME:EDT
+     END:DAYLIGHT
+     END:VTIMEZONE
+
+   This is an example showing a fictitious set of rules for the Eastern
+   United States, where the Daylight Time rule has an effective end date
+   (i.e., after that date, Daylight Time is no longer observed).
+
+     BEGIN:VTIMEZONE
+     TZID:US--Fictitious-Eastern
+     LAST-MODIFIED:19870101T000000Z
+     BEGIN:STANDARD
+     DTSTART:19671029T020000
+     RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+     TZOFFSETFROM:-0400
+     TZOFFSETTO:-0500
+     TZNAME:EST
+     END:STANDARD
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 66]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     BEGIN:DAYLIGHT
+     DTSTART:19870405T020000
+     RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=19980404T070000Z
+     TZOFFSETFROM:-0500
+     TZOFFSETTO:-0400
+     TZNAME:EDT
+     END:DAYLIGHT
+     END:VTIMEZONE
+
+   This is an example showing a fictitious set of rules for the Eastern
+   United States, where the first Daylight Time rule has an effective
+   end date. There is a second Daylight Time rule that picks up where
+   the other left off.
+
+     BEGIN:VTIMEZONE
+     TZID:US--Fictitious-Eastern
+     LAST-MODIFIED:19870101T000000Z
+     BEGIN:STANDARD
+     DTSTART:19671029T020000
+     RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+     TZOFFSETFROM:-0400
+     TZOFFSETTO:-0500
+     TZNAME:EST
+     END:STANDARD
+     BEGIN:DAYLIGHT
+     DTSTART:19870405T020000
+     RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=19980404T070000Z
+     TZOFFSETFROM:-0500
+     TZOFFSETTO:-0400
+     TZNAME:EDT
+     END:DAYLIGHT
+     BEGIN:DAYLIGHT
+     DTSTART:19990424T020000
+     RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=4
+     TZOFFSETFROM:-0500
+     TZOFFSETTO:-0400
+     TZNAME:EDT
+     END:DAYLIGHT
+     END:VTIMEZONE
+
+4.6.6 Alarm Component
+
+   Component Name: VALARM
+
+   Purpose: Provide a grouping of component properties that define an
+   alarm.
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 67]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Formal Definition: A "VALARM" calendar component is defined by the
+   following notation:
+
+          alarmc     = "BEGIN" ":" "VALARM" CRLF
+                       (audioprop / dispprop / emailprop / procprop)
+                       "END" ":" "VALARM" CRLF
+
+     audioprop  = 2*(
+
+                ; 'action' and 'trigger' are both REQUIRED,
+                ; but MUST NOT occur more than once
+
+                action / trigger /
+
+                ; 'duration' and 'repeat' are both optional,
+                ; and MUST NOT occur more than once each,
+                ; but if one occurs, so MUST the other
+
+                duration / repeat /
+
+                ; the following is optional,
+                ; but MUST NOT occur more than once
+
+                attach /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                x-prop
+
+                )
+
+
+
+     dispprop   = 3*(
+
+                ; the following are all REQUIRED,
+                ; but MUST NOT occur more than once
+
+                action / description / trigger /
+
+                ; 'duration' and 'repeat' are both optional,
+                ; and MUST NOT occur more than once each,
+                ; but if one occurs, so MUST the other
+
+                duration / repeat /
+
+                ; the following is optional,
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 68]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+                ; and MAY occur more than once
+
+                *x-prop
+
+                )
+
+
+
+     emailprop  = 5*(
+
+                ; the following are all REQUIRED,
+                ; but MUST NOT occur more than once
+
+                action / description / trigger / summary
+
+                ; the following is REQUIRED,
+                ; and MAY occur more than once
+
+                attendee /
+
+                ; 'duration' and 'repeat' are both optional,
+                ; and MUST NOT occur more than once each,
+                ; but if one occurs, so MUST the other
+
+                duration / repeat /
+
+                ; the following are optional,
+                ; and MAY occur more than once
+
+                attach / x-prop
+
+                )
+
+
+
+     procprop   = 3*(
+
+                ; the following are all REQUIRED,
+                ; but MUST NOT occur more than once
+
+                action / attach / trigger /
+
+                ; 'duration' and 'repeat' are both optional,
+                ; and MUST NOT occur more than once each,
+                ; but if one occurs, so MUST the other
+
+                duration / repeat /
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 69]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+                ; 'description' is optional,
+                ; and MUST NOT occur more than once
+
+                description /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                x-prop
+
+                )
+
+   Description: A "VALARM" calendar component is a grouping of component
+   properties that is a reminder or alarm for an event or a to-do. For
+   example, it may be used to define a reminder for a pending event or
+   an overdue to-do.
+
+   The "VALARM" calendar component MUST include the "ACTION" and
+   "TRIGGER" properties. The "ACTION" property further constrains the
+   "VALARM" calendar component in the following ways:
+
+   When the action is "AUDIO", the alarm can also include one and only
+   one "ATTACH" property, which MUST point to a sound resource, which is
+   rendered when the alarm is triggered.
+
+   When the action is "DISPLAY", the alarm MUST also include a
+   "DESCRIPTION" property, which contains the text to be displayed when
+   the alarm is triggered.
+
+   When the action is "EMAIL", the alarm MUST include a "DESCRIPTION"
+   property, which contains the text to be used as the message body, a
+   "SUMMARY" property, which contains the text to be used as the message
+   subject, and one or more "ATTENDEE" properties, which contain the
+   email address of attendees to receive the message. It can also
+   include one or more "ATTACH" properties, which are intended to be
+   sent as message attachments. When the alarm is triggered, the email
+   message is sent.
+
+   When the action is "PROCEDURE", the alarm MUST include one and only
+   one "ATTACH" property, which MUST point to a procedure resource,
+   which is invoked when the alarm is triggered.
+
+   The "VALARM" calendar component MUST only appear within either a
+   "VEVENT" or "VTODO" calendar component. "VALARM" calendar components
+   cannot be nested. Multiple mutually independent "VALARM" calendar
+   components can be specified for a single "VEVENT" or "VTODO" calendar
+   component.
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 70]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   The "TRIGGER" property specifies when the alarm will be triggered.
+   The "TRIGGER" property specifies a duration prior to the start of an
+   event or a to-do. The "TRIGGER" edge may be explicitly set to be
+   relative to the "START" or "END" of the event or to-do with the
+   "RELATED" parameter of the "TRIGGER" property. The "TRIGGER" property
+   value type can alternatively be set to an absolute calendar date and
+   time of day value.
+
+   In an alarm set to trigger on the "START" of an event or to-do, the
+   "DTSTART" property MUST be present in the associated event or to-do.
+   In an alarm in a "VEVENT" calendar component set to trigger on the
+   "END" of the event, either the "DTEND" property MUST be present, or
+   the "DTSTART" and "DURATION" properties MUST both be present. In an
+   alarm in a "VTODO" calendar component set to trigger on the "END" of
+   the to-do, either the "DUE" property MUST be present, or the
+   "DTSTART" and "DURATION" properties MUST both be present.
+
+   The alarm can be defined such that it triggers repeatedly. A
+   definition of an alarm with a repeating trigger MUST include both the
+   "DURATION" and "REPEAT" properties. The "DURATION" property specifies
+   the delay period, after which the alarm will repeat. The "REPEAT"
+   property specifies the number of additional repetitions that the
+   alarm will triggered. This repitition count is in addition to the
+   initial triggering of the alarm. Both of these properties MUST be
+   present in order to specify a repeating alarm. If one of these two
+   properties is absent, then the alarm will not repeat beyond the
+   initial trigger.
+
+   The "ACTION" property is used within the "VALARM" calendar component
+   to specify the type of action invoked when the alarm is triggered.
+   The "VALARM" properties provide enough information for a specific
+   action to be invoked. It is typically the responsibility of a
+   "Calendar User Agent" (CUA) to deliver the alarm in the specified
+   fashion. An "ACTION" property value of AUDIO specifies an alarm that
+   causes a sound to be played to alert the user; DISPLAY specifies an
+   alarm that causes a text message to be displayed to the user; EMAIL
+   specifies an alarm that causes an electronic email message to be
+   delivered to one or more email addresses; and PROCEDURE specifies an
+   alarm that causes a procedure to be executed. The "ACTION" property
+   MUST specify one and only one of these values.
+
+   In an AUDIO alarm, if the optional "ATTACH" property is included, it
+   MUST specify an audio sound resource. The intention is that the sound
+   will be played as the alarm effect. If an "ATTACH" property is
+   specified that does not refer to a sound resource, or if the
+   specified sound resource cannot be rendered (because its format is
+   unsupported, or because it cannot be retrieved), then the CUA or
+   other entity responsible for playing the sound may choose a fallback
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 71]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   action, such as playing a built-in default sound, or playing no sound
+   at all.
+
+   In a DISPLAY alarm, the intended alarm effect is for the text value
+   of the "DESCRIPTION" property to be displayed to the user.
+
+   In an EMAIL alarm, the intended alarm effect is for an email message
+   to be composed and delivered to all the addresses specified by the
+   "ATTENDEE" properties in the "VALARM" calendar component. The
+   "DESCRIPTION" property of the "VALARM" calendar component MUST be
+   used as the body text of the message, and the "SUMMARY" property MUST
+   be used as the subject text. Any "ATTACH" properties in the "VALARM"
+   calendar component SHOULD be sent as attachments to the message.
+
+   In a PROCEDURE alarm, the "ATTACH" property in the "VALARM" calendar
+   component MUST specify a procedure or program that is intended to be
+   invoked as the alarm effect. If the procedure or program is in a
+   format that cannot be rendered, then no procedure alarm will be
+   invoked. If the "DESCRIPTION" property is present, its value
+   specifies the argument string to be passed to the procedure or
+   program. "Calendar User Agents" that receive an iCalendar object with
+   this category of alarm, can disable or allow the "Calendar User" to
+   disable, or otherwise ignore this type of alarm. While a very useful
+   alarm capability, the PROCEDURE type of alarm SHOULD be treated by
+   the "Calendar User Agent" as a potential security risk.
+
+   Example: The following example is for a "VALARM" calendar component
+   that specifies an audio alarm that will sound at a precise time and
+   repeat 4 more times at 15 minute intervals:
+
+     BEGIN:VALARM
+     TRIGGER;VALUE=DATE-TIME:19970317T133000Z
+     REPEAT:4
+     DURATION:PT15M
+     ACTION:AUDIO
+     ATTACH;FMTTYPE=audio/basic:ftp://host.com/pub/sounds/bell-01.aud
+     END:VALARM
+
+   The following example is for a "VALARM" calendar component that
+   specifies a display alarm that will trigger 30 minutes before the
+   scheduled start of the event or the due date/time of the to-do it is
+   associated with and will repeat 2 more times at 15 minute intervals:
+
+     BEGIN:VALARM
+     TRIGGER:-PT30M
+     REPEAT:2
+     DURATION:PT15M
+     ACTION:DISPLAY
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 72]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     DESCRIPTION:Breakfast meeting with executive\n
+      team at 8:30 AM EST.
+     END:VALARM
+
+   The following example is for a "VALARM" calendar component that
+   specifies an email alarm that will trigger 2 days before the
+   scheduled due date/time of a to-do it is associated with. It does not
+   repeat. The email has a subject, body and attachment link.
+
+     BEGIN:VALARM
+     TRIGGER:-P2D
+     ACTION:EMAIL
+     ATTENDEE:MAILTO:john_doe@host.com
+     SUMMARY:*** REMINDER: SEND AGENDA FOR WEEKLY STAFF MEETING ***
+     DESCRIPTION:A draft agenda needs to be sent out to the attendees
+       to the weekly managers meeting (MGR-LIST). Attached is a
+       pointer the document template for the agenda file.
+     ATTACH;FMTTYPE=application/binary:http://host.com/templates/agen
+      da.doc
+     END:VALARM
+
+   The following example is for a "VALARM" calendar component that
+   specifies a procedural alarm that will trigger at a precise date/time
+   and will repeat 23 more times at one hour intervals. The alarm will
+   invoke a procedure file.
+
+     BEGIN:VALARM
+     TRIGGER;VALUE=DATE-TIME:19980101T050000Z
+     REPEAT:23
+     DURATION:PT1H
+     ACTION:PROCEDURE
+     ATTACH;FMTTYPE=application/binary:ftp://host.com/novo-
+      procs/felizano.exe
+     END:VALARM
+
+4.7 Calendar Properties
+
+   The Calendar Properties are attributes that apply to the iCalendar
+   object, as a whole. These properties do not appear within a calendar
+   component. They SHOULD be specified after the "BEGIN:VCALENDAR"
+   property and prior to any calendar component.
+
+4.7.1 Calendar Scale
+
+   Property Name: CALSCALE
+
+   Purpose: This property defines the calendar scale used for the
+   calendar information specified in the iCalendar object.
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 73]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: Property can be specified in an iCalendar object. The
+   default value is "GREGORIAN".
+
+   Description: This memo is based on the Gregorian calendar scale. The
+   Gregorian calendar scale is assumed if this property is not specified
+   in the iCalendar object. It is expected that other calendar scales
+   will be defined in other specifications or by future versions of this
+   memo.
+
+   Format Definition: The property is defined by the following notation:
+
+     calscale   = "CALSCALE" calparam ":" calvalue CRLF
+
+     calparam   = *(";" xparam)
+
+     calvalue   = "GREGORIAN" / iana-token
+
+   Example: The following is an example of this property:
+
+     CALSCALE:GREGORIAN
+
+4.7.2 Method
+
+   Property Name: METHOD
+
+   Purpose: This property defines the iCalendar object method associated
+   with the calendar object.
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: The property can be specified in an iCalendar object.
+
+   Description: When used in a MIME message entity, the value of this
+   property MUST be the same as the Content-Type "method" parameter
+   value. This property can only appear once within the iCalendar
+   object. If either the "METHOD" property or the Content-Type "method"
+   parameter is specified, then the other MUST also be specified.
+
+   No methods are defined by this specification. This is the subject of
+   other specifications, such as the iCalendar Transport-independent
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 74]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Interoperability Protocol (iTIP) defined by [ITIP].
+
+   If this property is not present in the iCalendar object, then a
+   scheduling transaction MUST NOT be assumed. In such cases, the
+   iCalendar object is merely being used to transport a snapshot of some
+   calendar information; without the intention of conveying a scheduling
+   semantic.
+
+   Format Definition: The property is defined by the following notation:
+
+     method     = "METHOD" metparam ":" metvalue CRLF
+
+     metparam   = *(";" xparam)
+
+     metvalue   = iana-token
+
+   Example: The following is a hypothetical example of this property to
+   convey that the iCalendar object is a request for a meeting:
+
+     METHOD:REQUEST
+
+4.7.3 Product Identifier
+
+   Property Name: PRODID
+
+   Purpose: This property specifies the identifier for the product that
+   created the iCalendar object.
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: The property MUST be specified once in an iCalendar
+   object.
+
+   Description: The vendor of the implementation SHOULD assure that this
+   is a globally unique identifier; using some technique such as an FPI
+   value, as defined in [ISO 9070].
+
+   This property SHOULD not be used to alter the interpretation of an
+   iCalendar object beyond the semantics specified in this memo. For
+   example, it is not to be used to further the understanding of non-
+   standard properties.
+
+   Format Definition: The property is defined by the following notation:
+
+     prodid     = "PRODID" pidparam ":" pidvalue CRLF
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 75]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     pidparam   = *(";" xparam)
+
+     pidvalue   = text
+     ;Any text that describes the product and version
+     ;and that is generally assured of being unique.
+
+   Example: The following is an example of this property. It does not
+   imply that English is the default language.
+
+     PRODID:-//ABC Corporation//NONSGML My Product//EN
+
+4.7.4 Version
+
+   Property Name: VERSION
+
+   Purpose: This property specifies the identifier corresponding to the
+   highest version number or the minimum and maximum range of the
+   iCalendar specification that is required in order to interpret the
+   iCalendar object.
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: This property MUST be specified by an iCalendar object,
+   but MUST only be specified once.
+
+   Description: A value of "2.0" corresponds to this memo.
+
+   Format Definition: The property is defined by the following notation:
+
+     version    = "VERSION" verparam ":" vervalue CRLF
+
+     verparam   = *(";" xparam)
+
+     vervalue   = "2.0"         ;This memo
+                / maxver
+                / (minver ";" maxver)
+
+     minver     = <A IANA registered iCalendar version identifier>
+     ;Minimum iCalendar version needed to parse the iCalendar object
+
+     maxver     = <A IANA registered iCalendar version identifier>
+     ;Maximum iCalendar version needed to parse the iCalendar object
+
+   Example: The following is an example of this property:
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 76]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     VERSION:2.0
+
+4.8 Component Properties
+
+   The following properties can appear within calendar components, as
+   specified by each component property definition.
+
+4.8.1 Descriptive Component Properties
+
+   The following properties specify descriptive information about
+   calendar components.
+
+4.8.1.1 Attachment
+
+   Property Name: ATTACH
+
+   Purpose: The property provides the capability to associate a document
+   object with a calendar component.
+
+   Value Type: The default value type for this property is URI. The
+   value type can also be set to BINARY to indicate inline binary
+   encoded content information.
+
+   Property Parameters: Non-standard, inline encoding, format type and
+   value data type property parameters can be specified on this
+   property.
+
+   Conformance: The property can be specified in a "VEVENT", "VTODO",
+   "VJOURNAL" or "VALARM" calendar components.
+
+   Description: The property can be specified within "VEVENT", "VTODO",
+   "VJOURNAL", or "VALARM" calendar components. This property can be
+   specified multiple times within an iCalendar object.
+
+   Format Definition: The property is defined by the following notation:
+
+     attach     = "ATTACH" attparam ":" uri  CRLF
+
+     attach     =/ "ATTACH" attparam ";" "ENCODING" "=" "BASE64"
+                   ";" "VALUE" "=" "BINARY" ":" binary
+
+     attparam   = *(
+
+                ; the following is optional,
+                ; but MUST NOT occur more than once
+
+                (";" fmttypeparam) /
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 77]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+   Example: The following are examples of this property:
+
+     ATTACH:CID:jsmith.part3.960817T083000.xyzMail@host1.com
+
+     ATTACH;FMTTYPE=application/postscript:ftp://xyzCorp.com/pub/
+      reports/r-960812.ps
+
+4.8.1.2 Categories
+
+   Property Name: CATEGORIES
+
+   Purpose: This property defines the categories for a calendar
+   component.
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard and language property parameters
+   can be specified on this property.
+
+   Conformance: The property can be specified within "VEVENT", "VTODO"
+   or "VJOURNAL" calendar components.
+
+   Description: This property is used to specify categories or subtypes
+   of the calendar component. The categories are useful in searching for
+   a calendar component of a particular type and category. Within the
+   "VEVENT", "VTODO" or "VJOURNAL" calendar components, more than one
+   category can be specified as a list of categories separated by the
+   COMMA character (US-ASCII decimal 44).
+
+   Format Definition: The property is defined by the following notation:
+
+     categories = "CATEGORIES" catparam ":" text *("," text)
+                  CRLF
+
+     catparam   = *(
+
+                ; the following is optional,
+                ; but MUST NOT occur more than once
+
+                (";" languageparam ) /
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 78]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+   Example: The following are examples of this property:
+
+     CATEGORIES:APPOINTMENT,EDUCATION
+
+     CATEGORIES:MEETING
+
+4.8.1.3 Classification
+
+   Property Name: CLASS
+
+   Purpose: This property defines the access classification for a
+   calendar component.
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: The property can be specified once in a "VEVENT",
+   "VTODO" or "VJOURNAL" calendar components.
+
+   Description: An access classification is only one component of the
+   general security system within a calendar application. It provides a
+   method of capturing the scope of the access the calendar owner
+   intends for information within an individual calendar entry. The
+   access classification of an individual iCalendar component is useful
+   when measured along with the other security components of a calendar
+   system (e.g., calendar user authentication, authorization, access
+   rights, access role, etc.). Hence, the semantics of the individual
+   access classifications cannot be completely defined by this memo
+   alone. Additionally, due to the "blind" nature of most exchange
+   processes using this memo, these access classifications cannot serve
+   as an enforcement statement for a system receiving an iCalendar
+   object. Rather, they provide a method for capturing the intention of
+   the calendar owner for the access to the calendar component.
+
+   Format Definition: The property is defined by the following notation:
+
+     class      = "CLASS" classparam ":" classvalue CRLF
+
+     classparam = *(";" xparam)
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 79]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     classvalue = "PUBLIC" / "PRIVATE" / "CONFIDENTIAL" / iana-token
+                / x-name
+     ;Default is PUBLIC
+
+   Example: The following is an example of this property:
+
+     CLASS:PUBLIC
+
+4.8.1.4 Comment
+
+   Property Name: COMMENT
+
+   Purpose: This property specifies non-processing information intended
+   to provide a comment to the calendar user.
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard, alternate text representation and
+   language property parameters can be specified on this property.
+
+   Conformance: This property can be specified in "VEVENT", "VTODO",
+   "VJOURNAL", "VTIMEZONE" or "VFREEBUSY" calendar components.
+
+   Description: The property can be specified multiple times.
+
+   Format Definition: The property is defined by the following notation:
+
+     comment    = "COMMENT" commparam ":" text CRLF
+
+     commparam  = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                (";" altrepparam) / (";" languageparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+   Example: The following is an example of this property:
+
+     COMMENT:The meeting really needs to include both ourselves
+       and the customer. We can't hold this  meeting without them.
+       As a matter of fact\, the venue for the meeting ought to be at
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 80]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+       their site. - - John
+
+   The data type for this property is TEXT.
+
+4.8.1.5 Description
+
+   Property Name: DESCRIPTION
+
+   Purpose: This property provides a more complete description of the
+   calendar component, than that provided by the "SUMMARY" property.
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard, alternate text representation and
+   language property parameters can be specified on this property.
+
+   Conformance: The property can be specified in the "VEVENT", "VTODO",
+   "VJOURNAL" or "VALARM" calendar components. The property can be
+   specified multiple times only within a "VJOURNAL" calendar component.
+
+   Description: This property is used in the "VEVENT" and "VTODO" to
+   capture lengthy textual decriptions associated with the activity.
+
+   This property is used in the "VJOURNAL" calendar component to capture
+   one more textual journal entries.
+
+   This property is used in the "VALARM" calendar component to capture
+   the display text for a DISPLAY category of alarm, to capture the body
+   text for an EMAIL category of alarm and to capture the argument
+   string for a PROCEDURE category of alarm.
+
+   Format Definition: The property is defined by the following notation:
+
+     description        = "DESCRIPTION" descparam ":" text CRLF
+
+     descparam  = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                (";" altrepparam) / (";" languageparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 81]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Example: The following is an example of the property with formatted
+   line breaks in the property value:
+
+     DESCRIPTION:Meeting to provide technical review for "Phoenix"
+       design.\n Happy Face Conference Room. Phoenix design team
+       MUST attend this meeting.\n RSVP to team leader.
+
+   The following is an example of the property with folding of long
+   lines:
+
+     DESCRIPTION:Last draft of the new novel is to be completed
+       for the editor's proof today.
+
+4.8.1.6 Geographic Position
+
+   Property Name: GEO
+
+   Purpose: This property specifies information related to the global
+   position for the activity specified by a calendar component.
+
+   Value Type: FLOAT. The value MUST be two SEMICOLON separated FLOAT
+   values.
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: This property can be specified in  "VEVENT" or "VTODO"
+   calendar components.
+
+   Description: The property value specifies latitude and longitude, in
+   that order (i.e., "LAT LON" ordering). The longitude represents the
+   location east or west of the prime meridian as a positive or negative
+   real number, respectively. The longitude and latitude values MAY be
+   specified up to six decimal places, which will allow for accuracy to
+   within one meter of geographical position. Receiving applications
+   MUST accept values of this precision and MAY truncate values of
+   greater precision.
+
+   Values for latitude and longitude shall be expressed as decimal
+   fractions of degrees. Whole degrees of latitude shall be represented
+   by a two-digit decimal number ranging from 0 through 90. Whole
+   degrees of longitude shall be represented by a decimal number ranging
+   from 0 through 180. When a decimal fraction of a degree is specified,
+   it shall be separated from the whole number of degrees by a decimal
+   point.
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 82]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Latitudes north of the equator shall be specified by a plus sign (+),
+   or by the absence of a minus sign (-), preceding the digits
+   designating degrees. Latitudes south of the Equator shall be
+   designated by a minus sign (-) preceding the digits designating
+   degrees. A point on the Equator shall be assigned to the Northern
+   Hemisphere.
+
+   Longitudes east of the prime meridian shall be specified by a plus
+   sign (+), or by the absence of a minus sign (-), preceding the digits
+   designating degrees. Longitudes west of the meridian shall be
+   designated by minus sign (-) preceding the digits designating
+   degrees. A point on the prime meridian shall be assigned to the
+   Eastern Hemisphere. A point on the 180th meridian shall be assigned
+   to the Western Hemisphere. One exception to this last convention is
+   permitted. For the special condition of describing a band of latitude
+   around the earth, the East Bounding Coordinate data element shall be
+   assigned the value +180 (180) degrees.
+
+   Any spatial address with a latitude of +90 (90) or -90 degrees will
+   specify the position at the North or South Pole, respectively. The
+   component for longitude may have any legal value.
+
+   With the exception of the special condition described above, this
+   form is specified in Department of Commerce, 1986, Representation of
+   geographic point locations for information interchange (Federal
+   Information Processing Standard 70-1):  Washington,  Department of
+   Commerce, National Institute of Standards and Technology.
+
+   The simple formula for converting degrees-minutes-seconds into
+   decimal degrees is:
+
+     decimal = degrees + minutes/60 + seconds/3600.
+
+   Format Definition: The property is defined by the following notation:
+
+     geo        = "GEO" geoparam ":" geovalue CRLF
+
+     geoparam   = *(";" xparam)
+
+     geovalue   = float ";" float
+     ;Latitude and Longitude components
+
+   Example: The following is an example of this property:
+
+     GEO:37.386013;-122.082932
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 83]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+4.8.1.7 Location
+
+   Property Name: LOCATION
+
+   Purpose: The property defines the intended venue for the activity
+   defined by a calendar component.
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard, alternate text representation and
+   language property parameters can be specified on this property.
+
+   Conformance: This property can be specified in "VEVENT" or "VTODO"
+   calendar component.
+
+   Description: Specific venues such as conference or meeting rooms may
+   be explicitly specified using this property. An alternate
+   representation may be specified that is a URI that points to
+   directory information with more structured specification of the
+   location. For example, the alternate representation may specify
+   either an LDAP URI pointing to an LDAP server entry or a CID URI
+   pointing to a MIME body part containing a vCard [RFC 2426] for the
+   location.
+
+   Format Definition: The property is defined by the following notation:
+
+     location   = "LOCATION locparam ":" text CRLF
+
+     locparam   = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                (";" altrepparam) / (";" languageparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+   Example: The following are some examples of this property:
+
+     LOCATION:Conference Room - F123, Bldg. 002
+
+     LOCATION;ALTREP="http://xyzcorp.com/conf-rooms/f123.vcf":
+      Conference Room - F123, Bldg. 002
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 84]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+4.8.1.8 Percent Complete
+
+   Property Name: PERCENT-COMPLETE
+
+   Purpose: This property is used by an assignee or delegatee of a to-do
+   to convey the percent completion of a to-do to the Organizer.
+
+   Value Type: INTEGER
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: This property can be specified in a "VTODO" calendar
+   component.
+
+   Description: The property value is a positive integer between zero
+   and one hundred. A value of "0" indicates the to-do has not yet been
+   started. A value of "100" indicates that the to-do has been
+   completed. Integer values in between indicate the percent partially
+   complete.
+
+   When a to-do is assigned to multiple individuals, the property value
+   indicates the percent complete for that portion of the to-do assigned
+   to the assignee or delegatee. For example, if a to-do is assigned to
+   both individuals "A" and "B". A reply from "A" with a percent
+   complete of "70" indicates that "A" has completed 70% of the to-do
+   assigned to them. A reply from "B" with a percent complete of "50"
+   indicates "B" has completed 50% of the to-do assigned to them.
+
+   Format Definition: The property is defined by the following notation:
+
+     percent = "PERCENT-COMPLETE" pctparam ":" integer CRLF
+
+     pctparam   = *(";" xparam)
+
+   Example: The following is an example of this property to show 39%
+   completion:
+
+     PERCENT-COMPLETE:39
+
+4.8.1.9 Priority
+
+   Property Name: PRIORITY
+
+   Purpose: The property defines the relative priority for a calendar
+   component.
+
+   Value Type: INTEGER
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 85]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: The property can be specified in a "VEVENT" or "VTODO"
+   calendar component.
+
+   Description: The priority is specified as an integer in the range
+   zero to nine. A value of zero (US-ASCII decimal 48) specifies an
+   undefined priority. A value of one (US-ASCII decimal 49) is the
+   highest priority. A value of two (US-ASCII decimal 50) is the second
+   highest priority. Subsequent numbers specify a decreasing ordinal
+   priority. A value of nine (US-ASCII decimal 58) is the lowest
+   priority.
+
+   A CUA with a three-level priority scheme of "HIGH", "MEDIUM" and
+   "LOW" is mapped into this property such that a property value in the
+   range of one (US-ASCII decimal 49) to four (US-ASCII decimal 52)
+   specifies "HIGH" priority. A value of five (US-ASCII decimal 53) is
+   the normal or "MEDIUM" priority. A value in the range of six (US-
+   ASCII decimal 54) to nine (US-ASCII decimal 58) is "LOW" priority.
+
+   A CUA with a priority schema of "A1", "A2", "A3", "B1", "B2", ...,
+   "C3" is mapped into this property such that a property value of one
+   (US-ASCII decimal 49) specifies "A1", a property value of two (US-
+   ASCII decimal 50) specifies "A2", a property value of three (US-ASCII
+   decimal 51) specifies "A3", and so forth up to a property value of 9
+   (US-ASCII decimal 58) specifies "C3".
+
+   Other integer values are reserved for future use.
+
+   Within a "VEVENT" calendar component, this property specifies a
+   priority for the event. This property may be useful when more than
+   one event is scheduled for a given time period.
+
+   Within a "VTODO" calendar component, this property specified a
+   priority for the to-do. This property is useful in prioritizing
+   multiple action items for a given time period.
+
+   Format Definition: The property is specified by the following
+   notation:
+
+     priority   = "PRIORITY" prioparam ":" privalue CRLF
+     ;Default is zero
+
+     prioparam  = *(";" xparam)
+
+     privalue   = integer       ;Must be in the range [0..9]
+        ; All other values are reserved for future use
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 86]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   The following is an example of a property with the highest priority:
+
+     PRIORITY:1
+
+   The following is an example of a property with a next highest
+   priority:
+
+     PRIORITY:2
+
+   Example: The following is an example of a property with no priority.
+   This is equivalent to not specifying the "PRIORITY" property:
+
+     PRIORITY:0
+
+4.8.1.10 Resources
+
+   Property Name: RESOURCES
+
+   Purpose: This property defines the equipment or resources anticipated
+   for an activity specified by a calendar entity..
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard, alternate text representation and
+   language property parameters can be specified on this property.
+
+   Conformance: This property can be specified in "VEVENT" or "VTODO"
+   calendar component.
+
+   Description: The property value is an arbitrary text. More than one
+   resource can be specified as a list of resources separated by the
+   COMMA character (US-ASCII decimal 44).
+
+   Format Definition: The property is defined by the following notation:
+
+     resources  = "RESOURCES" resrcparam ":" text *("," text) CRLF
+
+     resrcparam = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                (";" altrepparam) / (";" languageparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 87]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+                (";" xparam)
+
+                )
+
+   Example: The following is an example of this property:
+
+     RESOURCES:EASEL,PROJECTOR,VCR
+
+     RESOURCES;LANGUAGE=fr:1 raton-laveur
+
+4.8.1.11 Status
+
+   Property Name: STATUS
+
+   Purpose: This property defines the overall status or confirmation for
+   the calendar component.
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: This property can be specified in "VEVENT", "VTODO" or
+   "VJOURNAL" calendar components.
+
+   Description: In a group scheduled calendar component, the property is
+   used by the "Organizer" to provide a confirmation of the event to the
+   "Attendees". For example in a "VEVENT" calendar component, the
+   "Organizer" can indicate that a meeting is tentative, confirmed or
+   cancelled. In a "VTODO" calendar component, the "Organizer" can
+   indicate that an action item needs action, is completed, is in
+   process or being worked on, or has been cancelled. In a "VJOURNAL"
+   calendar component, the "Organizer" can indicate that a journal entry
+   is draft, final or has been cancelled or removed.
+
+   Format Definition: The property is defined by the following notation:
+
+     status     = "STATUS" statparam] ":" statvalue CRLF
+
+     statparam  = *(";" xparam)
+
+     statvalue  = "TENTATIVE"           ;Indicates event is
+                                        ;tentative.
+                / "CONFIRMED"           ;Indicates event is
+                                        ;definite.
+                / "CANCELLED"           ;Indicates event was
+                                        ;cancelled.
+        ;Status values for a "VEVENT"
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 88]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     statvalue  =/ "NEEDS-ACTION"       ;Indicates to-do needs action.
+                / "COMPLETED"           ;Indicates to-do completed.
+                / "IN-PROCESS"          ;Indicates to-do in process of
+                / "CANCELLED"           ;Indicates to-do was cancelled.
+        ;Status values for "VTODO".
+
+     statvalue  =/ "DRAFT"              ;Indicates journal is draft.
+                / "FINAL"               ;Indicates journal is final.
+                / "CANCELLED"           ;Indicates journal is removed.
+        ;Status values for "VJOURNAL".
+
+   Example: The following is an example of this property for a "VEVENT"
+   calendar component:
+
+     STATUS:TENTATIVE
+
+   The following is an example of this property for a "VTODO" calendar
+   component:
+
+     STATUS:NEEDS-ACTION
+
+   The following is an example of this property for a "VJOURNAL"
+   calendar component:
+
+     STATUS:DRAFT
+
+4.8.1.12 Summary
+
+   Property Name: SUMMARY
+
+   Purpose: This property defines a short summary or subject for the
+   calendar component.
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard, alternate text representation and
+   language property parameters can be specified on this property.
+
+   Conformance: The property can be specified in "VEVENT", "VTODO",
+   "VJOURNAL" or "VALARM" calendar components.
+
+   Description: This property is used in the "VEVENT", "VTODO" and
+   "VJOURNAL" calendar components to capture a short, one line summary
+   about the activity or journal entry.
+
+   This property is used in the "VALARM" calendar component to capture
+   the subject of an EMAIL category of alarm.
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 89]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Format Definition: The property is defined by the following notation:
+
+     summary    = "SUMMARY" summparam ":" text CRLF
+
+     summparam  = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                (";" altrepparam) / (";" languageparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+   Example: The following is an example of this property:
+
+     SUMMARY:Department Party
+
+4.8.2 Date and Time Component Properties
+
+   The following properties specify date and time related information in
+   calendar components.
+
+4.8.2.1 Date/Time Completed
+
+   Property Name: COMPLETED
+
+   Purpose: This property defines the date and time that a to-do was
+   actually completed.
+
+   Value Type: DATE-TIME
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: The property can be specified in a "VTODO" calendar
+   component.
+
+   Description: The date and time MUST be in a UTC format.
+
+   Format Definition: The property is defined by the following notation:
+
+     completed  = "COMPLETED" compparam ":" date-time CRLF
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 90]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     compparam  = *(";" xparam)
+
+   Example: The following is an example of this property:
+
+     COMPLETED:19960401T235959Z
+
+4.8.2.2 Date/Time End
+
+   Property Name: DTEND
+
+   Purpose: This property specifies the date and time that a calendar
+   component ends.
+
+   Value Type: The default value type is DATE-TIME. The value type can
+   be set to a DATE value type.
+
+   Property Parameters: Non-standard, value data type, time zone
+   identifier property parameters can be specified on this property.
+
+   Conformance: This property can be specified in "VEVENT" or
+   "VFREEBUSY" calendar components.
+
+   Description: Within the "VEVENT" calendar component, this property
+   defines the date and time by which the event ends. The value MUST be
+   later in time than the value of the "DTSTART" property.
+
+   Within the "VFREEBUSY" calendar component, this property defines the
+   end date and time for the free or busy time information. The time
+   MUST be specified in the UTC time format. The value MUST be later in
+   time than the value of the "DTSTART" property.
+
+   Format Definition: The property is defined by the following notation:
+
+     dtend      = "DTEND" dtendparam":" dtendval CRLF
+
+     dtendparam = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                (";" "VALUE" "=" ("DATE-TIME" / "DATE")) /
+                (";" tzidparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 91]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+                (";" xparam)
+
+                )
+
+
+
+     dtendval   = date-time / date
+     ;Value MUST match value type
+
+   Example: The following is an example of this property:
+
+     DTEND:19960401T235959Z
+
+     DTEND;VALUE=DATE:19980704
+
+4.8.2.3 Date/Time Due
+
+   Property Name: DUE
+
+   Purpose: This property defines the date and time that a to-do is
+   expected to be completed.
+
+   Value Type: The default value type is DATE-TIME. The value type can
+   be set to a DATE value type.
+
+   Property Parameters: Non-standard, value data type, time zone
+   identifier property parameters can be specified on this property.
+
+   Conformance: The property can be specified once in a "VTODO" calendar
+   component.
+
+   Description: The value MUST be a date/time equal to or after the
+   DTSTART value, if specified.
+
+   Format Definition: The property is defined by the following notation:
+
+     due        = "DUE" dueparam":" dueval CRLF
+
+     dueparam   = *(
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                (";" "VALUE" "=" ("DATE-TIME" / "DATE")) /
+                (";" tzidparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 92]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+                  *(";" xparam)
+
+                )
+
+
+
+     dueval     = date-time / date
+     ;Value MUST match value type
+
+   Example: The following is an example of this property:
+
+     DUE:19980430T235959Z
+
+4.8.2.4 Date/Time Start
+
+   Property Name: DTSTART
+
+   Purpose: This property specifies when the calendar component begins.
+
+   Value Type: The default value type is DATE-TIME. The time value MUST
+   be one of the forms defined for the DATE-TIME value type. The value
+   type can be set to a DATE value type.
+
+   Property Parameters: Non-standard, value data type, time zone
+   identifier property parameters can be specified on this property.
+
+   Conformance: This property can be specified in the "VEVENT", "VTODO",
+   "VFREEBUSY", or "VTIMEZONE" calendar components.
+
+   Description: Within the "VEVENT" calendar component, this property
+   defines the start date and time for the event. The property is
+   REQUIRED in "VEVENT" calendar components. Events can have a start
+   date/time but no end date/time. In that case, the event does not take
+   up any time.
+
+   Within the "VFREEBUSY" calendar component, this property defines the
+   start date and time for the free or busy time information. The time
+   MUST be specified in UTC time.
+
+   Within the "VTIMEZONE" calendar component, this property defines the
+   effective start date and time for a time zone specification. This
+   property is REQUIRED within each STANDARD and DAYLIGHT part included
+   in "VTIMEZONE" calendar components and MUST be specified as a local
+   DATE-TIME without the "TZID" property parameter.
+
+   Format Definition: The property is defined by the following notation:
+
+     dtstart    = "DTSTART" dtstparam ":" dtstval CRLF
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 93]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     dtstparam  = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                (";" "VALUE" "=" ("DATE-TIME" / "DATE")) /
+                (";" tzidparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                  *(";" xparam)
+
+                )
+
+
+
+     dtstval    = date-time / date
+     ;Value MUST match value type
+
+   Example: The following is an example of this property:
+
+     DTSTART:19980118T073000Z
+
+4.8.2.5 Duration
+
+   Property Name: DURATION
+
+   Purpose: The property specifies a positive duration of time.
+
+   Value Type: DURATION
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: The property can be specified in "VEVENT", "VTODO",
+   "VFREEBUSY" or "VALARM" calendar components.
+
+   Description: In a "VEVENT" calendar component the property may be
+   used to specify a duration of the event, instead of an explicit end
+   date/time. In a "VTODO" calendar component the property may be used
+   to specify a duration for the to-do, instead of an explicit due
+   date/time. In a "VFREEBUSY" calendar component the property may be
+   used to specify the interval of free time being requested. In a
+   "VALARM" calendar component the property may be used to specify the
+   delay period prior to repeating an alarm.
+
+   Format Definition: The property is defined by the following notation:
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 94]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     duration   = "DURATION" durparam ":" dur-value CRLF
+                  ;consisting of a positive duration of time.
+
+     durparam   = *(";" xparam)
+
+   Example: The following is an example of this property that specifies
+   an interval of time of 1 hour and zero minutes and zero seconds:
+
+     DURATION:PT1H0M0S
+
+   The following is an example of this property that specifies an
+   interval of time of 15 minutes.
+
+     DURATION:PT15M
+
+4.8.2.6 Free/Busy Time
+
+   Property Name: FREEBUSY
+
+   Purpose: The property defines one or more free or busy time
+   intervals.
+
+   Value Type: PERIOD. The date and time values MUST be in an UTC time
+   format.
+
+   Property Parameters: Non-standard or free/busy time type property
+   parameters can be specified on this property.
+
+   Conformance: The property can be specified in a "VFREEBUSY" calendar
+   component.
+
+   Property Parameter: "FBTYPE" and non-standard parameters can be
+   specified on this property.
+
+   Description: These time periods can be specified as either a start
+   and end date-time or a start date-time and duration. The date and
+   time MUST be a UTC time format.
+
+   "FREEBUSY" properties within the "VFREEBUSY" calendar component
+   SHOULD be sorted in ascending order, based on start time and then end
+   time, with the earliest periods first.
+
+   The "FREEBUSY" property can specify more than one value, separated by
+   the COMMA character (US-ASCII decimal 44). In such cases, the
+   "FREEBUSY" property values SHOULD all be of the same "FBTYPE"
+   property parameter type (e.g., all values of a particular "FBTYPE"
+   listed together in a single property).
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 95]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Format Definition: The property is defined by the following notation:
+
+     freebusy   = "FREEBUSY" fbparam ":" fbvalue
+                  CRLF
+
+     fbparam    = *(
+                ; the following is optional,
+                ; but MUST NOT occur more than once
+
+                (";" fbtypeparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+     fbvalue    = period *["," period]
+     ;Time value MUST be in the UTC time format.
+
+   Example: The following are some examples of this property:
+
+     FREEBUSY;FBTYPE=BUSY-UNAVAILABLE:19970308T160000Z/PT8H30M
+
+     FREEBUSY;FBTYPE=FREE:19970308T160000Z/PT3H,19970308T200000Z/PT1H
+
+     FREEBUSY;FBTYPE=FREE:19970308T160000Z/PT3H,19970308T200000Z/PT1H,
+      19970308T230000Z/19970309T000000Z
+
+4.8.2.7 Time Transparency
+
+   Property Name: TRANSP
+
+   Purpose: This property defines whether an event is transparent or not
+   to busy time searches.
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: This property can be specified once in a "VEVENT"
+   calendar component.
+
+   Description: Time Transparency is the characteristic of an event that
+   determines whether it appears to consume time on a calendar. Events
+   that consume actual time for the individual or resource associated
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 96]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   with the calendar SHOULD be recorded as OPAQUE, allowing them to be
+   detected by free-busy time searches. Other events, which do not take
+   up the individual's (or resource's) time SHOULD be recorded as
+   TRANSPARENT, making them invisible to free-busy time searches.
+
+   Format Definition: The property is specified by the following
+   notation:
+
+     transp     = "TRANSP" tranparam ":" transvalue CRLF
+
+     tranparam  = *(";" xparam)
+
+     transvalue = "OPAQUE"      ;Blocks or opaque on busy time searches.
+                / "TRANSPARENT" ;Transparent on busy time searches.
+        ;Default value is OPAQUE
+
+   Example: The following is an example of this property for an event
+   that is transparent or does not block on free/busy time searches:
+
+     TRANSP:TRANSPARENT
+
+   The following is an example of this property for an event that is
+   opaque or blocks on free/busy time searches:
+
+     TRANSP:OPAQUE
+
+4.8.3 Time Zone Component Properties
+
+   The following properties specify time zone information in calendar
+   components.
+
+4.8.3.1 Time Zone Identifier
+
+   Property Name: TZID
+
+   Purpose: This property specifies the text value that uniquely
+   identifies the "VTIMEZONE" calendar component.
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: This property MUST be specified in a "VTIMEZONE"
+   calendar component.
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 97]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Description: This is the label by which a time zone calendar
+   component is referenced by any iCalendar properties whose data type
+   is either DATE-TIME or TIME and not intended to specify a UTC or a
+   "floating" time. The presence of the SOLIDUS character (US-ASCII
+   decimal 47) as a prefix, indicates that this TZID represents an
+   unique ID in a globally defined time zone registry (when such
+   registry is defined).
+
+        Note: This document does not define a naming convention for time
+        zone identifiers. Implementers may want to use the naming
+        conventions defined in existing time zone specifications such as
+        the public-domain Olson database [TZ]. The specification of
+        globally unique time zone identifiers is not addressed by this
+        document and is left for future study.
+
+   Format Definition: This property is defined by the following
+   notation:
+
+     tzid       = "TZID" tzidpropparam ":" [tzidprefix] text CRLF
+
+     tzidpropparam      = *(";" xparam)
+
+     ;tzidprefix        = "/"
+     ; Defined previously. Just listed here for reader convenience.
+
+   Example: The following are examples of non-globally unique time zone
+   identifiers:
+
+     TZID:US-Eastern
+
+     TZID:California-Los_Angeles
+
+   The following is an example of a fictitious globally unique time zone
+   identifier:
+
+     TZID:/US-New_York-New_York
+
+4.8.3.2 Time Zone Name
+
+   Property Name: TZNAME
+
+   Purpose: This property specifies the customary designation for a time
+   zone description.
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard and language property parameters
+   can be specified on this property.
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 98]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Conformance: This property can be specified in a "VTIMEZONE" calendar
+   component.
+
+   Description: This property may be specified in multiple languages; in
+   order to provide for different language requirements.
+
+   Format Definition: This property is defined by the following
+   notation:
+
+     tzname     = "TZNAME" tznparam ":" text CRLF
+
+     tznparam   = *(
+
+                ; the following is optional,
+                ; but MUST NOT occur more than once
+
+                (";" languageparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+   Example: The following are example of this property:
+
+     TZNAME:EST
+
+   The following is an example of this property when two different
+   languages for the time zone name are specified:
+
+     TZNAME;LANGUAGE=en:EST
+     TZNAME;LANGUAGE=fr-CA:HNE
+
+4.8.3.3 Time Zone Offset From
+
+   Property Name: TZOFFSETFROM
+
+   Purpose: This property specifies the offset which is in use prior to
+   this time zone observance.
+
+   Value Type: UTC-OFFSET
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+
+
+
+
+Dawson & Stenerson          Standards Track                    [Page 99]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Conformance: This property MUST be specified in a "VTIMEZONE"
+   calendar component.
+
+   Description: This property specifies the offset which is in use prior
+   to this time observance. It is used to calculate the absolute time at
+   which the transition to a given observance takes place. This property
+   MUST only be specified in a "VTIMEZONE" calendar component. A
+   "VTIMEZONE" calendar component MUST include this property. The
+   property value is a signed numeric indicating the number of hours and
+   possibly minutes from UTC. Positive numbers represent time zones east
+   of the prime meridian, or ahead of UTC. Negative numbers represent
+   time zones west of the prime meridian, or behind UTC.
+
+   Format Definition: The property is defined by the following notation:
+
+     tzoffsetfrom       = "TZOFFSETFROM" frmparam ":" utc-offset
+                          CRLF
+
+     frmparam   = *(";" xparam)
+
+   Example: The following are examples of this property:
+
+     TZOFFSETFROM:-0500
+
+     TZOFFSETFROM:+1345
+
+4.8.3.4 Time Zone Offset To
+
+   Property Name: TZOFFSETTO
+
+   Purpose: This property specifies the offset which is in use in this
+   time zone observance.
+
+   Value Type: UTC-OFFSET
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: This property MUST be specified in a "VTIMEZONE"
+   calendar component.
+
+   Description: This property specifies the offset which is in use in
+   this time zone observance. It is used to calculate the absolute time
+   for the new observance. The property value is a signed numeric
+   indicating the number of hours and possibly minutes from UTC.
+   Positive numbers represent time zones east of the prime meridian, or
+   ahead of UTC. Negative numbers represent time zones west of the prime
+   meridian, or behind UTC.
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 100]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Format Definition: The property is defined by the following notation:
+
+     tzoffsetto = "TZOFFSETTO" toparam ":" utc-offset CRLF
+
+     toparam    = *(";" xparam)
+
+   Example: The following are examples of this property:
+
+     TZOFFSETTO:-0400
+
+     TZOFFSETTO:+1245
+
+4.8.3.5 Time Zone URL
+
+   Property Name: TZURL
+
+   Purpose: The TZURL provides a means for a VTIMEZONE component to
+   point to a network location that can be used to retrieve an up-to-
+   date version of itself.
+
+   Value Type: URI
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: This property can be specified in a "VTIMEZONE" calendar
+   component.
+
+   Description: The TZURL provides a means for a VTIMEZONE component to
+   point to a network location that can be used to retrieve an up-to-
+   date version of itself. This provides a hook to handle changes
+   government bodies impose upon time zone definitions. Retrieval of
+   this resource results in an iCalendar object containing a single
+   VTIMEZONE component and a METHOD property set to PUBLISH.
+
+   Format Definition: The property is defined by the following notation:
+
+     tzurl      = "TZURL" tzurlparam ":" uri CRLF
+
+     tzurlparam = *(";" xparam)
+
+   Example: The following is an example of this property:
+
+     TZURL:http://timezones.r.us.net/tz/US-California-Los_Angeles
+
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 101]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+4.8.4 Relationship Component Properties
+
+   The following properties specify relationship information in calendar
+   components.
+
+4.8.4.1 Attendee
+
+   Property Name: ATTENDEE
+
+   Purpose: The property defines an "Attendee" within a calendar
+   component.
+
+   Value Type: CAL-ADDRESS
+
+   Property Parameters: Non-standard, language, calendar user type,
+   group or list membership, participation role, participation status,
+   RSVP expectation, delegatee, delegator, sent by, common name or
+   directory entry reference property parameters can be specified on
+   this property.
+
+   Conformance: This property MUST be specified in an iCalendar object
+   that specifies a group scheduled calendar entity. This property MUST
+   NOT be specified in an iCalendar object when publishing the calendar
+   information (e.g., NOT in an iCalendar object that specifies the
+   publication of a calendar user's busy time, event, to-do or journal).
+   This property is not specified in an iCalendar object that specifies
+   only a time zone definition or that defines calendar entities that
+   are not group scheduled entities, but are entities only on a single
+   user's calendar.
+
+   Description: The property MUST only be specified within calendar
+   components to specify participants, non-participants and the chair of
+   a group scheduled calendar entity. The property is specified within
+   an "EMAIL" category of the "VALARM" calendar component to specify an
+   email address that is to receive the email type of iCalendar alarm.
+
+   The property parameter CN is for the common or displayable name
+   associated with the calendar address; ROLE, for the intended role
+   that the attendee will have in the calendar component; PARTSTAT, for
+   the status of the attendee's participation; RSVP, for indicating
+   whether the favor of a reply is requested; CUTYPE, to indicate the
+   type of calendar user; MEMBER, to indicate the groups that the
+   attendee belongs to; DELEGATED-TO, to indicate the calendar users
+   that the original request was delegated to; and DELEGATED-FROM, to
+   indicate whom the request was delegated from; SENT-BY, to indicate
+   whom is acting on behalf of the ATTENDEE; and DIR, to indicate the
+   URI that points to the directory information corresponding to the
+   attendee. These property parameters can be specified on an "ATTENDEE"
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 102]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   property in either a "VEVENT", "VTODO" or "VJOURNAL" calendar
+   component. They MUST not be specified in an "ATTENDEE" property in a
+   "VFREEBUSY" or "VALARM" calendar component. If the LANGUAGE property
+   parameter is specified, the identified language applies to the CN
+   parameter.
+
+   A recipient delegated a request MUST inherit the RSVP and ROLE values
+   from the attendee that delegated the request to them.
+
+   Multiple attendees can be specified by including multiple "ATTENDEE"
+   properties within the calendar component.
+
+   Format Definition: The property is defined by the following notation:
+
+     attendee   = "ATTENDEE" attparam ":" cal-address CRLF
+
+     attparam   = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                (";" cutypeparam) / (";"memberparam) /
+                (";" roleparam) / (";" partstatparam) /
+                (";" rsvpparam) / (";" deltoparam) /
+                (";" delfromparam) / (";" sentbyparam) /
+                (";"cnparam) / (";" dirparam) /
+                (";" languageparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+   Example: The following are examples of this property's use for a to-
+   do:
+
+     ORGANIZER:MAILTO:jsmith@host1.com
+     ATTENDEE;MEMBER="MAILTO:DEV-GROUP@host2.com":
+      MAILTO:joecool@host2.com
+     ATTENDEE;DELEGATED-FROM="MAILTO:immud@host3.com":
+      MAILTO:ildoit@host1.com
+
+   The following is an example of this property used for specifying
+   multiple attendees to an event:
+
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 103]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     ORGANIZER:MAILTO:jsmith@host1.com
+     ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=TENTATIVE;CN=Henry Cabot
+      :MAILTO:hcabot@host2.com
+     ATTENDEE;ROLE=REQ-PARTICIPANT;DELEGATED-FROM="MAILTO:bob@host.com"
+      ;PARTSTAT=ACCEPTED;CN=Jane Doe:MAILTO:jdoe@host1.com
+
+   The following is an example of this property with a URI to the
+   directory information associated with the attendee:
+
+     ATTENDEE;CN=John Smith;DIR="ldap://host.com:6666/o=eDABC%
+      20Industries,c=3DUS??(cn=3DBJim%20Dolittle)":MAILTO:jimdo@
+      host1.com
+
+   The following is an example of this property with "delegatee" and
+   "delegator" information for an event:
+
+     ORGANIZER;CN=John Smith:MAILTO:jsmith@host.com
+     ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=TENTATIVE;DELEGATED-FROM=
+      "MAILTO:iamboss@host2.com";CN=Henry Cabot:MAILTO:hcabot@
+      host2.com
+     ATTENDEE;ROLE=NON-PARTICIPANT;PARTSTAT=DELEGATED;DELEGATED-TO=
+      "MAILTO:hcabot@host2.com";CN=The Big Cheese:MAILTO:iamboss
+      @host2.com
+     ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=Jane Doe
+      :MAILTO:jdoe@host1.com
+
+   Example: The following is an example of this property's use when
+   another calendar user is acting on behalf of the "Attendee":
+
+     ATTENDEE;SENT-BY=MAILTO:jan_doe@host1.com;CN=John Smith:MAILTO:
+      jsmith@host1.com
+
+4.8.4.2 Contact
+
+   Property Name: CONTACT
+
+   Purpose: The property is used to represent contact information or
+   alternately a reference to contact information associated with the
+   calendar component.
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard, alternate text representation and
+   language property parameters can be specified on this property.
+
+   Conformance: The property can be specified in a "VEVENT", "VTODO",
+   "VJOURNAL" or "VFREEBUSY" calendar component.
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 104]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Description: The property value consists of textual contact
+   information. An alternative representation for the property value can
+   also be specified that refers to a URI pointing to an alternate form,
+   such as a vCard [RFC 2426], for the contact information.
+
+   Format Definition: The property is defined by the following notation:
+
+     contact    = "CONTACT" contparam ":" text CRLF
+
+     contparam  = *(
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                (";" altrepparam) / (";" languageparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+   Example: The following is an example of this property referencing
+   textual contact information:
+
+     CONTACT:Jim Dolittle\, ABC Industries\, +1-919-555-1234
+
+   The following is an example of this property with an alternate
+   representation of a LDAP URI to a directory entry containing the
+   contact information:
+
+     CONTACT;ALTREP="ldap://host.com:6666/o=3DABC%20Industries\,
+      c=3DUS??(cn=3DBJim%20Dolittle)":Jim Dolittle\, ABC Industries\,
+      +1-919-555-1234
+
+   The following is an example of this property with an alternate
+   representation of a MIME body part containing the contact
+   information, such as a vCard [RFC 2426] embedded in a [MIME-DIR]
+   content-type:
+
+     CONTACT;ALTREP="CID=<part3.msg970930T083000SILVER@host.com>":Jim
+       Dolittle\, ABC Industries\, +1-919-555-1234
+
+   The following is an example of this property referencing a network
+   resource, such as a vCard [RFC 2426] object containing the contact
+   information:
+
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 105]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     CONTACT;ALTREP="http://host.com/pdi/jdoe.vcf":Jim
+       Dolittle\, ABC Industries\, +1-919-555-1234
+
+4.8.4.3 Organizer
+
+   Property Name: ORGANIZER
+
+   Purpose: The property defines the organizer for a calendar component.
+
+   Value Type: CAL-ADDRESS
+
+   Property Parameters: Non-standard, language, common name, directory
+   entry reference, sent by property parameters can be specified on this
+   property.
+
+   Conformance: This property MUST be specified in an iCalendar object
+   that specifies a group scheduled calendar entity. This property MUST
+   be specified in an iCalendar object that specifies the publication of
+   a calendar user's busy time. This property MUST NOT be specified in
+   an iCalendar object that specifies only a time zone definition or
+   that defines calendar entities that are not group scheduled entities,
+   but are entities only on a single user's calendar.
+
+   Description: The property is specified within the "VEVENT", "VTODO",
+   "VJOURNAL calendar components to specify the organizer of a group
+   scheduled calendar entity. The property is specified within the
+   "VFREEBUSY" calendar component to specify the calendar user
+   requesting the free or busy time. When publishing a "VFREEBUSY"
+   calendar component, the property is used to specify the calendar that
+   the published busy time came from.
+
+   The property has the property parameters CN, for specifying the
+   common or display name associated with the "Organizer", DIR, for
+   specifying a pointer to the directory information associated with the
+   "Organizer", SENT-BY, for specifying another calendar user that is
+   acting on behalf of the "Organizer". The non-standard parameters may
+   also be specified on this property. If the LANGUAGE property
+   parameter is specified, the identified language applies to the CN
+   parameter value.
+
+   Format Definition: The property is defined by the following notation:
+
+     organizer  = "ORGANIZER" orgparam ":"
+                  cal-address CRLF
+
+     orgparam   = *(
+
+                ; the following are optional,
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 106]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+                ; but MUST NOT occur more than once
+
+                (";" cnparam) / (";" dirparam) / (";" sentbyparam) /
+                (";" languageparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+   Example: The following is an example of this property:
+
+     ORGANIZER;CN=John Smith:MAILTO:jsmith@host1.com
+
+   The following is an example of this property with a pointer to the
+   directory information associated with the organizer:
+
+     ORGANIZER;CN=JohnSmith;DIR="ldap://host.com:6666/o=3DDC%20Associ
+      ates,c=3DUS??(cn=3DJohn%20Smith)":MAILTO:jsmith@host1.com
+
+   The following is an example of this property used by another calendar
+   user who is acting on behalf of the organizer, with responses
+   intended to be sent back to the organizer, not the other calendar
+   user:
+
+     ORGANIZER;SENT-BY="MAILTO:jane_doe@host.com":
+      MAILTO:jsmith@host1.com
+
+4.8.4.4 Recurrence ID
+
+   Property Name: RECURRENCE-ID
+
+   Purpose: This property is used in conjunction with the "UID" and
+   "SEQUENCE" property to identify a specific instance of a recurring
+   "VEVENT", "VTODO" or "VJOURNAL" calendar component. The property
+   value is the effective value of the "DTSTART" property of the
+   recurrence instance.
+
+   Value Type: The default value type for this property is DATE-TIME.
+   The time format can be any of the valid forms defined for a DATE-TIME
+   value type. See DATE-TIME value type definition for specific
+   interpretations of the various forms. The value type can be set to
+   DATE.
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 107]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Property Parameters: Non-standard property, value data type, time
+   zone identifier and recurrence identifier range parameters can be
+   specified on this property.
+
+   Conformance: This property can be specified in an iCalendar object
+   containing a recurring calendar component.
+
+   Description: The full range of calendar components specified by a
+   recurrence set is referenced by referring to just the "UID" property
+   value corresponding to the calendar component. The "RECURRENCE-ID"
+   property allows the reference to an individual instance within the
+   recurrence set.
+
+   If the value of the "DTSTART" property is a DATE type value, then the
+   value MUST be the calendar date for the recurrence instance.
+
+   The date/time value is set to the time when the original recurrence
+   instance would occur; meaning that if the intent is to change a
+   Friday meeting to Thursday, the date/time is still set to the
+   original Friday meeting.
+
+   The "RECURRENCE-ID" property is used in conjunction with the "UID"
+   and "SEQUENCE" property to identify a particular instance of a
+   recurring event, to-do or journal. For a given pair of "UID" and
+   "SEQUENCE" property values, the "RECURRENCE-ID" value for a
+   recurrence instance is fixed. When the definition of the recurrence
+   set for a calendar component changes, and hence the "SEQUENCE"
+   property value changes, the "RECURRENCE-ID" for a given recurrence
+   instance might also change.The "RANGE" parameter is used to specify
+   the effective range of recurrence instances from the instance
+   specified by the "RECURRENCE-ID" property value. The default value
+   for the range parameter is the single recurrence instance only. The
+   value can also be "THISANDPRIOR" to indicate a range defined by the
+   given recurrence instance and all prior instances or the value can be
+   "THISANDFUTURE" to indicate a range defined by the given recurrence
+   instance and all subsequent instances.
+
+   Format Definition: The property is defined by the following notation:
+
+     recurid    = "RECURRENCE-ID" ridparam ":" ridval CRLF
+
+     ridparam   = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                (";" "VALUE" "=" ("DATE-TIME" / "DATE)) /
+                (";" tzidparam) / (";" rangeparam) /
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 108]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+     ridval     = date-time / date
+     ;Value MUST match value type
+
+   Example: The following are examples of this property:
+
+     RECURRENCE-ID;VALUE=DATE:19960401
+
+     RECURRENCE-ID;RANGE=THISANDFUTURE:19960120T120000Z
+
+4.8.4.5 Related To
+
+   Property Name: RELATED-TO
+
+   Purpose: The property is used to represent a relationship or
+   reference between one calendar component and another.
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard and relationship type property
+   parameters can be specified on this property.
+
+   Conformance: The property can be specified one or more times in the
+   "VEVENT", "VTODO" or "VJOURNAL" calendar components.
+
+   Description: The property value consists of the persistent, globally
+   unique identifier of another calendar component. This value would be
+   represented in a calendar component by the "UID" property.
+
+   By default, the property value points to another calendar component
+   that has a PARENT relationship to the referencing object. The
+   "RELTYPE" property parameter is used to either explicitly state the
+   default PARENT relationship type to the referenced calendar component
+   or to override the default PARENT relationship type and specify
+   either a CHILD or SIBLING relationship. The PARENT relationship
+   indicates that the calendar component is a subordinate of the
+   referenced calendar component. The CHILD relationship indicates that
+   the calendar component is a superior of the referenced calendar
+   component. The SIBLING relationship indicates that the calendar
+   component is a peer of the referenced calendar component.
+
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 109]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Changes to a calendar component referenced by this property can have
+   an implicit impact on the related calendar component. For example, if
+   a group event changes its start or end date or time, then the
+   related, dependent events will need to have their start and end dates
+   changed in a corresponding way. Similarly, if a PARENT calendar
+   component is canceled or deleted, then there is an implied impact to
+   the related CHILD calendar components. This property is intended only
+   to provide information on the relationship of calendar components. It
+   is up to the target calendar system to maintain any property
+   implications of this relationship.
+
+   Format Definition: The property is defined by the following notation:
+
+     related    = "RELATED-TO" [relparam] ":" text CRLF
+
+     relparam   = *(
+
+                ; the following is optional,
+                ; but MUST NOT occur more than once
+
+                (";" reltypeparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparm)
+
+                )
+
+   The following is an example of this property:
+
+     RELATED-TO:<jsmith.part7.19960817T083000.xyzMail@host3.com>
+
+     RELATED-TO:<19960401-080045-4000F192713-0052@host1.com>
+
+4.8.4.6 Uniform Resource Locator
+
+   Property Name: URL
+
+   Purpose: This property defines a Uniform Resource Locator (URL)
+   associated with the iCalendar object.
+
+   Value Type: URI
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 110]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Conformance: This property can be specified once in the "VEVENT",
+   "VTODO", "VJOURNAL" or "VFREEBUSY" calendar components.
+
+   Description: This property may be used in a calendar component to
+   convey a location where a more dynamic rendition of the calendar
+   information associated with the calendar component can be found. This
+   memo does not attempt to standardize the form of the URI, nor the
+   format of the resource pointed to by the property value. If the URL
+   property and Content-Location MIME header are both specified, they
+   MUST point to the same resource.
+
+   Format Definition: The property is defined by the following notation:
+
+     url        = "URL" urlparam ":" uri CRLF
+
+     urlparam   = *(";" xparam)
+
+   Example: The following is an example of this property:
+
+     URL:http://abc.com/pub/calendars/jsmith/mytime.ics
+
+4.8.4.7 Unique Identifier
+
+   Property Name: UID
+
+   Purpose: This property defines the persistent, globally unique
+   identifier for the calendar component.
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: The property MUST be specified in the "VEVENT", "VTODO",
+   "VJOURNAL" or "VFREEBUSY" calendar components.
+
+   Description: The UID itself MUST be a globally unique identifier. The
+   generator of the identifier MUST guarantee that the identifier is
+   unique. There are several algorithms that can be used to accomplish
+   this. The identifier is RECOMMENDED to be the identical syntax to the
+   [RFC 822] addr-spec. A good method to assure uniqueness is to put the
+   domain name or a domain literal IP address of the host on which the
+   identifier was created on the right hand side of the "@", and on the
+   left hand side, put a combination of the current calendar date and
+   time of day (i.e., formatted in as a DATE-TIME value) along with some
+   other currently unique (perhaps sequential) identifier available on
+   the system (for example, a process id number). Using a date/time
+   value on the left hand side and a domain name or domain literal on
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 111]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   the right hand side makes it possible to guarantee uniqueness since
+   no two hosts should be using the same domain name or IP address at
+   the same time. Though other algorithms will work, it is RECOMMENDED
+   that the right hand side contain some domain identifier (either of
+   the host itself or otherwise) such that the generator of the message
+   identifier can guarantee the uniqueness of the left hand side within
+   the scope of that domain.
+
+   This is the method for correlating scheduling messages with the
+   referenced "VEVENT", "VTODO", or "VJOURNAL" calendar component.
+
+   The full range of calendar components specified by a recurrence set
+   is referenced by referring to just the "UID" property value
+   corresponding to the calendar component. The "RECURRENCE-ID" property
+   allows the reference to an individual instance within the recurrence
+   set.
+
+   This property is an important method for group scheduling
+   applications to match requests with later replies, modifications or
+   deletion requests. Calendaring and scheduling applications MUST
+   generate this property in "VEVENT", "VTODO" and "VJOURNAL" calendar
+   components to assure interoperability with other group scheduling
+   applications. This identifier is created by the calendar system that
+   generates an iCalendar object.
+
+   Implementations MUST be able to receive and persist values of at
+   least 255 characters for this property.
+
+   Format Definition: The property is defined by the following notation:
+
+     uid        = "UID" uidparam ":" text CRLF
+
+     uidparam   = *(";" xparam)
+
+   Example: The following is an example of this property:
+
+     UID:19960401T080045Z-4000F192713-0052@host1.com
+
+4.8.5 Recurrence Component Properties
+
+   The following properties specify recurrence information in calendar
+   components.
+
+4.8.5.1 Exception Date/Times
+
+   Property Name: EXDATE
+
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 112]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Purpose: This property defines the list of date/time exceptions for a
+   recurring calendar component.
+
+   Value Type: The default value type for this property is DATE-TIME.
+   The value type can be set to DATE.
+
+   Property Parameters: Non-standard, value data type and time zone
+   identifier property parameters can be specified on this property.
+
+   Conformance: This property can be specified in an iCalendar object
+   that includes a recurring calendar component.
+
+   Description: The exception dates, if specified, are used in computing
+   the recurrence set. The recurrence set is the complete set of
+   recurrence instances for a calendar component. The recurrence set is
+   generated by considering the initial "DTSTART" property along with
+   the "RRULE", "RDATE", "EXDATE" and "EXRULE" properties contained
+   within the iCalendar object. The "DTSTART" property defines the first
+   instance in the recurrence set. Multiple instances of the "RRULE" and
+   "EXRULE" properties can also be specified to define more
+   sophisticated recurrence sets. The final recurrence set is generated
+   by gathering all of the start date-times generated by any of the
+   specified "RRULE" and "RDATE" properties, and then excluding any
+   start date and times which fall within the union of start date and
+   times generated by any specified "EXRULE" and "EXDATE" properties.
+   This implies that start date and times within exclusion related
+   properties (i.e., "EXDATE" and "EXRULE") take precedence over those
+   specified by inclusion properties (i.e., "RDATE" and "RRULE"). Where
+   duplicate instances are generated by the "RRULE" and "RDATE"
+   properties, only one recurrence is considered. Duplicate instances
+   are ignored.
+
+   The "EXDATE" property can be used to exclude the value specified in
+   "DTSTART". However, in such cases the original "DTSTART" date MUST
+   still be maintained by the calendaring and scheduling system because
+   the original "DTSTART" value has inherent usage dependencies by other
+   properties such as the "RECURRENCE-ID".
+
+   Format Definition: The property is defined by the following notation:
+
+     exdate     = "EXDATE" exdtparam ":" exdtval *("," exdtval) CRLF
+
+     exdtparam  = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                (";" "VALUE" "=" ("DATE-TIME" / "DATE")) /
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 113]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+                (";" tzidparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+     exdtval    = date-time / date
+     ;Value MUST match value type
+
+   Example: The following is an example of this property:
+
+     EXDATE:19960402T010000Z,19960403T010000Z,19960404T010000Z
+
+4.8.5.2 Exception Rule
+
+   Property Name: EXRULE
+
+   Purpose: This property defines a rule or repeating pattern for an
+   exception to a recurrence set.
+
+   Value Type: RECUR
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: This property can be specified in "VEVENT", "VTODO" or
+   "VJOURNAL" calendar components.
+
+   Description: The exception rule, if specified, is used in computing
+   the recurrence set. The recurrence set is the complete set of
+   recurrence instances for a calendar component. The recurrence set is
+   generated by considering the initial "DTSTART" property along with
+   the "RRULE", "RDATE", "EXDATE" and "EXRULE" properties contained
+   within the iCalendar object. The "DTSTART" defines the first instance
+   in the recurrence set. Multiple instances of the "RRULE" and "EXRULE"
+   properties can also be specified to define more sophisticated
+   recurrence sets. The final recurrence set is generated by gathering
+   all of the start date-times generated by any of the specified "RRULE"
+   and "RDATE" properties, and excluding any start date and times which
+   fall within the union of start date and times generated by any
+   specified "EXRULE" and "EXDATE" properties. This implies that start
+   date and times within exclusion related properties (i.e., "EXDATE"
+   and "EXRULE") take precedence over those specified by inclusion
+
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 114]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   properties (i.e., "RDATE" and "RRULE"). Where duplicate instances are
+   generated by the "RRULE" and "RDATE" properties, only one recurrence
+   is considered. Duplicate instances are ignored.
+
+   The "EXRULE" property can be used to exclude the value specified in
+   "DTSTART". However, in such cases the original "DTSTART" date MUST
+   still be maintained by the calendaring and scheduling system because
+   the original "DTSTART" value has inherent usage dependencies by other
+   properties such as the "RECURRENCE-ID".
+
+   Format Definition: The property is defined by the following notation:
+
+     exrule     = "EXRULE" exrparam ":" recur CRLF
+
+     exrparam   = *(";" xparam)
+
+   Example: The following are examples of this property. Except every
+   other week, on Tuesday and Thursday for 4 occurrences:
+
+     EXRULE:FREQ=WEEKLY;COUNT=4;INTERVAL=2;BYDAY=TU,TH
+
+   Except daily for 10 occurrences:
+
+     EXRULE:FREQ=DAILY;COUNT=10
+
+   Except yearly in June and July for 8 occurrences:
+
+     EXRULE:FREQ=YEARLY;COUNT=8;BYMONTH=6,7
+
+4.8.5.3 Recurrence Date/Times
+
+   Property Name: RDATE
+
+   Purpose: This property defines the list of date/times for a
+   recurrence set.
+
+   Value Type: The default value type for this property is DATE-TIME.
+   The value type can be set to DATE or PERIOD.
+
+   Property Parameters: Non-standard, value data type and time zone
+   identifier property parameters can be specified on this property.
+
+   Conformance: The property can be specified in "VEVENT", "VTODO",
+   "VJOURNAL" or "VTIMEZONE" calendar components.
+
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 115]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Description: This property can appear along with the "RRULE" property
+   to define an aggregate set of repeating occurrences. When they both
+   appear in an iCalendar object, the recurring events are defined by
+   the union of occurrences defined by both the "RDATE" and "RRULE".
+
+   The recurrence dates, if specified, are used in computing the
+   recurrence set. The recurrence set is the complete set of recurrence
+   instances for a calendar component. The recurrence set is generated
+   by considering the initial "DTSTART" property along with the "RRULE",
+   "RDATE", "EXDATE" and "EXRULE" properties contained within the
+   iCalendar object. The "DTSTART" property defines the first instance
+   in the recurrence set. Multiple instances of the "RRULE" and "EXRULE"
+   properties can also be specified to define more sophisticated
+   recurrence sets. The final recurrence set is generated by gathering
+   all of the start date/times generated by any of the specified "RRULE"
+   and "RDATE" properties, and excluding any start date/times which fall
+   within the union of start date/times generated by any specified
+   "EXRULE" and "EXDATE" properties. This implies that start date/times
+   within exclusion related properties (i.e., "EXDATE" and "EXRULE")
+   take precedence over those specified by inclusion properties (i.e.,
+   "RDATE" and "RRULE"). Where duplicate instances are generated by the
+   "RRULE" and "RDATE" properties, only one recurrence is considered.
+   Duplicate instances are ignored.
+
+   Format Definition: The property is defined by the following notation:
+
+     rdate      = "RDATE" rdtparam ":" rdtval *("," rdtval) CRLF
+
+     rdtparam   = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                (";" "VALUE" "=" ("DATE-TIME" / "DATE" / "PERIOD")) /
+                (";" tzidparam) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+     rdtval     = date-time / date / period
+     ;Value MUST match value type
+
+   Example: The following are examples of this property:
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 116]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     RDATE:19970714T123000Z
+
+     RDATE;TZID=US-EASTERN:19970714T083000
+
+     RDATE;VALUE=PERIOD:19960403T020000Z/19960403T040000Z,
+      19960404T010000Z/PT3H
+
+     RDATE;VALUE=DATE:19970101,19970120,19970217,19970421
+      19970526,19970704,19970901,19971014,19971128,19971129,19971225
+
+4.8.5.4 Recurrence Rule
+
+   Property Name: RRULE
+
+   Purpose: This property defines a rule or repeating pattern for
+   recurring events, to-dos, or time zone definitions.
+
+   Value Type: RECUR
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: This property can be specified one or more times in
+   recurring "VEVENT", "VTODO" and "VJOURNAL" calendar components. It
+   can also be specified once in each STANDARD or DAYLIGHT sub-component
+   of the "VTIMEZONE" calendar component.
+
+   Description: The recurrence rule, if specified, is used in computing
+   the recurrence set. The recurrence set is the complete set of
+   recurrence instances for a calendar component. The recurrence set is
+   generated by considering the initial "DTSTART" property along with
+   the "RRULE", "RDATE", "EXDATE" and "EXRULE" properties contained
+   within the iCalendar object. The "DTSTART" property defines the first
+   instance in the recurrence set. Multiple instances of the "RRULE" and
+   "EXRULE" properties can also be specified to define more
+   sophisticated recurrence sets. The final recurrence set is generated
+   by gathering all of the start date/times generated by any of the
+   specified "RRULE" and "RDATE" properties, and excluding any start
+   date/times which fall within the union of start date/times generated
+   by any specified "EXRULE" and "EXDATE" properties. This implies that
+   start date/times within exclusion related properties (i.e., "EXDATE"
+   and "EXRULE") take precedence over those specified by inclusion
+   properties (i.e., "RDATE" and "RRULE"). Where duplicate instances are
+   generated by the "RRULE" and "RDATE" properties, only one recurrence
+   is considered. Duplicate instances are ignored.
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 117]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   The "DTSTART" and "DTEND" property pair or "DTSTART" and "DURATION"
+   property pair, specified within the iCalendar object defines the
+   first instance of the recurrence. When used with a recurrence rule,
+   the "DTSTART" and "DTEND" properties MUST be specified in local time
+   and the appropriate set of "VTIMEZONE" calendar components MUST be
+   included. For detail on the usage of the "VTIMEZONE" calendar
+   component, see the "VTIMEZONE" calendar component definition.
+
+   Any duration associated with the iCalendar object applies to all
+   members of the generated recurrence set. Any modified duration for
+   specific recurrences MUST be explicitly specified using the "RDATE"
+   property.
+
+   Format Definition: This property is defined by the following
+   notation:
+
+     rrule      = "RRULE" rrulparam ":" recur CRLF
+
+     rrulparam  = *(";" xparam)
+
+   Example: All examples assume the Eastern United States time zone.
+
+   Daily for 10 occurrences:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=DAILY;COUNT=10
+
+     ==> (1997 9:00 AM EDT)September 2-11
+
+   Daily until December 24, 1997:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=DAILY;UNTIL=19971224T000000Z
+
+     ==> (1997 9:00 AM EDT)September 2-30;October 1-25
+         (1997 9:00 AM EST)October 26-31;November 1-30;December 1-23
+
+   Every other day - forever:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=DAILY;INTERVAL=2
+     ==> (1997 9:00 AM EDT)September2,4,6,8...24,26,28,30;
+          October 2,4,6...20,22,24
+         (1997 9:00 AM EST)October 26,28,30;November 1,3,5,7...25,27,29;
+          Dec 1,3,...
+
+   Every 10 days, 5 occurrences:
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 118]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5
+
+     ==> (1997 9:00 AM EDT)September 2,12,22;October 2,12
+
+   Everyday in January, for 3 years:
+
+     DTSTART;TZID=US-Eastern:19980101T090000
+     RRULE:FREQ=YEARLY;UNTIL=20000131T090000Z;
+      BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA
+     or
+     RRULE:FREQ=DAILY;UNTIL=20000131T090000Z;BYMONTH=1
+
+     ==> (1998 9:00 AM EDT)January 1-31
+         (1999 9:00 AM EDT)January 1-31
+         (2000 9:00 AM EDT)January 1-31
+
+   Weekly for 10 occurrences
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=WEEKLY;COUNT=10
+
+     ==> (1997 9:00 AM EDT)September 2,9,16,23,30;October 7,14,21
+         (1997 9:00 AM EST)October 28;November 4
+
+   Weekly until December 24, 1997
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=WEEKLY;UNTIL=19971224T000000Z
+
+     ==> (1997 9:00 AM EDT)September 2,9,16,23,30;October 7,14,21
+         (1997 9:00 AM EST)October 28;November 4,11,18,25;
+                           December 2,9,16,23
+   Every other week - forever:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=WEEKLY;INTERVAL=2;WKST=SU
+
+     ==> (1997 9:00 AM EDT)September 2,16,30;October 14
+         (1997 9:00 AM EST)October 28;November 11,25;December 9,23
+         (1998 9:00 AM EST)January 6,20;February
+     ...
+
+   Weekly on Tuesday and Thursday for 5 weeks:
+
+    DTSTART;TZID=US-Eastern:19970902T090000
+    RRULE:FREQ=WEEKLY;UNTIL=19971007T000000Z;WKST=SU;BYDAY=TU,TH
+    or
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 119]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+    RRULE:FREQ=WEEKLY;COUNT=10;WKST=SU;BYDAY=TU,TH
+
+    ==> (1997 9:00 AM EDT)September 2,4,9,11,16,18,23,25,30;October 2
+
+   Every other week on Monday, Wednesday and Friday until December 24,
+   1997, but starting on Tuesday, September 2, 1997:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=WEEKLY;INTERVAL=2;UNTIL=19971224T000000Z;WKST=SU;
+      BYDAY=MO,WE,FR
+     ==> (1997 9:00 AM EDT)September 2,3,5,15,17,19,29;October
+     1,3,13,15,17
+         (1997 9:00 AM EST)October 27,29,31;November 10,12,14,24,26,28;
+                           December 8,10,12,22
+
+   Every other week on Tuesday and Thursday, for 8 occurrences:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=8;WKST=SU;BYDAY=TU,TH
+
+     ==> (1997 9:00 AM EDT)September 2,4,16,18,30;October 2,14,16
+
+   Monthly on the 1st Friday for ten occurrences:
+
+     DTSTART;TZID=US-Eastern:19970905T090000
+     RRULE:FREQ=MONTHLY;COUNT=10;BYDAY=1FR
+
+     ==> (1997 9:00 AM EDT)September 5;October 3
+         (1997 9:00 AM EST)November 7;Dec 5
+         (1998 9:00 AM EST)January 2;February 6;March 6;April 3
+         (1998 9:00 AM EDT)May 1;June 5
+
+   Monthly on the 1st Friday until December 24, 1997:
+
+     DTSTART;TZID=US-Eastern:19970905T090000
+     RRULE:FREQ=MONTHLY;UNTIL=19971224T000000Z;BYDAY=1FR
+
+     ==> (1997 9:00 AM EDT)September 5;October 3
+         (1997 9:00 AM EST)November 7;December 5
+
+   Every other month on the 1st and last Sunday of the month for 10
+   occurrences:
+
+     DTSTART;TZID=US-Eastern:19970907T090000
+     RRULE:FREQ=MONTHLY;INTERVAL=2;COUNT=10;BYDAY=1SU,-1SU
+
+     ==> (1997 9:00 AM EDT)September 7,28
+         (1997 9:00 AM EST)November 2,30
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 120]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+         (1998 9:00 AM EST)January 4,25;March 1,29
+         (1998 9:00 AM EDT)May 3,31
+
+   Monthly on the second to last Monday of the month for 6 months:
+
+     DTSTART;TZID=US-Eastern:19970922T090000
+     RRULE:FREQ=MONTHLY;COUNT=6;BYDAY=-2MO
+
+     ==> (1997 9:00 AM EDT)September 22;October 20
+         (1997 9:00 AM EST)November 17;December 22
+         (1998 9:00 AM EST)January 19;February 16
+
+   Monthly on the third to the last day of the month, forever:
+
+     DTSTART;TZID=US-Eastern:19970928T090000
+     RRULE:FREQ=MONTHLY;BYMONTHDAY=-3
+
+     ==> (1997 9:00 AM EDT)September 28
+         (1997 9:00 AM EST)October 29;November 28;December 29
+         (1998 9:00 AM EST)January 29;February 26
+     ...
+
+   Monthly on the 2nd and 15th of the month for 10 occurrences:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=MONTHLY;COUNT=10;BYMONTHDAY=2,15
+
+     ==> (1997 9:00 AM EDT)September 2,15;October 2,15
+         (1997 9:00 AM EST)November 2,15;December 2,15
+         (1998 9:00 AM EST)January 2,15
+
+   Monthly on the first and last day of the month for 10 occurrences:
+
+     DTSTART;TZID=US-Eastern:19970930T090000
+     RRULE:FREQ=MONTHLY;COUNT=10;BYMONTHDAY=1,-1
+
+     ==> (1997 9:00 AM EDT)September 30;October 1
+         (1997 9:00 AM EST)October 31;November 1,30;December 1,31
+         (1998 9:00 AM EST)January 1,31;February 1
+
+   Every 18 months on the 10th thru 15th of the month for 10
+   occurrences:
+
+     DTSTART;TZID=US-Eastern:19970910T090000
+     RRULE:FREQ=MONTHLY;INTERVAL=18;COUNT=10;BYMONTHDAY=10,11,12,13,14,
+      15
+
+     ==> (1997 9:00 AM EDT)September 10,11,12,13,14,15
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 121]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+         (1999 9:00 AM EST)March 10,11,12,13
+
+   Every Tuesday, every other month:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=MONTHLY;INTERVAL=2;BYDAY=TU
+
+     ==> (1997 9:00 AM EDT)September 2,9,16,23,30
+         (1997 9:00 AM EST)November 4,11,18,25
+         (1998 9:00 AM EST)January 6,13,20,27;March 3,10,17,24,31
+     ...
+
+   Yearly in June and July for 10 occurrences:
+
+     DTSTART;TZID=US-Eastern:19970610T090000
+     RRULE:FREQ=YEARLY;COUNT=10;BYMONTH=6,7
+     ==> (1997 9:00 AM EDT)June 10;July 10
+         (1998 9:00 AM EDT)June 10;July 10
+         (1999 9:00 AM EDT)June 10;July 10
+         (2000 9:00 AM EDT)June 10;July 10
+         (2001 9:00 AM EDT)June 10;July 10
+     Note: Since none of the BYDAY, BYMONTHDAY or BYYEARDAY components
+     are specified, the day is gotten from DTSTART
+
+   Every other year on January, February, and March for 10 occurrences:
+
+     DTSTART;TZID=US-Eastern:19970310T090000
+     RRULE:FREQ=YEARLY;INTERVAL=2;COUNT=10;BYMONTH=1,2,3
+
+     ==> (1997 9:00 AM EST)March 10
+         (1999 9:00 AM EST)January 10;February 10;March 10
+         (2001 9:00 AM EST)January 10;February 10;March 10
+         (2003 9:00 AM EST)January 10;February 10;March 10
+
+   Every 3rd year on the 1st, 100th and 200th day for 10 occurrences:
+
+     DTSTART;TZID=US-Eastern:19970101T090000
+     RRULE:FREQ=YEARLY;INTERVAL=3;COUNT=10;BYYEARDAY=1,100,200
+
+     ==> (1997 9:00 AM EST)January 1
+         (1997 9:00 AM EDT)April 10;July 19
+         (2000 9:00 AM EST)January 1
+         (2000 9:00 AM EDT)April 9;July 18
+         (2003 9:00 AM EST)January 1
+         (2003 9:00 AM EDT)April 10;July 19
+         (2006 9:00 AM EST)January 1
+
+   Every 20th Monday of the year, forever:
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 122]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     DTSTART;TZID=US-Eastern:19970519T090000
+     RRULE:FREQ=YEARLY;BYDAY=20MO
+
+     ==> (1997 9:00 AM EDT)May 19
+         (1998 9:00 AM EDT)May 18
+         (1999 9:00 AM EDT)May 17
+     ...
+
+   Monday of week number 20 (where the default start of the week is
+   Monday), forever:
+
+     DTSTART;TZID=US-Eastern:19970512T090000
+     RRULE:FREQ=YEARLY;BYWEEKNO=20;BYDAY=MO
+
+     ==> (1997 9:00 AM EDT)May 12
+         (1998 9:00 AM EDT)May 11
+         (1999 9:00 AM EDT)May 17
+     ...
+
+   Every Thursday in March, forever:
+
+     DTSTART;TZID=US-Eastern:19970313T090000
+     RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=TH
+
+     ==> (1997 9:00 AM EST)March 13,20,27
+         (1998 9:00 AM EST)March 5,12,19,26
+         (1999 9:00 AM EST)March 4,11,18,25
+     ...
+
+   Every Thursday, but only during June, July, and August, forever:
+
+     DTSTART;TZID=US-Eastern:19970605T090000
+     RRULE:FREQ=YEARLY;BYDAY=TH;BYMONTH=6,7,8
+
+     ==> (1997 9:00 AM EDT)June 5,12,19,26;July 3,10,17,24,31;
+                       August 7,14,21,28
+         (1998 9:00 AM EDT)June 4,11,18,25;July 2,9,16,23,30;
+                       August 6,13,20,27
+         (1999 9:00 AM EDT)June 3,10,17,24;July 1,8,15,22,29;
+                       August 5,12,19,26
+     ...
+
+   Every Friday the 13th, forever:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     EXDATE;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=MONTHLY;BYDAY=FR;BYMONTHDAY=13
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 123]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     ==> (1998 9:00 AM EST)February 13;March 13;November 13
+         (1999 9:00 AM EDT)August 13
+         (2000 9:00 AM EDT)October 13
+     ...
+
+   The first Saturday that follows the first Sunday of the month,
+    forever:
+
+     DTSTART;TZID=US-Eastern:19970913T090000
+     RRULE:FREQ=MONTHLY;BYDAY=SA;BYMONTHDAY=7,8,9,10,11,12,13
+
+     ==> (1997 9:00 AM EDT)September 13;October 11
+         (1997 9:00 AM EST)November 8;December 13
+         (1998 9:00 AM EST)January 10;February 7;March 7
+         (1998 9:00 AM EDT)April 11;May 9;June 13...
+     ...
+
+   Every four years, the first Tuesday after a Monday in November,
+   forever (U.S. Presidential Election day):
+
+     DTSTART;TZID=US-Eastern:19961105T090000
+     RRULE:FREQ=YEARLY;INTERVAL=4;BYMONTH=11;BYDAY=TU;BYMONTHDAY=2,3,4,
+      5,6,7,8
+
+     ==> (1996 9:00 AM EST)November 5
+         (2000 9:00 AM EST)November 7
+         (2004 9:00 AM EST)November 2
+     ...
+
+   The 3rd instance into the month of one of Tuesday, Wednesday or
+   Thursday, for the next 3 months:
+
+     DTSTART;TZID=US-Eastern:19970904T090000
+     RRULE:FREQ=MONTHLY;COUNT=3;BYDAY=TU,WE,TH;BYSETPOS=3
+
+     ==> (1997 9:00 AM EDT)September 4;October 7
+         (1997 9:00 AM EST)November 6
+
+   The 2nd to last weekday of the month:
+
+     DTSTART;TZID=US-Eastern:19970929T090000
+     RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-2
+
+     ==> (1997 9:00 AM EDT)September 29
+         (1997 9:00 AM EST)October 30;November 27;December 30
+         (1998 9:00 AM EST)January 29;February 26;March 30
+     ...
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 124]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Every 3 hours from 9:00 AM to 5:00 PM on a specific day:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=HOURLY;INTERVAL=3;UNTIL=19970902T170000Z
+
+     ==> (September 2, 1997 EDT)09:00,12:00,15:00
+
+   Every 15 minutes for 6 occurrences:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=MINUTELY;INTERVAL=15;COUNT=6
+
+     ==> (September 2, 1997 EDT)09:00,09:15,09:30,09:45,10:00,10:15
+
+   Every hour and a half for 4 occurrences:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=MINUTELY;INTERVAL=90;COUNT=4
+
+     ==> (September 2, 1997 EDT)09:00,10:30;12:00;13:30
+
+   Every 20 minutes from 9:00 AM to 4:40 PM every day:
+
+     DTSTART;TZID=US-Eastern:19970902T090000
+     RRULE:FREQ=DAILY;BYHOUR=9,10,11,12,13,14,15,16;BYMINUTE=0,20,40
+     or
+     RRULE:FREQ=MINUTELY;INTERVAL=20;BYHOUR=9,10,11,12,13,14,15,16
+
+     ==> (September 2, 1997 EDT)9:00,9:20,9:40,10:00,10:20,
+                                ... 16:00,16:20,16:40
+         (September 3, 1997 EDT)9:00,9:20,9:40,10:00,10:20,
+                               ...16:00,16:20,16:40
+     ...
+
+   An example where the days generated makes a difference because of
+   WKST:
+
+     DTSTART;TZID=US-Eastern:19970805T090000
+     RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU;WKST=MO
+
+     ==> (1997 EDT)Aug 5,10,19,24
+
+     changing only WKST from MO to SU, yields different results...
+
+     DTSTART;TZID=US-Eastern:19970805T090000
+     RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU;WKST=SU
+     ==> (1997 EDT)August 5,17,19,31
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 125]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+4.8.6 Alarm Component Properties
+
+   The following properties specify alarm information in calendar
+   components.
+
+4.8.6.1 Action
+
+   Property Name: ACTION
+
+   Purpose: This property defines the action to be invoked when an alarm
+   is triggered.
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: This property MUST be specified once in a "VALARM"
+   calendar component.
+
+   Description: Each "VALARM" calendar component has a particular type
+   of action associated with it. This property specifies the type of
+   action
+
+   Format Definition: The property is defined by the following notation:
+
+     action     = "ACTION" actionparam ":" actionvalue CRLF
+
+     actionparam        = *(";" xparam)
+
+     actionvalue        = "AUDIO" / "DISPLAY" / "EMAIL" / "PROCEDURE"
+                        / iana-token / x-name
+
+   Example: The following are examples of this property in a "VALARM"
+   calendar component:
+
+     ACTION:AUDIO
+
+     ACTION:DISPLAY
+
+     ACTION:PROCEDURE
+
+4.8.6.2 Repeat Count
+
+   Property Name: REPEAT
+
+   Purpose: This property defines the number of time the alarm should be
+   repeated, after the initial trigger.
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 126]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Value Type: INTEGER
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: This property can be specified in a "VALARM" calendar
+   component.
+
+   Description: If the alarm triggers more than once, then this property
+   MUST be specified along with the "DURATION" property.
+
+   Format Definition: The property is defined by the following notation:
+
+     repeatcnt  = "REPEAT" repparam ":" integer CRLF
+     ;Default is "0", zero.
+
+     repparam   = *(";" xparam)
+
+   Example: The following is an example of this property for an alarm
+   that repeats 4 additional times with a 5 minute delay after the
+   initial triggering of the alarm:
+
+     REPEAT:4
+     DURATION:PT5M
+
+4.8.6.3 Trigger
+
+   Property Name: TRIGGER
+
+   Purpose: This property specifies when an alarm will trigger.
+
+   Value Type: The default value type is DURATION. The value type can be
+   set to a DATE-TIME value type, in which case the value MUST specify a
+   UTC formatted DATE-TIME value.
+
+   Property Parameters: Non-standard, value data type, time zone
+   identifier or trigger relationship property parameters can be
+   specified on this property. The trigger relationship property
+   parameter MUST only be specified when the value type is DURATION.
+
+   Conformance: This property MUST be specified in the "VALARM" calendar
+   component.
+
+   Description: Within the "VALARM" calendar component, this property
+   defines when the alarm will trigger. The default value type is
+   DURATION, specifying a relative time for the trigger of the alarm.
+   The default duration is relative to the start of an event or to-do
+   that the alarm is associated with. The duration can be explicitly set
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 127]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   to trigger from either the end or the start of the associated event
+   or to-do with the "RELATED" parameter. A value of START will set the
+   alarm to trigger off the start of the associated event or to-do. A
+   value of END will set the alarm to trigger off the end of the
+   associated event or to-do.
+
+   Either a positive or negative duration may be specified for the
+   "TRIGGER" property. An alarm with a positive duration is triggered
+   after the associated start or end of the event or to-do. An alarm
+   with a negative duration is triggered before the associated start or
+   end of the event or to-do.
+
+   The "RELATED" property parameter is not valid if the value type of
+   the property is set to DATE-TIME (i.e., for an absolute date and time
+   alarm trigger). If a value type of DATE-TIME is specified, then the
+   property value MUST be specified in the UTC time format. If an
+   absolute trigger is specified on an alarm for a recurring event or
+   to-do, then the alarm will only trigger for the specified absolute
+   date/time, along with any specified repeating instances.
+
+   If the trigger is set relative to START, then the "DTSTART" property
+   MUST be present in the associated "VEVENT" or "VTODO" calendar
+   component. If an alarm is specified for an event with the trigger set
+   relative to the END, then the "DTEND" property or the "DSTART" and
+   "DURATION' properties MUST be present in the associated "VEVENT"
+   calendar component. If the alarm is specified for a to-do with a
+   trigger set relative to the END, then either the "DUE" property or
+   the "DSTART" and "DURATION' properties MUST be present in the
+   associated "VTODO" calendar component.
+
+   Alarms specified in an event or to-do which is defined in terms of a
+   DATE value type will be triggered relative to 00:00:00 UTC on the
+   specified date. For example, if "DTSTART:19980205, then the duration
+   trigger will be relative to19980205T000000Z.
+
+   Format Definition: The property is defined by the following notation:
+
+     trigger    = "TRIGGER" (trigrel / trigabs)
+
+     trigrel    = *(
+
+                ; the following are optional,
+                ; but MUST NOT occur more than once
+
+                  (";" "VALUE" "=" "DURATION") /
+                  (";" trigrelparam) /
+
+                ; the following is optional,
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 128]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+                ; and MAY occur more than once
+
+                  (";" xparam)
+                  ) ":"  dur-value
+
+     trigabs    = 1*(
+
+                ; the following is REQUIRED,
+                ; but MUST NOT occur more than once
+
+                  (";" "VALUE" "=" "DATE-TIME") /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                  (";" xparam)
+
+                  ) ":" date-time
+
+   Example: A trigger set 15 minutes prior to the start of the event or
+   to-do.
+
+     TRIGGER:-P15M
+
+   A trigger set 5 minutes after the end of the event or to-do.
+
+     TRIGGER;RELATED=END:P5M
+
+   A trigger set to an absolute date/time.
+
+     TRIGGER;VALUE=DATE-TIME:19980101T050000Z
+
+4.8.7 Change Management Component Properties
+
+   The following properties specify change management information in
+   calendar components.
+
+4.8.7.1 Date/Time Created
+
+   Property Name: CREATED
+
+   Purpose: This property specifies the date and time that the calendar
+   information was created by the calendar user agent in the calendar
+   store.
+
+        Note: This is analogous to the creation date and time for a file
+        in the file system.
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 129]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Value Type: DATE-TIME
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: The property can be specified once in "VEVENT", "VTODO"
+   or "VJOURNAL" calendar components.
+
+   Description: The date and time is a UTC value.
+
+   Format Definition: The property is defined by the following notation:
+
+     created    = "CREATED" creaparam ":" date-time CRLF
+
+     creaparam  = *(";" xparam)
+
+   Example: The following is an example of this property:
+
+     CREATED:19960329T133000Z
+
+4.8.7.2 Date/Time Stamp
+
+   Property Name: DTSTAMP
+
+   Purpose: The property indicates the date/time that the instance of
+   the iCalendar object was created.
+
+   Value Type: DATE-TIME
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: This property MUST be included in the "VEVENT", "VTODO",
+   "VJOURNAL" or "VFREEBUSY" calendar components.
+
+   Description: The value MUST be specified in the UTC time format.
+
+   This property is also useful to protocols such as [IMIP] that have
+   inherent latency issues with the delivery of content. This property
+   will assist in the proper sequencing of messages containing iCalendar
+   objects.
+
+   This property is different than the "CREATED" and "LAST-MODIFIED"
+   properties. These two properties are used to specify when the
+   particular calendar data in the calendar store was created and last
+   modified. This is different than when the iCalendar object
+   representation of the calendar service information was created or
+   last modified.
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 130]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Format Definition: The property is defined by the following notation:
+
+     dtstamp    = "DTSTAMP" stmparam ":" date-time CRLF
+
+     stmparam   = *(";" xparam)
+
+   Example:
+
+     DTSTAMP:19971210T080000Z
+
+4.8.7.3 Last Modified
+
+   Property Name: LAST-MODIFIED
+
+   Purpose: The property specifies the date and time that the
+   information associated with the calendar component was last revised
+   in the calendar store.
+
+        Note: This is analogous to the modification date and time for a
+        file in the file system.
+
+   Value Type: DATE-TIME
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: This property can be specified in the "EVENT", "VTODO",
+   "VJOURNAL" or "VTIMEZONE" calendar components.
+
+   Description: The property value MUST be specified in the UTC time
+   format.
+
+   Format Definition: The property is defined by the following notation:
+
+     last-mod   = "LAST-MODIFIED" lstparam ":" date-time CRLF
+
+     lstparam   = *(";" xparam)
+
+   Example: The following is are examples of this property:
+
+     LAST-MODIFIED:19960817T133000Z
+
+4.8.7.4 Sequence Number
+
+   Property Name: SEQUENCE
+
+   Purpose: This property defines the revision sequence number of the
+   calendar component within a sequence of revisions.
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 131]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Value Type: integer
+
+   Property Parameters: Non-standard property parameters can be
+   specified on this property.
+
+   Conformance: The property can be specified in "VEVENT", "VTODO" or
+   "VJOURNAL" calendar component.
+
+   Description: When a calendar component is created, its sequence
+   number is zero (US-ASCII decimal 48). It is monotonically incremented
+   by the "Organizer's" CUA each time the "Organizer" makes a
+   significant revision to the calendar component. When the "Organizer"
+   makes changes to one of the following properties, the sequence number
+   MUST be incremented:
+
+     .  "DTSTART"
+
+     .  "DTEND"
+
+     .  "DUE"
+
+     .  "RDATE"
+
+     .  "RRULE"
+
+     .  "EXDATE"
+
+     .  "EXRULE"
+
+     .  "STATUS"
+
+   In addition, changes made by the "Organizer" to other properties can
+   also force the sequence number to be incremented. The "Organizer" CUA
+   MUST increment the sequence number when ever it makes changes to
+   properties in the calendar component that the "Organizer" deems will
+   jeopardize the validity of the participation status of the
+   "Attendees". For example, changing the location of a meeting from one
+   locale to another distant locale could effectively impact the
+   participation status of the "Attendees".
+
+   The "Organizer" includes this property in an iCalendar object that it
+   sends to an "Attendee" to specify the current version of the calendar
+   component.
+
+   The "Attendee" includes this property in an iCalendar object that it
+   sends to the "Organizer" to specify the version of the calendar
+   component that the "Attendee" is referring to.
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 132]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   A change to the sequence number is not the mechanism that an
+   "Organizer" uses to request a response from the "Attendees". The
+   "RSVP" parameter on the "ATTENDEE" property is used by the
+   "Organizer" to indicate that a response from the "Attendees" is
+   requested.
+
+   Format Definition: This property is defined by the following
+   notation:
+
+     seq = "SEQUENCE" seqparam ":" integer CRLF
+     ; Default is "0"
+
+     seqparam   = *(";" xparam)
+
+   Example: The following is an example of this property for a calendar
+   component that was just created by the "Organizer".
+
+     SEQUENCE:0
+
+   The following is an example of this property for a calendar component
+   that has been revised two different times by the "Organizer".
+
+     SEQUENCE:2
+
+4.8.8 Miscellaneous Component Properties
+
+   The following properties specify information about a number of
+   miscellaneous features of calendar components.
+
+4.8.8.1 Non-standard Properties
+
+   Property Name: Any property name with a "X-" prefix
+
+   Purpose: This class of property provides a framework for defining
+   non-standard properties.
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard and language property parameters
+   can be specified on this property.
+
+   Conformance: This property can be specified in any calendar
+   component.
+
+   Description: The MIME Calendaring and Scheduling Content Type
+   provides a "standard mechanism for doing non-standard things". This
+   extension support is provided for implementers to "push the envelope"
+   on the existing version of the memo. Extension properties are
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 133]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   specified by property and/or property parameter names that have the
+   prefix text of "X-" (the two character sequence: LATIN CAPITAL LETTER
+   X character followed by the HYPEN-MINUS character). It is recommended
+   that vendors concatenate onto this sentinel another short prefix text
+   to identify the vendor. This will facilitate readability of the
+   extensions and minimize possible collision of names between different
+   vendors. User agents that support this content type are expected to
+   be able to parse the extension properties and property parameters but
+   can ignore them.
+
+   At present, there is no registration authority for names of extension
+   properties and property parameters. The data type for this property
+   is TEXT. Optionally, the data type can be any of the other valid data
+   types.
+
+   Format Definition: The property is defined by the following notation:
+
+     x-prop     = x-name *(";" xparam) [";" languageparam] ":" text CRLF
+        ; Lines longer than 75 octets should be folded
+
+   Example: The following might be the ABC vendor's extension for an
+   audio-clip form of subject property:
+
+     X-ABC-MMSUBJ;X-ABC-MMSUBJTYPE=wave:http://load.noise.org/mysubj.wav
+
+4.8.8.2 Request Status
+
+   Property Name: REQUEST-STATUS
+
+   Purpose: This property defines the status code returned for a
+   scheduling request.
+
+   Value Type: TEXT
+
+   Property Parameters: Non-standard and language property parameters
+   can be specified on this property.
+
+   Conformance: The property can be specified in "VEVENT", "VTODO",
+   "VJOURNAL" or "VFREEBUSY" calendar component.
+
+   Description: This property is used to return status code information
+   related to the processing of an associated iCalendar object. The data
+   type for this property is TEXT.
+
+   The value consists of a short return status component, a longer
+   return status description component, and optionally a status-specific
+   data component. The components of the value are separated by the
+   SEMICOLON character (US-ASCII decimal 59).
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 134]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   The short return status is a PERIOD character (US-ASCII decimal 46)
+   separated 3-tuple of integers. For example, "3.1.1". The successive
+   levels of integers provide for a successive level of status code
+   granularity.
+
+   The following are initial classes for the return status code.
+   Individual iCalendar object methods will define specific return
+   status codes for these classes. In addition, other classes for the
+   return status code may be defined using the registration process
+   defined later in this memo.
+
+     |==============+===============================================|
+     | Short Return | Longer Return Status Description              |
+     | Status Code  |                                               |
+     |==============+===============================================|
+     |    1.xx      | Preliminary success. This class of status     |
+     |              | of status code indicates that the request has |
+     |              | request has been initially processed but that |
+     |              | completion is pending.                        |
+     |==============+===============================================|
+     |    2.xx      | Successful. This class of status code         |
+     |              | indicates that the request was completed      |
+     |              | successfuly. However, the exact status code   |
+     |              | can indicate that a fallback has been taken.  |
+     |==============+===============================================|
+     |    3.xx      | Client Error. This class of status code       |
+     |              | indicates that the request was not successful.|
+     |              | The error is the result of either a syntax or |
+     |              | a semantic error in the client formatted      |
+     |              | request. Request should not be retried until  |
+     |              | the condition in the request is corrected.    |
+     |==============+===============================================|
+     |    4.xx      | Scheduling Error. This class of status code   |
+     |              | indicates that the request was not successful.|
+     |              | Some sort of error occurred within the        |
+     |              | calendaring and scheduling service, not       |
+     |              | directly related to the request itself.       |
+     |==============+===============================================|
+
+   Format Definition: The property is defined by the following notation:
+
+     rstatus    = "REQUEST-STATUS" rstatparam ":"
+                  statcode ";" statdesc [";" extdata]
+
+     rstatparam = *(
+
+                ; the following is optional,
+                ; but MUST NOT occur more than once
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 135]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+                (";" languageparm) /
+
+                ; the following is optional,
+                ; and MAY occur more than once
+
+                (";" xparam)
+
+                )
+
+     statcode   = 1*DIGIT *("." 1*DIGIT)
+     ;Hierarchical, numeric return status code
+
+     statdesc   = text
+     ;Textual status description
+
+     extdata    = text
+     ;Textual exception data. For example, the offending property
+     ;name and value or complete property line.
+
+   Example: The following are some possible examples of this property.
+   The COMMA and SEMICOLON separator characters in the property value
+   are BACKSLASH character escaped because they appear in a  text value.
+
+     REQUEST-STATUS:2.0;Success
+
+     REQUEST-STATUS:3.1;Invalid property value;DTSTART:96-Apr-01
+
+     REQUEST-STATUS:2.8; Success\, repeating event ignored. Scheduled
+      as a single event.;RRULE:FREQ=WEEKLY\;INTERVAL=2
+
+     REQUEST-STATUS:4.1;Event conflict. Date/time is busy.
+
+     REQUEST-STATUS:3.7;Invalid calendar user;ATTENDEE:
+      MAILTO:jsmith@host.com
+
+5 iCalendar Object Examples
+
+   The following examples are provided as an informational source of
+   illustrative iCalendar objects consistent with this content type.
+
+   The following example specifies a three-day conference that begins at
+   8:00 AM EDT, September 18, 1996 and end at 6:00 PM EDT, September 20,
+   1996.
+
+     BEGIN:VCALENDAR PRODID:-//xyz Corp//NONSGML PDA Calendar Verson
+     1.0//EN VERSION:2.0 BEGIN:VEVENT DTSTAMP:19960704T120000Z
+     UID:uid1@host.com ORGANIZER:MAILTO:jsmith@host.com
+     DTSTART:19960918T143000Z DTEND:19960920T220000Z STATUS:CONFIRMED
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 136]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     CATEGORIES:CONFERENCE SUMMARY:Networld+Interop Conference
+     DESCRIPTION:Networld+Interop Conference
+       and Exhibit\nAtlanta World Congress Center\n
+      Atlanta, Georgia END:VEVENT END:VCALENDAR
+
+   The following example specifies a group scheduled meeting that begin
+   at 8:30 AM EST on March 12, 1998 and end at 9:30 AM EST on March 12,
+   1998. The "Organizer" has scheduled the meeting with one or more
+   calendar users in a group. A time zone specification for Eastern
+   United States has been specified.
+
+     BEGIN:VCALENDAR
+     PRODID:-//RDU Software//NONSGML HandCal//EN
+     VERSION:2.0
+     BEGIN:VTIMEZONE
+     TZID:US-Eastern
+     BEGIN:STANDARD
+     DTSTART:19981025T020000
+     RDATE:19981025T020000
+     TZOFFSETFROM:-0400
+     TZOFFSETTO:-0500
+     TZNAME:EST
+     END:STANDARD
+     BEGIN:DAYLIGHT
+     DTSTART:19990404T020000
+     RDATE:19990404T020000
+     TZOFFSETFROM:-0500
+     TZOFFSETTO:-0400
+     TZNAME:EDT
+     END:DAYLIGHT
+     END:VTIMEZONE
+     BEGIN:VEVENT
+     DTSTAMP:19980309T231000Z
+     UID:guid-1.host1.com
+     ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com
+     ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:
+      MAILTO:employee-A@host.com
+     DESCRIPTION:Project XYZ Review Meeting
+     CATEGORIES:MEETING
+     CLASS:PUBLIC
+     CREATED:19980309T130000Z
+     SUMMARY:XYZ Project Review
+     DTSTART;TZID=US-Eastern:19980312T083000
+     DTEND;TZID=US-Eastern:19980312T093000
+     LOCATION:1CP Conference Room 4350
+     END:VEVENT
+     END:VCALENDAR
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 137]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   The following is an example of an iCalendar object passed in a MIME
+   message with a single body part consisting of a "text/calendar"
+   Content Type.
+
+     TO:jsmith@host1.com
+     FROM:jdoe@host1.com
+     MIME-VERSION:1.0
+     MESSAGE-ID:<id3@host1.com>
+     CONTENT-TYPE:text/calendar
+
+     BEGIN:VCALENDAR
+     METHOD:xyz
+     VERSION:2.0
+     PRODID:-//ABC Corporation//NONSGML My Product//EN
+     BEGIN:VEVENT
+     DTSTAMP:19970324T1200Z
+     SEQUENCE:0
+     UID:uid3@host1.com
+     ORGANIZER:MAILTO:jdoe@host1.com
+     ATTENDEE;RSVP=TRUE:MAILTO:jsmith@host1.com
+     DTSTART:19970324T123000Z
+     DTEND:19970324T210000Z
+     CATEGORIES:MEETING,PROJECT
+     CLASS:PUBLIC
+     SUMMARY:Calendaring Interoperability Planning Meeting
+     DESCRIPTION:Discuss how we can test c&s interoperability\n
+      using iCalendar and other IETF standards.
+     LOCATION:LDB Lobby
+     ATTACH;FMTTYPE=application/postscript:ftp://xyzCorp.com/pub/
+      conf/bkgrnd.ps
+     END:VEVENT
+     END:VCALENDAR
+
+   The following is an example of a to-do due on April 15, 1998. An
+   audio alarm has been specified to remind the calendar user at noon,
+   the day before the to-do is expected to be completed and repeat
+   hourly, four additional times. The to-do definition has been modified
+   twice since it was initially created.
+
+     BEGIN:VCALENDAR
+     VERSION:2.0
+     PRODID:-//ABC Corporation//NONSGML My Product//EN
+     BEGIN:VTODO
+     DTSTAMP:19980130T134500Z
+     SEQUENCE:2
+     UID:uid4@host1.com
+     ORGANIZER:MAILTO:unclesam@us.gov
+     ATTENDEE;PARTSTAT=ACCEPTED:MAILTO:jqpublic@host.com
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 138]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     DUE:19980415T235959
+     STATUS:NEEDS-ACTION
+     SUMMARY:Submit Income Taxes
+     BEGIN:VALARM
+     ACTION:AUDIO
+     TRIGGER:19980403T120000
+     ATTACH;FMTTYPE=audio/basic:http://host.com/pub/audio-
+      files/ssbanner.aud
+     REPEAT:4
+     DURATION:PT1H
+     END:VALARM
+     END:VTODO
+     END:VCALENDAR
+
+   The following is an example of a journal entry.
+
+     BEGIN:VCALENDAR
+     VERSION:2.0
+     PRODID:-//ABC Corporation//NONSGML My Product//EN
+     BEGIN:VJOURNAL
+     DTSTAMP:19970324T120000Z
+     UID:uid5@host1.com
+     ORGANIZER:MAILTO:jsmith@host.com
+     STATUS:DRAFT
+     CLASS:PUBLIC
+     CATEGORY:Project Report, XYZ, Weekly Meeting
+     DESCRIPTION:Project xyz Review Meeting Minutes\n
+      Agenda\n1. Review of project version 1.0 requirements.\n2.
+     Definition
+      of project processes.\n3. Review of project schedule.\n
+      Participants: John Smith, Jane Doe, Jim Dandy\n-It was
+       decided that the requirements need to be signed off by
+       product marketing.\n-Project processes were accepted.\n
+      -Project schedule needs to account for scheduled holidays
+       and employee vacation time. Check with HR for specific
+       dates.\n-New schedule will be distributed by Friday.\n-
+      Next weeks meeting is cancelled. No meeting until 3/23.
+     END:VJOURNAL
+     END:VCALENDAR
+
+   The following is an example of published busy time information. The
+   iCalendar object might be placed in the network resource
+   www.host.com/calendar/busytime/jsmith.ifb.
+
+     BEGIN:VCALENDAR
+     VERSION:2.0
+     PRODID:-//RDU Software//NONSGML HandCal//EN
+     BEGIN:VFREEBUSY
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 139]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+     ORGANIZER:MAILTO:jsmith@host.com
+     DTSTART:19980313T141711Z
+     DTEND:19980410T141711Z
+     FREEBUSY:19980314T233000Z/19980315T003000Z
+     FREEBUSY:19980316T153000Z/19980316T163000Z
+     FREEBUSY:19980318T030000Z/19980318T040000Z
+     URL:http://www.host.com/calendar/busytime/jsmith.ifb
+     END:VFREEBUSY
+     END:VCALENDAR
+
+6 Recommended Practices
+
+   These recommended practices should be followed in order to assure
+   consistent handling of the following cases for an iCalendar object.
+
+   1.  Content lines longer than 75 octets SHOULD be folded.
+
+   2.  A calendar entry with a "DTSTART" property but no "DTEND"
+       property does not take up any time. It is intended to represent
+       an event that is associated with a given calendar date and time
+       of day, such as an anniversary. Since the event does not take up
+       any time, it MUST NOT be used to record busy time no matter what
+       the value for the "TRANSP" property.
+
+   3.  When the "DTSTART" and "DTEND", for "VEVENT", "VJOURNAL" and
+       "VFREEBUSY" calendar components, and "DTSTART" and "DUE", for
+       "VTODO" calendar components, have the same value data type (e.g.,
+       DATE-TIME), they SHOULD specify values in the same time format
+       (e.g., UTC time format).
+
+   4.  When the combination of the "RRULE" and "RDATE" properties on an
+       iCalendar object produces multiple instances having the same
+       start date/time, they should be collapsed to, and considered as,
+       a single instance.
+
+   5.  When a calendar user receives multiple requests for the same
+       calendar component (e.g., REQUEST for a "VEVENT" calendar
+       component) as a result of being on multiple mailing lists
+       specified by "ATTENDEE" properties in the request, they SHOULD
+       respond to only one of the requests. The calendar user SHOULD
+       also specify (using the "MEMBER" parameter of the "ATTENDEE"
+       property) which mailing list they are a member of.
+
+   6.  An implementation can truncate a "SUMMARY" property value to 255
+       characters.
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 140]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   7.  If seconds of the minute are not supported by an implementation,
+       then a value of "00" SHOULD be specified for the seconds
+       component in a time value.
+
+   8.  If the value type parameter (VALUE=) contains an unknown value
+       type, it SHOULD be treated as TEXT.
+
+   9.  TZURL values SHOULD NOT be specified as a FILE URI type. This URI
+       form can be useful within an organization, but is problematic in
+       the Internet.
+
+   10.  Some possible English values for CATEGORIES property include
+        "ANNIVERSARY", "APPOINTMENT", "BUSINESS", "EDUCATION",
+        "HOLIDAY", "MEETING", "MISCELLANEOUS", "NON-WORKING HOURS", "NOT
+        IN OFFICE", "PERSONAL", "PHONE CALL", "SICK DAY", "SPECIAL
+        OCCASION", "TRAVEL", "VACATION". Categories can be specified in
+        any registered language.
+
+   11.  Some possible English values for RESOURCES property include
+        "CATERING", "CHAIRS", "COMPUTER PROJECTOR", "EASEL", "OVERHEAD
+        PROJECTOR", "SPEAKER PHONE", "TABLE", "TV", "VCR", "VIDEO
+        PHONE", "VEHICLE". Resources can be specified in any registered
+        language.
+
+7 Registration of Content Type Elements
+
+   This section provides the process for registration of MIME
+   Calendaring and Scheduling Content Type iCalendar object methods and
+   new or modified properties.
+
+7.1 Registration of New and Modified iCalendar Object Methods
+
+   New MIME Calendaring and Scheduling Content Type iCalendar object
+   methods are registered by the publication of an IETF Request for
+   Comments (RFC). Changes to an iCalendar object method are registered
+   by the publication of a revision of the RFC defining the method.
+
+7.2 Registration of New Properties
+
+   This section defines procedures by which new properties or enumerated
+   property values for the MIME Calendaring and Scheduling Content Type
+   can be registered with the IANA. Non-IANA properties can be used by
+   bilateral agreement, provided the associated properties names follow
+   the "X-" convention.
+
+   The procedures defined here are designed to allow public comment and
+   review of new properties, while posing only a small impediment to the
+   definition of new properties.
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 141]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Registration of a new property is accomplished by the following
+   steps.
+
+7.2.1 Define the property
+
+   A property is defined by completing the following template.
+
+     To: ietf-calendar@imc.org
+
+     Subject: Registration of text/calendar MIME property XXX
+
+     Property name:
+
+     Property purpose:
+
+     Property value type(s):
+
+     Property parameter (s):
+
+     Conformance:
+
+     Description:
+
+     Format definition:
+
+     Examples:
+
+   The meaning of each field in the template is as follows.
+
+   Property name: The name of the property, as it will appear in the
+   body of an text/calendar MIME Content-Type "property: value" line to
+   the left of the colon ":".
+
+   Property purpose: The purpose of the property (e.g., to indicate a
+   delegate for the event or to-do, etc.). Give a short but clear
+   description.
+
+   Property value type (s): Any of the valid value types for the
+   property value needs to be specified. The default value type also
+   needs to be specified. If a new value type is specified, it needs to
+   be declared in this section.
+
+   Property parameter (s): Any of the valid property parameters for the
+   property needs to be specified.
+
+   Conformance: The calendar components that the property can appear in
+   needs to be specified.
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 142]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Description: Any special notes about the property, how it is to be
+   used, etc.
+
+   Format definition: The ABNF for the property definition needs to be
+   specified.
+
+   Examples: One or more examples of instances of the property needs to
+   be specified.
+
+7.2.2 Post the Property definition
+
+   The property description MUST be posted to the new property
+   discussion list, ietf-calendar@imc.org.
+
+7.2.3   Allow a comment period
+
+   Discussion on the new property MUST be allowed to take place on the
+   list for a minimum of two weeks. Consensus MUST be reached on the
+   property before proceeding to the next step.
+
+7.2.4 Submit the property for approval
+
+   Once the two-week comment period has elapsed, and the proposer is
+   convinced consensus has been reached on the property, the
+   registration application should be submitted to the Method Reviewer
+   for approval. The Method Reviewer is appointed to the Application
+   Area Directors and can either accept or reject the property
+   registration. An accepted registration should be passed on by the
+   Method Reviewer to the IANA for inclusion in the official IANA method
+   registry. The registration can be rejected for any of the following
+   reasons. 1) Insufficient comment period; 2) Consensus not reached; 3)
+   Technical deficiencies raised on the list or elsewhere have not been
+   addressed. The Method Reviewer's decision to reject a property can be
+   appealed by the proposer to the IESG, or the objections raised can be
+   addressed by the proposer and the property resubmitted.
+
+7.3 Property Change Control
+
+   Existing properties can be changed using the same process by which
+   they were registered.
+
+        1.           Define the change
+
+        2.           Post the change
+
+        3.           Allow a comment period
+
+        4.           Submit the property for approval
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 143]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   Note that the original author or any other interested party can
+   propose a change to an existing property, but that such changes
+   should only be proposed when there are serious omissions or errors in
+   the published memo. The Method Reviewer can object to a change if it
+   is not backward compatible, but is not required to do so.
+
+   Property definitions can never be deleted from the IANA registry, but
+   properties which are no longer believed to be useful can be declared
+   OBSOLETE by a change to their "intended use" field.
+
+8 References
+
+   [IMIP]     Dawson, F., Mansour, S. and S. Silverberg, "iCalendar
+              Message-based Interoperability Protocol (IMIP)", RFC 2447,
+              November 1998.
+
+   [ITIP]     Silverberg, S., Mansour, S., Dawson, F. and R. Hopson,
+              "iCalendar Transport-Independent Interoperability Protocol
+              (iTIP) : Scheduling Events, Busy Time, To-dos and Journal
+              Entries", RFC 2446, November 1998.
+
+   [ISO 8601] ISO 8601, "Data elements and interchange formats-
+              Information interchange--Representation of dates and
+              times", International Organization for Standardization,
+              June, 1988.
+
+   [ISO 9070] ISO/IEC 9070, "Information Technology_SGML Support
+              Facilities--Registration Procedures for Public Text Owner
+              Identifiers", Second Edition, International Organization
+              for Standardization, April 1991.
+
+   [RFC 822]  Crocker, D., "Standard for the Format of ARPA Internet
+              Text Messages", STD 11, RFC 822, August 1982.
+
+   [RFC 1738] Berners-Lee, T., Masinter, L. and M. McCahill, "Uniform
+              Resource Locators (URL)", RFC 1738, December 1994.
+
+   [RFC 1766] Alvestrand, H., "Tags for the Identification of
+              Languages", RFC 1766, March 1995.
+
+   [RFC 2045] Freed, N. and N. Borenstein, " Multipurpose Internet Mail
+              Extensions (MIME) - Part One: Format of Internet Message
+              Bodies", RFC 2045, November 1996.
+
+   [RFC 2046] Freed, N. and N. Borenstein, " Multipurpose Internet Mail
+              Extensions (MIME) - Part Two: Media Types", RFC 2046,
+              November 1996.
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 144]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   [RFC 2048] Freed, N., Klensin, J. and J. Postel, "Multipurpose
+              Internet Mail Extensions (MIME) - Part Four: Registration
+              Procedures", RFC 2048, January 1997.
+
+   [RFC 2119] Bradner, S., "Key words for use in RFCs to Indicate
+              Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+   [RFC 2234] Crocker, D. and P. Overell, "Augmented BNF for Syntax
+              Specifications: ABNF", RFC 2234, November 1997.
+
+   [RFC 2279] Yergeau, F., "UTF-8, a transformation format of ISO
+              10646", RFC 2279, January 1998.
+
+   [RFC 2425] Howes, T., Smith, M. and F. Dawson, "A MIME Content-Type
+              for Directory Information", RFC 2425, September 1998.
+
+   [RFC 2426] Dawson, F. and T. Howes, "vCard MIME Directory Profile",
+              RFC 2426, September 1998.
+
+   [TZ]       Olson, A.D., et al, Time zone code and data,
+              ftp://elsie.nci.nih.gov/pub/, updated periodically.
+
+   [VCAL]     Internet Mail Consortium, "vCalendar - The Electronic
+              Calendaring and Scheduling Exchange Format",
+              http://www.imc.org/pdi/vcal-10.txt, September 18, 1996.
+
+9 Acknowledgments
+
+   A hearty thanks to the IETF Calendaring and Scheduling Working Group
+   and also the following individuals who have participated in the
+   drafting, review and discussion of this memo:
+
+   Roland Alden, Harald T. Alvestrand, Eric Berman, Denis Bigorgne, John
+   Binici, Bill Bliss, Philippe Boucher, Steve Carter, Andre
+   Courtemanche, Dave Crocker, David Curley, Alec Dun, John Evans, Ross
+   Finlayson, Randell Flint, Ned Freed, Patrik Faltstrom, Chuck
+   Grandgent, Mark Handley, Steve Hanna, Paul B. Hill, Paul Hoffman,
+   Ross Hopson, Mark Horton, Daryl Huff, Bruce Kahn, C. Harald Koch,
+   Ryan Jansen, Don Lavange, Antoine Leca, Theodore Lorek, Steve
+   Mansour, Skip Montanaro, Keith Moore, Cecil Murray, Chris Newman,
+   John Noerenberg, Ralph Patterson, Pete Resnick, Keith Rhodes, Robert
+   Ripberger, John Rose, Doug Royer, Andras Salamar, Ted Schuh, Vinod
+   Seraphin, Derrick Shadel, Ken Shan, Andrew Shuman, Steve Silverberg,
+   William P. Spencer, John Sun, Mark Towfiq, Yvonne Tso, Robert Visnov,
+   James L. Weiner, Mike Weston, William Wyatt.
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 145]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+10 Authors' and Chairs' Addresses
+
+   The following address information is provided in a MIME-VCARD,
+   Electronic Business Card, format.
+
+   The authors of this memo are:
+
+   BEGIN:VCARD
+   VERSION:3.0
+   N:Dawson;Frank
+   FN:Frank Dawson
+   ORG:Lotus Development Corporation
+   ADR;TYPE=WORK,POSTAL,PARCEL:;;6544 Battleford Drive;
+    Raleigh;NC;27613-3502;USA
+   TEL;TYPE=WORK,MSG:+1-919-676-9515
+   TEL;TYPE=WORK,FAX:+1-919-676-9564
+   EMAIL;TYPE=PREF,INTERNET:Frank_Dawson@Lotus.com
+   EMAIL;TYPE=INTERNET:fdawson@earthlink.net
+   URL:http://home.earthlink.net/~fdawson
+   END:VCARD
+
+   BEGIN:VCARD
+   VERSION:3.0
+   N:Stenerson;Derik
+   FN:Derik Stenerson
+   ORG:Microsoft Corporation
+   ADR;TYPE=WORK,POSTAL,PARCEL:;;One Microsoft Way;
+    Redmond;WA;98052-6399;USA
+   TEL;TYPE=WORK,MSG:+1-425-936-5522
+   TEL;TYPE=WORK,FAX:+1-425-936-7329
+   EMAIL;TYPE=INTERNET:deriks@Microsoft.com
+   END:VCARD
+
+   The iCalendar object is a result of the work of the Internet
+   Engineering Task Force Calendaring and Scheduling Working Group. The
+   chairmen of that working group are:
+
+   BEGIN:VCARD
+   VERSION:3.0
+   N:Ganguly;Anik
+   FN:Anik Ganguly
+   ORG: Open Text Inc.
+   ADR;TYPE=WORK,POSTAL,PARCEL:;Suite 101;38777 West Six Mile Road;
+    Livonia;MI;48152;USA
+   TEL;TYPE=WORK,MSG:+1-734-542-5955
+   EMAIL;TYPE=INTERNET:ganguly@acm.org
+   END:VCARD
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 146]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+   The co-chairman of that working group is:
+
+   BEGIN:VCARD
+   VERSION:3.0
+   N:Moskowitz;Robert
+   FN:Robert Moskowitz
+   EMAIL;TYPE=INTERNET:rgm-ietf@htt-consult.com
+   END:VCARD
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 147]
+
+RFC 2445                       iCalendar                   November 1998
+
+
+11.  Full Copyright Statement
+
+   Copyright (C) The Internet Society (1998).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Dawson & Stenerson          Standards Track                   [Page 148]
+
Index: /tags/calendar/0.9.3/egroupware.org/accept_holiday.php
===================================================================
--- /tags/calendar/0.9.3/egroupware.org/accept_holiday.php	(revision 2)
+++ /tags/calendar/0.9.3/egroupware.org/accept_holiday.php	(revision 2)
@@ -0,0 +1,55 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare                                                               *
+  * http://www.egroupware.org                                                *
+  * Written by Mark Peters <skeeter@phpgroupware.org>                        *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+	$send_back_to = str_replace('submit','admin',$_SERVER['HTTP_REFERER']);
+	if(!$_POST['locale'])
+	{
+		Header('Location: '.$send_back_to);
+	}
+
+	$send_back_to = str_replace('&locale='.$_POST['locale'],'',$send_back_to);
+	$file = './holidays.'.$_POST['locale'].'.csv';
+	if(!file_exists($file))
+	{
+		if (count($_POST['name']))
+		{
+			$c_holidays = count($_POST['name']);
+			$fp = fopen($file,'w');
+			for($i=0;$i<$c_holidays;$i++)
+			{
+				fwrite($fp,$_POST['locale']."\t".$_POST['name'][$i]."\t".$_POST['day'][$i]."\t".$_POST['month'][$i]."\t".$_POST['occurence'][$i]."\t".$_POST['dow'][$i]."\t".$_POST['observance'][$i]."\n");
+			}
+			fclose($fp);
+		}
+		Header('Location: '.$send_back_to);
+	}
+	else
+	{
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+	<title>eGroupWare.org: There is already a holiday-file for '<?php echo $_POST['locale']; ?>' !!!</title>
+</head>
+<body>
+	<h1>There is already a holiday-file for '<?php echo $_POST['locale']; ?>' !!!</h1>
+
+	<p>If you think your version of the holidays for '<?php echo $_POST['locale']; ?>' should replace
+	the existing one, please <a href="<?php echo $_SERVER['HTTP_REFERER']; ?>&download=1">download</a> the file
+	and <a href="mailto:egroupware-developers@lists.sourceforge.net">mail it</a> to us.</p>
+
+	<p>To get back to your own eGroupWare-install <a href="<?php echo $send_back_to; ?>">click here</a>.</p>
+</body>
+</html>
+<?php
+	}
+?>
Index: /tags/calendar/0.9.3/release_notes.txt
===================================================================
--- /tags/calendar/0.9.3/release_notes.txt	(revision 133)
+++ /tags/calendar/0.9.3/release_notes.txt	(revision 133)
@@ -0,0 +1,16 @@
+Sobre o Update da versão 0.9.16.002 para 0.9.17:
+
+- Corrigido problema no envio dos emails (mudança do content-type: html para text/html);
+- Implementação da integração do ExpressoMail com a Agenda, usando o framework AJAX para
+carregar os participantes da Agenda. Isso é uma opção na configuração do servidor, caso o
+administrador queira os recursos existentes do ExpressoMail na Agenda;
+- Inclusão do item Participantes Externos no Compromisso: O usuário pode convidar algum
+participante que não seja do seu servidor Expresso, enviando por email o aviso do compromisso.
+Utilizando a integração do ExpressoMail com a Agenda, o usuário terá acesso aos seus contatos
+pessoais cadastrados pelo autocompletar. Também poderá consultar no Catálogo Geral através da 
+tecla F9. Essa alteração impactou também nas classes de negócio, e adição de campo na base de
+dados;
+
+IMPORTANTE: Para atualizar essa versão, utilize o setup do E-groupware.
+
+Responsável pelas alterações: Nilton E. Buhrer Neto (niltonneto@celepar.pr.gov.br)
Index: /tags/calendar/0.9.3/inc/class.boalarm.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.boalarm.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/inc/class.boalarm.inc.php	(revision 2)
@@ -0,0 +1,209 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar                                                    *
+  * http://www.egroupware.org                                                *
+  * Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
+  *          http://www.radix.net/~cknudsen                                  *
+  * Modified by Mark Peters <milosch@phpwhere.org>                           *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	define('PHPGW_ACL_DELETEALARM',PHPGW_ACL_DELETE);	// for now
+	define('PHPGW_ACL_SETALARM',PHPGW_ACL_WRITE);
+	define('PHPGW_ACL_READALARM',PHPGW_ACL_READ);
+
+	class boalarm
+	{
+		var $so;
+		var $cal;
+		var $cal_id;
+
+		var $tz_offset;
+
+		var $debug = False;
+//		var $debug = True;
+
+		var $public_functions = array(
+			'add'       => True,
+			'delete'    => True
+		);
+
+		function boalarm()
+		{
+			$cal_id = (isset($_POST['cal_id'])?(int)$_POST['cal_id']:'');
+			if($cal_id)
+			{
+				$this->cal_id = $cal_id;
+			}
+			$this->bo = CreateObject('calendar.bocalendar',1);
+			$this->so = CreateObject('calendar.socalendar',1);
+			$this->tz_offset = $GLOBALS['phpgw']->datetime->tz_offset;
+
+			if($this->debug)
+			{
+				echo "BO Owner : ".$this->bo->owner."<br>\n";
+			}
+
+			if($this->bo->use_session)
+			{
+				$this->save_sessiondata();
+			}
+		}
+
+		function save_sessiondata()
+		{
+			$data = array(
+				'filter' => $this->bo->filter,
+				'cat_id' => $this->bo->cat_id,
+				'owner'  => $this->bo->owner,
+				'year'   => $this->bo->year,
+				'month'  => $this->bo->month,
+				'day'    => $this->bo->day
+			);
+			$this->bo->save_sessiondata($data);
+		}
+
+		function read_entry($cal_id)
+		{
+			return $this->bo->read_entry((int)$cal_id);
+		}
+
+		/*!
+		@function add
+		@abstract adds a new alarm to an event
+		@syntax add(&$event,$time,$login_id)
+		@param &$event event to add the alarm too
+		@param $time for the alarm in sec before the starttime of the event
+		@param $login_id user to alarm
+		@returns the alarm or False
+		*/
+		function add(&$event,$time,$owner)
+		{
+			//echo "<p>boalarm::add(event="; print_r($event); ",time=$time,owner=$owner)</p>\n";
+			if (!$this->check_perms(PHPGW_ACL_SETALARM,$owner) || !($cal_id = $event['id']))
+			{
+				return False;
+			}
+			$alarm = Array(
+				'time'    => ($etime=$this->bo->maketime($event['start'])) - $time,
+				'offset'  => $time,
+				'owner'   => $owner,
+				'enabled' => 1
+			);
+			$alarm['id'] = $this->so->save_alarm($cal_id,$alarm);
+			$event['alarm'][$alarm['id']] = $alarm;
+			$event['alarm'][$alarm['id']]['time'] = $alarm['time'] + $this->tz_offset;	// allows viewing alarm time in users timezone
+
+			return $alarm;
+		}
+
+		/*!
+		@function check_perms
+		@abstract checks if user has a certain grant from the owner of an alarm or event
+		@syntax check_perms($grant,$owner)
+		@param $grant PHPGW_ACL_{SET|READ|DELETE}ALARM (defined at the top of this file)
+		*/
+		function check_perms($grant,$owner)
+		{
+			return $this->bo->check_perms($grant,0,$owner);
+		}
+
+		/*!
+		@function participants
+		@abstract get the participants of an event, the user has grants to alarm
+		@syntax participants($event,$fullnames=True)
+		@param $event or cal_id of an event
+		@param $fullnames if true return array with fullnames as values
+		@returns array with account_ids as keys
+		*/
+		function participants($event,$fullnames=True)
+		{
+			if (!is_array($event))
+			{
+				$event = $this->read_entry($event);
+			}
+			if (!$event)
+			{
+				return False;
+			}
+			$participants = array();
+			foreach ($event['participants'] as $uid => $status)
+			{
+				if ($this->check_perms(PHPGW_ACL_SETALARM,$uid))
+				{
+					$participants[$uid] = $fullnames ? $GLOBALS['phpgw']->common->grab_owner_name($uid) : True;
+				}
+			}
+			return $participants;
+		}
+
+		/*!
+		@function enable
+		@abstract enable or disable one or more alarms identified by its ids
+		@syntax enable($ids,$enable=True)
+		@param $ids array with alarm ids as keys (!)
+		@returns the number of alarms enabled or -1 for insuficent permission to do so
+		@note Not found alarms or insuficent perms stop the enableing of multiple alarms
+		*/
+		function enable($alarms,$enable=True)
+		{
+			$enabled = 0;
+			foreach ($alarms as $id => $field)
+			{
+				if (!($alarm = $this->so->read_alarm($id)))
+				{
+					return 0;	// alarm not found
+				}
+				if (!$alarm['enabled'] == !$enable)
+				{
+					continue;	// nothing to do
+				}
+				if ($enable && !$this->check_perms(PHPGW_ACL_SETALARM,$alarm['owner']) ||
+					!$enable && !$this->check_perms(PHPGW_ACL_DELETEALARM,$alarm['owner']))
+				{
+					return -1;
+				}
+				$alarm['enabled'] = (int)(!$alarm['enabled']);
+				if ($this->so->save_alarm($alarm['cal_id'],$alarm))
+				{
+					++$enabled;
+				}
+			}
+			return $enabled;
+		}
+
+		/*!
+		@function delete
+		@abstract delete one or more alarms identified by its ids
+		@syntax delete($ids)
+		@param $ids array with alarm ids as keys (!)
+		@returns the number of alarms deleted or -1 for insuficent permission to do so
+		@note Not found alarms or insuficent perms stop the deleting of multiple alarms
+		*/
+		function delete($alarms)
+		{
+			$deleted = 0;
+			foreach ($alarms as $id => $field)
+			{
+				if (!($alarm = $this->so->read_alarm($id)))
+				{
+					return 0;	// alarm not found
+				}
+				if (!$this->check_perms(PHPGW_ACL_DELETEALARM,$alarm['owner']))
+				{
+					return -1;
+				}
+				if ($this->so->delete_alarm($id))
+				{
+					++$deleted;
+				}
+			}
+			return $deleted;
+		}
+	}
+?>
Index: /tags/calendar/0.9.3/inc/class.bocustom_fields.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.bocustom_fields.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/inc/class.bocustom_fields.inc.php	(revision 2)
@@ -0,0 +1,97 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar - Custom fields and sorting                        *
+  * http://www.egroupware.org                                                *
+  * Written by Ralf Becker <RalfBecker@outdoor-training.de>                  *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	class bocustom_fields
+	{
+		var $stock_fields = array(
+			'title' => array(
+				'label' => 'Title',
+				'title' => True
+			),
+			'description' => 'Description',
+			'category'    => 'Category',
+			'location'    => 'Location',
+			'startdate'   => 'Start Date/Time',
+			'enddate'     => 'End Date/Time',
+			'priority'    => 'Priority',
+			'access'      => 'Access',
+			'participants'=> 'Participants',
+			'ex_participants'=> 'External Participants',
+			'owner'       => 'Created By',
+			'updated'     => 'Updated',
+			'alarm'       => 'Alarm',
+			'recure_type' => 'Repetition'
+		);
+
+		function bocustom_fields()
+		{
+			$this->config = CreateObject('phpgwapi.config','calendar');
+			$this->config->read_repository();
+
+			$this->fields = &$this->config->config_data['fields'];
+
+			if (!is_array($this->fields)) {
+				$this->fields = array();
+			}
+
+			foreach ($this->fields as $field => $data)	// this can be removed after a while
+			{
+				if (!isset($this->stock_fields[$field]) && $field[0] != '#')
+				{
+					unset($this->fields[$field]);
+					$this->fields['#'.$field] = $data;
+				}
+			}
+
+			foreach($this->stock_fields as $field => $data)
+			{
+				if (!is_array($data))
+				{
+					$data = array('label' => $data);
+				}
+				if (!isset($this->fields[$field]))
+				{
+					$this->fields[$field] = array(
+						'name'     => $field,
+						'title'    => $data['title'],
+						'disabled' => $data['disabled']
+					);
+				}
+				$this->fields[$field]['label']  = $data['label'];
+				$this->fields[$field]['length'] = $data['length'];
+				$this->fields[$field]['shown']  = $data['shown'];
+			}
+		}
+
+		function set($data)
+		{
+			if (is_array($data) && strlen($data['name']) > 0)
+			{
+				if (!isset($this->stock_fields[$name = $data['name']]))
+				{
+					$name = '#'.$name;
+				}
+				$this->fields[$name] = $data;
+			}
+		}
+
+		function save($fields=False)
+		{
+			if ($fields)
+			{
+				$this->fields = $fields;
+			}
+			//echo "<pre>"; print_r($this->config->config_data); echo "</pre>\n";
+			$this->config->save_repository();
+		}
+	}
Index: /tags/calendar/0.9.3/inc/class.calendar_holiday.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.calendar_holiday.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/inc/class.calendar_holiday.inc.php	(revision 2)
@@ -0,0 +1,313 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar Holidays                                           *
+  * http://www.egroupware.org                                                *
+  * Written by Mark Peters <skeeter@phpgroupware.org>                        *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	class calendar_holiday
+	{
+		var $db;
+		var $year;
+		var $tz_offset;
+		var $holidays = Array();
+		var $index = Array();
+		var $users = Array();
+		var $datetime;
+
+		function calendar_holiday($owner='')
+		{
+			$this->datetime = CreateObject('phpgwapi.date_time');
+			$this->db = $GLOBALS['phpgw']->db;
+			if(@$GLOBALS['phpgw_info']['user']['preferences']['common']['country'])
+			{
+				$this->users['user'] = $GLOBALS['phpgw_info']['user']['preferences']['common']['country'];
+			}
+			else
+			{
+				$this->users['user'] = 'US';
+			}
+			$owner_id = get_account_id($owner);
+			if($owner_id != $GLOBALS['phpgw_info']['user']['account_id'])
+			{
+				$owner_pref = CreateObject('phpgwapi.preferences',$owner_id);
+				$owner_prefs = $owner_pref->read_repository();
+				if(isset($owner_prefs['calendar']['locale']) && $owner_prefs['common']['country'])
+				{
+					$this->users['owner'] = $owner_prefs['common']['country'];
+				}
+				else
+				{
+					$this->users['owner'] = 'US';
+				}
+			}
+			if($GLOBALS['phpgw_info']['server']['auto_load_holidays'] == True)
+			{
+				while(list($key,$value) = each($this->users))
+				{
+					$this->is_network_load_needed($value);
+				}
+			}
+		}
+
+		function is_network_load_needed($locale)
+		{
+			$sql = "SELECT count(*) FROM phpgw_cal_holidays WHERE locale='".$locale."'";
+			$this->db->query($sql,__LINE__,__FILE__);
+			$this->db->next_record();
+			$rows = $this->db->f(0);
+			if($rows==0)
+			{
+				$this->load_from_network($locale);
+			}
+		}
+
+		function save_holiday($holiday)
+		{
+			if(isset($holiday['hol_id']) && $holiday['hol_id'])
+			{
+	//			echo "Updating LOCALE='".$holiday['locale']."' NAME='".$holiday['name']."' extra=(".$holiday['mday'].'/'.$holiday['month_num'].'/'.$holiday['occurence'].'/'.$holiday['dow'].'/'.$holiday['observance_rule'].")<br>\n";
+				$sql = "UPDATE phpgw_cal_holidays SET name='".$holiday['name']."', mday=".$holiday['mday'].', month_num='.$holiday['month_num'].', occurence='.$holiday['occurence'].', dow='.$holiday['dow'].', observance_rule='.(int)$holiday['observance_rule'].' WHERE hol_id='.$holiday['hol_id'];
+			}
+			else
+			{
+	//			echo "Inserting LOCALE='".$holiday['locale']."' NAME='".$holiday['name']."' extra=(".$holiday['mday'].'/'.$holiday['month_num'].'/'.$holiday['occurence'].'/'.$holiday['dow'].'/'.$holiday['observance_rule'].")<br>\n";
+				$sql = 'INSERT INTO phpgw_cal_holidays(locale,name,mday,month_num,occurence,dow,observance_rule) '
+					. "VALUES('".strtoupper($holiday['locale'])."','".$holiday['name']."',".$holiday['mday'].','.$holiday['month_num'].','.$holiday['occurence'].','.$holiday['dow'].','.(int)$holiday['observance_rule'].")";
+			}
+			$this->db->query($sql,__LINE__,__FILE__);
+		}
+
+		function delete_holiday($id)
+		{
+			$sql = 'DELETE FROM phpgw_cal_holidays WHERE hol_id='.$id;
+			$this->db->query($sql,__LINE__,__FILE__);
+		}
+
+		function delete_locale($locale)
+		{
+			$sql = "DELETE FROM phpgw_cal_holidays WHERE locale='".$locale."'";
+			$this->db->query($sql,__LINE__,__FILE__);
+		}
+
+		function load_from_network($locale)
+		{
+			@set_time_limit(0);
+
+			// get the file that contains the calendar events for your locale
+			// "http://www.phpgroupware.org/headlines.rdf";
+			$network = CreateObject('phpgwapi.network');
+			if(isset($GLOBALS['phpgw_info']['server']['holidays_url_path']) && $GLOBALS['phpgw_info']['server']['holidays_url_path'] != 'localhost')
+			{
+				$load_from = $GLOBALS['phpgw_info']['server']['holidays_url_path'];
+			}
+			else
+			{
+				$pos = strpos(' '.$GLOBALS['phpgw_info']['server']['webserver_url'],$_SERVER['HTTP_HOST']);
+				if($pos == 0)
+				{
+					switch($_SERVER['SERVER_PORT'])
+					{
+						case 80:
+							$http_protocol = 'http://';
+							break;
+						case 443:
+							$http_protocol = 'https://';
+							break;
+					}
+					$server_host = $http_protocol.$_SERVER['HTTP_HOST'].$GLOBALS['phpgw_info']['server']['webserver_url'];
+				}
+				else
+				{
+					$server_host = $GLOBALS['phpgw_info']['server']['webserver_url'];
+				}
+				$load_from = $server_host.'/calendar/setup';
+			}
+	//		echo 'Loading from: '.$load_from.'/holidays.'.strtoupper($locale)."<br>\n";
+			$lines = $network->gethttpsocketfile($load_from.'/holidays.'.strtoupper($locale));
+			if(!$lines)
+			{
+				return False;
+			}
+			$c_lines = count($lines);
+			for($i=0;$i<$c_lines;$i++)
+			{
+	//			echo 'Line #'.$i.' : '.$lines[$i]."<br>\n";
+				$holiday = explode("\t",$lines[$i]);
+				if(count($holiday) == 7)
+				{
+					$holiday['locale'] = $holiday[0];
+					$holiday['name'] = addslashes($holiday[1]);
+					$holiday['mday'] = (int)$holiday[2];
+					$holiday['month_num'] = (int)$holiday[3];
+					$holiday['occurence'] = (int)$holiday[4];
+					$holiday['dow'] = (int)$holiday[5];
+					$holiday['observance_rule'] = (int)$holiday[6];
+					$holiday['hol_id'] = 0;
+					$this->save_holiday($holiday);
+				}
+			}
+		}
+
+		function read_holiday()
+		{
+			$this->year = (int)$GLOBALS['phpgw']->calendar->tempyear;
+
+			$sql = $this->build_holiday_query();
+			if($sql == False)
+			{
+				return False;
+			}
+			$this->holidays = Null;
+			$this->db->query($sql,__LINE__,__FILE__);
+
+			$i = 0;
+			$temp_locale = $GLOBALS['phpgw_info']['user']['preferences']['common']['country'];
+			while($this->db->next_record())
+			{
+				$this->index[$this->db->f('hol_id')] = $i;
+				$this->holidays[$i]['locale'] = $this->db->f('locale');
+				$this->holidays[$i]['name'] = $GLOBALS['phpgw']->strip_html($this->db->f('name'));
+				$this->holidays[$i]['day'] = (int)$this->db->f('mday');
+				$this->holidays[$i]['month'] = (int)$this->db->f('month_num');
+				$this->holidays[$i]['occurence'] = (int)$this->db->f('occurence');
+				$this->holidays[$i]['dow'] = (int)$this->db->f('dow');
+				$this->holidays[$i]['observance_rule'] = $this->db->f('observance_rule');
+				if(count($this->users) == 2 && $this->users[0] != $this->users[1])
+				{
+					if($this->holidays[$i]['locale'] == $this->users[1])
+					{
+						$this->holidays[$i]['owner'] = 'user';
+					}
+					else
+					{
+						$this->holidays[$i]['owner'] = 'owner';
+					}
+				}
+				else
+				{
+					$this->holidays[$i]['owner'] = 'user';
+				}
+				$c = $i;
+				$GLOBALS['phpgw_info']['user']['preferences']['common']['country'] = $this->holidays[$i]['locale'];
+				$holidaycalc = CreateObject('calendar.holidaycalc');
+				$this->holidays[$i]['date'] = $holidaycalc->calculate_date($this->holidays[$i], $this->holidays, $this->year, $this->datetime, $c);
+				unset($holidaycalc);
+				if($c != $i)
+				{
+					$i = $c;
+				}
+				$i++;
+			}
+			$this->holidays = $this->sort_by_date($this->holidays);
+			$GLOBALS['phpgw_info']['user']['preferences']['common']['country'] = $temp_locale;
+			return $this->holidays;
+		}
+
+		function build_list_for_submission($locale)
+		{
+			$i = -1;
+			$this->db->query("SELECT * FROM phpgw_cal_holidays WHERE locale='".$locale."'");
+			while($this->db->next_record())
+			{
+				$i++;
+				$holidays[$i]['locale'] = $this->db->f('locale');
+				$holidays[$i]['name']   = $GLOBALS['phpgw']->strip_html($this->db->f('name'));
+				$holidays[$i]['day']    = (int)$this->db->f('mday');
+				$holidays[$i]['month']  = (int)$this->db->f('month_num');
+				$holidays[$i]['occurence'] = (int)$this->db->f('occurence');
+				$holidays[$i]['dow']    = (int)$this->db->f('dow');
+				$holidays[$i]['observance_rule'] = $this->db->f('observance_rule');
+			}
+			return $holidays;
+		}
+
+		function build_holiday_query()
+		{
+			if(!isset($this->users) || count($this->users) == 0)
+			{
+				return False;
+			}
+			$sql = 'SELECT * FROM phpgw_cal_holidays WHERE locale in (';
+			$find_it = '';
+			reset($this->users);
+			while(list($key,$value) = each($this->users))
+			{
+				if($find_it)
+				{
+					$find_it .= ',';
+				}
+				$find_it .= "'".$value."'";
+			}
+			$sql .= $find_it.')';
+
+			return $sql;
+		}
+
+		function sort_by_date($holidays)
+		{
+			$c_holidays = count($holidays);
+			for($outer_loop=0;$outer_loop<($c_holidays - 1);$outer_loop++)
+			{
+				$outer_date = $holidays[$outer_loop]['date'];
+				for($inner_loop=$outer_loop;$inner_loop<$c_holidays;$inner_loop++)
+				{
+					$inner_date = $holidays[$inner_loop]['date'];
+					if($outer_date > $inner_date)
+					{
+						$temp = $holidays[$inner_loop];
+						$holidays[$inner_loop] = $holidays[$outer_loop];
+						$holidays[$outer_loop] = $temp;
+					}
+				}
+			}
+			return $holidays;
+		}
+
+		function find_date($date)
+		{
+			if($this->holidays == Null)
+			{
+				return False;
+			}
+
+			$c_holidays = count($this->holidays);
+			for($i=0;$i<$c_holidays;$i++)
+			{
+				if($this->holidays[$i]['date'] > $date)
+				{
+					$i = $c_holidays + 1;
+				}
+				elseif($this->holidays[$i]['date'] == $date)
+				{
+					$return_value[] = $i;
+				}
+			}
+	//		echo 'Searching for '.$GLOBALS['phpgw']->common->show_date($date).'  Found = '.count($return_value)."<br>\n";
+			if(isset($return_value))
+			{
+				return $return_value;
+			}
+			else
+			{
+				return False;
+			}
+		}
+
+		function get_holiday($index)
+		{
+			return $this->holidays[$index];
+		}
+
+		function get_name($id)
+		{
+			return $this->holidays[$id]['name'];
+		}
+	}
+?>
Index: /tags/calendar/0.9.3/inc/hook_home_planner.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/hook_home_planner.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/inc/hook_home_planner.inc.php	(revision 2)
@@ -0,0 +1,26 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar - Planner                                          *
+  * http://www.egroupware.org                                                *
+  * Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
+  *          http://www.radix.net/~cknudsen                                  *
+  * Written by Mark Peters <skeeter@phpgroupware.org>                        *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	$d1 = strtolower(substr(PHPGW_APP_INC,0,3));
+	if($d1 == 'htt' || $d1 == 'ftp' )
+	{
+		echo 'Failed attempt to break in via an old Security Hole!<br>'."\n";
+		$GLOBALS['phpgw']->common->phpgw_exit();
+	}
+	unset($d1);
+
+	$GLOBALS['extra_data'] = '<table width="100%" cellpadding="0"><tr><td bgcolor="white">'.
+		ExecMethod('calendar.uicalendar.planner').'</td></tr></table>';
+?>
Index: /tags/calendar/0.9.3/inc/class.holidaycalc_US.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.holidaycalc_US.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/inc/class.holidaycalc_US.inc.php	(revision 2)
@@ -0,0 +1,84 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - holidaycalc_US                                              *
+  * http://www.egroupware.org                                                *
+  * Based on Yoshihiro Kamimura <your@itheart.com>                           *
+  *          http://www.itheart.com                                          *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	class holidaycalc
+	{
+		function calculate_date($holiday, &$holidays, $year, &$i)
+		{
+	//		if($holiday['day'] == 0 && $holiday['dow'] != 0 && $holiday['occurence'] != 0)
+			if($holiday['day'] == 0 && $holiday['occurence'] != 0)
+			{
+				if($holiday['occurence'] != 99)
+				{
+					$dow = $GLOBALS['phpgw']->datetime->day_of_week($year,$holiday['month'],1);
+					$day = (((7 * $holiday['occurence']) - 6) + ((($holiday['dow'] + 7) - $dow) % 7));
+					$day += ($day < 1 ? 7 : 0);
+					// What is the point of this?
+					// Add 7 when the holiday falls on a Monday???
+					//$day += ($holiday['dow']==1 ? 7 : 0);
+
+					// Sometimes the 5th occurance of a weekday (ie the 5th monday)
+					// can spill over to the next month.  This prevents that.
+					$ld = $GLOBALS['phpgw']->datetime->days_in_month($holiday['month'],$year);
+					if ($day > $ld)
+					{
+						return;
+					}
+				}
+				else
+				{
+					$ld = $GLOBALS['phpgw']->datetime->days_in_month($holiday['month'],$year);
+					$dow = $GLOBALS['phpgw']->datetime->day_of_week($year,$holiday['month'],$ld);
+					$day = $ld - (($dow + 7) - $holiday['dow']) % 7 ;
+				}
+			}
+			else
+			{
+				$day = $holiday['day'];
+				if($holiday['observance_rule'] == True)
+				{
+					$dow = $GLOBALS['phpgw']->datetime->day_of_week($year,$holiday['month'],$day);
+					// This now calulates Observed holidays and creates a new entry for them.
+					if($dow == 0)
+					{
+						$i++;
+						$holidays[$i]['locale'] = $holiday['locale'];
+						$holidays[$i]['name'] = $holiday['name'].' (Observed)';
+						$holidays[$i]['day'] = $holiday['day'] + 1;
+						$holidays[$i]['month'] = $holiday['month'];
+						$holidays[$i]['occurence'] = $holiday['occurence'];
+						$holidays[$i]['dow'] = $holiday['dow'];
+						$holidays[$i]['date'] = mktime(0,0,0,$holiday['month'],$day+1,$year);
+						$holidays[$i]['obervance_rule'] = 0;
+					}
+					elseif($dow == 6)
+					{
+						$i++;
+						$holidays[$i]['locale'] = $holiday['locale'];
+						$holidays[$i]['name'] = $holiday['name'].' (Observed)';
+						$holidays[$i]['day'] = $holiday['day'] - 1;
+						$holidays[$i]['month'] = $holiday['month'];
+						$holidays[$i]['occurence'] = $holiday['occurence'];
+						$holidays[$i]['dow'] = $holiday['dow'];
+						$holidays[$i]['date'] = mktime(0,0,0,$holiday['month'],$day-1,$year);
+						$holidays[$i]['obervance_rule'] = 0;
+					}
+				}
+			}
+			$date = mktime(0,0,0,$holiday['month'],$day,$year);
+
+			return $date;
+		}
+	}
+?>
Index: /tags/calendar/0.9.3/inc/class.uiholiday.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.uiholiday.inc.php	(revision 204)
+++ /tags/calendar/0.9.3/inc/class.uiholiday.inc.php	(revision 204)
@@ -0,0 +1,513 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar                                                    *
+  * http://www.egroupware.org                                                *
+  * Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
+  *          http://www.radix.net/~cknudsen                                  *
+  * Modified by Mark Peters <skeeter@phpgroupware.org>                       *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	class uiholiday
+	{
+		var $debug = False;
+		var $base_url;
+		var $bo;
+		var $template_dir;
+		var $holidays;
+		var $cat_id;
+
+		var $public_functions = array(
+			'admin' => True,
+			'edit_locale' => True,
+			'edit_holiday' => True,
+			'copy_holiday' => True,
+			'delete_holiday' => True,
+			'delete_locale'	=> True,
+			'submit'	=> True
+		);
+
+		function uiholiday()
+		{
+			$GLOBALS['phpgw']->nextmatchs = CreateObject('phpgwapi.nextmatchs');
+
+			$this->bo = CreateObject('calendar.boholiday');
+			$this->bo->check_admin();
+			$this->base_url = $this->bo->base_url;
+			$this->template_dir = $GLOBALS['phpgw']->common->get_tpl_dir('calendar');
+			$this->sb = CreateObject('phpgwapi.sbox');
+
+			$GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['calendar']['title'].' - '.lang('Holiday Management');
+		}
+
+		function admin()
+		{
+			unset($GLOBALS['phpgw_info']['flags']['noheader']);
+			unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+			$GLOBALS['phpgw_info']['flags']['noappfooter'] = True;
+			$GLOBALS['phpgw']->common->phpgw_header();
+
+			$p = &$GLOBALS['phpgw']->template;
+			$p->set_file(Array('locales'=>'locales.tpl'));
+			$p->set_block('locales','list','list');
+			$p->set_block('locales','row','row');
+			$p->set_block('locales','row_empty','row_empty');
+			$p->set_block('locales','submit_column','submit_column');
+
+			$var = Array(
+				'th_bg'		=> $GLOBALS['phpgw_info']['theme']['th_bg'],
+				'left_next_matchs'	=> $GLOBALS['phpgw']->nextmatchs->left('/index.php?menuaction=calendar.uiholiday.admin',$this->bo->start,$this->bo->total),
+				'right_next_matchs'	=> $GLOBALS['phpgw']->nextmatchs->right('/index.php?menuaction=calendar.uiholiday.admin',$this->bo->start,$this->bo->total),
+				'center'			=> '<td align="center">'.lang('Countries').'</td>',
+				'sort_name'		=> $GLOBALS['phpgw']->nextmatchs->show_sort_order($this->bo->sort,'locale',$this->bo->order,'/calendar/'.basename($SCRIPT_FILENAME),lang('Country')),
+				'header_edit'	=> lang('Edit'),
+				'header_delete'	=> lang('Delete'),
+				'header_extra'	=> lang('Submit to Repository'),
+				'extra_width'  => 'width="45%"',
+				'rule'         => '',
+				'header_rule'  => '',
+				'back_button'	=> ''
+			);
+
+			$p->set_var($var);
+
+			$locales = $this->bo->get_locale_list($this->bo->sort, $this->bo->order, $this->bo->query, $this->bo->total);
+			@reset($locales);
+			if (!$locales)
+			{
+				$p->set_var('message',lang('no matches found'));
+				$p->parse('rows','row_empty',True);
+			}
+			else
+			{
+				$p->set_var('submit_extra',' width="5%"');
+				while (list(,$value) = each($locales))
+				{
+					$tr_color = $GLOBALS['phpgw']->nextmatchs->alternate_row_color($tr_color);
+					if (! $value)  $value  = '&nbsp;';
+
+					$var = Array(
+						'tr_color'		=> $tr_color,
+						'group_name'	=> $value,
+						'edit_link'		=> '<a href="'.$GLOBALS['phpgw']->link($this->base_url,Array('menuaction'=>'calendar.uiholiday.edit_locale','locale'=>$value)) . '"> '.lang('Edit').' </a>',
+						'delete_link'	=> '<a href="'.$GLOBALS['phpgw']->link($this->base_url,Array('menuaction'=>'calendar.uiholiday.delete_locale','locale'=>$value)).'"> '.lang('Delete').' </a>',
+						'extra_link'	=> '<a href="'.$GLOBALS['phpgw']->link($this->base_url,Array('menuaction'=>'calendar.uiholiday.submit','locale'=>$value)).'"> '.lang('Submit').' </a>'.
+							' &nbsp; &nbsp; <a href="'.$GLOBALS['phpgw']->link($this->base_url,Array('menuaction'=>'calendar.uiholiday.submit','locale'=>$value,'download'=>1)).'"> '.lang('Download').' </a>'
+					);
+					$p->set_var($var);
+					$p->parse('rows','row',True);
+				}
+			}
+
+			$var = Array(
+				'new_action'		=> $GLOBALS['phpgw']->link($this->base_url,Array('menuaction'=>'calendar.uiholiday.edit_holiday','id'=>0)),
+				'lang_add'			=> lang('add'),
+				'search_action'	=> $GLOBALS['phpgw']->link($this->base_url,Array('menuaction'=>'calendar.uiholiday.admin')),
+				'lang_search'		=> lang('search')
+			);
+
+			$p->set_var($var);
+			$p->pparse('out','list');
+		}
+
+		function edit_locale($locale='')
+		{
+			if ($locale === '')
+			{
+				$locale = $this->bo->locale;
+			}
+			if ($locale)
+			{
+				$this->bo->locales = array($locale);
+				$this->bo->total = $this->bo->so->holiday_total($locale,$this->bo->query);
+			}
+			if(!$this->bo->total && !isset($this->bo->query))
+			{
+				$link_params = Array(
+					'menuaction'	=> 'calendar.uiholiday.admin'
+				);
+				$GLOBALS['phpgw']->redirect_link($this->base_url,$link_params);
+			}
+			unset($GLOBALS['phpgw_info']['flags']['noheader']);
+			unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+			$GLOBALS['phpgw_info']['flags']['noappfooter'] = True;
+			$GLOBALS['phpgw']->common->phpgw_header();
+			$p = CreateObject('phpgwapi.Template',$this->template_dir);
+			$p->set_file(Array('locale'=>'locales.tpl'));
+			$p->set_block('locale','list','list');
+			$p->set_block('locale','row','row');
+			$p->set_block('locale','row_empty','row_empty');
+			$p->set_block('locale','back_button_form','back_button_form');
+
+			if (!is_object($GLOBALS['phpgw']->html))
+			{
+				$GLOBALS['phpgw']->html = CreateObject('phpgwapi.html');
+			}
+			$html = &$GLOBALS['phpgw']->html;
+			$year_form = str_replace('<option value=""></option>','',$html->form($html->sbox_submit($this->sb->getYears('year',$this->bo->year),true),array(),
+				$this->base_url,Array('menuaction'=>'calendar.uiholiday.edit_locale','locale'=>$this->bo->locales[0])));
+			unset($html);
+
+			$holidays = $this->bo->get_holiday_list();
+			$total = count($holidays);
+
+			$var = Array(
+				'th_bg'				=> $GLOBALS['phpgw_info']['theme']['th_bg'],
+				'left_next_matchs'	=> $GLOBALS['phpgw']->nextmatchs->left('/index.php',$this->bo->start,$total,'&menuaction=calendar.uiholiday.edit_locale&locale='.$this->bo->locales[0].'&year='.$this->bo->year),
+				'right_next_matchs'	=> $GLOBALS['phpgw']->nextmatchs->right('/index.php',$this->bo->start,$total,'&menuaction=calendar.uiholiday.edit_locale&locale='.$this->bo->locales[0].'&year='.$this->bo->year),
+				'center'			=> '<td align="right">'.lang('Holidays').' ('.$this->bo->locales[0].')</td><td align="left">'.$year_form.'</td>',
+				'sort_name'			=> $GLOBALS['phpgw']->nextmatchs->show_sort_order($this->bo->sort,'name',$this->bo->order,'/index.php',lang('Holiday'),'&menuaction=calendar.uiholiday.edit_locale&locale='.$this->bo->locales[0].'&year='.$this->bo->year),
+				'header_edit'		=> lang('Edit'),
+				'header_delete'		=> lang('Delete'),
+				'header_rule'		=> '<td>'.$GLOBALS['phpgw']->nextmatchs->show_sort_order($this->bo->sort,'month_num,mday',$this->bo->order,'/index.php',lang('Rule'),'&menuaction=calendar.uiholiday.edit_locale&locale='.$this->bo->locales[0].'&year='.$this->bo->year).'</td>',
+				'header_extra'		=> lang('Copy'),
+				'extra_width'		=> 'width="5%"'
+			);
+
+			$p->set_var($var);
+
+			if (!count($holidays))
+			{
+				$p->set_var('message',lang('no matches found'));
+				$p->parse('rows','row_empty',True);
+			}
+			else
+			{
+				$maxmatchs = $GLOBALS['phpgw_info']['user']['preferences']['common']['maxmatchs'];
+				$end = min($total,$this->bo->start+$maxmatchs);
+				$p->set_var('rows',lang('showing %1 - %2 of %3',1+$this->bo->start,$end,$total));
+				for($i=$this->bo->start; $i < $end; $i++)
+				{
+					$tr_color = $GLOBALS['phpgw']->nextmatchs->alternate_row_color($tr_color);
+					if (!$holidays[$i]['name'])
+					{
+						$holidays[$i]['name'] = '&nbsp;';
+					}
+					
+					$var = Array(
+						'tr_color'		=> $tr_color,
+						'header_delete'=> lang('Delete'),
+						'group_name'	=> $holidays[$i]['name'],
+						'rule'			=> '<td>'.$this->bo->rule_string($holidays[$i]).'</td>',
+						'edit_link'		=> '<a href="'.$GLOBALS['phpgw']->link($this->base_url,Array('menuaction'=>'calendar.uiholiday.edit_holiday','locale'=>$this->bo->locales[0],'id'=>$holidays[$i]['index'],'year'=>$this->bo->year)).'"> '.lang('Edit').' </a>',
+						'extra_link'	=> '<a href="'.$GLOBALS['phpgw']->link($this->base_url,Array('menuaction'=>'calendar.uiholiday.copy_holiday','locale'=>$this->bo->locales[0],'id'=>$holidays[$i]['index'],'year'=>$this->bo->year)).'"> '.lang('Copy').' </a>',
+						'delete_link'	=> '<a href="'.$GLOBALS['phpgw']->link($this->base_url,Array('menuaction'=>'calendar.uiholiday.delete_holiday','locale'=>$this->bo->locales[0],'id'=>$holidays[$i]['index'],'year'=>$this->bo->year)).'"> '.lang('Delete').' </a>'
+					);
+
+					$p->set_var($var);
+					$p->parse('rows','row',True);
+				}
+			}
+
+			$var = Array(
+				'new_action'	=> $GLOBALS['phpgw']->link($this->base_url,Array('menuaction'=>'calendar.uiholiday.edit_holiday','locale'=>$this->bo->locales[0],'id'=>0,'year'=>$this->bo->year)),
+				'lang_add'		=> lang('add'),
+				'back_action'	=> $GLOBALS['phpgw']->link($this->base_url,Array('menuaction'=>'calendar.uiholiday.admin')),
+				'lang_back'		=> lang('Back'),
+				'search_action'=> $GLOBALS['phpgw']->link($this->base_url,Array('menuaction'=>'calendar.uiholiday.edit_locale','locale'=>$this->bo->locales[0],'year'=>$this->bo->year)),
+				'lang_search'	=> lang('search')
+			);
+			$p->set_var($var);
+			$p->parse('back_button','back_button_form',False);
+			$p->pparse('out','list');
+		}
+
+		function copy_holiday()
+		{
+			if(@$this->bo->id)
+			{
+				$holiday = $this->bo->read_entry($this->bo->id);
+			}
+			$this->bo->id = 0;
+
+			if (!$holiday['occurence'] || $holiday['occurence'] >= 1900)
+			{
+				$holiday['occurence'] = date('Y');
+			}
+			$this->edit_holiday('',$holiday);
+		}
+
+		function edit_holiday($error='',$holiday='')
+		{
+			if(@$this->bo->id && !$holiday)
+			{
+				$holiday = $this->bo->read_entry($this->bo->id);
+			}
+			if ($this->locale)
+			{
+				$holiday['locale'] = $this->locale;
+			}
+			unset($GLOBALS['phpgw_info']['flags']['noheader']);
+			unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+			$GLOBALS['phpgw_info']['flags']['noappfooter'] = True;
+			$GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['calendar']['title'].' - '.($this->bo->id ? lang('Edit') : lang('Add')).' '.lang('Holiday');
+			$GLOBALS['phpgw']->common->phpgw_header();
+
+			$t = &$GLOBALS['phpgw']->template;
+			$t->set_file(Array('holiday'=>'holiday.tpl','form_button'=>'form_button_script.tpl'));
+			$t->set_block('holiday','form','form');
+			$t->set_block('holiday','list','list');
+
+			if (@count($error))
+			{
+				$message = $GLOBALS['phpgw']->common->error_list($error);
+			}
+			else
+			{
+				$message = '';
+			}
+	
+			$var = Array(
+				'title_holiday' => ($this->bo->id ? lang('Edit') : lang('Add')).' '.lang('Holiday'),
+				'message'       => $message,
+				'actionurl'     => $GLOBALS['phpgw']->link($this->base_url,'menuaction=calendar.boholiday.add&year='.$this->bo->year),
+				'hidden_vars'   => '<input type="hidden" name="holiday[hol_id]" value="'.$this->bo->id.'">'."\n"
+					. '<input type="hidden" name="holiday[locales]" value="'.$this->bo->locales[0].'">'."\n"
+			);
+			$t->set_var($var);
+
+// Locale
+			$this->display_item($t,lang('Country'),$this->sb->form_select($holiday['locale'],'holiday[locale]'));
+
+// Title/Name
+			$this->display_item($t,lang('title'),'<input name="holiday[name]" size="60" maxlength="50" value="'.$holiday['name'].'">');
+
+// Date
+			$this->display_item($t,lang('Date'),$GLOBALS['phpgw']->common->dateformatorder($this->sb->getYears('holiday[year]',$holiday['occurence']>1900?$holiday['occurence']:0),$this->sb->getMonthText('holiday[month_num]',$holiday['month']),$this->sb->getDays('holiday[mday]',$holiday['day'])).
+				'&nbsp;'.lang('Set a Year only for one-time / non-regular holidays.'));
+
+// Occurence
+			$occur = Array(
+				0	=> '',
+				1	=> '1.',
+				2	=> '2.',
+				3	=> '3.',
+				4	=> '4.',
+				5	=> '5.',
+				99	=> lang('Last')
+			);
+			$out = '';
+			while(list($key,$value) = each($occur))
+			{
+				$out .= '<option value="'.$key.'"'.($holiday['occurence']==$key?' selected':'').'>'.$value.'</option>'."\n";
+			}
+			$occurence_html = '<select name="holiday[occurence]">'."\n".$out.'</select>'."\n";
+
+			$dow = Array(
+				0	=> lang('Sun'),
+				1	=> lang('Mon'),
+				2	=> lang('Tue'),
+				3	=> lang('Wed'),
+				4	=> lang('Thu'),
+				5	=> lang('Fri'),
+				6	=> lang('Sat')
+			);
+			$out = '';
+			for($i=0;$i<7;$i++)
+			{
+				$out .= '<option value="'.$i.'"'.($holiday['dow']==$i?' selected':'').'>'.$dow[$i].'</option>'."\n";
+			}
+			$dow_html = '<select name="holiday[dow]">'."\n".$out.'</select>'."\n";
+			$this->display_item($t,lang('Occurence'),$occurence_html.'&nbsp;'.$dow_html.
+				'&nbsp;'.lang('You can either set a Year or a Occurence, not both !!!'));
+			$this->display_item($t,lang('Observance Rule'),'<input type="checkbox" name="holiday[observance_rule]" value="True"'.($holiday['observance_rule']?' checked':'').'>'.
+				'&nbsp;'.lang('If checked holidays falling on a weekend, are taken on the monday after.'));
+
+			$t->set_var('lang_add',lang('Save'));
+			$t->set_var('lang_reset',lang('Reset'));
+
+			if(@$this->bo->locales[0])
+			{
+				$link_params = Array(
+					'menuaction'	=> 'calendar.uiholiday.edit_locale',
+					'year'			=> $this->bo->year,
+					'locale'		=> $this->bo->locales[0]
+				);
+			}
+			else
+			{
+				$link_params = Array(
+					'menuaction'	=> 'calendar.uiholiday.admin'
+				);
+			}
+			
+			$t->set_var(Array(
+				'action_url_button'	=> $GLOBALS['phpgw']->link($this->base_url,$link_params),
+				'action_text_button'	=> lang('Cancel'),
+				'action_confirm_button'	=> '',
+				'action_extra_field'	=> ''
+			));
+			$t->parse('cancel_button','form_button');
+			
+			if ($this->bo->id)
+			{
+				$link_params = Array(
+					'menuaction'	=> 'calendar.uiholiday.delete_holiday',
+					'year'			=> $this->bo->year,
+					'locale'		=> $this->bo->locales[0],
+					'id'			=> $this->bo->id
+				);
+				$t->set_var(Array(
+					'action_url_button'	=> $GLOBALS['phpgw']->link($this->base_url,$link_params),
+					'action_text_button'	=> lang('Delete'),
+					'action_confirm_button'	=> '',
+					'action_extra_field'	=> ''
+				));
+				$t->parse('delete_button','form_button');
+			}
+			else
+			{
+				$t->set_var('delete_button','&nbsp;');
+			}
+			$t->pparse('out','form');
+		}
+
+
+		function delete_locale()
+		{
+			if(!$this->bo->total)
+			{
+				$this->admin();
+			}
+
+			unset($GLOBALS['phpgw_info']['flags']['noheader']);
+			unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+			$GLOBALS['phpgw_info']['flags']['noappfooter'] = True;
+			$GLOBALS['phpgw']->common->phpgw_header();
+
+			$p = CreateObject('phpgwapi.Template',$this->template_dir);
+			$p->set_file(Array('form'=>'delete_common.tpl','form_button'=>'form_button_script.tpl'));
+		
+			$p->set_var('messages',lang('Are you sure want to delete this Country?')."<br>".$this->bo->locales[0]);
+
+			$var = Array(
+				'action_url_button'	=> $GLOBALS['phpgw']->link($this->base_url,Array('menuaction'=>'calendar.uiholiday.admin')),
+				'action_text_button'	=> lang('No'),
+				'action_confirm_button'	=> '',
+				'action_extra_field'	=> ''
+			);
+			$p->set_var($var);
+			$p->parse('no','form_button');
+
+			$var = Array(
+				'action_url_button'	=> $GLOBALS['phpgw']->link($this->base_url,Array('menuaction'=>'calendar.boholiday.delete_locale','locale'=>$this->bo->locales[0])),
+				'action_text_button'	=> lang('Yes'),
+				'action_confirm_button'	=> '',
+				'action_extra_field'	=> ''
+			);
+			$p->set_var($var);
+			$p->parse('yes','form_button');
+
+			$p->pparse('out','form');
+		}
+
+		function delete_holiday()
+		{
+			$holiday = $this->bo->read_entry($this->bo->id);
+
+			if(!$holiday)
+			{
+				$this->edit_locale();
+			}
+			
+			unset($GLOBALS['phpgw_info']['flags']['noheader']);
+			unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+			$GLOBALS['phpgw_info']['flags']['noappfooter'] = True;
+			$GLOBALS['phpgw']->common->phpgw_header();
+
+			$p = CreateObject('phpgwapi.Template',$this->template_dir);
+			$p->set_file(Array('form'=>'delete_common.tpl','form_button'=>'form_button_script.tpl'));
+		
+			$p->set_var('messages',lang('Are you sure want to delete this holiday?')."<br>".$holiday['name'].' ('.$this->bo->locales[0].') '.$this->bo->rule_string($holiday));
+
+			$var = Array(
+				'action_url_button'	=> $GLOBALS['phpgw']->link($this->base_url,Array('menuaction'=>'calendar.uiholiday.edit_locale','locale'=>$this->bo->locales[0],'year'=>$this->bo->year)),
+				'action_text_button'	=> lang('No'),
+				'action_confirm_button'	=> '',
+				'action_extra_field'	=> ''
+			);
+			$p->set_var($var);
+			$p->parse('no','form_button');
+
+			$var = Array(
+				'action_url_button'	=> $GLOBALS['phpgw']->link($this->base_url,Array('menuaction'=>'calendar.boholiday.delete_holiday','locale'=>$this->bo->locales[0],'id'=>$this->bo->id,'year'=>$this->bo->year)),
+				'action_text_button'	=> lang('Yes'),
+				'action_confirm_button'	=> '',
+				'action_extra_field'	=> ''
+			);
+			$p->set_var($var);
+			$p->parse('yes','form_button');
+
+			$p->pparse('out','form');
+		}
+
+		function submit()
+		{
+			if(!@$this->bo->locales[0])
+			{
+				$this->admin();
+			}
+			$this->bo->year = 0;	// for a complete list with all years
+			$holidays = $this->bo->get_holiday_list();
+
+			if (isset($_GET['download']))
+			{
+				$locale = $this->bo->locales[0];
+				$browser = CreateObject('phpgwapi.browser');
+				$browser->content_header("holidays.$locale.csv",'text/text');
+				unset($browser);
+
+				while (list(,$holiday) = @each($holidays))
+				{
+					echo "$locale\t$holiday[name]\t$holiday[day]\t$holiday[month]\t$holiday[occurence]\t$holiday[dow]\t$holiday[observance_rule]\n";
+				}
+				$GLOBALS['phpgw']->common->phpgw_exit();
+			}
+			elseif($this->debug)
+			{
+				$action = $GLOBALS['phpgw']->link('/calendar/phpgroupware.org/accept_holiday.php');
+			}
+			else
+			{
+				$action = 'http://www.egroupware.org/cal/accept_holiday.php';
+			}
+			$GLOBALS['phpgw_info']['flags']['noappheader']	= True;
+			$GLOBALS['phpgw_info']['flags']['noappfooter'] = True;
+			$GLOBALS['phpgw_info']['flags']['nofooter'] = True;
+			$GLOBALS['phpgw']->common->phpgw_header();
+
+			echo '<body onLoad="document.submitform.submit()">'."\n";
+			echo '<form action="'.$action.'" method="post" name="submitform">'."\n";
+
+			$c_holidays = count($holidays);
+			echo '<input type="hidden" name="locale" value="'.$this->bo->locales[0].'">'."\n";
+			for($i=0;$i<$c_holidays;$i++)
+			{
+				echo '<input type="hidden" name="name[]" value="'.htmlspecialchars($holidays[$i]['name']).'">'."\n"
+					. '<input type="hidden" name="day[]" value="'.$holidays[$i]['day'].'">'."\n"
+					. '<input type="hidden" name="month[]" value="'.$holidays[$i]['month'].'">'."\n"
+					. '<input type="hidden" name="occurence[]" value="'.$holidays[$i]['occurence'].'">'."\n"
+					. '<input type="hidden" name="dow[]" value="'.$holidays[$i]['dow'].'">'."\n"
+					. '<input type="hidden" name="observance[]" value="'.$holidays[$i]['observance_rule'].'">'."\n";
+			}
+			echo "</form>\n</body>\n</head>";
+		}
+
+		/* private functions */
+		function display_item(&$p,$field,$data)
+		{
+			$var = Array(
+				'tr_color' => $GLOBALS['phpgw']->nextmatchs->alternate_row_color(),
+				'field'	=> $field,
+				'data'	=> $data
+			);
+			$p->set_var($var);
+			$p->parse('rows','list',True);
+		}
+	}
+?>
Index: /tags/calendar/0.9.3/inc/class.uialarm.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.uialarm.inc.php	(revision 204)
+++ /tags/calendar/0.9.3/inc/class.uialarm.inc.php	(revision 204)
@@ -0,0 +1,234 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar                                                    *
+  * http://www.egroupware.org                                                *
+  * Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
+  *          http://www.radix.net/~cknudsen                                  *
+  * Modified by Mark Peters <skeeter@phpgroupware.org>                       *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	class uialarm
+	{
+		var $template;
+		var $template_dir;
+
+		var $bo;
+		var $event;
+
+		var $debug = False;
+//		var $debug = True;
+
+		var $tz_offset;
+		var $theme;
+
+		var $public_functions = array(
+			'manager' => True
+		);
+
+		function uialarm()
+		{
+			$GLOBALS['phpgw']->nextmatchs = CreateObject('phpgwapi.nextmatchs');
+			$GLOBALS['phpgw']->browser    = CreateObject('phpgwapi.browser');
+			
+			$this->theme = $GLOBALS['phpgw_info']['theme'];
+
+			$this->bo = CreateObject('calendar.boalarm');
+
+			if($this->debug)
+			{
+				echo "BO Owner : ".$this->bo->owner."<br>\n";
+			}
+			$this->template_dir = $GLOBALS['phpgw']->common->get_tpl_dir('calendar');
+
+			if (!is_object($GLOBALS['phpgw']->html))
+			{
+				$GLOBALS['phpgw']->html = CreateObject('phpgwapi.html');
+			}
+			$this->html = &$GLOBALS['phpgw']->html;
+		}
+
+		function prep_page()
+		{
+			if ($this->bo->cal_id <= 0 ||
+				!$this->event = $this->bo->read_entry($this->bo->cal_id))
+			{
+				$GLOBALS['phpgw']->redirect_link('/index.php',Array(
+					'menuaction'	=> 'calendar.uicalendar.index'
+				));
+			}
+
+			unset($GLOBALS['phpgw_info']['flags']['noheader']);
+			unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+			$GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['calendar']['title'].' - '.lang('Alarm Management');
+			$GLOBALS['phpgw']->common->phpgw_header();
+
+			$this->template = CreateObject('phpgwapi.Template',$this->template_dir);
+
+			$this->template->set_unknowns('remove');
+			$this->template->set_file(
+				Array(
+					'alarm'	=> 'alarm.tpl'
+				)
+			);
+			$this->template->set_block('alarm','alarm_management','alarm_management');
+			$this->template->set_block('alarm','alarm_headers','alarm_headers');
+			$this->template->set_block('alarm','list','list');
+			$this->template->set_block('alarm','hr','hr');
+			$this->template->set_block('alarm','buttons','buttons');
+		}
+
+		function output_template_array($row,$list,$var)
+		{
+			if (!isset($var['tr_color']))
+			{
+				$var['tr_color'] = $GLOBALS['phpgw']->nextmatchs->alternate_row_color();
+			}
+			$this->template->set_var($var);
+			$this->template->parse($row,$list,True);
+		}
+
+		/* Public functions */
+
+		function manager()
+		{
+			if ($_POST['cancel'])
+			{
+				$GLOBALS['phpgw']->redirect_link('/index.php','menuaction='.($_POST['return_to'] ? $_POST['return_to'] : 'calendar.uicalendar.index'));
+			}
+			if ($_POST['delete'] && count($_POST['alarm']))
+			{
+				if ($this->bo->delete($_POST['alarm']) < 0)
+				{
+					echo '<center>'.lang('You do not have permission to delete this alarm !!!').'</center>';
+					$GLOBALS['phpgw']->common->phpgw_exit(True);
+				}
+			}
+			if (($_POST['enable'] || $_POST['disable']) && count($_POST['alarm']))
+			{
+				if ($this->bo->enable($_POST['alarm'],$_POST['enable']) < 0)
+				{
+					echo '<center>'.lang('You do not have permission to enable/disable this alarm !!!').'</center>';
+					$GLOBALS['phpgw']->common->phpgw_exit(True);
+				}
+			}
+			$this->prep_page();
+
+			if ($_POST['add'])
+			{
+				// Unix time format of event start
+				$start_event=mktime( $this->bo->bo->so->cal->event['start']['hour'] ,
+									 $this->bo->bo->so->cal->event['start']['min'] ,
+									 $this->bo->bo->so->cal->event['start']['sec'] ,
+									 $this->bo->bo->so->cal->event['start']['month'] ,
+									 $this->bo->bo->so->cal->event['start']['mday'],
+									 $this->bo->bo->so->cal->event['start']['year'] );
+				$time = (int)($_POST['time']['days'])*24*3600 +
+					(int)($_POST['time']['hours'])*3600 +
+					(int)($_POST['time']['mins'])*60;
+				$alarm_time = $start_event - $time;
+				
+				if ($alarm_time <= time())
+				{
+					echo lang('Alarm is older than now!!!');
+					$GLOBALS['phpgw']->common->phpgw_exit(True);
+				}
+				
+				foreach ( $this->bo->bo->so->cal->event['alarm'] as $object ){
+					if ($object['time'] == $alarm_time)
+					{
+						echo '<center>'.lang('Alarm already added!!!').'</center>';
+						$GLOBALS['phpgw']->common->phpgw_exit(True);
+					}
+				}
+
+				if ($time > 0 && !$this->bo->add($this->event,$time,$_POST['owner']))
+				{
+					echo '<center>'.lang('You do not have permission to add alarms to this event !!!').'</center>';
+					$GLOBALS['phpgw']->common->phpgw_exit(True);
+				}
+			}
+			if (!ExecMethod('calendar.uicalendar.view_event',$this->event))
+			{
+				echo '<center>'.lang('You do not have permission to read this record!').'</center>';
+				$GLOBALS['phpgw']->common->phpgw_exit(True);
+			}
+			echo "<br>\n";
+			$GLOBALS['phpgw']->template->set_var('th_bg',$this->theme['th_bg']);
+			$GLOBALS['phpgw']->template->set_var('hr_text',lang('Alarms').':');
+			$GLOBALS['phpgw']->template->fp('row','hr',True);
+			$GLOBALS['phpgw']->template->pfp('phpgw_body','view_event');
+
+			$var = Array(
+				'tr_color'		=> $this->theme['th_bg'],
+				'lang_select'	=> lang('Select'),
+				'lang_time'		=> lang('Time'),
+				'lang_text'		=> lang('Text'),
+				'lang_owner'	=> lang('Owner'),
+				'lang_enabled'	=> lang('enabled'),
+				'lang_disabled'	=> lang('disabled'),
+			);
+			if($this->event['alarm'])
+			{
+				$this->output_template_array('rows','alarm_headers',$var);
+
+				foreach($this->event['alarm'] as $key => $alarm)
+				{
+					if (!$this->bo->check_perms(PHPGW_ACL_READALARM,$alarm['owner']))
+					{
+						continue;
+					}
+					$var = Array(
+						'field'    => $GLOBALS['phpgw']->common->show_date($alarm['time']),
+						//'data'   => $alarm['text'],
+						'data'     => lang('Email Notification'),
+						'owner'    => $GLOBALS['phpgw']->common->grab_owner_name($alarm['owner']),
+						'enabled'  => $this->html->image('calendar',$alarm['enabled']?'enabled':'disabled',$alarm['enabled']?'enabled':'disabled','width="13" height="13"'),
+						'select'   => $this->html->checkbox("alarm[$alarm[id]]")
+					);
+					if ($this->bo->check_perms(PHPGW_ACL_DELETEALARM,$alarm['owner']))
+					{
+						++$to_delete;
+					}
+					$this->output_template_array('rows','list',$var);
+				}
+				$this->template->set_var('enable_button',$this->html->submit_button('enable','Enable'));
+				$this->template->set_var('disable_button',$this->html->submit_button('disable','Disable'));
+				if ($to_delete)
+				{
+					$this->template->set_var('delete_button',$this->html->submit_button('delete','Delete',"return confirm('".lang("Are you sure want to delete these alarms?")."')"));
+				}
+				$this->template->parse('rows','buttons',True);
+			}
+			if (isset($this->event['participants'][(int)$GLOBALS['phpgw_info']['user']['account_id']]))
+			{
+				$this->template->set_var(Array(
+					'input_days'    => $this->html->select('time[days]',$_POST['time']['days'],range(0,31),True).' '.lang('days'),
+					'input_hours'   => $this->html->select('time[hours]',$_POST['time']['hours'],range(0,24),True).' '.lang('hours'),
+					'input_minutes' => $this->html->select('time[mins]',$_POST['time']['mins'],range(0,60),True).' '.lang('minutes').' '.lang('before the event'),
+					'input_owner'   => $this->html->select('owner',$GLOBALS['phpgw_info']['user']['account_id'],$this->bo->participants($this->event,True),True),
+					'input_add'     => $this->html->submit_button('add','Add Alarm'),
+				));
+			}
+			$this->template->set_var(Array(
+				'action_url'	=> $GLOBALS['phpgw']->link('/index.php',Array('menuaction'=>'calendar.uialarm.manager')),
+				'hidden_vars'	=> $this->html->input_hidden(array(
+					'cal_id' => $this->bo->cal_id,
+					'return_to' => $_POST['return_to']
+				)),
+				'lang_enable'	=> lang('Enable'),
+				'lang_disable'	=> lang('Disable'),
+				'input_cancel'  => $this->html->submit_button('cancel','Cancel')
+			));
+//echo "<p>alarm_management='".htmlspecialchars($this->template->get_var('alarm_management'))."'</p>\n";
+			$this->template->pfp('out','alarm_management');
+			$GLOBALS['phpgw']->common->phpgw_footer();
+		}
+	
+	}
+?>
Index: /tags/calendar/0.9.3/inc/class.bocalendar.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.bocalendar.inc.php	(revision 641)
+++ /tags/calendar/0.9.3/inc/class.bocalendar.inc.php	(revision 641)
@@ -0,0 +1,3770 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar                                                    *
+  * http://www.eGroupWare.org                                                *
+  * Maintained and further developed by RalfBecker@outdoor-training.de       *
+  * Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
+  *          http://www.radix.net/~cknudsen                                  *
+  * Originaly modified by Mark Peters <skeeter@phpgroupware.org>             *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	class bocalendar
+	{
+		var $public_functions = Array(
+			'read_entry'      => True,
+			'delete_entry'    => True,
+			'delete_calendar' => True,
+			'change_owner'    => True,
+			'update'          => True,
+			'check_set_default_prefs' => True,
+			'store_to_cache'  => True,
+			'export_event'    => True,
+			'send_alarm'      => True,
+			'reinstate'       => True
+		);
+
+		var $soap_functions = Array(
+			'read_entry' => Array(
+				'in' => Array(
+					'int'
+				),
+				'out' => Array(
+					'SOAPStruct'
+				)
+			),
+			'delete_entry' => Array(
+				'in' => Array(
+					'int'
+				),
+				'out' => Array(
+					'int'
+				)
+			),
+			'delete_calendar' => Array(
+				'in' => Array(
+					'int'
+				),
+				'out' => Array(
+					'int'
+				)
+			),
+			'change_owner' => Array(
+				'in' => Array(
+					'array'
+				),
+				'out' => Array(
+					'int'
+				)
+			),
+			'update' => Array(
+				'in' => Array(
+					'array',
+					'array',
+					'array',
+					'array',
+					'array'
+				),
+				'out' => Array(
+					'array'
+				)
+			),
+			'store_to_cache'	=> Array(
+				'in' => Array(
+					'struct'
+				),
+				'out' => Array(
+					'SOAPStruct'
+				)
+			),
+			'store_to_cache'	=> Array(
+				'in' => Array(
+					'array'
+				),
+				'out' => Array(
+					'string'
+				)
+			),
+			'categories' => array(
+				'in'  => array('bool'),
+				'out' => array('array')
+			),
+		);
+
+		var $debug = False;
+//		var $debug = True;
+
+		var $so;
+		var $so1;
+		var $ex_participants;
+		var $cached_events;
+		var $repeating_events;
+		var $day;
+		var $month;
+		var $year;
+		var $prefs;
+
+		var $owner;
+		var $holiday_color;
+		var $printer_friendly = False;
+
+		var $cached_holidays;
+
+		var $g_owner = 0;
+
+		var $filter;
+		var $cat_id;
+		var $users_timeformat;
+
+		var $modified;
+		var $deleted;
+		var $added;
+
+		var $is_group = False;
+
+		var $soap = False;
+
+		var $use_session = False;
+
+		var $today;
+		var $debug_string;
+
+		var $sortby;
+		var $num_months;
+		var $xmlrpc = False;	// not called via xmlrpc
+       	var $async = false;
+
+		function bocalendar($session=0)
+		{
+
+			if(!is_object($GLOBALS['phpgw']->datetime))
+			{
+				$GLOBALS['phpgw']->datetime = createobject('phpgwapi.date_time');
+			}
+
+			$this->cat = CreateObject('phpgwapi.categories');
+			$this->grants = $GLOBALS['phpgw']->acl->get_grants('calendar');
+			@reset($this->grants);
+			if(DEBUG_APP)
+			{
+				if(floor(phpversion()) >= 4)
+				{
+					$this->debug_string = '';
+					ob_start();
+				}
+
+				foreach($this->grants as $grantor => $rights)
+				{
+					print_debug('Grantor',$grantor);
+					print_debug('Rights',$rights);
+				}
+			}
+
+			print_debug('Read use_session',$session);
+
+			if($session)
+			{
+				$this->read_sessiondata();
+				$this->use_session = True;
+			}
+			print_debug('BO Filter',$this->filter);
+			print_debug('Owner',$this->owner);
+
+			if ($GLOBALS['argv']) {
+			  $this->async = true;
+			  $this->load_lang();
+			}
+
+			$this->prefs['calendar']    = $GLOBALS['phpgw_info']['user']['preferences']['calendar'];
+			$this->check_set_default_prefs();
+
+			$owner = get_var('owner',array('GET','POST'),$GLOBALS['owner']);
+
+			ereg('menuaction=([a-zA-Z.]+)',$_SERVER['HTTP_REFERER'],$regs);
+			$from = $regs[1];
+			if ((substr($_SERVER['PHP_SELF'],-8) == 'home.php' && substr($this->prefs['calendar']['defaultcalendar'],0,7) == 'planner'
+				|| $_GET['menuaction'] == 'calendar.uicalendar.planner' &&
+				$from  != 'calendar.uicalendar.planner' && !$this->save_owner)
+				&& (int)$this->prefs['calendar']['planner_start_with_group'] > 0)
+			{
+				// entering planner for the first time ==> saving owner in save_owner, setting owner to default
+				//
+				$this->save_owner = $this->owner;
+				$owner = 'g_'.$this->prefs['calendar']['planner_start_with_group'];
+			}
+			elseif ($_GET['menuaction'] != 'calendar.uicalendar.planner' &&
+				$this->save_owner)
+			{
+				// leaving planner with an unchanged user/owner ==> setting owner back to save_owner
+				//
+				$owner = (int)(isset($_GET['owner']) ? $_GET['owner'] : $this->save_owner);
+				unset($this->save_owner);
+			}
+			elseif (!empty($owner) && $owner != $this->owner && $from == 'calendar.uicalendar.planner')
+			{
+				// user/owner changed within planner ==> forgetting save_owner
+				//
+				unset($this->save_owner);
+			}
+
+			if(isset($owner) && $owner!='' && substr($owner,0,2) == 'g_')
+			{
+				$this->set_owner_to_group(substr($owner,2));
+			}
+			elseif(isset($owner) && $owner!='')
+			{
+				$this->owner = (int)$owner;
+			}
+			elseif(!@isset($this->owner) || !@$this->owner)
+			{
+				$this->owner = (int)$GLOBALS['phpgw_info']['user']['account_id'];
+			}
+			elseif(isset($this->owner) && $GLOBALS['phpgw']->accounts->get_type($this->owner) == 'g')
+			{
+				$this->set_owner_to_group((int)$this->owner);
+			}
+
+			$this->prefs['common']    = $GLOBALS['phpgw_info']['user']['preferences']['common'];
+
+			if ($this->prefs['common']['timeformat'] == '12')
+			{
+				$this->users_timeformat = 'h:ia';
+			}
+			else
+			{
+				$this->users_timeformat = 'H:i';
+			}
+			$this->holiday_color = (substr($GLOBALS['phpgw_info']['theme']['bg07'],0,1)=='#'?'':'#').$GLOBALS['phpgw_info']['theme']['bg07'];
+
+			$friendly = (isset($_GET['friendly'])?$_GET['friendly']:'');
+			$friendly = ($friendly=='' && isset($_POST['friendly'])?$_POST['friendly']:$friendly);
+
+			$this->printer_friendly = ((int)$friendly == 1?True:False);
+
+			if(isset($_POST['filter'])) { $this->filter = $_POST['filter']; }
+			if(isset($_POST['sortby'])) { $this->sortby = $_POST['sortby']; }
+			if(isset($_POST['cat_id'])) { $this->cat_id = $_POST['cat_id']; }
+
+			if(!isset($this->filter))
+			{
+				$this->filter = ' '.$this->prefs['calendar']['defaultfilter'].' ';
+			}
+
+			if(!isset($this->sortby))
+			{
+				$this->sortby = $this->prefs['calendar']['defaultcalendar'] == 'planner_user' ? 'user' : 'category';
+			}
+
+			if($GLOBALS['phpgw']->accounts->get_type($this->owner)=='g')
+			{
+				$this->filter = ' all ';
+			}
+
+			$this->so = CreateObject('calendar.socalendar',
+				Array(
+					'owner'		=> $this->owner,
+					'filter'	=> $this->filter,
+					'category'	=> $this->cat_id,
+					'g_owner'	=> $this->g_owner
+				)
+			);
+			$this->rpt_day = array(	// need to be after creation of socalendar
+				MCAL_M_SUNDAY    => 'Sunday',
+				MCAL_M_MONDAY    => 'Monday',
+				MCAL_M_TUESDAY   => 'Tuesday',
+				MCAL_M_WEDNESDAY => 'Wednesday',
+				MCAL_M_THURSDAY  => 'Thursday',
+				MCAL_M_FRIDAY    => 'Friday',
+				MCAL_M_SATURDAY  => 'Saturday'
+			);
+			if($this->bo->prefs['calendar']['weekdaystarts'] != 'Sunday')
+			{
+				$mcals = array_keys($this->rpt_day);
+				$days  = array_values($this->rpt_day);
+				$this->rpt_day = array();
+				list($n) = $found = array_keys($days,$this->prefs['calendar']['weekdaystarts']);
+				for ($i = 0; $i < 7; ++$i,++$n)
+				{
+					$this->rpt_day[$mcals[$n % 7]] = $days[$n % 7];
+				}
+			}
+			$this->rpt_type = Array(
+				MCAL_RECUR_NONE		=> 'None',
+				MCAL_RECUR_DAILY	=> 'Daily',
+				MCAL_RECUR_WEEKLY	=> 'Weekly',
+				MCAL_RECUR_MONTHLY_WDAY	=> 'Monthly (by day)',
+				MCAL_RECUR_MONTHLY_MDAY	=> 'Monthly (by date)',
+				MCAL_RECUR_YEARLY	=> 'Yearly'
+			);
+
+			$localtime = $GLOBALS['phpgw']->datetime->users_localtime;
+
+			$date = (isset($GLOBALS['date'])?$GLOBALS['date']:'');
+			$date = (isset($_GET['date'])?$_GET['date']:$date);
+			$date = ($date=='' && isset($_POST['date'])?$_POST['date']:$date);
+
+			$year = (isset($_GET['year'])?$_GET['year']:'');
+			$year = ($year=='' && isset($_POST['year'])?$_POST['year']:$year);
+
+			$month = (isset($_GET['month'])?$_GET['month']:'');
+			$month = ($month=='' && isset($_POST['month'])?$_POST['month']:$month);
+
+			$day = (isset($_GET['day'])?$_GET['day']:'');
+			$day = ($day=='' && isset($_POST['day'])?$_POST['day']:'');
+
+			$num_months = (isset($_GET['num_months'])?$_GET['num_months']:'');
+			$num_months = ($num_months=='' && isset($_POST['num_months'])?$_POST['num_months']:$num_months);
+
+			if(isset($date) && $date!='')
+			{
+				$this->year  = (int)(substr($date,0,4));
+				$this->month = (int)(substr($date,4,2));
+				$this->day   = (int)(substr($date,6,2));
+			}
+			else
+			{
+				if(isset($year) && $year!='')
+				{
+					$this->year = $year;
+				}
+				else
+				{
+					$this->year = date('Y',$localtime);
+				}
+				if(isset($month) && $month!='')
+				{
+					$this->month = $month;
+				}
+				else
+				{
+					$this->month = date('m',$localtime);
+				}
+				if(isset($day) && $day!='')
+				{
+					$this->day = $day;
+				}
+				else
+				{
+					$this->day = date('d',$localtime);
+				}
+			}
+
+			if(isset($num_months) && $num_months!='')
+			{
+				$this->num_months = $num_months;
+			}
+			elseif($this->num_months == 0)
+			{
+				$this->num_months = 1;
+			}
+
+			$this->today = date('Ymd',$GLOBALS['phpgw']->datetime->users_localtime);
+
+			if(DEBUG_APP)
+			{
+				print_debug('BO Filter','('.$this->filter.')');
+				print_debug('Owner',$this->owner);
+				print_debug('Today',$this->today);
+				if(floor(phpversion()) >= 4)
+				{
+					$this->debug_string .= ob_get_contents();
+					ob_end_clean();
+				}
+			}
+			$this->xmlrpc = is_object($GLOBALS['server']) && $GLOBALS['server']->last_method;
+		}
+
+	  function load_lang() {
+	    if(!$_SESSION['phpgw_info']['calendar']['langAlarm']) 
+	      {
+		$array_keys = array();
+		$fn = '../../calendar/setup/phpgw_alarm_'.$GLOBALS['phpgw_info']['user']['preferences']['common']['lang'].'.lang';			
+		echo $fn;
+		if (file_exists($fn)){
+		  $fp = fopen($fn,'r');
+		  while ($data = fgets($fp,16000))	{
+		    list($message_id,$app_name,$null,$content) = explode("\t",substr($data,0,-1));			
+		    $_SESSION['phpgw_info']['calendar']['langAlarm'][$message_id] =  $content;
+		  }
+		  fclose($fp);
+		}
+	      }
+	  }
+		function list_methods($_type='xmlrpc')
+		{
+			/*
+			  This handles introspection or discovery by the logged in client,
+			  in which case the input might be an array.  The server always calls
+			  this function to fill the server dispatch map using a string.
+			*/
+			if (is_array($_type))
+			{
+				$_type = $_type['type'];
+			}
+			switch($_type)
+			{
+				case 'xmlrpc':
+					$xml_functions = array(
+						'list_methods' => array(
+							'function'  => 'list_methods',
+							'signature' => array(array(xmlrpcStruct,xmlrpcString)),
+							'docstring' => lang('Read this list of methods.')
+						),
+						'read' => array(
+							'function'  => 'read_entry',
+							'signature' => array(array(xmlrpcStruct,xmlrpcInt)),
+							'docstring' => lang('Read a single entry by passing the id and fieldlist.')
+						),
+						'read_entry' => array(	// deprecated, use read
+							'function'  => 'read_entry',
+							'signature' => array(array(xmlrpcStruct,xmlrpcInt)),
+							'docstring' => lang('Read a single entry by passing the id and fieldlist.')
+						),
+						'write' => array(
+							'function'  => 'update',
+							'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
+							'docstring' => lang('Add or update a single entry by passing the fields.')
+						),
+						'add_entry' => array(	// deprecated, use write
+							'function'  => 'update',
+							'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
+							'docstring' => lang('Add a single entry by passing the fields.')
+						),
+						'update_entry' => array(	// deprecated, use write
+							'function'  => 'update',
+							'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
+							'docstring' => lang('Update a single entry by passing the fields.')
+						),
+						'delete' => array(
+							'function'  => 'delete_entry',
+							'signature' => array(array(xmlrpcInt,xmlrpcInt)),
+							'docstring' => lang('Delete a single entry by passing the id.')
+						),
+						'delete_entry' => array(	// deprecated, use delete
+							'function'  => 'delete_entry',
+							'signature' => array(array(xmlrpcInt,xmlrpcInt)),
+							'docstring' => lang('Delete a single entry by passing the id.')
+						),
+						'delete_calendar' => array(
+							'function'  => 'delete_calendar',
+							'signature' => array(array(xmlrpcInt,xmlrpcInt)),
+							'docstring' => lang('Delete an entire users calendar.')
+						),
+						'change_owner' => array(
+							'function'  => 'change_owner',
+							'signature' => array(array(xmlrpcInt,xmlrpcStruct)),
+							'docstring' => lang('Change all events for $params[\'old_owner\'] to $params[\'new_owner\'].')
+						),
+						'search' => array(
+							'function'  => 'store_to_cache',
+							'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
+							'docstring' => lang('Read a list of entries.')
+						),
+						'store_to_cache' => array(	// deprecated, use search
+							'function'  => 'store_to_cache',
+							'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
+							'docstring' => lang('Read a list of entries.')
+						),
+						'export_event' => array(
+							'function'  => 'export_event',
+							'signature' => array(array(xmlrpcString,xmlrpcStruct)),
+							'docstring' => lang('Export a list of entries in iCal format.')
+						),
+						'categories' => array(
+							'function'  => 'categories',
+							'signature' => array(array(xmlrpcStruct,xmlrpcStruct)),
+							'docstring' => lang('List all categories.')
+						),
+					);
+					return $xml_functions;
+					break;
+				case 'soap':
+					return $this->soap_functions;
+					break;
+				default:
+					return array();
+					break;
+			}
+		}
+
+		function set_owner_to_group($owner)
+		{
+			print_debug('calendar::bocalendar::set_owner_to_group:owner',$owner);
+			$this->owner = (int)$owner;
+			$this->is_group = True;
+			$this->g_owner = Array();
+			$members = $GLOBALS['phpgw']->accounts->member($owner);
+			if (is_array($members))
+			{
+				foreach($members as $user)
+				{
+					// use only members which gave the user a read-grant
+					if ($this->check_perms(PHPGW_ACL_READ,0,$user['account_id']))
+					{
+						$this->g_owner[] = $user['account_id'];
+					}
+				}
+			}
+			//echo "<p>".function_backtrace().": set_owner_to_group($owner) = ".print_r($this->g_owner,True)."</p>\n";
+		}
+
+		function member_of_group($owner=0)
+		{
+			$owner = ($owner==0?$GLOBALS['phpgw_info']['user']['account_id']:$owner);
+			$group_owners = $GLOBALS['phpgw']->accounts->membership();
+			while($group_owners && list($index,$group_info) = each($group_owners))
+			{
+				if($this->owner == $group_info['account_id'])
+				{
+					return True;
+				}
+			}
+			return False;
+		}
+
+		function save_sessiondata($data='')
+		{
+			if ($this->use_session)
+			{
+				if (!is_array($data))
+				{
+					$data = array(
+						'filter'     => $this->filter,
+						'cat_id'     => $this->cat_id,
+						'owner'      => $this->owner,
+						'save_owner' => $this->save_owner,
+						'year'       => $this->year,
+						'month'      => $this->month,
+						'day'        => $this->day,
+						'date'       => $this->date,
+						'sortby'     => $this->sortby,
+						'num_months' => $this->num_months,
+						'return_to'  => $this->return_to
+					);
+				}
+				if($this->debug)
+				{
+					if(floor(phpversion()) >= 4)
+					{
+						ob_start();
+					}
+					echo '<!-- '."\n".'Save:'."\n"._debug_array($data,False)."\n".' -->'."\n";
+					if(floor(phpversion()) >= 4)
+					{
+						$this->debug_string .= ob_get_contents();
+						ob_end_clean();
+					}
+				}
+				$GLOBALS['phpgw']->session->appsession('session_data','calendar',$data);
+			}
+		}
+
+		function read_sessiondata()
+		{
+			$data = $GLOBALS['phpgw']->session->appsession('session_data','calendar');
+			print_debug('Read',_debug_array($data,False));
+
+			$this->filter = $data['filter'];
+			$this->cat_id = $data['cat_id'];
+			$this->sortby = $data['sortby'];
+			$this->owner  = (int)$data['owner'];
+			$this->save_owner = (int)$data['save_owner'];
+			$this->year   = (int)$data['year'];
+			$this->month  = (int)$data['month'];
+			$this->day    = (int)$data['day'];
+			$this->num_months = (int)$data['num_months'];
+			$this->return_to = $data['return_to'];
+		}
+
+		function read_entry($id,$ignore_acl=False)
+		{
+			if (is_array($id) && count($id) == 1)
+			{
+				list(,$id) = each($id);
+			}
+			if($ignore_acl || $this->check_perms(PHPGW_ACL_READ,$id))
+			{
+				$event = $this->so->read_entry($id);
+				if(!isset($event['participants'][$this->owner]) && $this->user_is_a_member($event,$this->owner))
+				{
+					$this->so->add_attribute('participants','U',(int)$this->owner);
+					$this->so->add_entry($event);
+					$event = $this->get_cached_event();
+				}
+				return $this->xmlrpc ? $this->xmlrpc_prepare($event) : $event;
+			}
+			if ($this->xmlrpc)
+			{
+				$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
+			}
+			return False;
+		}
+
+		function delete_single($param)
+		{
+			if($this->check_perms(PHPGW_ACL_DELETE,(int)$param['id']))
+			{
+				$temp_event = $this->get_cached_event();
+				$event = $this->read_entry((int)$param['id']);
+//				if($this->owner == $event['owner'])
+//				{
+				$exception_time = mktime($event['start']['hour'],$event['start']['min'],0,$param['month'],$param['day'],$param['year']) - $GLOBALS['phpgw']->datetime->tz_offset;
+				$event['recur_exception'][] = (int)$exception_time;
+				$this->so->cal->event = $event;
+//				print_debug('exception time',$event['recur_exception'][count($event['recur_exception']) -1]);
+//				print_debug('count event exceptions',count($event['recur_exception']));
+				$this->so->add_entry($event);
+				$cd = 16;
+
+				$this->so->cal->event = $temp_event;
+				unset($temp_event);
+			}
+			else
+			{
+				$cd = 60;
+			}
+//			}
+			return $cd;
+		}
+
+		function delete_entry($id)
+		{
+			if (is_array($id) && count($id) == 1)
+			{
+				list(,$id) = each($id);
+			}
+			if($this->check_perms(PHPGW_ACL_DELETE,$id))
+			{
+				$this->so->delete_entry($id);
+
+				if ($this->xmlrpc)
+				{
+					$this->so->expunge($id);
+				}
+				return $this->xmlrpc ? True : 16;
+			}
+			if ($this->xmlrpc)
+			{
+				$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
+			}
+			return 60;
+		}
+
+		function reinstate($params='')
+		{
+			if($this->check_perms(PHPGW_ACL_EDIT,$params['cal_id']) && isset($params['reinstate_index']))
+			{
+				$event = $this->so->read_entry($params['cal_id']);
+				@reset($params['reinstate_index']);
+				print_debug('Count of reinstate_index',count($params['reinstate_index']));
+				if(count($params['reinstate_index']) > 1)
+				{
+					while(list($key,$value) = each($params['reinstate_index']))
+					{
+						print_debug('reinstate_index ['.$key.']',(int)$value);
+						print_debug('exception time',$event['recur_exception'][(int)$value]);
+						unset($event['recur_exception'][(int)$value]);
+						print_debug('count event exceptions',count($event['recur_exception']));
+					}
+				}
+				else
+				{
+					print_debug('reinstate_index[0]',(int)$params['reinstate_index'][0]);
+					print_debug('exception time',$event['recur_exception'][(int)$params['reinstate_index'][0]]);
+					unset($event['recur_exception'][(int)$params['reinstate_index'][0]]);
+					print_debug('count event exceptions',count($event['recur_exception']));
+				}
+				$this->so->cal->event = $event;
+				$this->so->add_entry($event);
+				return 42;
+			}
+			else
+			{
+				return 43;
+			}
+		}
+
+		function delete_calendar($owner)
+		{
+			if($GLOBALS['phpgw_info']['user']['apps']['admin'])
+			{
+				$this->so->delete_calendar($owner);
+			}
+		}
+
+		function change_owner($params='')
+		{
+			if($GLOBALS['phpgw_info']['server']['calendar_type'] == 'sql')
+			{
+				if(is_array($params))
+				{
+					$this->so->change_owner($params['old_owner'],$params['new_owner']);
+				}
+			}
+		}
+
+		function expunge()
+		{
+			reset($this->so->cal->deleted_events);
+			while(list($i,$event_id) = each($this->so->cal->deleted_events))
+			{
+				$event = $this->so->read_entry($event_id);
+				if(!$this->ex_participants)
+					$this->ex_participants = html_entity_decode($event['ex_participants']);			
+				if($this->check_perms(PHPGW_ACL_DELETE,$event))
+				{
+					$this->send_update(MSG_DELETED,$event['participants'],$event);
+				}
+				else
+				{
+					unset($this->so->cal->deleted_events[$i]);
+				}
+			}
+			$this->so->expunge();
+		}
+
+		function search_keywords($keywords)
+		{
+			$type = $GLOBALS['phpgw']->accounts->get_type($this->owner);
+
+			if($type == 'g')
+			{
+				$members = $GLOBALS['phpgw']->acl->get_ids_for_location($this->owner, 1, 'phpgw_group');
+			}
+			else
+			{
+				$members = array_keys($this->grants);
+
+				if (!in_array($this->owner,$members))
+				{
+					$members[] = $this->owner;
+				}
+			}
+			foreach($members as $n => $uid)
+			{
+				if (!($this->grants[$uid] & PHPGW_ACL_READ))
+				{
+					unset($members[$n]);
+				}
+			}
+			return $this->so->list_events_keyword($keywords,$members);
+		}
+
+		function update($params='')
+		{
+			
+			if($params['from_mobile']) {
+				$ui_return = "mobile.ui_mobilecalendar.edit";
+				$ui_index = "mobile.ui_mobilecalendar.index";
+				$ui_overlap = "mobile.ui_mobilecalendar.overlap";
+			}
+			else {
+				$ui_return = "calendar.uicalendar.edit";
+				$ui_index = "calendar.uicalendar.index";		
+				$ui_overlap = "calendar.uicalendar.overlap";
+			}
+			
+			if(!is_object($GLOBALS['phpgw']->datetime))
+			{
+				$GLOBALS['phpgw']->datetime = createobject('phpgwapi.date_time');
+			}
+			$l_cal = (@isset($params['cal']) && $params['cal']?$params['cal']:$_POST['cal']);
+			$l_participants = (@$params['participants']?$params['participants']:$_POST['participants']);
+			$this->ex_participants = (@$params['ex_participants']?$params['ex_participants']:$_POST['ex_participants']);
+			$l_categories = (@$params['categories']?$params['categories']:$_POST['categories']);
+			$l_start = (@isset($params['start']) && $params['start']?$params['start']:$_POST['start']);
+			$l_end = (@isset($params['end']) && $params['end']?$params['end']:$_POST['end']);
+			$l_recur_enddate = (@isset($params['recur_enddate']) && $params['recur_enddate']?$params['recur_enddate']:$_POST['recur_enddate']);
+
+			
+			$send_to_ui = True;
+			//if ((!is_array($l_start) || !is_array($l_end)) && !isset($_GET['readsess']))	// xmlrpc call
+			if ($this->xmlrpc)	// xmlrpc call
+			{
+				$send_to_ui = False;
+
+				$l_cal = $params;	// no extra array
+
+				foreach(array('start','end','recur_enddate') as $name)
+				{
+					$var = 'l_'.$name;
+					$$var = $GLOBALS['server']->iso86012date($params[$name]);
+					unset($l_cal[$name]);
+				}
+				if (!is_array($l_participants) || !count($l_participants))
+				{
+					$l_participants = array($GLOBALS['phpgw_info']['user']['account_id'].'A');
+				}
+				else
+				{
+					$l_participants = array();
+					foreach($params['participants'] as $user => $data)
+					{
+						$l_participants[] = $user.$data['status'];
+					}
+				}
+				unset($l_cal['participants']);
+
+				if (!is_object($GLOBALS['phpgw']->categories))
+				{
+					$GLOBALS['phpgw']->categories = CreateObject('phpgwapi.categories');
+				}
+				$l_categories = $GLOBALS['server']->xmlrpc2cats($params['category']);
+				unset($l_cal['category']);
+
+				// using access={public|private} in all modules via xmlrpc
+				$l_cal['public'] = $params['access'] != 'private';
+				unset($l_cal['access']);
+/*
+				$fp = fopen('/tmp/xmlrpc.log','a+');
+				ob_start();
+				echo "\nbocalendar::update("; print_r($params); echo ")\n";
+				//echo "\nl_start="; print_r($l_start);
+				//echo "\nl_end="; print_r($l_end);
+				fwrite($fp,ob_get_contents());
+				ob_end_clean();
+				fclose($fp);
+*/
+			}
+			print_debug('ID',$l_cal['id']);
+
+			// don't wrap to the next day for no time
+			if ($l_end['hour'] == 24 && $l_end['min'] == 0)
+			{
+				$l_end['hour'] = 23;
+				$l_end['min'] = 59;
+			}
+
+			if(isset($_GET['readsess']))
+			{
+				$event = $this->restore_from_appsession();
+				$event['title'] = stripslashes($event['title']);
+				$event['description'] = stripslashes($event['description']);
+				$event['ex_participants'] = stripslashes($event['ex_participants']);
+				$datetime_check = $this->validate_update($event);
+				if($datetime_check)
+				{
+					ExecMethod($ui_return,
+						Array(
+							'cd'		=> $datetime_check,
+							'readsess'	=> 1
+						)
+					);
+					if(!$params['from_mobile'])
+						$GLOBALS['phpgw']->common->phpgw_exit(True);
+					else
+						return;
+				}
+				$overlapping_events = False;
+			}
+			else
+			{
+				if((!$l_cal['id'] && !$this->check_perms(PHPGW_ACL_ADD)) ||
+				   ($l_cal['id'] && !$this->check_perms(PHPGW_ACL_EDIT,$l_cal['id'])))
+				{
+					if ($this->xmlrpc)
+					{
+						$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['no_access'],$GLOBALS['xmlrpcstr']['no_access']);
+					}
+					if (!$send_to_ui)
+					{
+						return array(($l_cal['id']?1:2) => 'permission denied');
+					}
+					ExecMethod($ui_index);
+					if(!$params['from_mobile'])
+						$GLOBALS['phpgw']->common->phpgw_exit();
+					else
+						return;
+				}
+
+				print_debug('Prior to fix_update_time()');
+				$this->fix_update_time($l_start);
+				$this->fix_update_time($l_end);
+				if(!isset($l_cal['ex_participants']))
+				{
+					$l_cal['ex_participants'] = $this->ex_participants;
+				}
+
+				if(!isset($l_categories))
+				{
+					$l_categories = 0;
+				}
+
+				$is_public = ($l_cal['type'] != 'private');
+				$this->so->event_init();
+				$this->add_attribute('uid',$l_cal['uid']);
+				$this->add_attribute('type',$l_cal['type']);
+				if($l_cal['ex_participants']) {
+					$this->add_attribute('ex_participants',$l_cal['ex_participants']);
+				}
+				if(count($l_categories) >= 2)
+				{
+					$this->so->set_category(implode(',',$l_categories));
+				}
+				else
+				{
+					$this->so->set_category(strval($l_categories[0]));
+				}
+				$this->so->set_title($l_cal['title']);
+				$this->so->set_description($l_cal['description']);
+				$this->so->set_ex_participants($l_cal['ex_participants']);
+				$this->so->set_start($l_start['year'],$l_start['month'],$l_start['mday'],$l_start['hour'],$l_start['min'],0);
+				$this->so->set_end($l_end['year'],$l_end['month'],$l_end['mday'],$l_end['hour'],$l_end['min'],0);
+				$this->so->set_class($is_public);
+				$this->so->add_attribute('reference',(@isset($l_cal['reference']) && $l_cal['reference']?$l_cal['reference']:0));
+				$this->so->add_attribute('location',(@isset($l_cal['location']) && $l_cal['location']?$l_cal['location']:''));
+				if($l_cal['id'])
+				{
+					$this->so->add_attribute('id',$l_cal['id']);
+				}
+
+				if($l_cal['rpt_use_end'] != 'y')
+				{
+					$l_recur_enddate['year'] = 0;
+					$l_recur_enddate['month'] = 0;
+					$l_recur_enddate['mday'] = 0;
+				}
+				elseif (isset($l_recur_enddate['str']))
+				{
+					$l_recur_enddate = $this->jscal->input2date($l_recur_enddate['str'],False,'mday');
+				}
+
+				switch((int)$l_cal['recur_type'])
+				{
+					case MCAL_RECUR_NONE:
+						$this->so->set_recur_none();
+
+						$repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
+
+						break;
+					case MCAL_RECUR_DAILY:
+						$this->so->set_recur_daily((int)$l_recur_enddate['year'],(int)$l_recur_enddate['month'],(int)$l_recur_enddate['mday'],(int)$l_cal['recur_interval']);
+
+						$repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
+
+						$tmp_init = explode("/",$_POST['start']['str']); // recebe a data inicial da repeticao;
+						$init_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_init[1]),$tmp_init[0],$tmp_init[2]); // transforma a data inicial + hora + minuto em UNIX timestamp;
+
+						if($l_cal['rpt_use_end'] == 'y') // verifica se foi indicada data final da repeticao, se sim:
+						{
+
+							$tmp_end = explode("/",$_POST['recur_enddate']['str']); // recebe data final da repeticao;
+							$end_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_end[1]),$tmp_end[0],$tmp_end[2]); // transforma a data inicial + hora e minuto de inicio da repeticao em UNIX timestamp;
+
+						}else { // se nao existe data final da repeticao (agendamento infinito):
+
+							$end_rept = 0; // variavel recebe zero e nao sera adicionado nenhum alarme para o agendamento;
+						}
+						break;
+					case MCAL_RECUR_WEEKLY:
+
+						$repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
+
+						$tmp_init = explode("/",$_POST['start']['str']); // recebe a data inicial da repeticao;
+						$init_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_init[1]),$tmp_init[0],$tmp_init[2]); // transforma a data inicial + hora + minuto em UNIX timestamp;
+
+						if($l_cal['rpt_use_end'] == 'y') // verifica se foi indicada data final da repeticao, se sim:
+						{
+
+							$tmp_end = explode("/",$_POST['recur_enddate']['str']); // recebe data final da repeticao;
+							$end_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_end[1]),$tmp_end[0],$tmp_end[2]); // transforma a data inicial + hora e minuto de inicio da repeticao em UNIX timestamp;
+
+						}else { // se nao existe data final da repeticao (agendamento infinito):
+
+							$end_rept = 0; // variavel recebe zero e nao sera adicionado nenhum alarme para o agendamento;
+						}
+
+						foreach(array('rpt_sun','rpt_mon','rpt_tue','rpt_wed','rpt_thu','rpt_fri','rpt_sat') as $rpt_day)
+						{
+							$l_cal['recur_data'] += (int)$l_cal[$rpt_day];
+						}
+						if (is_array($l_cal['rpt_day']))
+						{
+							foreach ($l_cal['rpt_day'] as $mask)
+							{
+								$l_cal['recur_data'] |= (int)$mask;
+								$rpt_wdays = $l_cal['recur_data']; // recebe os dias da semana (somatorio) para repetir o alarme;
+							}
+						}
+						$this->so->set_recur_weekly((int)$l_recur_enddate['year'],(int)$l_recur_enddate['month'],(int)$l_recur_enddate['mday'],(int)$l_cal['recur_interval'],$l_cal['recur_data']);
+						break;
+					case MCAL_RECUR_MONTHLY_MDAY:
+						$this->so->set_recur_monthly_mday((int)$l_recur_enddate['year'],(int)$l_recur_enddate['month'],(int)$l_recur_enddate['mday'],(int)$l_cal['recur_interval']);
+
+						$repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
+
+						$tmp_init = explode("/",$_POST['start']['str']); // recebe a data inicial da repeticao;
+						$init_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_init[1]),$tmp_init[0],$tmp_init[2]); // transforma a data inicial + hora + minuto em UNIX timestamp;
+
+						if($l_cal['rpt_use_end'] == 'y') // verifica se foi indicada data final da repeticao, se sim:
+						{
+
+							$tmp_end = explode("/",$_POST['recur_enddate']['str']); // recebe data final da repeticao;
+							$end_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_end[1]),$tmp_end[0],$tmp_end[2]); // transforma a data inicial + hora e minuto de inicio da repeticao em UNIX timestamp;
+
+						}else { // se nao existe data final da repeticao (agendamento infinito):
+
+							$end_rept = 0; // variavel recebe zero e nao sera adicionado nenhum alarme para o agendamento;
+						}
+						break;
+					case MCAL_RECUR_MONTHLY_WDAY:
+						$this->so->set_recur_monthly_wday((int)$l_recur_enddate['year'],(int)$l_recur_enddate['month'],(int)$l_recur_enddate['mday'],(int)$l_cal['recur_interval']);
+						break;
+					case MCAL_RECUR_YEARLY:
+						$this->so->set_recur_yearly((int)$l_recur_enddate['year'],(int)$l_recur_enddate['month'],(int)$l_recur_enddate['mday'],(int)$l_cal['recur_interval']);
+
+						$repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
+
+						$tmp_init = explode("/",$_POST['start']['str']); // recebe a data inicial da repeticao;
+						$init_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_init[1]),$tmp_init[0],$tmp_init[2]); // transforma a data inicial + hora + minuto em UNIX timestamp;
+
+						if($l_cal['rpt_use_end'] == 'y') // verifica se foi indicada data final da repeticao, se sim:
+						{
+
+							$tmp_end = explode("/",$_POST['recur_enddate']['str']); // recebe data final da repeticao;
+							$end_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_end[1]),$tmp_end[0],$tmp_end[2]); // transforma a data inicial + hora e minuto de inicio da repeticao em UNIX timestamp;
+
+						}else { // se nao existe data final da repeticao (agendamento infinito):
+
+							$end_rept = 0; // variavel recebe zero e nao sera adicionado nenhum alarme para o agendamento;
+						}
+						break;
+				}
+
+				if($l_participants)
+				{
+					$parts = $l_participants;
+					$minparts = min($l_participants);
+					$part = Array();
+					for($i=0;$i<count($parts);$i++)
+					{
+						if (($accept_type = substr($parts[$i],-1,1)) == '0' || (int)$accept_type > 0)
+						{
+							$accept_type = 'U';
+						}
+						$acct_type = $GLOBALS['phpgw']->accounts->get_type((int)$parts[$i]);
+						if($acct_type == 'u')
+						{
+							$part[(int)$parts[$i]] = $accept_type;
+						}
+						elseif($acct_type == 'g')
+						{
+							$part[(int)$parts[$i]] = $accept_type;
+							$groups[] = $parts[$i];
+							/* This pulls ALL users of a group and makes them as participants to the event */
+							/* I would like to turn this back into a group thing. */
+							$acct = CreateObject('phpgwapi.accounts',(int)$parts[$i]);
+							$members = $acct->member((int)$parts[$i]);
+							unset($acct);
+							if($members == False)
+							{
+								continue;
+							}
+							while($member = each($members))
+							{
+								$part[$member[1]['account_id']] = $accept_type;
+							}
+						}
+					}
+				}
+				else
+				{
+					$part = False;
+				}
+
+				if($part)
+				{
+					@reset($part);
+					while(list($key,$accept_type) = each($part))
+					{
+						$this->so->add_attribute('participants',$accept_type,(int)$key);
+					}
+				}
+
+				if($groups)
+				{
+					@reset($groups);
+					$this->so->add_attribute('groups',(int)$group_id);
+				}
+
+				$event = $this->get_cached_event();
+				if(!is_int($minparts))
+				{
+					$minparts = $this->owner;
+				}
+				if(!@isset($event['participants'][$l_cal['owner']]))
+				{
+					$this->so->add_attribute('owner',$minparts);
+				}
+				else
+				{
+					$this->so->add_attribute('owner',$l_cal['owner']);
+				}
+				$this->so->add_attribute('priority',$l_cal['priority']);
+
+				foreach($l_cal as $name => $value)
+				{
+					if ($name[0] == '#')	// Custom field
+					{
+						$this->so->add_attribute($name,stripslashes($value));
+					}
+				}
+				if (isset($_POST['preserved']) && is_array($preserved = unserialize(stripslashes($_POST['preserved']))))
+				{
+					foreach($preserved as $name => $value)
+					{
+						switch($name)
+						{
+							case 'owner':
+								$this->so->add_attribute('participants',$value,$l_cal['owner']);
+								break;
+							default:
+								$this->so->add_attribute($name,str_replace(array('&amp;','&quot;','&lt;','&gt;'),array('&','"','<','>'),$value));
+						}
+					}
+				}
+				$event = $this->get_cached_event();
+
+				if ($l_cal['alarmdays'] > 0 || $l_cal['alarmhours'] > 0 ||
+						$l_cal['alarmminutes'] > 0)
+				{
+					$offset = ($l_cal['alarmdays'] * 24 * 3600) +
+						($l_cal['alarmhours'] * 3600) + ($l_cal['alarmminutes'] * 60);
+
+					$time = $this->maketime($event['start']) - $offset;
+
+					$event['alarm'][] = Array(
+						'time'    => $time,
+						'offset'  => $offset,
+						'owner'   => $this->owner,
+						'enabled' => 1,
+						'repeat'  => $repetido, // para repetir alarme;
+						'init_rept' => $init_rept, // inicio repeticao;
+						'end_rept' => $end_rept, // fim repeticao;
+						'rpt_wdays' => $rpt_wdays // dias repeticao da semana;
+					);
+				}
+
+				$this->store_to_appsession($event);
+				$datetime_check = $this->validate_update($event);
+				print_debug('bo->validated_update() returnval',$datetime_check);
+				if($datetime_check)
+				{
+					if (!$send_to_ui)
+					{
+						return array($datetime_check => 'invalid input data');
+					}
+					ExecMethod($ui_return,
+						Array(
+							'cd'		=> $datetime_check,
+							'readsess'	=> 1
+						)
+					);
+					if(!$params['from_mobile'])
+						$GLOBALS['phpgw']->common->phpgw_exit(True);
+					else
+						return;
+				}
+
+				if($event['id'])
+				{
+					$event_ids[] = $event['id'];
+				}
+				if($event['reference'])
+				{
+					$event_ids[] = $event['reference'];
+				}
+
+				$overlapping_events = $this->overlap(
+					$this->maketime($event['start']),
+					$this->maketime($event['end']),
+					$event['participants'],
+					$event['owner'],
+					$event_ids
+				);
+			}
+			if(!$this->ex_participants)
+				$this->ex_participants = $event['ex_participants'];			
+			if($overlapping_events)
+			{
+				if($send_to_ui)
+				{
+					$event['ex_participants'] = $this->ex_participants;
+					unset($GLOBALS['phpgw_info']['flags']['noheader']);
+					unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+					ExecMethod($ui_overlap,
+						Array(
+							'o_events'	=> $overlapping_events,
+							'this_event'	=> $event
+						)
+					);
+					if(!$params['from_mobile'])
+						$GLOBALS['phpgw']->common->phpgw_exit(True);
+					else
+						return;
+				}
+				else
+				{
+					return $overlapping_events;
+				}
+			}
+			else
+			{
+				if(!$event['id'])
+				{
+					$this->so->add_entry($event);
+					$this->send_update(MSG_ADDED,$event['participants'],'',$this->get_cached_event());
+					print_debug('New Event ID',$event['id']);
+				}
+				else
+				{
+					print_debug('Updating Event ID',$event['id']);
+					$new_event = $event;
+					$old_event = $this->read_entry($event['id']);
+					// if old event has alarm and the start-time changed => update them
+					//echo "<p>checking ".count($old_event['alarm'])." alarms of event #$event[id] start moved from ".print_r($old_event['start'],True)." to ".print_r($event['start'],True)."</p>\n";
+					if ($old_event['alarm'] &&
+						$this->maketime($old_event['start']) != $this->maketime($event['start']))
+					{
+						$this->so->delete_alarms($old_event['id']);
+						foreach($old_event['alarm'] as $id => $alarm)
+						{
+							$alarm['time'] = $this->maketime($event['start']) - $alarm['offset'];
+							$event['alarm'][] = $alarm;
+						}
+						//echo "updated alarms<pre>".print_r($event['alarm'],True)."</pre>\n";
+					}
+					$this->so->cal->event = $event;
+					$this->so->add_entry($event);
+					$this->prepare_recipients($new_event,$old_event);
+				}
+
+				$date = sprintf("%04d%02d%02d",$event['start']['year'],$event['start']['month'],$event['start']['mday']);
+				if($send_to_ui)
+				{
+					$this->read_sessiondata();
+					if ($this->return_to)
+					{
+						$GLOBALS['phpgw']->redirect_link('/index.php','menuaction='.$this->return_to);
+						$GLOBALS['phpgw']->common->phpgw_exit();
+					}
+					Execmethod($ui_index);
+				}
+				else
+				{
+					return (int)$event['id'];
+				}
+			}
+			return True;
+		}
+
+		/* Private functions */
+		function read_holidays($year=0)
+		{
+			if(!$year)
+			{
+				$year = $this->year;
+			}
+			$holiday = CreateObject('calendar.boholiday');
+			$holiday->prepare_read_holidays($year,$this->owner);
+			$this->cached_holidays = $holiday->read_holiday();
+			unset($holiday);
+		}
+
+		function user_is_a_member($event,$user)
+		{
+			@reset($event['participants']);
+			$uim = False;
+			$security_equals = $GLOBALS['phpgw']->accounts->membership($user);
+			while(!$uim && $event['participants'] && $security_equals && list($participant,$status) = each($event['participants']))
+			{
+				if($GLOBALS['phpgw']->accounts->get_type($participant) == 'g')
+				{
+					@reset($security_equals);
+					while(list($key,$group_info) = each($security_equals))
+					{
+						if($group_info['account_id'] == $participant)
+						{
+							return True;
+							$uim = True;
+						}
+					}
+				}
+			}
+			return $uim;
+		}
+
+		function maketime($time)
+		{
+			return mktime(intval($time['hour']),intval($time['min']),intval($time['sec']),intval($time['month']),intval($time['mday']),intval($time['year']));
+		}
+
+		/*!
+		@function time2array
+		@abstract returns a date-array suitable for the start- or endtime of an event from a timestamp
+		@syntax time2array($time,$alarm=0)
+		@param $time the timestamp for the values of the array
+		@param $alarm (optional) alarm field of the array, defaults to 0
+		@author ralfbecker
+		*/
+		function time2array($time,$alarm = 0)
+		{
+			return array(
+				'year'  => (int)(date('Y',$time)),
+				'month' => (int)(date('m',$time)),
+				'mday'  => (int)(date('d',$time)),
+				'hour'  => (int)(date('H',$time)),
+				'min'   => (int)(date('i',$time)),
+				'sec'   => (int)(date('s',$time)),
+				'alarm' => (int)($alarm)
+			);
+		}
+
+		/*!
+		@function set_recur_date
+		@abstract set the start- and enddates of a recuring event for a recur-date
+		@syntax set_recur_date(&$event,$date)
+		@param $event the event which fields to set (has to be the original event for start-/end-times)
+		@param $date  the recuring date in form 'Ymd', eg. 20030226
+		@author ralfbecker
+		*/
+		function set_recur_date(&$event,$date)
+		{
+			$org_start = $this->maketime($event['start']);
+			$org_end   = $this->maketime($event['end']);
+			$start = mktime($event['start']['hour'],$event['start']['min'],0,substr($date,4,2),substr($date,6,2),substr($date,0,4));
+			$end   = $org_end + $start - $org_start;
+			$event['start'] = $this->time2array($start);
+			$event['end']   = $this->time2array($end);
+		}
+
+		function fix_update_time(&$time_param)
+		{
+			if (isset($time_param['str']))
+			{
+				if (!is_object($this->jscal))
+				{
+					$this->jscal = CreateObject('phpgwapi.jscalendar');
+				}
+				$time_param += $this->jscal->input2date($time_param['str'],False,'mday');
+				unset($time_param['str']);
+			}
+			if ($this->prefs['common']['timeformat'] == '12')
+			{
+				if ($time_param['ampm'] == 'pm')
+				{
+					if ($time_param['hour'] <> 12)
+					{
+						$time_param['hour'] += 12;
+					}
+				}
+				elseif ($time_param['ampm'] == 'am')
+				{
+					if ($time_param['hour'] == 12)
+					{
+						$time_param['hour'] -= 12;
+					}
+				}
+
+				if($time_param['hour'] > 24)
+				{
+					$time_param['hour'] -= 12;
+				}
+			}
+		}
+
+		function validate_update($event)
+		{
+			$error = 0;
+			// do a little form verifying
+			if (!count($event['participants']))
+			{
+				$error = 43;
+			}
+			elseif ($event['title'] == '')
+			{
+				$error = 40;
+			}
+			elseif (($GLOBALS['phpgw']->datetime->time_valid($event['start']['hour'],$event['start']['min'],0) == False) || ($GLOBALS['phpgw']->datetime->time_valid($event['end']['hour'],$event['end']['min'],0) == False))
+			{
+				$error = 41;
+			}
+			elseif (($GLOBALS['phpgw']->datetime->date_valid($event['start']['year'],$event['start']['month'],$event['start']['mday']) == False) || ($GLOBALS['phpgw']->datetime->date_valid($event['end']['year'],$event['end']['month'],$event['end']['mday']) == False) || ($GLOBALS['phpgw']->datetime->date_compare($event['start']['year'],$event['start']['month'],$event['start']['mday'],$event['end']['year'],$event['end']['month'],$event['end']['mday']) == 1))
+			{
+				$error = 42;
+			}
+			elseif ($GLOBALS['phpgw']->datetime->date_compare($event['start']['year'],$event['start']['month'],$event['start']['mday'],$event['end']['year'],$event['end']['month'],$event['end']['mday']) == 0)
+			{
+				if ($GLOBALS['phpgw']->datetime->time_compare($event['start']['hour'],$event['start']['min'],0,$event['end']['hour'],$event['end']['min'],0) == 1)
+				{
+					$error = 42;
+				}
+			}
+			return $error;
+		}
+
+		/*!
+		@function participants_not_rejected($participants,$event)
+		@abstract checks if any of the $particpants participates in $event and has not rejected it
+		*/
+		function participants_not_rejected($participants,$event)
+		{
+			//echo "participants_not_rejected()<br>participants =<pre>"; print_r($participants); echo "</pre><br>event[participants]=<pre>"; print_r($event['participants']); echo "</pre>\n";
+			foreach($participants as $uid => $status)
+			{
+				//echo "testing event[participants][uid=$uid] = '".$event['participants'][$uid]."'<br>\n";
+				if (isset($event['participants'][$uid]) && $event['participants'][$uid] != 'R' &&
+					$status != 'R')
+				{
+					return True;	// found not rejected participant in event
+				}
+			}
+			return False;
+		}
+
+		function overlap($starttime,$endtime,$participants,$owner=0,$id=0,$restore_cache=False)
+		{
+//			$retval = Array();
+//			$ok = False;
+
+/* This needs some attention.. by commenting this chunk of code it will fix bug #444265 */
+
+			if($restore_cache)
+			{
+				$temp_cache_events = $this->cached_events;
+			}
+
+//			$temp_start = (int)$GLOBALS['phpgw']->common->show_date($starttime,'Ymd');
+//			$temp_start_time = (int)($GLOBALS['phpgw']->common->show_date($starttime,'Hi');
+//			$temp_end = (int)$GLOBALS['phpgw']->common->show_date($endtime,'Ymd');
+//			$temp_end_time = (int)$GLOBALS['phpgw']->common->show_date($endtime,'Hi');
+			$temp_start = (int)(date('Ymd',$starttime));
+			$temp_start_time = (int)(date('Hi',$starttime));
+			$temp_end = (int)(date('Ymd',$endtime));
+			$temp_end_time = (int)(date('Hi',$endtime));
+			if($this->debug)
+			{
+				echo '<!-- Temp_Start: '.$temp_start.' -->'."\n";
+				echo '<!-- Temp_End: '.$temp_end.' -->'."\n";
+			}
+
+			$users = Array();
+			if(count($participants))
+			{
+				while(list($user,$status) = each($participants))
+				{
+					$users[] = $user;
+				}
+			}
+			else
+			{
+				$users[] = $this->owner;
+			}
+
+			$possible_conflicts = $this->store_to_cache(
+				Array(
+					'smonth'	=> substr(strval($temp_start),4,2),
+					'sday'	=> substr(strval($temp_start),6,2),
+					'syear'	=> substr(strval($temp_start),0,4),
+					'emonth'	=> substr(strval($temp_end),4,2),
+					'eday'	=> substr(strval($temp_end),6,2),
+					'eyear'	=> substr(strval($temp_end),0,4),
+					'owner'	=> $users
+				)
+			);
+
+			if($this->debug)
+			{
+				echo '<!-- Possible Conflicts ('.($temp_start - 1).'): '.count($possible_conflicts[$temp_start - 1]).' -->'."\n";
+				echo '<!-- Possible Conflicts ('.$temp_start.'): '.count($possible_conflicts[$temp_start]).' '.count($id).' -->'."\n";
+			}
+
+			if($possible_conflicts[$temp_start] || $possible_conflicts[$temp_end])
+			{
+				if($temp_start == $temp_end)
+				{
+					if($this->debug)
+					{
+						echo '<!-- Temp_Start == Temp_End -->'."\n";
+					}
+					@reset($possible_conflicts[$temp_start]);
+					while(list($key,$event) = each($possible_conflicts[$temp_start]))
+					{
+						$found = False;
+						if($id)
+						{
+							@reset($id);
+							while(list($key,$event_id) = each($id))
+							{
+								if($this->debug)
+								{
+									echo '<!-- $id['.$key.'] = '.$id[$key].' = '.$event_id.' -->'."\n";
+									echo '<!-- '.$event['id'].' == '.$event_id.' -->'."\n";
+								}
+								if($event['id'] == $event_id)
+								{
+									$found = True;
+								}
+							}
+						}
+						if($this->debug)
+						{
+							echo '<!-- Item found: '.$found.' -->'."<br>\n";
+						}
+						if(!$found)
+						{
+							if($this->debug)
+							{
+								echo '<!-- Checking event id #'.$event['id'];
+							}
+							$temp_event_start = sprintf("%d%02d",$event['start']['hour'],$event['start']['min']);
+							$temp_event_end = sprintf("%d%02d",$event['end']['hour'],$event['end']['min']);
+//							if((($temp_start_time <= $temp_event_start) && ($temp_end_time >= $temp_event_start) && ($temp_end_time <= $temp_event_end)) ||
+							if(($temp_start_time <= $temp_event_start &&
+								$temp_end_time > $temp_event_start &&
+								$temp_end_time <= $temp_event_end ||
+								$temp_start_time >= $temp_event_start &&
+								$temp_start_time < $temp_event_end &&
+								$temp_end_time >= $temp_event_end ||
+								$temp_start_time <= $temp_event_start &&
+								$temp_end_time >= $temp_event_end ||
+								$temp_start_time >= $temp_event_start &&
+								$temp_end_time <= $temp_event_end) &&
+								$this->participants_not_rejected($participants,$event))
+							{
+								if($this->debug)
+								{
+									echo ' Conflicts';
+								}
+								$retval[] = $event['id'];
+							}
+							if($this->debug)
+							{
+								echo ' -->'."\n";
+							}
+						}
+					}
+				}
+			}
+			else
+			{
+				$retval = False;
+			}
+
+			if($restore_cache)
+			{
+				$this->cached_events = $temp_cache_events;
+			}
+
+			return $retval;
+		}
+
+		/*!
+		@function check_perms( )
+		@syntax check_perms($needed,$event=0,$other=0)
+		@abstract Checks if the current user has the necessary ACL rights
+		@author ralfbecker
+		@discussion The check is performed on an event or general on the cal of an other user
+		@param $needed necessary ACL right: PHPGW_ACL_{READ|EDIT|DELETE}
+		@param $event event as array or the event-id or 0 for general check
+		@param $other uid to check (if event==0) or 0 to check against $this->owner
+		@note Participating in an event is considered as haveing read-access on that event, \
+			even if you have no general read-grant from that user.
+		*/
+		function check_perms($needed,$event=0,$other=0)
+		{
+			$event_in = $event;
+			
+			if (is_int($event) && $event == 0)
+			{
+				$owner = $other > 0 ? $other : $this->owner;
+			}
+			else
+			{
+				if (!is_array($event))
+				{
+					$event = $this->so->read_entry((int) $event);
+				}
+				if (!is_array($event))
+				{
+					if ($this->xmlrpc)
+					{
+						$GLOBALS['server']->xmlrpc_error($GLOBALS['xmlrpcerr']['not_exist'],$GLOBALS['xmlrpcstr']['not_exist']);
+					}
+					return False;
+				}
+				$owner = $event['owner'];
+				$private = $event['public'] == False || $event['public'] == 0;
+			}
+			$user = $GLOBALS['phpgw_info']['user']['account_id'];
+			$grants = $this->grants[$owner];
+
+			if (is_array($event) && $needed == PHPGW_ACL_READ)
+			{
+				// Check if the $user is one of the participants or has a read-grant from one of them
+				//
+				foreach($event['participants'] as $uid => $accept)
+				{
+					if ($this->grants[$uid] & PHPGW_ACL_READ || $uid == $user)
+					{
+						$grants |= PHPGW_ACL_READ;
+						// if the $user is one of the participants read-grant private (restricted) too.
+						if($uid == $user || ($this->grants[$uid] & PHPGW_ACL_PRIVATE)) {
+							$grants |= PHPGW_ACL_PRIVATE;
+						}
+						//break;
+					}
+				}
+			}
+
+			if ($GLOBALS['phpgw']->accounts->get_type($owner) == 'g' && $needed == PHPGW_ACL_ADD)
+			{
+				$access = False;	// a group can't be the owner of an event
+			}
+			else
+			{
+				$access = $user == $owner || $grants & $needed && (!$private || $grants & PHPGW_ACL_PRIVATE);
+			}
+			//echo "<p>".function_backtrace()." check_perms($needed,$event_id,$other) for user $user and needed_acl $needed: event='$event[title]': owner=$owner, private=$private, grants=$grants ==> access=$access</p>\n";
+
+			return $access;
+		}
+
+
+		function display_status($user_status)
+		{
+			if(@$this->prefs['calendar']['display_status'] && $user_status)
+			{
+				$user_status = substr($this->get_long_status($user_status),0,1);
+
+				return ' ('.$user_status.')';
+			}
+			else
+			{
+				return '';
+			}
+		}
+
+		function get_long_status($status_short)
+		{
+			switch ($status_short)
+			{
+				case 'A':
+					$status = lang('Accepted');
+					break;
+				case 'R':
+					$status = lang('Rejected');
+					break;
+				case 'T':
+					$status = lang('Tentative');
+					break;
+				case 'U':
+					$status = lang('No Response');
+					break;
+			}
+			return $status;
+		}
+
+		function is_private($event,$owner)
+		{
+			if($owner == 0)
+			{
+				$owner = $this->owner;
+			}
+			if ($owner == $GLOBALS['phpgw_info']['user']['account_id'] || ($event['public']==1) || ($this->check_perms(PHPGW_ACL_PRIVATE,$event) && $event['public']==0) || $event['owner'] == $GLOBALS['phpgw_info']['user']['account_id'])
+			{
+				return False;
+			}
+			elseif($event['public'] == 0)
+			{
+				return True;
+			}
+			elseif($event['public'] == 2)
+			{
+				$is_private = True;
+				$groups = $GLOBALS['phpgw']->accounts->membership($owner);
+				while (list($key,$group) = each($groups))
+				{
+					if (strpos(' '.implode(',',$event['groups']).' ',$group['account_id']))
+					{
+						return False;
+					}
+				}
+			}
+			else
+			{
+				return False;
+			}
+
+			return $is_private;
+		}
+
+		function get_short_field($event,$is_private=True,$field='')
+		{
+			if($is_private)
+			{
+				return lang('private');
+			}
+
+// cut off too long titles
+			elseif(strlen($event[$field]) > 19 && !$this->printer_friendly && $field=="title")
+//			elseif(strlen($event[$field]) > 19 && $this->printer_friendly)
+			{
+// we dont use currently 160304
+//				return substr($event[$field], 0 , 19) . '&nbsp;...';
+				return $event[$field];
+			}
+			else
+			{
+				return $event[$field];
+			}
+		}
+
+		function long_date($first,$last=0)
+		{
+			if (!is_array($first))
+			{
+				$first = $this->time2array($raw = $first);
+				$first['raw'] = $raw;
+				$first['day'] = $first['mday'];
+			}
+			if ($last && !is_array($last))
+			{
+				$last = $this->time2array($raw = $last);
+				$last['raw'] = $raw;
+				$last['day'] = $last['mday'];
+			}
+			$datefmt = $this->prefs['common']['dateformat'];
+
+			$month_before_day = strtolower($datefmt[0]) == 'm' ||
+				strtolower($datefmt[2]) == 'm' && $datefmt[4] == 'd';
+
+			for ($i = 0; $i < 5; $i += 2)
+			{
+				switch($datefmt[$i])
+				{
+					case 'd':
+						$range .= $first['day'] . ($datefmt[1] == '.' ? '.' : '');
+						if ($first['month'] != $last['month'] || $first['year'] != $last['year'])
+						{
+							if (!$month_before_day)
+							{
+								$range .= ' '.lang(strftime('%B',$first['raw']));
+							}
+							if ($first['year'] != $last['year'] && $datefmt[0] != 'Y')
+							{
+								$range .= ($datefmt[0] != 'd' ? ', ' : ' ') . $first['year'];
+							}
+							if (!$last)
+							{
+								return $range;
+							}
+							$range .= ' - ';
+
+							if ($first['year'] != $last['year'] && $datefmt[0] == 'Y')
+							{
+								$range .= $last['year'] . ', ';
+							}
+
+							if ($month_before_day)
+							{
+								$range .= lang(strftime('%B',$last['raw']));
+							}
+						}
+						else
+						{
+							$range .= ' - ';
+						}
+						$range .= ' ' . $last['day'] . ($datefmt[1] == '.' ? '.' : '');
+						break;
+					case 'm':
+					case 'M':
+						$range .= ' '.lang(strftime('%B',$month_before_day ? $first['raw'] : $last['raw'])) . ' ';
+						break;
+					case 'Y':
+						$range .= ($datefmt[0] == 'm' ? ', ' : ' ') . ($datefmt[0] == 'Y' ? $first['year'].($datefmt[2] == 'd' ? ', ' : ' ') : $last['year'].' ');
+						break;
+				}
+			}
+			return $range;
+		}
+
+		function get_week_label()
+		{
+			$first = $GLOBALS['phpgw']->datetime->gmtdate($GLOBALS['phpgw']->datetime->get_weekday_start($this->year, $this->month, $this->day));
+			$last = $GLOBALS['phpgw']->datetime->gmtdate($first['raw'] + 518400);
+
+			return ($this->long_date($first,$last));
+		}
+
+		function normalizeminutes(&$minutes)
+		{
+			$hour = 0;
+			$min = (int)$minutes;
+			if($min >= 60)
+			{
+				$hour += $min / 60;
+				$min %= 60;
+			}
+			settype($minutes,'integer');
+			$minutes = $min;
+			return $hour;
+		}
+
+		function splittime($time,$follow_24_rule=True)
+		{
+			$temp = array('hour','minute','second','ampm');
+			$time = strrev($time);
+			$second = (int)(strrev(substr($time,0,2)));
+			$minute = (int)(strrev(substr($time,2,2)));
+			$hour   = (int)(strrev(substr($time,4)));
+			$hour += $this->normalizeminutes($minute);
+			$temp['second'] = $second;
+			$temp['minute'] = $minute;
+			$temp['hour']   = $hour;
+			$temp['ampm']   = '  ';
+			if($follow_24_rule == True)
+			{
+				if ($this->prefs['common']['timeformat'] == '24')
+				{
+					return $temp;
+				}
+
+				$temp['ampm'] = 'am';
+
+				if ((int)$temp['hour'] > 12)
+				{
+					$temp['hour'] = (int)((int)$temp['hour'] - 12);
+					$temp['ampm'] = 'pm';
+				}
+				elseif ((int)$temp['hour'] == 12)
+				{
+					$temp['ampm'] = 'pm';
+				}
+			}
+			return $temp;
+		}
+
+		function get_exception_array($exception_str='')
+		{
+			$exception = Array();
+			if(strpos(' '.$exception_str,','))
+			{
+				$exceptions = explode(',',$exception_str);
+				for($exception_count=0;$exception_count<count($exceptions);$exception_count++)
+				{
+					$exception[] = (int)$exceptions[$exception_count];
+				}
+			}
+			elseif($exception_str != '')
+			{
+				$exception[] = (int)$exception_str;
+			}
+			return $exception;
+		}
+
+		function build_time_for_display($fixed_time)
+		{
+			$time = $this->splittime($fixed_time);
+			$str = $time['hour'].':'.((int)$time['minute']<=9?'0':'').$time['minute'];
+
+			if ($this->prefs['common']['timeformat'] == '12')
+			{
+				$str .= ' ' . $time['ampm'];
+			}
+
+			return $str;
+		}
+
+		function sort_event($event,$date)
+		{
+			$inserted = False;
+			if(isset($event['recur_exception']))
+			{
+				$event_time = mktime($event['start']['hour'],$event['start']['min'],0,(int)(substr($date,4,2)),(int)(substr($date,6,2)),(int)(substr($date,0,4))) - $GLOBALS['phpgw']->datetime->tz_offset;
+				while($inserted == False && list($key,$exception_time) = each($event['recur_exception']))
+				{
+					if($this->debug)
+					{
+						echo '<!-- checking exception datetime '.$exception_time.' to event datetime '.$event_time.' -->'."\n";
+					}
+					if($exception_time == $event_time)
+					{
+						$inserted = True;
+					}
+				}
+			}
+			if($this->cached_events[$date] && $inserted == False)
+			{
+
+				if($this->debug)
+				{
+					echo '<!-- Cached Events found for '.$date.' -->'."\n";
+				}
+				$year = substr($date,0,4);
+				$month = substr($date,4,2);
+				$day = substr($date,6,2);
+
+				if($this->debug)
+				{
+					echo '<!-- Date : '.$date.' Count : '.count($this->cached_events[$date]).' -->'."\n";
+				}
+
+				for($i=0;$i<count($this->cached_events[$date]);$i++)
+				{
+					if($this->cached_events[$date][$i]['id'] == $event['id'] || $this->cached_events[$date][$i]['reference'] == $event['id'])
+					{
+						if($this->debug)
+						{
+							echo '<!-- Item already inserted! -->'."\n";
+						}
+						$inserted = True;
+						break;
+					}
+					/* This puts all spanning events across multiple days up at the top. */
+					if($this->cached_events[$date][$i]['recur_type'] == MCAL_RECUR_NONE)
+					{
+						if($this->cached_events[$date][$i]['start']['mday'] != $day && $this->cached_events[$date][$i]['end']['mday'] >= $day)
+						{
+							continue;
+						}
+					}
+					if(date('Hi',mktime($event['start']['hour'],$event['start']['min'],$event['start']['sec'],$month,$day,$year)) < date('Hi',mktime($this->cached_events[$date][$i]['start']['hour'],$this->cached_events[$date][$i]['start']['min'],$this->cached_events[$date][$i]['start']['sec'],$month,$day,$year)))
+					{
+						for($j=count($this->cached_events[$date]);$j>=$i;$j--)
+						{
+							$this->cached_events[$date][$j] = $this->cached_events[$date][$j-1];
+						}
+						if($this->debug)
+						{
+							echo '<!-- Adding event ID: '.$event['id'].' to cached_events -->'."\n";
+						}
+						$inserted = True;
+						$this->cached_events[$date][$i] = $event;
+						break;
+					}
+				}
+			}
+			if(!$inserted)
+			{
+				if($this->debug)
+				{
+					echo '<!-- Adding event ID: '.$event['id'].' to cached_events -->'."\n";
+				}
+				$this->cached_events[$date][] = $event;
+			}
+		}
+
+		function check_repeating_events($datetime)
+		{
+			@reset($this->repeating_events);
+			$search_date_full = date('Ymd',$datetime);
+			$search_date_year = date('Y',$datetime);
+			$search_date_month = date('m',$datetime);
+			$search_date_day = date('d',$datetime);
+			$search_date_dow = date('w',$datetime);
+			$search_beg_day = mktime(0,0,0,$search_date_month,$search_date_day,$search_date_year);
+			if($this->debug)
+			{
+				echo '<!-- Search Date Full = '.$search_date_full.' -->'."\n";
+			}
+			$repeated = $this->repeating_events;
+			$r_events = count($repeated);
+			for ($i=0;$i<$r_events;$i++)
+			{
+				$rep_events = $this->repeating_events[$i];
+				$id = $rep_events['id'];
+				$event_beg_day = mktime(0,0,0,$rep_events['start']['month'],$rep_events['start']['mday'],$rep_events['start']['year']);
+				if($rep_events['recur_enddate']['month'] != 0 && $rep_events['recur_enddate']['mday'] != 0 && $rep_events['recur_enddate']['year'] != 0)
+				{
+					$event_recur_time = $this->maketime($rep_events['recur_enddate']);
+				}
+				else
+				{
+					$event_recur_time = mktime(0,0,0,1,1,2030);
+				}
+				$end_recur_date = date('Ymd',$event_recur_time);
+				$full_event_date = date('Ymd',$event_beg_day);
+
+				if($this->debug)
+				{
+					echo '<!-- check_repeating_events - Processing ID - '.$id.' -->'."\n";
+					echo '<!-- check_repeating_events - Recurring End Date - '.$end_recur_date.' -->'."\n";
+				}
+
+				// only repeat after the beginning, and if there is an rpt_end before the end date
+				if (($search_date_full > $end_recur_date) || ($search_date_full < $full_event_date))
+				{
+					continue;
+				}
+
+				if ($search_date_full == $full_event_date)
+				{
+					$this->sort_event($rep_events,$search_date_full);
+					continue;
+				}
+				else
+				{
+					$freq = $rep_events['recur_interval'];
+					$freq = $freq ? $freq : 1;
+					$type = $rep_events['recur_type'];
+					switch($type)
+					{
+						case MCAL_RECUR_DAILY:
+							if($this->debug)
+							{
+								echo '<!-- check_repeating_events - MCAL_RECUR_DAILY - '.$id.' -->'."\n";
+							}
+							
+							if ($freq == 1 && $rep_events['recur_enddate']['month'] != 0 && $rep_events['recur_enddate']['mday'] != 0 && $rep_events['recur_enddate']['year'] != 0 && $search_date_full <= $end_recur_date)
+							{
+								$this->sort_event($rep_events,$search_date_full);
+							}
+							elseif (floor(($search_beg_day - $event_beg_day)/86400) % ($freq ? $freq : 1))
+							{
+								continue;
+							}
+							else
+							{
+								$this->sort_event($rep_events,$search_date_full);
+							}
+							break;
+						case MCAL_RECUR_WEEKLY:
+							if (floor(($search_beg_day - $event_beg_day)/604800)  % ($freq ? $freq : 1))
+							{
+								continue;
+							}
+							$check = 0;
+							switch($search_date_dow)
+							{
+								case 0:
+									$check = MCAL_M_SUNDAY;
+									break;
+								case 1:
+									$check = MCAL_M_MONDAY;
+									break;
+								case 2:
+									$check = MCAL_M_TUESDAY;
+									break;
+								case 3:
+									$check = MCAL_M_WEDNESDAY;
+									break;
+								case 4:
+									$check = MCAL_M_THURSDAY;
+									break;
+								case 5:
+									$check = MCAL_M_FRIDAY;
+									break;
+								case 6:
+									$check = MCAL_M_SATURDAY;
+									break;
+							}
+							if ($rep_events['recur_data'] & $check)
+							{
+								$this->sort_event($rep_events,$search_date_full);
+							}
+							break;
+						case MCAL_RECUR_MONTHLY_WDAY:
+							if ((($search_date_year - $rep_events['start']['year']) * 12 + $search_date_month - $rep_events['start']['month']) % $freq)
+							{
+								continue;
+							}
+
+							if (($GLOBALS['phpgw']->datetime->day_of_week($rep_events['start']['year'],$rep_events['start']['month'],$rep_events['start']['mday']) == $GLOBALS['phpgw']->datetime->day_of_week($search_date_year,$search_date_month,$search_date_day)) &&
+								(ceil($rep_events['start']['mday']/7) == ceil($search_date_day/7)))
+							{
+								$this->sort_event($rep_events,$search_date_full);
+							}
+							break;
+						case MCAL_RECUR_MONTHLY_MDAY:
+							if ((($search_date_year - $rep_events['start']['year']) * 12 + $search_date_month - $rep_events['start']['month'])  % ($freq ? $freq : 1))
+							{
+								continue;
+							}
+							if ($search_date_day == $rep_events['start']['mday'])
+							{
+								$this->sort_event($rep_events,$search_date_full);
+							}
+							break;
+						case MCAL_RECUR_YEARLY:
+							if (($search_date_year - $rep_events['start']['year']) % ($freq ? $freq : 1))
+							{
+								continue;
+							}
+							if (date('dm',$datetime) == date('dm',$event_beg_day))
+							{
+								$this->sort_event($rep_events,$search_date_full);
+							}
+							break;
+					}
+				}
+			}	// end for loop
+		}	// end function
+
+		function store_to_cache($params)
+		{
+			if(!is_array($params))
+			{
+				return False;
+			}
+			if (isset($params['start']) && ($datearr = $GLOBALS['server']->iso86012date($params['start'])))
+			{
+				$syear = $datearr['year'];
+				$smonth = $datearr['month'];
+				$sday = $datearr['mday'];
+				$this->xmlrpc = True;
+			}
+			else
+			{
+				$syear = $params['syear'];
+				$smonth = $params['smonth'];
+				$sday = $params['sday'];
+			}
+			if (isset($params['end']) && ($datearr = $GLOBALS['server']->iso86012date($params['end'])))
+			{
+				$eyear = $datearr['year'];
+				$emonth = $datearr['month'];
+				$eday = $datearr['mday'];
+				$this->xmlrpc = True;
+			}
+			else
+			{
+				$eyear = (isset($params['eyear'])?$params['eyear']:0);
+				$emonth = (isset($params['emonth'])?$params['emonth']:0);
+				$eday = (isset($params['eday'])?$params['eday']:0);
+			}
+			if (!isset($params['owner']) && @$this->xmlrpc)
+			{
+				$owner_id = $GLOBALS['phpgw_info']['user']['user_id'];
+			}
+			else
+			{
+				$owner_id = (isset($params['owner'])?$params['owner']:0);
+				if($owner_id==0 && $this->is_group)
+				{
+					unset($owner_id);
+					$owner_id = $this->g_owner;
+					if($this->debug)
+					{
+						echo '<!-- owner_id in ('.implode(',',$owner_id).') -->'."\n";
+					}
+				}
+			}
+			if(!$eyear && !$emonth && !$eday)
+			{
+				$edate = mktime(23,59,59,$smonth + 1,$sday + 1,$syear);
+				$eyear = date('Y',$edate);
+				$emonth = date('m',$edate);
+				$eday = date('d',$edate);
+			}
+			else
+			{
+				if(!$eyear)
+				{
+					$eyear = $syear;
+				}
+				if(!$emonth)
+				{
+					$emonth = $smonth + 1;
+					if($emonth > 12)
+					{
+						$emonth = 1;
+						$eyear++;
+					}
+				}
+				if(!$eday)
+				{
+					$eday = $sday + 1;
+				}
+				$edate = mktime(23,59,59,$emonth,$eday,$eyear);
+			}
+			//echo "<p>bocalendar::store_to_cache(".print_r($params,True).") syear=$syear, smonth=$smonth, sday=$sday, eyear=$eyear, emonth=$emonth, eday=$eday, xmlrpc='$param[xmlrpc]'</p>\n";
+			if($this->debug)
+			{
+				echo '<!-- Start Date : '.sprintf("%04d%02d%02d",$syear,$smonth,$sday).' -->'."\n";
+				echo '<!-- End   Date : '.sprintf("%04d%02d%02d",$eyear,$emonth,$eday).' -->'."\n";
+			}
+
+			if($owner_id)
+			{
+				$cached_event_ids = $this->so->list_events($syear,$smonth,$sday,$eyear,$emonth,$eday,$owner_id);
+				$cached_event_ids_repeating = $this->so->list_repeated_events($syear,$smonth,$sday,$eyear,$emonth,$eday,$owner_id);
+			}
+			else
+			{
+				$cached_event_ids = $this->so->list_events($syear,$smonth,$sday,$eyear,$emonth,$eday);
+				$cached_event_ids_repeating = $this->so->list_repeated_events($syear,$smonth,$sday,$eyear,$emonth,$eday);
+			}
+
+			$c_cached_ids = count($cached_event_ids);
+			$c_cached_ids_repeating = count($cached_event_ids_repeating);
+
+			if($this->debug)
+			{
+				echo '<!-- events cached : '.$c_cached_ids.' : for : '.sprintf("%04d%02d%02d",$syear,$smonth,$sday).' -->'."\n";
+				echo '<!-- repeating events cached : '.$c_cached_ids_repeating.' : for : '.sprintf("%04d%02d%02d",$syear,$smonth,$sday).' -->'."\n";
+			}
+
+			$this->cached_events = Array();
+
+			if($c_cached_ids == 0 && $c_cached_ids_repeating == 0)
+			{
+				return;
+			}
+
+			$cache_start = (int)(sprintf("%04d%02d%02d",$syear,$smonth,$sday));
+			$cached_event=$this->get_cached_event();
+			if($c_cached_ids)
+			{
+				for($i=0;$i<$c_cached_ids;$i++)
+				{
+					$event = $this->so->read_entry($cached_event_ids[$i]);
+					if ($event['recur_type'])
+					{
+						continue;	// fetch recuring events only in 2. loop
+					}
+					$startdate = (int)(date('Ymd',$this->maketime($event['start'])));
+					$enddate = (int)(date('Ymd',$this->maketime($event['end'])));
+					$this->cached_events[$startdate][] = $event;
+					if($startdate != $enddate)
+					{
+						$start['year'] = (int)(substr($startdate,0,4));
+						$start['month'] = (int)(substr($startdate,4,2));
+						$start['mday'] = (int)(substr($startdate,6,2));
+						for($j=$startdate,$k=0;$j<=$enddate;$k++,$j=(int)(date('Ymd',mktime(0,0,0,$start['month'],$start['mday'] + $k,$start['year']))))
+						{
+							$c_evt_day = count($this->cached_events[$j]) - 1;
+							if($c_evt_day < 0)
+							{
+								$c_evt_day = 0;
+							}
+							if($this->debug)
+							{
+								echo '<!-- Date: '.$j.' Count : '.$c_evt_day.' -->'."\n";
+							}
+							if($this->cached_events[$j][$c_evt_day]['id'] != $event['id'])
+							{
+								if($this->debug)
+								{
+									echo '<!-- Adding Event for Date: '.$j.' -->'."\n";
+								}
+								$this->cached_events[$j][] = $event;
+							}
+							if ($j >= $cache_start && (@$params['no_doubles'] || @$this->xmlrpc))
+							{
+								break;	// add event only once on it's startdate
+							}
+						}
+					}
+				}
+			}
+
+			$this->repeating_events = Array();
+			if($c_cached_ids_repeating)
+			{
+				for($i=0;$i<$c_cached_ids_repeating;$i++)
+				{
+					$this->repeating_events[$i] = $this->so->read_entry($cached_event_ids_repeating[$i]);
+					if($this->debug)
+					{
+						echo '<!-- Cached Events ID: '.$cached_event_ids_repeating[$i].' ('.sprintf("%04d%02d%02d",$this->repeating_events[$i]['start']['year'],$this->repeating_events[$i]['start']['month'],$this->repeating_events[$i]['start']['mday']).') -->'."\n";
+					}
+				}
+				for($date=mktime(0,0,0,$smonth,$sday,$syear);$date<=$edate;$date += 86400)
+				{
+					if($this->debug)
+					{
+						$search_date = date('Ymd',$date);
+						echo '<!-- Calling check_repeating_events('.$search_date.') -->'."\n";
+					}
+					$this->check_repeating_events($date);
+					if($this->debug)
+					{
+						echo '<!-- Total events found matching '.$search_date.' = '.count($this->cached_events[$search_date]).' -->'."\n";
+						for($i=0;$i<count($this->cached_events[$search_date]);$i++)
+						{
+							echo '<!-- Date: '.$search_date.' ['.$i.'] = '.$this->cached_events[$search_date][$i]['id'].' -->'."\n";
+						}
+					}
+				}
+			}
+			$retval = Array();
+			for($j=date('Ymd',mktime(0,0,0,$smonth,$sday,$syear)),$k=0;$j<=date('Ymd',mktime(0,0,0,$emonth,$eday,$eyear));$k++,$j=date('Ymd',mktime(0,0,0,$smonth,$sday + $k,$syear)))
+			{
+				if(is_array($this->cached_events[$j]))
+				{
+					if ($this->xmlrpc)
+					{
+						foreach($this->cached_events[$j] as $event)
+						{
+							$retval[] = $this->xmlrpc_prepare($event);
+						}
+					}
+					else
+					{
+						$retval[$j] = $this->cached_events[$j];
+					}
+				}
+			}
+			//echo "store_to_cache(".print_r($params,True).")=<pre>".print_r($retval,True)."</pre>\n";
+			$this->so->cal->event = $cached_event;
+			return $retval;
+		}
+
+		function xmlrpc_prepare(&$event)
+		{
+			$event['rights'] = $this->grants[$event['owner']];
+
+			foreach(array('start','end','modtime','recur_enddate') as $name)
+			{
+				if (isset($event[$name]))
+				{
+					$event[$name] = $GLOBALS['server']->date2iso8601($event[$name]);
+				}
+			}
+			if (is_array($event['recur_exception']))
+			{
+				foreach($event['recur_exception'] as $key => $timestamp)
+				{
+					$event['recur_exception'][$key] = $GLOBALS['server']->date2iso8601($timestamp);
+				}
+			}
+			static $user_cache = array();
+
+			if (!is_object($GLOBALS['phpgw']->perferences))
+			{
+				$GLOBALS['phpgw']->perferences = CreateObject('phpgwapi.preferences');
+			}
+			foreach($event['participants'] as $user_id => $status)
+			{
+				if (!isset($user_cache[$user_id]))
+				{
+					$user_cache[$user_id] = array(
+						'name'   => $GLOBALS['phpgw']->common->grab_owner_name($user_id),
+						'email'  => $GLOBALS['phpgw']->perferences->email_address($user_id)
+					);
+				}
+				$event['participants'][$user_id] = $user_cache[$user_id] + array(
+					'status' => $status,
+				);
+			}
+			if (is_array($event['alarm']))
+			{
+				foreach($event['alarm'] as $id => $alarm)
+				{
+					$event['alarm'][$id]['time'] = $GLOBALS['server']->date2iso8601($alarm['time']);
+					if ($alarm['owner'] != $GLOBALS['phpgw_info']['user']['account_id'])
+					{
+						unset($event['alarm'][$id]);
+					}
+				}
+			}
+			$event['category'] = $GLOBALS['server']->cats2xmlrpc(explode(',',$event['category']));
+
+			// using access={public|privat} in all modules via xmlrpc
+			$event['access'] = $event['public'] ? 'public' : 'privat';
+			unset($event['public']);
+
+			return $event;
+		}
+
+		/* Begin Appsession Data */
+		function store_to_appsession($event)
+		{
+			$GLOBALS['phpgw']->session->appsession('entry','calendar',$event);
+		}
+
+		function restore_from_appsession()
+		{
+			$this->event_init();
+			$event = $GLOBALS['phpgw']->session->appsession('entry','calendar');
+			$this->so->cal->event = $event;
+			return $event;
+		}
+		/* End Appsession Data */
+
+		/* Begin of SO functions */
+		function get_cached_event()
+		{
+			return $this->so->get_cached_event();
+		}
+
+		function add_attribute($var,$value,$index='**(**')
+		{
+			$this->so->add_attribute($var,$value,$index);
+		}
+
+		function event_init()
+		{
+			$this->so->event_init();
+		}
+
+		function set_start($year,$month,$day=0,$hour=0,$min=0,$sec=0)
+		{
+			$this->so->set_start($year,$month,$day,$hour,$min,$sec);
+		}
+
+		function set_end($year,$month,$day=0,$hour=0,$min=0,$sec=0)
+		{
+			$this->so->set_end($year,$month,$day,$hour,$min,$sec);
+		}
+
+		function set_title($title='')
+		{
+			$this->so->set_title($title);
+		}
+
+		function set_description($description='')
+		{
+			$this->so->set_description($description);
+		}
+		function set_ex_participants($ex_participants='')
+		{
+			$this->so->set_ex_participants($ex_participants);
+		}
+
+		function set_class($class)
+		{
+			$this->so->set_class($class);
+		}
+
+		function set_category($category='')
+		{
+			$this->so->set_category($category);
+		}
+
+		function set_alarm($alarm)
+		{
+			$this->so->set_alarm($alarm);
+		}
+
+		function set_recur_none()
+		{
+			$this->so->set_recur_none();
+		}
+
+		function set_recur_daily($year,$month,$day,$interval)
+		{
+			$this->so->set_recur_daily($year,$month,$day,$interval);
+		}
+
+		function set_recur_weekly($year,$month,$day,$interval,$weekdays)
+		{
+			$this->so->set_recur_weekly($year,$month,$day,$interval,$weekdays);
+		}
+
+		function set_recur_monthly_mday($year,$month,$day,$interval)
+		{
+			$this->so->set_recur_monthly_mday($year,$month,$day,$interval);
+		}
+
+		function set_recur_monthly_wday($year,$month,$day,$interval)
+		{
+			$this->so->set_recur_monthly_wday($year,$month,$day,$interval);
+		}
+
+		function set_recur_yearly($year,$month,$day,$interval)
+		{
+			$this->so->set_recur_yearly($year,$month,$day,$interval);
+		}
+		/* End of SO functions */
+
+		function prepare_matrix($interval,$increment,$part,$fulldate)
+		{
+			for($h=0;$h<24;$h++)
+			{
+				for($m=0;$m<$interval;$m++)
+				{
+					$index = (($h * 10000) + (($m * $increment) * 100));
+					$time_slice[$index]['marker'] = '&nbsp';
+					$time_slice[$index]['description'] = '';
+				}
+			}
+			foreach($this->cached_events[$fulldate] as $event)
+			{
+				if ($event['participants'][$part] == 'R')
+				{
+					continue;	// dont show rejected invitations, as they are free time
+				}
+				$eventstart = $GLOBALS['phpgw']->datetime->localdates($this->maketime($event['start']) - $GLOBALS['phpgw']->datetime->tz_offset);
+				$eventend = $GLOBALS['phpgw']->datetime->localdates($this->maketime($event['end']) - $GLOBALS['phpgw']->datetime->tz_offset);
+				$start = ($eventstart['hour'] * 10000) + ($eventstart['minute'] * 100);
+				$starttemp = $this->splittime("$start",False);
+				$subminute = 0;
+				for($m=0;$m<$interval;$m++)
+				{
+					$minutes = $increment * $m;
+					if((int)$starttemp['minute'] > $minutes && (int)$starttemp['minute'] < ($minutes + $increment))
+					{
+						$subminute = ($starttemp['minute'] - $minutes) * 100;
+					}
+				}
+				$start -= $subminute;
+				$end =  ($eventend['hour'] * 10000) + ($eventend['minute'] * 100);
+				$endtemp = $this->splittime("$end",False);
+				$addminute = 0;
+				for($m=0;$m<$interval;$m++)
+				{
+					$minutes = ($increment * $m);
+					if($endtemp['minute'] < ($minutes + $increment) && $endtemp['minute'] > $minutes)
+					{
+						$addminute = ($minutes + $increment - $endtemp['minute']) * 100;
+					}
+				}
+				$end += $addminute;
+				$starttemp = $this->splittime("$start",False);
+				$endtemp = $this->splittime("$end",False);
+
+				for($h=$starttemp['hour'];$h<=$endtemp['hour'];$h++)
+				{
+					$startminute = 0;
+					$endminute = $interval;
+					$hour = $h * 10000;
+					if($h == (int)$starttemp['hour'])
+					{
+						$startminute = ($starttemp['minute'] / $increment);
+					}
+					if($h == (int)$endtemp['hour'])
+					{
+						$endminute = ($endtemp['minute'] / $increment);
+					}
+					$private = $this->is_private($event,$part);
+					$time_display = $GLOBALS['phpgw']->common->show_date($eventstart['raw'],$this->users_timeformat).'-'.$GLOBALS['phpgw']->common->show_date($eventend['raw'],$this->users_timeformat);
+					$time_description = '('.$time_display.') '.$this->get_short_field($event,$private,'title').$this->display_status($event['participants'][$part]);
+					for($m=$startminute;$m<$endminute;$m++)
+					{
+						$index = ($hour + (($m * $increment) * 100));
+						$time_slice[$index]['marker'] = '-';
+						$time_slice[$index]['description'] = $time_description;
+						$time_slice[$index]['id'] = $event['id'];
+					}
+				}
+			}
+			return $time_slice;
+		}
+
+		/*!
+		@function set_status
+		@abstract set the participant response $status for event $cal_id and notifies the owner of the event
+		*/
+		function set_status($cal_id,$status)
+		{
+			$status2msg = array(
+				REJECTED  => MSG_REJECTED,
+				TENTATIVE => MSG_TENTATIVE,
+				ACCEPTED  => MSG_ACCEPTED
+			);
+			if (!isset($status2msg[$status]))
+			{
+				return False;
+			}
+			$event = $this->so->read_entry($cal_id);
+			$account_id = $GLOBALS['phpgw_info']['user']['account_id'];
+			if(($status2msg[$status] == "5" && $event['participants'][$account_id] == "A") ||
+			 ($status2msg[$status] == "3" && $event['participants'][$account_id] == "R")) {
+				return True;
+			}
+			$this->so->set_status($cal_id,$status);
+			$event = $this->so->read_entry($cal_id);
+			$this->send_update($status2msg[$status],$event['participants'],$event);
+
+		}
+
+		/*!
+		@function update_requested
+		@abstract checks if $userid has requested (in $part_prefs) updates for $msg_type
+		@syntax update_requested($userid,$part_prefs,$msg_type,$old_event,$new_event)
+		@param $userid numerical user-id
+		@param $part_prefs preferces of the user $userid
+		@param $msg_type type of the notification: MSG_ADDED, MSG_MODIFIED, MSG_ACCEPTED, ...
+		@param $old_event Event before the change
+		@param $new_event Event after the change
+		@returns 0 = no update requested, > 0 update requested
+		*/
+		function update_requested($userid,$part_prefs,$msg_type,$old_event,$new_event)
+		{
+			if ($msg_type == MSG_ALARM)
+			{
+				return True;	// always True for now
+			}
+			$want_update = 0;
+
+			// the following switch fall-through all cases, as each included the following too
+			//
+			$msg_is_response = $msg_type == MSG_REJECTED || $msg_type == MSG_ACCEPTED || $msg_type == MSG_TENTATIVE;
+
+			switch($ru = $part_prefs['calendar']['receive_updates'])
+			{
+				case 'responses':
+					if ($msg_is_response)
+					{
+						++$want_update;
+					}
+				case 'modifications':
+					if ($msg_type == MSG_MODIFIED)
+					{
+						++$want_update;
+					}
+				case 'time_change_4h':
+				case 'time_change':
+					$diff = max(abs($this->maketime($old_event['start'])-$this->maketime($new_event['start'])),
+						abs($this->maketime($old_event['end'])-$this->maketime($new_event['end'])));
+					$check = $ru == 'time_change_4h' ? 4 * 60 * 60 - 1 : 0;
+					if ($msg_type == MSG_MODIFIED && $diff > $check)
+					{
+						++$want_update;
+					}
+				case 'add_cancel':
+					if ($old_event['owner'] == $userid && $msg_is_response ||
+						$msg_type == MSG_DELETED || $msg_type == MSG_ADDED)
+					{
+						++$want_update;
+					}
+					break;
+				case 'no':
+					break;
+			}
+			//echo "<p>bocalendar::update_requested(user=$userid,pref=".$part_prefs['calendar']['receive_updates'] .",msg_type=$msg_type,".($old_event?$old_event['title']:'False').",".($old_event?$old_event['title']:'False').") = $want_update</p>\n";
+			return $want_update > 0;
+		}
+
+	function create_vcard($event_array)
+	{
+	if(!is_array($event_array))
+		return null;
+	$tmpattach="BEGIN:VCALENDAR\n"
+	."PRODID:-//Expresso Livre//Calendar//EN\n"
+	."VERSION:1.0\n";
+		foreach ($event_array as $event)
+		{
+			// It translates int to string
+			if (!is_object($event) && !is_array($event) || !array_key_exists  ('end', $event))
+				$event = $event_array;
+			if ( $event['end']['month'] < 10 )
+				$end_event_month="0".$event['end']['month'];
+			else
+				$end_event_month=$event['end']['month'];
+			if ( $event['start']['month'] < 10 )
+				$start_event_month="0".$event['start']['month'];
+			else
+				$start_event_month=$event['start']['month'];
+			if ( $event['end']['mday'] < 10 )
+				$end_event_day="0".$event['end']['mday'];
+			else
+				$end_event_day=$event['end']['mday'];
+			if ( $event['start']['mday'] < 10 )
+				$start_event_day="0".$event['start']['mday'];
+			else
+				$start_event_day=$event['start']['mday'];
+			if ( $event['start']['hour'] < 10)
+				$start_event_hour="0".$event['start']['hour'];
+			else
+				$start_event_hour=$event['start']['hour'];
+			if ( $event['end']['hour'] < 10)
+				$end_event_hour="0".$event['end']['hour'];
+			else
+				$end_event_hour=$event['end']['hour'];
+				
+			if ( $event['start']['min'] < 10)
+				$start_event_min="0".$event['start']['min'];
+			else
+				$start_event_min=$event['start']['min'];
+			if ( $event['end']['min'] < 10)
+				$end_event_min="0".$event['end']['min'];
+			else
+				$end_event_min=$event['end']['min'];	
+		
+
+			$tmpattach.="BEGIN:VEVENT\n"
+			."DTSTART:".$event['start'][year].$start_event_month.$start_event_day."T".$start_event_hour.$start_event_min."00Z\n"
+			."DTEND:".$event[end][year].$end_event_month.$end_event_day."T".$end_event_hour.$end_event_min."00Z\n"
+			."UID:Expresso-".$event[id].$event[uid]."\n"
+			."LAST-MODIFIED:".time()."\n"
+			."DESCRIPTION:".$event[description]."\n"
+			."SUMMARY:".$event[title]."\n"
+			."LOCATION:".$event[location]."\n"
+			."END:VEVENT"."\n";
+		}
+			$tmpattach.="END:VCALENDAR\n";
+			return $tmpattach;
+}
+
+		/*!
+		@function send_update
+		@abstract sends update-messages to certain participants of an event
+		@syntax send_update($msg_type,$to_notify,$old_event,$new_event=False)
+		@param $msg_type type of the notification: MSG_ADDED, MSG_MODIFIED, MSG_ACCEPTED, ...
+		@param $to_notify array with numerical user-ids as keys (!) (value is not used)
+		@param $old_event Event before the change
+		@param $new_event Event after the change
+		*/
+		function send_update($msg_type,$to_notify,$old_event,$new_event=False,$user=False)
+		{
+			
+			//echo "<p>bocalendar::send_update(type=$msg_type,to_notify="; print_r($to_notify); echo ", old_event="; print_r($old_event); echo ", new_event="; print_r($new_event); echo ", user=$user)</p>\n";
+			if (!is_array($to_notify))
+			{
+				$to_notify = array();
+			}
+			$owner = $old_event ? $old_event['owner'] : $new_event['owner'];
+			if ($owner && !isset($to_notify[$owner]) && $msg_type != MSG_ALARM)
+			{
+				$to_notify[$owner] = 'owner';	// always include the event-owner
+			}
+			$version = $GLOBALS['phpgw_info']['apps']['calendar']['version'];
+
+			$GLOBALS['phpgw_info']['user']['preferences'] = $GLOBALS['phpgw']->preferences->create_email_preferences();
+			$sender = $GLOBALS['phpgw_info']['user']['email'];
+
+			$temp_tz_offset = $this->prefs['common']['tz_offset'];
+			$temp_timeformat = $this->prefs['common']['timeformat'];
+			$temp_dateformat = $this->prefs['common']['dateformat'];
+
+			$tz_offset = ((60 * 60) * (int)$temp_tz_offset);
+
+			if($old_event != False)
+			{
+				$t_old_start_time = $this->maketime($old_event['start']);
+				if($t_old_start_time < (time() - 86400))
+				{
+					return False;
+				}
+			}
+
+			$temp_user = $GLOBALS['phpgw_info']['user'];
+
+			if (!$user)
+			{
+				$user = $this->owner;
+			}
+			$GLOBALS['phpgw_info']['user']['preferences'] = $GLOBALS['phpgw']->preferences->create_email_preferences($user);
+
+			$event = $msg_type == MSG_ADDED || $msg_type == MSG_MODIFIED ? $new_event : $old_event;
+			if($old_event != False)
+			{
+				$old_starttime = $t_old_start_time - $GLOBALS['phpgw']->datetime->tz_offset;
+			}
+			$starttime = $this->maketime($event['start']) - $GLOBALS['phpgw']->datetime->tz_offset;
+			$endtime   = $this->maketime($event['end']) - $GLOBALS['phpgw']->datetime->tz_offset;
+
+			switch($msg_type)
+			{
+				case MSG_DELETED:
+					$action = lang('Canceled');
+					$msg = 'Canceled';
+					$msgtype = '"calendar";';
+					$method = 'cancel';
+					$typesend = 1;
+					break;
+				case MSG_MODIFIED:
+					$action = lang('Modified');
+					$msg = 'Modified';
+					$msgtype = '"calendar"; Version="'.$version.'"; Id="'.$new_event['id'].'"';
+					$method = 'request';
+					$typesend = 2;
+					break;
+				case MSG_ADDED:
+					$action = lang('Added');
+					$msg = 'Added';
+					$msgtype = '"calendar"; Version="'.$version.'"; Id="'.$new_event['id'].'"';
+					$method = 'request';
+					$typesend = 3;
+					break;
+				case MSG_REJECTED:
+					$action = lang('Rejected');
+					$msg = 'Response';
+					$msgtype = '"calendar";';
+					$method = 'reply';
+					$typesend = 4;
+					break;
+				case MSG_TENTATIVE:
+					$action = lang('Tentative');
+					$msg = 'Response';
+					$msgtype = '"calendar";';
+					$method = 'reply';
+					$typesend = 5;
+					break;
+				case MSG_ACCEPTED:
+					$action = lang('Accepted');
+					$msg = 'Response';
+					$msgtype = '"calendar";';
+					$method = 'reply';
+					$typesend = 6;
+					break;
+				case MSG_ALARM:
+					$action = lang('Alarm');
+					$msg = 'Alarm';
+					$msgtype = '"calendar";';
+					$method = 'publish';	// duno if thats right
+					$typesend = 7;
+					break;
+				default:
+					$method = 'publish';
+					$typesend = 8;
+			}
+			$notify_msg = $this->prefs['calendar']['notify'.$msg];
+			if (empty($notify_msg))
+			{
+				$notify_msg = $this->prefs['calendar']['notifyAdded'];	// use a default
+			}
+			$details = array(			// event-details for the notify-msg
+				'id'          => $msg_type == MSG_ADDED ? $new_event['id'] : $old_event['id'],
+				'action'      => $action,
+			);
+			$event_arr = $this->event2array($event);
+			foreach($event_arr as $key => $val)
+			{
+				$details[$key] = $val['data'];
+			}
+			
+			$details['participants'] = implode("\n",$details['participants']);
+
+			$details['link'] = $GLOBALS['phpgw_info']['server']['webserver_url'].'/index.php?menuaction=calendar.uicalendar.view&cal_id='.$event['id'];
+			// if url is only a path, try guessing the rest ;-)
+			if ($GLOBALS['phpgw_info']['server']['webserver_url'][0] == '/')
+			{
+				$details['link'] = ($GLOBALS['phpgw_info']['server']['enforce_ssl'] ? 'https://' : 'http://').
+					($GLOBALS['phpgw_info']['server']['hostname'] ? $GLOBALS['phpgw_info']['server']['hostname'] : 'localhost').
+					$details['link'];
+			}
+			
+			//Seta o email usando phpmailer
+			define('PHPGW_INCLUDE_ROOT','../');	
+			define('PHPGW_API_INC','../phpgwapi/inc');	
+			include_once(PHPGW_API_INC.'/class.phpmailer.inc.php');
+			$mail = new PHPMailer();
+			$mail->IsSMTP();
+			$boemailadmin = CreateObject('emailadmin.bo');
+			$emailadmin_profile = $boemailadmin->getProfileList();
+			$emailadmin = $boemailadmin->getProfile($emailadmin_profile[0]['profileID']);
+		
+			$mail->Host = $emailadmin['smtpServer'];
+			$mail->Port = $emailadmin['smtpPort'];
+			$mail->From = $GLOBALS['phpgw']->preferences->values['email'];
+			$mail->FromName = $GLOBALS['phpgw_info']['user']['fullname'];
+			$mail->IsHTML(true);
+
+			// Aqui ï¿œ enviado o email
+			foreach($to_notify as $userid => $statusid) 
+			{
+			 	$mail->ClearAttachments();
+			 	
+				$userid = (int)$userid;
+
+				if ($statusid == 'R' || $GLOBALS['phpgw']->accounts->get_type($userid) == 'g')
+				{
+					continue;	// dont notify rejected participants
+				}
+				if($userid != $GLOBALS['phpgw_info']['user']['account_id'] ||  $msg_type == MSG_ALARM)
+				{
+					print_debug('Msg Type',$msg_type);
+					print_debug('UserID',$userid);
+
+					$preferences = CreateObject('phpgwapi.preferences',$userid);
+					$part_prefs = $preferences->read_repository();
+
+					if (!$this->update_requested($userid,$part_prefs,$msg_type,$old_event,$new_event))
+					{
+						continue;
+					}
+					$GLOBALS['phpgw']->accounts->get_account_name($userid,$lid,$details['to-firstname'],$details['to-lastname']);
+					$details['to-fullname'] = $GLOBALS['phpgw']->common->display_fullname('',$details['to-firstname'],$details['to-lastname']);
+
+					$to = $preferences->email_address($userid);
+					
+					if (empty($to) || $to[0] == '@' || $to[0] == '$')	// we have no valid email-address
+					{
+						//echo "<p>bocalendar::send_update: Empty email adress for user '".$details['to-fullname']."' ==> ignored !!!</p>\n";
+						continue;
+					}
+					print_debug('Email being sent to',$to);
+
+					$GLOBALS['phpgw_info']['user']['preferences']['common']['tz_offset'] = $part_prefs['common']['tz_offset'];
+					$GLOBALS['phpgw_info']['user']['preferences']['common']['timeformat'] = $part_prefs['common']['timeformat'];
+					$GLOBALS['phpgw_info']['user']['preferences']['common']['dateformat'] = $part_prefs['common']['dateformat'];
+
+					$GLOBALS['phpgw']->datetime->tz_offset = ((60 * 60) * (int)$GLOBALS['phpgw_info']['user']['preferences']['common']['tz_offset']);
+
+					if($old_starttime)
+					{
+						$details['olddate'] = $GLOBALS['phpgw']->common->show_date($old_starttime);
+					}
+					$details['startdate'] = $GLOBALS['phpgw']->common->show_date($starttime);
+					$details['enddate']   = $GLOBALS['phpgw']->common->show_date($endtime);
+					
+					
+					list($subject,$body1) = split("\n",$GLOBALS['phpgw']->preferences->parse_notify($notify_msg,$details),2);
+					
+					switch($part_prefs['calendar']['update_format'])
+ 					{
+						case  'extended':
+							//$body .= "\n\n".lang('Event Details follow').":\n";
+							$body = '';
+							$body .= "<br>".lang('Event Details follow')." :: ";
+							foreach($event_arr as $key => $val)
+							{
+								// titulo
+								if($key =='title')
+								{
+									$var1 = $val['field'];
+									$vardata1 = $details[$key];
+								}
+								//descricao
+								if($key =='description')
+								{
+									$var2 = $val['field'];
+									$vardata2 = $details[$key];
+								}
+								//dt inicio
+								if($key =='startdate')
+								{
+									switch(trim($part_prefs['common']['dateformat']))
+									{
+										
+										case ($part_prefs['common']['dateformat'] === "m/d/Y" || $part_prefs['common']['dateformat'] === "m-d-Y" || $part_prefs['common']['dateformat'] === "m.d.Y"):
+											$var3 = $val['field'];
+											$vardata3 = $details[$key];
+											$newmounth3 = substr($vardata3,0,2);
+											$newday3 = substr($vardata3,3,2);
+											$newyear3 = substr($vardata3,6,4);
+											$newall3 =$newyear3.$newmounth3.$newday3;
+											break;
+											
+										case	($part_prefs['common']['dateformat'] === "Y/d/m" || $part_prefs['common']['dateformat'] === "Y-d-m" || $part_prefs['common']['dateformat'] === "Y.d.m"):
+
+											$var3 = $val['field'];
+											$vardata3 = $details[$key];
+											$newyear3 = substr($vardata3,0,4);
+											$newday3 = substr($vardata3,5,2);
+											$newmounth3 = substr($vardata3,8,2);
+											$newall3 =$newyear3.$newmounth3.$newday3;
+											break;
+
+										case ($part_prefs['common']['dateformat'] === "Y/m/d" || $part_prefs['common']['dateformat'] === "Y-m-d" || $part_prefs['common']['dateformat'] === "Y.m.d"):
+
+											$var3 = $val['field'];
+											$vardata3 = $details[$key];
+											$newyear3 = substr($vardata3,0,4);
+											$newmounth3 = substr($vardata3,5,2);
+											$newday3 = substr($vardata3,8,2);
+											$newall3 =$newyear3.$newmounth3.$newday3;
+											break;
+
+										case ($part_prefs['common']['dateformat'] === "d/m/Y" || $part_prefs['common']['dateformat'] === "d-m-Y" || $part_prefs['common']['dateformat'] === "d.m.Y" || $part_prefs['common']['dateformat'] === "d-M-Y"):
+										
+											$var3 = $val['field'];
+											$vardata3 = $details[$key];
+											$newday3 = substr($vardata3,0,2);
+											$newmounth3 = substr($vardata3,3,2);
+											$newyear3 = substr($vardata3,6,4);
+											$newall3 =$newyear3.$newmounth3.$newday3;
+											break;
+									
+									}
+									
+								}
+								//dt final
+								if($key =='enddate')
+								{
+									$var4 = $val['field'];
+									$vardata4 = $details[$key];
+								}
+								//localizacao
+								if($key =='location')
+								{
+									$var8 = $val['field'];
+									$vardata8 = $details[$key];
+								}
+								//participantes
+								if($key =='participants')
+								{
+									$var5 = $val['field'];
+									foreach($val['data'] as $NewKey => $NewVal)
+									{
+										//Research inside of ldap ( Pesquisa dentro do ldap )
+										$newvalue = $this->so->search_uidNumber($to);
+										foreach($newvalue as $tmp)
+										{
+											$tmpmail = $tmp['mail'][0];
+											$tmpuid = $tmp['uidnumber'][0];
+											if( trim($tmpmail) == trim($to) & trim($tmpuid) == trim($NewKey))
+											{
+													if($typesend == 3)
+													{
+
+														$lang1 = lang("To See Commitment");
+														$varbuttom = "<form action=".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uicalendar.view&cal_id=$event[id]&date=$newall3' method='POST'>
+																		  		  <input type='submit' value='$lang1'>
+																		  		   </form>";
+														$lang2 = lang("To accept");
+														$varbuttom1 ="<input type='submit' value='$lang2' onClick='javascript:window.open(\"".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uicalendar.set_action&cal_id=$event[id]&action=3&response=1\",\"frontpage\",\"height=100,width=400,statusbar=no,toolbar=no,scrollbars=no,menubar=no,left=300,top=200\")'>";
+
+														$lang3 = lang("To reject");
+														$varbuttom2 ="<input type='submit' value='$lang3' onClick='javascript:window.open(\"".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uicalendar.set_action&cal_id=$event[id]&action=0&response=0\",\"frontpage\",\"height=100,width=400,statusbar=no,toolbar=no,scrollbars=no,menubar=no,left=300,top=200\")'>";
+														
+														$lang4 = lang("Alarm");
+														$varbuttom3 = "<form action=".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uialarm.manager method='POST'>
+																		  		  <input type='submit' value='$lang4'>
+																		  		  <input type='hidden' name='cal_id' value=$event[id]>
+																		  		   </form>";
+													}
+													else
+													{
+															$varbuttom  = "";
+															$varbuttom1 = "";
+															$varbuttom2 = "";
+															$varbuttom3 = "";
+													}
+											}
+											// It only mounts variavel with the name of the participants of the list ( Monta a variavel somente com o nome dos participantes da lista)
+											if($typesend == 3)
+											{
+												list($tmpvardata5,$tmp2vardata5) = explode("(",$NewVal);
+												$vardata5 = $tmpvardata5."<br>";
+											}
+											else
+											{
+												$vardata5 = $NewVal."<br>";
+											}
+										
+										}
+										$vardata6 .= $vardata5;
+										unset($vardata5);
+									}
+								}		
+							}
+							//To mount the message as text/html (Para montar a mensagem como text/html - /phpgwapi/inc/class.send.inc.php )
+							$content_type = "text/html";
+							//It mounts the body of the message (Monta o corpo da mensagem)
+							
+							// A constante PHPGW_APP_TPL nao existe para envio de alarmes (cront, asyncservice).
+							define ("PHPGW_APP_TPL",PHPGW_API_INC . "/../../calendar/templates/celepar");
+							
+							$body = CreateObject('phpgwapi.Template',PHPGW_APP_TPL);
+							$body->set_file(Array('calendar' => 'body_email.tpl'));
+							$body->set_block('calendar','list');
+							$var = Array(
+								'script'			=> $script,
+								'subject'			=> $body1,
+								'var1'				=> $var1,
+								'vardata1'			=> $vardata1,
+								'var2'				=> $var2,
+								'vardata2'			=> $vardata2,
+								'var3'				=> $var3,
+								'vardata3'			=> $vardata3,
+								'var4'				=> $var4,
+								'vardata4'			=> $vardata4,
+								'var5'				=> $var5,
+								'vardata6'			=> $vardata6,
+								'var8'				=> $var8,
+								'vardata8'			=> $vardata8,							
+								'varbuttom'			=> $varbuttom,
+								'varbuttom1'		=> $varbuttom1,
+								'varbuttom2'		=> $varbuttom2,
+								'varbuttom3'		=> $varbuttom3 
+								
+							);
+							$body->set_var($var);
+							$tmpbody = $body->fp('out','list');
+														
+							break;
+
+						case 'ical':
+							$content_type = "calendar; method=$method; name=calendar.ics";
+/*							if ($body != '')
+							{
+								$boundary = '----Message-Boundary';
+								$body .= "\n\n\n$boundary\nContent-type: text/$content_type\n".
+									"Content-Disposition: inline\nContent-transfer-encoding: 7BIT\n\n";
+								$content_type = '';
+							}
+*/
+							$body = ExecMethod('calendar.boicalendar.export',array(
+								'l_event_id'  => $event['id'],
+								'method'      => $method,
+								'chunk_split' => False
+							));
+							break;
+					}
+					$mail->AddAddress($to);
+					$mail->Body = $tmpbody;
+					$mail->From = $sender;
+					$mail->FromName = $GLOBALS['phpgw_info']['user']['fullname'];
+					$mail->Sender = $mail->From;
+					$mail->SenderName = $mail->FromName;
+					$mail->Subject = $subject;
+					unset($vardata5);
+					unset($vardata6);
+				}
+			}
+
+			//Inicializa variï¿œvel de retorno.
+			$returncode=true;			
+			if(count($mail->to)) {				
+				// Envia aviso a todos os participantes.
+				if(!$mail->Send()) {				
+					$returncode = false;
+					$errorInfo['participants'] = $mail->ErrorInfo;
+				}
+				else
+					$returncode =  true;
+			}
+			
+			if(count($to_notify) && $this->ex_participants){
+				$mail->ClearAllRecipients();
+				$var = explode(",",trim($this->ex_participants));
+				$to = array();
+				if(!$subject) {
+					$details['startdate'] = $GLOBALS['phpgw']->common->show_date($starttime);
+					$details['enddate']   = $GLOBALS['phpgw']->common->show_date($endtime);
+					list($subject,$body1) = split("\n",$GLOBALS['phpgw']->preferences->parse_notify($notify_msg,$details),2);
+				}
+				
+				foreach($var as $index => $ex_participant){
+					$ex_participant = trim($ex_participant);
+					$ex_participant = preg_replace('#"(.*)" <(.*)\@(.*)\.(.*)>#','\\2@\\3.\\4',$ex_participant);
+						if($ex_participant)
+							$to[] = $ex_participant;
+				}		
+				
+				foreach($to as $i => $to_array)
+					$mail->AddAddress($to_array);
+				
+				$_body = explode("<hr size='1' width='100%'>",$tmpbody);
+				$tmpbody = $_body[0] ? $_body[0] : $subject ;
+				$tmpbody.= "<br><b>".lang("external participants").":: </b> ".htmlentities($this->ex_participants);
+				$tmpbody.= "<br>".lang("Summary").": ".$this->so->cal->event[title]."<br>";
+				$tmpbody.= "<br>".lang("Start time").": ".$GLOBALS['phpgw']->common->show_date($starttime)."<br>".lang("End date").": ".$GLOBALS['phpgw']->common->show_date($endtime)."<br>";
+				$tmpbody.= "<br><br><hr size='1' width='100%'><font color='red'>"
+				.lang("This message was sent by server. You must send a message to sender to confirm this event")."<br>"
+				.lang("This is an external event. Even if it added to your expresso its can be changed any time at all")."</font><br>";
+				
+				if ($GLOBALS['bocalendar']->so->cal->event[start][month] > 10)
+					$event_month=$GLOBALS['bocalendar']->so->cal->event[start][month];
+				else
+					$event_month="0".$GLOBALS['bocalendar']->so->cal->event[start][month];
+				//attach extern vcard			
+				// define('context','$GLOBALS.bocalendar.so.cal.event');
+				$tmpattach = $this->create_vcard($GLOBALS['bocalendar']->so->cal->event);
+				if($tmpattach){					
+					$tmpbody .="<a href='../index.php?menuaction=calendar.uicalendar.add&date="
+					.$GLOBALS['bocalendar']->so->cal->event[start][year]
+				.$event_month
+				.$GLOBALS['bocalendar']->so->cal->event[start][mday]
+					."&hour=".$GLOBALS['bocalendar']->so->cal->event[start][hour]
+					."&minute=".$GLOBALS['bocalendar']->so->cal->event[start][min]
+					."&title=".$GLOBALS['bocalendar']->so->cal->event['title']
+					."&description=".$GLOBALS['bocalendar']->so->cal->event['description']
+					."&location=".$GLOBALS['bocalendar']->so->cal->event['location']."'>"
+					."<h2>".lang("Add to my expresso")."</h2>";
+					$tempdir = $GLOBALS['phpgw_info']['server']['temp_dir'] . SEP;
+					srand((double)microtime()*1000000);
+					$random_number = rand(100000000,999999999);
+					$newfilename = md5(time() . getenv("REMOTE_ADDR") . $random_number );
+					$filename = $tempdir . $newfilename;
+					$attach_fd = fopen($filename,"w+");
+					fwrite($attach_fd,$tmpattach);
+					$mail->AddAttachment($filename, "extern.vcard", "base64", "text/plain"); // "application/octet-stream"
+					fclose($attach_fd);
+				}
+				$mail->From = $sender;
+				$mail->FromName = $GLOBALS['phpgw_info']['user']['fullname'];
+				$mail->Sender = $mail->From;
+				$mail->SenderName = $mail->FromName;
+				$mail->Subject = lang("External event from Expresso");
+				$mail->Body = $tmpbody;
+																		
+				if(!$mail->Send()) 
+				{
+					$returncode=false;
+					$errorInfo['ex_participants'] = $mail->ErrorInfo;
+				}
+				else
+				{
+					$returncode=true;
+				}
+			}
+
+
+			if((is_int($this->user) && $this->user != $temp_user['account_id']) ||
+				(is_string($this->user) && $this->user != $temp_user['account_lid']))
+			{
+				$GLOBALS['phpgw_info']['user'] = $temp_user;
+			}	
+
+			$GLOBALS['phpgw_info']['user']['preferences']['common']['tz_offset'] = $temp_tz_offset;
+			$GLBOALS['phpgw']->datetime->tz_offset = ((60 * 60) * $temp_tz_offset);
+			$GLOBALS['phpgw_info']['user']['preferences']['common']['timeformat'] = $temp_timeformat;
+			$GLOBALS['phpgw_info']['user']['preferences']['common']['dateformat'] = $temp_dateformat;
+			
+			// Notifica por email o criador do compromisso, com as possï¿œveis falhas.						
+			if($errorInfo) {
+				$tmpbody = "<font color='red'>".lang("The following commitment had problems for DELIVERING the NOTIFICATION messages.").".</font><br>";
+				$tmpbody.= "<br>".lang("Summary").": ".$this->so->cal->event[title]."<br>";
+				$tmpbody.= "<br>".lang("Start time").": ".$GLOBALS['phpgw']->common->show_date($starttime)."<br>".lang("End date").": ".$GLOBALS['phpgw']->common->show_date($endtime)."<br>";				
+				$tmpbody.= "<br><u>".lang("Failed to delivery")."</u><br>";
+				$failed = false;				
+				if(strstr($errorInfo['participants'],"recipients_failed")){
+					$failed	= explode("recipients_failed",$errorInfo['participants']);
+					$tmpbody.= lang("to").": ".$failed[1];
+				}
+				if(strstr($errorInfo['ex_participants'],"recipients_failed")){
+					$failed = explode("recipients_failed",$errorInfo['ex_participants']);
+					$tmpbody.= lang("to").": ".$failed[1];
+				}			
+				if(!$failed) {
+					$tmpbody.= lang("Description").":<br>";
+					$tmpbody.= $errorInfo['participants'];
+					$tmpbody.= "<br>".$errorInfo['ex_participants'];
+				}
+				$tmpbody.= "<br>".lang("Subject").": ".$subject;
+				// Reinicializa o objeto, devido ao erro anterior na entrega.
+				
+				$mail = new PHPMailer();
+				$mail->IsSMTP();
+				$mail->Host = $emailadmin['smtpServer'];
+				$mail->Port = $emailadmin['smtpPort'];
+				$mail->From = $sender;
+				$mail->FromName = $GLOBALS['phpgw_info']['user']['fullname'];
+				$mail->Sender = $mail->From;
+				$mail->SenderName = $mail->FromName;
+				$mail->IsHTML(True);
+				$mail->Subject = lang("calendar event")." - ".lang("email notification");							
+				$mail->Body = $tmpbody;					
+				$mail->AddAddress($sender);
+				if(!$mail->Send())			
+					$returncode = false;
+				else
+					$returncode =  true;
+			}
+			return $returncode;
+		}
+		
+		function send_alarm($alarm)
+		{
+			//echo "<p>bocalendar::send_alarm("; print_r($alarm); echo ")</p>\n";
+			
+			$GLOBALS['phpgw_info']['user']['account_id'] = $this->owner = $alarm['owner'];
+
+			if (!$alarm['enabled'] || !$alarm['owner'] || !$alarm['cal_id'] || !($event = $this->so->read_entry($alarm['cal_id'])))
+			{
+				return False;	// event not found
+			}
+			if ($alarm['all'])
+			{
+				$to_notify = $event['participants'];
+			}
+			elseif ($this->check_perms(PHPGW_ACL_READ,$event))	// checks agains $this->owner set to $alarm[owner]
+			{
+				$to_notify[$alarm['owner']] = 'A';
+			}
+			else
+			{
+				return False;	// no rights
+			}
+			return $this->send_update(MSG_ALARM,$to_notify,$event,False,$alarm['owner']);
+		}
+
+		function get_alarms($event_id)
+		{
+			return $this->so->get_alarm($event_id);
+		}
+
+		function alarm_today($event,$today,$starttime)
+		{
+			$found = False;
+			@reset($event['alarm']);
+			$starttime_hi = $GLOBALS['phpgw']->common->show_date($starttime,'Hi');
+			$t_appt['month'] =$GLOBALS['phpgw']->common->show_date($today,'m');
+			$t_appt['mday'] = $GLOBALS['phpgw']->common->show_date($today,'d');
+			$t_appt['year'] = $GLOBALS['phpgw']->common->show_date($today,'Y');
+			$t_appt['hour'] = $GLOBALS['phpgw']->common->show_date($starttime,'H');
+			$t_appt['min']  = $GLOBALS['phpgw']->common->show_date($starttime,'i');
+			$t_appt['sec']  = 0;
+			$t_time = $this->maketime($t_appt) - $GLOBALS['phpgw']->datetime->tz_offset;
+			$y_time = $t_time - 86400;
+			$tt_time = $t_time + 86399;
+			print_debug('T_TIME',$t_time.' : '.$GLOBALS['phpgw']->common->show_date($t_time));
+			print_debug('Y_TIME',$y_time.' : '.$GLOBALS['phpgw']->common->show_date($y_time));
+			print_debug('TT_TIME',$tt_time.' : '.$GLOBALS['phpgw']->common->show_date($tt_time));
+			while(list($key,$alarm) = each($event['alarm']))
+			{
+				if($alarm['enabled'])
+				{
+					print_debug('TIME',$alarm['time'].' : '.$GLOBALS['phpgw']->common->show_date($alarm['time']).' ('.$event['id'].')');
+					if($event['recur_type'] != MCAL_RECUR_NONE)   /* Recurring Event */
+					{
+						print_debug('Recurring Event');
+						if($alarm['time'] > $y_time && $GLOBALS['phpgw']->common->show_date($alarm['time'],'Hi') < $starttime_hi && $alarm['time'] < $t_time)
+						{
+							$found = True;
+						}
+					}
+					elseif($alarm['time'] > $y_time && $alarm['time'] < $t_time)
+					{
+						$found = True;
+					}
+				}
+			}
+			print_debug('Found',$found);
+			return $found;
+		}
+
+		function prepare_recipients(&$new_event,$old_event)
+		{
+						
+			// Find modified and deleted users.....
+			while(list($old_userid,$old_status) = each($old_event['participants']))
+			{
+				if(isset($new_event['participants'][$old_userid]))
+				{
+					print_debug('Modifying event for user',$old_userid);
+					$this->modified[(int)$old_userid] = $new_status;
+				}
+				else
+				{
+					print_debug('Deleting user from the event',$old_userid);
+					$this->deleted[(int)$old_userid] = $old_status;
+				}
+			}
+			// Find new users.....
+			while(list($new_userid,$new_status) = each($new_event['participants']))
+			{
+				if(!isset($old_event['participants'][$new_userid]))
+				{
+					print_debug('Adding event for user',$new_userid);
+					$this->added[$new_userid] = 'U';
+					$new_event['participants'][$new_userid] = 'U';
+				}
+			}
+			
+			if(count($this->added) > 0 || count($this->modified) > 0 || count($this->deleted) > 0)
+			{
+				if(count($this->added) > 0)
+				{
+					$this->ex_participants = '';
+					$this->send_update(MSG_ADDED,$this->added,'',$new_event);
+				}
+				if(count($this->modified) > 0)
+				{
+					$this->send_update(MSG_MODIFIED,$this->modified,$old_event,$new_event);
+				}
+				if(count($this->deleted) > 0)
+				{
+					$this->ex_participants = '';
+					$this->send_update(MSG_DELETED,$this->deleted,$old_event);
+				}
+			}
+		}
+
+		function remove_doubles_in_cache($firstday,$lastday)
+		{
+			$already_moved = Array();
+			for($v=$firstday;$v<=$lastday;$v++)
+			{
+				if (!$this->cached_events[$v])
+				{
+					continue;
+				}
+				$cached = $this->cached_events[$v];
+				$this->cached_events[$v] = array();
+				while (list($g,$event) = each($cached))
+				{
+					$end = date('Ymd',$this->maketime($event['end']));
+					print_debug('EVENT',_debug_array($event,False));
+					print_debug('start',$start);
+					print_debug('v',$v);
+
+					if (!isset($already_moved[$event['id']]) || $event['recur_type'] && $v > $end)
+					{
+						$this->cached_events[$v][] = $event;
+						$already_moved[$event['id']] = 1;
+						print_debug('Event moved');
+					}
+				}
+			}
+		}
+
+		function get_dirty_entries($lastmod=-1)
+		{
+			$events = false;
+			$event_ids = $this->so->cal->list_dirty_events($lastmod);
+			if(is_array($event_ids))
+			{
+				foreach($event_ids as $key => $id)
+				{
+					$events[$id] = $this->so->cal->fetch_event($id);
+				}
+			}
+			unset($event_ids);
+
+			$rep_event_ids = $this->so->cal->list_dirty_events($lastmod,$true);
+			if(is_array($rep_event_ids))
+			{
+				foreach($rep_event_ids as $key => $id)
+				{
+					$events[$id] = $this->so->cal->fetch_event($id);
+				}
+			}
+			unset($rep_event_ids);
+
+			return $events;
+		}
+
+		function _debug_array($data)
+		{
+			echo '<br>UI:';
+			_debug_array($data);
+		}
+
+		/*!
+		@function rejected_no_show
+		@abstract checks if event is rejected from user and he's not the owner and dont want rejected
+		@param $event to check
+		@returns True if event should not be shown
+		*/
+		function rejected_no_show($event)
+		{
+			$ret = !$this->prefs['calendar']['show_rejected'] &&
+				$event['owner'] != $this->owner &&
+				$event['participants'][$this->owner] == 'R';
+			//echo "<p>rejected_no_show($event[title])='$ret': user=$this->owner, event-owner=$event[owner], status='".$event['participants'][$this->owner]."', show_rejected='".$this->prefs['calendar']['show_rejected']."'</p>\n";
+			return $ret;
+		}
+
+		/* This is called only by list_cals().  It was moved here to remove fatal error in php5 beta4 */
+		function list_cals_add($id,&$users,&$groups)
+		{
+			$name = $GLOBALS['phpgw']->common->grab_owner_name($id);
+			if (($type = $GLOBALS['phpgw']->accounts->get_type($id)) == 'g')
+			{
+				$arr = &$groups;
+			}
+			else
+			{
+				$arr = &$users;
+			}
+			$arr[$name] = Array(
+				'grantor' => $id,
+				'value'   => ($type == 'g' ? 'g_' : '') . $id,
+				'name'    => $name
+			);
+		}
+
+		/*!
+		@function list_cals
+		@abstract generate list of user- / group-calendars for the selectbox in the header
+		@returns alphabeticaly sorted array with groups first and then users
+		*/
+		function list_cals()
+		{
+			$users = $groups = array();
+			foreach($this->grants as $id => $rights)
+			{
+				$this->list_cals_add($id,$users,$groups);
+			}
+			
+			//by JakJr, melhora de performance na abertura da agenda
+			/*if ($memberships = $GLOBALS['phpgw']->accounts->membership($GLOBALS['phpgw_info']['user']['account_id']))
+			{
+				foreach($memberships as $group_info)
+				{
+					$this->list_cals_add($group_info['account_id'],$users,$groups);
+
+					if ($account_perms = $GLOBALS['phpgw']->acl->get_ids_for_location($group_info['account_id'],PHPGW_ACL_READ,'calendar'))
+					{
+						foreach($account_perms as $id)
+						{
+							$this->list_cals_add($id,$users,$groups);
+						}
+					}
+				}
+			}*/
+			uksort($users,'strnatcasecmp');
+			uksort($groups,'strnatcasecmp');
+
+			return $users + $groups;	// users first and then groups, both alphabeticaly
+		}
+
+	  function translate($key,$vars=false, $not_found='*' )
+	  {
+    	    if ($this->async)
+	      return $GLOBALS['phpgw']->translation->translate_async($key, $vars);
+	    return lang($key, $vars);
+	  }
+
+		/*!
+		@function event2array
+		@abstract create array with name, translated name and readable content of each attributes of an event
+		@syntax event2array($event,$sep='<br>')
+		@param $event event to use
+		@returns array of attributes with fieldname as key and array with the 'field'=translated name \
+			'data' = readable content (for participants this is an array !)
+		*/
+		function event2array($event)
+		{
+			
+			
+		  $var['title'] = Array(
+				'field'		=> $this->translate('Title'),
+				'data'		=> $event['title']
+			);
+
+			// Some browser add a \n when its entered in the database. Not a big deal
+			// this will be printed even though its not needed.
+			$var['description'] = Array(
+				'field'	=> $this->translate('Description'),
+				'data'	=> $event['description']
+			);
+
+			$var['ex_participants'] = Array(
+				'field'	=> $this->translate('External Participants'),
+				'data'	=> $event['ex_participants']
+			);
+			
+			$cats = Array();
+			$this->cat->categories($this->bo->owner,'calendar');
+			if(strpos($event['category'],','))
+			{
+				$cats = explode(',',$event['category']);
+			}
+			else
+			{
+				$cats[] = $event['category'];
+			}
+			foreach($cats as $cat_id)
+			{
+				list($cat) = $this->cat->return_single($cat_id);
+				$cat_string[] = $cat['name'];
+			}
+			$var['category'] = Array(
+				'field'	=> $this->translate('Category'),
+				'data'	=> implode(', ',$cat_string)
+			);
+
+			$var['location'] = Array(
+				'field'	=> $this->translate('Location'),
+				'data'	=> $event['location']
+			);
+
+			$var['startdate'] = Array(
+				'field'	=> $this->translate('Start Date/Time'),
+				'data'	=> $GLOBALS['phpgw']->common->show_date($this->maketime($event['start']) - $GLOBALS['phpgw']->datetime->tz_offset),
+			);
+
+			$var['enddate'] = Array(
+				'field'	=> $this->translate('End Date/Time'),
+				'data'	=> $GLOBALS['phpgw']->common->show_date($this->maketime($event['end']) - $GLOBALS['phpgw']->datetime->tz_offset)
+			);
+
+			$pri = Array(
+				1	=> lang('Low'),
+				2	=> lang('Normal'),
+				3	=> lang('High')
+			);
+			$var['priority'] = Array(
+				'field'	=> lang('Priority'),
+				'data'	=> $pri[$event['priority']]
+			);
+
+			$var['owner'] = Array(
+				'field'	=> lang('Created By'),
+				'data'	=> $GLOBALS['phpgw']->common->grab_owner_name($event['owner'])
+			);
+
+			$var['updated'] = Array(
+				'field'	=> lang('Updated'),
+				'data'	=> $GLOBALS['phpgw']->common->show_date($this->maketime($event['modtime']) - $GLOBALS['phpgw']->datetime->tz_offset)
+			);
+
+			$var['access'] = Array(
+				'field'	=> lang('Access'),
+				'data'	=> $event['public'] ? lang('Public') : lang('Private')
+			);
+
+			if(@isset($event['groups'][0]))
+			{
+				$cal_grps = '';
+				for($i=0;$i<count($event['groups']);$i++)
+				{
+					if($GLOBALS['phpgw']->accounts->exists($event['groups'][$i]))
+					{
+						$cal_grps .= ($i>0?'<br>':'').$GLOBALS['phpgw']->accounts->id2name($event['groups'][$i]);
+					}
+				}
+
+				$var['groups'] = Array(
+					'field'	=> lang('Groups'),
+					'data'	=> $cal_grps
+				);
+			}
+
+			$participants = array();
+			foreach($event['participants'] as $user => $short_status)
+			{
+				if($GLOBALS['phpgw']->accounts->exists($user))
+				{
+					$participants[$user] = $GLOBALS['phpgw']->common->grab_owner_name($user).' ('.$this->get_long_status($short_status).')';
+				}
+			}
+			$var['participants'] = Array(
+				'field'	=> $this->translate('Participants'),
+				'data'	=> $participants
+			);
+
+			// Repeated Events
+			if($event['recur_type'] != MCAL_RECUR_NONE)
+			{
+				$str = lang($this->rpt_type[$event['recur_type']]);
+
+				$str_extra = array();
+				if ($event['recur_enddate']['mday'] != 0 && $event['recur_enddate']['month'] != 0 && $event['recur_enddate']['year'] != 0)
+				{
+					$recur_end = $this->maketime($event['recur_enddate']);
+					if($recur_end != 0)
+					{
+						$recur_end -= $GLOBALS['phpgw']->datetime->tz_offset;
+						$str_extra[] = lang('ends').': '.lang($GLOBALS['phpgw']->common->show_date($recur_end,'l')).', '.$this->long_date($recur_end).' ';
+					}
+				}
+				// only weekly uses the recur-data (days) !!!
+				if($event['recur_type'] == MCAL_RECUR_WEEKLY)
+				{
+					$repeat_days = array();
+					foreach ($this->rpt_day as $mcal_mask => $dayname)
+					{
+						if ($event['recur_data'] & $mcal_mask)
+						{
+							$repeat_days[] = lang($dayname);
+						}
+					}
+					if(count($repeat_days))
+					{
+						$str_extra[] = lang('days repeated').': '.implode(', ',$repeat_days);
+					}
+				}
+				if($event['recur_interval'] != 0)
+				{
+					$str_extra[] = lang('Interval').': '.$event['recur_interval'];
+				}
+
+				if(count($str_extra))
+				{
+					$str .= ' ('.implode(', ',$str_extra).')';
+				}
+
+				$var['recure_type'] = Array(
+					'field'	=> lang('Repetition'),
+					'data'	=> $str,
+				);
+			}
+
+			if (!isset($this->fields))
+			{
+				$this->custom_fields = CreateObject('calendar.bocustom_fields');
+				$this->fields = &$this->custom_fields->fields;
+				$this->stock_fields = &$this->custom_fields->stock_fields;
+			}
+			foreach($this->fields as $field => $data)
+			{
+				if (!$data['disabled'])
+				{
+					if (isset($var[$field]))
+					{
+						$sorted[$field] = $var[$field];
+					}
+					elseif (!isset($this->stock_fields[$field]) && strlen($event[$field]))	// Custom field
+					{
+						$lang = lang($name = substr($field,1));
+						$sorted[$field] = array(
+							'field' => $lang == $name.'*' ? $name : $lang,
+							'data'  => $event[$field]
+						);
+					}
+				}
+				unset($var[$field]);
+			}
+			foreach($var as $name => $v)
+			{
+				$sorted[$name] = $v;
+
+			}
+			return $sorted;
+		}
+
+		/*!
+		@function check_set_default_prefs
+		@abstract sets the default prefs, if they are not already set (on a per pref. basis)
+		@note It sets a flag in the app-session-data to be called only once per session
+		*/
+		function check_set_default_prefs()
+		{
+			if (($set = $GLOBALS['phpgw']->session->appsession('default_prefs_set','calendar')))
+			{
+				return;
+			}
+			$GLOBALS['phpgw']->session->appsession('default_prefs_set','calendar','set');
+
+			//$default_prefs = $GLOBALS['phpgw']->preferences->default['calendar']; jakjr
+
+			$subject = $this->translate('Calendar Event') . ' - $$action$$: $$startdate$$ $$title$$'."\n";
+			$defaults = array(
+				'defaultcalendar' => 'week',
+				'mainscreen_showevents' => '0',
+				'summary'         => 'no',
+				'receive_updates' => 'no',
+				'update_format'   => 'extended',	// leave it to extended for now, as iCal kills the message-body
+				'notifyAdded'     => $subject . $this->translate ('You have a meeting scheduled for %1',array('$$startdate$$')),
+				'notifyCanceled'  => $subject . $this->translate ('Your meeting scheduled for %1 has been canceled',array('$$startdate$$')),
+				'notifyModified'  => $subject . $this->translate ('Your meeting that had been scheduled for %1 has been rescheduled to %2',array('$$olddate$$','$$startdate$$')),
+				'notifyResponse'  => $subject . $this->translate ('On %1 %2 %3 your meeting request for %4', array('$$date$$','$$fullname$$','$$action$$','$$startdate$$')),
+				'notifyAlarm'     => $this->translate('Alarm for %1 at %2 in %3',array('$$title$$','$$startdate$$','$$location$$')) . "\n" . $this->translate('Here is your requested alarm.'),
+				'show_rejected'   => '0',
+				'hide_event_conflict'   => '0',
+				'display_status'  => '1',
+				'weekdaystarts'   => 'Monday',
+				'workdaystarts'   => '9',
+				'workdayends'     => '17',
+				'interval'        => '30',
+				'defaultlength'   => '60',
+				'planner_start_with_group' => $GLOBALS['phpgw']->accounts->name2id('Default'),
+				'planner_intervals_per_day'=> '4',
+				'defaultfilter'   => 'all',
+				'default_private' => '0',
+				'display_minicals'=> '1',
+				'print_black_white'=>'0'
+			);
+			foreach($defaults as $var => $default)
+			{
+				if (!isset($default_prefs[$var]) || $default_prefs[$var] == '')
+				{
+					$GLOBALS['phpgw']->preferences->add('calendar',$var,$default,'default');
+					$need_save = True;
+				}
+			}
+			if ($need_save)
+			{
+				$prefs = $GLOBALS['phpgw']->preferences->save_repository(False,'default');
+				$this->prefs['calendar'] = $prefs['calendar'];
+			}
+			if ($this->prefs['calendar']['send_updates'] && !isset($this->prefs['calendar']['receive_updates']))
+			{
+				$this->prefs['calendar']['receive_updates'] = $this->prefs['calendar']['send_updates'];
+				$GLOBALS['phpgw']->preferences->add('calendar','receive_updates',$this->prefs['calendar']['send_updates']);
+				$GLOBALS['phpgw']->preferences->delete('calendar','send_updates');
+				$prefs = $GLOBALS['phpgw']->preferences->save_repository();
+			}
+		}
+
+		// return array with all infolog categories (for xmlrpc)
+		function categories($complete = False)
+		{
+			return $GLOBALS['server']->categories($complete);
+		}
+	}
+?>
Index: /tags/calendar/0.9.3/inc/class.soholiday.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.soholiday.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/inc/class.soholiday.inc.php	(revision 2)
@@ -0,0 +1,189 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Holiday                                                     *
+  * http://www.egroupware.org                                                *
+  * Written by Mark Peters <skeeter@phpgroupware.org>                        *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	class soholiday
+	{
+		var $debug = False;
+		var $db;
+
+		function soholiday()
+		{
+			$this->db = $GLOBALS['phpgw']->db;
+			$this->table = 'phpgw_cal_holidays';
+			$this->table_definition = $this->db->get_table_definitions('calendar',$this->table);
+			$this->db->set_column_definitions($this->table_definition['fd']);
+		}
+
+		/* Begin Holiday functions */
+		function save_holiday($holiday)
+		{
+			if(@$holiday['hol_id'])
+			{
+				if($this->debug)
+				{
+					echo "Updating LOCALE='".$holiday['locale']."' NAME='".$holiday['name']."' extra=(".$holiday['mday'].'/'.$holiday['month_num'].'/'.$holiday['occurence'].'/'.$holiday['dow'].'/'.$holiday['observance_rule'].")<br>\n";
+				}
+				$sql = "UPDATE $this->table SET ".$this->db->column_data_implode(',',$holiday,True,True).' WHERE hol_id='.(int)$holiday['hol_id'];
+			}
+			else
+			{
+				if($this->debug)
+				{
+					echo "Inserting LOCALE='".$holiday['locale']."' NAME='".$holiday['name']."' extra=(".$holiday['mday'].'/'.$holiday['month_num'].'/'.$holiday['occurence'].'/'.$holiday['dow'].'/'.$holiday['observance_rule'].")<br>\n";
+				}
+				unset($holiday['hol_id']);	// in case its 0
+				$holiday['locale'] = strtoupper($holiday['locale']);
+				$sql = "INSERT INTO $this->table ".$this->db->column_data_implode(',',$holiday,'VALUES',True);
+			}
+			$this->db->query($sql,__LINE__,__FILE__);
+		}
+
+		function store_to_array(&$holidays)
+		{
+			while($this->db->next_record())
+			{
+				$holidays[] = Array(
+					'index'			=> $this->db->f('hol_id'),
+					'locale'		=> $this->db->f('locale'),
+					'name'			=> $GLOBALS['phpgw']->strip_html($this->db->f('name')),
+					'day'			=> (int)$this->db->f('mday'),
+					'month'			=> (int)$this->db->f('month_num'),
+					'occurence'		=> (int)$this->db->f('occurence'),
+					'dow'			=> (int)$this->db->f('dow'),
+					'observance_rule'	=> $this->db->f('observance_rule')
+				);
+				if($this->debug)
+				{
+					echo 'Holiday ID: '.$this->db->f('hol_id').'<br>'."\n";
+				}
+			}
+		}
+
+		function read_holidays($locales='',$query='',$order='',$year=0)
+		{
+			$holidays = Array();
+
+			if($locales == '')
+			{
+				return $holidays;
+			}
+
+			$sql = $this->build_query($locales,$query,$order,$year);
+
+			if($this->debug)
+			{
+				echo 'Read Holidays : '.$sql.'<br>'."\n";
+			}
+
+			$this->db->query($sql,__LINE__,__FILE__);
+			$this->store_to_array($holidays);
+			return $holidays;
+		}
+
+		function read_holiday($id)
+		{
+			$holidays = Array();
+			if($this->debug)
+			{
+				echo 'Reading Holiday ID : '.$id.'<br>'."\n";
+			}
+			$this->db->query("SELECT * FROM $this->table WHERE hol_id=".(int)$id,__LINE__,__FILE__);
+			$this->store_to_array($holidays);
+			@reset($holidays);
+			return $holidays[0];
+		}
+
+		function delete_holiday($id)
+		{
+			$this->db->query("DELETE FROM $this->table WHERE hol_id=".(int)$id,__LINE__,__FILE__);
+		}
+
+		function delete_locale($locale)
+		{
+			$this->db->query("DELETE FROM $this->table WHERE locale=".$this->db->quote($locale),__LINE__,__FILE__);
+		}
+		
+		/* Private functions */
+		function build_query($locales,$query='',$order='',$year=0)
+		{
+			$querymethod = 'locale';
+			if (is_array($locales))
+			{
+				$querymethod .= ' IN ('.$this->db->column_data_implode(',',$locales,False).')';
+			}
+			else
+			{
+				$querymethod .= '='.$this->db->quote($locales);
+			}
+			if($query)
+			{
+				$querymethod = " AND name LIKE ".$this->db->quote('%'.$query.'%');
+			}
+			if ($year > 1900)
+			{
+				$querymethod .= " AND (occurence < 1900 OR occurence = ".(int)$year.")";
+			}
+			$querymethod .= ' ORDER BY '.(preg_match('/[a-zA-Z0-9_,]+/',$order) ? $order : 'month_num,mday');
+
+			return "SELECT * FROM $this->table WHERE ".$querymethod;
+		}
+
+		function get_locale_list($sort='', $order='', $query='')
+		{
+			$querymethod = '';
+			if($query)
+			{
+				$querymethod .= " WHERE locale LIKE ".$this->db->quote('%'.$query.'%');
+			}
+		
+			if(preg_match('/[a-zA-Z0-9_,]+/',$order))
+			{
+				$querymethod .= ' ORDER BY '.$order;
+			}
+			$this->db->query("SELECT DISTINCT locale FROM $this->table".$querymethod,__LINE__,__FILE__);
+			while($this->db->next_record())
+			{
+				$locale[] = $this->db->f('locale');
+			}
+			return $locale;
+		}
+		
+		function holiday_total($locale,$query='',$year=0)
+		{
+			$querymethod='';
+			if($query)
+			{
+				$querymethod = ' AND name LIKE '.$this->db->quote('%'.$query.'%');
+			}
+			if ($year >= 1900)
+			{
+				$querymethod .= ' AND (occurence < 1900 OR occurence = '.(int)$year.")";
+			}
+			$sql = "SELECT count(*) FROM $this->table WHERE locale=".$this->db->quote($locale).$querymethod;
+
+			if($this->debug)
+			{
+				echo 'HOLIDAY_TOTAL : '.$sql.'<br>'."\n";
+			}
+			
+			$this->db->query($sql,__LINE__,__FILE__);
+			$this->db->next_record();
+			$retval = (int)$this->db->f(0);
+			if($this->debug)
+			{
+				echo 'Total Holidays for : '.$locale.' : '.$retval."<br>\n";
+			}
+			return $retval;
+		}
+	}
+?>
Index: /tags/calendar/0.9.3/inc/hourReport.php
===================================================================
--- /tags/calendar/0.9.3/inc/hourReport.php	(revision 626)
+++ /tags/calendar/0.9.3/inc/hourReport.php	(revision 626)
@@ -0,0 +1,167 @@
+<?php
+$phpgw_flags = Array(
+	'currentapp'    =>      'calendar',
+	'noappheader'   =>      True,
+	'noappfooter'   =>      True,
+	'nofooter'      =>      True
+);
+$GLOBALS['phpgw_info']['flags'] = $phpgw_flags;
+
+include('../../header.inc.php');
+$_SESSION['calendar']['user'] = $GLOBALS['phpgw_info']['user'];
+$_SESSION['calendar']['server'] = $GLOBALS['phpgw_info']['server'];
+define('PHPGW_API_INC','../../phpgwapi/inc');
+include_once(PHPGW_API_INC.'/class.db.inc.php');
+$page_content = <<<PAGE
+<HTML><HEAD></HEAD><BODY>
+<SCRIPT type="text/javascript">
+var Total = 0;
+	function show_table(){
+		var MainDiv = document.getElementById('MainDiv');
+		var showTable = document.createElement('TABLE');
+		showTable.style.color = "#000066"
+		showTable.style.background = "#F7F7F7";
+		showTable.style.border = "1px solid #CCCCCC";
+		showTable.width = "75%";
+		showTable.align = "center";
+		var trLine = document.createElement('TR');
+		var tdVal = document.createElement('TD');
+		tdVal.innerHTML = "Titulo";
+		trLine.appendChild(tdVal);
+		tdVal = document.createElement('TD');
+		tdVal.innerHTML = "Descricao";
+		trLine.appendChild(tdVal);
+                tdVal = document.createElement('TD');
+                tdVal.innerHTML = "Data";
+                trLine.appendChild(tdVal);
+		tdVal = document.createElement('TD');
+		tdVal.innerHTML = "Horas";
+		trLine.appendChild(tdVal);
+		trLine.style.background = "#DDD";
+		showTable.appendChild(trLine);
+
+		var Eelement = MainDiv.firstChild;
+		while (Eelement){
+			trLine = document.createElement('TR');
+			tdVal = document.createElement('TD');
+			var cal_id = Eelement.childNodes[4].innerHTML;
+			tdVal.innerHTML = "<a href='../../index.php?menuaction=calendar.uicalendar.view&cal_id="+cal_id+"'>"+Eelement.childNodes[0].innerHTML+"</a>";
+			trLine.appendChild(tdVal);
+                        tdVal = document.createElement('TD');
+                        tdVal.innerHTML = Eelement.childNodes[1].innerHTML;
+                        trLine.appendChild(tdVal);
+			tdVal = document.createElement('TD');
+			var today = new Date();
+			today.setTime(parseInt(Eelement.childNodes[2].innerHTML)*1000);
+                        tdVal.innerHTML = (today.getDate()+"/"+(today.getMonth()+1)+"/"+(today.getYear()+1900));
+                        trLine.appendChild(tdVal);
+			tdVal = document.createElement('TD');
+			Total += (Eelement.childNodes[3].innerHTML-Eelement.childNodes[2].innerHTML)/3600;
+                        tdVal.innerHTML = ((Eelement.childNodes[3].innerHTML-Eelement.childNodes[2].innerHTML)/3600).toFixed(1);
+			trLine.appendChild(tdVal);
+			var tbody = document.createElement('tbody');
+			tbody.appendChild(trLine);
+			showTable.appendChild(tbody);
+	                Eelement = Eelement.nextSibling;
+
+		}
+		trLine = document.createElement('TR');
+		tdVal = document.createElement('TD');
+		tdDes =  document.createElement('TD');
+		tdDes.innerHTML = "Total";
+		tdDes.align = "left";
+		tdVal.innerHTML = Total.toFixed(1);
+		trLine.style.background = "#FFF";
+		trLine.appendChild(tdDes);
+		trLine.appendChild(document.createElement('TD'));
+                trLine.appendChild(document.createElement('TD'));
+		trLine.appendChild(tdVal);
+		var tbody = document.createElement('tbody');
+                tbody.appendChild(trLine);
+		showTable.appendChild(tbody);
+		MainDiv.parentNode.appendChild(showTable);
+	}
+</SCRIPT>
+PAGE;
+echo $page_content;
+$db = new db();
+$db->Halt_On_Error = 'no';
+$db->connect(
+	$_SESSION['calendar']['server']['db_name'],
+	$_SESSION['calendar']['server']['db_host'],
+	$_SESSION['calendar']['server']['db_port'],
+	$_SESSION['calendar']['server']['db_user'],
+	$_SESSION['calendar']['server']['db_pass'],
+	$_SESSION['calendar']['server']['db_type']
+);
+if (IsSet($_POST['CAT'])){
+	if (!preg_match("/[a-zA-Z0-9]+/i",$_POST['CAT'][0])){
+		echo "Invalid entry:".$_POST['CAT'][0];
+		return false;
+	}
+	if (strlen($_POST['DAT']) > 0 && !preg_match("/[0123][0-9].[01][0-9].[12][90][0-9][0-9]$/i",$_POST['DAT'])){
+		echo "Invalid entry:".$_POST['DAT'];
+		return false;
+	}
+
+	if (IsSet($_POST['DAT']))
+		$initDate = mktime(null,null,null,substr($_POST['DAT'],3,2),substr($_POST['DAT'],0,2),substr($_POST['DAT'],6,4));
+	if ($_POST['CAL'][0] != 'run')
+		$user_id = $_POST['CAL'][0];
+
+	foreach ($_POST['CAL'] as $cal_uid){
+		$found = false;	
+		foreach($_SESSION['calendar']['cals'] as $grant)
+			if ($cal_uid == $grant['value'])
+				$found = true;
+			if (!$found){
+				echo "Permission denied, cal. id:".$cal_uid."<br>";
+				return;
+			}
+		}
+
+
+	foreach($_POST['CAT'] as $catid){
+		$query = "select cal_id,title,description,datetime,edatetime from phpgw_cal where ".(!$_POST['NORM']?"cal_type = 'H' and":" is_public = 1 and ")." owner = ".$user_id." and (category like '%,".$catid.",%' or category like '%,".$catid."' or category like '".$catid.",%' or category = '".$catid."')".(IsSet($initDate)?" and datetime > ".$initDate:"");
+		if(!$db->query($query)){
+			print("<br>Query failed at host:<br>".$_SESSION['calendar']['server']['db_user']."@".$_SESSION['calendar']['server']['db_host'].":".$_SESSION['calendar']['server']['db_port']."<br>");
+			return;
+		}
+		else{
+			while($db->next_record()){
+				$entry = $db->row();
+				$repeated = false;
+				if (!empty($result_))
+				foreach($result_ as $value){
+					if ($value['cal_id'] == $entry['cal_id'])
+						$repeated = true;
+				}
+				if(!$repeated)
+					$result_[] = $entry;
+			}
+		}
+}
+	echo "<div id='MainDiv' style='display: none;'>";
+	if (!empty($result_))
+	foreach($result_ as $ind => $entry){
+		echo "<div id=\"entry_".$ind."\"><div id=\"title_".$ind."\">".htmlspecialchars($entry['title'])."</div><div id=\"description_".$ind."\">".htmlspecialchars($entry['description'])."</div><div id=\"datetime_".$ind."\">".$entry['datetime']."</div><div id=\"edatetime_".$ind."\">".$entry['edatetime']."</div><div>".$entry['cal_id']."</div></div>";
+	}
+	echo "</div><script type=\"text/javascript\"> show_table();</script>";
+	return;
+}
+
+$self = $_SERVER['PHP_SELF'];
+print("<table><tbody><tr><td>");
+print("<form id=\"form1\" method=\"post\" action=\"$self\">");
+print("Categoria(s):<br></td><td>");
+print("<select name=\"CAT[]\" multiple>");
+print($_SESSION['calendar']['categories']);
+print("</select></td></tr><tr><td>");
+print("Incluir ocorr&ecirc;ncias do tipo normal:</td><td><input name=\"NORM\" type=\"checkbox\"></input><br></td></tr>");
+print("<tr><td>Usuario:</td><td><select name=\"CAL[]\" multiple>");
+foreach($_SESSION['calendar']['cals'] as $grant)
+	print(!strstr($grant['value'],'g_')?'<option value="'.$grant['value'].'">'.$grant['name'].'</option>':"");
+print("</td></tr><tr><td>Apartir da data: dd/mm/aaaa<br>(caso todas deixar em branco):</td><td><input name=\"DAT\" type=\"text\"></input></td></tr>");
+print("</td></tr></tbody></table><br><input value=\"Fazer consulta\" type=\"submit\"><br></form>");
+print("</BODY></HTML>");
+?>
Index: /tags/calendar/0.9.3/inc/class.uicustom_fields.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.uicustom_fields.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/inc/class.uicustom_fields.inc.php	(revision 2)
@@ -0,0 +1,205 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar - Custom fields and sorting                        *
+  * http://www.egroupware.org                                                *
+  * Written by Ralf Becker <RalfBecker@outdoor-training.de>                  *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	require_once(PHPGW_INCLUDE_ROOT.'/calendar/inc/class.bocustom_fields.inc.php');
+	$GLOBALS['phpgw_info']['flags']['included_classes']['bocustom_fields'] = True; // for 0.9.14
+
+	class uicustom_fields extends bocustom_fields
+	{
+		var $public_functions = array(
+			'index' => True,
+			'submited'  => True
+		);
+
+		function uicustom_fields()
+		{
+			$this->bocustom_fields();	// call constructor of extended class
+
+			$this->tpl = $GLOBALS['phpgw']->template;
+			if (!is_object($GLOBALS['phpgw']->nextmatchs))
+			{
+				$GLOBALS['phpgw']->nextmatchs = CreateObject('phpgwapi.nextmatchs');
+			}
+			if (!is_object($GLOBALS['phpgw']->html))
+			{
+				$GLOBALS['phpgw']->html = CreateObject('phpgwapi.html');
+			}
+			$this->html = &$GLOBALS['phpgw']->html;
+		}
+
+		function index($error='')
+		{
+			unset($GLOBALS['phpgw_info']['flags']['noheader']);
+			unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+			$GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['calendar']['title'].' - '.lang('Custom fields and sorting');
+			$GLOBALS['phpgw']->common->phpgw_header();
+
+			$this->tpl = $GLOBALS['phpgw']->template;
+
+			$this->tpl->set_unknowns('remove');
+			$this->tpl->set_file(array(
+				'custom_fields_tpl'	=> 'custom_fields.tpl'
+			));
+			$this->tpl->set_block('custom_fields_tpl','custom_fields','custom_fields');
+			$this->tpl->set_block('custom_fields_tpl','row','row');
+
+			$n = 0;
+			foreach($this->fields as $field => $data)
+			{
+				$data['order'] = ($n += 10);
+				if (isset($this->stock_fields[$field]))
+				{
+					$this->set_row($data,$field);
+				}
+				else
+				{
+					$this->set_row($data,$field,'delete','Delete');
+				}
+			}
+			$this->tpl->set_var(array(
+				'hidden_vars'  => '',
+				'lang_error'   => $error,
+				'lang_name'    => lang('Name'),
+				'lang_length'  => lang('Length<br>(<= 255)'),
+				'lang_shown'   => lang('Length shown<br>(emtpy for full length)'),
+				'lang_order'   => lang('Order'),
+				'lang_title'   => lang('Title-row'),
+				'lang_disabled'=> lang('Disabled'),
+				'action_url'   => $GLOBALS['phpgw']->link('/index.php','menuaction=calendar.uicustom_fields.submited'),
+				'save_button'  => $this->html->submit_button('save','Save'),
+				'cancel_button'=> $this->html->submit_button('cancel','Cancel'),
+			));
+
+			$this->set_row(array('order' => $n+10),'***new***','add','Add');
+
+			$this->tpl->pfp('out','custom_fields');
+		}
+
+		function set_row($values,$id='',$name='',$label='')
+		{
+			if ($id !== '')
+			{
+				$id = '['.htmlspecialchars($id).']';
+			}
+			$this->tpl->set_var(array(
+				'name'    => $values['label'] ? lang($values['label']) : $this->html->input('name'.$id,$values['name'],'','SIZE="40" MAXLENGTH="40"'),
+				'length'  => $values['label'] ? '&nbsp' : $this->html->input('length'.$id,$values['length'],'','SIZE="3"'),
+				'shown'   => $values['label'] ? '&nbsp' : $this->html->input('shown'.$id,$values['shown'],'','SIZE="3"'),
+				'order'   => $this->html->input('order'.$id,$values['order'],'','SIZE="3"'),
+				'title'   => $this->html->checkbox('title'.$id,$values['title']),
+				'disabled'=> $this->html->checkbox('disabled'.$id,$values['disabled']),
+				'button'  => $name ? $this->html->submit_button($name.$id,$label) : '&nbsp'
+			));
+			if ($name !== 'add')
+			{
+				$this->tpl->set_var('tr_color',$values['title'] ? $GLOBALS['phpgw_info']['theme']['th_bg'] : $GLOBALS['phpgw']->nextmatchs->alternate_row_color());
+				$this->tpl->parse('rows','row',True);
+			}
+		}
+
+		function submited()
+		{
+			if ($_POST['cancel'])
+			{
+				$GLOBALS['phpgw']->redirect_link('/admin/');
+			}
+			//echo "<pre>"; print_r($_POST); echo "</pre>";
+
+			foreach ($_POST['order'] as $field => $order)
+			{
+				if (isset($_POST['delete'][$field]) || $field == '***new***')
+				{
+					continue;
+				}
+				while(isset($ordered[$order]))
+				{
+					++$order;
+				}
+				$ordered[$order] = array(
+					'field'     => $field,
+					'name'      => stripslashes($_POST['name'][$field]),
+					'length'    => (int)$_POST['length'][$field],
+					'shown'     => (int)$_POST['shown'][$field],
+					'title'     => !!$_POST['title'][$field],
+					'disabled'  => !!$_POST['disabled'][$field]
+				);
+				if (isset($this->stock_fields[$field]))
+				{
+					$ordered[$order]['name']  = $this->fields[$field]['name'];
+					$ordered[$order]['label'] = $this->fields[$field]['label'];
+				}
+			}
+			if (isset($_POST['add']) || strlen($_POST['name']['***new***']))
+			{
+				$name = stripslashes($_POST['name']['***new***']);
+
+				if (!strlen($name) || array_search($name,$_POST['name']) != '***new***')
+				{
+					$error .= lang('New name must not exist and not be empty!!!');
+				}
+				else
+				{
+					$order = $_POST['order']['***new***'];
+					while(isset($_POST['order'][$order]))
+					{
+						++$order;
+					}
+					$ordered[$order] = array(
+						'field'     => '#'.$name,
+						'name'      => $name,
+						'length'    => (int)$_POST['length']['***new***'],
+						'shown'     => (int)$_POST['shown']['***new***'],
+						'title'     => !!$_POST['title']['***new***'],
+						'disabled'  => !!$_POST['disabled']['***new***']
+					);
+				}
+			}
+			//echo "<pre>"; print_r($ordered); echo "</pre>\n";
+			ksort($ordered,SORT_NUMERIC);
+
+			$this->fields = array();
+			foreach($ordered as $order => $data)
+			{
+				if ($data['length'] > 255)
+				{
+					$data['length'] = 255;
+				}
+				if ($data['length'] <= 0)
+				{
+					unset($data['length']);
+				}
+				if ($data['shown'] >= $data['length'] || $data['shown'] <= 0)
+				{
+					unset($data['shown']);
+				}
+				if (!$data['title'])
+				{
+					unset($data['title']);
+				}
+				if (!$data['disabled'])
+				{
+					unset($data['disabled']);
+				}
+				$field = $data['field'];
+				unset($data['field']);
+				$this->fields[$field] = $data;
+			}
+			if (!$error && isset($_POST['save']))
+			{
+				$this->save();
+				$GLOBALS['phpgw']->redirect_link('/admin/');
+			}
+			$this->index($error);
+		}
+	}
+?>
Index: /tags/calendar/0.9.3/inc/hook_home_day.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/hook_home_day.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/inc/hook_home_day.inc.php	(revision 2)
@@ -0,0 +1,42 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar                                                    *
+  * http://www.egroupware.org                                                *
+  * Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
+  *          http://www.radix.net/~cknudsen                                  *
+  * Written by Mark Peters <skeeter@phpgroupware.org>                        *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	$d1 = strtolower(substr(PHPGW_APP_INC,0,3));
+	if($d1 == 'htt' || $d1 == 'ftp' )
+	{
+		echo 'Failed attempt to break in via an old Security Hole!<br>'."\n";
+		$GLOBALS['phpgw']->common->phpgw_exit();
+	}
+	unset($d1);
+
+	$GLOBALS['extra_data'] = $GLOBALS['css']."\n".'<td>'."\n".'<table border="0" cols="3"><tr><td align="center" width="35%" valign="top">'
+		. ExecMethod('calendar.uicalendar.mini_calendar',
+			Array(
+				'day'		=> $GLOBALS['g_day'],
+				'month'	=> $GLOBALS['g_month'],
+				'year'	=> $GLOBALS['g_year'],
+				'link'	=> 'day'
+			)
+		).'</td><td align="center"><table border="0" width="100%" cellspacing="0" cellpadding="0">'
+		. '<tr><td align="center">'.ExecMethod('calendar.bocalendar.long_date',time())
+		.'</td></tr><tr><td bgcolor="'.$GLOBALS['phpgw_info']['theme']['bg_text']
+		.'" valign="top">'.ExecMethod('calendar.uicalendar.print_day',
+			Array(
+				'year'	=> $GLOBALS['g_year'],
+				'month'	=> $GLOBALS['g_month'],
+				'day'		=> $GLOBALS['g_day']
+			)
+		).'</td></tr></table>'."\n".'</td>'."\n".'</tr>'."\n".'</table>'."\n".'</td>'."\n";
+?>
Index: /tags/calendar/0.9.3/inc/class.boicalendar.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.boicalendar.inc.php	(revision 678)
+++ /tags/calendar/0.9.3/inc/class.boicalendar.inc.php	(revision 678)
@@ -0,0 +1,3591 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - iCalendar Parser                                            *
+  * http://www.egroupware.org                                                *
+  * Written by Mark Peters <skeeter@phpgroupware.org>                        *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	define('FOLD_LENGTH',75);
+
+	define('VEVENT',1);
+	define('VTODO',2);
+
+	define('NONE',0);
+	define('CHAIR',1);
+	define('REQ_PARTICIPANT',2);
+	define('OPT_PARTICIPANT',3);
+	define('NON_PARTICIPANT',4);
+
+	define('INDIVIDUAL',1);
+	define('GROUP',2);
+	define('RESOURCE',4);
+	define('ROOM',8);
+	define('UNKNOWN',16);
+
+	define('NEEDS_ACTION',0);
+	define('ACCEPTED',1);
+	define('DECLINED',2);
+	define('TENTATIVE',3);
+	define('DELEGATED',4);
+	define('COMPLETED',5);
+	define('IN_PROCESS',6);
+
+	/*
+	* Class
+	*/
+	define('_PRIVATE',0);
+	define('_PUBLIC',1);
+	define('_CONFIDENTIAL',3);
+
+	/*
+	* Transparency
+	*/
+	define('TRANSPARENT',0);
+	define('OPAQUE',1);
+
+	/*
+	* Frequency
+	*/
+	define('SECONDLY',1);
+	define('MINUTELY',2);
+	define('HOURLY',3);
+	define('DAILY',4);
+	define('WEEKLY',5);
+	define('MONTHLY',6);
+	define('YEARLY',7);
+
+	define('FREE',0);
+	define('BUSY',1);
+	define('BUSY_UNAVAILABLE',2);
+	define('BUSY_TENTATIVE',3);
+
+	define('THISANDPRIOR',0);
+	define('THISANDFUTURE',1);
+
+	define('START',0);
+	define('END',1);
+
+	define('_8BIT',0);
+	define('_BASE64',1);
+
+	define('OTHER',99);
+
+	class boicalendar
+	{
+		var $public_functions = array(
+			'import' => True,
+			'export' => True,
+			'freebusy' => True,
+		);
+
+		var $ical;
+		var $line = 0;
+		var $event = Array();
+		var $todo = Array();
+		var $journal = Array();
+		var $freebusy = Array();
+		var $timezone = Array();
+		var $property = Array();
+		var $parameter = Array();
+		var $debug_str = False;
+		var $api = True;
+		var $chunk_split = True;
+
+		/*
+		* Base Functions
+		*/
+
+		function boicalendar()
+		{
+			$this->property = Array(
+				'action'		=> Array(
+					'type'		=> 'text',
+					'to_text'	=> True,
+					'valarm'		=> Array(
+						'state'		=> 'required',
+						'multiples'	=> False
+					)
+				),
+				'attach'		=> Array(
+					'type'		=> 'uri',
+					'to_text'	=> True,
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'valarm'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					)
+				),
+				'attendee'		=> Array(
+					'type'		=> 'cal-address',
+					'to_text'	=> False,
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'valarm'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vfreebusy'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					)
+				),
+				'categories'		=> Array(
+					'type'		=> 'text',
+					'to_text'	=> True,
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					)
+				),
+				'class'			=> Array(
+					'type'		=> 'text',
+					'to_text'	=> True,
+					'vevent'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'comment'		=> Array(
+					'type'		=> 'text',
+					'to_text'	=> True,
+					'daylight'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'standard'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'valarm'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vfreebusy'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					)
+				),
+				'completed'		=> Array(
+					'type'		=> 'date-time',
+					'to_text'	=> False,
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'contact'		=> Array(
+					'type'		=> 'text',
+					'to_text'	=> True,
+					'vevent'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vfreebusy'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					)
+				),
+				'created'		=> Array(
+					'type'		=> 'date-time',
+					'to_text'	=> False,
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'description'		=> Array(
+					'type'		=> 'text',
+					'to_text'	=> True,
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'valarm'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'dtend'			=> Array(
+					'type'		=> 'date-time',
+					'to_text'	=> False,
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vfreebusy'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'dtstamp'		=> Array(
+					'type'		=> 'date-time',
+					'to_text'	=> False,
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vfreebusy'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'dtstart'		=> Array(
+					'type'		=> 'date-time',
+					'to_text'	=> False,
+					'daylight'	=> Array(
+						'state'		=> 'required',
+						'multiples'	=> False
+					),
+					'standard'	=> Array(
+						'state'		=> 'required',
+						'multiples'	=> False
+					),
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vfreebusy'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'due'			=> Array(
+					'type'		=> 'date-time',
+					'to_text'	=> False,
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'duration'		=> Array(
+					'type'		=> 'duration',
+					'to_text'	=> False,
+					'valarm'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vfreebusy'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'exdate'		=> Array(
+					'type'		=> 'date-time',
+					'to_text'	=> False,
+					'vevent'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					)
+				),
+				'exrule'		=> Array(
+					'type'		=> 'recur',
+					'to_text'	=> False,
+					'vevent'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					)
+				),
+				'freebusy'		=> Array(
+					'type'		=> 'freebusy',
+					'to_text'	=> False,
+					'vfreebusy'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					)
+				),
+				'geo'			=> Array(
+					'type'		=> 'float',
+					'to_text'	=> True,
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'last_modified'		=> Array(
+					'type'		=> 'date-time',
+					'to_text'	=> False,
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vtimezone'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'location'		=> Array(
+					'type'		=> 'text',
+					'to_text'	=> True,
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'method'			=> Array(
+					'type'		=> 'text',
+					'to_text'	=> True,
+					'ical'	=> Array(
+						'state'		=> 'required',
+						'multiples'	=> False
+					)
+				),
+				'organizer'		=> Array(
+					'type'		=> 'cal-address',
+					'to_text'	=> False,
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vfreebusy'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'percent_complete'	=> Array(
+					'type'		=> 'integer',
+					'to_text'	=> False,
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'priority'		=> Array(
+					'type'		=> 'integer',
+					'to_text'	=> True,
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'prodid'			=> Array(
+					'type'		=> 'text',
+					'to_text'	=> True,
+					'ical'	=> Array(
+						'state'		=> 'required',
+						'multiples'	=> False
+					)
+				),
+				'rdate'			=> Array(
+					'type'		=> 'date-time',
+					'to_text'	=> False,
+					'daylight'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'standard'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					)
+				),
+				'recurrence_id'		=> Array(
+					'type'		=> 'date-time',
+					'to_text'	=> False,
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vtodo'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'related_to'		=> Array(
+					'type'		=> 'text',
+					'to_text'	=> False,
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					)
+				),
+				'request_status'	=> Array(
+					'type'		=> 'text',
+					'to_text'	=> True,
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vfreebusy'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					)
+				),
+				'resources'		=> Array(
+					'type'		=> 'text',
+					'to_text'	=> False,
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'rrule'			=> Array(
+					'type'		=> 'recur',
+					'to_text'	=> False,
+					'daylight'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'standard'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					)
+				),
+				'sequence'		=> Array(
+					'type'		=> 'integer',
+					'to_text'	=> True,
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'status'		=> Array(
+					'type'		=> 'text',
+					'to_text'	=> True,
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'summary'		=> Array(
+					'type'		=> 'text',
+					'to_text'	=> True,
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'valarm'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'transp'		=> Array(
+					'type'		=> 'text',
+					'to_text'	=> True,
+					'vevent'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'trigger'		=> Array(
+					'type'		=> 'text',
+					'to_text'	=> True,
+					'valarm'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'tzid'			=> Array(
+					'type'		=> 'text',
+					'to_text'	=> True,
+					'vtimezone'		=> Array(
+						'state'		=> 'required',
+						'multiples'	=> False
+					)
+				),
+				'tzname'		=> Array(
+					'type'		=> 'text',
+					'to_text'	=> True,
+					'daylight'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					),
+					'standard'	=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> True
+					)
+				),
+				'tzoffsetfrom'		=> Array(
+					'type'		=> 'utc-offset',
+					'to_text'	=> True,
+					'daylight'		=> Array(
+						'state'		=> 'required',
+						'multiples'	=> False
+					),
+					'standard'		=> Array(
+						'state'		=> 'required',
+						'multiples'	=> False
+					)
+				),
+				'tzoffsetto'		=> Array(
+					'type'		=> 'utc-offset',
+					'to_text'	=> True,
+					'daylight'		=> Array(
+						'state'		=> 'required',
+						'multiples'	=> False
+					),
+					'standard'		=> Array(
+						'state'		=> 'required',
+						'multiples'	=> False
+					)
+				),
+				'tzurl'			=> Array(
+					'type'		=> 'uri',
+					'to_text'	=> True,
+					'vtimezone'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					)
+				),
+				'uid'			=> Array(
+					'type'		=> 'text',
+					'to_text'	=> True,
+					'vevent'	=> Array(
+						'state'		=> 'required',
+						'multiples'	=> False
+					),
+					'vfreebusy'		=> Array(
+						'state'		=> 'required',
+						'multiples'	=> False
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'required',
+						'multiples'	=> False
+					),
+					'vtodo'		=> Array(
+						'state'		=> 'required',
+						'multiples'	=> False
+					)
+				),
+				'url'			=> Array(
+					'type'		=> 'text',
+					'to_text'	=> True,
+					'vevent'	=> Array(
+						'state'		=> 'required',
+						'multiples'	=> False
+					),
+					'vfreebusy'		=> Array(
+						'state'		=> 'required',
+						'multiples'	=> False
+					),
+					'vjournal'		=> Array(
+						'state'		=> 'optional',
+						'multiples'	=> False
+					),
+					'vtodo'	=> Array(
+						'state'		=> 'required',
+						'multiples'	=> False
+					)
+				),
+				'version'			=> Array(
+					'type'		=> 'text',
+					'to_text'	=> True,
+					'ical'	=> Array(
+						'state'		=> 'required',
+						'multiples'	=> False
+					)
+				)
+			);
+			$this->parameter = Array(
+				'altrep'		=> Array(
+					'type'		=> 'uri',
+					'quoted'		=> True,
+					'to_text'	=> True,
+					'properties'	=> Array(
+						'comment'		=> True,
+						'description'	=> True,
+						'location'		=> True,
+						'prodid'			=> True,
+						'resources'		=> True,
+						'summary'		=> True,
+						'contact'		=> True
+					)
+				),
+				'byday'		=> Array(
+					'type'		=> 'text',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'rrule'		=> True
+					)
+				),
+				'byhour'		=> Array(
+					'type'		=> 'text',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'rrule'		=> True
+					)
+				),
+				'byminute'		=> Array(
+					'type'		=> 'text',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'rrule'		=> True
+					)
+				),
+				'bymonth'		=> Array(
+					'type'		=> 'text',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'rrule'		=> True
+					)
+				),
+				'bymonthday'	=> Array(
+					'type'		=> 'text',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'rrule'		=> True
+					)
+				),
+				'bysecond'		=> Array(
+					'type'		=> 'text',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'rrule'		=> True
+					)
+				),
+				'bysetpos'		=> Array(
+					'type'		=> 'text',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'rrule'		=> True
+					)
+				),
+				'byweekno'		=> Array(
+					'type'		=> 'text',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'rrule'		=> True
+					)
+				),
+				'byyearday'		=> Array(
+					'type'		=> 'text',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'rrule'		=> True
+					)
+				),
+				'class'			=> Array(
+					'type'		=> 'function',
+					'function'	=> 'switch_class',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'class'			=> True
+					)
+				),
+				'cn'			=> Array(
+					'type'		=> 'text',
+					'quoted'		=> True,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'attendee'		=> True,
+						'organizer'		=> True
+					)
+				),
+				'count'		=> Array(
+					'type'		=> 'integer',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'rrule'			=> True
+					)
+				),
+				'cu'			=> Array(
+					'type'		=> 'function',
+					'function'	=> 'switch_cu',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'attendee'		=> True
+					)
+				),
+				'delegated_from'	=> Array(
+					'type'		=> 'function',
+					'function'	=> 'switch_mailto',
+					'quoted'		=> True,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'attendee'		=> True
+					)
+				),
+				'delegated_to'	=> Array(
+					'type'		=> 'function',
+					'function'	=> 'switch_mailto',
+					'quoted'		=> True,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'attendee'		=> True
+					)
+				),
+				'dir'			=> Array(
+					'type'		=> 'dir',
+					'quoted'		=> True,
+					'to_text'	=> True,
+					'properties'	=> Array(
+						'attendee'		=> True,
+						'organizer'		=> True
+					)
+				),
+				'dtend'		=> Array(
+					'type'		=> 'function',
+					'function'	=> 'switch_date',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'dtend'		=> True
+					)
+				),
+				'dtstamp'		=> Array(
+					'type'		=> 'function',
+					'function'	=> 'switch_date',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'dtstamp'		=> True
+					)
+				),
+				'dtstart'		=> Array(
+					'type'		=> 'function',
+					'function'	=> 'switch_date',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'dtstart'		=> True
+					)
+				),
+				'encoding'	=> Array( // was enocding ???
+					'type'		=> 'function',
+					'function'	=> 'switch_encoding',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'attach'			=> True
+					)
+				),
+				'fmttype'	=> Array(
+					'type'		=> 'text',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'attach'			=> True
+					)
+				),
+				'fbtype'		=> Array(
+					'type'		=> 'function',
+					'function'	=> 'switch_fbtype',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'attach'			=> True
+					)
+				),
+				'freq'		=> Array(
+					'type'		=> 'function',
+					'function'	=> 'switch_freq',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'rrule'			=> True
+					)
+				),
+				'interval'		=> Array(
+					'type'		=> 'integer',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'rrule'		=> True
+					)
+				),
+				'language'		=> Array(
+					'type'		=> 'text',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'categories'	=> True,
+						'comment'		=> True,
+						'description'	=> True,
+						'location'		=> True,
+						'resources'		=> True,
+						'summary'		=> True,
+						'tzname'			=> True,
+						'attendee'		=> True,
+						'contact'		=> True,
+						'organizer'		=> True,
+						'x-type'			=> True
+					)
+				),
+				'last_modified'		=> Array(
+					'type'		=> 'function',
+					'function'	=> 'switch_date',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'last_modified'	=> True
+					)
+				),
+				'mailto'		=> Array(
+					'type'		=> 'function',
+					'function'	=> 'switch_mailto',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'attendee'		=> True,
+						'organizer'		=> True
+					)
+				),
+				'member'		=> Array(
+					'type'		=> 'function',
+					'function'	=> 'switch_mailto',
+					'quoted'		=> True,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'attendee'		=> True
+					)
+				),
+				'partstat'		=> Array(
+					'type'		=> 'function',
+					'function'	=> 'switch_partstat',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'attendee'		=> True,
+						'organizer'		=> True
+					)
+				),
+				'range'		=> Array(
+					'type'		=> 'function',
+					'function'	=> 'switch_range',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'recurrence_id'	=> True
+					)
+				),
+				'related'		=> Array(
+					'type'		=> 'function',
+					'function'	=> 'switch_related',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'related_to'	=> True
+					)
+				),
+				'role'		=> Array(
+					'type'		=> 'function',
+					'function'	=> 'switch_role',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'attendee'		=> True,
+						'organizer'		=> True
+					)
+				),
+				'rsvp'		=> Array(
+					'type'		=> 'function',
+					'function'	=> 'switch_rsvp',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'attendee'		=> True
+					)
+				),
+				'sent_by'		=> Array(
+					'type'		=> 'function',
+					'function'	=> 'parse_user_host',
+					'quoted'		=> True,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'attendee'		=> True,
+						'organizer'		=> True
+					)
+				),
+				'tzid'		=> Array(
+					'type'		=> 'text',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'dtend'		=> True,
+						'due'			=> True,
+						'dtstart'	=> True,
+						'exdate'		=> True,
+						'rdate'		=> True,
+						'recurrence_id'	=> True
+					)
+				),
+				'until'		=> Array(
+					'type'		=> 'function',
+					'function'	=> 'switch_date',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'rrule'		=> True
+					)
+				),
+				'value'		=> Array(
+					'type'		=> 'value',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'calscale'	=> True,
+						'prodid'		=> True,
+						'method'		=> True,
+						'version'	=> True,
+						'attach'		=> True,
+						'categories'	=> True,
+						'class'		=> True,
+						'comment'	=> True,
+						'description'	=> True,
+						'geo'		=> True,
+						'location'	=> True,
+						'percent'	=> True,
+						'priority'	=> True,
+						'resources'	=> True,
+						'status'		=> True,
+						'summary'	=> True,
+						'completed'	=> True,
+						'dtend'		=> True,
+						'due'		=> True,
+						'dtstart'	=> True,
+						'duration'	=> True,
+						'freebusy'	=> True,
+						'transp'		=> True,
+						'tzid'		=> True,
+						'tzname'		=> True,
+						'tzoffsetfrom'	=> True,
+						'tzoffsetto'	=> True,
+						'tzurl'		=> True,
+						'attendee'	=> True,
+						'contact'	=> True,
+						'organizer'	=> True,
+						'recurrence_id'	=> True,
+						'url'		=> True,
+						'uid'		=> True,
+						'exdate'	=> True,
+						'exrule'	=> True,
+						'rdate'	=> True,
+						'rrule'	=> True,
+						'action'	=> True,
+						'repeat'	=> True,
+						'trigger'	=> True,
+						'created'	=> True,
+						'dtstamp'	=> True,
+						'last_modified'	=> True,
+						'sequence'	=> True,
+						'x_type'		=> True,
+						'request_status'	=> True
+					)
+				),
+				'wkst'		=> Array(
+					'type'		=> 'string',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'rrule'		=> True
+					)
+				),
+				'x_type'		=> Array(
+					'type'		=> 'x_type',
+					'quoted'		=> False,
+					'to_text'	=> False,
+					'properties'	=> Array(
+						'calscale'	=> True,
+						'method'		=> True,
+						'prodid'		=> True,
+						'version'	=> True,
+						'attach'		=> True,
+						'categories'	=> True,
+						'class'		=> True,
+						'comment'	=> True,
+						'description'	=> True,
+						'geo'		=> True,
+						'location'	=> True,
+						'percent'	=> True,
+						'priority'	=> True,
+						'resources'	=> True,
+						'status'		=> True,
+						'summary'	=> True,
+						'completed'	=> True,
+						'dtend'		=> True,
+						'due'		=> True,
+						'dtstart'	=> True,
+						'duration'	=> True,
+						'freebusy'	=> True,
+						'transp'		=> True,
+						'tzid'		=> True,
+						'tzname'		=> True,
+						'tzoffsetfrom'	=> True,
+						'tzoffsetto'	=> True,
+						'tzurl'		=> True,
+						'attendee'	=> True,
+						'contact'	=> True,
+						'organizer'	=> True,
+						'recurrence_id'	=> True,
+						'url'		=> True,
+						'uid'		=> True,
+						'exdate'	=> True,
+						'exrule'	=> True,
+						'rdate'	=> True,
+						'rrule'	=> True,
+						'action'	=> True,
+						'repeat'	=> True,
+						'trigger'	=> True,
+						'created'	=> True,
+						'dtstamp'	=> True,
+						'last_modified'	=> True,
+						'sequence'	=> True,
+						'x_type'		=> True,
+						'request_status'	=> True
+					)
+				)
+			);
+			if(!is_object($GLOBALS['phpgw']->datetime))
+			{
+				$GLOBALS['phpgw']->datetime = createobject('phpgwapi.date_time');
+			}
+		}
+
+		function set_var(&$event,$type,$value)
+		{
+			$type = strtolower(str_replace('-','_',$type));
+			$event[$type] = $value;
+			if(is_string($value))
+			{
+				$this->debug("Setting ".$type." = ".$value);
+			}
+			else
+			{
+				$this->debug("Setting ".$type." = "._debug_array($value,False));
+			}
+		}
+
+		function read_line_unfold($ical_text)
+		{
+			if($this->line < count($ical_text))
+			{
+				$str = str_replace("\r\n",'',$ical_text[$this->line]);
+				$this->line = $this->line + 1;
+				while(ereg("^[[:space:]]",$ical_text[$this->line]))
+				{
+					$str .= substr(str_replace("\r\n",'',$ical_text[$this->line]),1);
+					$this->line = $this->line + 1;
+				}
+				$this->debug("LINE : ".$str);
+				return $str;
+			}
+			else
+			{
+				return False;
+			}
+		}
+
+		function fold($str)
+		{
+			return $this->chunk_split==True ? chunk_split($str,FOLD_LENGTH,"\r\n") : $str."\r\n";
+		}
+
+		function strip_quotes($str)
+		{
+			return str_replace('"','',$str);
+		}
+
+		function from_text($str)
+		{
+			$str = str_replace("\\,",",",$str);
+			$str = str_replace("\\;",";",$str);
+			$str = str_replace("\\N","\n",$str);
+			$str = str_replace("\\n","\n",$str);
+			$str = str_replace("\\\\","\\",$str);
+			return "$str";
+		}
+
+		function to_text($str)
+		{
+			$str = str_replace("\\","\\\\",$str);
+			$str = str_replace(",","\\,",$str);
+			$str = str_replace(";","\\;",$str);
+			$str = str_replace("\n","\\n",$str);
+			return "$str";
+		}
+
+		function from_dir($str)
+		{
+			return str_replace('=3D','=',str_replace('%20',' ',$str));
+		}
+
+		function to_dir($str)
+		{
+			return str_replace('=','=3D',str_replace(' ','%20',$str));
+		}
+
+		function find_parameters($property)
+		{
+			static  $cached_returns;
+
+			if(isset($cached_returns[$property]))
+			{
+				reset($cached_returns[$property]);
+				return $cached_returns[$property];
+			}
+
+			reset($this->parameter);
+			while(list($key,$param_array) = each($this->parameter))
+			{
+				if($param_array['properties'][$property])
+				{
+					$param[] = $key;
+					$this->debug('Property : '.$property.' = Parameter : '.$key);
+				}
+			}
+			reset($param);
+			$cached_returns[$property] = $param;
+			return $param;
+		}
+
+		function find_properties($ical_type)
+		{
+			static  $cached_returns;
+
+			if(isset($cached_returns[$ical_type]))
+			{
+				reset($cached_returns[$ical_type]);
+				return $cached_returns[$ical_type];
+			}
+
+			reset($this->property);
+			while(list($key,$param_array) = each($this->property))
+			{
+				if($param_array[$ical_type])
+				{
+					$prop[] = $key;
+				}
+			}
+			reset($prop);
+			$cached_returns[$ical_type] = $prop;
+			return $prop;
+		}
+
+		function new_ical()
+		{
+			return Array();
+		}
+
+		/*
+		* Parse Functions
+		*/
+
+		function parse_geo(&$event,$value)
+		{
+			//		$return_value = $this->explode_param($value,True);
+			if(count($return_value) == 2)
+			{
+				$event['lat'] = $return_value[0];
+				$event['lon'] = $return_value[1];
+			}
+		}
+
+		function parse_xtype(&$event,$majortype,$value)
+		{
+			$temp_x_type['name'] = strtoupper(substr($majortype,2));
+			$temp_x_type['value'] = $value;
+			$event['x_type'][] = $temp_x_type;
+		}
+
+		function parse_parameters(&$event,$majortype,$value)
+		{
+			if(!ereg('[\=\;]',$value))
+			{
+				$return_value[] = Array(
+					'param'	=> $majortype,
+					'value'	=> $value
+				);
+				$value = '';
+			}
+			elseif(ereg('(.*(\:\\\\)?.*):(.*)',$value,$temp))
+			{
+				$this->debug('Value : '._debug_array($temp,False));
+				$this->debug('Param '.$majortype.' Value : '.$temp[3]);
+				if($temp[3])
+				{
+					$return_value[] = Array(
+						'param'	=> $majortype,
+						'value'	=> $temp[3]
+					);
+					$value = str_replace(':MAILTO','',$temp[1]);
+				}
+				while(ereg('(([A-Z\-]*)[=]([[:alnum:] \_\)\(\/\$\.\,\:\\\|\*\&\^\%\#\!\~\"\?\&\@\<\>\-]*))([\;]?)(.*)',$value,$temp))
+				{
+					$this->debug('Value : '._debug_array($temp,False));
+					$this->debug('Param '.$temp[2].' Value : '.$temp[3]);
+					$return_value[] = Array(
+						'param'	=> $temp[2],
+						'value'	=> $temp[3]
+					);
+					$value = chop($temp[5]);
+					$this->debug('Value would be = '.$value);
+				}
+			}
+			else
+			{
+				while(ereg('(([A-Z\-]*)[=]([[:alnum:] \_\)\(\/\$\.\,\:\\\|\*\&\^\%\#\!\~\"\?\&\@\<\>\-]*))([\;]?)(.*)',$value,$temp))
+				{
+					$this->debug('Value : '._debug_array($temp,False));
+					$this->debug('Param '.$temp[2].' Value : '.$temp[3]);
+					$return_value[] = Array(
+						'param'	=> $temp[2],
+						'value'	=> $temp[3]
+					);
+					$value = chop($temp[5]);
+					$this->debug('Value would be = '.$value);
+				}
+			}
+
+			for($i=0;$i<count($return_value);$i++)
+			{
+				$name = strtolower($return_value[$i]['param']);
+				$value = $this->strip_quotes($return_value[$i]['value']);
+				if(substr($name,0,2) == 'x-')
+				{
+					$param = 'x_type';
+					$name = str_replace('-','_',$return_value[$i]['param']);
+				}
+				else
+				{
+					$param = str_replace('-','_',strtolower($name));
+					if(!isset($this->parameter[$param]) || $majortype == 'tzid')
+					{
+						if($majortype == 'attendee' || $majortype == 'organizer')
+						{
+							$param = 'mailto';
+							$name = $param;
+						}
+						else
+						{
+							$param = 'value';
+						}
+					}
+				}
+				$this->debug('name : '.$name.' : Param = '.$param);
+				if(@$this->parameter[$param]['properties'][$majortype])
+				{
+					switch(@$this->parameter[$param]['type'])
+					{
+						case 'dir':
+							$this->set_var($event,$name,$this->from_dir($value));
+							break;
+						case 'text':
+							$this->set_var($event,$name,$value);
+							break;
+						case 'x_type':
+							$this->parse_xtype($event,$name,$value);
+							break;
+						case 'function':
+							$function = $this->parameter[$param]['function'];
+							$this->set_var($event,$name,$this->$function($value));
+							break;
+						case 'uri':
+							if(@$this->parameter[$param]['to_text'])
+							{
+								$value = $this->to_text($value);
+							}
+							$this->set_var($event,$name,$value);
+							break;
+						case 'integer':
+							$this->set_var($event,$name,(int)$value);
+							break;
+						case 'value':
+							if(@$this->property[$majortype]['type'] == 'date-time')
+							{
+								$this->set_var($event,$param,$this->switch_date($name));
+							}
+							elseif($value <> "\\n" && $value)
+							{
+								$this->set_var($event[$majortype],$param,$value);
+							}
+							$this->debug('Event : '._debug_array($event,False));
+							break;
+					}
+				}
+			}
+		}
+
+		function parse_value(&$event,$majortype,$value,$mode)
+		{
+			$var = Array();
+			$this->debug('Mode : '.$mode.' Majortype : '.$majortype);
+			$this->parse_parameters($var,$majortype,$value);
+			if($this->property[$majortype][$mode]['multiples'])
+			{
+				$this->debug(_debug_array($var,False));
+				$event[$majortype][] = $var;
+			}
+			else
+			{
+				$this->debug('Majortype : '.$majortype);
+				$this->debug('Property : '.$this->property[$majortype]['type']);
+				if($this->property[$majortype]['type'] == 'date-time')
+				{
+					$this->debug('Got a DATE-TIME type!');
+					$t_var = $var[$majortype];
+					unset($var[$majortype]);
+					reset($t_var);
+					while(list($key,$val) = each($t_var))
+					{
+						$var[$key] = $val;
+					}
+					$this->debug($majortype.' : '._debug_array($var,False));
+				}
+				$this->set_var($event,$majortype,$var);
+			}
+		}
+
+		/*
+		 * Build-Card Functions
+		 */
+
+		function build_xtype($x_type,$seperator='=')
+		{
+			$quote = '';
+			if($seperator == '=')
+			{
+				$quote = '"';
+			}
+
+			$return_value = $this->fold('X-'.$x_type['name'].$seperator.$quote.$x_type['value'].$quote);
+			if($seperator == '=')
+			{
+				return str_replace("\r\n",'',$return_value);
+			}
+			else
+			{
+				return $return_value;
+			}
+		}
+
+		function build_parameters($event,$property)
+		{
+			$str = '';
+			$include_mailto = False;
+			$include_datetime = False;
+			$param = $this->find_parameters($property);
+
+			if($property == 'exdate')
+			{
+				while(list($key,$value) = each($event))
+				{
+					$exdates[] = $this->switch_date($value);
+				}
+				return ':'.implode($exdates,',');
+			}
+			else
+			{
+				while(list($dumb_key,$key) = each($param))
+				{
+					if($key == 'value')
+					{
+						continue;
+					}
+					if($key == 'mailto')
+					{
+						$include_mailto = True;
+						continue;
+					}
+					$param_array = @$this->parameter[$key];
+					$type = @$this->parameter[$key]['type'];
+					if($type == 'date-time')
+					{
+						$include_datetime = True;
+						continue;
+					}
+					$quote = (@$this->parameter[$key]['quoted']?'"':'');
+					if(isset($event[$key]) && @$this->parameter[$key]['properties'][$property])
+					{
+						$change_text = @$this->parameter[$key]['to_text'];
+						$value = $event[$key];
+						if($change_text && $type == 'text')
+						{
+							$value = $this->to_text($value);
+						}
+						switch($type)
+						{
+							case 'dir':
+								$str .= ';'.str_replace('_','-',strtoupper($key)).'='.$quote.$this->to_dir($value).$quote;
+								break;
+							case 'function':
+								$str .= ';'.str_replace('_','-',strtoupper($key)).'=';
+								$function = $this->parameter[$key]['function'];
+								$this->debug($key.' Function Param : '.$value);
+								$str .= $quote.$this->$function($value).$quote;
+								break;
+							case 'text':
+							case 'string':
+								$str .= ';'.strtoupper($key).'='.$quote.$value.$quote;
+								break;
+							case 'date-time':
+								$str .= ($key=='until'?':':';UNTIL=').date('Ymd\THis',mktime($event['hour'],$event['min'],$event['sec'],$event['month'],$event['mday'],$event['year'])).(!@isset($event['tzid'])?'Z':'');
+								break;
+						}
+						unset($value);
+					}
+				}
+
+				if(!empty($event['x_type']))
+				{
+					$c_x_type = count($event['x_type']);
+					for($j=0;$j<$c_x_type;$j++)
+					{
+						$str .= ';'.$this->build_xtype($event['x_type'][$j],'=');
+					}
+				}
+				if(!empty($event['value']))
+				{
+					if($property == 'trigger')
+					{
+						$seperator = ';';
+					}
+					else
+					{
+						$seperator = ':';
+					}
+					$str .= $seperator.($this->parameter['value']['to_text']?$this->to_text($event['value']):$event['value']);
+				}
+				if($include_mailto == True)
+				{
+					$key = 'mailto';
+					$function = $this->parameter[$key]['function'];
+					$ret_value = $this->$function($event[$key]);
+					$str .= ($ret_value?':'.$ret_value:'');
+				}
+				if($include_datetime == True || @$this->property[$property]['type'] == 'date-time')
+				{
+					$str .= ':'.date('Ymd\THis',mktime($event['hour'],$event['min'],$event['sec'],$event['month'],$event['mday'],$event['year'])).(!@isset($event['tzid'])?'Z':'');
+				}
+				return ($property=='rrule'?':'.substr($str,1):$str);
+			}
+		}
+
+		function build_text($event,$property)
+		{
+			$str = '';
+			$param = $this->find_parameters($property);
+			while(list($dumb_key,$key) = each($param))
+			{
+				if(!empty($event[$key]) && $key != 'value')
+				{
+					$type = @$this->parameter[$key]['type'];
+					$quote = @$this->parameter[$key]['quote'];
+					if(@$this->parameter[$key]['to_text'] == True)
+					{
+						$value = $this->to_text($event[$key]);
+					}
+					else
+					{
+						$value = $event[$key];
+					}
+					switch($type)
+					{
+						case 'text':
+						$str .= ';'.strtoupper($key).'='.$quote.$value.$quote;
+						break;
+					}
+				}
+			}
+			if(!empty($event['x_type']))
+			{
+				$c_x_type = count($event['x_type']);
+				for($j=0;$j<$c_x_type;$j++)
+				{
+					$str .= ';'.$this->build_xtype($event['x_type'][$j],'=');
+				}
+			}
+			if(!empty($event['value']))
+			{
+				$str .= ':'.($this->parameter['value']['to_text']?$this->to_text($event['value']):$event['value']);
+			}
+			return $str;
+		}
+
+		function build_card_internals($ical_item,$event)
+		{
+			$prop = $this->find_properties($ical_item);
+			reset($prop);
+			while(list($dumb_key,$key) = each($prop))
+			{
+				$value  = $key;
+				$varray = $this->property[$key];
+				$type   = $varray['type'];
+				$to_text = $varray['to_text'];
+				$state  = @$varray[$ical_item]['state'];
+				$multiples  = @$varray[$ical_item]['multiples'];
+				switch($type)
+				{
+					case 'date-time':
+						if(!empty($event[$value]))
+						{
+							if($multiples && $value != 'exdate')
+							{
+								for($i=0;$i<count($event[$value]);$i++)
+								{
+									$str .= $this->fold(strtoupper(str_replace('_','-',$value)).$this->build_parameters($event[$value][$i],$value));
+								}
+							}
+							else
+							{
+								$str .= $this->fold(strtoupper(str_replace('_','-',$value)).$this->build_parameters($event[$value],$value));
+							}
+						}
+						elseif($value == 'dtstamp' || $value == 'created')
+						{
+							$str .= $this->fold(strtoupper(str_replace('_','-',$value)).':'.gmdate('Ymd\THis\Z'));
+						}
+						break;
+					case 'uri':
+						if(!empty($event[$value]))
+						{
+							for($i=0;$i<count($event[$value]);$i++)
+							{
+								$str .= $this->fold(strtoupper(str_replace('_','-',$value)).$this->build_parameters($event[$value][$i],$to_text));
+							}
+						}
+						break;
+					case 'recur':
+						if(!empty($event[$value]))
+						{
+							if($multiples)
+							{
+								for($i=0;$i<count($event[$value]);$i++)
+								{
+									$str .= $this->fold(strtoupper(str_replace('_','-',$value)).$this->build_parameters($event[$value][$i],$value));
+								}
+							}
+							else
+							{
+								$str .= $this->fold(strtoupper(str_replace('_','-',$value)).$this->build_parameters($event[$value],$value));
+							}
+						}
+						break;
+					case 'integer':
+						if(!empty($event[$value]))
+						{
+							$str .= $this->fold(strtoupper(str_replace('_','-',$value)).':'.$event[$value]);
+						}
+						elseif($value == 'sequence' || $value == 'percent_complete')
+						{
+							$str .= $this->fold(strtoupper(str_replace('_','-',$value)).':0');
+						}
+						break;
+					case 'function':
+						$str .= ';'.str_replace('_','-',strtoupper($value)).'=';
+						$function = @$this->parameter[$key]['function'];
+						$str .= (@$this->parameter[$key]['quoted']?'"':'').$this->$function($event[$key]).(@$this->parameter[$key]['quoted']?'"':'');
+						break;
+					case 'float':
+						if(!empty($event[$value]))
+						{
+							$str .= $this->fold(strtoupper(str_replace('_','-',$value)).':'.$event[$value]['lat'].';'.$event[$value]['lon']);
+						}
+						break;
+					case 'text':
+						if(isset($event[$value]))
+						{
+							if(@$this->parameter[$key]['type'] != 'function')
+							{
+								if($multiples && count($event[$value]) > 1)
+								{
+									for($i=0;$i<count($event[$value]);$i++)
+									{
+										$str .= $this->fold(strtoupper(str_replace('_','-',$value)).$this->build_parameters($event[$value][$i],$value));
+									}
+								}
+								else
+								{
+									$str .= $this->fold(strtoupper(str_replace('_','-',$value)).$this->build_parameters($event[$value],$value));
+								}
+							}
+							else
+							{
+								$function = $this->parameter[$value]['function'];
+								if($multiples)
+								{
+									for($i=0;$i<count($event[$value]);$i++)
+									{
+										$str .= $this->fold(strtoupper(str_replace('_','-',$value)).':'.$this->$function($event[$value][$i]));
+									}
+								}
+								else
+								{
+									$str .= $this->fold(strtoupper(str_replace('_','-',$value)).':'.$this->$function($event[$value]));
+								}
+							}
+						}
+						break;
+					case 'cal-address':
+						if(is_array($event[$value][0]))
+						{
+							for($j=0;$j<count($event[$value]);$j++)
+							{
+								$temp_output = $this->build_parameters($event[$value][$j],$value);
+								if($temp_output)
+								{
+									$str .= $this->fold(strtoupper(str_replace('_','-',$value)).$temp_output);
+								}
+							}
+						}
+						else
+						{
+							$temp_output = $this->build_parameters($event[$value],$value);
+							if($temp_output)
+							{
+								$str .= $this->fold(strtoupper(str_replace('_','-',$value)).$temp_output);
+							}
+						}
+						break;
+				}
+			}
+			if(!empty($event['x_type']))
+			{
+				for($i=0;$i<count($event['x_type']);$i++)
+				{
+					$str .= $this->build_xtype($event['x_type'][$i],':');
+				}
+			}
+
+			if($ical_item == 'vtimezone')
+			{
+				if($event['tzdata'])
+				{
+					for($k=0;$k<count($event['tzdata']);$k++)
+					{
+						$str .= 'BEGIN:'.strtoupper($event['tzdata'][$k]['type'])."\r\n";
+						$str .= $this->build_card_internals(strtolower($event['tzdata'][$k]['type']),$event['tzdata'][$k]);
+						$str .= 'END:'.strtoupper($event['tzdata'][$k]['type'])."\r\n";
+					}
+				}
+			}
+			elseif($event['alarm'])
+			{
+				for($k=0;$k<count($event['alarm']);$k++)
+				{
+					$str .= 'BEGIN:VALARM'."\r\n";
+					$str .= $this->build_card_internals('valarm',$event['alarm'][$k]);
+					$str .= 'END:VALARM'."\r\n";
+				}
+			}
+			return $str;
+		}
+
+		/*
+		* Switching Functions
+		*/
+
+		function switch_class($var)
+		{
+			if(is_string($var))
+			{
+				switch($var)
+				{
+					case '_PRIVATE':
+						$var = _PRIVATE;
+						break;
+					case '_PUBLIC':
+						$var = _PUBLIC;
+						break;
+					case '_CONFIDENTIAL':
+						$var = _CONFIDENTIAL;
+						break;
+				}
+			}
+			elseif(is_int($var))
+			{
+				switch((int)$var)
+				{
+					case _PRIVATE:
+						$var = '_PRIVATE';
+						break;
+					case _PUBLIC:
+						$var = '_PUBLIC';
+						break;
+					case _CONFIDENTIAL:
+						$var = '_CONFIDENTIAL';
+						break;
+				}
+			}
+			return $var;
+		}
+
+		function switch_cu($var)
+		{
+			if(gettype($var) == 'string')
+			{
+				switch($var)
+				{
+					case 'INDIVIDUAL':
+						return INDIVIDUAL;
+						break;
+					case 'GROUP':
+						return GROUP;
+						break;
+					case 'RESOURCE':
+						return RESOURCE;
+						break;
+					case 'ROOM':
+						return ROOM;
+						break;
+					case 'UNKNOWN':
+						return UNKNOWN;
+						break;
+					default:
+						return OTHER;
+						break;
+				}
+			}
+			elseif(gettype($var) == 'integer')
+			{
+				switch($var)
+				{
+					case INDIVIDUAL:
+						return 'INDIVIDUAL';
+						break;
+					case GROUP:
+						return 'GROUP';
+						break;
+					case RESOURCE:
+						return 'RESOURCE';
+						break;
+					case ROOM:
+						return 'ROOM';
+						break;
+					case UNKNOWN:
+						return 'UNKNOWN';
+						break;
+					default:
+						return 'X-OTHER';
+						break;
+				}
+			}
+			else
+			{
+				return $var;
+			}
+		}
+
+		function switch_date($var)
+		{
+		$this->debug('SWITCH_DATE: gettype = '.gettype($var));
+			if(is_string($var))
+			{
+				$dtime = Array();
+				if(strpos($var,':'))
+				{
+					$pos = explode(':',$var);
+					$var = $pos[1];
+				}
+				$this->set_var($dtime,'year',(int)(substr($var,0,4)));
+				$this->set_var($dtime,'month',(int)(substr($var,4,2)));
+				$this->set_var($dtime,'mday',(int)(substr($var,6,2)));
+				if(substr($var,8,1) == 'T')
+				{
+					$this->set_var($dtime,'hour',(int)(substr($var,9,2)));
+					$this->set_var($dtime,'min',(int)(substr($var,11,2)));
+					$this->set_var($dtime,'sec',(int)(substr($var,13,2)));
+					if(strlen($var) > 14)
+					{
+						if(substr($var,14,1) != 'Z')
+						{
+							if($this->api)
+							{
+								$dtime['hour'] -= $GLOBALS['phpgw_info']['users']['common']['tz_offset'];
+								if($dtime['hour'] < 0)
+								{
+									$dtime['mday'] -= 1;
+									$dtime['hour'] = 24 - $dtime['hour'];
+								}
+								elseif($dtime['hour'] >= 24)
+								{
+									$dtime['mday'] += 1;
+									$dtime['hour'] = $dtime['hour'] - 24;
+								}
+							}
+						}
+					}
+					else
+					{
+						/*
+						* The time provided by the iCal is considered local time.
+						*
+						* The implementor will need to consider how to convert that time to UTC.
+						*/
+						//					if($this->api)
+						//					{
+						//						$dtime['hour'] -= $GLOBALS['phpgw_info']['users']['common']['tz_offset'];
+						//						if($dtime['hour'] < 0)
+						//						{
+						//							$dtime['mday'] -= 1;
+						//							$dtime['hour'] = 24 - $dtime['hour'];
+						//						}
+						//						elseif($dtime['hour'] >= 24)
+						//						{
+						//							$dtime['mday'] += 1;
+						//							$dtime['hour'] = $dtime['hour'] - 24;
+						//						}
+						//					}
+					}
+				}
+				else
+				{
+					$this->set_var($dtime,'hour',0);
+					$this->set_var($dtime,'min',0);
+					$this->set_var($dtime,'sec',0);
+					if($this->api)
+					{
+						$dtime['hour'] -= $GLOBALS['phpgw_info']['users']['common']['tz_offset'];
+						if($dtime['hour'] < 0)
+						{
+							$dtime['mday'] -= 1;
+							$dtime['hour'] = 24 - $dtime['hour'];
+						}
+						elseif($dtime['hour'] >= 24)
+						{
+							$dtime['mday'] += 1;
+							$dtime['hour'] = $dtime['hour'] - 24;
+						}
+					}
+				}
+				$this->debug('DATETIME : '._debug_array($dtime,False));
+				return $dtime;
+			}
+			elseif(is_array($var))
+			{
+				return date('Ymd\THis\Z',mktime($var['hour'],$var['min'],$var['sec'],$var['month'],$var['mday'],$var['year']));
+			}
+			else
+			{
+				return $var;
+			}
+		}
+
+		function switch_encoding($var)
+		{
+			if(is_string($var))
+			{
+				switch($var)
+				{
+					case '8BIT':
+						return _8BIT;
+						break;
+					case 'BASE64':
+						return _BASE64;
+						break;
+					default:
+						return OTHER;
+						break;
+				}
+			}
+			elseif(is_int($var))
+			{
+				switch($var)
+				{
+					case _8BIT:
+						return '8BIT';
+						break;
+					case _BASE64:
+						return 'BASE64';
+						break;
+					case OTHER:
+						return 'OTHER';
+						break;
+				}
+			}
+			else
+			{
+				return $var;
+			}
+		}
+
+		function switch_fbtype($var)
+		{
+			if(is_string($var))
+			{
+				switch($var)
+				{
+					case 'FREE':
+						return FREE;
+						break;
+					case 'BUSY':
+						return BUSY;
+						break;
+					case 'BUSY-UNAVAILABLE':
+						return BUSY_UNAVAILABLE;
+						break;
+					case 'BUSY-TENTATIVE':
+						return BUSY_TENTATIVE;
+						break;
+					default:
+						return OTHER;
+						break;
+				}
+			}
+			elseif(is_int($var))
+			{
+				switch($var)
+				{
+					case FREE:
+						return 'FREE';
+						break;
+					case BUSY:
+						return 'BUSY';
+						break;
+					case BUSY_UNAVAILABLE:
+						return 'BUSY-UNAVAILABLE';
+						break;
+					case BUSY_TENTATIVE:
+						return 'BUSY-TENTATIVE';
+						break;
+					default:
+						return 'OTHER';
+						break;
+				}
+			}
+			else
+			{
+				return $var;
+			}
+		}
+
+		function switch_freq($var)
+		{
+			if(is_string($var))
+			{
+				switch($var)
+				{
+					case 'SECONDLY':
+						return SECONDLY;
+						break;
+					case 'MINUTELY':
+						return MINUTELY;
+						break;
+					case 'HOURLY':
+						return HOURLY;
+						break;
+					case 'DAILY':
+						return DAILY;
+						break;
+					case 'WEEKLY':
+						return WEEKLY;
+						break;
+					case 'MONTHLY':
+						return MONTHLY;
+						break;
+					case 'YEARLY':
+						return YEARLY;
+						break;
+				}
+			}
+			elseif(is_int($var))
+			{
+				switch($var)
+				{
+					case SECONDLY:
+						return 'SECONDLY';
+						break;
+					case MINUTELY:
+						return 'MINUTELY';
+						break;
+					case HOURLY:
+						return 'HOURLY';
+						break;
+					case DAILY:
+						return 'DAILY';
+						break;
+					case WEEKLY:
+						return 'WEEKLY';
+						break;
+					case MONTHLY:
+						return 'MONTHLY';
+						break;
+					case YEARLY:
+						return 'YEARLY';
+						break;
+				}
+			}
+			else
+			{
+				return $var;
+			}
+		}
+
+		function switch_mailto($var)
+		{
+			if(is_string($var))
+			{
+				if(strpos(' '.$var,':'))
+				{
+					$parts = explode(':',$var);
+					$var = $parts[1];
+				}
+
+				$parts = explode('@',$var);
+				$this->debug("Count of mailto parts : ".count($parts));
+				if(count($parts) == 2)
+				{
+					$this->debug("Splitting ".$parts[0]." @ ".$parts[1]);
+					$temp_address = Array();
+					$temp_address['user'] = $parts[0];
+					$temp_address['host'] = $parts[1];
+					return $temp_address;
+				}
+				else
+				{
+					return False;
+				}
+			}
+			elseif(is_array($var))
+			{
+//				return 'MAILTO:'.$var['user'].'@'.$var['host'];
+				return $var['user'].'@'.$var['host'];
+			}
+		}
+
+		function switch_partstat($var)
+		{
+//			$this->debug_str = True;
+			$this->debug('PARTSTAT = '.$var);
+//			$this->debug_str = False;
+			if(is_string($var))
+			{
+				switch($var)
+				{
+					case 'NEEDS-ACTION':
+						return 0; // NEEDS_ACTION;
+						break;
+					case 'ACCEPTED':
+						return 1; // ACCEPTED;
+						break;
+					case 'DECLINED':
+						return 2; // DECLINED;
+						break;
+					case 'TENTATIVE':
+						return 3; // TENTATIVE;
+						break;
+					case 'DELEGATED':
+						return 4; // DELEGATED;
+						break;
+					case 'COMPLETED':
+						return 5; // COMPLETED;
+						break;
+					case 'IN-PROCESS':
+						return 6; // IN_PROCESS;
+						break;
+					default:
+						return 99; // OTHER;
+						break;
+				}
+			}
+			elseif(is_int($var))
+			{
+				switch((int)$var)
+				{
+					case 0: // NEEDS_ACTION:
+						return 'NEEDS-ACTION';
+						break;
+					case 1: //  ACCEPTED:
+						return 'ACCEPTED';
+						break;
+					case 2: // DECLINED:
+						return 'DECLINED';
+						break;
+					case 3: // TENTATIVE:
+						return 'TENTATIVE';
+						break;
+					case 4: // DELEGATED:
+						return 'DELEGATED';
+						break;
+					case 5: // COMPLETED:
+						return 'COMPLETED';
+						break;
+					case 6: // IN_PROCESS:
+						return 'IN-PROCESS';
+						break;
+					default:
+						return 'X-OTHER';
+						break;
+				}
+			}
+			else
+			{
+				return $var;
+			}
+		}
+
+		function switch_range($var)
+		{
+			if(is_string($var))
+			{
+				switch($var)
+				{
+					case 'THISANDPRIOR':
+						return THISANDPRIOR;
+						break;
+					case 'THISANDFUTURE':
+						return THISANDFUTURE;
+						break;
+				}
+			}
+			elseif(is_int($var))
+			{
+				switch($var)
+				{
+					case THISANDPRIOR:
+						return 'THISANDPRIOR';
+						break;
+					case THISANDFUTURE:
+						return 'THISANDFUTURE';
+						break;
+				}
+			}
+			else
+			{
+				return $var;
+			}
+		}
+
+		function switch_related($var)
+		{
+			if(is_string($var))
+			{
+				switch($var)
+				{
+					case 'START':
+						return START;
+						break;
+					case 'END':
+						return END;
+						break;
+				}
+			}
+			elseif(is_int($var))
+			{
+				switch($var)
+				{
+					case START:
+						return 'START';
+						break;
+					case END:
+						return 'END';
+						break;
+				}
+			}
+			else
+			{
+				return $var;
+			}
+		}
+
+		function switch_reltype($var)
+		{
+			if(is_string($var))
+			{
+				switch($var)
+				{
+					case 'PARENT':
+						return PARENT;
+						break;
+					case 'CHILD':
+						return CHILD;
+						break;
+					case 'SIBLING':
+						return SIBLING;
+						break;
+				}
+			}
+			elseif(is_int($var))
+			{
+				switch($var)
+				{
+					case PARENT:
+						return 'PARENT';
+						break;
+					case CHILD:
+						return 'CHILD';
+						break;
+					case SIBLING:
+						return 'SIBLING';
+						break;
+				}
+			}
+			else
+			{
+				return $var;
+			}
+		}
+
+		function switch_role($var)
+		{
+			if(is_string($var))
+			{
+				switch($var)
+				{
+					case 'NONE':
+						return NONE;
+						break;
+					case 'CHAIR':
+						return CHAIR;
+						break;
+					case 'REQ-PARTICIPANT':
+						return REQ_PARTICIPANT;
+						break;
+					case 'OPT-PARTICIPANT':
+						return OPT_PARTICIPANT;
+						break;
+					case 'NON-PARTICIPANT':
+						return NON_PARTICIPANT;
+						break;
+				}
+			}
+			elseif(is_int($var))
+			{
+				switch($var)
+				{
+					case NONE:
+						return 'NONE';
+						break;
+					case CHAIR:
+						return 'CHAIR';
+						break;
+					case REQ_PARTICIPANT:
+						return 'REQ-PARTICIPANT';
+						break;
+					case OPT_PARTICIPANT:
+						return 'OPT-PARTICIPANT';
+						break;
+					case NON_PARTICIPANT:
+						return 'NON-PARTICIPANT';
+						break;
+				}
+			}
+			else
+			{
+				return $var;
+			}
+		}
+
+		function switch_rsvp($var)
+		{
+			if(is_string($var))
+			{
+				if($var == 'TRUE')
+				{
+					return 1;
+				}
+				elseif($var == 'FALSE')
+				{
+					return 0;
+				}
+			}
+			elseif(is_int($var) || $var == False)
+			{
+				if($var == 1)
+				{
+					return 'TRUE';
+				}
+				elseif($var == 0)
+				{
+					return 'FALSE';
+				}
+			}
+			else
+			{
+				return $var;
+			}
+		}
+
+		function switch_transp($var)
+		{
+			if(is_string($var))
+			{
+				switch($var)
+				{
+					case 'TRANSPARENT':
+						return TRANSPARENT;
+						break;
+					case 'OPAQUE':
+						return OPAQUE;
+						break;
+				}
+			}
+			elseif(is_int($var))
+			{
+				switch($var)
+				{
+					case TRANSPARENT:
+						return 'TRANSPARENT';
+						break;
+					case OPAQUE:
+						return 'OPAQUE';
+						break;
+				}
+			}
+			else
+			{
+				return $var;
+			}
+		}
+
+		/*
+		 * The brunt of the class
+		 */
+
+		function parse($ical_text)
+		{
+			$begin_regexp = '^';
+			$semi_colon_regexp = '[\;\:]';
+			$colon_regexp = '[\:]';
+			$catch_all_regexp = '(.*)';
+			$end_regexp = '$';
+			$property_regexp = $begin_regexp.'([A-Z\-]*)'.$semi_colon_regexp.$catch_all_regexp.$end_regexp;
+			$param_regexp = $begin_regexp.$catch_all_regexp.':'.$catch_all_regexp.$end_regexp;
+
+			$mode = 'none';
+			$text = $this->read_line_unfold($ical_text);
+			while($text)
+			{
+//				if(strlen($ical_text[$i]) > 75)
+//				{
+//					continue;
+//				}
+
+				ereg($property_regexp,$text,$temp);
+				$majortype = str_replace('-','_',strtolower($temp[1]));
+				$value = chop($temp[2]);
+
+				if($mode != 'none' && ($majortype != 'begin' && $majortype != 'end'))
+				{
+					$this->debug('PARSE:MAJORTYPE : '.$majortype);
+					if(isset($this->property[$majortype]))
+					{
+						$state = @$this->property[$majortype]["$mode"]['state'];
+						$type = @$this->property[$majortype]['type'];
+						$multiples = @$this->property[$majortype]["$mode"]['multiples'];
+						$do_to_text = @$this->property[$majortype]['to_text'];
+					}
+					elseif(substr($majortype,0,2) == 'x_')
+					{
+						$state = 'optional';
+						$type = 'xtype';
+						$multiples = True;
+						$do_to_test = True;
+					}
+					else
+					{
+						$state = '';
+					}
+				}
+				else
+				{
+					$state = 'required';
+				}
+
+				if($majortype == 'duration')
+				{
+					// Unset dur var
+					unset($dur);
+
+					// Split «DURATION»
+					list($_f_['day_raw'], $_f_['time_raw']) = split('T', substr($value, 1, strlen($value)-1));
+
+					/* Datecode */
+					if(isset($_f_['day_raw']) OR $_f_['day_raw'])
+					{
+						// Days
+//						if(ereg('D', $_f_['day_raw']))
+						if(strstr($_f_['day_raw'],'D'))
+						{
+							$dur['days'] = eregi_replace("([0-9]+)D(.*)", "\\1", $_f_['day_raw']);
+						}
+
+						// Weeks
+//						if(ereg("W", $_f_["day_raw"]))
+						if(strstr($_f_['day_raw'],'W'))
+						{
+							$dur['weeks'] = eregi_replace("([^|.*]+D)?([0-9]+)W", "\\2", $_f_['day_raw']);
+						}
+					}
+
+					/* Timecode */
+					if(isset($_f_['time_raw']) OR $_f_['time_raw'])
+					{
+						// Hours
+//						if(ereg("H", $_f_["time_raw"]))
+						if(strstr($_f_['time_raw'],'H'))
+						{
+							$dur['hours'] = eregi_replace("([0-9]+)H(.*)", "\\1", $_f_['time_raw']);
+						}
+
+						// Minutes
+						/* If you find better, contact me very quickly :) */
+//						if(ereg("M", $_f_["time_raw"]))
+						if(strstr($_f_['time_raw'],'M'))
+						{
+							$dur['minutes'] = eregi_replace("([^|.*]+H)?([0-9]+)M(.*)", "\\2", $_f_['time_raw']);
+						}
+
+						// Seconds
+						/* Same comment :) */
+//						if(ereg("S", $_f_["time_raw"]) )
+						if(strstr($_f_['time_raw'],'S'))
+						{
+							$dur['seconds'] = eregi_replace("([^|.*]+M)?([0-9]+)S(.*)", "\\2", $_f_['time_raw']);
+						}
+					}
+
+					$dur['raw'] = Array(
+						'timecode' => $_f_['time_raw'],
+						'datecode' => $_f_['day_raw'],
+						'all'      => $value
+					);
+					// Add new parameters in Event
+					$this->set_var($event, $majortype, $dur);
+				}
+
+				if($majortype == 'begin')
+				{
+					$tmode = $mode;
+					$mode = strtolower($value);
+					switch(strtolower($value))
+					{
+						case 'daylight':
+						case 'standard':
+							$t_event = Array();
+							$t_event = $event;
+							$event = Array();
+							break;
+						case 'valarm':
+							if($tmode == 'vevent' || $tmode == 'vtodo')
+							{
+								$t_event = $event;
+								unset($event);
+								$event = Array();
+							}
+							else
+							{
+								$mode = $tmode;
+							}
+							break;
+						case 'vcalendar':
+							$ical = $this->new_ical();
+							break;
+						case 'vevent':
+						case 'vfreebusy':
+						case 'vjournal':
+						case 'vtimezone':
+						case 'vtodo':
+							$event = Array();
+							break;
+					}
+					$event['type'] = strtolower($value);
+				}
+				elseif($majortype == 'end')
+				{
+					$mode = 'none';
+					switch(strtolower($value))
+					{
+						case 'daylight':
+						case 'standard':
+							$tzdata[] = $event;
+							unset($event);
+							$event = $t_event;
+							unset($t_event);
+							$mode = 'vtimezone';
+							break;
+						case 'valarm':
+							$alarm[] = $event;
+							unset($event);
+							$event = $t_event;
+							unset($t_event);
+							$mode = $tmode;
+							break;
+						case 'vevent':
+							if(!empty($alarm))
+							{
+								$event['alarm'] = $alarm;
+								unset($alarm);
+							}
+							$this->event[] = $event;
+							unset($event);
+							break;
+						case 'vfreebusy':
+							$this->freebusy[] = $event;
+							unset($event);
+							break;
+						case 'vjournal':
+							$this->journal[] = $event;
+							unset($event);
+							break;
+						case 'vtimezone':
+							if(!empty($tzdata))
+							{
+								$event['tzdata'] = $tzdata;
+								unset($tzdata);
+							}
+							$this->timezone[] = $event;
+							unset($event);
+							break;
+						case 'vtodo':
+							if(!empty($alarm))
+							{
+								$event['alarm'] = $alarm;
+								unset($alarm);
+							}
+							$this->todo[] = $event['alarm'];
+							unset($event);
+							break;
+						case 'vcalendar':
+							$this->ical = $ical;
+							$this->ical['event'] = $this->event;
+							$this->ical['freebusy'] = $this->freebusy;
+							$this->ical['journal'] = $this->journal;
+							$this->ical['timezone'] = $this->timezone;
+							$this->ical['todo'] = $this->todo;
+							break 2;
+					}
+				}
+				elseif($majortype == 'prodid' || $majortype == 'version' || $majortype == 'method' || $majortype == 'calscale')
+				{
+					$this->parse_parameters($ical,$majortype,$this->from_text($value));
+				}
+				elseif($state == 'optional' || $state == 'required')
+				{
+					$this->debug('Mode : '.$mode.' Majortype : '.$majortype);
+					if($do_to_text)
+					{
+						$value = $this->from_text($value);
+					}
+					switch($type)
+					{
+						case 'text':
+							$this->parse_parameters($event,$majortype,$value);
+							break;
+						case 'recur':
+						case 'date-time':
+						case 'cal-address':
+							$this->parse_value($event,$majortype,$value,$mode);
+							break;
+						case 'integer':
+							if($multiples)
+							{
+								$event[$majortype][] = (int)$value;
+							}
+							else
+							{
+								$this->set_var($event,$majortype,(int)$value);
+							}
+							break;
+						case 'float':
+							$event->$majortype = new class_geo;
+							$this->parse_geo($event->$majortype,$value);
+							break;
+						case 'utc-offset':
+							$this->set_var($event,$majortype,(int)$value);
+							break;
+						case 'uri':
+							$new_var = Array();
+							$this->parse_parameters($new_var,$majortype,$value);
+							if($multiples)
+							{
+								switch($mode)
+								{
+									case 'valarm':
+										$alarm['attach'][] = $new_var;
+										break;
+									default:
+										$event[$majortype][] = $new_var;
+										break;
+								}
+							}
+							else
+							{
+								$event[$majortype] = $new_var;
+							}
+							unset($new_var);
+							break;
+						case 'xtype':
+							$this->parse_xtype($event,$majortype,$value);
+							break;
+					}
+				}
+				$text = $this->read_line_unfold($ical_text);
+			}
+			return $this->ical;
+		}
+
+
+		function switch_to_phpgw_status($partstat)
+		{
+			switch($partstat)
+			{
+				case 0:
+					return 'U';
+					break;
+				case 1:
+					return 'A';
+					break;
+				case 2:
+					return 'R';
+					break;
+				case 3:
+					return 'T';
+					break;
+				default:
+					return 'U';
+					break;
+			}
+		}
+
+		function switch_phpgw_status($status)
+		{
+			switch($status)
+			{
+				case 'U':
+					return 0;
+					break;
+				case 'A':
+					return 1;
+					break;
+				case 'R':
+					return 2;
+					break;
+				case 'T':
+					return 3;
+					break;
+			}
+		}
+
+		function is_owner($part_record)
+		{
+			if(($part_record['user'].'@'.$part_record['host'] == $GLOBALS['phpgw_info']['user']['preferences']['email']['address']) ||
+				($part_record['cn'] == $GLOBALS['phpgw_info']['user']['account_lid']))
+			{
+				return True;
+			}
+			else
+			{
+				return False;
+			}
+		}
+
+		function check_owner(&$event,$ical,$so_event)
+		{
+			if(!isset($event['participant'][$GLOBALS['phpgw_info']['user']['account_id']]))
+			{
+				if(isset($ical['organizer']))
+				{
+					if($this->is_owner($ical['organizer']))
+					{
+						$so_event->add_attribute('owner',$GLOBALS['phpgw_info']['user']['account_id']);
+						$so_event->add_attribute('participants',$this->switch_to_phpgw_status($ical['organizer']['partstat']),$GLOBALS['phpgw_info']['user']['account_id']);
+					}
+				}
+				elseif(isset($ical['attendee']))
+				{
+					$attendee_count = count($ical['attendee']);
+
+					for($j=0;$j<$attendee_count;$j++)
+					{
+						if($this->is_owner($ical['attendee'][$j]))
+						{
+							$so_event->add_attribute('participants',$this->switch_to_phpgw_status($ical['attendee'][$j]['partstat']),(int)$GLOBALS['phpgw_info']['user']['account_id']);
+						}
+					}
+				}
+				else
+				{
+					$so_event->add_attribute('owner',$GLOBALS['phpgw_info']['user']['account_id']);
+					$so_event->add_attribute('participants','A',$GLOBALS['phpgw_info']['user']['account_id']);
+				}
+			}
+		}
+
+		function import_file()
+		{
+			if($_FILES['uploadedfile']['tmp_name'] == 'none' || $_FILES['uploadedfile']['tmp_name'] == '')
+			{
+				Header('Location: ' . $GLOBALS['phpgw']->link('/index.php',
+						Array(
+							'menuaction'	=> 'calendar.uiicalendar.import',
+							'action'	=> 'GetFile'
+						)
+					)
+				);
+				$GLOBALS['phpwg']->common->phpgw_exit();
+			}
+			$uploaddir = $GLOBALS['phpgw_info']['server']['temp_dir'] . SEP;
+
+			srand((double)microtime()*1000000);
+			$random_number = rand(100000000,999999999);
+			$newfilename = md5($_FILES['uploadedfile']['tmp_name'].", ".$uploadedfile_name.", "
+				. time() . getenv("REMOTE_ADDR") . $random_number );
+
+			$filename = $uploaddir . $newfilename;
+
+			move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $filename);
+//			$ftp = fopen($uploaddir . $newfilename . '.info','wb');
+//			fputs($ftp,$uploadedfile_type."\n".$uploadedfile_name."\n");
+//			fclose($ftp);
+			return $filename;
+		}
+
+		function import($mime_msg='', $from_ajax = false)
+		{
+			if($_FILES['uploadedfile']['tmp_name'] != 'none' && $_FILES['uploadedfile']['tmp_name'] != '')
+			{
+				$filename = $this->import_file();
+				$fp=fopen($filename,'rt');
+				$mime_msg = explode("\n",fread($fp, filesize($filename)));
+				fclose($fp);
+				unlink($filename);
+			}
+			elseif(!$mime_msg)
+			{
+				Header('Location: ' . $GLOBALS['phpgw']->link('/index.php',
+						Array(
+							'menuaction'	=> 'calendar.uiicalendar.import',
+							'action'	=> 'GetFile'
+						)
+					)
+				);
+				$GLOBALS['phpwg']->common->phpgw_exit();
+			}
+
+			if(!is_object($GLOBALS['uicalendar']))
+			{
+				$so_event = createobject('calendar.socalendar',
+					Array(
+						'owner'	=> 0,
+						'filter'	=> '',
+						'category'	=> ''
+					)
+				);
+			}
+			else
+			{
+				$so_event = $GLOBALS['uicalendar']->bo->so;
+			}
+
+			$datetime_vars = Array(
+				'start'	=> 'dtstart',
+				'end'	=> 'dtend',
+				'modtime'	=> 'dtstamp',
+				'modtime'	=> 'last_modified'
+			);
+
+			$date_array = Array(
+				'Y'	=> 'year',
+				'm'	=> 'month',
+				'd'	=> 'mday',
+				'H'	=> 'hour',
+				'i'	=> 'min',
+				's'	=> 'sec'
+			);
+
+			// time limit should be controlled elsewhere
+			@set_time_limit(0);
+
+			$GLOBALS['phpgw_info']['user']['preferences'] = $GLOBALS['phpgw']->preferences->create_email_preferences();
+			$users_email = $GLOBALS['phpgw_info']['user']['preferences']['email']['address'];
+			$cats = CreateObject('phpgwapi.categories');
+			$ical = $this->parse($mime_msg);
+			switch($ical['version']['value'])
+			{
+				case '1.0':
+					$cat_sep = ';';
+					break;
+				case '2.0':
+				default:
+					$cat_sep = ',';
+					break;
+			}
+			$c_events = count($ical['event']);
+			for($i=0;$i<$c_events;$i++)
+			{
+				if($ical['event'][$i]['uid']['value'])
+				{
+					$uid_exists = $so_event->find_uid($ical['event'][$i]['uid']['value']);
+				}
+				else
+				{
+					$uid_exists = False;
+				}
+				if($uid_exists)
+				{
+					$event = $so_event->read_entry($uid_exists);
+					$this->check_owner($event,$ical['event'][$i],$so_event);
+					$event = $so_event->get_cached_event();
+					$so_event->add_entry($event);
+//					$event = $so_event->get_cached_event();
+				}
+				else
+				{
+					$so_event->event_init();
+					$so_event->add_attribute('id',0);
+					$so_event->add_attribute('reference',0);
+					if($ical['event'][$i]['uid']['value'])
+					{
+						$so_event->add_attribute('uid',$ical['event'][$i]['uid']['value']);
+					}
+					if($ical['event'][$i]['summary']['value'])
+					{
+						$so_event->set_title($ical['event'][$i]['summary']['value']);
+					}
+					if($ical['event'][$i]['description']['value'])
+					{
+						$so_event->set_description($ical['event'][$i]['description']['value']);
+					}
+					if($ical['event'][$i]['ex_participants']['value'])
+					{
+						$so_event->set_ex_participants($ical['event'][$i]['ex_participants']['value']);
+					}
+					if($ical['event'][$i]['location']['value'])
+					{
+						$so_event->add_attribute('location',$ical['event'][$i]['location']['value']);
+					}
+					if(isset($ical['event'][$i]['priority']))
+					{
+						$so_event->add_attribute('priority',$ical['event'][$i]['priority']);
+					}
+					else
+					{
+						$so_event->add_attribute('priority',2);
+					}
+					if(!isset($ical['event'][$i]['class']))
+					{
+						$ical['event'][$i]['class'] = 1;
+					}
+					$so_event->set_class($ical['event'][$i]['class']);
+
+					@reset($datetime_vars);
+					while(list($e_datevar,$i_datevar) = each($datetime_vars))
+					{
+						if(isset($ical['event'][$i][$i_datevar]))
+						{
+							$temp_time = $so_event->maketime($ical['event'][$i][$i_datevar]) + $GLOBALS['phpgw']->datetime->tz_offset;
+							@reset($date_array);
+							while(list($key,$var) = each($date_array))
+							{
+								$event[$e_datevar][$var] = (int)(date($key,$temp_time));
+							}
+							$so_event->set_date($e_datevar,$event[$e_datevar]['year'],$event[$e_datevar]['month'],$event[$e_datevar]['mday'],$event[$e_datevar]['hour'],$event[$e_datevar]['min'],$event[$e_datevar]['sec']);
+						}
+					}
+					if(!isset($ical['event'][$i]['categories']['value']) || !$ical['event'][$i]['categories']['value'])
+					{
+						$so_event->set_category(0);
+					}
+					else
+					{
+						$ical_cats = Array();
+						if(strpos($ical['event'][$i]['categories']['value'],$cat_sep))
+						{
+							$ical_cats = explode($cat_sep,$ical['event'][$i]['categories']['value']);
+						}
+						else
+						{
+							$ical_cats[] = $ical['event'][$i]['categories']['value'];
+						}
+
+						@reset($ical_cats);
+						$cat_id_nums = Array();
+						while(list($key,$cat) = each($ical_cats))
+						{
+							if(!$cats->exists('appandmains',$cat))
+							{
+								$cats->add(
+									Array(
+										'name'	=> $cat,
+										'descr'	=> $cat,
+										'parent'	=> '',
+										'access'	=> 'private',
+										'data'	=> ''
+									)
+								);
+							}
+//							$temp_id = $cats->name2id($cat);
+//							echo 'Category Name : '.$cat.' : Category ID :'.$temp_id."<br>\n";
+//							$cat_id_nums[] = $temp_id;
+							$cat_id_nums[] = $cats->name2id($cat);
+						}
+						@reset($cat_id_nums);
+						if(count($cat_id_nums) > 1)
+						{
+							$so_event->set_category(implode($cat_id_nums,','));
+						}
+						else
+						{
+							$so_event->set_category($cat_id_nums[0]);
+						}
+					}
+
+//rrule
+					if(isset($ical['event'][$i]['rrule'])  OR isset($ical['event'][$i]['duration']) )
+					{
+// recur_enddate
+						if(isset($ical['event'][$i]['rrule']['until']))
+						{
+							$recur_enddate['year']  = (int)($ical['event'][$i]['rrule']['until']['year']);
+							$recur_enddate['month'] = (int)($ical['event'][$i]['rrule']['until']['month']);
+							$recur_enddate['mday']  = (int)($ical['event'][$i]['rrule']['until']['mday']);
+						}
+						elseif( isset($ical['event'][$i]['duration']) )
+						{
+							// Create timecode for strtotime
+							$ptimer = mktime($ical['event'][$i]['dtstart']['hour'],
+							$ical['event'][$i]['dtstart']['min'],
+							$ical['event'][$i]['dtstart']['sec'],
+							$ical['event'][$i]['dtstart']['month'],
+							$ical['event'][$i]['dtstart']['mday'],
+							$ical['event'][$i]['dtstart']['year']
+						);
+
+						/*  -- Fixbug --
+						* if "DURATION" has 1 day (for example).
+						* Event takes places between the first date
+						* (this define in "start" tag) and next day  :(
+							* This "fix" destroy one day and set hours as "23" and minutes as "59"
+							*/
+
+							// Weeks::Day--
+							if(     $ical['event'][$i]['duration']['weeks']
+							AND
+							( $ical['event'][$i]['duration']['hours'] == 0 )
+							AND
+							( $ical['event'][$i]['duration']['minutes'] == 0 )
+						)
+						{
+							$ical['event'][$i]['duration']['days'] = (
+								$ical['event'][$i]['duration']['days'] +
+								($ical['event'][$i]['duration']['weeks']*7))-1;
+								unset($ical['event'][$i]['duration']['weeks']);
+								$ical['event'][$i]['duration']['hours'] = "23";
+								$ical['event'][$i]['duration']['minutes'] = "59";
+								$ical['event'][$i]['duration']['seconds'] = "59";
+							}
+							// Days::Day--
+							if(
+								$ical['event'][$i]['duration']['days']
+								AND
+								( $ical['event'][$i]['duration']['hours'] == 0 )
+								AND
+								( $ical['event'][$i]['duration']['minutes'] == 0 )
+							)
+							{
+								$ical['event'][$i]['duration']['days']--;
+								$ical['event'][$i]['duration']['hours'] = "23";
+								$ical['event'][$i]['duration']['minutes'] = "59";
+								$ical['event'][$i]['duration']['seconds'] = "59";
+							}
+
+							// Create string contains datetime for strtotime
+							$pdate = "+";
+							if( isset($ical['event'][$i]['duration']['weeks']) )
+							$pdate .= $ical['event'][$i]['duration']['weeks'] . " weeks ";
+							if( isset($ical['event'][$i]['duration']['days']) )
+							$pdate .= $ical['event'][$i]['duration']['days'] . " days ";
+							if( isset($ical['event'][$i]['duration']['hours']) )
+							$pdate .= $ical['event'][$i]['duration']['hours'] . " hours ";
+							if( isset($ical['event'][$i]['duration']['minutes']) )
+							$pdate .= $ical['event'][$i]['duration']['minutes'] . " minutes ";
+							if( isset($ical['event'][$i]['duration']['seconds']) )
+							$pdate .= $ical['event'][$i]['duration']['seconds'] . " seconds ";
+
+							// What is datetime in 2192 ?
+							$enddate = strtotime($pdate, $ptimer);
+							list(   $recur_enddate['year'],
+							$recur_enddate['month'],
+							$recur_enddate['mday'],
+							$recur_enddate['hour'],
+							$recur_enddate['min'],
+							$recur_enddate['sec'] ) = split(":", date("Y:m:d:H:i:s", $enddate));
+
+							// Set End of event
+							$so_event->set_end(     $recur_enddate['year'],
+							$recur_enddate['month'],
+							$recur_enddate['mday'],
+							$recur_enddate['hour'],
+							$recur_enddate['min'],
+							$recur_enddate['sec']);
+
+						}
+						else
+						{
+							$recur_enddate['year'] = 0;
+							$recur_enddate['month'] = 0;
+							$recur_enddate['mday'] = 0;
+						}
+
+// recur_data
+						$recur_data = 0;
+						if(isset($ical['event'][$i]['rrule']['byday']))
+						{
+							$week_days = Array(
+								MCAL_M_SUNDAY	=> 'SU',
+								MCAL_M_MONDAY	=> 'MO',
+								MCAL_M_TUESDAY	=> 'TU',
+								MCAL_M_WEDNESDAY	=> 'WE',
+								MCAL_M_THURSDAY	=> 'TH',
+								MCAL_M_FRIDAY	=> 'FR',
+								MCAL_M_SATURDAY	=> 'SA'
+							);
+							@reset($week_days);
+							while(list($key,$val) = each($week_days))
+							{
+								if(strpos(' '.$ical['event'][$i]['rrule']['byday'],$val))
+								{
+									$recur_data += $key;
+								}
+							}
+						}
+
+// interval
+						if(!isset($ical['event'][$i]['rrule']['interval']))
+						{
+							$interval = 1;
+						}
+						else
+						{
+							$interval = (int)$ical['event'][$i]['rrule']['interval'];
+						}
+// recur_type
+						switch($ical['event'][$i]['rrule']['freq'])
+						{
+							case DAILY:
+								$recur_type = MCAL_RECUR_DAILY;
+								break;
+							case WEEKLY:
+								$so_event->set_recur_weekly($recur_enddate['year'],$recur_enddate['month'],$recur_enddate['mday'],$interval,$recur_data);
+								break;
+							case MONTHLY:
+// Still need to determine if this is by day or by week for the month..
+//								$recur_type = MCAL_RECUR_M??????;
+								break;
+							case YEARLY:
+								$so_event->set_recur_yearly($recur_enddate['year'],$recur_enddate['month'],$recur_enddate['mday'],$interval);
+								break;
+						}
+					}
+					else
+					{
+						$so_event->set_recur_none();
+					}
+
+// Owner
+					if(!isset($ical['event'][$i]['organizer']) || (isset($ical['event'][$i]['organizer']) && $this->is_owner($ical['event'][$i]['organizer'])))
+					{
+						$so_event->add_attribute('owner',$GLOBALS['phpgw_info']['user']['account_id']);
+						$so_event->add_attribute('participants','A',(int)$GLOBALS['phpgw_info']['user']['account_id']);
+					}
+					else
+					{
+//owner
+					}
+
+					$event = $so_event->get_cached_event();
+					$so_event->add_entry($event);
+//					$event = $so_event->get_cached_event();
+				}
+			}
+			if(!$from_ajax) {
+				Header('Location: '.$GLOBALS['phpgw']->link('/index.php',
+					Array(
+						'menuaction'	=> 'calendar.uicalendar.view',
+						'cal_id'	=> $event['id']
+						)
+					)
+				);
+				$GLOBALS['phpgw']->common->phpgw_exit();				
+			}
+			else 
+				return true;
+		}
+
+		function export($params)
+		{
+			$event_id = $params['l_event_id'] ? $params['l_event_id'] : $_GET['cal_id'];
+			$this->chunk_split = $params['chunk_split'];
+			$method = $params['method'] ? $params['method'] : 'publish';
+			$vtype = $params['vtype'] ? $params['vtype'] : 'event';
+
+			$string_array = Array(
+				'summary'		=> 'description',
+				'location'		=> 'location',
+				'description'	=> 'title',
+				'uid'		=> 'uid'
+			);
+
+			$cats = CreateObject('phpgwapi.categories');
+
+			include(PHPGW_SERVER_ROOT.'/calendar/setup/setup.inc.php');
+			if(!is_array($event_id))
+			{
+				$ids[] = $event_id;
+			}
+			else
+			{
+				$ids = $event_id;
+			}
+
+			$ical = $this->new_ical();
+
+			$this->set_var($ical['prodid'],'value','-//eGroupWare//eGroupWare '.$setup_info['calendar']['version'].' MIMEDIR//'.strtoupper($GLOBALS['phpgw_info']['user']['preferences']['common']['lang']));
+			$this->set_var($ical['version'],'value','2.0');
+			$this->set_var($ical['method'],'value',strtoupper($method));
+
+			if(!$GLOBALS['phpgw_info']['flags']['included_classes']['uicalendar'])
+			{
+				if(!$GLOBALS['phpgw_info']['flags']['included_classes']['bocalendar'])
+				{
+					$so_event = createobject('calendar.socalendar',
+						Array(
+							'owner'	=> 0,
+							'filter'	=> '',
+							'category'	=> ''
+						)
+					);
+				}
+				else
+				{
+					$so_event = $GLOBALS['bocalendar']->so;
+				}
+			}
+			else
+			{
+				$so_event = $GLOBALS['uicalendar']->bo->so;
+			}
+
+			foreach($ids as $event)
+			{
+				$ical_event = Array();
+				if (!is_array($event))
+				{
+					$event = $so_event->read_entry($event);
+				}
+				if($event['alarm'])
+				{
+					foreach($event['alarm'] as $alarm)
+					{
+						$ical_temp = Array();
+						$ical_temp['action']['value'] = 'DISPLAY';
+						$ical_temp['description']['value'] = $alarm['text'];
+						$this->set_var($ical_temp['trigger'],'value','VALUE=DATE-TIME:'.date('Ymd\THis\Z',$alarm['time']),'valarm');
+						$ical_event['alarm'][] = $ical_temp;
+					}
+				}
+
+				// use system's date info for caluculating local timezone's offset in minutes
+				//
+				$gmt_offset = date('O',$GLOBALS['phpgw']->datetime->users_localtime);  // offset to GMT
+				$offset = (int)(substr($gmt_offset, 0, 3)) * 60 + (int)(substr($gmt_offset, 3, 2));
+				$event['start']['min']   -= $offset;
+				$event['end']['min']     -= $offset;
+				$event['modtime']['min'] -= $offset;
+
+				$ical_event['priority'] = $event['priority'];
+				$ical_event['class'] = (int)$event['public'];
+				$dtstart_mktime = $so_event->maketime($event['start']);
+				$this->parse_value($ical_event,'dtstart',date('Ymd\THis\Z',$dtstart_mktime),'vevent');
+				$dtend_mktime = $so_event->maketime($event['end']);
+				$this->parse_value($ical_event,'dtend',date('Ymd\THis\Z',$dtend_mktime),'vevent');
+				$mod_mktime = $so_event->maketime($event['modtime']);
+				$this->parse_value($ical_event,'last_modified',date('Ymd\THis\Z',$mod_mktime),'vevent');
+				foreach($string_array as $ical_value => $event_value)
+				{
+					if($event[$event_value])
+					{
+						$this->set_var($ical_event[$ical_value],'value',$event[$event_value]);
+					}
+				}
+
+				if ($event['category'])
+				{
+					$cats->categories(0,'calendar');
+					foreach(explode(',',$event['category']) as $cat)
+					{
+						$_cat = $cats->return_single($cat);
+						$cat_string[] = $_cat[0]['name'];
+					}
+					@reset($cat_string);
+					$this->set_var($ical_event['categories'],'value',implode($cat_string,','));
+				}
+
+				if(count($event['participants']) > 1)
+				{
+					if(!is_object($db))
+					{
+						$db = $GLOBALS['phpgw']->db;
+					}
+					foreach($event['participants'] as $part => $status)
+					{
+						$GLOBALS['phpgw']->accounts->get_account_name($part,$lid,$fname,$lname);
+						$name = $fname.' '.$lname;
+
+						$owner_status = $this->switch_partstat((int)$this->switch_phpgw_status($event['participants'][$part]));
+
+						$mail_prefs = $GLOBALS['phpgw']->preferences->create_email_preferences($part);
+						$mailto = $mail_prefs['email']['address'];
+
+						$str = 'CN="'.$name.'";PARTSTAT='.$owner_status.':'.$mailto;
+						if($part == $event['owner'])
+						{
+							$str = 'ROLE=CHAIR;'.$str;
+						}
+						else
+						{
+							$str = 'ROLE=REQ-PARTICIPANT;'.$str;
+						}
+						if ($method != 'reply' || $part == $GLOBALS['phpgw_info']['user']['account_id'])
+						{
+							$this->parse_value($ical_event,'attendee',$str,'vevent');
+						}
+						if($part == $event['owner'])
+						{
+							$this->parse_value($ical_event,'organizer',$str,'vevent');
+						}
+					}
+				}
+				if($event['recur_type'])
+				{
+					$str = '';
+					switch($event['recur_type'])
+					{
+						case MCAL_RECUR_DAILY:
+							$str .= 'FREQ=DAILY';
+							break;
+						case MCAL_RECUR_WEEKLY:
+							$str .= 'FREQ=WEEKLY';
+							if($event['recur_data'])
+							{
+								$str .= ';BYDAY=';
+								for($i=1;$i<MCAL_M_ALLDAYS;$i=$i*2)
+								{
+									if($i & $event['recur_data'])
+									{
+										switch($i)
+										{
+											case MCAL_M_SUNDAY:
+												$day[] = 'SU';
+												break;
+											case MCAL_M_MONDAY:
+												$day[] = 'MO';
+												break;
+											CASE MCAL_M_TUESDAY:
+												$day[] = 'TU';
+												break;
+											case MCAL_M_WEDNESDAY:
+												$day[] = 'WE';
+												break;
+											case MCAL_M_THURSDAY:
+												$day[] = 'TH';
+												break;
+											case MCAL_M_FRIDAY:
+												$day[] = 'FR';
+												break;
+											case MCAL_M_SATURDAY:
+												$day[] = 'SA';
+												break;
+										}
+									}
+								}
+								$str .= implode(',',$day);
+							}
+							break;
+						case MCAL_RECUR_MONTHLY_MDAY:
+							break;
+						case MCAL_RECUR_MONTHLY_WDAY:
+							break;
+						case MCAL_RECUR_YEARLY:
+							$str .= 'FREQ=YEARLY';
+							break;
+					}
+					if($event['recur_interval'])
+					{
+						$str .= ';INTERVAL='.$event['recur_interval'];
+					}
+					if($event['recur_enddate']['month'] != 0 && $event['recur_enddate']['mday'] != 0 && $event['recur_enddate']['year'] != 0)
+					{
+						$recur_mktime = $so_event->maketime($event['recur_enddate']) - $GLOBALS['phpgw']->datetime->tz_offset;
+						$str .= ';UNTIL='.date('Ymd\THis\Z',$recur_mktime);
+					}
+					$this->parse_value($ical_event,'rrule',$str,'vevent');
+
+					$exceptions = $event['recur_exception'];
+					if(is_array($exceptions))
+					{
+						foreach($exceptions as $except_datetime)
+						{
+							$ical_event['exdate'][] = $this->switch_date(date('Ymd\THis\Z',$except_datetime));
+						}
+					}
+				}
+				$ical_events[] = $ical_event;
+			}
+
+			$ical[$vtype] = $ical_events;
+
+			// iCals are by default utf-8
+			return $GLOBALS['phpgw']->translation->convert($this->build_ical($ical),$GLOBALS['phpgw']->translation->charset(),'utf-8');
+		}
+
+		function freebusy($params=False)
+		{
+			if (!$params) $params = $_GET;
+			$user  = is_numeric($params['user']) ? (int) $params['user'] : $GLOBALS['phpgw']->accounts->name2id($params['user']);
+			$start = isset($params['start']) ? $params['start'] : date('Ymd');
+			$end   = isset($params['end']) ? $params['end'] : (date('Y')+1).date('md');
+
+			$this->bo = CreateObject('calendar.bocalendar');
+			$events_per_day = $this->bo->store_to_cache(array(
+				'owner'  => $user,
+				'syear'  => (int) substr($start,0,4),
+				'smonth' => (int) substr($start,4,2),
+				'sday'   => (int) substr($start,6,2),
+				'eyear'  => (int) substr($end,0,4),
+				'emonth' => (int) substr($end,4,2),
+				'eday'   => (int) substr($end,6,2),
+				'no_doubles' => True,	// report events only on the startday
+			));
+			if (!is_array($events_per_day)) $events_per_day = array();
+			$ids = array();
+			foreach($events_per_day as $day => $events)
+			{
+				foreach($events as $event)
+				{
+					$ids[] = $event;
+				}
+			}
+			$browser = CreateObject('phpgwapi.browser');
+			$browser->content_header($GLOBALS['phpgw']->accounts->id2name($user).'.ifb','text/calendar');
+
+			echo $this->export(array(
+				'vtype'      => 'freebusy',
+				'l_event_id' => $ids,
+			));
+		}
+
+		function debug($str='')
+		{
+			if($this->debug_str)
+			{
+				echo $str."<br>\n";
+			}
+		}
+	}
+?>
Index: /tags/calendar/0.9.3/inc/hook_admin.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/hook_admin.inc.php	(revision 421)
+++ /tags/calendar/0.9.3/inc/hook_admin.inc.php	(revision 421)
@@ -0,0 +1,27 @@
+<?php
+	/**************************************************************************\
+	* eGroupWare                                                               *
+	* http://www.egroupware.org                                                *
+	* Written by Joseph Engo <jengo@phpgroupware.org>                          *
+	* --------------------------------------------                             *
+	*  This program is free software; you can redistribute it and/or modify it *
+	*  under the terms of the GNU General Public License as published by the   *
+	*  Free Software Foundation; either version 2 of the License, or (at your  *
+	*  option) any later version.                                              *
+	\**************************************************************************/
+
+{
+// Only Modify the $file and $title variables.....
+	$title = $appname;
+	$file = Array(
+		'Site Configuration' => $GLOBALS['phpgw']->link('/index.php','menuaction=admin.uiconfig.index&appname=' . $appname),
+		'Custom fields and sorting' => $GLOBALS['phpgw']->link('/index.php','menuaction=calendar.uicustom_fields.index'),
+		'Calendar Holiday Management' => $GLOBALS['phpgw']->link('/index.php','menuaction=calendar.uiholiday.admin'),
+		'Import CSV-File' => $GLOBALS['phpgw']->link('/calendar/csv_import.php'),
+		'Global Categories' => $GLOBALS['phpgw']->link('/index.php','menuaction=admin.uicategories.index&appname=calendar'),
+		'Grant Access by Group' => $GLOBALS['phpgw']->link('/index.php','menuaction=calendar.uigroup_access.index')
+	);
+//Do not modify below this line
+	display_section($appname,$title,$file);
+}
+?>
Index: /tags/calendar/0.9.3/inc/class.holidaycalc_JP.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.holidaycalc_JP.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/inc/class.holidaycalc_JP.inc.php	(revision 2)
@@ -0,0 +1,152 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - holidaycalc_JP                                              *
+  * http://www.egroupware.org                                              *
+  * Based on Yoshihiro Kamimura <your@itheart.com>                           *
+  *          http://www.itheart.com                                          *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	class holidaycalc
+	{
+		function calculate_date($holiday, &$holidays, $year, &$i)
+		{
+			static	$cached_month;
+			static	$cached_day;
+			static	$cached_observance_rule;
+
+			if ($holiday['day'] == 0 && $holiday['dow'] != 0 && $holiday['occurence'] != 0)
+			{
+				$dow = $GLOBALS['phpgw']->datetime->day_of_week($year, $holiday['month'], 1);
+				$dayshift = (($holiday['dow'] + 7) - $dow) % 7;
+				$day = ($holiday['occurence'] - 1) * 7 + $dayshift + 1;
+
+				// Happy monday law.
+				if ($holiday['month'] == 1)
+				{
+					if ($year < 2000)
+					{
+						$day = 15;
+					}
+				}
+				elseif ($holiday['month'] == 7)
+				{
+					if ($year < 2003)
+					{
+						$day = 20;
+					}
+				}
+				elseif ($holiday['month'] == 9)
+				{
+					if ($year < 2003)
+					{
+						$day = 15;
+					}
+				}
+				elseif ($holiday['month'] == 10)
+				{
+					if ($year < 2000)
+					{
+						$day = 10;
+					}
+				}
+			}
+			elseif ($holiday['day'] == 0 && $holiday['dow'] == 0 && $holiday['occurence'] == 0)
+			{
+				// For the next generation.
+				// over 2151, please set $factor...
+				if ($holiday['month'] == 3)
+				{
+					// for Vernal Equinox
+					if ($year >= 1980 && $year <= 2099)
+					{
+						$factor = 20.8431;
+					}
+					elseif ($year >= 2100 && $year <= 2150)
+					{
+						$factor = 21.851;
+					}
+				}
+				elseif ($holiday['month'] == 9)
+				{
+					// for Autumnal Equinox
+					if ($year >= 1980 && $year <= 2099)
+					{
+						$factor = 23.2488;
+					}
+					elseif ($year >= 2100 && $year <= 2150)
+					{
+						$factor = 24.2488;
+					}
+				}
+
+				$day = (int)($factor + 0.242194 * ($year - 1980)
+					- (int)(($year - 1980) / 4));
+			}
+			else
+			{
+				// normal holiday
+				$day = $holiday['day'];
+			}
+
+			if ($year >= 1985 && $holiday['month'] == $cached_month && $day == $cached_day + 2 && $cached_observance_rule == True && $holiday['observance_rule'] == True)
+			{
+				$pdow = $GLOBALS['phpgw']->datetime->day_of_week($year,$holiday['month'],$day-1);
+				if ($pdow != 0)
+				{
+					$addcnt = count($holidays) + 1;
+					$holidays[$addcnt]['locale'] = $holiday['locale'];
+					if ($pdow == 1)
+					{
+						$holidays[$addcnt]['name'] = lang('overlap holiday');
+					}
+					else
+					{
+						$holidays[$addcnt]['name'] = lang('people holiday');
+					}
+					$holidays[$addcnt]['day'] = $day - 1;
+					$holidays[$addcnt]['month'] = $holiday['month'];
+					$holidays[$addcnt]['occurence'] = 0;
+					$holidays[$addcnt]['dow'] = 0;
+					$holidays[$addcnt]['date'] = mktime(0,0,0,$holiday['month'],$day-1,$year);
+					$holidays[$addcnt]['observance_rule'] = 0;
+				}
+			}
+
+			$cached_month = $holiday['month'];
+			$cached_day = $day;
+			$cached_observance_rule = $holiday['observance_rule'];
+
+			if ($year >= 1985 && $holiday['month'] == 5 && $day == 3)
+			{
+				;
+			}
+			elseif ($holiday['observance_rule'] == True)
+			{
+				$dow = $GLOBALS['phpgw']->datetime->day_of_week($year,$holiday['month'],$day);
+				// This now calulates Observed holidays and creates a new entry for them.
+				if($dow == 0)
+				{
+					$addcnt = count($holidays) + 1;
+					$holidays[$addcnt]['locale'] = $holiday['locale'];
+					$holidays[$addcnt]['name'] = lang('overlap holiday');
+					$holidays[$addcnt]['day'] = $day + 1;
+					$holidays[$addcnt]['month'] = $holiday['month'];
+					$holidays[$addcnt]['occurence'] = $holiday['occurence'];
+					$holidays[$addcnt]['dow'] = $holiday['dow'];
+					$holidays[$addcnt]['date'] = mktime(0,0,0,$holiday['month'],$day+1,$year);
+					$holidays[$addcnt]['observance_rule'] = 0;
+				}
+			}
+
+			$date = mktime(0,0,0,$holiday['month'],$day,$year);
+
+			return $date;
+		}
+	}
+?>
Index: /tags/calendar/0.9.3/inc/class.socalendar__.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.socalendar__.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/inc/class.socalendar__.inc.php	(revision 2)
@@ -0,0 +1,204 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar                                                    *
+  * http://www.egroupware.org                                                *
+  * Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
+  *          http://www.radix.net/~cknudsen                                  *
+  * Modified by Mark Peters <skeeter@phpgroupware.org>                       *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	if (@$GLOBALS['phpgw_info']['flags']['included_classes']['socalendar__'])
+	{
+		return;
+	}
+
+	$GLOBALS['phpgw_info']['flags']['included_classes']['socalendar__'] = True;
+
+	/*	include(PHPGW_SERVER_ROOT.'/calendar/setup/setup.inc.php');	*/
+
+	if(extension_loaded('mcal') == False)
+	{
+		define('MCAL_RECUR_NONE',0);
+		define('MCAL_RECUR_DAILY',1);
+		define('MCAL_RECUR_WEEKLY',2);
+		define('MCAL_RECUR_MONTHLY_MDAY',3);
+		define('MCAL_RECUR_MONTHLY_WDAY',4);
+		define('MCAL_RECUR_YEARLY',5);
+		
+		define('MCAL_M_SUNDAY',1);
+		define('MCAL_M_MONDAY',2);
+		define('MCAL_M_TUESDAY',4);
+		define('MCAL_M_WEDNESDAY',8);
+		define('MCAL_M_THURSDAY',16);
+		define('MCAL_M_FRIDAY',32);
+		define('MCAL_M_SATURDAY',64);
+		
+		define('MCAL_M_WEEKDAYS',62);
+		define('MCAL_M_WEEKEND',65);
+		define('MCAL_M_ALLDAYS',127);
+	}
+
+	define('MSG_DELETED',0);
+	define('MSG_MODIFIED',1);
+	define('MSG_ADDED',2);
+	define('MSG_REJECTED',3);
+	define('MSG_TENTATIVE',4);
+	define('MSG_ACCEPTED',5);
+	define('MSG_ALARM',6);
+
+	define('REJECTED',0);
+	define('NO_RESPONSE',1);
+	define('TENTATIVE',2);
+	define('ACCEPTED',3);
+
+	class socalendar__
+	{
+		var $event;
+		var $stream;
+		var $user;
+		var $users_status;
+		var $debug = False;
+	//	var $debug = True;
+
+		function socalendar__()
+		{
+		}
+
+		function maketime($time)
+		{
+			return mktime($time['hour'],$time['min'],$time['sec'],$time['month'],$time['mday'],$time['year']);
+		}
+
+		function get_cached_event()
+		{
+			return $this->event;
+		}
+
+		function event_init()
+		{
+			$this->event = Array();
+			$this->add_attribute('owner',(int)$this->user);
+		}
+
+		function set_category($category='')
+		{
+			$this->add_attribute('category',$category);
+		}
+
+		function set_title($title='')
+		{
+			$this->add_attribute('title',$title);
+		}
+
+		function set_description($description='')
+		{
+			$this->add_attribute('description',$description);
+		}
+
+		function set_ex_participants($ex_participants='')
+		{
+			$this->add_attribute('ex_participants',$ex_participants);
+		}
+
+		function set_date($element,$year,$month,$day=0,$hour=0,$min=0,$sec=0)
+		{
+			$this->add_attribute($element,(int)$year,'year');
+			$this->add_attribute($element,(int)$month,'month');
+			$this->add_attribute($element,(int)$day,'mday');
+			$this->add_attribute($element,(int)$hour,'hour');
+			$this->add_attribute($element,(int)$min,'min');
+			$this->add_attribute($element,(int)$sec,'sec');
+			$this->add_attribute($element,0,'alarm');
+		}
+
+		function set_start($year,$month,$day=0,$hour=0,$min=0,$sec=0)
+		{
+			$this->set_date('start',$year,$month,$day,$hour,$min,$sec);
+		}
+
+		function set_end($year,$month,$day=0,$hour=0,$min=0,$sec=0)
+		{
+			$this->set_date('end',$year,$month,$day,$hour,$min,$sec);
+		}
+
+		function set_alarm($alarm)
+		{
+			$this->add_attribute('alarm',(int)$alarm);
+		}
+
+		function set_class($class)
+		{
+			$this->add_attribute('public',$class);
+		}
+
+		function set_common_recur($year=0,$month=0,$day=0,$interval=0)
+		{
+			$this->add_attribute('recur_interval',(int)$interval);
+			$this->set_date('recur_enddate',$year,$month,$day,0,0,0);
+			$this->add_attribute('recur_data',0);
+		}
+
+		function set_recur_none()
+		{
+			$this->set_common_recur(0,0,0,0);
+			$this->add_attribute('recur_type',MCAL_RECUR_NONE);
+		}
+
+		function set_recur_daily($year,$month,$day,$interval)
+		{
+			$this->set_common_recur((int)$year,(int)$month,(int)$day,$interval);
+			$this->add_attribute('recur_type',MCAL_RECUR_DAILY);
+		}
+
+		function set_recur_weekly($year,$month,$day,$interval,$weekdays)
+		{
+			$this->set_common_recur((int)$year,(int)$month,(int)$day,$interval);
+			$this->add_attribute('recur_type',MCAL_RECUR_WEEKLY);
+			$this->add_attribute('recur_data',(int)$weekdays);
+		}
+
+		function set_recur_monthly_mday($year,$month,$day,$interval)
+		{
+			$this->set_common_recur((int)$year,(int)$month,(int)$day,$interval);
+			$this->add_attribute('recur_type',MCAL_RECUR_MONTHLY_MDAY);
+		}
+		
+		function set_recur_monthly_wday($year,$month,$day,$interval)
+		{
+			$this->set_common_recur((int)$year,(int)$month,(int)$day,$interval);
+			$this->add_attribute('recur_type',MCAL_RECUR_MONTHLY_WDAY);
+		}
+		
+		function set_recur_yearly($year,$month,$day,$interval)
+		{
+			$this->set_common_recur((int)$year,(int)$month,(int)$day,$interval);
+			$this->add_attribute('recur_type',MCAL_RECUR_YEARLY);
+		}
+
+		function fetch_current_stream_event()
+		{
+			return $this->fetch_event($this->event['id']);
+		}
+		
+		function add_attribute($attribute,$value,$element='**(**')
+		{
+			if(is_array($value))
+			{
+				reset($value);
+			}
+			if($element!='**(**')
+			{
+				$this->event[$attribute][$element] = $value;
+			}
+			else
+			{
+				$this->event[$attribute] = $value;
+			}
+		}
+	}
Index: /tags/calendar/0.9.3/inc/class.socalendar_.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.socalendar_.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/inc/class.socalendar_.inc.php	(revision 2)
@@ -0,0 +1,28 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar                                                    *
+  * http://www.egroupware.org                                                *
+  * Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
+  *          http://www.radix.net/~cknudsen                                  *
+  * Modified by Mark Peters <skeeter@phpgroupware.org>                       *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	if(@$GLOBALS['phpgw_info']['server']['calendar_type'] == 'mcal' &&
+		extension_loaded('mcal') == False)
+	{
+		$GLOBALS['phpgw_info']['server']['calendar_type'] = 'sql';
+	}
+/* This will be elminated when ical is fully implemented */
+	else
+	{
+		$GLOBALS['phpgw_info']['server']['calendar_type'] = 'sql';
+	}
+	include(PHPGW_INCLUDE_ROOT.'/calendar/inc/class.socalendar__.inc.php');
+	include(PHPGW_INCLUDE_ROOT.'/calendar/inc/class.socalendar_'.$GLOBALS['phpgw_info']['server']['calendar_type'].'.inc.php');
+?>
Index: /tags/calendar/0.9.3/inc/class.uigroup_access.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.uigroup_access.inc.php	(revision 580)
+++ /tags/calendar/0.9.3/inc/class.uigroup_access.inc.php	(revision 580)
@@ -0,0 +1,160 @@
+<?php
+
+ /**************************************************************************\
+  * Expresso Livre - Grant Group Access - administration                     *
+  *															                 *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+include_once("class.bogroup_access.inc.php");
+
+class uigroup_access
+{
+	var $public_functions = array(
+		'add'      	=> True,
+		'index'		=> True,
+	);
+
+	var $bo;
+	var $template;
+	var $template_dir;
+	var $html;
+	var $theme;
+
+	final function __construct()
+	{
+		
+		$this->bo = new bogroup_access();				
+	}
+
+	function index(){
+		
+		$GLOBALS['phpgw_info']['flags'] = array(
+					'currentapp' => 'calendar',
+					'nonavbar'   => false,
+					'app_header' => lang('Grant Access by Group'),
+					'noheader'   => false
+					);
+		
+		$GLOBALS['phpgw']->common->phpgw_header();
+		$this->template_dir = 'calendar/templates/'.$GLOBALS['phpgw_info']['user']['preferences']['common']['template_set'];
+		$this->template = CreateObject('phpgwapi.Template',PHPGW_APP_TPL);		
+		if (!is_object($GLOBALS['phpgw']->html)){
+			$GLOBALS['phpgw']->html = CreateObject('phpgwapi.html');
+		}
+		
+		$this->html = &$GLOBALS['phpgw']->html;
+		$this->theme = $GLOBALS['phpgw_info']['theme'];
+				
+		$_SESSION['phpgw_info']['server'] = $GLOBALS['phpgw_info']['server'];
+		$this->template->set_file(Array('main'	=> 'grant_group_access.tpl'	));	
+		$this->template->set_block('main','list','list_t');			
+		
+		// if ExpressoMail 1.2 has been installed and enabled, show the plugin using AJAX. 
+		if($GLOBALS['phpgw_info']['server']['cal_expressoMail']) {							
+			$module_name = 'expressoMail'.(str_replace("1.","1_",$GLOBALS['phpgw_info']['server']['cal_expressoMail']));
+			if($GLOBALS['phpgw_info']['user']['apps'][$module_name]){								
+				$ldap_manager = CreateObject('contactcenter.bo_ldap_manager');
+				$_SESSION['phpgw_info']['expressomail']['user'] = $GLOBALS['phpgw_info']['user'];				
+				$_SESSION['phpgw_info']['expressomail']['user']['owner'] = $GLOBALS['phpgw_info']['user']['account_id'];
+				$_SESSION['phpgw_info']['expressomail']['server'] = $GLOBALS['phpgw_info']['server'];
+				$_SESSION['phpgw_info']['expressomail']['ldap_server'] = $ldap_manager ? $ldap_manager->srcs[1] : null;
+				// Carrega todos scripts necessarios				
+				$scripts =	"<script src='".$module_name."/js/connector.js' type='text/javascript'></script>".
+							"<script type='text/javascript'>var DEFAULT_URL = '".$module_name."/controller.php?action=';</script> ".											
+							"<script src='".$this->template_dir."/js/search.js' type='text/javascript'></script>";				
+				// Fim				
+				
+				$this->template->set_var('lang_Loading',lang("Loading"));
+				$this->template->set_var('lang_Searching', lang("Searching"));
+				$this->template->set_var('lang_Users', lang("Users"));
+				$this->template->set_var('lang_Groups', lang("Groups"));
+				$this->template->set_var('template_set', $this->template_dir);
+				$this->template->set_var('lang_Event_participants', lang("Event's participants"));
+				$this->template->set_var('lang_Add', lang("Add"));
+				$this->template->set_var('lang_Remove', lang("Remove"));
+				$this->template->set_var('lang_Organization', lang("Organization"));
+				$this->template->set_var('lang_Search_for', lang("Search for"));
+				$this->template->set_var('lang_Available_users_and_groups', lang("Available users and groups"));
+				$this->template->set_var('lang_User_to_grant_access', lang("User to grant access"));
+				$this->template->set_var('lang_Group_to_share_calendar', lang("Group to share calendar"));
+				$this->template->set_var('scripts',$scripts);
+			}
+		}	
+				
+		$this->template->set_var('tr_color',$this->theme['th_bg']);		
+		$this->template->set_var('lang_granted_user',lang("Granted user"));			
+		$this->template->set_var('lang_shared_group',lang("Shared group"));
+		
+		$this->template->set_var('lang_rights',lang("Rights"));
+		$this->template->set_var('lang_read',lang("Read"));
+		$this->template->set_var('lang_add',lang("Add"));
+		$this->template->set_var('lang_edit',lang("Edit"));
+		$this->template->set_var('lang_delete',lang("Delete"));
+		$this->template->set_var('lang_private',lang("Private"));
+		
+		$this->template->set_var('lang_access_type',lang("Permission"));		
+		$this->template->set_var('lang_remove',lang("remove"));
+		
+		$this->template->set_var('lang_confirm',lang("Do you confirm this action?"));
+		$this->template->set_var('lang_success',lang("The sharing was granted."));
+		$this->template->set_var('lang_exist',lang("This sharing already exist."));
+		$this->template->set_var('lang_nouser',lang("No user was selected"));
+		$this->template->set_var('lang_nogroup',lang("No group was selected"));
+		$this->template->set_var('lang_nopermissiontype',lang("No permission type was selected"));
+		$this->template->set_var('lang_typemoreletters',lang("Type more %1 letters.","X"));		
+									
+		$grants = $this->get_grants('calendar');
+		
+		$i = 0;
+		$data = array();
+		if($grants) {		
+			foreach($grants as $key => $acl) {				
+				$GLOBALS['phpgw']->accounts->get_account_name($acl['userID'], &$lid, &$fuser, &$luser);
+				$GLOBALS['phpgw']->accounts->get_account_name($acl['groupID'], &$lid, &$groupname, &$lname);			
+				$rights = $acl['rights'] & PHPGW_ACL_READ ? "L" : "";
+				$rights.= $acl['rights'] & PHPGW_ACL_ADD ? "A" : "";
+				$rights.= $acl['rights'] & PHPGW_ACL_EDIT ? "E" : "";
+				$rights.= $acl['rights'] & PHPGW_ACL_DELETE ? "R" : "";
+				$rights.= $acl['rights'] & PHPGW_ACL_PRIVATE ? "P" : "";
+			
+				$data[$fuser." ".$luser.$i++] = array('granted_user'    => $fuser." ".$luser,
+						'shared_group'     => $groupname,
+						'access_type'      => $rights,
+						'tr_color_header'  => "#DCDCDC",
+						'select'   => $key
+					);
+			}
+			ksort($data);
+			foreach($data as $key => $var){
+				$this->template->set_var($var);			
+				$this->template->parse('list_t','list',$var);				
+			}
+		}		
+		
+		$this->template->pfp('out', 'main');
+	}
+
+	private function get_grants($app){
+		return $this->bo->get_grants($app);		
+	}
+	public function search_user($params){		
+		return $this->bo->search_user($params);	
+	} 	
+	public final function add_user($params) {				
+		$rights  = strstr($params['rights'],"L") ? 1 : 0;
+		$rights |= strstr($params['rights'],"A") ? 2 : 0;
+		$rights |= strstr($params['rights'],"E") ? 4 : 0;
+		$rights |= strstr($params['rights'],"R") ? 8 : 0;
+		$rights |= strstr($params['rights'],"P") ? 16 : 0;
+		$params["id"] .= ";".$rights;
+		return $this->bo->add_user($params);
+	}
+	public final function rem_user($params) {
+		return $this->bo->rem_user($params);
+	}
+}
+?>
Index: /tags/calendar/0.9.3/inc/hook_preferences.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/hook_preferences.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/inc/hook_preferences.inc.php	(revision 2)
@@ -0,0 +1,23 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare                                                               *
+  * http://www.egroupware.org                                                *
+  * Written by Joseph Engo <jengo@phpgroupware.org>                          *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+{
+// Only Modify the $file and $title variables.....
+	$title = $appname;
+	$file = array(
+		'Preferences'     => $GLOBALS['phpgw']->link('/preferences/preferences.php','appname='.$appname),
+		'Grant Access'    => $GLOBALS['phpgw']->link('/index.php','menuaction=preferences.uiaclprefs.index&acl_app='.$appname),
+		'Edit Categories' => $GLOBALS['phpgw']->link('/index.php','menuaction=preferences.uicategories.index&cats_app='.$appname.'&cats_level=True&global_cats=True')
+	);
+//Do not modify below this line
+	display_section($appname,$title,$file);
+}
+?>
Index: /tags/calendar/0.9.3/inc/hook_home_week.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/hook_home_week.inc.php	(revision 136)
+++ /tags/calendar/0.9.3/inc/hook_home_week.inc.php	(revision 136)
@@ -0,0 +1,27 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar                                                    *
+  * http://www.egroupware.org                                                *
+  * Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
+  *          http://www.radix.net/~cknudsen                                  *
+  * Written by Mark Peters <skeeter@phpgroupware.org>                        *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	$d1 = strtolower(substr(PHPGW_APP_INC,0,3));
+	if($d1 == 'htt' || $d1 == 'ftp' )
+	{
+		echo 'Failed attempt to break in via an old Security Hole!<br>'."\n";
+		$GLOBALS['phpgw']->common->phpgw_exit();
+	}
+	unset($d1);
+
+	$GLOBALS['extra_data'] = $GLOBALS['css']."\n".'<td>'."\n".'<table  width="100%" border="0" cols="3"><tr><td  align="center" width="100%" valign="top">'
+		. ExecMethod('calendar.uicalendar.get_week')
+		.'</td>'."\n".'</tr>'."\n".'</table>'."\n".'</td>'."\n";
+?>
Index: /tags/calendar/0.9.3/inc/class.uiicalendar.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.uiicalendar.inc.php	(revision 678)
+++ /tags/calendar/0.9.3/inc/class.uiicalendar.inc.php	(revision 678)
@@ -0,0 +1,124 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar                                                    *
+  * http://www.egroupware.org                                                *
+  * Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
+  *          http://www.radix.net/~cknudsen                                  *
+  * Modified by Mark Peters <skeeter@phpgroupware.org>                       *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	class uiicalendar
+	{
+		var $bo;
+		var $template;
+
+		var $public_functions = array(
+			'test'		=> True,
+			'import'		=> True,
+			'import_from_mail' => True
+		);
+
+
+
+		function uiicalendar()
+		{
+			$this->bo = CreateObject('calendar.boicalendar');
+			$this->template = $GLOBALS['phpgw']->template;
+			$GLOBALS['phpgw_info']['flags']['app_header'] = lang('Calendar - [iv]Cal Importer');
+		}
+
+		function print_test($val,$title,$x_pre='')
+		{
+//			echo 'VAL = '._debug_array($val,False)."<br>\n";
+			if(is_array($val))
+			{
+				@reset($val);
+				while(list($key,$value) = each($val))
+				{
+					if(is_array($key))
+					{
+						$this->print_test($key,$title,$x_pre);
+					}
+					elseif(is_array($value))
+					{
+						$this->print_test($value,$title,$x_pre);
+					}
+					else
+					{
+						if($x_pre && $key == 'name')
+						{
+							$x_key = $x_pre.$value;
+							list($key,$value) = each($val);
+							$key=$x_key;
+						}
+						if($this->bo->parameter[$key]['type'] == 'function')
+						{
+							$function = $this->bo->parameter[$key]['function'];
+							$v_value = $this->bo->$function($value);
+						}
+						else
+						{
+							$v_value = $value;
+						}
+						echo $title.' ('.$key.') = '.$v_value."<br>\n";
+					}
+				}
+			}
+			elseif($val != '')
+			{
+				echo $title.' = '.$val."<br>\n";
+			}
+		}
+
+		function import_from_mail($calendar) {
+			return $this->bo->import(explode("\n",$calendar),true);
+		}
+
+
+		function import()
+		{
+			unset($GLOBALS['phpgw_info']['flags']['noheader']);
+			unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+			$GLOBALS['phpgw_info']['flags']['nonappheader'] = True;
+			$GLOBALS['phpgw_info']['flags']['nonappfooter'] = True;
+			$GLOBALS['phpgw']->common->phpgw_header();
+
+			if(!@is_dir($GLOBALS['phpgw_info']['server']['temp_dir']))
+			{
+				mkdir($GLOBALS['phpgw_info']['server']['temp_dir'],0700);
+			}
+
+			echo '<body bgcolor="' . $GLOBALS['phpgw_info']['theme']['bg_color'] . '">';
+
+			if ($GLOBALS['HTTP_GET_VARS']['action'] == 'GetFile')
+			{
+				echo '<b><center>' . lang('You must select a [iv]Cal. (*.[iv]cs)') . '</b></center><br><br>';
+			}
+
+ 			$this->template->set_file(
+ 				Array(
+ 					'vcalimport' => 'vcal_import.tpl'
+ 				)
+ 			);
+
+			$var = Array(
+				'vcal_header'	=> '<p>',
+				'ical_lang'		=> lang('(i/v)Cal'),
+				'action_url'	=> $GLOBALS['phpgw']->link('/index.php','menuaction=calendar.boicalendar.import'),
+				'lang_access'	=> lang('Access'),
+				'lang_groups'	=> lang('Which groups'),
+				'access_option'=> $access_option,
+				'group_option'	=> $group_option,
+				'load_vcal'	=> lang('Load [iv]Cal')
+			);
+			$this->template->set_var($var);
+			$this->template->pparse('out','vcalimport');
+		}
+	}
+?>
Index: /tags/calendar/0.9.3/inc/lang_alarm.php
===================================================================
--- /tags/calendar/0.9.3/inc/lang_alarm.php	(revision 204)
+++ /tags/calendar/0.9.3/inc/lang_alarm.php	(revision 204)
@@ -0,0 +1,18 @@
+<?
+function load_lang() {
+	if(!$_SESSION['phpgw_info']['calendar']['langAlarm']) 
+	{
+		$array_keys = array();
+		$fn = '../setup/phpgw_alarm_'.$GLOBALS['phpgw_info']['user']['preferences']['common']['lang'].'.lang';			
+		echo $fn;
+		if (file_exists($fn)){
+			$fp = fopen($fn,'r');
+			while ($data = fgets($fp,16000))	{
+				list($message_id,$app_name,$null,$content) = explode("\t",substr($data,0,-1));			
+				$_SESSION['phpgw_info']['calendar']['langAlarm'][$message_id] =  $content;
+			}
+			fclose($fp);
+		}
+	}
+}
+?>
Index: /tags/calendar/0.9.3/inc/hook_home_year.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/hook_home_year.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/inc/hook_home_year.inc.php	(revision 2)
@@ -0,0 +1,27 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar                                                    *
+  * http://www.egroupware.org                                                *
+  * Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
+  *          http://www.radix.net/~cknudsen                                  *
+  * Written by Mark Peters <skeeter@phpgroupware.org>                        *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	$d1 = strtolower(substr(PHPGW_APP_INC,0,3));
+	if($d1 == 'htt' || $d1 == 'ftp' )
+	{
+		echo 'Failed attempt to break in via an old Security Hole!<br>'."\n";
+		$GLOBALS['phpgw']->common->phpgw_exit();
+	}
+	unset($d1);
+
+	$GLOBALS['extra_data'] = $GLOBALS['css']."\n".'<td>'."\n".'<table border="0" cols="3"><tr><td align="center" width="100%" valign="top">'
+		. ExecMethod('calendar.uicalendar.get_year')
+		.'</td>'."\n".'</tr>'."\n".'</table>'."\n".'</td>'."\n";
+?>
Index: /tags/calendar/0.9.3/inc/hook_manual.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/hook_manual.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/inc/hook_manual.inc.php	(revision 2)
@@ -0,0 +1,22 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar Holidays                                           *
+  * http://www.egroupware.org                                                *
+  * Written by Mark Peters <skeeter@phpgroupware.org>                        *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+// Only Modify the $file variable.....
+	$file = Array(
+		'Viewing'	=>	'view.php',
+		'Adding'	=> 'add.php',
+		'Edit/Deleting'	=> 'edit_delete.php'
+	);
+//Do not modify below this line
+	display_manual_section($appname,$file);
+?>
Index: /tags/calendar/0.9.3/inc/class.socalendar_sql.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.socalendar_sql.inc.php	(revision 583)
+++ /tags/calendar/0.9.3/inc/class.socalendar_sql.inc.php	(revision 583)
@@ -0,0 +1,1220 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar                                                    *
+  * http://www.eGroupWare.org                                                *
+  * Maintained and further developed by RalfBecker@outdoor-training.de       *
+  * Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
+  *          http://www.radix.net/~cknudsen                                  *
+  * Originaly modified by Mark Peters <skeeter@phpgroupware.org>             *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	if (@$GLOBALS['phpgw_info']['flags']['included_classes']['socalendar_'])
+	{
+		return;
+	}
+
+	$GLOBALS['phpgw_info']['flags']['included_classes']['socalendar_'] = True;
+
+	class socalendar_ extends socalendar__
+	{
+		var $deleted_events = Array();
+
+		var $cal_event;
+		var $today = Array('raw','day','month','year','full','dow','dm','bd');
+
+
+		function socalendar_()
+		{
+			$this->socalendar__();
+
+			if (!is_object($GLOBALS['phpgw']->asyncservice))
+			{
+				$GLOBALS['phpgw']->asyncservice = CreateObject('phpgwapi.asyncservice');
+			}
+			$this->async = &$GLOBALS['phpgw']->asyncservice;
+		}
+
+		function open($calendar='',$user='',$passwd='',$options='')
+		{
+			if($user=='')
+			{
+	//			settype($user,'integer');
+				$this->user = $GLOBALS['phpgw_info']['user']['account_id'];
+			}
+			elseif(is_int($user))
+			{
+				$this->user = $user;
+			}
+			elseif(is_string($user))
+			{
+				$this->user = $GLOBALS['phpgw']->accounts->name2id($user);
+			}
+
+			$this->stream = $GLOBALS['phpgw']->db;
+			return $this->stream;
+		}
+
+		function popen($calendar='',$user='',$passwd='',$options='')
+		{
+			return $this->open($calendar,$user,$passwd,$options);
+		}
+
+		function reopen($calendar,$options='')
+		{
+			return $this->stream;
+		}
+
+		function close($options='')
+		{
+			return True;
+		}
+
+		function create_calendar($calendar='')
+		{
+			return $calendar;
+		}
+
+		function rename_calendar($old_name='',$new_name='')
+		{
+			return $new_name;
+		}
+
+		function delete_calendar($calendar='')
+		{
+			$this->stream->query('SELECT cal_id FROM phpgw_cal WHERE owner='.(int)$calendar,__LINE__,__FILE__);
+			if($this->stream->num_rows())
+			{
+				while($this->stream->next_record())
+				{
+					$this->delete_event((int)$this->stream->f('cal_id'));
+				}
+				$this->expunge();
+			}
+			$this->stream->lock(array('phpgw_cal_user'));
+			$this->stream->query('DELETE FROM phpgw_cal_user WHERE cal_login='.(int)$calendar,__LINE__,__FILE__);
+			$this->stream->unlock();
+
+			return $calendar;
+		}
+
+		/*!
+		@function read_alarms
+		@abstract read the alarms of a calendar-event specified by $cal_id
+		@returns array of alarms with alarm-id as key
+		@note the alarm-id is a string of 'cal:'.$cal_id.':'.$alarm_nr, it is used as the job-id too
+		*/
+		function read_alarms($cal_id)
+		{
+			$alarms = array();
+
+			if ($jobs = $this->async->read('cal:'.(int)$cal_id.':%'))
+			{
+				foreach($jobs as $id => $job)
+				{
+					$alarm         = $job['data'];	// text, enabled
+					$alarm['id']   = $id;
+					$alarm['time'] = $job['next'];
+
+					$alarms[$id] = $alarm;
+				}
+			}
+			return $alarms;
+		}
+
+		/*!
+		@function read_alarm
+		@abstract read a single alarm specified by it's $id
+		@returns array with data of the alarm
+		@note the alarm-id is a string of 'cal:'.$cal_id.':'.$alarm_nr, it is used as the job-id too
+		*/
+		function read_alarm($id)
+		{
+			if (!($jobs = $this->async->read($id)))
+			{
+				return False;
+			}
+			list($id,$job) = each($jobs);
+			$alarm         = $job['data'];	// text, enabled
+			$alarm['id']   = $id;
+			$alarm['time'] = $job['next'];
+
+			//echo "<p>read_alarm('$id')="; print_r($alarm); echo "</p>\n";
+			return $alarm;
+		}
+
+/* Funcao save_alarm modificada para gerar alarmes repetidos, caso seja marcado um evento igualmente repetido. A funcao recebe qual o tipo
+de repeticao escolhido pelo usuario (diario, semanal, mensal, anual) e insere alarmes nas respectivas repeticoes do evento. */
+		/*!
+		@function save_alarm
+		@abstract saves a new or updated alarm
+		@syntax save_alarm($cal_id,$alarm,$id=False)
+		@param $cal_id Id of the calendar-entry
+		@param $alarm array with fields: text, owner, enabled, ..
+		@returns the id of the alarm
+		*/
+		function save_alarm($cal_id,$alarm)
+		{
+
+			if (!($id = $alarm['id']))
+			{
+				$alarm['time'] -= $GLOBALS['phpgw']->datetime->tz_offset;	// time should be stored in server timezone
+				$alarms = $this->read_alarms($cal_id);	// find a free alarm#
+
+				if($alarm['repeat'] == 1) // repeticao do tipo "Diariamente";
+				{
+					$n = 0;
+
+					while(@isset($alarms[$id]));
+					{
+
+						$init_alarm = $alarm['init_rept'];
+						$end_alarm = $alarm['end_rept'];
+
+						if($end_alarm != 0)
+						{
+							while($init_alarm <= $end_alarm)
+							{
+								$id = 'cal:'.(int)$cal_id.':'.$n;
+								$n++;
+								
+								$alarm['cal_id'] = $cal_id;		// we need the back-reference
+
+								unset($alarm['repeat']);
+								unset($alarm['init_rept']);
+								unset($alarm['end_rept']);
+								unset($alarm['rpt_wdays']);
+
+								if (!$this->async->set_timer($alarm['time'],$id,'calendar.bocalendar.send_alarm',$alarm))
+								{
+									return False;
+								}
+
+								$alarm['time'] += 86400;
+								$init_alarm += 86400;
+							}
+						}
+					}
+
+				}elseif($alarm['repeat'] == 2) { // repeticao do tipo "Semanalmente";
+
+					$n = 0;
+
+					$init_alarm = $data_atual = $alarm['init_rept'];
+					$end_alarm = $alarm['end_rept'];
+
+					$rpt_alarm_wdays = $alarm['rpt_wdays'];
+
+					$divisor = 64;
+					$quociente = 0;
+					$resto = 0;
+
+					$dia_semana = date("w",$init_alarm);
+
+					switch($dia_semana)
+					{
+						case 0:
+							$dia = array(
+									0 => 'domingo',
+									1 => 'segunda',
+									2 => 'terca',
+									3 => 'quarta',
+									4 => 'quinta',
+									5 => 'sexta',
+									6 => 'sabado'
+							);
+							break;
+						case 1:
+							$dia = array(
+									0 => 'segunda',
+									1 => 'terca',
+									2 => 'quarta',
+									3 => 'quinta',
+									4 => 'sexta',
+									5 => 'sabado',
+									6 => 'domingo'
+							);
+							break;
+						case 2:
+							$dia = array(
+									0 => 'terca',
+									1 => 'quarta',
+									2 => 'quinta',
+									3 => 'sexta',
+									4 => 'sabado',
+									5 => 'domingo',
+									6 => 'segunda'
+							);
+							break;
+						case 3:
+							$dia = array(
+									0 => 'quarta',
+									1 => 'quinta',
+									2 => 'sexta',
+									3 => 'sabado',
+									4 => 'domingo',
+									5 => 'segunda',
+									6 => 'terca'
+							);
+							break;
+						case 4:
+							$dia = array(
+									0 => 'quinta',
+									1 => 'sexta',
+									2 => 'sabado',
+									3 => 'domingo',
+									4 => 'segunda',
+									5 => 'terca',
+									6 => 'quarta'
+							);
+							break;
+						case 5:
+							$dia = array(
+									0 => 'sexta',
+									1 => 'sabado',
+									2 => 'domingo',
+									3 => 'segunda',
+									4 => 'terca',
+									5 => 'quarta',
+									6 => 'quinta'
+							);
+							break;
+						case 6:
+							$dia = array(
+									0 => 'sabado',
+									1 => 'domingo',
+									2 => 'segunda',
+									3 => 'terca',
+									4 => 'quarta',
+									5 => 'quinta',
+									6 => 'sexta'
+							);
+							break;
+					}
+
+
+					$dias_semana = array(
+								64 => 'sabado',
+								32 => 'sexta',
+								16 => 'quinta',
+								8 => 'quarta',
+								4 => 'terca',
+								2 => 'segunda',
+								1 => 'domingo'
+							);
+
+					do
+					{
+
+						$resto = ($rpt_alarm_wdays % $divisor);
+						$quociente = floor($rpt_alarm_wdays / $divisor);
+
+						if($quociente == 1)
+						{
+							$result[] .= $dias_semana[$divisor];
+
+							$divisor = $divisor / 2;
+							$rpt_alarm_wdays = $resto;
+
+						}else {
+
+							while($rpt_alarm_wdays < $divisor)
+							{
+								$divisor = $divisor / 2;
+							}
+
+							$resto = ($rpt_alarm_wdays % $divisor);
+							$quociente = floor($rpt_alarm_wdays / $divisor);
+
+							if($quociente == 1)
+							{
+
+								$result[] .= $dias_semana[$divisor];
+
+								$divisor = $divisor / 2;
+								$rpt_alarm_wdays = $resto;
+							}
+						}
+
+					}
+					while($resto != 0);
+
+					krsort($result);
+
+					$week_num = 0;
+					$y = 0;
+
+					while(@isset($alarms[$id]));
+					{
+
+						if($end_alarm != 0)
+						{
+
+							while($data_atual <= $end_alarm)
+							{
+
+								foreach($dia as $index => $value)
+								{
+									if(in_array($value,$result))
+									{
+
+										$nova_data = $init_alarm + (86400 * ($index + (7 * $y)));
+
+										if($nova_data == $init_alarm){
+
+											continue;
+										}
+
+										$id = 'cal:'.(int)$cal_id.':'.$n;
+										$n++;
+
+										$alarm['cal_id'] = $cal_id;		// we need the back-reference
+
+										unset($alarm['repeat']);
+										unset($alarm['init_rept']);
+										unset($alarm['end_rept']);
+										unset($alarm['rpt_wdays']);
+										
+										$data_atual = $nova_data;
+
+										if($data_atual > $end_alarm){
+											if (!$this->async->set_timer($alarm['time'],$id,'calendar.bocalendar.send_alarm',$alarm))
+											{
+												return False;
+											}
+											break;
+										}
+
+										if (!$this->async->set_timer($alarm['time'],$id,'calendar.bocalendar.send_alarm',$alarm))
+										{
+											return False;
+										}
+											$alarm['time'] = $nova_data - $alarm['offset'] - $GLOBALS['phpgw']->datetime->tz_offset; 
+									}
+								}
+								$y++;
+							}
+						}
+					}
+
+				}elseif($alarm['repeat'] == 3) { // repeticao do tipo "Mensalmente (por data)";
+
+					$n = 0;
+
+					$init_alarm = $alarm['init_rept'];
+					$end_alarm = $alarm['end_rept'];
+					
+					while(@isset($alarms[$id]));
+					{
+
+						if($end_alarm != 0)
+						{
+							while($init_alarm <= $end_alarm)
+							{
+
+								$next_month = date("n",$init_alarm) + 1;
+								$next_alarm = mktime(date("G",$alarm['time']),date("i",$alarm['time']),date("s",$alarm['time']),$next_month,date("j",$alarm['time']),date("Y",$alarm['time']));
+
+								$id = 'cal:'.(int)$cal_id.':'.$n;
+								$n++;
+
+								$alarm['cal_id'] = $cal_id;		// we need the back-reference
+
+								unset($alarm['repeat']);
+								unset($alarm['init_rept']);
+								unset($alarm['end_rept']);
+								unset($alarm['rpt_wdays']);
+
+								if (!$this->async->set_timer($alarm['time'],$id,'calendar.bocalendar.send_alarm',$alarm))
+								{
+									return False;
+								}
+
+								$alarm['time'] = $next_alarm;
+								$init_alarm = $next_alarm;
+
+							}
+						}
+					}
+
+				}elseif($alarm['repeat'] == 5) { // repeticao do tipo "Anualmente";
+
+					$n = 0;
+
+					$init_alarm = $alarm['init_rept'];
+					$end_alarm = $alarm['end_rept'];
+					
+					while(@isset($alarms[$id]));
+					{
+
+
+						if($end_alarm != 0)
+						{
+							while($init_alarm < $end_alarm)
+							{
+
+								$next_year = date("Y",$init_alarm) + 1;
+								$next_alarm = mktime(date("G",$alarm['time']),date("i",$alarm['time']),date("s",$alarm['time']),date("n",$alarm['time']),date("j",$alarm['time']),$next_year);
+
+								$id = 'cal:'.(int)$cal_id.':'.$n;
+								$n++;
+
+								$alarm['cal_id'] = $cal_id;		// we need the back-reference
+
+								unset($alarm['repeat']);
+								unset($alarm['init_rept']);
+								unset($alarm['end_rept']);
+								unset($alarm['rpt_wdays']);
+
+								if (!$this->async->set_timer($alarm['time'],$id,'calendar.bocalendar.send_alarm',$alarm))
+								{
+									return False;
+								}
+
+								$alarm['time'] = $next_alarm;
+								$init_alarm = $next_alarm;
+							}
+						}
+					}
+
+				}else {
+					$alarm['time'] -= $GLOBALS['phpgw']->datetime->tz_offset;	// time should be stored in server timezone
+					$n = count($alarms);
+					while(@isset($alarms[$id]));
+					{
+
+						$id = 'cal:'.(int)$cal_id.':'.$n;
+
+						unset($alarm['repeat']);
+						unset($alarm['init_rept']);
+						unset($alarm['end_rept']);
+						unset($alarm['rpt_wdays']);
+
+						$alarm['cal_id'] = $cal_id;		// we need the back-reference
+						if (!$this->async->set_timer($alarm['time'],$id,'calendar.bocalendar.send_alarm',$alarm))
+						{
+							return False;
+						}
+
+						++$n;
+					}
+				}
+
+			}
+			else
+			{
+				$this->async->cancel_timer($id);
+			}
+			$alarm['time'] -= $GLOBALS['phpgw']->datetime->tz_offset;	// time should be stored in server timezone
+			return $id;
+		}
+
+		/*!
+		@function delete_alarms($cal_id)
+		@abstract delete all alarms of a calendar-entry
+		@returns the number of alarms deleted
+		*/
+		function delete_alarms($cal_id)
+		{
+			$alarms = $this->read_alarms($cal_id);
+
+			foreach($alarms as $id => $alarm)
+			{
+				$this->async->cancel_timer($id);
+			}
+			return count($alarms);
+		}
+
+		/*!
+		@function delete_alarm($id)
+		@abstract delete one alarms identified by its id
+		@returns the number of alarms deleted
+		*/
+		function delete_alarm($id)
+		{
+			return $this->async->cancel_timer($id);
+		}
+
+		function fetch_event($event_id,$options='')
+		{
+			if(!isset($this->stream))
+			{
+				return False;
+			}
+
+			$event_id = (int)$event_id;
+
+			$this->stream->lock(array('phpgw_cal','phpgw_cal_user','phpgw_cal_repeats','phpgw_cal_extra'/* OLD-ALARM,'phpgw_cal_alarm'*/));
+
+			$this->stream->query('SELECT * FROM phpgw_cal WHERE cal_id='.$event_id,__LINE__,__FILE__);
+
+			if($this->stream->num_rows() > 0)
+			{
+				$this->event_init();
+
+				$this->stream->next_record();
+				// Load the calendar event data from the db into $event structure
+				// Use http://www.php.net/manual/en/function.mcal-fetch-event.php as the reference
+				$this->add_attribute('owner',(int)$this->stream->f('owner'));
+				$this->add_attribute('id',(int)$this->stream->f('cal_id'));
+				$this->add_attribute('type',$this->stream->f('cal_type'));
+				$this->set_class((int)$this->stream->f('is_public'));
+				$this->set_category($this->stream->f('category'));
+				$this->set_title(stripslashes($GLOBALS['phpgw']->strip_html($this->stream->f('title'))));
+				$this->set_description(stripslashes($GLOBALS['phpgw']->strip_html($this->stream->f('description'))));
+				$this->set_ex_participants(stripslashes($GLOBALS['phpgw']->strip_html($this->stream->f('ex_participants'))));
+				$this->add_attribute('uid',$GLOBALS['phpgw']->strip_html($this->stream->f('uid')));
+				$this->add_attribute('location',stripslashes($GLOBALS['phpgw']->strip_html($this->stream->f('location'))));
+				$this->add_attribute('reference',(int)$this->stream->f('reference'));
+
+				// This is the preferred method once everything is normalized...
+				//$this->event->alarm = (int)$this->stream->f('alarm');
+				// But until then, do it this way...
+				//Legacy Support (New)
+
+				$datetime = $GLOBALS['phpgw']->datetime->localdates($this->stream->f('datetime'));
+				$this->set_start($datetime['year'],$datetime['month'],$datetime['day'],$datetime['hour'],$datetime['minute'],$datetime['second']);
+
+				$datetime = $GLOBALS['phpgw']->datetime->localdates($this->stream->f('mdatetime'));
+				$this->set_date('modtime',$datetime['year'],$datetime['month'],$datetime['day'],$datetime['hour'],$datetime['minute'],$datetime['second']);
+
+				$datetime = $GLOBALS['phpgw']->datetime->localdates($this->stream->f('edatetime'));
+				$this->set_end($datetime['year'],$datetime['month'],$datetime['day'],$datetime['hour'],$datetime['minute'],$datetime['second']);
+
+			//Legacy Support
+				$this->add_attribute('priority',(int)$this->stream->f('priority'));
+				if($this->stream->f('cal_group') || $this->stream->f('groups') != 'NULL')
+				{
+					$groups = explode(',',$this->stream->f('groups'));
+					for($j=1;$j<count($groups) - 1;$j++)
+					{
+						$this->add_attribute('groups',$groups[$j],$j-1);
+					}
+				}
+
+				$this->stream->query('SELECT * FROM phpgw_cal_repeats WHERE cal_id='.$event_id,__LINE__,__FILE__);
+				if($this->stream->num_rows())
+				{
+					$this->stream->next_record();
+
+					$this->add_attribute('recur_type',(int)$this->stream->f('recur_type'));
+					$this->add_attribute('recur_interval',(int)$this->stream->f('recur_interval'));
+					$enddate = $this->stream->f('recur_enddate');
+					if($enddate != 0 && $enddate != Null)
+					{
+						$datetime = $GLOBALS['phpgw']->datetime->localdates($enddate);
+						$this->add_attribute('recur_enddate',$datetime['year'],'year');
+						$this->add_attribute('recur_enddate',$datetime['month'],'month');
+						$this->add_attribute('recur_enddate',$datetime['day'],'mday');
+						$this->add_attribute('recur_enddate',$datetime['hour'],'hour');
+						$this->add_attribute('recur_enddate',$datetime['minute'],'min');
+						$this->add_attribute('recur_enddate',$datetime['second'],'sec');
+					}
+					else
+					{
+						$this->add_attribute('recur_enddate',0,'year');
+						$this->add_attribute('recur_enddate',0,'month');
+						$this->add_attribute('recur_enddate',0,'mday');
+						$this->add_attribute('recur_enddate',0,'hour');
+						$this->add_attribute('recur_enddate',0,'min');
+						$this->add_attribute('recur_enddate',0,'sec');
+					}
+					$this->add_attribute('recur_enddate',0,'alarm');
+					if($this->debug)
+					{
+						echo 'Event ID#'.$this->event['id'].' : Enddate = '.$enddate."<br>\n";
+					}
+					$this->add_attribute('recur_data',$this->stream->f('recur_data'));
+
+					$exception_list = $this->stream->f('recur_exception');
+					$exceptions = Array();
+					if(strpos(' '.$exception_list,','))
+					{
+						$exceptions = explode(',',$exception_list);
+					}
+					elseif($exception_list != '')
+					{
+						$exceptions[]= $exception_list;
+					}
+					$this->add_attribute('recur_exception',$exceptions);
+				}
+
+			//Legacy Support
+				$this->stream->query('SELECT * FROM phpgw_cal_user WHERE cal_id='.$event_id,__LINE__,__FILE__);
+				if($this->stream->num_rows())
+				{
+					while($this->stream->next_record())
+					{
+						if((int)$this->stream->f('cal_login') == (int)$this->user)
+						{
+							$this->add_attribute('users_status',$this->stream->f('cal_status'));
+						}
+						$this->add_attribute('participants',$this->stream->f('cal_status'),(int)$this->stream->f('cal_login'));
+					}
+				}
+
+			// Custom fields
+				$this->stream->query('SELECT * FROM phpgw_cal_extra WHERE cal_id='.$event_id,__LINE__,__FILE__);
+				if($this->stream->num_rows())
+				{
+					while($this->stream->next_record())
+					{
+						$this->add_attribute('#'.$this->stream->f('cal_extra_name'),$this->stream->f('cal_extra_value'));
+					}
+				}
+
+	/* OLD-ALARM
+				if($this->event['reference'])
+				{
+					// What is event['reference']???
+					$alarm_cal_id = $event_id.','.$this->event['reference'];
+				}
+				else
+				{
+					$alarm_cal_id = $event_id;
+				}
+
+				//echo '<!-- cal_id='.$alarm_cal_id.' -->'."\n";
+				//$this->stream->query('SELECT * FROM phpgw_cal_alarm WHERE cal_id in ('.$alarm_cal_id.') AND cal_owner='.$this->user,__LINE__,__FILE__);
+				$this->stream->query('SELECT * FROM phpgw_cal_alarm WHERE cal_id='.$event_id.' AND cal_owner='.$this->user,__LINE__,__FILE__);
+				if($this->stream->num_rows())
+				{
+					while($this->stream->next_record())
+					{
+						$this->event['alarm'][] = Array(
+							'id'		=> (int)$this->stream->f('alarm_id'),
+							'time'	=> (int)$this->stream->f('cal_time'),
+							'text'	=> $this->stream->f('cal_text'),
+							'enabled'	=> (int)$this->stream->f('alarm_enabled')
+						);
+					}
+				}
+	*/
+			}
+			else
+			{
+				$this->event = False;
+			}
+
+			$this->stream->unlock();
+
+			if ($this->event)
+			{
+				$this->event['alarm'] = $this->read_alarms($event_id);
+
+				if($this->event['reference'])
+				{
+					$this->event['alarm'] += $this->read_alarms($event_id);
+				}
+			}
+			return $this->event;
+		}
+
+		function list_events($startYear,$startMonth,$startDay,$endYear=0,$endMonth=0,$endDay=0,$extra='',$tz_offset=0,$owner_id=0)
+		{
+			if(!isset($this->stream))
+			{
+				return False;
+			}
+
+			$datetime = mktime(0,0,0,$startMonth,$startDay,$startYear) - $tz_offset;
+
+			$user_where = ' AND (phpgw_cal_user.cal_login in (';
+			if(is_array($owner_id) && count($owner_id))
+			{
+				$user_where .= implode(',',$owner_id);
+			}
+			else
+			{
+				$user_where .= $this->user;
+			}
+			$member_groups = $GLOBALS['phpgw']->accounts->membership($this->user);
+			@reset($member_groups);
+			while($member_groups != False && list($key,$group_info) = each($member_groups))
+			{
+				$member[] = $group_info['account_id'];
+			}
+			@reset($member);
+	//		$user_where .= ','.implode(',',$member);
+			$user_where .= ')) ';
+
+			if($this->debug)
+			{
+				echo '<!-- '.$user_where.' -->'."\n";
+			}
+
+			$startDate = 'AND ( ( (phpgw_cal.datetime >= '.$datetime.') ';
+
+			$enddate = '';
+			if($endYear != 0 && $endMonth != 0 && $endDay != 0)
+			{
+				$edatetime = mktime(23,59,59,(int)$endMonth,(int)$endDay,(int)$endYear) - $tz_offset;
+				$endDate .= 'AND (phpgw_cal.edatetime <= '.$edatetime.') ) '
+					. 'OR ( (phpgw_cal.datetime <= '.$datetime.') '
+					. 'AND (phpgw_cal.edatetime >= '.$edatetime.') ) '
+					. 'OR ( (phpgw_cal.datetime >= '.$datetime.') '
+					. 'AND (phpgw_cal.datetime <= '.$edatetime.') '
+					. 'AND (phpgw_cal.edatetime >= '.$edatetime.') ) '
+					. 'OR ( (phpgw_cal.datetime <= '.$datetime.') '
+					. 'AND (phpgw_cal.edatetime >= '.$datetime.') '
+					. 'AND (phpgw_cal.edatetime <= '.$edatetime.') ';
+			}
+			$endDate .= ') ) ';
+
+			$order_by = 'ORDER BY phpgw_cal.datetime ASC, phpgw_cal.edatetime ASC, phpgw_cal.priority ASC';
+			if($this->debug)
+			{
+				echo "SQL : ".$user_where.$startDate.$endDate.$extra."<br>\n";
+			}
+			return $this->get_event_ids(False,$user_where.$startDate.$endDate.$extra.$order_by);
+		}
+
+		function append_event()
+		{
+			$this->save_event($this->event);
+			$this->send_update(MSG_ADDED,$this->event->participants,'',$this->event);
+			return $this->event['id'];
+		}
+
+		function store_event()
+		{
+			return $this->save_event(&$this->event);
+		}
+
+		function delete_event($event_id)
+		{
+			$this->deleted_events[] = $event_id;
+		}
+
+		function snooze($event_id)
+		{
+		//Turn off an alarm for an event
+		//Returns true.
+		}
+
+		function list_alarms($begin_year='',$begin_month='',$begin_day='',$end_year='',$end_month='',$end_day='')
+		{
+		//Return a list of events that has an alarm triggered at the given datetime
+		//Returns an array of event ID's
+		}
+
+		// The function definition doesn't look correct...
+		// Need more information for this function
+		function next_recurrence($weekstart,$next)
+		{
+	//		return next_recurrence (int stream, int weekstart, array next);
+		}
+
+		function expunge()
+		{
+			if(count($this->deleted_events) <= 0)
+			{
+				return 1;
+			}
+			$this_event = $this->event;
+			$locks = Array(
+				'phpgw_cal',
+				'phpgw_cal_user',
+				'phpgw_cal_repeats',
+				'phpgw_cal_extra'
+	// OLD-ALARM			'phpgw_cal_alarm'
+			);
+			$this->stream->lock($locks);
+			foreach($this->deleted_events as $cal_id)
+			{
+				foreach ($locks as $table)
+				{
+					$this->stream->query('DELETE FROM '.$table.' WHERE cal_id='.$cal_id,__LINE__,__FILE__);
+				}
+			}
+			$this->stream->unlock();
+
+			foreach($this->deleted_events as $cal_id)
+			{
+				$this->delete_alarms($cal_id);
+			}
+			$this->deleted_events = array();
+
+			$this->event = $this_event;
+			return 1;
+		}
+
+		/***************** Local functions for SQL based Calendar *****************/
+
+		function get_event_ids($search_repeats=False,$extra='',$search_extra=False)
+		{
+			$from = $where = ' ';
+			if($search_repeats)
+			{
+				$from  = ', phpgw_cal_repeats ';
+				$where = 'AND (phpgw_cal_repeats.cal_id = phpgw_cal.cal_id) ';
+			}
+			if($search_extra)
+			{
+				$from  .= 'LEFT JOIN phpgw_cal_extra ON phpgw_cal_extra.cal_id = phpgw_cal.cal_id ';
+			}
+
+			$sql = 'SELECT DISTINCT phpgw_cal.cal_id,'
+					. 'phpgw_cal.datetime,phpgw_cal.edatetime,'
+					. 'phpgw_cal.priority '
+					. 'FROM phpgw_cal_user, phpgw_cal'
+					. $from
+					. 'WHERE (phpgw_cal_user.cal_id = phpgw_cal.cal_id) '
+					. $where . $extra;
+
+			if($this->debug)
+			{
+				echo "FULL SQL : ".$sql."<br>\n";
+			}
+
+			$this->stream->query($sql,__LINE__,__FILE__);
+
+			$retval = Array();
+			if($this->stream->num_rows() == 0)
+			{
+				if($this->debug)
+				{
+					echo "No records found!<br>\n";
+				}
+				return $retval;
+			}
+
+			while($this->stream->next_record())
+			{
+				$retval[] = (int)$this->stream->f('cal_id');
+			}
+			if($this->debug)
+			{
+				echo "Records found!<br>\n";
+			}
+			return $retval;
+		}
+
+		function save_event(&$event)
+		{
+
+			$GLOBALS['calendar']->bocalendar = CreateObject('calendar.bocalendar');
+
+			$locks = Array(
+				'phpgw_cal',
+				'phpgw_cal_user',
+				'phpgw_cal_repeats',
+				'phpgw_cal_extra'
+	// OLD-ALARM			'phpgw_cal_alarm'
+			);
+			$this->stream->lock($locks);
+			if($event['id'] == 0)
+			{
+				if(!$event['uid'])
+				{
+					if ($GLOBALS['phpgw_info']['server']['hostname'] != '')
+					{
+						$id_suffix = $GLOBALS['phpgw_info']['server']['hostname'];
+					}
+					else
+					{
+						$id_suffix = $GLOBALS['phpgw']->common->randomstring(3).'local';
+					}
+					$parts = Array(
+						0 => 'title',
+						1 => 'description',
+						2 => 'ex_participants'
+					);
+					@reset($parts);
+					while(list($key,$field) = each($parts))
+					{
+						$part[$key] = substr($GLOBALS['phpgw']->crypto->encrypt($event[$field]),0,20);
+						if(!$GLOBALS['phpgw']->crypto->enabled)
+						{
+							$part[$key] = bin2hex(unserialize($part[$key]));
+						}
+					}
+					$event['uid'] = $part[0].'-'.$part[1].'@'.$id_suffix;
+				}
+				$this->stream->query('INSERT INTO phpgw_cal(uid,title,owner,priority,is_public,category) '
+					. "values('".$event['uid']."','".$this->stream->db_addslashes($event['title'])
+					. "',".(int)$event['owner'].','.(int)$event['priority'].','.(int)$event['public'].",'"
+					. $event['category']."')",__LINE__,__FILE__);
+				$event['id'] = $this->stream->get_last_insert_id('phpgw_cal','cal_id');
+				$last_status = true;
+			}
+
+			$date = $this->maketime($event['start']) - $GLOBALS['phpgw']->datetime->tz_offset;
+			$enddate = $this->maketime($event['end']) - $GLOBALS['phpgw']->datetime->tz_offset;
+			$today = time() - $GLOBALS['phpgw']->datetime->tz_offset;
+
+			if($event['recur_type'] != MCAL_RECUR_NONE)
+			{
+				$type = 'M';
+			}
+			else
+			{
+				if ($event['type'] == 'hourAppointment')
+					$type = 'H';
+				else
+					$type = 'E';
+			}
+
+			$sql = 'UPDATE phpgw_cal SET '
+					. 'owner='.(int)$event['owner'].', '
+					. 'datetime='.(int)$date.', '
+					. 'mdatetime='.(int)$today.', '
+					. 'edatetime='.(int)$enddate.', '
+					. 'priority='.(int)$event['priority'].', '
+					. "category='".$this->stream->db_addslashes($event['category'])."', "
+					. "cal_type='".$this->stream->db_addslashes($type)."', "
+					. 'is_public='.(int)$event['public'].', '
+					. "title='".$this->stream->db_addslashes($event['title'])."', "
+					. "description='".$this->stream->db_addslashes($event['description'])."', "
+					. "ex_participants='".$this->stream->db_addslashes($event['ex_participants'])."', "
+					. "location='".$this->stream->db_addslashes($event['location'])."', "
+					. ($event['groups']?"groups='".(count($event['groups'])>1?implode(',',$event['groups']):','.$event['groups'][0].',')."', ":'')
+					. 'reference='.(int)$event['reference'].' '
+					. ',last_status = '.($last_status ? "'N'" : "'U'").',last_update = '.time()."000". ' '
+					. 'WHERE cal_id='.(int)$event['id'];
+
+			$this->stream->query($sql,__LINE__,__FILE__);
+
+			$this->stream->query('DELETE FROM phpgw_cal_user WHERE cal_id='.(int)$event['id'],__LINE__,__FILE__);
+
+			@reset($event['participants']);
+			while (list($key,$value) = @each($event['participants']))
+			{
+				if((int)$key == $event['owner'])
+				{
+					$value = 'A';
+				}
+				$this->stream->query('INSERT INTO phpgw_cal_user(cal_id,cal_login,cal_status) '
+					. 'VALUES('.(int)$event['id'].','.(int)$key.",'".$this->stream->db_addslashes($value)."')",__LINE__,__FILE__);
+			}
+
+			if($event['recur_type'] != MCAL_RECUR_NONE)
+			{
+				if($event['recur_enddate']['month'] != 0 && $event['recur_enddate']['mday'] != 0 && $event['recur_enddate']['year'] != 0)
+				{
+					$end = $this->maketime($event['recur_enddate']) - $GLOBALS['phpgw']->datetime->tz_offset;
+				}
+				else
+				{
+					$end = 0;
+				}
+
+				$this->stream->query('SELECT count(cal_id) FROM phpgw_cal_repeats WHERE cal_id='.(int)$event['id'],__LINE__,__FILE__);
+				$this->stream->next_record();
+				$num_rows = $this->stream->f(0);
+				if($num_rows == 0)
+				{
+					$this->stream->query('INSERT INTO phpgw_cal_repeats(cal_id,recur_type,recur_enddate,recur_data,recur_interval) '
+						.'VALUES('.(int)$event['id'].','.$event['recur_type'].','.(int)$end.','.$event['recur_data'].','.$event['recur_interval'].')',__LINE__,__FILE__);
+				}
+				else
+				{
+					$this->stream->query('UPDATE phpgw_cal_repeats '
+						. 'SET recur_type='.$event['recur_type'].', '
+						. 'recur_enddate='.(int)$end.', '
+						. 'recur_data='.$event['recur_data'].', '
+						. 'recur_interval='.$event['recur_interval'].', '
+						. "recur_exception='".(count($event['recur_exception'])>1?implode(',',$event['recur_exception']):(count($event['recur_exception'])==1?$event['recur_exception'][0]:''))."' "
+						. 'WHERE cal_id='.$event['id'],__LINE__,__FILE__);
+				}
+
+			}
+			else
+			{
+				$this->stream->query('DELETE FROM phpgw_cal_repeats WHERE cal_id='.$event['id'],__LINE__,__FILE__);
+			}
+			// Custom fields
+			$this->stream->query('DELETE FROM phpgw_cal_extra WHERE cal_id='.$event['id'],__LINE__,__FILE__);
+
+			foreach($event as $name => $value)
+			{
+				if ($name[0] == '#' && strlen($value))
+				{
+					$this->stream->query('INSERT INTO phpgw_cal_extra (cal_id,cal_extra_name,cal_extra_value) '
+					. 'VALUES('.$event['id'].",'".addslashes(substr($name,1))."','".addslashes($value)."')",__LINE__,__FILE__);
+				}
+			}
+	/*
+			$alarmcount = count($event['alarm']);
+			if ($alarmcount > 1)
+			{
+				// this should never happen, $event['alarm'] should only be set
+				// if creating a new event and uicalendar only sets up 1 alarm
+				// the user must use "Alarm Management" to create/establish multiple
+				// alarms or to edit/change an alarm
+				echo '<!-- how did this happen, too many alarms -->'."\n";
+				$this->stream->unlock();
+				return True;
+			}
+
+			if ($alarmcount == 1)
+			{
+
+				list($key,$alarm) = @each($event['alarm']);
+
+				$this->stream->query('INSERT INTO phpgw_cal_alarm(cal_id,cal_owner,cal_time,cal_text,alarm_enabled) VALUES('.$event['id'].','.$event['owner'].','.$alarm['time'].",'".$alarm['text']."',".$alarm['enabled'].')',__LINE__,__FILE__);
+				$this->stream->query('SELECT LAST_INSERT_ID()');
+				$this->stream->next_record();
+				$alarm['id'] = $this->stream->f(0);
+			}
+	*/
+			print_debug('Event Saved: ID #',$event['id']);
+
+			$this->stream->unlock();
+
+			if (is_array($event['alarm']))
+			{
+				foreach ($event['alarm'] as $alarm)	// this are all new alarms
+				{
+					$this->save_alarm($event['id'],$alarm);
+				}
+			}
+			$GLOBALS['phpgw_info']['cal_new_event_id'] = $event['id'];
+			$this->event = $event;
+			return True;
+		}
+
+		function get_alarm($cal_id)
+		{
+	/* OLD-ALARM
+			$this->stream->query('SELECT cal_time, cal_text FROM phpgw_cal_alarm WHERE cal_id='.$id.' AND cal_owner='.$this->user,__LINE__,__FILE__);
+			if($this->stream->num_rows())
+			{
+				while($this->stream->next_record())
+				{
+					$alarm[$this->stream->f('cal_time')] = $this->stream->f('cal_text');
+				}
+				@reset($alarm);
+				return $alarm;
+			}
+			else
+			{
+				return False;
+			}
+	*/
+			$alarms = $this->read_alarms($cal_id);
+			$ret = False;
+
+			foreach($alarms as $alarm)
+			{
+				if ($alarm['owner'] == $this->user || !$alarm['owner'])
+				{
+					$ret[$alarm['time']] = $alarm['text'];
+				}
+			}
+			return $ret;
+		}
+
+		function set_status($id,$owner,$status)
+		{
+			$status_code_short = Array(
+				REJECTED =>	'R',
+				NO_RESPONSE	=> 'U',
+				TENTATIVE	=>	'T',
+				ACCEPTED	=>	'A'
+			);
+
+			$this->stream->query("UPDATE phpgw_cal_user SET cal_status='".$status_code_short[$status]."' WHERE cal_id=".$id." AND cal_login=".$owner,__LINE__,__FILE__);
+	/* OLD-ALARM
+			if ($status == 'R')
+			{
+				$this->stream->query('UPDATE phpgw_cal_alarm set alarm_enabled=0 where cal_id='.$id.' and cal_owner='.$owner,__LINE__,__FILE__);
+			}
+	*/
+			return True;
+		}
+
+	// End of ICal style support.......
+
+		function group_search($owner=0)
+		{
+			$owner = ($owner==$GLOBALS['phpgw_info']['user']['account_id']?0:$owner);
+			$groups = substr($GLOBALS['phpgw']->common->sql_search('phpgw_cal.groups',(int)$owner),4);
+			if (!$groups)
+			{
+				return '';
+			}
+			else
+			{
+				return "(phpgw_cal.is_public=2 AND (". $groups .')) ';
+			}
+		}
+
+		function splittime_($time)
+		{
+			$temp = array('hour','minute','second','ampm');
+			$time = strrev($time);
+			$second = (int)strrev(substr($time,0,2));
+			$minute = (int)strrev(substr($time,2,2));
+			$hour   = (int)strrev(substr($time,4));
+			$temp['second'] = (int)$second;
+			$temp['minute'] = (int)$minute;
+			$temp['hour']   = (int)$hour;
+			$temp['ampm']   = '  ';
+
+			return $temp;
+		}
+
+		function date_to_epoch($d)
+		{
+			return $this->localdates(mktime(0,0,0,(int)(substr($d,4,2)),(int)(substr($d,6,2)),(int)(substr($d,0,4))));
+		}
+
+		function list_dirty_events($lastmod=-1,$repeats=false)
+		{
+			if(!isset($this->stream))
+			{
+				return False;
+			}
+			$lastmod = (int)  $lastmod;
+			$repeats = (bool) $repeats;
+
+			$user_where = " AND phpgw_cal_user.cal_login = $this->user";
+
+			$member_groups = $GLOBALS['phpgw']->accounts->membership($this->user);
+			@reset($member_groups);
+			while($member_groups != False && list($key,$group_info) = each($member_groups))
+			{
+				$member[] = $group_info['account_id'];
+			}
+			@reset($member);
+	//		$user_where .= ','.implode(',',$member);
+			//$user_where .= ')) ';
+
+			if($this->debug)
+			{
+				echo '<!-- '.$user_where.' -->'."\n";
+			}
+
+			if($lastmod > 0)
+			{
+				$wheremod = "AND mdatetime = $lastmod";
+			}
+
+			$order_by = ' ORDER BY phpgw_cal.cal_id ASC';
+			if($this->debug)
+			{
+				echo "SQL : ".$user_where.$wheremod.$extra."<br>\n";
+			}
+			return $this->get_event_ids($repeats,$user_where.$wheremod.$extra.$order_by);
+		}
+
+	/* OLD-ALARM
+		function add_alarm($eventid,$alarm,$owner)
+		{
+			$this->stream->query('INSERT INTO phpgw_cal_alarm(cal_id,cal_owner,cal_time,cal_text,alarm_enabled) VALUES('.$eventid.','.$owner.','.$alarm['time'].",'".$alarm['text']."',1)",__LINE__,__FILE__);
+			$this->stream->query('SELECT LAST_INSERT_ID()');
+			$this->stream->next_record();
+			return($this->stream->f(0));
+		}
+		function delete_alarm($alarmid)
+		{
+			$this->stream->query('DELETE FROM phpgw_cal_alarm WHERE alarm_id='.$alarmid,__LINE__,__FILE__);
+		}
+	*/
+	}
Index: /tags/calendar/0.9.3/inc/hook_deleteaccount.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/hook_deleteaccount.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/inc/hook_deleteaccount.inc.php	(revision 2)
@@ -0,0 +1,27 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare                                                               *
+  * http://www.egroupware.org                                                *
+  * Written by Mark Peters <skeeter@phpgroupware.org>                        *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+	// Delete all records for a user
+	if((int)$_POST['new_owner'] == 0)
+	{
+		ExecMethod('calendar.bocalendar.delete_calendar',(int)$_POST['account_id']);
+	}
+	else
+	{
+		ExecMethod('calendar.bocalendar.change_owner',
+			Array(
+				'old_owner'	=> (int)$_POST['account_id'],
+				'new_owner'	=> (int)$_POST['new_owner']
+			)
+		);
+	}
+?>
Index: /tags/calendar/0.9.3/inc/hook_home_small.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/hook_home_small.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/inc/hook_home_small.inc.php	(revision 2)
@@ -0,0 +1,58 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar                                                    *
+  * http://www.egroupware.org                                                *
+  * Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
+  *          http://www.radix.net/~cknudsen                                  *
+  * Written by Mark Peters <skeeter@phpgroupware.org>                        *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	$d1 = strtolower(substr(PHPGW_APP_INC,0,3));
+	if($d1 == 'htt' || $d1 == 'ftp' )
+	{
+		echo 'Failed attempt to break in via an old Security Hole!<br>'."\n";
+		$GLOBALS['phpgw']->common->phpgw_exit();
+	}
+	unset($d1);
+
+	$today = $GLOBALS['phpgw']->datetime->users_localtime;
+	$dates = array($today);
+	$wday = date('w',$today);
+	if($wday=='5') // if it's Friday, show the weekend, plus Monday
+	{
+		$dates[] = $today + 86400;		// Saturday
+		$dates[] = $today + (2*86400);	// Sunday
+	}
+	if($wday=='6') // if it's Saturday, show Sunday, plus Monday
+	{
+		$dates[] = $today + 86400;		// Sunday
+	}
+	$dates[] = $dates[count($dates)-1] + 86400; // the next business day
+
+	$extra_data = $GLOBALS['css']."\n"
+			. '<table border="0" width="100%" cellspacing="0" cellpadding="1">'
+			. '<tr><td valign="top" width="100%">';
+	foreach($dates as $id=>$day)
+	{
+		$dayprint = ExecMethod('calendar.uicalendar.print_day',
+							Array(
+								'year'  => date('Y',$day),
+								'month' => date('m',$day),
+								'day'   => date('d',$day)
+							));
+		$extra_data .= '<font class="event-off" style="font-weight: bold">&nbsp;&nbsp&nbsp;'.lang(date('l',$day)) .'</font><br />' . $dayprint;
+	}
+	$extra_data .= '</td></tr></table>'."\n";
+
+	$GLOBALS['extra_data'] = $extra_data;
+
+	unset($dates);
+	unset($today);
+	unset($extra_data);
+?>
Index: /tags/calendar/0.9.3/inc/hook_sidebox_menu.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/hook_sidebox_menu.inc.php	(revision 581)
+++ /tags/calendar/0.9.3/inc/hook_sidebox_menu.inc.php	(revision 581)
@@ -0,0 +1,66 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar's Sidebox-Menu for idots-template                  *
+  * http://www.egroupware.org                                                *
+  * Written by Pim Snel <pim@lingewoud.nl>                                   *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+{
+
+ /*
+	This hookfile is for generating an app-specific side menu used in the idots
+	template set.
+
+	$menu_title speaks for itself
+	$file is the array with link to app functions
+
+	display_sidebox can be called as much as you like
+ */
+
+	$menu_title = $GLOBALS['phpgw_info']['apps'][$appname]['title'] . ' '. lang('Menu');
+	$file = Array(
+		'New Entry'   => $GLOBALS['phpgw']->link('/index.php','menuaction=calendar.uicalendar.add'),
+		'_NewLine_', // give a newline
+		'Today'=>$GLOBALS['phpgw']->link('/index.php','menuaction=calendar.uicalendar.day'),
+		'This week'=>$GLOBALS['phpgw']->link('/index.php','menuaction=calendar.uicalendar.week'),
+		'This month'=>$GLOBALS['phpgw']->link('/index.php','menuaction=calendar.uicalendar.month'),
+		'This year'=>$GLOBALS['phpgw']->link('/index.php','menuaction=calendar.uicalendar.year'),
+		'Group Planner'=>$GLOBALS['phpgw']->link('/index.php','menuaction=calendar.uicalendar.planner'),
+		//'Daily Matrix View'=>$GLOBALS['phpgw']->link('/index.php','menuaction=calendar.uicalendar.matrixselect'),
+		'_NewLine_', // give a newline
+		'Import'=>$GLOBALS['phpgw']->link('/index.php','menuaction=calendar.uiicalendar.import'),
+		'Report of hours'=>$GLOBALS['phpgw']->link('/calendar/inc/hourReport.php',''),
+		'Public Calendars'=> "javascript:openwindow('calendar/templates/celepar/publicView.php')"
+	);
+	display_sidebox($appname,$menu_title,$file);
+
+	if ($GLOBALS['phpgw_info']['user']['apps']['preferences'])
+	{
+		$menu_title = lang('Preferences');
+		$file = Array(
+			'Calendar preferences'=>$GLOBALS['phpgw']->link('/preferences/preferences.php','appname=calendar'),
+			'Grant Access'=>$GLOBALS['phpgw']->link('/index.php','menuaction=preferences.uiaclprefs.index&acl_app=calendar'),
+			'Edit Categories' =>$GLOBALS['phpgw']->link('/index.php','menuaction=preferences.uicategories.index&cats_app=calendar&cats_level=True&global_cats=True'),
+		);
+		display_sidebox($appname,$menu_title,$file);
+	}
+
+	if ($GLOBALS['phpgw_info']['user']['apps']['admin'])
+	{
+		$menu_title = lang('Administration');
+		$file = Array(
+			'Configuration'=>$GLOBALS['phpgw']->link('/index.php','menuaction=admin.uiconfig.index&appname=calendar'),
+			'Custom Fields'=>$GLOBALS['phpgw']->link('/index.php','menuaction=calendar.uicustom_fields.index'),
+			'Holiday Management'=>$GLOBALS['phpgw']->link('/index.php','menuaction=calendar.uiholiday.admin'),
+			'Import CSV-File' => $GLOBALS['phpgw']->link('/calendar/csv_import.php'),
+			'Global Categories' =>$GLOBALS['phpgw']->link('/index.php','menuaction=admin.uicategories.index&appname=calendar'),
+		);
+		display_sidebox($appname,$menu_title,$file);
+	}
+}
+?>
Index: /tags/calendar/0.9.3/inc/class.bogroup_access.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.bogroup_access.inc.php	(revision 580)
+++ /tags/calendar/0.9.3/inc/class.bogroup_access.inc.php	(revision 580)
@@ -0,0 +1,107 @@
+<?php
+
+  /**************************************************************************\
+  * Expresso Livre - Grant Group Access - administration                     *
+  *															                 *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+class bogroup_access
+{
+	final function __construct(){
+		// Including ExpressoMail Classes
+		if(file_exists("../expressoMail1_2/inc/class.db_functions.inc.php"))
+			include_once("../expressoMail1_2/inc/class.db_functions.inc.php");
+		if(file_exists("../expressoMail1_2/inc/class.ldap_functions.inc.php"))
+			include_once("../expressoMail1_2/inc/class.ldap_functions.inc.php");
+	}
+
+	public final function search_user($params){			
+		$objLdap = new ldap_functions();
+		$objLdap -> ldapRootConnect();
+		$ldap = $objLdap -> ds;		
+		$search = $params['search'];
+		$accounttype = $params['type'];
+		$justthese = array("cn","uid", "uidNumber","gidNumber");
+    	$users_list=ldap_search($ldap, $_SESSION['phpgw_info']['expressomail']['server']['ldap_context'], "(&(phpgwAccountType=$accounttype) (|(cn=*$search*)(mail=$search*)) )", $justthese);    	
+    	if (ldap_count_entries($ldap, $users_list) == 0)
+    	{
+    		$return['status'] = 'false';
+    		$return['msg'] = 'Nenhum resultado encontrado.';
+    		return $return;
+    	}    	
+    	ldap_sort($ldap, $users_list, "cn");    	
+    	$entries = ldap_get_entries($ldap, $users_list);    	    	
+		$options = '';
+		for ($i=0; $i<$entries['count']; $i++)
+		{
+			$value = $entries[$i][$accounttype == "u" ? 'uidnumber' : 'gidnumber'][0];		
+			if($entries[$i]['mail'][0])
+				$mail = "(".$entries[$i]['mail'][0].")";
+			$options .= "<option value=" . $value. ">" . $entries[$i]['cn'][0] . " $mail" . "</option>";
+		}    	
+    	return $options;		
+	} 
+	
+	public function get_grants($app){
+		$db2 = $GLOBALS['phpgw']->db;
+		$db2->select('phpgw_acl',array('acl_location','acl_account','acl_rights'),"acl_appname='".$app."' AND acl_location <> 'run'",__LINE__,__FILE__);
+			
+		$grants = array();
+		while ($db2->next_record())	{				
+			$objectID = $db2->f('acl_account');
+			$type = $GLOBALS['phpgw']->accounts->get_type($objectID);				
+			if($type == 'g') {
+				$userID	= $db2->f('acl_location');
+				$rights = $db2->f('acl_rights');				
+				$grants[$userID.";".$objectID] = array( "userID"=> $userID,"groupID"=> $objectID, "rights" => $rights);
+			}
+		}	
+		unset($db2);
+		return $grants;
+	}
+	
+	public final function add_user($params) {
+		
+		list($user,$group,$rights) = explode(";",$params['id']);
+		$objDB = new db_functions();
+		$db = $objDB -> db;
+		$db -> select('phpgw_acl','count(*)',array(
+						'acl_appname'  => "calendar",
+						'acl_location' => $user,
+						'acl_account'  => $group),__LINE__,__FILE__);
+						
+		// Verify if already exists....
+		if ($db->next_record() && $db->f(0)) {
+			return false; 		
+		}	
+		
+		$where = false;						
+		$db -> insert('phpgw_acl',array(
+						'acl_appname'  => "calendar",
+						'acl_location' => $user,
+						'acl_account'  => $group,
+						'acl_rights'   => $rights
+			), $where, __LINE__,__FILE__);
+		
+		return true;
+	}
+	
+	public final function rem_user($params){
+		
+		list($user,$group) = explode(";",$params['id']);
+		$objDB = new db_functions();
+		$db = $objDB -> db;
+		$db -> delete('phpgw_acl',array(
+						'acl_appname'  => "calendar",
+						'acl_location' => $user,
+						'acl_account'  => $group),__LINE__,__FILE__);
+		return true;
+	}
+}
+?>
Index: /tags/calendar/0.9.3/inc/hook_email.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/hook_email.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/inc/hook_email.inc.php	(revision 2)
@@ -0,0 +1,53 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar                                                    *
+  * http://www.egroupware.org                                                *
+  * Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
+  *          http://www.radix.net/~cknudsen                                  *
+  * Written by Mark Peters <skeeter@phpgroupware.org>                        *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	global $calendar_id;
+
+	$d1 = strtolower(substr($GLOBALS['phpgw_info']['server']['app_inc'],0,3));
+	if($d1 == 'htt' || $d1 == 'ftp')
+	{
+		echo 'Failed attempt to break in via an old Security Hole!<br>'."\n";
+		$phpgw->common->phpgw_exit();
+	}
+	unset($d1);
+
+	if ($calendar_id)
+	{
+		$GLOBALS['phpgw']->translation->add_app('calendar');
+
+		$cal = CreateObject('calendar.uicalendar');
+		//echo "Event ID: $calendar_id<br>\n";
+
+		if ($event = $cal->bo->read_entry($calendar_id))
+		{
+			echo $cal->timematrix(
+				Array(
+					'date'		=> $GLOBALS['phpgw']->datetime->localdates(mktime(0,0,0,$event['start']['month'],$event['start']['mday'],$event['start']['year']) - $phpgw->calendar->tz_offset),
+					'starttime'	=> $cal->bo->splittime('000000',False),
+					'endtime'	=> 0,
+					'participants'	=> $event['participants'])
+					) .
+
+				'</td></tr><tr><td>' .
+
+				$cal->view_event($event) .
+
+				'</td></tr><tr><td align="center">' .
+
+				$cal->get_response($calendar_id);
+		}
+		unset($cal); unset($event);
+	}
+?>
Index: /tags/calendar/0.9.3/inc/hook_home.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/hook_home.inc.php	(revision 234)
+++ /tags/calendar/0.9.3/inc/hook_home.inc.php	(revision 234)
@@ -0,0 +1,108 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar                                                    *
+  * http://www.egroupware.org                                                *
+  * Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
+  *          http://www.radix.net/~cknudsen                                  *
+  * Written by Mark Peters <skeeter@phpgroupware.org>                        *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+	$phpgw_flags = Array(
+		'currentapp'	=>	'calendar',
+		'noheader'	=>	True,
+		'nonavbar'	=>	True,
+		'noappheader'	=>	True,
+		'noappfooter'	=>	True,
+		'nofooter'	=>	True
+	);
+
+	$GLOBALS['phpgw_info']['flags'] = $phpgw_flags;
+
+	$d1 = strtolower(substr(PHPGW_APP_INC,0,3));
+	if($d1 == 'htt' || $d1 == 'ftp' )
+	{
+		echo 'Failed attempt to break in via an old Security Hole!<br>'."\n";
+		$GLOBALS['phpgw']->common->phpgw_exit();
+	}
+	unset($d1);
+
+	$showevents = (int)$GLOBALS['phpgw_info']['user']['preferences']['calendar']['mainscreen_showevents'];
+	if($showevents>0)
+	{
+		$GLOBALS['phpgw']->translation->add_app('calendar');
+		if(!is_object($GLOBALS['phpgw']->datetime))
+		{
+			$GLOBALS['phpgw']->datetime = CreateObject('phpgwapi.date_time');
+		}
+
+		$GLOBALS['date'] = date('Ymd',$GLOBALS['phpgw']->datetime->users_localtime);
+		$GLOBALS['g_year'] = substr($GLOBALS['date'],0,4);
+		$GLOBALS['g_month'] = substr($GLOBALS['date'],4,2);
+		$GLOBALS['g_day'] = substr($GLOBALS['date'],6,2);
+		$GLOBALS['owner'] = $GLOBALS['phpgw_info']['user']['account_id'];
+		$GLOBALS['css'] = "\n".'<style type="text/css">'."\n".'<!--'."\n"
+			. ExecMethod('calendar.uicalendar.css').'-->'."\n".'</style>';
+
+		if($showevents==2)
+		{
+			$_page = "small";
+		}
+		else
+		{
+			$page_ = explode('.',$GLOBALS['phpgw_info']['user']['preferences']['calendar']['defaultcalendar']);
+			$_page = substr($page_[0],0,7);	// makes planner from planner_{user|category}
+			if ($_page=='index' || ($_page != 'day' && $_page != 'week' && $_page != 'month' && $_page != 'year' && $_page != 'planner'))
+			{
+				$_page = 'month';
+//			$GLOBALS['phpgw']->preferences->add('calendar','defaultcalendar','month');
+//			$GLOBALS['phpgw']->preferences->save_repository();
+			}
+		}
+
+		if(!@file_exists(PHPGW_INCLUDE_ROOT.'/calendar/inc/hook_home_'.$_page.'.inc.php'))
+		{
+			$_page = 'day';
+		}
+		include(PHPGW_INCLUDE_ROOT.'/calendar/inc/hook_home_'.$_page.'.inc.php');
+
+		$title = lang('Calendar');
+
+		$portalbox = CreateObject('phpgwapi.listbox',
+			Array(
+				'title'	=> $title,
+				'primary'	=> $GLOBALS['phpgw_info']['theme']['navbar_bg'],
+				'secondary'	=> $GLOBALS['phpgw_info']['theme']['navbar_bg'],
+				'tertiary'	=> $GLOBALS['phpgw_info']['theme']['navbar_bg'],
+				'width'	=> '100%',
+				'outerborderwidth'	=> '0',
+				'header_background_image'	=> $GLOBALS['phpgw']->common->image('phpgwapi/templates/default','bg_filler')
+			)
+		);
+
+		$app_id = $GLOBALS['phpgw']->applications->name2id('calendar');
+		$GLOBALS['portal_order'][] = $app_id;
+		$var = Array(
+			'up'	=> Array('url'	=> '/set_box.php', 'app'	=> $app_id),
+			'down'	=> Array('url'	=> '/set_box.php', 'app'	=> $app_id),
+			'close'	=> Array('url'	=> '/set_box.php', 'app'	=> $app_id),
+			'question'	=> Array('url'	=> '/set_box.php', 'app'	=> $app_id),
+			'edit'	=> Array('url'	=> '/set_box.php', 'app'	=> $app_id)
+		);
+
+		while(list($key,$value) = each($var))
+		{
+			$portalbox->set_controls($key,$value);
+		}
+
+		$portalbox->data = Array();
+
+		echo "\n".'<!-- BEGIN Calendar info -->'."\n".$portalbox->draw($GLOBALS['extra_data'])."\n".'<!-- END Calendar info -->'."\n";
+		unset($cal);
+	}
+	flush();
+	unset($showevents);
+?>
Index: /tags/calendar/0.9.3/inc/class.calendar_icap.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.calendar_icap.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/inc/class.calendar_icap.inc.php	(revision 2)
@@ -0,0 +1,346 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - ICal Calendar                                               *
+  * http://www.egroupware.org                                                *
+  * Created by Mark Peters <skeeter@phpgroupware.org>                        *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	if (isset($GLOBALS['phpgw_info']['flags']['included_classes']['calendar_']) &&
+		$GLOBALS['phpgw_info']['flags']['included_classes']['calendar_'] == True)
+	{
+		return;
+	}
+
+	$GLOBALS['phpgw_info']['flags']['included_classes']['calendar_'] = True;
+
+	class calendar_ extends calendar__
+	{
+		function open($calendar='',$user='',$passwd='',$options='')
+		{
+			if($user=='')
+			{
+				$user = $GLOBALS['phpgw_info']['user']['account_lid'];
+			}
+			elseif(is_int($user))
+			{
+				$this->user = $GLOBALS['phpgw']->accounts->id2name($user);
+			}
+			elseif(is_string($user))
+			{
+				$this->user = $user;
+			}
+			if($options != '')
+			{
+				$this->stream = mcal_open('{'.$GLOBALS['phpgw_info']['server']['icap_server'].'/'.$GLOBALS['phpgw_info']['server']['icap_type'].'}'.$calendar,$this->user,$passwd,$options);
+			}
+			else
+			{
+				$this->stream = mcal_open('{'.$GLOBALS['phpgw_info']['server']['icap_server'].'/'.$GLOBALS['phpgw_info']['server']['icap_type'].'}'.$calendar,$this->user,$passwd);
+			}
+		}
+
+		function popen($calendar='',$user='',$passwd='',$options='')
+		{
+			if($user=='')
+			{
+				$this->user = $GLOBALS['phpgw_info']['user']['account_lid'];
+			}
+			elseif(is_int($user))
+			{
+				$this->user = $GLOBALS['phpgw']->accounts->id2name($user);
+			}
+			elseif(is_string($user))
+			{
+				$this->user = $user;
+			}
+			if($options != '')
+			{
+				$this->stream = mcal_popen('{'.$GLOBALS['phpgw_info']['server']['icap_server'].'/'.$GLOBALS['phpgw_info']['server']['icap_type'].'}'.$calendar,$this->user,$passwd,$options);
+			}
+			else
+			{
+				$this->stream = mcal_popen('{'.$GLOBALS['phpgw_info']['server']['icap_server'].'/'.$GLOBALS['phpgw_info']['server']['icap_type'].'}'.$calendar,$this->user,$passwd);
+			}
+		}
+
+		function reopen($calendar,$options='')
+		{
+			if($options != '')
+			{
+				$this->stream = mcal_reopen($calendar,$options);
+			}
+			else
+			{
+				$this->stream = mcal_reopen($calendar);
+			}
+		}
+
+		function close($options='')
+		{
+			if($options != '')
+			{
+				return mcal_close($this->stream,$options);
+			}
+			else
+			{
+				return mcal_close($this->stream);
+			}
+		}
+
+		function create_calendar($calendar)
+		{
+			return mcal_create_calendar($this->stream,$calendar);
+		}
+
+		function rename_calendar($old_name,$new_name)
+		{
+			return mcal_rename_calendar($this->stream,$old_name,$new_name);
+		}
+
+		function delete_calendar($calendar)
+		{
+			return mcal_delete_calendar($this->stream,$calendar);
+		}
+
+		function fetch_event($event_id,$options='')
+		{
+			if(!isset($this->stream))
+			{
+				return False;
+			}
+
+			$this->event = CreateObject('calendar.calendar_item');
+
+			if($options != '')
+			{
+				$this->event = mcal_fetch_event($this->stream,$event_id,$options);
+			}
+			else
+			{
+				$this->event = mcal_fetch_event($this->stream,$event_id);
+			}
+
+			// Need to load the $this->event variable with the $event structure from
+			// the mcal_fetch_event() call
+			// Use http://www.php.net/manual/en/function.mcal-fetch-event.php as the reference
+			// This only needs legacy support
+
+			return $this->event;
+		}
+
+		function list_events($startYear,$startMonth,$startDay,$endYear='',$endMonth='',$endYear='')
+		{
+			if($endYear != '' && $endMonth != '' && $endDay != '')
+			{
+				$events = mcal_list_events($this->stream,$startYear,$startMonth,$startDay,$endYear,$endMonth,$endYear);
+			}
+			else
+			{
+				$events = mcal_list_events($this->stream,$startYear,$startMonth,$startDay);
+			}
+
+			return $events;
+		}
+
+		function append_event()
+		{
+			return mcal_append_event($this->stream);
+		}
+
+		function store_event()
+		{
+			return mcal_store_event($this->stream);
+		}
+
+		function delete_event($event_id)
+		{
+			return mcal_delete_event($this->stream,$event_id);
+		}
+
+		function snooze($event_id)
+		{
+			return mcal_snooze($this->stream,$event_id);
+		}
+
+		function list_alarms($begin_year='',$begin_month='',$begin_day='',$end_year='',$end_month='',$end_day='')
+		{
+			if($end_day == '')
+			{
+				if($end_month == '')
+				{
+					if($end_year == '')
+					{
+						if($begin_day == '')
+						{
+							if($begin_month == '')
+							{
+								if($begin_year == '')
+								{
+									return mcal_list_alarms($this->stream);
+								}
+								else
+								{
+									return mcal_list_alarms($this->stream,$begin_year);
+								}
+							}
+							else
+							{
+								return mcal_list_alarms($this->stream,$begin_year,$begin_month);
+							}
+						}
+						else
+						{
+							return mcal_list_alarms($this->stream,$begin_year,$begin_month,$begin_day);
+						}
+					}
+					else
+					{
+						return mcal_list_alarms($this->stream,$begin_year,$begin_month,$begin_day,$end_year);
+					}
+				}
+				else
+				{
+					return mcal_list_alarms($this->stream,$begin_year,$begin_month,$begin_day,$end_year,$end_month);
+				}
+			}
+			else
+			{
+				return mcal_list_alarms($this->stream,$begin_year,$begin_month,$begin_day,$end_year,$end_month,$end_day);
+			}
+		}
+
+		function event_init()
+		{
+			$this->event = CreateObject('calendar.calendar_item');
+			return mcal_event_init($this->stream);
+		}
+
+		function set_category($category='')
+		{
+			calendar__::set_category($category);
+			return mcal_event_set_category($this->stream,$category);
+		}
+
+		function set_title($title='')
+		{
+			calendar__::set_title($title);
+			return mcal_event_set_title($this->stream,$title);
+		}
+
+		function set_description($description='')
+		{
+			calendar__::set_description($description);
+			return mcal_event_set_description($this->stream,$description);
+		}
+		
+		function set_ex_participants($ex_participants='')
+		{
+			calendar__::set_ex_participants($ex_participants);
+			return mcal_event_set_ex_participants($this->stream,$ex_participants);
+		}
+
+		function set_start($year,$month,$day=0,$hour=0,$min=0,$sec=0)
+		{
+			calendar__::set_start($year,$month,$day,$hour,$min,$sec);
+			return mcal_event_set_start($this->stream,$year,$month,$day,$hour,$min,$sec);
+		}
+
+		function set_end($year,$month,$day=0,$hour=0,$min=0,$sec=0)
+		{
+			calendar__::set_end($year,$month,$day,$hour,$min,$sec);
+			return mcal_event_set_end($this->stream,$year,$month,$day,$hour,$min,$sec);
+		}
+
+		function set_alarm($alarm)
+		{
+			calendar__::set_alarm($alarm);
+			return mcal_event_set_alarm ($this->stream,$alarm);
+		}
+
+		function set_class($class)
+		{
+			calendar__::set_class($class);
+			return mcal_event_set_class($this->stream,$class);
+		}
+
+		// The function definition doesn't look correct...
+		// Need more information for this function
+		function next_recurrence($weekstart,$next)
+		{
+			return mcal_next_recurrence($this->stream,$weekstart,$next);
+		}
+
+		function set_recur_none()
+		{
+			calendar__::set_recur_none();
+			return mcal_event_set_recur_none($this->stream);
+		}
+
+		function set_recur_daily($year,$month,$day,$interval)
+		{
+			calendar__::set_recur_daily($year,$month,$day,$interval);
+			return mcal_event_set_recur_daily($this->stream,$year,$month,$day,$interval);
+		}
+
+		function set_recur_weekly($year,$month,$day,$interval,$weekdays)
+		{
+			calendar__::set_recur_weekly($year,$month,$day,$interval,$weekdays);
+			return mcal_event_set_recur_weekly($this->stream,$year,$month,$day,$interval,$weekdays);
+		}
+
+		function set_recur_monthly_mday($year,$month,$day,$interval)
+		{
+			calendar__::set_recur_monthly_mday($year,$month,$day,$interval);
+			return mcal_event_set_recur_monthly_mday($this->stream,$year,$month,$day,$interval);
+		}
+
+		function set_recur_monthly_wday($year,$month,$day,$interval)
+		{
+			calendar__::set_recur_monthly_wday($year,$month,$day,$interval);
+			return mcal_event_set_recur_monthly_wday($this->stream,$year,$month,$day,$interval);
+		}
+
+		function set_recur_yearly($year,$month,$day,$interval)
+		{
+			calendar__::set_recur_yearly($year,$month,$day,$interval);
+			return mcal_event_set_recur_yearly($this->stream,$year,$month,$day,$interval);
+		}
+
+		function fetch_current_stream_event()
+		{
+			$this->event = mcal_fetch_current_stream_event($this->stream);
+			return $this->event;
+		}
+
+		function add_attribute($attribute,$value)
+		{
+			calendar__::add_attribute($attribute,$value);
+			return mcal_event_add_attribute($this->stream,$attribute,$value);
+		}
+
+		function expunge()
+		{
+			return mcal_expunge($this->stream);
+		}
+
+		/**************** Local functions for ICAL based Calendar *****************/
+
+		function set_status($id,$owner,$status)
+		{
+			$status_code_short = Array(
+				REJECTED =>	'R',
+				NO_RESPONSE	=> 'U',
+				TENTATIVE	=>	'T',
+				ACCEPTED	=>	'A'
+			);
+			$this->add_attribute('status['.$owner.']',$status_code_short[$status]);
+	//		$this->stream->query("UPDATE calendar_entry_user SET cal_status='".$status_code_short[$status]."' WHERE cal_id=".$id." AND cal_login=".$owner,__LINE__,__FILE__);
+			return True;
+		}
+	}
Index: /tags/calendar/0.9.3/inc/class.uipublicview.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.uipublicview.inc.php	(revision 41)
+++ /tags/calendar/0.9.3/inc/class.uipublicview.inc.php	(revision 41)
@@ -0,0 +1,1069 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar                                                    *
+  * http://www.eGroupWare.org                                                *
+  * Maintained and further developed by RalfBecker@outdoor-training.de       *
+  * Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
+  *          http://www.radix.net/~cknudsen                                  *
+  * Originaly modified by Mark Peters <skeeter@phpgroupware.org>             *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	class uipublicview
+	{
+		var $template;
+		var $template_dir;
+
+		var $bo;
+		var $cat;
+
+		var $holidays;
+		var $holiday_color;
+		
+		// Variable defined to view public calendars;
+		var $publicView = False;
+		var $user = False;
+
+		var $debug = False;
+//		var $debug = True;
+
+		var $cat_id;
+		var $theme;
+		var $link_tpl;
+
+		// planner related variables
+		var $planner_header;
+		var $planner_rows;
+
+		var $planner_group_members;
+
+		var $planner_firstday;
+		var $planner_lastday;
+		var $planner_days;
+
+		var $planner_end_month;
+		var $planner_end_year;
+		var $planner_days_in_end_month;
+
+		var $planner_intervals = array(	// conversation hour and interval depending on intervals_per_day
+					//                                  1 1 1 1 1 1 1 1 1 1 2 2 2 2
+					//              0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
+						'1' => array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), // 0=0-23h
+						'2' => array(0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0), // 0=0-12h, 1=12-23h
+						'3' => array(0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2), // 0=0-12h, 2=12-18h, 3=18-23h
+						'4' => array(0,0,0,0,0,0,0,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3)  // 0=0-7, 7-12h, 3=12-18h, 4=18-23h
+					);
+
+		var $public_functions = array(		
+			'index' => True,
+			'publicView'  => True,
+			'get_publicView' => True,
+			'view' => True,
+			'header' => True,
+			'footer' => True,
+			
+		);
+
+		function uipublicview()
+		{ 
+			$GLOBALS['phpgw']->nextmatchs = CreateObject('phpgwapi.nextmatchs');
+			$GLOBALS['phpgw']->browser    = CreateObject('phpgwapi.browser');
+
+			$this->theme = $GLOBALS['phpgw_info']['theme'];
+
+			$this->bo = CreateObject('calendar.bocalendar',1);
+			$this->cat = &$this->bo->cat;
+			print_debug('BO Owner',$this->bo->owner);
+
+			$this->template = $GLOBALS['phpgw']->template;
+			$this->template_dir = $GLOBALS['phpgw']->common->get_tpl_dir('calendar');
+			$this->holiday_color = (substr($this->theme['bg06'],0,1)=='#'?'':'#').$this->theme['bg06'];
+
+			$this->cat_id   = $this->bo->cat_id;
+
+			$this->link_tpl = CreateObject('phpgwapi.Template',$this->template_dir);
+			$this->link_tpl->set_unknowns('remove');
+			$this->link_tpl->set_file(
+				Array(
+					'link_picture'	=> 'link_pict.tpl'
+				)
+			);
+			
+			$this->link_tpl->set_block('link_picture','link_pict','link_pict');
+			$this->link_tpl->set_block('link_picture','pict','pict');
+			$this->link_tpl->set_block('link_picture','link_open','link_open');
+			$this->link_tpl->set_block('link_picture','link_close','link_close');
+			$this->link_tpl->set_block('link_picture','link_text','link_text');
+
+			if($this->bo->use_session)
+			{
+				// save return-fkt for add, view, ...
+				list(,,$fkt) = explode('.',$_GET['menuaction']);
+				if ($fkt == 'day' || $fkt == 'week' || $fkt == 'month' || $fkt == 'year' || $fkt == 'planner')
+				{
+					$this->bo->return_to = $_GET['menuaction'].
+						sprintf('&date=%04d%02d%02d',$this->bo->year,$this->bo->month,$this->bo->day);
+				}
+				$this->bo->save_sessiondata();
+			}
+			$this->always_app_header = True;
+			
+			
+			print_debug('UI',$this->_debug_sqsof());
+
+			if (!is_object($GLOBALS['phpgw']->html))
+			{
+				$GLOBALS['phpgw']->html = CreateObject('phpgwapi.html');
+			}
+			$this->html = &$GLOBALS['phpgw']->html;
+		}
+
+		/* Public functions */
+
+		function index($params='')
+		{
+			if (!$params)
+			{
+				foreach(array('date','year','month','day') as $field)
+				{
+					if (isset($_GET[$field]))
+					{
+						$params[$field] = $_GET[$field];
+					}
+				}
+			}
+			$GLOBALS['phpgw']->redirect($this->page('',$params));
+		}
+
+		/* Private functions */
+		function _debug_sqsof()
+		{
+			$data = array(
+				'filter'     => $this->bo->filter,
+				'cat_id'     => $this->bo->cat_id,
+				'owner'      => $this->bo->owner,
+				'year'       => $this->bo->year,
+				'month'      => $this->bo->month,
+				'day'        => $this->bo->day,
+				'sortby'     => $this->bo->sortby,
+				'num_months' => $this->bo->num_months
+			);
+			Return _debug_array($data,False);
+		}
+
+		function output_template_array(&$p,$row,$list,$var)
+		{
+			if (!isset($var['hidden_vars']))
+			{
+				$var['hidden_vars'] = '';
+			}
+			if (!isset($var['tr_color']))
+			{
+				$var['tr_color'] = $GLOBALS['phpgw']->nextmatchs->alternate_row_color();
+			}
+			$p->set_var($var);
+			$p->parse($row,$list,True);
+		}
+
+		function page($_page='',$params='')
+		{
+			if($_page == '')
+			{
+				$page_ = explode('.',$this->bo->prefs['calendar']['defaultcalendar']);
+				$_page = $page_[0];
+
+				if ($_page=='planner_cat' || $_page=='planner_user')
+				{
+					$_page = 'planner';
+				}
+				elseif ($_page=='index' || ($_page != 'day' && $_page != 'week' && $_page != 'month' && $_page != 'year' && $_page != 'planner'))
+				{
+					$_page = 'month';
+					$GLOBALS['phpgw']->preferences->add('calendar','defaultcalendar','month');
+					$GLOBALS['phpgw']->preferences->save_repository();
+				}
+			}
+			
+			if($GLOBALS['phpgw_info']['flags']['currentapp'] == 'home' ||
+				strstr($GLOBALS['phpgw_info']['flags']['currentapp'],'mail'))	// email, felamimail, ...
+			{	
+				$page_app = 'calendar';
+			}
+			else
+			{	
+				$page_app = $GLOBALS['phpgw_info']['flags']['currentapp'];
+			}
+			$page_app = 'calendar.uipublicview.publicView';
+			
+			if (is_array($params))
+			{
+				$params['menuaction'] = $page_app;
+			}
+			else
+			{
+				$params = 'menuaction='.$page_app.$params;
+			}
+			return $GLOBALS['phpgw']->link('/index.php',$params);
+		}
+
+		function header()
+		{
+			$cols = 8;
+			if($this->bo->check_perms(PHPGW_ACL_PRIVATE) == True)
+			{
+				$cols++;
+			}
+
+			$tpl = $GLOBALS['phpgw']->template;
+			$tpl->set_unknowns('remove');
+
+			if (!file_exists($file = $this->template_dir.'/header.inc.php'))
+			{
+				$file = PHPGW_SERVER_ROOT . '/calendar/templates/default/header.inc.php';
+			}
+			include($file);
+			$header = $tpl->fp('out','head');
+			unset($tpl);
+			echo $header;
+		}
+
+		function footer(){
+		
+		}
+		function selectFilter()
+		{
+			
+			$menuaction = $_GET['menuaction'];
+
+			list(,,$method) = explode('.',$menuaction);
+
+			if (@$this->bo->printer_friendly)
+			{
+				return;
+			}
+
+			$p = $GLOBALS['phpgw']->template;
+			
+			$p->set_file(
+				Array(
+					'footer'	=> 'footer.tpl',
+					'form_button'	=> 'form_button_script.tpl'
+
+				)
+			);
+			$p->set_block('footer','footer_table','footer_table');
+			$p->set_block('footer','footer_row','footer_row');
+			$p->set_block('footer','blank_row','blank_row');
+
+			$m = $this->bo->month;
+			$y = $this->bo->year;
+
+			$thisdate = date('Ymd',mktime(0,0,0,$m,1,$y));
+			$y--;
+
+			$str = '';
+			for ($i = 0; $i < 25; $i++)
+			{
+				$m++;
+				if ($m > 12)
+				{
+					$m = 1;
+					$y++;
+				}
+				$d = mktime(0,0,0,$m,1,$y);
+				$d_ymd = date('Ymd',$d);
+				$str .= '<option value="'.$d_ymd.'"'.($d_ymd == $thisdate?' selected':'').'>'.lang(date('F', $d)).strftime(' %Y', $d).'</option>'."\n";
+			}
+			
+			$var = Array(
+				'action_url'	=> $this->page($method,''),
+				'form_name'	=> 'SelectMonth',
+				'label'		=> lang('Month'),
+				'user'	=> $this->user,
+				'form_label'	=> 'date',
+				'form_onchange'	=> 'document.SelectMonth.submit()',
+				'row'		=> $str,
+				'go'		=> lang('Go!')
+			);
+			
+			$this->output_template_array($p,'table_row','footer_row',$var);
+
+		   if($menuaction == 'calendar.uipublicview.week' || $menuaction == 'calendar.uipublicview.publicView')
+		   {
+				unset($thisdate);
+				$thisdate = mktime(0,0,0,$this->bo->month,$this->bo->day,$this->bo->year) - $GLOBALS['phpgw']->datetime->tz_offset;
+				$sun = $GLOBALS['phpgw']->datetime->get_weekday_start($this->bo->year,$this->bo->month,$this->bo->day) - $GLOBALS['phpgw']->datetime->tz_offset;
+
+				$str = '';
+				for ($i = -7; $i <= 7; $i++)
+				{
+					$begin = $sun + (7*24*60*60 * $i) + 12*60*60;	// we use midday, that changes in daylight-saveing does not effect us
+					$end = $begin + 6*24*60*60;
+                    $str .= '<option value="' . $GLOBALS['phpgw']->common->show_date($begin,'Ymd') . '"'.($begin <= $thisdate+12*60*60 && $end >= $thisdate+12*60*60 ? ' selected':'').'>'                    
+						. $GLOBALS['phpgw']->common->show_date($begin,$GLOBALS['phpgw_info']['user']['preferences']['common']['dateformat']) . ' - '
+                        . $GLOBALS['phpgw']->common->show_date($end,$GLOBALS['phpgw_info']['user']['preferences']['common']['dateformat'])
+                        . '</option>' . "\n";                        
+				}
+
+				$var = Array(
+					'action_url'	=> $this->page($method,''),
+					'form_name'	=> 'SelectWeek',
+					'label'		=> lang('Week'),
+					'form_label'	=> 'date',
+					'user'	=> $this->user,
+					'form_onchange'	=> 'document.SelectWeek.submit()',
+					'row'		=> $str,
+					'go'		=> lang('Go!')
+				);
+
+				$this->output_template_array($p,'table_row','footer_row',$var);
+			}
+
+			$str = '';
+			for ($i = ($this->bo->year - 3); $i < ($this->bo->year + 3); $i++)
+			{
+				$str .= '<option value="'.$i.'"'.($i == $this->bo->year?' selected':'').'>'.$i.'</option>'."\n";
+			}
+
+			$var = Array(
+				'action_url'	=> $this->page($method,''),
+				'form_name'	=> 'SelectYear',
+				'label'		=> lang('Year'),
+				'user'	=> $this->user,
+				'form_label'	=> 'year',
+				'form_onchange'	=> 'document.SelectYear.submit()',
+				'row'		=> $str,
+				'go'		=> lang('Go!')
+			);
+			$this->output_template_array($p,'table_row','footer_row',$var);
+
+			if($menuaction == 'calendar.uipublicview.planner')
+			{
+				$str = '';
+				$date_str = '';
+
+				if(isset($_GET['date']) && $_GET['date'])
+				{
+					$date_str .= '    <input type="hidden" name="date" value="'.$_GET['date'].'">'."\n";
+				}
+				$date_str .= '    <input type="hidden" name="month" value="'.$this->bo->month.'">'."\n";
+				$date_str .= '    <input type="hidden" name="day" value="'.$this->bo->day.'">'."\n";
+				$date_str .= '    <input type="hidden" name="year" value="'.$this->bo->year.'">'."\n";
+
+				for($i=1; $i<=6; $i++)
+				{
+					$str .= '<option value="'.$i.'"'.($i == $this->bo->num_months?' selected':'').'>'.$i.'</option>'."\n";
+				}
+				
+				$var = Array(
+					'action_url'	=> $this->page($method,''),
+					'form_name'	=> 'SelectNumberOfMonths',
+					'label'		=> lang('Number of Months'),
+					'hidden_vars' => $date_str,
+					'form_label'	=> 'num_months',
+					'form_onchange'	=> 'document.SelectNumberOfMonths.submit()',
+					'action_extra_field'	=> $date_str,
+					'user'	=> $this->user,
+					'row'		=> $str,
+					'go'		=> lang('Go!')
+				);
+				
+
+				$this->output_template_array($p,'table_row','footer_row',$var);
+			}
+				
+			$p->pparse('out','footer_table');
+			unset($p);
+		}
+
+
+		function link_to_entry($event,$month,$day,$year)
+		{
+			$str = '';
+			$is_private = !$event['public'] && !$this->bo->check_perms(PHPGW_ACL_READ,$event);
+			$viewable = !$this->bo->printer_friendly && $this->bo->check_perms(PHPGW_ACL_READ,$event);
+
+			$starttime = $this->bo->maketime($event['start']) - $GLOBALS['phpgw']->datetime->tz_offset;
+			$endtime = $this->bo->maketime($event['end']) - $GLOBALS['phpgw']->datetime->tz_offset;
+			$rawdate = mktime(0,0,0,$month,$day,$year);
+			$rawdate_offset = $rawdate - $GLOBALS['phpgw']->datetime->tz_offset;
+			$nextday = mktime(0,0,0,$month,$day + 1,$year) - $GLOBALS['phpgw']->datetime->tz_offset;
+			if ((int)$GLOBALS['phpgw']->common->show_date($starttime,'Hi') && $starttime == $endtime)
+			{
+				$time = $GLOBALS['phpgw']->common->show_date($starttime,$this->bo->users_timeformat);
+			}
+			elseif ($starttime <= $rawdate_offset && $endtime >= $nextday - 60)
+			{
+				$time = '[ '.lang('All Day').' ]';
+			}
+			elseif ((int)$GLOBALS['phpgw']->common->show_date($starttime,'Hi') || $starttime != $endtime)
+			{
+				if($starttime < $rawdate_offset && $event['recur_type'] == MCAL_RECUR_NONE)
+				{
+					$start_time = $GLOBALS['phpgw']->common->show_date($rawdate_offset,$this->bo->users_timeformat);
+				}
+				else
+				{
+					$start_time = $GLOBALS['phpgw']->common->show_date($starttime,$this->bo->users_timeformat);
+				}
+
+				if($endtime >= ($rawdate_offset + 86400))
+				{
+					$end_time = $GLOBALS['phpgw']->common->show_date(mktime(23,59,59,$month,$day,$year) - $GLOBALS['phpgw']->datetime->tz_offset,$this->bo->users_timeformat);
+				}
+				else
+				{
+					$end_time = $GLOBALS['phpgw']->common->show_date($endtime,$this->bo->users_timeformat);
+				}
+				$time = $start_time.'-'.$end_time;
+			}
+			else
+			{
+				$time = '';
+			}
+			
+			$texttitle = $texttime = $textdesc = $textlocation = $textstatus = '';
+
+			
+			
+			if(!$is_private)
+			{
+				// split text for better display by templates, also see $texttime $texttitle $textdesc $textlocation	
+				$textstatus=$this->bo->display_status($event['users_status']); 
+				
+			}
+
+			
+			$texttime=$time;
+			$texttitle=$this->bo->get_short_field($event,$is_private,'title');
+			$textdesc=(!$is_private && $event['description'] ? $this->bo->get_short_field($event,$is_private,'description'):'');
+			// added $textlocation but this must be activated in the actual pict_link.tpl file of the used template set
+			$textlocation=$this->bo->get_short_field($event,$is_private,'location');
+
+			if (!$is_private)
+			{
+				if($event['priority'] == 3)
+				{
+					$picture[] = Array(
+						'pict'	=> $GLOBALS['phpgw']->common->image('calendar','high'),
+						'width'	=> 16,
+						'height'=> 16,
+						'title' => lang('high priority')
+					);
+				}
+				if($event['recur_type'] == MCAL_RECUR_NONE)
+				{
+					$picture[] = Array(
+						'pict'	=> $GLOBALS['phpgw']->common->image('calendar','circle'),
+						'width'	=> 9,
+						'height'=> 9,
+						'title' => lang('single event')
+					);
+				}
+				else
+				{
+					$picture[] = Array(
+						'pict'	=> $GLOBALS['phpgw']->common->image('calendar','recur'),
+						'width'	=> 12,
+						'height'=> 12,
+						'title' => lang('recurring event')
+					);
+				}
+			}
+			$participants = $this->planner_participants($event['participants']);
+			if(count($event['participants']) > 1)
+			{
+				$picture[] = Array(
+					'pict'	=> $GLOBALS['phpgw']->common->image('calendar','multi_3'),
+					'width'	=> 14,
+					'height'=> 14,
+					'title' => $participants
+				);
+			}
+			else
+			{
+				$picture[] = Array(
+					'pict'	=>  $GLOBALS['phpgw']->common->image('calendar','single'),
+					'width'	=> 14,
+					'height'=> 14,
+					'title' => $participants
+				);
+			}
+			if($event['public'] == 0)
+			{
+				$picture[] = Array(
+					'pict'	=> $GLOBALS['phpgw']->common->image('calendar','private'),
+					'width'	=> 13,
+					'height'=> 13,
+					'title' => lang('private')
+				);
+			}
+			if(@isset($event['alarm']) && count($event['alarm']) >= 1 && !$is_private)
+			{
+				// if the alarm is to go off the day before the event
+				// the icon does not show up because of 'alarm_today'
+				// - TOM
+				if($this->bo->alarm_today($event,$rawdate_offset,$starttime))
+				{
+					$picture[] = Array(
+						'pict'  => $GLOBALS['phpgw']->common->image('calendar','alarm'),
+						'width' => 13,
+						'height'=> 13,
+						'title' => lang('alarm')
+					);
+				}
+			}
+
+			$description = $this->bo->get_short_field($event,$is_private,'description');
+			for($i=0;$i<count($picture);$i++)
+			{
+				$var = Array(
+					'pic_image' => $picture[$i]['pict'],
+					'width'     => $picture[$i]['width'],
+					'height'    => $picture[$i]['height'],
+					'title'     => $picture[$i]['title']
+				);
+				$this->output_template_array($this->link_tpl,'picture','pict',$var);
+			}
+			if ($texttitle)
+			{
+				$var = Array(
+			//		'text' => $text,
+					'time'=> $texttime,
+					'title'=> $texttitle,
+					'users_status'=>$textstatus,
+					'desc'=> $textdesc,
+					'location'=> $textlocation
+				);
+				$this->output_template_array($this->link_tpl,'picture','link_text',$var);
+			}
+
+			if ($viewable)
+			{
+				$this->link_tpl->parse('picture','link_close',True);
+			}
+			$str = $this->link_tpl->fp('out','link_pict');
+			$this->link_tpl->set_var('picture','');
+			$this->link_tpl->set_var('out','');
+//			unset($p);
+			return $str;
+		}
+
+		function planner_participants($parts)
+		{
+			static $id2lid;
+
+			$names = '';
+			while (list($id,$status) = each($parts))
+			{
+				$status = substr($this->bo->get_long_status($status),0,1);
+
+				if (!isset($id2lid[$id]))
+				{
+					$id2lid[$id] = $GLOBALS['phpgw']->common->grab_owner_name($id);
+				}
+				if (strlen($names))
+				{
+					$names .= ",\n";
+				}
+				$names .= $id2lid[$id]." ($status)";
+			}
+			if($this->debug)
+			{
+				echo '<!-- Inside participants() : '.$names.' -->'."\n";
+			}
+			return $names;
+		}
+
+
+		function week_header($month,$year,$display_name = False)
+		{
+			$this->weekstarttime = $GLOBALS['phpgw']->datetime->get_weekday_start($year,$month,1);
+
+			$p = CreateObject('phpgwapi.Template',$this->template_dir);
+			$p->set_unknowns('remove');
+			$p->set_file(
+				Array (
+					'month_header' => 'month_header.tpl'
+				)
+			);
+			$p->set_block('month_header','monthly_header','monthly_header');
+			$p->set_block('month_header','column_title','column_title');
+
+			$var = Array(
+				'bgcolor'	=> $this->theme['th_bg'],
+				'font_color'	=> $this->theme['th_text']
+			);
+			if($this->bo->printer_friendly && @$this->bo->prefs['calendar']['print_black_white'])
+			{
+				$var = Array(
+					'bgcolor'	=> '',
+					'font_color'	=> ''
+				);
+			}
+			$p->set_var($var);
+
+			$p->set_var('col_width','14');
+			if($display_name == True)
+			{
+				$p->set_var('col_title',lang('name'));
+				$p->parse('column_header','column_title',True);
+				$p->set_var('col_width','12');
+			}
+
+			for($i=0;$i<7;$i++)
+			{
+				$p->set_var('col_title',lang($GLOBALS['phpgw']->datetime->days[$i]));
+				$p->parse('column_header','column_title',True);
+			}
+			return $p->fp('out','monthly_header');
+		}
+
+		function display_week($startdate,$weekly,$cellcolor,$display_name = False,$owner=0,$monthstart=0,$monthend=0)
+		{	
+			if($owner == 0)
+			{
+				$owner = $GLOBALS['phpgw_info']['user']['account_id'];
+			}
+
+			$temp_owner = $this->bo->owner;
+			$publicView = $this -> publicView;
+
+			$str = '';
+			$p = CreateObject('phpgwapi.Template',$this->template_dir);
+			$p->set_unknowns('keep');
+
+			$p->set_file(
+				Array(
+					'month_header'	=> 'month_header.tpl',
+					'month_day'	=> 'month_day.tpl'
+				)
+			);
+			$p->set_block('month_header','monthly_header','monthly_header');
+			$p->set_block('month_header','month_column','month_column');
+			$p->set_block('month_day','month_daily','month_daily');
+			$p->set_block('month_day','day_event','day_event');
+			$p->set_block('month_day','event','event');
+
+			$p->set_var('extra','');
+			$p->set_var('col_width','14');
+			if($display_name)
+			{
+				$p->set_var('column_data',$GLOBALS['phpgw']->common->grab_owner_name($owner));
+				$p->parse('column_header','month_column',True);
+				$p->set_var('col_width','12');
+			}
+			$today = date('Ymd',$GLOBALS['phpgw']->datetime->users_localtime);
+			$daily = $this->set_week_array($startdate - $GLOBALS['phpgw']->datetime->tz_offset,$cellcolor,$weekly);
+			foreach($daily as $date => $day_params)
+			{
+				$year  = (int)substr($date,0,4);
+				$month = (int)substr($date,4,2);
+				$day   = (int)substr($date,6,2);
+				$var   = Array(
+					'column_data' => '',
+					'extra' => ''
+				);
+				$p->set_var($var);
+				if ($weekly || ($date >= $monthstart && $date <= $monthend))
+				{
+					if ($day_params['new_event'] && !$publicView)
+					{
+						$new_event_link = ' <a href="'.$this->page('add','&date='.$date).'">'
+							. '<img src="'.$GLOBALS['phpgw']->common->image('calendar','new3').'" width="10" height="10" title="'.lang('New Entry').'" border="0" align="center">'
+							. '</a>';
+						$day_number = '<a href="'.$this->page('day','&date='.$date).'">'.$day.'</a>';
+					}
+					else
+					{
+						$new_event_link = '';
+						$day_number = $day;
+					}
+
+					$var = Array(
+						'extra'		=> $day_params['extra'],
+						'new_event_link'=> $new_event_link,
+						'day_number'	=> $day_number
+					);
+							$p->set_var($var);
+
+					if(@$day_params['holidays'])
+					{
+						foreach($day_params['holidays'] as $key => $value)
+						{
+							$var = Array(
+								'day_events' => '<font face="'.$this->theme['font'].'" size="-1">'.$value.'</font>'.$GLOBALS['phpgw']->browser->br
+							);
+							$this->output_template_array($p,'daily_events','event',$var);
+						}
+					}
+
+					if($day_params['appts'])
+					{
+						$var = Array(
+							'week_day_font_size'	=> '2',
+							'events'		=> ''
+						);
+						$p->set_var($var);
+						$events = $this->bo->cached_events[$date];
+						foreach($events as $event)
+						{
+							if ($this->bo->rejected_no_show($event))
+							{
+								continue;	// user does not want to see rejected events
+							}
+							$p->set_var('day_events',$this->link_to_entry($event,$month,$day,$year));
+							$p->parse('events','event',True);
+							$p->set_var('day_events','');
+						}
+					}
+					$p->parse('daily_events','day_event',True);
+					$p->parse('column_data','month_daily',True);
+					$p->set_var('daily_events','');
+					$p->set_var('events','');
+				}
+				$p->parse('column_header','month_column',True);
+				$p->set_var('column_data','');
+			}
+			$this->bo->owner = $temp_owner;
+			return $p->fp('out','monthly_header');
+		}
+
+		function display_month($month,$year,$showyear,$owner=0)
+		{
+			if($this->debug)
+			{
+				echo '<!-- datetime:gmtdate = '.$GLOBALS['phpgw']->datetime->cv_gmtdate.' -->'."\n";
+			}
+
+			$this->bo->store_to_cache(
+				Array(
+					'syear'	=> $year,
+					'smonth'=> $month,
+					'sday'	=> 1
+				)
+			);
+
+			$monthstart = (int)(date('Ymd',mktime(0,0,0,$month    ,1,$year)));
+			$monthend   = (int)(date('Ymd',mktime(0,0,0,$month + 1,0,$year)));
+
+			$start = $GLOBALS['phpgw']->datetime->get_weekday_start($year, $month, 1);
+
+			if($this->debug)
+			{
+				echo '<!-- display_month:monthstart = '.$monthstart.' -->'."\n";
+				echo '<!-- display_month:start = '.date('Ymd H:i:s',$start).' -->'."\n";
+			}
+
+			$p = CreateObject('phpgwapi.Template',$this->template_dir);
+			$p->set_unknowns('keep');
+
+			$p->set_file(
+				Array(
+					'week' => 'month_day.tpl'
+				)
+			);
+			$p->set_block('week','m_w_table','m_w_table');
+			$p->set_block('week','event','event');
+
+			$var = Array(
+				'cols'      => 7,
+				'day_events'=> $this->week_header($month,$year,False)
+			);
+			$this->output_template_array($p,'row','event',$var);
+
+			$cellcolor = $this->theme['row_on'];
+
+			for($i = (int)($start + $GLOBALS['phpgw']->datetime->tz_offset);(int)(date('Ymd',$i)) <= $monthend;$i += 604800)
+			{
+				$cellcolor = $GLOBALS['phpgw']->nextmatchs->alternate_row_color($cellcolor);
+				$var = Array(
+					'day_events' => $this->display_week($i,False,$cellcolor,False,$owner,$monthstart,$monthend)
+				);
+				$this->output_template_array($p,'row','event',$var);
+			}
+			return $p->fp('out','m_w_table');
+		}
+
+		function display_weekly($params, $accountId)
+		{
+			if(!is_array($params))
+			{
+				$this->index();
+			}
+
+			$year = substr($params['date'],0,4);
+			$month = substr($params['date'],4,2);
+			$day = substr($params['date'],6,2);
+			$showyear = $params['showyear'];
+			$owners = $params['owners'];
+			
+			
+			$p = CreateObject('phpgwapi.Template',$this->template_dir);
+			$p->set_unknowns('keep');
+
+			$p->set_file(
+				Array(
+					'week'	=> 'month_day.tpl'
+				)
+			);
+			$p->set_block('week','m_w_table','m_w_table');
+			$p->set_block('week','event','event');
+
+			$start = $GLOBALS['phpgw']->datetime->get_weekday_start($year, $month, $day) + $GLOBALS['phpgw']->datetime->tz_offset;
+
+			$cellcolor = $this->theme['row_off'];
+
+			$true_printer_friendly = $this->bo->printer_friendly;
+
+			if(is_array($owners))
+			{
+				$display_name = True;
+				$counter = count($owners);
+				$owners_array = $owners;
+				$cols = 8;
+			}
+			else
+			{
+				$display_name = False;
+				$counter = 1;
+				$owners_array[0] = $owners;
+				$cols = 7;
+			}
+			$var = Array(
+				'cols'         => $cols,
+				'day_events'   => $this->week_header($month,$year,$display_name)
+			);
+			$this->output_template_array($p,'row','event',$var);
+
+			$tstart = $start - $GLOBALS['phpgw']->datetime->tz_offset;
+			$tstop = $tstart + 604800;
+			$original_owner = $this->bo->so->owner;
+
+			$this->bo->so->owner = $accountId;
+			$this->bo->so->open_box($accountId);
+			$this->bo->store_to_cache(
+					Array(
+						'syear'  => date('Y',$tstart),
+						'owner'	=> $original_owner,
+						'smonth' => date('m',$tstart),
+						'sday'   => date('d',$tstart),
+						'eyear'  => date('Y',$tstop),
+						'emonth' => date('m',$tstop),
+						'eday'   => date('d',$tstop)
+					)
+				);
+				
+			$p->set_var('day_events',$this->display_week($start,True,$cellcolor,$display_name,$accountId, True));
+				$p->parse('row','event',True);
+			
+			$this->bo->so->owner = $original_owner;
+			$this->bo->printer_friendly = $true_printer_friendly;
+			return $p->fp('out','m_w_table');
+		}
+		
+		function set_week_array($startdate,$cellcolor,$weekly)
+		{
+			for ($j=0,$datetime=$startdate;$j<7;$j++,$datetime += 86400)
+			{
+				$date = date('Ymd',$datetime + (60 * 60 * 2)); // +2h to be save when switching to and from dst, $datetime is alreay + TZ-Offset
+				print_debug('set_week_array : Date ',$date);
+
+				if($events = $this->bo->cached_events[$date])
+				{
+					print_debug('Date',$date);
+					print_debug('Appointments Found',count($events));
+
+					if (!$this->bo->prefs['calendar']['show_rejected'])
+					{
+						$appts = False;
+						foreach($events as $event)	// check for a not-rejected event
+						{
+							if (!$this->bo->rejected_no_show($event))
+							{
+								$appts = True;
+								break;
+							}
+						}
+					}
+					else
+					{
+						$appts = True;
+					}
+				}
+				else
+				{
+					$appts = False;
+				}
+
+				$holidays = $this->bo->cached_holidays[$date];
+				if($weekly)
+				{
+					$cellcolor = $GLOBALS['phpgw']->nextmatchs->alternate_row_color($cellcolor);
+				}
+
+				$day_image = '';
+				if($holidays)
+				{
+					$extra = ' bgcolor="'.$this->bo->holiday_color.'"';
+					$class = ($appts?'b':'').'minicalhol';
+					if ($date == $this->bo->today)
+					{
+						$day_image = ' background="'.$GLOBALS['phpgw']->common->image('calendar','mini_day_block').'"';
+					}
+				}
+				elseif ($date != $this->bo->today)
+				{
+					$extra = ' bgcolor="'.$cellcolor.'"';
+					$class = ($appts?'b':'').'minicalendar';
+				}
+				else
+				{
+					$extra = ' bgcolor="'.$GLOBALS['phpgw_info']['theme']['cal_today'].'"';
+					$class = ($appts?'b':'').'minicalendar';
+					$day_image = ' background="'.$GLOBALS['phpgw']->common->image('calendar','mini_day_block').'"';
+				}
+
+				if($this->bo->printer_friendly && @$this->bo->prefs['calendar']['print_black_white'])
+				{
+					$extra = '';
+				}
+
+				if(!$this->bo->printer_friendly && $this->bo->check_perms(PHPGW_ACL_ADD))
+				{
+					$new_event = True;
+				}
+				else
+				{
+					$new_event = False;
+				}
+				$holiday_name = Array();
+				if($holidays)
+				{
+					for($k=0;$k<count($holidays);$k++)
+					{
+						$holiday_name[] = $holidays[$k]['name'];
+					}
+				}
+				$week = '';
+				if (!$j || (!$weekly && $j && substr($date,6,2) == '01'))
+				{
+					$week = lang('week').' '.(int)((date('z',($startdate+(24*3600*4)))+7)/7);
+				}
+				$daily[$date] = Array(
+					'extra'		=> $extra,
+					'new_event'	=> $new_event,
+					'holidays'	=> $holiday_name,
+					'appts'		=> $appts,
+					'week'		=> $week,
+					'day_image'	=> $day_image,
+					'class'		=> $class
+				);
+			}
+
+			if($this->debug)
+			{
+				_debug_array($daily);
+			}
+
+			return $daily;
+		}
+		
+		function publicView()
+		{	
+			 						
+			$account_name = $_POST['user'] ? 
+							$_POST['user'] : 
+							($_GET['account_name'] ?
+							 $_GET['account_name'] : '');
+
+			$theme_css = $GLOBALS['phpgw_info']['server']['webserver_url'] . '/phpgwapi/templates/celepar/css/'.$GLOBALS['phpgw_info']['user']['preferences']['common']['theme'].'.css';
+		
+			echo '<html>'."\n"
+				.'<head>'."\n"
+				.'<LINK href="'.$theme_css.'" type=text/css rel=StyleSheet>'."\n"
+				.'</head><body>'
+				.'<div id="divAppboxHeader">'
+				.lang('weekly agenda of events')
+				.'</div><div id="divAppbox"  align="center" >';
+							 
+			if(!$account_name){			
+				echo '<font color="GREEN" size="+1">'.lang('it types login of the user to have access public agenda').'</font></center></div>';
+				return True;
+			}
+							 
+			$accounts = CreateObject('phpgwapi.accounts');
+			$accountId = $accounts->name2id($account_name);
+
+			if(!$accountId){			
+				echo '<font color="RED" size="+1">'.lang('this user does not exist').'</font></center></div>';
+				return True;
+			}
+
+			$prefs = CreateObject('phpgwapi.preferences', $accountId);
+			$account_prefs = $prefs->read();
+			
+			$publicView = $account_prefs['calendar']['public_view'];
+			
+			if($publicView){
+				$this -> user = $account_name;
+				$this-> selectFilter();				
+				echo $this->printer_publicView($this->get_publicView($accountId));
+				
+			}
+			else {
+				echo '<font color="RED" size="+1">'.lang('it types login of the user to have access public agenda').'</font></center></div>';
+			}
+
+			return True;	
+		}
+
+		function get_publicView($accountId)
+		{
+			// allow users to view public calendars;
+			$this -> publicView = True;
+			$this->bo->read_holidays();
+
+			$next = $GLOBALS['phpgw']->datetime->makegmttime(0,0,0,$this->bo->month,$this->bo->day + 7,$this->bo->year);
+			$prev = $GLOBALS['phpgw']->datetime->makegmttime(0,0,0,$this->bo->month,$this->bo->day - 7,$this->bo->year);
+
+			$var = Array(
+				'week_display'		=>	$this->display_weekly(
+					Array(
+						'date'		=> sprintf("%04d%02d%02d",$this->bo->year,$this->bo->month,$this->bo->day),
+						'showyear'	=> true, False
+					),$accountId
+				),
+				'print'			=>	$print
+			);
+
+			$p = CreateObject('phpgwapi.Template',$this->template_dir);
+			$p->set_file(
+				Array(
+					'week_t' => 'publicView.tpl'
+				)
+			);
+			$p->set_var($var);
+			return $p->fp('out','week_t');
+
+		}
+		
+		function printer_publicView($body)
+		{				
+			unset($GLOBALS['phpgw_info']['flags']['noheader']);
+			unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+			unset($GLOBALS['phpgw_info']['flags']['noappheader']);
+			unset($GLOBALS['phpgw_info']['flags']['noappfooter']);
+			
+			$new_body .= $this->bo->debug_string.$body;
+			return $new_body;
+		}
+		
+		
+	}
+?>
Index: /tags/calendar/0.9.3/inc/class.uicalendar.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.uicalendar.inc.php	(revision 663)
+++ /tags/calendar/0.9.3/inc/class.uicalendar.inc.php	(revision 663)
@@ -0,0 +1,5238 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar                                                    *
+  * http://www.eGroupWare.org                                                *
+  * Maintained and further developed by RalfBecker@outdoor-training.de       *
+  * Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
+  *          http://www.radix.net/~cknudsen                                  *
+  * Originaly modified by Mark Peters <skeeter@phpgroupware.org>             *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	class uicalendar
+	{
+		var $template;
+		var $template_dir;
+
+		var $bo;
+		var $cat;
+
+		var $holidays;
+		var $holiday_color;
+
+		var $debug = False;
+		//var $debug = True;
+
+		var $cat_id;
+		var $theme;
+		var $link_tpl;
+
+		// planner related variables
+		var $planner_header;
+		var $planner_rows;
+
+		var $planner_group_members;
+
+		var $planner_firstday;
+		var $planner_lastday;
+		var $planner_days;
+
+		var $planner_end_month;
+		var $planner_end_year;
+		var $planner_days_in_end_month;
+
+		var $planner_intervals = array(	// conversation hour and interval depending on intervals_per_day
+					//                                  1 1 1 1 1 1 1 1 1 1 2 2 2 2
+					//              0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
+						'1' => array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), // 0=0-23h
+						'2' => array(0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0), // 0=0-12h, 1=12-23h
+						'3' => array(0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2), // 0=0-12h, 2=12-18h, 3=18-23h
+						'4' => array(0,0,0,0,0,0,0,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3)  // 0=0-7, 7-12h, 3=12-18h, 4=18-23h
+					);
+
+		var $public_functions = array(
+			'mini_calendar' => True,
+			'index' => True,
+			'month' => True,
+			'get_month' => True,
+			'week'  => True,
+			'get_week' => True,
+			'year' => True,
+			'view' => True,
+			'edit' => True,
+			'export'	=> True,
+			'export_all' => True,
+			'reinstate_list'	=> True,
+			'reinstate'	=> True,
+			'add'  => True,
+			'delete' => True,
+			'preferences' => True,
+			'day' => True,
+			'edit_status' => True,
+			'set_action' => True,
+			'planner' => True,
+			'modify_ext_partlist' => True,
+			'matrixselect'	=> True,
+			'viewmatrix'	=> True,
+			'search' => True,
+			'header' => True,
+			'footer' => True,
+			'css'		=> True,
+			'accounts_popup' => True
+		);
+
+		function uicalendar()
+		{
+			$GLOBALS['phpgw']->nextmatchs = CreateObject('phpgwapi.nextmatchs');
+			$GLOBALS['phpgw']->browser    = CreateObject('phpgwapi.browser');
+
+			$this->theme = $GLOBALS['phpgw_info']['theme'];
+
+			$this->bo = CreateObject('calendar.bocalendar',1);
+			$this->cat = &$this->bo->cat;
+
+			print_debug('BO Owner',$this->bo->owner);
+
+			$this->template = $GLOBALS['phpgw']->template;
+			$this->template_dir = $GLOBALS['phpgw']->common->get_tpl_dir('calendar');
+
+			$this->holiday_color = (substr($this->theme['bg06'],0,1)=='#'?'':'#').$this->theme['bg06'];
+
+			$this->cat_id   = $this->bo->cat_id;
+
+			$this->link_tpl = CreateObject('phpgwapi.Template',$this->template_dir);
+			$this->link_tpl->set_unknowns('remove');
+			$this->link_tpl->set_file(
+				Array(
+					'link_picture'	=> 'link_pict.tpl'
+				)
+			);
+			$this->link_tpl->set_block('link_picture','link_pict','link_pict');
+			$this->link_tpl->set_block('link_picture','pict','pict');
+			$this->link_tpl->set_block('link_picture','link_open','link_open');
+			$this->link_tpl->set_block('link_picture','link_close','link_close');
+			$this->link_tpl->set_block('link_picture','link_text','link_text');
+			
+			/*************** EVENTO **************************/
+/* Este bloco de codigo foi adicionado pois os eventos de agendamento (exibicao do mes) para impressao serao tratados em outro template
+(event_link.tpl) */
+
+			$this->event_tpl = CreateObject('phpgwapi.Template',$this->template_dir);
+			$this->event_tpl = CreateObject('phpgwapi.Template',$this->template_dir);
+			$this->event_tpl->set_unknowns('remove');
+			$this->event_tpl->set_file(
+				Array(
+					'link_event'	=> 'event_link.tpl'
+				)
+			);
+			$this->event_tpl->set_block('link_event','link_event_pict','link_event_pict');
+			$this->event_tpl->set_block('link_event','event_pict','event_pict');
+			$this->event_tpl->set_block('link_event','link_event_open','link_event_open');
+			$this->event_tpl->set_block('link_event','link_event_close','link_event_close');
+			$this->event_tpl->set_block('link_event','link_event_text','link_event_text');
+
+
+/*************************************************/
+
+			if($this->bo->use_session)
+			{
+				// save return-fkt for add, view, ...
+				list(,,$fkt) = explode('.',$_GET['menuaction']);
+				if ($fkt == 'day' || $fkt == 'week' || $fkt == 'month' || $fkt == 'year' || $fkt == 'planner')
+				{
+					$this->bo->return_to = $_GET['menuaction'].
+						sprintf('&date=%04d%02d%02d',$this->bo->year,$this->bo->month,$this->bo->day);
+				}
+				$this->bo->save_sessiondata();
+			}
+			$this->always_app_header = $this->bo->prefs['common']['template_set'] == 'idots';
+
+			print_debug('UI',$this->_debug_sqsof());
+
+			if (!is_object($GLOBALS['phpgw']->html))
+			{
+				$GLOBALS['phpgw']->html = CreateObject('phpgwapi.html');
+			}
+			$this->html = &$GLOBALS['phpgw']->html;
+		}
+
+		/* Public functions */
+
+		function mini_calendar($params)
+		{
+			static $mini_cal_tpl;
+			if(!is_array($params))
+			{
+				return;
+			}
+
+			if($params['month'] == 0)
+			{
+				$params['month'] = 12;
+				$params['year'] = $params['year'] - 1;
+			}
+			elseif($params['month'] == 13)
+			{
+				$params['month'] = 1;
+				$params['year'] = $params['year'] + 1;
+			}
+
+			$this->bo->store_to_cache(
+				Array(
+					'smonth'	=> $params['month'],
+					'sday'	=> 1,
+					'syear'	=> $params['year']
+				)
+			);
+
+			$params['link']			= (!isset($params['link'])?'':$params['link']);
+			$params['buttons']		= (!isset($params['buttons'])?'none':$params['buttons']);
+			$params['outside_month']	= (!isset($params['outside_month'])?True:$params['outside_month']);
+
+			$this->bo->read_holidays($params['year']);
+
+			$date = $GLOBALS['phpgw']->datetime->makegmttime(0,0,0,$params['month'],$params['day'],$params['year']);
+			$month_ago = (int)(date('Ymd',mktime(0,0,0,$params['month'] - 1,$params['day'],$params['year'])));
+			$month_ahead = (int)(date('Ymd',mktime(0,0,0,$params['month'] + 1,$params['day'],$params['year'])));
+			$monthstart = (int)(date('Ymd',mktime(0,0,0,$params['month'],1,$params['year'])));
+			$monthend = (int)(date('Ymd',mktime(0,0,0,$params['month'] + 1,0,$params['year'])));
+
+			$weekstarttime = $GLOBALS['phpgw']->datetime->get_weekday_start($params['year'],$params['month'],1);
+
+			print_debug('mini_calendar:monthstart',$monthstart);
+			print_debug('mini_calendar:weekstarttime',date('Ymd H:i:s',$weekstarttime));
+
+			if(!is_object($mini_cal_tpl))
+			{
+				$mini_cal_tpl = CreateObject('phpgwapi.Template',$this->template_dir);
+				$mini_cal_tpl->set_unknowns('remove');
+				$mini_cal_tpl->set_file(
+					Array(
+						'mini_calendar'	=> 'mini_cal.tpl'
+					)
+				);
+				$mini_cal_tpl->set_block('mini_calendar','mini_cal','mini_cal');
+				$mini_cal_tpl->set_block('mini_calendar','mini_week','mini_week');
+				$mini_cal_tpl->set_block('mini_calendar','mini_day','mini_day');
+			}
+
+
+			if($this->bo->printer_friendly == False)
+			{
+//NDEE				$month = '<a href="' . $this->page('month','&month='.$GLOBALS['phpgw']->common->show_date($date['raw'],'m').'&year='.$GLOBALS['phpgw']->common->show_date($date['raw'],'Y')). '" class="_minicalendar">' . lang($GLOBALS['phpgw']->common->show_date($date['raw'],'F')).' '.$GLOBALS['phpgw']->common->show_date($date['raw'],'Y').'</a>';
+				$month = '<a href="' . $this->page('month','&month='.$GLOBALS['phpgw']->common->show_date($date['raw'],'m').'&year='.$GLOBALS['phpgw']->common->show_date($date['raw'],'Y')). '">' . lang($GLOBALS['phpgw']->common->show_date($date['raw'],'F')).' '.$GLOBALS['phpgw']->common->show_date($date['raw'],'Y').'</a>';
+			}
+			else
+			{
+				$month = lang($GLOBALS['phpgw']->common->show_date($date['raw'],'F')).' '.$GLOBALS['phpgw']->common->show_date($date['raw'],'Y');
+			}
+
+			$var = Array(
+				'cal_img_root'		=>	$GLOBALS['phpgw']->common->image('calendar','mini-calendar-bar'),
+				'bgcolor'			=>	$this->theme['bg_color'],
+				'bgcolor1'			=>	$this->theme['bg_color'],
+				'month'				=>	$month,
+				'bgcolor2'			=>	$this->theme['cal_dayview'],
+				'holiday_color'	=> $this->holiday_color
+			);
+
+			$mini_cal_tpl->set_var($var);
+
+			switch(strtolower($params['buttons']))
+			{
+				case 'right':
+					$var = Array(
+						'nextmonth'			=>	'<a href="'.$this->page('month','&date='.$month_ahead).'"><img src="'.$GLOBALS['phpgw']->common->image('phpgwapi','right').'" border="0"></a>'
+					);
+					break;
+				case 'left':
+					$var = Array(
+						'prevmonth'			=>	'<a href="'.$this->page('month','&date='.$month_ago).'"><img src="'.$GLOBALS['phpgw']->common->image('phpgwapi','left').'" border="0"></a>'
+					);
+					break;
+				case 'both':
+					$var = Array(
+						'prevmonth'			=>	'<a href="'.$this->page('month','&date='.$month_ago).'"><img src="'.$GLOBALS['phpgw']->common->image('phpgwapi','left').'" border="0"></a>',
+						'nextmonth'			=>	'<a href="'.$this->page('month','&date='.$month_ahead).'"><img src="'.$GLOBALS['phpgw']->common->image('phpgwapi','right').'" border="0"></a>'
+					);
+					break;
+				case 'none':
+				default:
+					$var = Array(
+						'prevmonth'			=>	'',
+						'nextmonth'			=>	''
+					);
+					break;
+			}
+			$mini_cal_tpl->set_var($var);
+
+			if(!$mini_cal_tpl->get_var('daynames'))
+			{
+				for($i=0;$i<7;$i++)
+				{
+					$var = Array(
+						'dayname'	=> '<b>' . lang($GLOBALS['phpgw']->datetime->days_short[$i]) . '</b>',
+						'day_image'	=> ''
+					);
+					$this->output_template_array($mini_cal_tpl,'daynames','mini_day',$var);
+				}
+			}
+			$today = date('Ymd',$GLOBALS['phpgw']->datetime->users_localtime);
+			unset($date);
+			for($i=$weekstarttime + $GLOBALS['phpgw']->datetime->tz_offset;date('Ymd',$i)<=$monthend;$i += (24 * 3600 * 7))
+			{
+				unset($var);
+				$daily = $this->set_week_array($i - $GLOBALS['phpgw']->datetime->tz_offset,$cellcolor,$weekly);
+				foreach($daily as $date => $day_params)
+				{
+					print_debug('Mini-Cal Date',$date);
+					$year = (int)(substr($date,0,4));
+					$month = (int)(substr($date,4,2));
+					$day = (int)(substr($date,6,2));
+					$str = '';
+					if(($date >= $monthstart && $date <= $monthend) || $params['outside_month'] == True)
+					{
+						if(!$this->bo->printer_friendly && $params['link'])
+						{
+//NDEE: class def what for?
+							$str = '<a href="'.$this->page($params['link'],'&date='.$date).'" class="'.$day_params['class'].'">'.$day.'</a>';
+						}
+						else
+						{
+
+//NDEE: printer-friendly (mini-calendar)
+							$str = $day;
+						}
+
+					}
+					else
+					{
+						$day_params['day_image'] = '';
+					}
+					$var[] = Array(
+						'day_image'	=> $day_params['day_image'],
+						'dayname'	=> $str
+					);
+				}
+				for($l=0;$l<count($var);$l++)
+				{
+					$this->output_template_array($mini_cal_tpl,'monthweek_day','mini_day',$var[$l]);
+				}
+				$mini_cal_tpl->parse('display_monthweek','mini_week',True);
+				$mini_cal_tpl->set_var('dayname','');
+				$mini_cal_tpl->set_var('monthweek_day','');
+			}
+
+			$return_value = $mini_cal_tpl->fp('out','mini_cal');
+			$mini_cal_tpl->set_var('display_monthweek','');
+//			$mini_cal_tpl->set_var('daynames','');
+//			unset($p);
+			return $return_value;
+		}
+
+		function index($params='')
+		{
+			if (!$params)
+			{
+				foreach(array('date','year','month','day') as $field)
+				{
+					if (isset($_GET[$field]))
+					{
+						$params[$field] = $_GET[$field];
+					}
+				}
+			}
+			$GLOBALS['phpgw']->redirect($this->page('',$params));
+			
+		}
+
+
+
+// NDEE: printer-friendly
+
+		function printer_friendly($body,$app_header='')
+		{
+			$_SESSION['calendar']['categories'] = $this->cat->formated_list('select','all',$this->bo->cat_id,'True');
+			if((!isset($GLOBALS['phpgw_info']['server']['deny_user_grants_access']) || !$GLOBALS['phpgw_info']['server']['deny_user_grants_access']) && count($this->bo->grants) > 0)
+				$_SESSION['calendar']['cals'] = $this->bo->list_cals();
+
+			if($this->bo->printer_friendly)
+			{	
+				$new_body = '<html>'."\n"
+					.'<head>'."\n"
+					.'<LINK href="'.$GLOBALS['phpgw_info']['server']['webserver_url'].'/calendar/templates/'.$GLOBALS['phpgw_info']['user']['preferences']['common']['template_set'].'/app.css" type=text/css rel=StyleSheet>'."\n"
+					.'<LINK href="'.$GLOBALS['phpgw_info']['server']['webserver_url'].'/calendar/templates/'.$GLOBALS['phpgw_info']['user']['preferences']['common']['template_set'].'/app_print.css" type=text/css rel=StyleSheet media="print">'."\n"
+					.'</head>
+					<table id="calendar_print_main" class="calendar_print_main">						
+						<tr>
+							<td id="calendar_print_content" class="calendar_print_content">'.$body.'</td>
+						</tr>
+						<tr>
+							<td><right><input class=button type="button" onClick="javascript:this.style.visibility=\'hidden\';window.print();window.close();" value="Imprimir esta p&aacute;gina"></right></td>
+						</tr>						
+					</table></body>'."\n"
+					.'</html>'."\n";
+				//$new_body = utf8_decode($new_body);
+			}
+			else
+			{
+				unset($GLOBALS['phpgw_info']['flags']['noheader']);
+				unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+				unset($GLOBALS['phpgw_info']['flags']['noappheader']);
+				unset($GLOBALS['phpgw_info']['flags']['noappfooter']);
+				if ($app_header && $this->always_app_header)
+				{
+					$GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['calendar']['title'].' - '.$app_header;
+				}
+				
+				$GLOBALS['phpgw']->common->phpgw_header();
+				$new_body = $this->bo->debug_string.$body;				
+				
+			}
+			return $new_body;
+		}
+
+		function month()
+		{
+			echo $this->printer_friendly($this->get_month(),lang('Monthview'));
+			$GLOBALS['phpgw']->common->phpgw_footer();
+		}
+
+		function get_month()
+		{
+			$m = mktime(0,0,0,$this->bo->month,1,$this->bo->year);
+
+			$next = $this->bo->month + 1;
+			$prev = $this->bo->month - 1;
+			$nextyear = $this->bo->year;
+			$prevyear = $this->bo->year;
+			if ($this->bo->month == 12)
+			{
+				$next = 1;
+				$nextyear = $nextyear + 1;
+			}
+			elseif ($this->bo->month == 1)
+			{
+				$prev = 12;
+				$prevyear = $prevyear - 1;
+			}
+
+			if (!$this->bo->printer_friendly || ($this->bo->printer_friendly && @$this->bo->prefs['calendar']['display_minicals']))
+			{
+				$minical_prev = $this->mini_calendar(
+					Array(
+						'day'	=> 1,
+						'month'	=> $this->bo->month - 1,
+						'year'	=> $this->bo->year,
+						'link'	=> 'day',
+						'outside_month'	=> False
+					)
+				);
+
+				$minical_next = $this->mini_calendar(
+					Array(
+						'day'	=> 1,
+						'month'	=> $this->bo->month + 1,
+						'year'	=> $this->bo->year,
+						'link'	=> 'day',
+						'outside_month'	=> False
+					)
+				);
+			}
+			else
+			{
+				$minical_prev = '';
+				$minical_next = '';
+			}
+
+			if (!$this->bo->printer_friendly)
+			{
+				$printer = '';
+				$prev_month_link = '<a href="'.$this->page('month','&year='.$prevyear.'&month='.$prev).'">&lt;&lt;</a>';
+				$next_month_link = '<a href="'.$this->page('month','&year='.$nextyear.'&month='.$next).'">&gt;&gt;</a>';
+				$param = '&year='.$this->bo->year.'&month='.$this->bo->month.'&friendly=1';
+				$print = "<a href='javascript:void(0)' onClick=\"javascript:window.open('".$this->page('month'.$param).
+						"','','width=600,height=600,toolbar=no,scrollbars=yes,resizable=no');\" onMouseOver=\"window.status = '".
+						lang('Generate printer-friendly version')."'\">[".lang('Printer Friendly').']</a>';
+				//linha abaixo foi adicionada para exibir a pagina do mes em tela
+				$large_month = $this->display_month($this->bo->month,$this->bo->year,True,$this->bo->owner);				
+			}
+			else
+			{
+				$printer = '<body bgcolor="'.$phpgw_info['theme']['bg_color'].'">';
+				$prev_month_link = '';
+				$next_month_link = '';
+				$print =	'';
+				$GLOBALS['phpgw_info']['flags']['nofooter'] = True;
+				//linha abaixo foi adicionada para exibir a pagina do mes para impressao
+				$large_month = $this->display_month_print($this->bo->month,$this->bo->year,True,$this->bo->owner);
+			}
+
+			$this->bo->read_holidays();
+
+			$var = Array(
+				'printer_friendly'		=>	$printer,
+				'bg_text'					=> $this->theme['bg_text'],
+				'small_calendar_prev'	=>	$minical_prev,
+				'prev_month_link'		=>	$prev_month_link,
+				'month_identifier'		=>	lang(strftime("%B",$m)).' '.$this->bo->year,
+				'username'					=>	$GLOBALS['phpgw']->common->grab_owner_name($this->bo->owner),
+				'next_month_link'		=>	$next_month_link,
+				'small_calendar_next'	=>	$minical_next,
+				//'large_month'				=>	$this->display_month($this->bo->month,$this->bo->year,True,$this->bo->owner),
+				'large_month'		=>	$large_month,
+				'print'						=>	$print
+			);
+
+			$p = CreateObject('phpgwapi.Template',$this->template_dir);
+			$p->set_unknowns('remove');
+			// Alteracao que desvincula o template para tela do template de impressao do mes (month_print teve que ser criado);
+			if($print != '')
+			{
+				$p->set_file(
+					Array(
+						'index_t'	=>	'index.tpl'
+					)
+				);
+			}else {
+				$p->set_file(
+					Array(
+						'index_t'	=>	'month_print.tpl'
+					)
+				);
+			}
+			$p->set_var($var);
+			return $p->fp('out','index_t');
+		}
+
+		function week()
+		{
+			echo $this->printer_friendly($this->get_week(),lang('Weekview'));
+			$GLOBALS['phpgw']->common->phpgw_footer();
+		}
+
+		function get_week()
+		{
+			$this->bo->read_holidays();
+
+			$next = $GLOBALS['phpgw']->datetime->makegmttime(0,0,0,$this->bo->month,$this->bo->day + 7,$this->bo->year);
+			$prev = $GLOBALS['phpgw']->datetime->makegmttime(0,0,0,$this->bo->month,$this->bo->day - 7,$this->bo->year);
+
+			if (!$this->bo->printer_friendly || ($this->bo->printer_friendly && @$this->bo->prefs['calendar']['display_minicals']))
+			{
+				$minical_this = $this->mini_calendar(
+					Array(
+						'day'	=> $this->bo->day,
+						'month'	=> $this->bo->month,
+						'year'	=> $this->bo->year,
+						'link'	=> 'day',
+						'butons'	=> 'none',
+						'outside_month'	=> False
+					)
+				);
+				$minical_prev = $this->mini_calendar(
+					Array(
+						'day'	=> $this->bo->day,
+						'month'	=> $this->bo->month - 1,
+						'year'	=> $this->bo->year,
+						'link'	=> 'day',
+						'butons'	=> 'left',
+						'outside_month'	=> False
+					)
+				);
+				$minical_next = $this->mini_calendar(
+					Array(
+						'day'	=> $this->bo->day,
+						'month'	=> $this->bo->month + 1,
+						'year'	=> $this->bo->year,
+						'link'	=> 'day',
+						'butons'	=> 'right',
+						'outside_month'	=> False
+					)
+				);
+			}
+			else
+			{
+
+//NDEE: printer-friendly what?
+				$minical_this = '';
+				$minical_prev = '';
+				$minical_next = '';
+			}
+
+			if (!$this->bo->printer_friendly)
+			{
+				$printer = '';
+				$prev_week_link = '<a href="'.$this->page('week','&date='.$prev['full']).'">&lt;&lt;</a>';
+				$next_week_link = '<a href="'.$this->page('week','&date='.$next['full']).'">&gt;&gt;</a>';
+				$print = '<a href="'.$this->page('week','&friendly=1&date='.sprintf("%04d%02d%02d",$this->bo->year,$this->bo->month,$this->bo->day))."\" TARGET=\"cal_printer_friendly\" onMouseOver=\"window.status = '".lang('Generate printer-friendly version')."'\">[".lang('Printer Friendly').']</a>';
+			}
+			else
+			{
+
+//NDEE: printer-friendly (weekly-view)
+				$printer = '<body bgcolor="'.$this->theme['bg_color'].'">';
+				$prev_week_link = '';
+				$next_week_link = '';
+				$print =	'';
+				$GLOBALS['phpgw_info']['flags']['nofooter'] = True;
+			}
+
+			$var = Array(
+				'printer_friendly'	=>	$print,
+				'bg_text'		=> $this->theme['bg_text'],
+				'small_calendar_prev'	=>	$minical_prev,
+				'prev_week_link'	=>	$prev_week_link,
+				'small_calendar_this'	=>	$minical_this,
+				'week_identifier'	=>	$this->bo->get_week_label(),
+				'next_week_link'	=>	$next_week_link,
+				'username'		=>	$GLOBALS['phpgw']->common->grab_owner_name($this->bo->owner),
+				'small_calendar_next'	=>	$minical_next,
+				'week_display'		=>	$this->display_weekly(
+					Array(
+						'date'		=> sprintf("%04d%02d%02d",$this->bo->year,$this->bo->month,$this->bo->day),
+						'showyear'	=> true,
+						'owners'	=> $this->bo->owner
+					)
+				),
+				'print'			=>	$print
+			);
+//todo
+			$p = CreateObject('phpgwapi.Template',$this->template_dir);
+			$p->set_file(
+				Array(
+					'week_t' => 'week.tpl'
+				)
+			);
+			$p->set_var($var);
+			return $p->fp('out','week_t');
+
+/*
+			$this->bo->read_holidays();
+
+			if (!$this->bo->printer_friendly || ($this->bo->printer_friendly && @$this->bo->prefs['calendar']['display_minicals']))
+			{
+				$minical = $this->mini_calendar(
+					Array(
+						'day'	=> $this->bo->day,
+						'month'	=> $this->bo->month,
+						'year'	=> $this->bo->year,
+						'link'	=> 'day'
+					)
+				);
+			}
+			else
+			{
+				$minical = '';
+			}
+
+			if (!$this->bo->printer_friendly)
+			{
+				unset($GLOBALS['phpgw_info']['flags']['noheader']);
+				unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+				$GLOBALS['phpgw']->common->phpgw_header();
+				$printer = '';
+				$param = '&date='.sprintf("%04d%02d%02d",$this->bo->year,$this->bo->month,$this->bo->day).'&friendly=1';
+				$print = '<a href="'.$this->page('day'.$param)."\" TARGET=\"cal_printer_friendly\" onMouseOver=\"window.status = '".lang('Generate printer-friendly version')."'\">[".lang('Printer Friendly').']</a>';
+			}
+			else
+			{
+				$GLOBALS['phpgw_info']['flags']['nofooter'] = True;
+				$printer = '<body bgcolor="'.$this->theme['bg_color'].'">';
+				$print =	'';
+			}
+
+			$now	= $GLOBALS['phpgw']->datetime->makegmttime(0, 0, 0, $this->bo->month, $this->bo->day, $this->bo->year);
+			$now['raw'] += $GLOBALS['phpgw']->datetime->tz_offset;
+			$m = mktime(0,0,0,$this->bo->month,1,$this->bo->year);
+
+			$p = $GLOBALS['phpgw']->template;
+			$p->set_file(
+				Array(
+					'day_t' => 'day.tpl'
+				)
+			);
+			$p->set_block('day_t','day','day');
+			$p->set_block('day_t','day_event','day_event');
+
+			$var = Array(
+				'printer_friendly'		=> $printer,
+				'bg_text'			=> $this->theme['bg_text'],
+				'daily_events'			=> $this->print_day(
+					Array(
+						'year'	=> $this->bo->year,
+						'month'	=> $this->bo->month,
+						'day'	=> $this->bo->day
+					)
+				),
+				'small_calendar'		=> $minical,
+				'date'				=> lang(date('F',$m)).' '.sprintf("%02d",$this->bo->day).', '.$this->bo->year,
+				'username'			=> $GLOBALS['phpgw']->common->grab_owner_name($this->bo->owner),
+				'print'				=> $print
+			);
+
+			$p->set_var($var);
+			$p->parse('day_events','day_event');
+			$p->pparse('out','day');
+*/
+		}
+
+		function year()
+		{
+			if($this->bo->printer_friendly)
+			{
+				$GLOBALS['phpgw_info']['flags']['nofooter'] = True;
+			}
+			echo $this->printer_friendly($this->get_year(),lang('Yearview'));
+			$GLOBALS['phpgw']->common->phpgw_footer();
+		}
+
+		function get_year()
+		{
+			if(!$this->bo->printer_friendly)
+			{
+				$print = '';
+				$left_link = '<a href="'.$this->page('year','&year='.($this->bo->year - 1)).'">&lt;&lt;</a>';
+				$right_link = '<a href="'.$this->page('year','&year='.($this->bo->year + 1)).'">&gt;&gt;</a>';
+				$link = 'day';
+				$printer = '<a href="'.$this->page('year','&friendly=1&year='.$this->bo->year).'" target="cal_printer_friendly" onMouseOver="window.status = '."'".lang('Generate printer-friendly version')."'".'">['.lang('Printer Friendly').']</a>';
+			}
+			else
+			{
+
+//NDEE: printer-friendly (year-view)
+				$print = '<body bgcolor="'.$this->theme['bg_color'].'">';
+				$left_link = '';
+				$right_link = '';
+				$link = '';
+				$printer = '';
+			}
+
+			$var = Array(
+				'print'		=> $print,
+				'left_link' => $left_link,
+				'font'		=> $this->theme['font'],
+				'year_text' => $this->bo->year,
+				'right_link'=> $right_link,
+				'printer_friendly'=> $printer
+			);
+
+			$p = CreateObject('phpgwapi.Template',$this->template_dir);
+			$p->set_file(
+				Array(
+					'year_t' => 'year.tpl'
+				)
+			);
+			$p->set_block('year_t','year','year');
+			$p->set_block('year_t','month','month_handle');
+			$p->set_block('year_t','month_sep','month_sep_handle');
+			$p->set_var($var);
+
+			for($i=1;$i<=12;$i++)
+			{
+				if(($i % 3) == 1)
+				{
+					$p->parse('row','month_sep',True);
+				}
+				$p->set_var('mini_month',$this->mini_calendar(
+						Array(
+							'day'	=> 1,
+							'month'	=> $i,
+							'year'	=> $this->bo->year,
+							'link'	=> $link,
+							'buttons'	=> 'none',
+							'outside_month'	=> False
+						)
+					)
+				);
+				$p->parse('row','month',True);
+				$p->set_var('mini_month','');
+			}
+			return $p->fp('out','year_t');
+		}
+
+		function view($vcal_id=0,$cal_date=0)
+		{
+			unset($GLOBALS['phpgw_info']['flags']['noheader']);
+			unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+			$GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['calendar']['title'].' - '.lang('View');
+			$GLOBALS['phpgw']->common->phpgw_header();
+
+			$cal_id = get_var('cal_id',array('GET','POST'),$vcal_id);
+
+			$date = $cal_date ? $cal_date : 0;
+			$date = $date ? $date : (int)$_GET['date'];
+	
+			// First, make sure they have permission to this entry
+			if ($cal_id < 1)
+			{
+				echo '<center>'.lang('Invalid entry id.').'</center>'."\n";
+				$GLOBALS['phpgw']->common->phpgw_exit(True);
+			}
+
+			if(!$this->bo->check_perms(PHPGW_ACL_READ,$cal_id))
+			{
+				echo '<center>'.lang('You do not have permission to read this record!').'</center>'."\n";
+				$GLOBALS['phpgw']->common->phpgw_exit(True);
+			}
+			
+			$event = $this->bo->read_entry($cal_id);
+
+			if(!isset($event['id']))
+			{
+				echo '<center>'.lang('Sorry, this event does not exist').'.'.'</center>'."\n";
+				$GLOBALS['phpgw']->common->phpgw_exit(True);
+			}
+
+			$this->bo->repeating_events = Array();
+			$this->bo->cached_events = Array();
+			$this->bo->repeating_events[0] = $event;
+			$datetime = mktime(0,0,0,$this->bo->month,$this->bo->day,$this->bo->year) - $GLOBALS['phpgw']->datetime->tz_offset;
+			$this->bo->check_repeating_events($datetime);
+			$check_date = $GLOBALS['phpgw']->common->show_date($datetime,'Ymd');
+			if(is_array($this->bo->cached_events[$check_date][0]) &&
+				$this->bo->cached_events[$check_date][0]['id'] == $event['id'])
+			{
+				$starttime = $this->bo->maketime($event['start']);
+				$endtime = $this->bo->maketime($event['end']);
+				$event['start']['month'] = $this->bo->month;
+				$event['start']['mday'] = $this->bo->day;
+				$event['start']['year'] = $this->bo->year;
+				$temp_end =  $this->bo->maketime($event['start']) + ($endtime - $starttime);
+				$event['end']['month'] = date('m',$temp_end);
+				$event['end']['mday'] = date('d',$temp_end);
+				$event['end']['year'] = date('Y',$temp_end);
+			}
+
+			if(!$this->view_event($event,True))
+			{
+				echo '<center>'.lang('You do not have permission to read this record!').'</center>';
+				$GLOBALS['phpgw']->common->phpgw_exit(True);
+			}
+						
+			$p = $GLOBALS['phpgw']->template;
+			$p->set_file(
+				Array(
+					'form_button'	=> 'form_button_script.tpl'
+				)
+			);
+
+			$button_left = $button_center = $button_right = '';
+
+			if($this->bo->check_perms(PHPGW_ACL_EDIT,$event))
+			{
+				if($event['recur_type'] != MCAL_RECUR_NONE)
+				{
+					$var = Array(
+						'action_url_button'	=> $this->page('edit','&cal_id='.$cal_id),
+						'action_text_button'	=> lang('Edit Single'),
+						'action_confirm_button'	=> '',
+						'action_extra_field'	=> $this->html->input_hidden(array(
+							'edit_type' => 'single',
+							'date' => sprintf('%04d%02d%02d',$this->bo->year,$this->bo->month,$this->bo->day)
+						))
+					);
+					$p->set_var($var);
+					$button_left .= '<td>'.$p->fp('button','form_button').'</td>';
+
+					$var = Array(
+						'action_url_button'	=> $this->page('edit','&cal_id='.$cal_id),
+						'action_text_button'	=> lang('Edit Series'),
+						'action_confirm_button'	=> '',
+						'action_extra_field'	=> $this->html->input_hidden('edit_type','series')
+					);
+					$p->set_var($var);
+					$button_left .= '<td>'.$p->fp('button','form_button').'</td>';
+				}
+				else
+				{
+					$var = Array(
+						'action_url_button'	=> $this->page('edit','&cal_id='.$cal_id),
+						'action_text_button'	=> lang('Edit'),
+						'action_confirm_button'	=> '',
+						'action_extra_field'	=> ''
+					);
+					$p->set_var($var);
+					$button_left .= '<td>'.$p->fp('button','form_button').'</td>';
+				}
+
+				$var = Array(
+					'action_url_button'	=> $GLOBALS['phpgw']->link('/index.php','menuaction=calendar.uialarm.manager'),
+					'action_text_button'	=> lang('Alarm Management'),
+					'action_confirm_button'	=> '',
+					'action_extra_field'	=> $this->html->input_hidden(array(
+						'cal_id' => $cal_id,
+						'return_to' => $this->bo->return_to
+					))
+				);
+				$p->set_var($var);
+				$button_center .= '<td>'.$p->fp('button','form_button').'</td>';
+			}
+
+			if ($this->bo->check_perms(PHPGW_ACL_DELETE,$event))
+			{
+				if($event['recur_type'] != MCAL_RECUR_NONE)
+				{
+					$var = Array(
+						'action_url_button'	=> $this->page('delete','&cal_id='.$cal_id),
+						'action_text_button'	=> lang('Delete Single'),
+						'action_confirm_button'	=> "onClick=\"return confirm('".lang('Are you sure want to delete this single occurence?\\nThis will delete this entry for all users.')."')\"",
+						'action_extra_field'	=> $this->html->input_hidden(array(
+							'delete_type' => 'single',
+							'date' => sprintf('%04d%02d%02d',$this->bo->year,$this->bo->month,$this->bo->day)
+						))
+					);
+					$p->set_var($var);
+					$button_right .= '<td>'.$p->fp('button','form_button').'</td>';
+
+					$var = Array(
+						'action_url_button'	=> $this->page('delete','&cal_id='.$cal_id),
+						'action_text_button'	=> lang('Delete Series'),
+						'action_confirm_button'	=> "onClick=\"return confirm('".lang('Are you sure want to delete this entry?\\nThis will delete this entry for all users.')."')\"",
+						'action_extra_field'	=> $this->html->input_hidden('delete_type','series')
+					);
+					$p->set_var($var);
+					$button_right .= '<td>'.$p->fp('button','form_button').'</td>';
+
+					if($event['recur_exception'])
+					{
+						$var = Array(
+							'action_url_button'	=> $this->page('reinstate_list','&cal_id='.$cal_id),
+							'action_text_button'	=> lang('Reinstate'),
+							'action_confirm_button'	=> '',
+							'action_extra_field'	=> ''
+						);
+						$p->set_var($var);
+						$button_center .= '<td>'.$p->fp('button','form_button').'</td>';
+					}
+				}
+				else
+				{
+					$var = Array(
+						'action_url_button'	=> $this->page('delete','&cal_id='.$cal_id),
+						'action_text_button'	=> lang('Delete'),
+						'action_confirm_button'	=> "onClick=\"return confirm('".lang('Are you sure want to delete this entry?\\nThis will delete this entry for all users.')."')\"",
+						'action_extra_field'	=> ''
+					);
+					$p->set_var($var);
+					$button_right .= '<td>'.$p->fp('button','form_button').'</td>';
+				}
+			}
+			else
+			{
+				// allow me (who I am logged in as) to set up an alarm
+				// if I am a participant, but not the owner
+				reset($event['participants']);
+				while (list($user,$short_status) = each($event['participants']))
+				{
+					if ($GLOBALS['phpgw_info']['user']['account_id'] == $user)
+					{
+						$var = Array(
+							'action_url_button'	=> $GLOBALS['phpgw']->link('/index.php','menuaction=calendar.uialarm.manager'),
+							'action_text_button'	=> lang('Alarm Management'),
+							'action_confirm_button'	=> '',
+							'action_extra_field'	=> $this->html->input_hidden(array(
+								'cal_id'    => $cal_id,
+								'return_to' => $this->bo->return_to
+							))
+						);
+						$p->set_var($var);
+						echo $p->fp('out','form_button');
+					}
+				}
+			}
+
+			$var = Array(
+				'action_url_button'	=> $this->page('export'),
+				'action_text_button'	=> lang('Export'),
+				'action_confirm_button'	=> '',
+				'action_extra_field'	=> $this->html->input_hidden('cal_id',$cal_id)
+			);
+			$p->set_var($var);
+			$button_center .= '<td>'.$p->fp('button','form_button').'</td>';
+
+			if ($this->bo->return_to)
+			{
+				$var = Array(
+					'action_url_button'	=> $GLOBALS['phpgw']->link('/index.php','menuaction='.$this->bo->return_to),
+					'action_text_button'	=> lang('Done'),
+					'action_confirm_button'	=> '',
+					'action_extra_field'	=> ''
+				);
+				$p->set_var($var);
+				$button_left .= '<td>'.$p->fp('button','form_button').'</td>';
+			}
+			$p->set_var(array(
+				'button_left'	=> $button_left,
+				'button_center'	=> $button_center,
+				'button_right'	=> $button_right
+			));
+			$p->pfp('phpgw_body','view_event');
+
+			$GLOBALS['phpgw']->hooks->process(array(
+				'location' => 'calendar_view',
+				'cal_id'   => $cal_id
+			));
+			
+			$GLOBALS['phpgw']->common->phpgw_footer();
+		}
+
+		function edit($params='')
+		{
+			if($this->debug)
+			{
+				echo '<!-- params[readsess] = '.$params['readsess'].' -->'."\n";
+				echo '<!-- params[cd] = '.$params['cd'].' -->'."\n";
+			}
+
+			if(isset($_GET['readsess']))
+			{
+				$params['readsess'] = $_GET['readsess'];
+				$params['cd'] = 0;
+			}
+
+			if($this->debug)
+			{
+				echo '<!-- params[readsess] = '.$params['readsess'].' -->'."\n";
+				echo '<!-- params[cd] = '.$params['cd'].' -->'."\n";
+			}
+
+			if($params != '' && @is_array($params) && @isset($params['readsess']))
+			{
+				$can_edit = True;
+				$this->edit_form(
+					Array(
+						'event' => $this->bo->restore_from_appsession(),
+						'cd' => $params['cd']
+					)
+				);
+			}
+			elseif(isset($_GET['cal_id']))
+			{
+				$cal_id = (int)$_GET['cal_id'];
+				$event = $this->bo->read_entry($cal_id);
+
+				if(!$this->bo->check_perms(PHPGW_ACL_EDIT,$event))
+				{
+					Header('Location: '.$this->page('view','&cal_id='.$cal_id));
+					$GLOBALS['phpgw']->common->phpgw_exit();
+				}
+				if(@isset($_POST['edit_type']) && $_POST['edit_type'] == 'single')
+				{
+					$event['id'] = 0;
+					$this->bo->set_recur_date($event,$_POST['date']);
+					$event['recur_type'] = MCAL_RECUR_NONE;
+					$event['recur_interval'] = 0;
+					$event['recur_data'] = 0;
+					$event['recur_enddate']['month'] = 0;
+					$event['recur_enddate']['mday'] = 0;
+					$event['recur_enddate']['year'] = 0;
+					$event['recur_exception'] = array();
+				}
+				$plain = $_GET['plain'];
+
+				$this->edit_form(
+					Array(
+						'event' => $event,
+						'cd'	=> $cd,
+						'plain' => $plain
+					)
+				);
+			}
+ 		}
+
+		function export_all()
+		{
+			$temp_path = $GLOBALS['phpgw_info']['server']['temp_dir'] . SEP;
+			srand((double)microtime()*1000000);
+			$random_number = rand(100000000,999999999);
+			$newfilename = md5(time() . getenv("REMOTE_ADDR") . $random_number );
+			$filename = $temp_path . $newfilename;
+			$attach_fd = fopen($filename,"w+");
+			$event_ids = $this->bo->search_keywords($_POST['keywords']);
+			foreach($event_ids as $key => $id)
+			{
+				$event[$key]=$this->bo->read_entry($id);
+			}
+			include_once('class.bocalendar.inc.php');
+			$cal = new bocalendar;
+			$tmpattach=$cal->create_vcard($event);
+			fwrite($attach_fd,$tmpattach);
+			header ("Content-Type: text/plain"); 
+			header ("Cache-Control: must-revalidate, post-check=0, pre-check=0");
+			header('Content-Length: ' . filesize($filename));
+			header("Content-disposition: attachment; filename="."export.vcard");
+			readfile($filename);
+			fclose($attach_fd);
+		}
+
+		function export($vcal_id=0)
+		{
+			$temp_path = $GLOBALS['phpgw_info']['server']['temp_dir'] . SEP;
+			srand((double)microtime()*1000000);
+			$random_number = rand(100000000,999999999);
+			$newfilename = md5(time() . getenv("REMOTE_ADDR") . $random_number );
+			$filename = $temp_path . $newfilename;
+			$attach_fd = fopen($filename,"w+");
+			$cal_id = get_var('cal_id',array('GET','POST'),$vcal_id);
+			$event[0] = $this->bo->read_entry($cal_id);
+			include_once('class.bocalendar.inc.php');
+			$cal = new bocalendar;
+			$tmpattach=$cal->create_vcard($event);
+			fwrite($attach_fd,$tmpattach);
+			header ("Content-Type: text/plain"); 
+			header ("Cache-Control: must-revalidate, post-check=0, pre-check=0");
+			header('Content-Length: ' . filesize($filename));
+			header("Content-disposition: attachment; filename="."export.vcard");
+			readfile($filename);
+			fclose($attach_fd);
+		}
+
+		function reinstate_list($params='')
+		{
+			if(!$this->bo->check_perms(PHPGW_ACL_EDIT))
+			{
+				$this->no_edit();
+			}
+			elseif(!$this->bo->check_perms(PHPGW_ACL_ADD))
+			{
+				$this->index();
+			}
+
+			unset($GLOBALS['phpgw_info']['flags']['noheader']);
+			unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+			$GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['calendar']['title'].' - '.lang('Reinstate');
+			$GLOBALS['phpgw']->common->phpgw_header();
+
+			$cal_id = get_var('cal_id',array('GET'),$params['cal_id']);
+
+			if ($cal_id < 1)
+			{
+				echo '<center>'.lang('Invalid entry id.').'</center>'."\n";
+				$GLOBALS['phpgw']->common->phpgw_exit(True);
+			}
+
+			if(!$this->bo->check_perms(PHPGW_ACL_READ))
+			{
+				echo '<center>'.lang('You do not have permission to read this record!').'</center>'."\n";
+				$GLOBALS['phpgw']->common->phpgw_exit(True);
+			}
+
+			$event = $this->bo->read_entry($cal_id);
+
+			if(!isset($event['id']))
+			{
+				echo '<center>'.lang('Sorry, this event does not exist').'.'.'</center>'."\n";
+				$GLOBALS['phpgw']->common->phpgw_exit(True);
+			}
+			elseif(!isset($event['recur_exception']))
+			{
+				echo '<center>'.lang('Sorry, this event does not have exceptions defined').'.'.'</center>'."\n";
+				$GLOBALS['phpgw']->common->phpgw_exit(True);
+			}
+
+			if(!$this->view_event($event,True))
+			{
+				echo '<center>'.lang('You do not have permission to read this record!').'</center>';
+				$GLOBALS['phpgw']->common->phpgw_exit(True);
+			}
+
+			$p = &$GLOBALS['phpgw']->template;
+			$p->set_file(
+				Array(
+					'form_button'	=> 'form_button_script.tpl'
+				)
+			);
+
+			$str = '';
+
+			for($i=0;$i<count($event['recur_exception']);$i++)
+			{
+				$str .= '    <option value="'.$i.'">'.$GLOBALS['phpgw']->common->show_date($event['recur_exception'][$i]).'</option>'."\n";
+			}
+			$this->output_template_array($p,'row','list',array(
+				'field'	=> lang('Exceptions'),
+				'data'	=> '<select name="reinstate_index[]" multiple size="5">'."\n".$str.'</select>'
+			));
+
+			$var = Array(
+				'action_url_button'	=> $this->page('reinstate','&cal_id='.$cal_id),
+				'action_text_button'	=> lang('Reinstate'),
+				'action_confirm_button'	=> '',
+				'action_extra_field'	=> ''
+			);
+			$p->set_var($var);
+			$button_left = '<td>'.$p->fp('out','form_button').'</td>';
+
+			$var = Array(
+				'action_url_button'	=> $this->bo->return_to ? $GLOBALS['phpgw']->link('/index.php','menuaction='.$this->bo->return_to) : $this->page(''),
+				'action_text_button'	=> lang('Cancel'),
+				'action_confirm_button'	=> '',
+				'action_extra_field'	=> ''
+			);
+			$p->set_var($var);
+			$button_left .= '<td>'.$p->fp('out','form_button').'</td>';
+
+			$p->set_var('button_left',$button_left);
+			$p->pfp('phpgw_body','view_event');
+		}
+
+		function reinstate($params='')
+		{
+			if(!$this->bo->check_perms(PHPGW_ACL_EDIT))
+			{
+				$this->no_edit();
+			}
+			elseif(!$this->bo->check_perms(PHPGW_ACL_ADD))
+			{
+				$this->index();
+			}
+			$cal_id = (isset($params['cal_id']) ? (int)$params['cal_id'] : '');
+			$cal_id = ($cal_id == '' ? (int)$_GET['cal_id'] : $cal_id);
+
+			$reinstate_index = (isset($params['reinstate_index']) ? (int)$params['reinstate_index'] : '');
+			$reinstate_index = ($reinstate_index == '' ? (int)$_POST['reinstate_index'] : $reinstate_index);
+			if($this->debug)
+			{
+				echo '<!-- Calling bo->reinstate -->'."\n";
+			}
+			$cd = $this->bo->reinstate(
+				Array(
+					'cal_id'	=> $cal_id,
+					'reinstate_index'	=> $reinstate_index
+				)
+			);
+			if($this->debug)
+			{
+				echo '<!-- Return Value = '.$cd.' -->'."\n";
+			}
+			if ($this->bo->return_to)
+			{
+				Header('Location: '.$GLOBALS['phpgw']->link('/index.php','menuaction='.$this->bo->return_to));
+			}
+			else
+			{
+				Header('Location: '.$this->page('',($cd?'&cd='.$cd:'')));
+			}
+			$GLOBALS['phpgw']->common->phpgw_exit();
+		}
+
+		function add($cd=0,$readsess=0)
+		{
+			if(!$this->bo->check_perms(PHPGW_ACL_ADD))
+			{
+				$this->index();
+			}
+			
+			if($readsess)
+			{
+				$event = $this->bo->restore_from_appsession;
+				if(!$event['owner'])
+				{
+					$this->bo->add_attribute('owner',$this->bo->owner);
+				}
+				$can_edit = True;
+			}
+			else
+			{
+				$this->bo->event_init();
+				$this->bo->add_attribute('id',0);
+
+				$can_edit = True;
+				$participants = (string)(get_var('participants',array('GET'),FALSE));
+				$starthour = (int)(get_var('hour',array('GET'),$this->bo->prefs['calendar']['workdaystarts']));
+				$startmin  = (int)(get_var('minute',array('GET'),0));
+				$endmin    = $startmin + (int)$this->bo->prefs['calendar']['defaultlength'];
+				$endhour   = $starthour + $this->bo->normalizeminutes($endmin);
+				
+				$subject	= (string)(get_var('title',array('GET'),0));
+				if ($subject != '0')
+				{
+					$description	= (string)(get_var('description',array('GET'),0));
+					$location	= (string)(get_var('location',array('GET'),0));
+				}
+				else
+					unset($subject);
+				
+				$this->bo->set_start($this->bo->year,$this->bo->month,$this->bo->day,$starthour,$startmin,0);
+				$this->bo->set_end($this->bo->year,$this->bo->month,$this->bo->day,$endhour,$endmin,0);
+				$this->bo->set_title($subject);
+				$this->bo->set_description($description);
+				$this->bo->add_attribute('location',$location);
+				$this->bo->set_ex_participants('');
+				$this->bo->add_attribute('uid','');
+				$this->bo->add_attribute('priority',2);
+				if(@$this->bo->prefs['calendar']['default_private'])
+				{
+					$this->bo->set_class(False);
+				}
+				else
+				{
+					$this->bo->set_class(True);
+				}
+				// Add participants
+				//$participants = explode(";", $GLOBALS['phpgw']->session->appsession("participants") );
+				//for($_f_part=0; $_f_part<count($participants); $_f_part++)
+				//{
+				//	$this->bo->add_attribute('participants','A',$participants[$_f_part]);
+				//}
+				// Add misc
+				$this->bo->add_attribute('participants','A',$this->bo->owner);
+				$this->bo->set_recur_none();
+				$event = $this->bo->get_cached_event();
+				
+			}
+			$this->edit_form(
+				Array(
+					'event' => $event,
+					'cd' => $cd,
+					'plain' => $_GET['plain']
+				)
+			);
+			$GLOBALS['phpgw']->common->phpgw_footer();
+		}
+
+		function delete()
+		{
+			if(!isset($_GET['cal_id']))
+			{
+				Header('Location: '.$this->page('','&date='.sprintf("%04d%02d%02d",$this->bo->year,$this->bo->month,$this->bo->day)));
+				$GLOBALS['phpgw']->common->phpgw_exit();
+			}
+
+			$date = sprintf("%04d%02d%02d",$this->bo->year,$this->bo->month,$this->bo->day);
+			if($this->bo->check_perms(PHPGW_ACL_DELETE,$cal_id = (int)$_GET['cal_id']))
+			{
+				if(isset($_POST['delete_type']) && $_POST['delete_type'] == 'single')
+				{
+					$date = $_POST['date'];
+					$cd = $this->bo->delete_single(
+						Array(
+							'id'	=> $cal_id,
+							'year'	=> substr($date,0,4),
+							'month'	=> substr($date,4,2),
+							'day'	=> substr($date,6,2)
+						)
+					);
+				}
+				elseif((isset($_POST['delete_type']) && $_POST['delete_type'] == 'series') || !isset($_POST['delete_type']))
+				{
+					$cd = $this->bo->delete_entry($cal_id);
+					$this->bo->expunge();
+				}
+			}
+			else
+			{
+				$cd = '';
+			}
+			if ($this->bo->return_to)
+			{
+				Header('Location: '.$GLOBALS['phpgw']->link('/index.php','menuaction='.$this->bo->return_to));
+			}
+			else
+			{
+				Header('Location: '.$this->page('','&date='.$date.($cd?'&cd='.$cd:'')));
+			}
+			$GLOBALS['phpgw']->common->phpgw_exit();
+		}
+
+		function day()
+		{
+			
+			$this->bo->read_holidays();
+
+			if (!$this->bo->printer_friendly || ($this->bo->printer_friendly && @$this->bo->prefs['calendar']['display_minicals']))
+			{
+				$minical = $this->mini_calendar(
+					Array(
+						'day'	=> $this->bo->day,
+						'month'	=> $this->bo->month,
+						'year'	=> $this->bo->year,
+						'link'	=> 'day'
+					)
+				);
+			}
+			else
+			{
+
+//NDEE: printer-friendly (what?)
+				$minical = '';
+			}
+
+			if (!$this->bo->printer_friendly)
+			{
+				$printer = '';
+				$param = '&date='.sprintf("%04d%02d%02d",$this->bo->year,$this->bo->month,$this->bo->day).'&friendly=1';
+				$print = '<a href="'.$this->page('day'.$param)."\" TARGET=\"cal_printer_friendly\" onMouseOver=\"window.status = '".lang('Generate printer-friendly version')."'\">[".lang('Printer Friendly').']</a>';
+			}
+			else
+			{
+
+//NDEE: printer-friendly (daily-view)
+				$GLOBALS['phpgw_info']['flags']['nofooter'] = True;
+				$printer = '<body bgcolor="'.$this->theme['bg_color'].'">';
+				$print =	'';
+			}
+
+			$now	= $GLOBALS['phpgw']->datetime->makegmttime(0, 0, 0, $this->bo->month, $this->bo->day, $this->bo->year);
+			$now['raw'] += $GLOBALS['phpgw']->datetime->tz_offset;
+
+			$p = $GLOBALS['phpgw']->template;
+			$p->set_file(
+				Array(
+					'day_t' => 'day.tpl'
+				)
+			);
+			$p->set_block('day_t','day','day');
+			$p->set_block('day_t','day_event','day_event');
+
+			$todos = $this->get_todos($todo_label);
+			$var = Array(
+				'printer_friendly'	=> $printer,
+				'bg_text'			=> $this->theme['bg_text'],
+				'daily_events'		=> $this->print_day(
+					Array(
+						'year'	=> $this->bo->year,
+						'month'	=> $this->bo->month,
+						'day'	=> $this->bo->day
+					)
+				),
+				'small_calendar'	=> $minical,
+				'date'				=> $this->bo->long_date($now),
+				'username'			=> $GLOBALS['phpgw']->common->grab_owner_name($this->bo->owner),
+				'print'				=> $print,
+				'lang_todos'		=> $todo_label,
+				'todos'				=> $this->bo->printer_friendly ? $todos :
+
+//NDEE: todo's layout
+					"<div style=\"overflow: auto; max-height: 200px\">\n$todos</div>\n"
+			);
+
+			$p->set_var($var);
+			$p->parse('day_events','day_event');
+			print $this->printer_friendly($p->fp('out','day'),lang('Dayview'));
+			$GLOBALS['phpgw']->common->phpgw_footer();
+		}
+
+		function get_todos(&$todo_label)
+		{
+			$todos_from_hook = $GLOBALS['phpgw']->hooks->process(array(
+				'location'  => 'calendar_include_todos',
+				'year'      => $this->bo->year,
+				'month'     => $this->bo->month,
+				'day'       => $this->bo->day,
+				'owner'     => $this->bo->owner	// num. id of the user, not necessary current user
+			));
+
+			if(is_array($todo_label))
+			{
+				list($label,$showall)=$todo_label;
+			}
+			else
+			{
+				$label=$todo_label;
+				$showall=true;
+			}
+			$maxshow = (int)$GLOBALS['phpgw_info']['user']['preferences']['infolog']['mainscreen_maxshow'];
+			if($maxshow<=0)
+			{
+				$maxshow=10;
+			}
+			//print_debug("get_todos(): label=$label; showall=$showall; max=$maxshow");
+
+			$content = $todo_label = '';
+			if (is_array($todos_from_hook) && count($todos_from_hook))
+			{
+				$todo_label = !empty($label)?$label:lang("open ToDo's:");
+
+				foreach($todos_from_hook as $todos)
+				{
+					$i = 0;
+					if (is_array($todos) && count($todos))
+					{
+						foreach($todos as $todo)
+						{
+							if(!$showall && ($i++>$maxshow))
+							{
+								break;
+							}
+							$icons = '';
+							foreach($todo['icons'] as $name => $app)
+							{
+								$icons .= ($icons?' ':'').$GLOBALS['phpgw']->html->image($app,$name,lang($name),'border="0" width="15" height="15"');
+							}
+							$class = $class == 'row_on' ? 'row_off' : 'row_on';
+
+//NDEE <tr starts here
+							$content .= " <tr id=\"debug\" class=\"$class\">\n  <td valign=\"top\" width=\"15%\"nowrap>".
+								($this->bo->printer_friendly?$icons:$GLOBALS['phpgw']->html->a_href($icons,$todo['view'])).
+								"</td>\n  <td>".($this->bo->printer_friendly?$todo['title']:
+								$GLOBALS['phpgw']->html->a_href($todo['title'],$todo['view']))."</td>\n </tr>\n";
+						}
+					}
+				}
+			}
+			if (!empty($content))
+			{
+				return "<table border=\"0\" width=\"100%\">\n$content</table>\n";
+			}
+			return False;
+		}
+
+		function edit_status()
+		{
+			unset($GLOBALS['phpgw_info']['flags']['noheader']);
+			unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+			$GLOBALS['phpgw_info']['flags']['noappheader'] = True;
+			$GLOBALS['phpgw_info']['flags']['noappfooter'] = True;
+			$GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['calendar']['title'].' - '.lang('Change Status');
+			$GLOBALS['phpgw']->common->phpgw_header();
+
+			$event = $this->bo->read_entry($_GET['cal_id']);
+
+			reset($event['participants']);
+
+			if(!$event['participants'][$this->bo->owner])
+			{
+				echo '<center>'.lang('The user %1 is not participating in this event!',$GLOBALS['phpgw']->common->grab_owner_name($this->bo->owner)).'</center>';
+				return;
+			}
+
+			if(!$this->bo->check_perms(PHPGW_ACL_EDIT))
+			{
+				$this->no_edit();
+				return;
+			}
+
+			$freetime = $GLOBALS['phpgw']->datetime->localdates(mktime(0,0,0,$event['start']['month'],$event['start']['mday'],$event['start']['year']) - $GLOBALS['phpgw']->datetime->tz_offset);
+			echo $this->timematrix(
+				Array(
+					'date'		=> $freetime,
+					'starttime'	=> $this->bo->splittime('000000',False),
+					'endtime'	=> 0,
+					'participants'	=> $event['participants']
+				)
+			).'<br>';
+
+			$event = $this->bo->read_entry($_GET['cal_id']);
+			$this->view_event($event);
+			$GLOBALS['phpgw']->template->pfp('phpgw_body','view_event');
+
+			echo $this->get_response($event['id']);
+		}
+		
+		function confirm_action($duplicated_action)
+		{
+				if($_GET['response'] == 1)
+				{
+					if(!$duplicated_action)
+						$notify_message = lang('The commitment was accepted successfully!');
+					else
+						$notify_message = lang('This commitment has already been accepted!');
+				}	
+				else
+				{					
+					if(!$duplicated_action)						
+						$notify_message = lang('The commitment was rejected successfully!');
+					else
+						$notify_message = lang('This commitment has already been rejected!');
+				}
+				
+				$body1 = CreateObject('phpgwapi.Template',PHPGW_APP_TPL);
+				$body1->set_file(Array('calendar' => 'confirm.tpl'));
+				$body1->set_block('calendar','list');
+				$var = Array( 'notify_message'	=> $notify_message);
+				$body1->set_var($var);
+				$tmpbody1 = $body1->pfp('out','list');
+		}
+		function set_action()
+		{
+			if(!$this->bo->check_perms(PHPGW_ACL_EDIT))
+			{
+				$this->no_edit();
+				return;
+			}
+			
+			$confirm_status = $this->bo->set_status((int)$_GET['cal_id'],(int)$_GET['action']);
+
+			if(isset($_GET['response']))
+			{
+					$this->confirm_action($confirm_status);
+					$GLOBALS['phpgw']->common->phpgw_exit(False);
+			}
+			else
+			{
+					if ($this->bo->return_to)
+					{
+						Header('Location: '.$GLOBALS['phpgw']->link('/index.php','menuaction='.$this->bo->return_to));
+					}
+					else
+					{
+						Header('Location: '.$this->page('',''));
+					}
+					$GLOBALS['phpgw']->common->phpgw_exit();
+			}
+			
+		}
+		function planner()
+		{
+			if(floor(phpversion()) < 4)
+			{
+				return;
+			}
+			$home = strstr($_SERVER['PHP_SELF'],'home') !== False;
+			// generate header and set global/member variables
+			//
+			$this->planner_prepare($home);
+
+			// process events within selected interval
+			//
+			$this->planner_process_interval();
+
+			// generate the planner view
+			//
+			if (!$home)
+			{
+				echo '<p>'.$this->planner_print_rows();
+			}
+			else
+			{
+				return $this->planner_print_rows();
+			}
+		}
+
+		function set_planner_group_members()
+		{
+			$type = $GLOBALS['phpgw']->accounts->get_type($this->bo->owner);
+
+			if ($type == 'g') // display schedule of all group members
+			{
+				$members = array();
+				$ids = $GLOBALS['phpgw']->acl->get_ids_for_location($this->bo->owner, 1, 'phpgw_group');
+				while (list(,$id) = each($ids))
+				{
+					if ($this->bo->check_perms(PHPGW_ACL_READ,0,$id))
+					{
+						$members[$GLOBALS['phpgw']->common->grab_owner_name($id)] = $id;
+					}
+				}
+				ksort($members);
+				$this->planner_group_members = $members;
+			}
+			else
+			{
+				$this->planner_group_members = array(
+					$GLOBALS['phpgw']->common->grab_owner_name($this->bo->owner) => $this->bo->owner
+				);
+			}
+		}
+
+		/**
+		 * planner_prepare - prepare the planner view
+		 *
+		 * - sets global environment variables
+		 * - initializes class member variables used in multiple planner related functions
+		 * - generates header lines for the planner view (month, calendar week, days)
+		 */
+		function planner_prepare($no_header = False)
+		{
+			// set some globals
+			//
+			if (!$no_header)
+			{
+				unset($GLOBALS['phpgw_info']['flags']['noheader']);
+				unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+				if ($this->always_app_header) $GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['calendar']['title'].' - '.lang('Group Planner');
+				$GLOBALS['phpgw']->common->phpgw_header();
+			}
+
+			// intervals_per_day can be configured in preferences now :-)
+			//
+			if (! $this->bo->prefs['calendar']['planner_intervals_per_day'])
+			{
+				$GLOBALS['phpgw']->preferences->add('calendar','planner_intervals_per_day',3);
+				$GLOBALS['phpgw']->preferences->save_repository();
+				$this->bo->prefs['calendar']['planner_intervals_per_day'] = 3;
+			}
+			$intervals_per_day = $this->bo->prefs['calendar']['planner_intervals_per_day'];
+			$this->bo->save_sessiondata();	// need to save $this->bo->save_owner
+
+			// set title for table and rows of planner view
+			//
+			if ($this->bo->sortby == 'category')
+			{
+				$title = lang('Category');
+			}
+			else
+			{
+				$title = lang('User');
+
+				$this->set_planner_group_members();
+			}
+
+			// create/initialize variables directly used for HTML code generation
+			//
+			$this->planner_header = array();
+			$this->planner_rows   = array();
+
+			// generate header lines with days and associated months
+			//
+			$hdr = &$this->planner_header;
+			$hdr[0]['0']  = $title;
+			$hdr[0]['.0'] = 'rowspan="3"';
+
+			$this->planner_days = 0; // reset
+
+			$m = $this->bo->month;
+			$y = $this->bo->year;
+			$this->bo->read_holidays($y);
+			for ($i=1; $i<=$this->bo->num_months; $i++,$m++)
+			{
+				if ($m == 13)
+				{
+					$m = 1; $y++; // "wrap-around" into new year
+					$this->bo->read_holidays($y);
+				}
+				$days = $GLOBALS['phpgw']->datetime->days_in_month($m,$y);
+
+				$d     = mktime(0,0,0,$m,1,$y);
+				$month = lang(date('F', $d)).strftime(' %Y', $d);
+				$color = $this->theme[$m % 2 || $this->bo->num_months == 1 ? 'th_bg' : 'row_on'];
+				$cols  = $days * $intervals_per_day;
+
+				$hdr[0]['.'.$i] = 'bgcolor="'.$color.'" colspan="'.$cols.'" align="center"';
+				$prev_month = sprintf('%04d%02d01',$y-($m==1),$m > 1?$m-1:12);
+				$next_month = sprintf('%04d%02d01',$y+($m==12),$m < 12?$m+1:1);
+				$prev_link = $GLOBALS['phpgw']->link('/index.php',"menuaction=calendar.uicalendar.planner&date=$prev_month");
+				$next_link = $GLOBALS['phpgw']->link('/index.php',"menuaction=calendar.uicalendar.planner&date=$next_month");
+				$hdr[0][$i] = "<b><a href=\"$prev_link\">&lt;&lt;</a> &nbsp $month &nbsp <a href=\"$next_link\">&gt;&gt;</a></b>";
+
+				$add_owner = array();	// if no add-rights on the showed cal use own cal
+				if (!$this->bo->save_owner && !$this->bo->check_perms(PHPGW_ACL_ADD) ||
+					!$this->bo->check_perms(PHPGW_ACL_ADD,0,$this->bo->save_owner))
+				{
+					$add_owner = array(
+						'owner' => $GLOBALS['phpgw_info']['user']['account_id']
+					);
+				}
+				for ($d=1; $d<=$days; $d++)
+				{
+					$dayname = substr(lang(date('D',mktime(0,0,0,$m,$d,$y))),0,2);
+					$index = $d + $this->planner_days;
+
+					$hdr[2]['.'.$index] = 'colspan="'.$intervals_per_day.'" align="center"';
+
+					// highlight today, saturday, sunday and holidays
+					//
+					$color = $this->theme['row_off'];
+					$dow = $GLOBALS['phpgw']->datetime->day_of_week($y,$m,$d);
+					$date = sprintf("%04d%02d%02d",$y,$m,$d);
+					if ($date == date('Ymd'))
+					{
+						$color = $GLOBALS['phpgw_info']['theme']['cal_today'];
+					}
+					elseif ($this->bo->cached_holidays[$date])
+					{
+						$color = $this->bo->holiday_color;
+						$hdr[2]['.'.$index] .= ' title="'.$this->bo->cached_holidays[$date][0]['name'].'"';
+					}
+					elseif ($dow == 0 || $dow == 6)
+					{
+						$color = $this->bo->theme['th_bg'];
+					}
+
+					$hdr[2]['.'.$index] .= " bgcolor=\"$color\"";
+
+					$hdr[2][$index] = '<a href="'.$this->html->link('/index.php',
+								array(
+									'menuaction' => 'calendar.uicalendar.add',
+									'date' => $date
+								) + $add_owner
+							).'">'.$dayname.'<br>'.$d.'</a>';
+				}
+				$this->planner_days += $days;
+			}
+
+			// create/initialize member variables describing the time interval to be displayed
+			//
+			$this->planner_end_month = $m - 1;
+			$this->planner_end_year  = $y;
+			$this->planner_days_in_end_month = $GLOBALS['phpgw']->datetime->days_in_month($this->planner_end_month,$this->planner_end_year);
+			$this->planner_firstday = (int)(date('Ymd',mktime(0,0,0,$this->bo->month,1,$this->bo->year)));
+			$this->planner_lastday  = (int)(date('Ymd',mktime(0,0,0,$this->planner_end_month,$this->planner_days_in_end_month,$this->planner_end_year)));
+
+			// generate line with calendar weeks in observed interval
+			//
+			$d      = mktime(0,0,0,$this->bo->month,1,$this->bo->year);
+			$w      = date('W', $d);
+			if ($w == 'W')	// php < 4.1
+			{
+				$w = 1 + (int)(date('z',$d) / 7);	// a bit simplistic
+			}
+			$offset = (7-date('w', $d)+1)%7;
+			$offset = $offset == 0 ? 7 : $offset;
+			$color = $this->theme[$w % 2 ? 'th_bg' : 'row_on'];
+
+			$hdr[1]['.'.$w] = 'bgcolor="'.$color.'" colspan="'.$intervals_per_day * $offset.'" align="left"';
+			$hdr[1][$w] = '';
+			if ($offset >= 3)
+			{
+
+//NDEE: style! (groupplanner)
+				$hdr[1][$w] .= '<font size="-2"> '.lang('week').' '.$w.' </font>';
+			}
+			$days_left = $this->planner_days - $offset;
+
+			$colspan = 7 * $intervals_per_day;
+			while ($days_left > 0)
+			{
+				$colspan = ($days_left < 7) ? $days_left*$intervals_per_day : $colspan;
+				$d += 604800; // 7 days whith 24 hours (1h == 3600 seconds) each
+				$w = date('W', $d);
+				if ($w == 'W')	// php < 4.1
+				{
+					$w = 1 + (int)(date('z',$d) / 7);	// a bit simplistic
+				}
+				$w += (isset($hdr[1][$w]))?1:0; // bug in "date('W')" ?
+
+				$color = $this->theme[$w % 2 ? 'th_bg' : 'row_on'];
+				$hdr[1]['.'.$w] = 'bgcolor="'.$color.'" colspan="'.$colspan.'" align="left"';
+				$hdr[1][$w] = '';
+				if ($days_left >= 3)
+				{
+
+//NDEE: style! (groupplanner)
+					$hdr[1][$w] .= '<font size="-2"> '.lang('week').' '.$w.' </font>';
+				}
+
+				$days_left -= 7;
+			}
+			return $hdr;
+		}
+
+		/**
+		 * planner_update_row - update a row of the planner view
+		 *
+		 * parameters are:
+		 *   - index (e.g. user id, category id, ...) of the row
+		 *   - name/title of the row (e.g. user name, category name)
+		 *   - the event to be integrated
+		 *   - list of categories associated with the event
+		 *   - first and last cell of the row
+		 */
+		function planner_update_row($index,$name,$event,$cat,$start_cell,$end_cell)
+		{
+			$rows              = &$this->planner_rows;
+			$intervals_per_day = $this->bo->prefs['calendar']['planner_intervals_per_day'];
+			$is_private        = !$this->bo->check_perms(PHPGW_ACL_READ,$event);
+
+			$view = $this->html->link('/index.php',
+				array(
+					'menuaction' => 'calendar.uicalendar.view',
+					'cal_id' => $event['id'],
+					'date' => date('Ymd',$this->bo->maketime($event['start']))
+				)
+			);
+
+			// check how many lines are needed for this "row" (currently: user or category)
+			$i = 0;
+			do {
+				++$i;
+
+				$k = $index.'_'.$i;
+				$ka = '.nr_'.$k;
+
+				if (!isset($rows[$k]))
+				{
+					if ($i > 1)				// further line - no name
+					{
+						$rows[$k] = array();
+						$rows[$index.'_1']['._name'] = 'rowspan="'.$i.'"';
+					}
+					else
+					{
+						$rows[$k]['_name'] = $name;
+					}
+					$rows[$ka] = 0;
+				}
+				$rows[$index.'_1']['._name'] .= ' nowrap'; // title must be one row
+
+				$row = &$rows[$k];
+				$akt_cell = &$rows[$ka];
+			} while ($akt_cell > $start_cell);
+
+			$id = $event['id'].'-'.date('Ymd',$this->bo->maketime($event['start']));
+			if ($akt_cell < $start_cell)
+			{
+				$row[$id.'_1'] = '&nbsp;';
+				$row['.'.$id.'_1'] = 'colspan="'.($start_cell-$akt_cell).'"';
+			}
+			$opt = &$row['.'.$id.'_2'];
+			$cel = &$row[$id.'_2'];
+
+			// if possible, display information about event within cells representing it
+			//
+			if ($start_cell < $end_cell)
+			{
+				$colspan = $end_cell - $start_cell;
+				$opt .= "colspan=".(1 + $colspan);
+
+				if (!$is_private)
+				{
+					$max_chars = (int)(3*$colspan/$intervals_per_day-2);
+
+					$min_chars = 3; // minimum for max_chars to display -> this should be configurable
+					if ($max_chars >= $min_chars)
+					{
+						$len_title = strlen($event['title']);
+
+						if ($len_title <= $max_chars)
+						{
+							$title = $event['title'];
+							$max_chars -= $len_title + 3; // 3 chars for separator: " - "
+							$len_descr = strlen($event['description']);
+
+							if ($len_descr > 0 && $len_descr <= $max_chars)
+							{
+								$event['print_description'] = 'yes';
+							}
+						}
+						else
+						{
+							$has_amp = strpos($event['title'],'&amp;');
+							
+//NDEE: event title gets cut here							
+							$title = substr($event['title'], 0 , $max_chars-1+($has_amp!==False&&$has_amp<$max_chars?4:0)).'...';
+						}
+						$event['print_title'] = 'yes';
+					}
+				}
+			}
+
+			if ($bgcolor=$cat['color'])
+			{
+				$opt .= ' bgcolor="'.$bgcolor.'"';
+			}
+			if (!$is_private)
+			{
+				$opt .= ' title="'.lang('Title').": ".$event['title'];
+				if ($event['description'])
+				{
+					$opt .= "\n".lang('Description').": ".$event['description'];
+				}
+			}
+			else
+			{
+				$opt .= ' title="'.lang('You do not have permission to read this record!');
+			}
+
+			$start = $GLOBALS['phpgw']->common->show_date($this->bo->maketime($event['start']) - $GLOBALS['phpgw']->datetime->tz_offset);
+			$end = $GLOBALS['phpgw']->common->show_date($this->bo->maketime($event['end']) - $GLOBALS['phpgw']->datetime->tz_offset);
+			$opt .= "\n".lang('Start Date/Time').": ".$start."\n".lang('End Date/Time').": ".$end;
+
+			if ($event['location'] && !$is_private)
+			{
+				$opt .= " \n".lang('Location').": ".$event['location'];
+			}
+
+			if (!$is_private)
+			{
+				$opt .= '" onClick="location=\''.$view.'\'"';
+				$cel = '<a href="'.$view.'">';
+			}
+			else
+			{
+				$opt .= '"';
+				$cel = '';
+			}
+			$opt .= ' class="planner-cell"';
+
+			if ($event['priority'] == 3)
+			{
+				$cel .= $this->html->image('calendar','mini-calendar-bar.gif','','border="0"');
+			}
+			if ($event['recur_type'])
+			{
+				$cel .= $this->html->image('calendar','recur.gif','','border="0"');
+			}
+			$cel .= $this->html->image('calendar',count($event['participants'])>1?'multi_3.gif':'single.gif',$this->planner_participants($event['participants']),'border="0"');
+			$cel .= '</a>';
+
+			if (isset($event['print_title']) && $event['print_title'] == 'yes')
+			{
+
+//NDEE: style! where?
+				$cel .= '<font size="-2"> '.$title.' </font>';
+			}
+			if (isset($event['print_description']) && $event['print_description'] == 'yes')
+			{
+
+//NDEE: style! where ?
+				$cel .= '<font size="-2"> - '.$event['description'].' </font>';
+			}
+
+			$akt_cell = $end_cell + 1;
+
+			return $rows;
+		}
+
+		function planner_process_event($event)
+		{
+			$intervals_per_day = $this->bo->prefs['calendar']['planner_intervals_per_day'];
+			$interval = $this->planner_intervals[$intervals_per_day];
+			$last_cell = $intervals_per_day * $this->planner_days - 1;
+
+			$rows = &$this->planner_rows;
+
+			// caluculate start and end of event
+			//
+			$event_start = (int)(date('Ymd',mktime(
+				0,0,0,
+				$event['start']['month'],
+				$event['start']['mday'],
+				$event['start']['year']
+			)));
+			$event_end   = (int)(date('Ymd',mktime(
+				0,0,0,
+				$event['end']['month'],
+				$event['end']['mday'],
+				$event['end']['year']
+			)));
+
+			// calculate first cell of event within observed interval
+			//
+			if ($event_start >= $this->planner_firstday)
+			{
+				$days_between = $GLOBALS['phpgw']->datetime->days_between($this->bo->month,1,$this->bo->year,$event['start']['month'],$event['start']['mday'],$event['start']['year']);
+
+				$start_cell = $intervals_per_day * $days_between + $interval[$event['start']['hour']];
+			}
+			else
+			{
+				$start_cell = 0;
+			}
+
+			// calculate last cell of event within observed interval
+			//
+			if ($event_end <= $this->planner_lastday)
+			{
+				$days_between = $GLOBALS['phpgw']->datetime->days_between($this->bo->month,1,$this->bo->year,$event['end']['month'],$event['end']['mday'],$event['end']['year']);
+				$end_cell = $intervals_per_day * $days_between + $interval[$event['end']['hour']];
+				if ($end_cell == $start_cell && $end_cell < $last_cell)
+				{
+					$end_cell++;	// min. width 1 interval
+				}
+			}
+			else
+			{
+				$end_cell = $last_cell;
+			}
+			// get the categories associated with event
+			//
+			if ($c = $event['category'])
+			{
+				list($cat)   = $this->planner_category($event['category']);
+				if ($cat['parent'])
+				{
+					list($pcat) = $this->planner_category($c = $cat['parent']);
+				}
+				else
+				{
+					$pcat = $cat;
+				}
+			}
+			else
+			{
+				$cat = $pcat = array( 'name' => lang('none'));
+			}
+
+			// add the event to it`s associated row(s)
+			//
+			if ($this->bo->sortby == 'category')
+			{
+				// event needs to show up in it`s category`s row
+				//
+				$this->planner_update_row($c,$pcat['name'],$event,$cat,$start_cell,$end_cell);
+			}
+			elseif ($this->bo->sortby == 'user')
+			{
+				// event needs to show up in rows of all participants that are also owners
+				//
+				reset($this->planner_group_members);
+				while(list($user_name,$id) = each($this->planner_group_members))
+				{
+					$status = $event['participants'][$id];
+
+					if (isset($status) && $status != 'R')
+					{
+						$this->planner_update_row($user_name,$user_name,$event,$cat,$start_cell,$end_cell);
+					}
+				}
+			}
+		}
+
+		function planner_pad_rows()
+		{
+			$rows = &$this->planner_rows;
+
+			if ($this->bo->sortby == 'user')
+			{
+				// add empty rows for users that do not participante in any event
+				//
+				reset($this->planner_group_members);
+				while(list($user_name,$id) = each($this->planner_group_members))
+				{
+					$k  = $user_name.'_1';
+					$ka = '.nr_'.$k;
+
+					if (!isset($rows[$k]))
+					{
+						$rows[$k]['_name'] = $user_name;
+						$rows[$k]['._name'] .= ' nowrap';
+						$rows[$ka] = 0;
+					}
+				}
+			}
+
+			// fill the remaining cols
+			//
+			$last_cell = $this->bo->prefs['calendar']['planner_intervals_per_day'] * $this->planner_days - 1;
+
+			ksort($rows);
+			while (list($k,$r) = each($rows))
+			{
+				if (is_array($r))
+				{
+					$rows['.'.$k] = 'bgcolor="'.$GLOBALS['phpgw']->nextmatchs->alternate_row_color().'"';
+					$row = &$rows[$k];
+					$akt_cell = &$rows['.nr_'.$k];
+					if ($akt_cell < $last_cell)
+					{
+						$row['3'] = '&nbsp';
+						$row['.3'] = 'colspan="'.(1+$last_cell-$akt_cell).'"';
+					}
+				}
+			}
+		}
+
+		function planner_print_rows()
+		{
+			$bgcolor = 'bgcolor="'.$this->theme['th_bg'].'"';
+			$intervals_per_day = $this->bo->prefs['calendar']['planner_intervals_per_day'];
+
+			if ($this->debug)
+			{
+				_debug_array($this->planner_rows);
+				reset($this->planner_rows);
+			}
+			return $this->html->table(
+				array(
+					'_hdr0' => $this->planner_header[0],
+					'._hdr0' => $bgcolor,
+					'_hdr1' => $this->planner_header[1],
+					'._hdr1' => $bgcolor,
+					'_hdr2' => $this->planner_header[2],
+					'._hdr2' => $bgcolor
+				)+$this->planner_rows,
+				'width="100%" cols="'.(1+$this->planner_days_in_end_month*$intervals_per_day).'"');
+		}
+
+		function planner_process_interval()
+		{
+			// generate duplicate free list of events within observed interval
+			//
+			$this->bo->store_to_cache(
+				Array(
+					'syear'	=> $this->bo->year,
+					'smonth'	=> $this->bo->month,
+					'sday'	=> 1,
+					'eyear'	=> $this->planner_end_year,
+					'emonth'	=> $this->planner_end_month,
+					'eday'	=> $this->planner_days_in_end_month
+				)
+			);
+			$this->bo->remove_doubles_in_cache($this->planner_firstday,$this->planner_lastday);
+
+			// process all events within observed interval
+			//
+			for($v=$this->planner_firstday;$v<=$this->planner_lastday;$v++)
+			{
+				$daily = $this->bo->cached_events[$v];
+
+				print_debug('For Date',$v);
+				print_debug('Count of items',count($daily));
+
+				// process all events on day $v
+				//
+				if (is_array($daily)) foreach($daily as $event)
+				{
+					if ($event['recur_type'])	// calculate start- + end-datetime for recuring events
+					{
+						$this->bo->set_recur_date($event,$v);
+					}
+					if (!$this->bo->rejected_no_show($event))
+					{
+						$this->planner_process_event($event);
+					}
+				}
+			}
+			$this->planner_pad_rows();
+		}
+
+		function matrixselect()
+		{
+			$datetime = mktime(0,0,0,$this->bo->month,$this->bo->day,$this->bo->year) - $GLOBALS['phpgw']->datetime->tz_offset;
+
+			$sb = CreateObject('phpgwapi.sbox');
+
+			unset($GLOBALS['phpgw_info']['flags']['noheader']);
+			unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+			if ($this->always_app_header) $GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['calendar']['title'].' - '.lang('Matrixview');
+			$GLOBALS['phpgw']->common->phpgw_header();
+
+			$p = &$GLOBALS['phpgw']->template;
+			$p->set_file(
+				Array(
+					'mq'		=> 'matrix_query.tpl',
+					'form_button'	=> 'form_button_script.tpl'
+				)
+			);
+			$p->set_block('mq','matrix_query','matrix_query');
+			$p->set_block('mq','list','list');
+
+			$p->set_var(array(
+				'title'			=> lang('Daily Matrix View'),
+				'th_bg'			=> $this->theme['th_bg'],
+				'action_url'	=> $this->page('viewmatrix')
+			));
+
+// Date
+			$var[] = Array(
+				'field'	=>	lang('Date'),
+				'data'	=>	$GLOBALS['phpgw']->common->dateformatorder(
+					$sb->getYears('year',(int)$GLOBALS['phpgw']->common->show_date($datetime,'Y'),(int)$GLOBALS['phpgw']->common->show_date($datetime,'Y')),
+					$sb->getMonthText('month',(int)$GLOBALS['phpgw']->common->show_date($datetime,'n')),
+					$sb->getDays('day',(int)$GLOBALS['phpgw']->common->show_date($datetime,'d'))
+				)
+			);
+
+// View type
+			$var[] = Array(
+				'field'	=>	lang('View'),
+				'data'	=>	'<select name="matrixtype">'."\n"
+					. '<option value="free/busy" selected>'.lang('free/busy').'</option>'."\n"
+					. '<option value="weekly">'.lang('Weekly').'</option>'."\n"
+					. '</select>'."\n"
+			);
+
+// Participants
+			$accounts = $GLOBALS['phpgw']->acl->get_ids_for_location('run',1,'calendar');
+			$users = Array();
+			for($i=0;$i<count($accounts);$i++)
+			{
+				$user = $accounts[$i];
+				if(!isset($users[$user]))
+				{
+					$users[$user] = $GLOBALS['phpgw']->common->grab_owner_name($user);
+					if($GLOBALS['phpgw']->accounts->get_type($user) == 'g')
+					{
+						$group_members = $GLOBALS['phpgw']->acl->get_ids_for_location($user,1,'phpgw_group');
+						if($group_members != False)
+						{
+							for($j=0;$j<count($group_members);$j++)
+							{
+								if(!isset($users[$group_members[$j]]))
+								{
+									$users[$group_members[$j]] = $GLOBALS['phpgw']->common->grab_owner_name($group_members[$j]);
+								}
+							}
+						}
+					}
+				}
+			}
+
+			$num_users = count($users);
+
+			if ($num_users > 50)
+			{
+				$size = 15;
+			}
+			elseif ($num_users > 5)
+			{
+				$size = 5;
+			}
+			else
+			{
+				$size = $num_users;
+			}
+			$str = '';
+			@asort($users);
+			@reset($users);
+			while ($user = each($users))
+			{
+				if(($GLOBALS['phpgw']->accounts->exists($user[0]) && $this->bo->check_perms(PHPGW_ACL_READ,0,$user[0])) || $GLOBALS['phpgw']->accounts->get_type($user[0]) == 'g')
+				{
+					$str .= '    <option value="'.$user[0].'">('.$GLOBALS['phpgw']->accounts->get_type($user[0]).') '.$user[1].'</option>'."\n";
+				}
+			}
+			$var[] = Array(
+				'field'	=>	lang('Participants'),
+				'data'	=>	"\n".'   <select name="participants[]" multiple size="'.$size.'">'."\n".$str.'   </select>'."\n"
+			);
+
+			for($i=0;$i<count($var);$i++)
+			{
+				$this->output_template_array($p,'rows','list',$var[$i]);
+			}
+
+			$vars = Array(
+				'submit_button'		=> lang('View'),
+				'action_url_button'	=> $this->bo->return_to ? $GLOBALS['phpgw']->link('/index.php','menuaction='.$this->bo->return_to) : $this->page(''),
+				'action_text_button'	=> lang('Cancel'),
+				'action_confirm_button'	=> '',
+				'action_extra_field'	=> ''
+			);
+
+			$p->set_var($vars);
+			$p->parse('cancel_button','form_button');
+			$p->pparse('out','matrix_query');
+		}
+
+		function viewmatrix()
+		{
+			if ($_POST['cancel'])
+			{
+				$this->index();
+			}
+			$participants = $_POST['participants'];
+			$parts = Array();
+			$acct = CreateObject('phpgwapi.accounts',$this->bo->owner);
+
+			if (is_array($participants))
+			{
+				foreach($participants as $participant)
+				{
+					switch ($GLOBALS['phpgw']->accounts->get_type($participant))
+					{
+						case 'g':
+							if ($members = $acct->member((int)$participant))
+							{
+								foreach($members as $member)
+								{
+									if($this->bo->check_perms(PHPGW_ACL_READ,0,$member['account_id']))
+									{
+										$parts[$member['account_id']] = True;
+									}
+								}
+							}
+							break;
+						case 'u':
+							if($this->bo->check_perms(PHPGW_ACL_READ,0,$participant))
+							{
+								$parts[$participant] = 1;
+							}
+							break;
+					}
+				}
+				unset($acct);
+			}
+			$participants = array_keys($parts);	// get id's as values and a numeric index
+
+			// Defined - into session - who participates
+			$GLOBALS['phpgw']->session->appsession("participants", NULL, implode(";", $participants));
+
+			unset($GLOBALS['phpgw_info']['flags']['noheader']);
+			unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+			if ($this->always_app_header) $GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['calendar']['title'].' - '.lang('Matrixview');
+			$GLOBALS['phpgw']->common->phpgw_header();
+
+			switch($_POST['matrixtype'])
+			{
+				case 'free/busy':
+					$freetime = $GLOBALS['phpgw']->datetime->gmtdate(mktime(0,0,0,$this->bo->month,$this->bo->day,$this->bo->year));
+					echo '<br>'.$this->timematrix(
+						Array(
+							'date'		=> $freetime,
+							'starttime'	=> $this->bo->splittime('000000',False),
+							'endtime'	=> 0,
+							'participants'	=> $parts
+						)
+					);
+					break;
+				case 'weekly':
+					echo '<br>'.$this->display_weekly(
+						Array(
+							'date'		=> sprintf("%04d%02d%02d",$this->bo->year,$this->bo->month,$this->bo->day),
+							'showyear'	=> true,
+							'owners'	=> $participants
+						)
+					);
+					break;
+			}
+			echo "\n<br>\n".'<form action="'.$this->page('viewmatrix').'" method="post" name="matrixform">'."\n";
+			echo ' <table cellpadding="5"><tr><td>'."\n";
+			echo '  <input type="hidden" name="year" value="'.$this->bo->year.'">'."\n";
+			echo '  <input type="hidden" name="month" value="'.$this->bo->month.'">'."\n";
+			echo '  <input type="hidden" name="day" value="'.$this->bo->day.'">'."\n";
+			echo '  <input type="hidden" name="matrixtype" value="'.$_POST['matrixtype'].'">'."\n";
+			foreach($participants as $part)
+			{
+				echo '  <input type="hidden" name="participants[]" value="'.$part.'">'."\n";
+			}
+			echo '  <input type="submit" name="refresh" value="'.lang('Refresh').'">'."\n";
+			echo ' </td><td>'."\n";
+			echo '  <input type="submit" name="cancel" value="'.lang('Cancel').'">'."\n";
+			echo ' </td></tr></table>'."\n";
+			echo '</form>'."\n";
+		}
+
+		function search()
+		{
+			if (empty($_POST['keywords']))
+			{
+				// If we reach this, it is because they didn't search for anything
+				// or they used one of the selectboxes (year, month, week) in the search-result
+				// attempt to send them back to where they came from.
+
+				$vars['menuaction'] = isset($_POST['from']) && $_POST['from'] != 'calendar.uicalendar.search' ?
+					$_POST['from'] : 'calendar.uicalendar.index';
+
+				foreach(array('date','year','month','day') as $field)
+				{
+					if (isset($_POST[$field]))
+					{
+						$vars[$field] = $_POST[$field];
+					}
+				}
+				$GLOBALS['phpgw']->redirect_link('/index.php',$vars);
+			}
+
+			unset($GLOBALS['phpgw_info']['flags']['noheader']);
+			unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+			$GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['calendar']['title'].' - '.lang('Search Results');
+			$GLOBALS['phpgw']->common->phpgw_header();
+
+			$error = '';
+
+			$matches = 0;
+
+			// There is currently a problem searching in with repeated events.
+			// It spits back out the date it was entered.  I would like to to say that
+			// it is a repeated event.
+
+			// This has been solved by the little icon indicator for recurring events.
+
+			$event_ids = $this->bo->search_keywords($_POST['keywords']);
+			foreach($event_ids as $key => $id)
+			{
+				$event = $this->bo->read_entry($id);
+
+				if(!$this->bo->check_perms(PHPGW_ACL_READ,$event))
+				{
+					continue;
+				}
+
+				$datetime = $this->bo->maketime($event['start']) - $GLOBALS['phpgw']->datetime->tz_offset;
+
+				$info[strval($event['id'])] = array(
+					'tr_color'	=> $GLOBALS['phpgw']->nextmatchs->alternate_row_color(),
+					'date'		=> $GLOBALS['phpgw']->common->show_date($datetime),
+					'link'		=> $this->link_to_entry($event,$event['start']['month'],$event['start']['mday'],$event['start']['year'])
+				);
+
+			}
+			$matches = count($event_ids);
+
+			if ($matches == 1)
+			{
+				$quantity = lang('1 match found').'.';
+			}
+			elseif ($matches > 0)
+			{
+				$quantity = lang('%1 matches found',$matches).'.';
+			}
+			else
+			{
+				echo '<b>'.lang('Error').':</b>'.lang('no matches found');
+				return;
+			}
+
+			$p = $GLOBALS['phpgw']->template;
+			$p->set_file(
+				Array(
+					'search_form'	=> 'search.tpl'
+				)
+			);
+			$p->set_block('search_form','search','search');
+			$p->set_block('search_form','search_list_header','search_list_header');
+			$p->set_block('search_form','search_list','search_list');
+			$p->set_block('search_form','search_list_footer','search_list_footer');
+
+			$var = Array(
+				'th_bg'		=> $this->theme['th_bg'],
+				'search_text'	=> lang('Search Results'),
+				'quantity'	=> $quantity
+			);
+			$p->set_var($var);
+
+			if($matches > 0)
+			{
+				$p->parse('rows','search_list_header',True);
+			}
+			foreach($info as $id => $data)
+			{
+				$p->set_var($data);
+				$p->parse('rows','search_list',True);
+			}
+
+			if($matches > 0)
+			{
+				$p->parse('rows','search_list_footer',True);
+			}
+
+			$p->pparse('out','search');
+		}
+
+		/* Private functions */
+		function _debug_sqsof()
+		{
+			$data = array(
+				'filter'     => $this->bo->filter,
+				'cat_id'     => $this->bo->cat_id,
+				'owner'      => $this->bo->owner,
+				'year'       => $this->bo->year,
+				'month'      => $this->bo->month,
+				'day'        => $this->bo->day,
+				'sortby'     => $this->bo->sortby,
+				'num_months' => $this->bo->num_months
+			);
+			Return _debug_array($data,False);
+		}
+
+		function output_template_array(&$p,$row,$list,$var)
+		{
+			if (!isset($var['hidden_vars']))
+			{
+				$var['hidden_vars'] = '';
+			}
+			if (!isset($var['tr_color']))
+			{
+				$var['tr_color'] = $GLOBALS['phpgw']->nextmatchs->alternate_row_color();
+			}
+			$p->set_var($var);
+			$p->parse($row,$list,True);
+		}
+
+		function page($_page='',$params='')
+		{
+			if($_page == '')
+			{
+				$page_ = explode('.',$this->bo->prefs['calendar']['defaultcalendar']);
+				$_page = $page_[0];
+
+				if ($_page=='planner_cat' || $_page=='planner_user')
+				{
+					$_page = 'planner';
+				}
+				elseif ($_page=='index' || ($_page != 'day' && $_page != 'week' && $_page != 'month' && $_page != 'year' && $_page != 'planner'))
+				{
+					$_page = 'month';
+					$GLOBALS['phpgw']->preferences->add('calendar','defaultcalendar','month');
+					$GLOBALS['phpgw']->preferences->save_repository();
+				}
+			}
+			if($GLOBALS['phpgw_info']['flags']['currentapp'] == 'home' ||
+				strstr($GLOBALS['phpgw_info']['flags']['currentapp'],'mail'))	// email, felamimail, ...
+			{
+				$page_app = 'calendar';
+			}
+			else
+			{
+				$page_app = $GLOBALS['phpgw_info']['flags']['currentapp'];
+			}
+			if (is_array($params))
+			{
+				$params['menuaction'] = $page_app.'.ui'.$page_app.'.'.$_page;
+			}
+			else
+			{
+				$params = 'menuaction='.$page_app.'.ui'.$page_app.'.'.$_page.$params;
+			}
+			return $GLOBALS['phpgw']->link('/index.php',$params);
+		}
+
+		function header()
+		{
+			$cols = 8;
+			if($this->bo->check_perms(PHPGW_ACL_PRIVATE) == True)
+			{
+				$cols++;
+			}
+
+			$tpl = $GLOBALS['phpgw']->template;
+			$tpl->set_unknowns('remove');
+
+			if (!file_exists($file = $this->template_dir.'/header.inc.php'))
+			{
+				$file = PHPGW_SERVER_ROOT . '/calendar/templates/default/header.inc.php';
+			}
+			
+			include($file);
+			$refer = explode('.',$GLOBALS['HTTP_GET_VARS']['menuaction']);
+			if($refer[2] != 'view') {
+			$header = $tpl->fp('out','head');
+			unset($tpl);
+			echo $header;
+		}
+			unset($tpl);
+		}
+
+		function footer()
+		{
+			$menuaction = $_GET['menuaction'];
+			list(,,$method) = explode('.',$menuaction);
+
+			if (@$this->bo->printer_friendly)
+			{
+				return;
+			}
+
+			$p = $GLOBALS['phpgw']->template;
+
+			$p->set_file(
+				Array(
+					'footer'	=> 'footer.tpl',
+					'form_button'	=> 'form_button_script.tpl'
+				)
+			);
+			$p->set_block('footer','footer_table','footer_table');
+			$p->set_block('footer','footer_row','footer_row');
+			$p->set_block('footer','blank_row','blank_row');
+
+			$m = $this->bo->month;
+			$y = $this->bo->year;
+
+			$thisdate = date('Ymd',mktime(0,0,0,$m,1,$y));
+			$y--;
+
+			$str = '';
+			for ($i = 0; $i < 25; $i++)
+			{
+				$m++;
+				if ($m > 12)
+				{
+					$m = 1;
+					$y++;
+				}
+				$d = mktime(0,0,0,$m,1,$y);
+				$d_ymd = date('Ymd',$d);
+				$str .= '<option value="'.$d_ymd.'"'.($d_ymd == $thisdate?' selected':'').'>'.lang(date('F', $d)).strftime(' %Y', $d).'</option>'."\n";
+			}
+
+			$var = Array(
+				'action_url'	=> $this->page($method,''),
+				'form_name'	=> 'SelectMonth',
+				'label'		=> lang('Month'),
+				'form_label'	=> 'date',
+				'form_onchange'	=> 'document.SelectMonth.submit()',
+				'row'		=> $str,
+				'go'		=> lang('Go!')
+			);
+			$this->output_template_array($p,'table_row','footer_row',$var);
+
+			if($menuaction == 'calendar.uicalendar.week')
+			{
+				unset($thisdate);
+				$thisdate = mktime(0,0,0,$this->bo->month,$this->bo->day,$this->bo->year) - $GLOBALS['phpgw']->datetime->tz_offset;
+				$sun = $GLOBALS['phpgw']->datetime->get_weekday_start($this->bo->year,$this->bo->month,$this->bo->day) - $GLOBALS['phpgw']->datetime->tz_offset;
+
+				$str = '';
+				for ($i = -7; $i <= 7; $i++)
+				{
+					$begin = $sun + (7*24*60*60 * $i) + 12*60*60;	// we use midday, that changes in daylight-saveing does not effect us
+					$end = $begin + 6*24*60*60;
+//					echo "<br>$i: ".date('d.m.Y H:i',$begin).' - '.date('d.m.Y H:i',$end);
+                    $str .= '<option value="' . $GLOBALS['phpgw']->common->show_date($begin,'Ymd') . '"'.($begin <= $thisdate+12*60*60 && $end >= $thisdate+12*60*60 ? ' selected':'').'>'                    
+						. $GLOBALS['phpgw']->common->show_date($begin,$GLOBALS['phpgw_info']['user']['preferences']['common']['dateformat']) . ' - '
+                        . $GLOBALS['phpgw']->common->show_date($end,$GLOBALS['phpgw_info']['user']['preferences']['common']['dateformat'])
+                        . '</option>' . "\n";                        
+				}
+
+				$var = Array(
+					'action_url'	=> $this->page($method,''),
+					'form_name'	=> 'SelectWeek',
+					'label'		=> lang('Week'),
+					'form_label'	=> 'date',
+					'form_onchange'	=> 'document.SelectWeek.submit()',
+					'row'		=> $str,
+					'go'		=> lang('Go!')
+				);
+
+				$this->output_template_array($p,'table_row','footer_row',$var);
+			}
+
+			$str = '';
+			for ($i = ($this->bo->year - 3); $i < ($this->bo->year + 3); $i++)
+			{
+				$str .= '<option value="'.$i.'"'.($i == $this->bo->year?' selected':'').'>'.$i.'</option>'."\n";
+			}
+
+			$var = Array(
+				'action_url'	=> $this->page($method,''),
+				'form_name'	=> 'SelectYear',
+				'label'		=> lang('Year'),
+				'form_label'	=> 'year',
+				'form_onchange'	=> 'document.SelectYear.submit()',
+				'row'		=> $str,
+				'go'		=> lang('Go!')
+			);
+			$this->output_template_array($p,'table_row','footer_row',$var);
+
+			if($menuaction == 'calendar.uicalendar.planner')
+			{
+				$str = '';
+				$date_str = '';
+
+				if(isset($_GET['date']) && $_GET['date'])
+				{
+					$date_str .= '    <input type="hidden" name="date" value="'.$_GET['date'].'">'."\n";
+				}
+				$date_str .= '    <input type="hidden" name="month" value="'.$this->bo->month.'">'."\n";
+				$date_str .= '    <input type="hidden" name="day" value="'.$this->bo->day.'">'."\n";
+				$date_str .= '    <input type="hidden" name="year" value="'.$this->bo->year.'">'."\n";
+
+				for($i=1; $i<=6; $i++)
+				{
+					$str .= '<option value="'.$i.'"'.($i == $this->bo->num_months?' selected':'').'>'.$i.'</option>'."\n";
+				}
+
+				$var = Array(
+					'action_url'	=> $this->page($method,''),
+					'form_name'	=> 'SelectNumberOfMonths',
+					'label'		=> lang('Number of Months'),
+					'hidden_vars' => $date_str,
+					'form_label'	=> 'num_months',
+					'form_onchange'	=> 'document.SelectNumberOfMonths.submit()',
+					'action_extra_field'	=> $date_str,
+					'row'		=> $str,
+					'go'		=> lang('Go!')
+				);
+				$this->output_template_array($p,'table_row','footer_row',$var);
+			}
+
+			$var = Array(
+				'submit_button'		=> lang('Submit'),
+				'action_url_button'	=> $GLOBALS['phpgw']->link('/index.php','menuaction=calendar.uiicalendar.import'),
+				'action_text_button'	=> lang('Import'),
+				'action_confirm_button'	=> '',
+				'action_extra_field'	=> ''
+			);
+			$this->output_template_array($p,'b_row','form_button',$var);
+			
+			$var = Array(
+				'submit_button'		=> lang('Submit'),
+				'action_url'	=> $this->page($method,''),
+				'action_url_button'	=> $GLOBALS['phpgw']->link('/index.php','menuaction=calendar.uicalendar.export_all'),
+				'action_text_button'	=> lang('Export all'),
+				'action_confirm_button'	=> '',
+				'action_extra_field'	=> ''
+			);
+			$this->output_template_array($p,'b_row2','form_button',$var);
+					
+			$p->parse('table_row','blank_row',True);
+
+			$p->pparse('out','footer_table');
+			unset($p);
+		}
+
+		function css()
+		{
+			$GLOBALS['phpgw']->browser->browser();
+			if($GLOBALS['phpgw']->browser->get_agent() == 'MOZILLA')
+			{
+				$time_width = ((int)($this->bo->prefs['common']['time_format']) == 12?12:8);
+			}
+			else
+			{
+				$time_width = ((int)($this->bo->prefs['common']['time_format']) == 12?10:7);
+			}
+
+// moved to app.css in templates/default for future separation of code and style [NDEE 10.03.04]
+/*
+			 return 'A.minicalendar { color: #000000; font-size: 72%; font-family: '.$this->theme['font'].' }'."\n"
+				. '  A.bminicalendar { color: #336699; font: italic bold x-small '.$this->theme['font'].' }'."\n"
+				. '  A.minicalendargrey { color: #999999; font-size: 8px; font-family: '.$this->theme['font'].' }'."\n"
+				. '  A.bminicalendargrey { color: #336699; font-style: italic; font-size:8px; font-family '.$this->theme['font'].' }'."\n"
+				. '  A.minicalhol { padding-left:3px; padding-right:3px; background: '.$this->holiday_color.'; color: #000000; font: x-small '.$this->theme['font'].' }'."\n"
+				. '  A.bminicalhol { padding-left:3px; padding-right:3px; background: '.$this->holiday_color.'; color: #336699; font: italic bold x-small '.$this->theme['font'].' }'."\n"
+				. '  A.minicalgreyhol { padding-left:3px; padding-right:3px; background: '.$this->holiday_color.'; color: #999999; font: x-small '.$this->theme['font'].' }'."\n"
+				. '  A.bminicalgreyhol { padding-left:3px; padding-right:3px; background: '.$this->holiday_color.'; color: #999999; font: italic bold x-small '.$this->theme['font'].' }'."\n"
+				. '  .event-on { background: '.$this->theme['row_on'].'; color: '.$this->theme['bg_text'].'; font: 100% '.$this->theme['font'].'; vertical-align: middle }'."\n"
+				. '  .event-off { background: '.$this->theme['row_off'].'; color: '.$this->theme['bg_text'].'; font: 100% '.$this->theme['font'].'; vertical-align: middle }'."\n"
+				. '  .event-holiday { background: '.$this->theme['bg04'].'; color: '.$this->theme['bg_text'].'; font: 100% '.$this->theme['font'].'; vertical-align: middle }'."\n"
+				. '  .time { background: '.$this->theme['th_bg'].'; color: '.$this->theme['bg_text'].'; font: bold 100% '.$this->theme['font'].'; width: '.$time_width.'%; vertical-align: middle; text-align: right; }'."\n"
+				. '  .tablecell { width: 80px; height: 80px }'."\n"
+				. '  .planner-cell { cursor:pointer; cursor:hand; border: thin solid black; }';
+*/
+		}
+
+		function no_edit()
+		{
+			if(!isset($GLOBALS['phpgw_info']['flags']['noheader']))
+			{
+				unset($GLOBALS['phpgw_info']['flags']['noheader']);
+				unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+				$GLOBALS['phpgw_info']['flags']['noappheader'] = True;
+				$GLOBALS['phpgw_info']['flags']['noappfooter'] = True;
+				$GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['calendar']['title'].' - '.lang('Permission denied');
+				$GLOBALS['phpgw']->common->phpgw_header();
+			}
+			echo '<center>You do not have permission to edit this appointment!</center>';
+			return;
+		}
+
+		function link_to_entry($event,$month,$day,$year)
+		{
+			$str = '';
+			$is_private = !$event['public'] && !$this->bo->check_perms(PHPGW_ACL_READ,$event);
+			$viewable = !$this->bo->printer_friendly && $this->bo->check_perms(PHPGW_ACL_READ,$event);
+
+			$starttime = $this->bo->maketime($event['start']) - $GLOBALS['phpgw']->datetime->tz_offset;
+			$endtime = $this->bo->maketime($event['end']) - $GLOBALS['phpgw']->datetime->tz_offset;
+			$rawdate = mktime(0,0,0,$month,$day,$year);
+			$rawdate_offset = $rawdate - $GLOBALS['phpgw']->datetime->tz_offset;
+			$nextday = mktime(0,0,0,$month,$day + 1,$year) - $GLOBALS['phpgw']->datetime->tz_offset;
+			if ((int)$GLOBALS['phpgw']->common->show_date($starttime,'Hi') && $starttime == $endtime)
+			{
+				$time = $GLOBALS['phpgw']->common->show_date($starttime,$this->bo->users_timeformat);
+			}
+			elseif ($starttime <= $rawdate_offset && $endtime >= $nextday - 60)
+			{
+				$time = '[ '.lang('All Day').' ]';
+			}
+			elseif ((int)$GLOBALS['phpgw']->common->show_date($starttime,'Hi') || $starttime != $endtime)
+			{
+				if($starttime < $rawdate_offset && $event['recur_type'] == MCAL_RECUR_NONE)
+				{
+					$start_time = $GLOBALS['phpgw']->common->show_date($rawdate_offset,$this->bo->users_timeformat);
+				}
+				else
+				{
+					$start_time = $GLOBALS['phpgw']->common->show_date($starttime,$this->bo->users_timeformat);
+				}
+
+				if($endtime >= ($rawdate_offset + 86400))
+				{
+					$end_time = $GLOBALS['phpgw']->common->show_date(mktime(23,59,59,$month,$day,$year) - $GLOBALS['phpgw']->datetime->tz_offset,$this->bo->users_timeformat);
+				}
+				else
+				{
+					$end_time = $GLOBALS['phpgw']->common->show_date($endtime,$this->bo->users_timeformat);
+				}
+				$time = $start_time.'-'.$end_time;
+			}
+			else
+			{
+				$time = '';
+			}
+			
+			$texttitle = $texttime = $textdesc = $textlocation = $textstatus = '';
+
+			
+			
+			if(!$is_private)
+			{
+				//$text .= $this->bo->display_status($event['users_status']);
+				
+				// split text for better display by templates, also see $texttime $texttitle $textdesc $textlocation	
+				$textstatus=$this->bo->display_status($event['users_status']); 
+				
+			}
+
+			/*
+			$text = '<nobr>&nbsp;'.$time.'&nbsp;</nobr> '.$this->bo->get_short_field($event,$is_private,'title').$text.
+				(!$is_private && $event['description'] ? ': <i>'.$this->bo->get_short_field($event,$is_private,'description').'</i>':'').
+				$GLOBALS['phpgw']->browser->br;
+			*/
+			
+			$texttime=$time;
+			$texttitle=$this->bo->get_short_field($event,$is_private,'title');
+			$textdesc=(!$is_private && $event['description'] ? $this->bo->get_short_field($event,$is_private,'description'):'');
+			// added $textlocation but this must be activated in the actual pict_link.tpl file of the used template set
+			$textlocation=$this->bo->get_short_field($event,$is_private,'location');
+
+			if ($viewable)
+			{
+				$date = sprintf('%04d%02d%02d',$year,$month,$day);
+				$this->link_tpl->set_var('link_link',$this->page('view','&cal_id='.$event['id'].'&date='.$date));
+				$this->link_tpl->set_var('lang_view',lang('View this entry'));
+				$this->link_tpl->set_var('desc', $textdesc);
+				$this->link_tpl->set_var('location', $textlocation);
+				$this->link_tpl->parse('picture','link_open',True);
+			}
+			if (!$is_private)
+			{
+				if($event['priority'] == 3)
+				{
+					$picture[] = Array(
+						'pict'	=> $GLOBALS['phpgw']->common->image('calendar','high'),
+						'width'	=> 16,
+						'height'=> 16,
+						'title' => lang('high priority')
+					);
+				}
+				if($event['recur_type'] == MCAL_RECUR_NONE)
+				{
+					$picture[] = Array(
+						'pict'	=> $GLOBALS['phpgw']->common->image('calendar','circle'),
+						'width'	=> 9,
+						'height'=> 9,
+						'title' => lang('single event')
+					);
+				}
+				else
+				{
+					$picture[] = Array(
+						'pict'	=> $GLOBALS['phpgw']->common->image('calendar','recur'),
+						'width'	=> 12,
+						'height'=> 12,
+						'title' => lang('recurring event')
+					);
+				}
+			}
+			$participants = $this->planner_participants($event['participants']);
+			if(count($event['participants']) > 1)
+			{
+				$picture[] = Array(
+					'pict'	=> $GLOBALS['phpgw']->common->image('calendar','multi_3'),
+					'width'	=> 14,
+					'height'=> 14,
+					'title' => $participants
+				);
+			}
+			else
+			{
+				$picture[] = Array(
+					'pict'	=>  $GLOBALS['phpgw']->common->image('calendar','single'),
+					'width'	=> 14,
+					'height'=> 14,
+					'title' => $participants
+				);
+			}
+			if($event['public'] == 0)
+			{
+				$picture[] = Array(
+					'pict'	=> $GLOBALS['phpgw']->common->image('calendar','private'),
+					'width'	=> 13,
+					'height'=> 13,
+					'title' => lang('private')
+				);
+			}
+			if(@isset($event['alarm']) && count($event['alarm']) >= 1 && !$is_private)
+			{
+				// if the alarm is to go off the day before the event
+				// the icon does not show up because of 'alarm_today'
+				// - TOM
+				if($this->bo->alarm_today($event,$rawdate_offset,$starttime))
+				{
+					$picture[] = Array(
+						'pict'  => $GLOBALS['phpgw']->common->image('calendar','alarm'),
+						'width' => 13,
+						'height'=> 13,
+						'title' => lang('alarm')
+					);
+				}
+			}
+
+			$description = $this->bo->get_short_field($event,$is_private,'description');
+			for($i=0;$i<count($picture);$i++)
+			{
+				$var = Array(
+					'pic_image' => $picture[$i]['pict'],
+					'width'     => $picture[$i]['width'],
+					'height'    => $picture[$i]['height'],
+					'title'     => $picture[$i]['title']
+				);
+				$this->output_template_array($this->link_tpl,'picture','pict',$var);
+			}
+			if ($texttitle)
+			{
+				$var = Array(
+			//		'text' => $text,
+					'time'=> $texttime,
+					'title'=> $texttitle,
+					'users_status'=>$textstatus,
+					'desc'=> $textdesc,
+					'location'=> "<br><b>Local:</b> ".$textlocation
+				);
+				$this->output_template_array($this->link_tpl,'picture','link_text',$var);
+			}
+
+			if ($viewable)
+			{
+				$this->link_tpl->parse('picture','link_close',True);
+			}
+			$str = $this->link_tpl->fp('out','link_pict');
+			$this->link_tpl->set_var('picture','');
+			$this->link_tpl->set_var('out','');
+//			unset($p);
+			return $str;
+		}
+
+/*****************************************************************************************/
+/*Funcao foi duplicada e alterada para tratar os eventos de agendamento (exibicao do mes) para impressao;
+utiliza o template event_lik.tpl*/
+
+		function link_to_month_entry($event,$month,$day,$year)
+		{
+			$str = '';
+			$is_private = !$event['public'] && !$this->bo->check_perms(PHPGW_ACL_READ,$event);
+			$viewable = !$this->bo->printer_friendly && $this->bo->check_perms(PHPGW_ACL_READ,$event);
+
+			$starttime = $this->bo->maketime($event['start']) - $GLOBALS['phpgw']->datetime->tz_offset;
+			$endtime = $this->bo->maketime($event['end']) - $GLOBALS['phpgw']->datetime->tz_offset;
+			$rawdate = mktime(0,0,0,$month,$day,$year);
+			$rawdate_offset = $rawdate - $GLOBALS['phpgw']->datetime->tz_offset;
+			$nextday = mktime(0,0,0,$month,$day + 1,$year) - $GLOBALS['phpgw']->datetime->tz_offset;
+			if ((int)$GLOBALS['phpgw']->common->show_date($starttime,'Hi') && $starttime == $endtime)
+			{
+				$time = $GLOBALS['phpgw']->common->show_date($starttime,$this->bo->users_timeformat);
+			}
+			elseif ($starttime <= $rawdate_offset && $endtime >= $nextday - 60)
+			{
+				$time = '[ '.lang('All Day').' ]';
+			}
+			elseif ((int)$GLOBALS['phpgw']->common->show_date($starttime,'Hi') || $starttime != $endtime)
+			{
+				if($starttime < $rawdate_offset && $event['recur_type'] == MCAL_RECUR_NONE)
+				{
+					$start_time = $GLOBALS['phpgw']->common->show_date($rawdate_offset,$this->bo->users_timeformat);
+				}
+				else
+				{
+					$start_time = $GLOBALS['phpgw']->common->show_date($starttime,$this->bo->users_timeformat);
+				}
+
+				if($endtime >= ($rawdate_offset + 86400))
+				{
+					$end_time = $GLOBALS['phpgw']->common->show_date(mktime(23,59,59,$month,$day,$year) - $GLOBALS['phpgw']->datetime->tz_offset,$this->bo->users_timeformat);
+				}
+				else
+				{
+					$end_time = $GLOBALS['phpgw']->common->show_date($endtime,$this->bo->users_timeformat);
+				}
+				$time = $start_time.' - '.$end_time;
+			}
+			else
+			{
+				$time = '';
+			}
+			
+			$texttitle = $texttime = $textdesc = $textlocation = $textstatus = '';
+
+			
+			
+			if(!$is_private)
+			{
+				//$text .= $this->bo->display_status($event['users_status']);
+				
+				// split text for better display by templates, also see $texttime $texttitle $textdesc $textlocation	
+				$textstatus=$this->bo->display_status($event['users_status']); 
+				
+			}
+
+			$text = '<nobr>&nbsp;'.$time.'&nbsp;</nobr> '.$this->bo->get_short_field($event,$is_private,'title').$text.
+			
+			$texttime=$time;
+			$texttitle=$this->bo->get_short_field($event,$is_private,'title');
+			$textdesc=(!$is_private && $event['description'] ? $this->bo->get_short_field($event,$is_private,'description'):'');
+			// added $textlocation but this must be activated in the actual pict_link.tpl file of the used template set
+			$textlocation=$this->bo->get_short_field($event,$is_private,'location');
+
+			if ($viewable)
+			{
+				$date = sprintf('%04d%02d%02d',$year,$month,$day);
+				$this->event_tpl->set_var('link_link',$this->page('view','&cal_id='.$event['id'].'&date='.$date));
+				$this->event_tpl->set_var('lang_view',lang('View this entry'));
+				$this->event_tpl->set_var('desc', $textdesc);
+				$this->event_tpl->set_var('location', $textlocation);
+				$this->event_tpl->parse('picture','link_event_open',True);
+			}
+			if (!$is_private)
+			{
+				if($event['priority'] == 3)
+				{
+					$picture[] = Array(
+						'pict'	=> $GLOBALS['phpgw']->common->image('calendar','high'),
+						'width'	=> 16,
+						'height'=> 16,
+						'title' => lang('high priority')
+					);
+				}
+				if($event['recur_type'] == MCAL_RECUR_NONE)
+				{
+					$picture[] = Array(
+						'pict'	=> $GLOBALS['phpgw']->common->image('calendar','circle'),
+						'width'	=> 9,
+						'height'=> 9,
+						'title' => lang('single event')
+					);
+				}
+				else
+				{
+					$picture[] = Array(
+						'pict'	=> $GLOBALS['phpgw']->common->image('calendar','recur'),
+						'width'	=> 12,
+						'height'=> 12,
+						'title' => lang('recurring event')
+					);
+				}
+			}
+			$participants = $this->planner_participants($event['participants']);
+			if(count($event['participants']) > 1)
+			{
+				$picture[] = Array(
+					'pict'	=> $GLOBALS['phpgw']->common->image('calendar','multi_3'),
+					'width'	=> 14,
+					'height'=> 14,
+					'title' => $participants
+				);
+			}
+			else
+			{
+				$picture[] = Array(
+					'pict'	=>  $GLOBALS['phpgw']->common->image('calendar','single'),
+					'width'	=> 14,
+					'height'=> 14,
+					'title' => $participants
+				);
+			}
+			if($event['public'] == 0)
+			{
+				$picture[] = Array(
+					'pict'	=> $GLOBALS['phpgw']->common->image('calendar','private'),
+					'width'	=> 13,
+					'height'=> 13,
+					'title' => lang('private')
+				);
+			}
+			if(@isset($event['alarm']) && count($event['alarm']) >= 1 && !$is_private)
+			{
+				// if the alarm is to go off the day before the event
+				// the icon does not show up because of 'alarm_today'
+				// - TOM
+				if($this->bo->alarm_today($event,$rawdate_offset,$starttime))
+				{
+					$picture[] = Array(
+						'pict'  => $GLOBALS['phpgw']->common->image('calendar','alarm'),
+						'width' => 13,
+						'height'=> 13,
+						'title' => lang('alarm')
+					);
+				}
+			}
+
+			$description = $this->bo->get_short_field($event,$is_private,'description');
+			for($i=0;$i<count($picture);$i++)
+			{
+				$var = Array(
+					'pic_image' => $picture[$i]['pict'],
+					'width'     => $picture[$i]['width'],
+					'height'    => $picture[$i]['height'],
+					'title'     => $picture[$i]['title']
+				);
+				$this->output_template_array($this->event_tpl,'picture','event_pict',$var);
+			}
+			if ($texttitle)
+			{
+				$var = Array(
+			//		'text' => $text,
+					'time'=> $texttime,
+					'title'=> $texttitle,
+					'users_status'=>$textstatus,
+					'desc'=> $textdesc,
+					'location'=> "<br><b>Local:</b> ".$textlocation
+				);
+				$this->output_template_array($this->event_tpl,'picture','link_event_text',$var);
+			}
+
+			if ($viewable)
+			{
+				$this->event_tpl->parse('picture','link_event_close',True);
+			}
+			$str = $this->event_tpl->fp('out','link_event_pict');
+			$this->event_tpl->set_var('picture','');
+			$this->event_tpl->set_var('out','');
+//			unset($p);
+			return $str;
+		}
+
+/*****************************************************************************************/
+		function normDec($num)
+		{
+			if ($num > 9)
+				return $num;
+			else
+				return "0".$num;
+		}
+		function overlap($params)
+		{
+			if(!is_array($params))
+			{
+			}
+			else
+			{
+				$overlapping_events = $params['o_events'];
+				$event = $params['this_event'];
+			}
+
+			$month = $event['start']['month'];
+			$mday = $event['start']['mday'];
+			$year = $event['start']['year'];
+
+			$start = mktime($event['start']['hour'],$event['start']['min'],$event['start']['sec'],$month,$mday,$year) - $GLOBALS['phpgw']->datetime->tz_offset;
+			$end = $this->bo->maketime($event['end']) - $GLOBALS['phpgw']->datetime->tz_offset;
+
+			$overlap = '';
+			for($i=0;$i<count($overlapping_events);$i++)
+			{
+				$overlapped_event = $this->bo->read_entry($overlapping_events[$i],True);
+				foreach($overlapped_event['participants'] as $id => $status)
+				{
+					$conflict = isset($event['participants'][$id]);
+					$overlap .= '<li>'.($conflict?'<b>':'').
+						$GLOBALS['phpgw']->common->grab_owner_name($id).
+						($conflict?'</b> - '.lang('Scheduling conflict'):'')."</li>";
+				}
+			 if ($this->bo->prefs['calendar']['hide_event_conflict'])
+				 $overlap .= '<ul><font size="1"><span>'.
+					 $this->normDec($overlapped_event['start']['hour']).":".
+					 $this->normDec($overlapped_event['start']['min'])."-".
+					 $this->normDec($overlapped_event['end']['hour']).":".
+					 $this->normDec($overlapped_event['end']['min']).
+					 '<br><b>'.lang('title').": ".lang("Hidden").
+					 '</b><br>'.lang('description').": ".lang("Hidden").'<br></span></ul><br>';
+			 else
+				 $overlap .= '<ul>'.$this->link_to_entry($overlapped_event,$month,$mday,$year)."</ul><br>";	
+			}
+
+			unset($GLOBALS['phpgw_info']['flags']['noheader']);
+			unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+			$GLOBALS['phpgw_info']['flags']['noappheader'] = True;
+			$GLOBALS['phpgw_info']['flags']['noappfooter'] = True;
+			$GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['calendar']['title'].' - '.lang('Scheduling Conflict');
+			$GLOBALS['phpgw']->common->phpgw_header();
+
+			$p = $GLOBALS['phpgw']->template;
+			$p->set_file(
+				Array(
+					'overlap'	=> 'overlap.tpl',
+   					'form_button'	=> 'form_button_script.tpl'
+				)
+			);
+
+			$var = Array(
+				'color'		=> $this->theme['bg_text'],
+				'overlap_title' => lang('Scheduling Conflict'),
+				'overlap_text'	=> lang('Your suggested time of <B> %1 - %2 </B> conflicts with the following existing calendar entries:',$GLOBALS['phpgw']->common->show_date($start),$GLOBALS['phpgw']->common->show_date($end)),
+				'overlap_list'	=> $overlap
+			);
+			$p->set_var($var);
+
+			$date = sprintf("%04d%02d%02d",$this->bo->year,$this->bo->month,$this->bo->mday);
+			$var = Array(
+				'action_url_button'	=> $GLOBALS['phpgw']->link('/index.php',Array('menuaction'=>'calendar.bocalendar.update','readsess'=>1)),
+				'action_text_button'	=> lang('Ignore Conflict'),
+				'action_confirm_button'	=> '',
+				'action_extra_field'	=> '',
+				'button_id'		=> 'ignore_button'
+			);
+			$this->output_template_array($p,'resubmit_button','form_button',$var);
+
+			$var = Array(
+				'action_url_button'	=> $GLOBALS['phpgw']->link('/index.php',Array('menuaction'=>'calendar.uicalendar.edit','readsess'=>1,'date'=>$date)),
+				'action_text_button'	=> lang('Re-Edit Event'),
+				'action_confirm_button'	=> '',
+				'action_extra_field'	=> '',
+				'button_id'		=> 'redit_button'
+			);
+			$this->output_template_array($p,'reedit_button','form_button',$var);
+			$p->pparse('out','overlap');
+		}
+
+		function planner_participants($parts)
+		{
+			static $id2lid;
+
+			$names = '';
+			while (list($id,$status) = each($parts))
+			{
+				$status = substr($this->bo->get_long_status($status),0,1);
+
+				if (!isset($id2lid[$id]))
+				{
+					$id2lid[$id] = $GLOBALS['phpgw']->common->grab_owner_name($id);
+				}
+				if (strlen($names))
+				{
+					$names .= ",\n";
+				}
+				$names .= $id2lid[$id]." ($status)";
+			}
+			if($this->debug)
+			{
+				echo '<!-- Inside participants() : '.$names.' -->'."\n";
+			}
+			return $names;
+		}
+
+		function planner_category($ids)
+		{
+			static $cats;
+			if(!is_array($ids))
+			{
+				if (strpos($ids,','))
+				{
+					$id_array = explode(',',$ids);
+				}
+				else
+				{
+					$id_array[0] = $ids;
+				}
+			}
+			@reset($id_array);
+			$ret_val = Array();
+			while(list($index,$id) = each($id_array))
+			{
+				if (!isset($cats[$id]))
+				{
+					$cat_arr = $this->cat->return_single( $id );
+					$cats[$id] = $cat_arr[0];
+					$cats[$id]['color'] = strstr($cats[$id]['description'],'#');
+				}
+				$ret_val[] = $cats[$id];
+			}
+			return $ret_val;
+		}
+
+		function week_header($month,$year,$display_name = False)
+		{
+			$this->weekstarttime = $GLOBALS['phpgw']->datetime->get_weekday_start($year,$month,1);
+
+			$p = CreateObject('phpgwapi.Template',$this->template_dir);
+			$p->set_unknowns('remove');
+			$p->set_file(
+				Array (
+					'month_header' => 'month_header.tpl'
+				)
+			);
+			$p->set_block('month_header','monthly_header','monthly_header');
+			$p->set_block('month_header','column_title','column_title');
+
+			$var = Array(
+				'bgcolor'	=> $this->theme['th_bg'],
+				'font_color'	=> $this->theme['th_text']
+			);
+			if($this->bo->printer_friendly && @$this->bo->prefs['calendar']['print_black_white'])
+			{
+				$var = Array(
+					'bgcolor'	=> '',
+					'font_color'	=> ''
+				);
+			}
+			$p->set_var($var);
+
+			$p->set_var('col_width','14');
+			if($display_name == True)
+			{
+				$p->set_var('col_title',lang('name'));
+				$p->parse('column_header','column_title',True);
+				$p->set_var('col_width','12');
+			}
+
+			for($i=0;$i<7;$i++)
+			{
+				$p->set_var('col_title',lang($GLOBALS['phpgw']->datetime->days[$i]));
+				$p->parse('column_header','column_title',True);
+			}
+			return $p->fp('out','monthly_header');
+		}
+
+		function display_week($startdate,$weekly,$cellcolor,$display_name = False,$owner=0,$monthstart=0,$monthend=0)
+		{
+			if($owner == 0)
+			{
+				$owner = $GLOBALS['phpgw_info']['user']['account_id'];
+			}
+
+			$temp_owner = $this->bo->owner;
+
+			$str = '';
+			$p = CreateObject('phpgwapi.Template',$this->template_dir);
+			$p->set_unknowns('keep');
+
+			$p->set_file(
+				Array(
+					'month_header'	=> 'month_header.tpl',
+					'month_day'	=> 'month_day.tpl'
+				)
+			);
+			$p->set_block('month_header','monthly_header','monthly_header');
+			$p->set_block('month_header','month_column','month_column');
+			$p->set_block('month_day','month_daily','month_daily');
+			$p->set_block('month_day','day_event','day_event');
+			$p->set_block('month_day','event','event');
+
+			$p->set_var('extra','');
+			$p->set_var('col_width','14');
+			if($display_name)
+			{
+				$p->set_var('column_data',$GLOBALS['phpgw']->common->grab_owner_name($owner));
+				$p->parse('column_header','month_column',True);
+				$p->set_var('col_width','12');
+			}
+			$today = date('Ymd',$GLOBALS['phpgw']->datetime->users_localtime);
+			$daily = $this->set_week_array($startdate - $GLOBALS['phpgw']->datetime->tz_offset,$cellcolor,$weekly);
+			foreach($daily as $date => $day_params)
+			{
+				$year  = (int)substr($date,0,4);
+				$month = (int)substr($date,4,2);
+				$day   = (int)substr($date,6,2);
+				$var   = Array(
+					'column_data' => '',
+					'extra' => ''
+				);
+				$p->set_var($var);
+				if ($weekly || ($date >= $monthstart && $date <= $monthend))
+				{
+					if ($day_params['new_event'])
+					{
+						$new_event_link = ' <a href="'.$this->page('add','&date='.$date).'">'
+							. '<img src="'.$GLOBALS['phpgw']->common->image('calendar','new3').'" width="10" height="10" title="'.lang('New Entry').'" border="0" align="center">'
+							. '</a>';
+						$day_number = '<a href="'.$this->page('day','&date='.$date).'">'.$day.'</a>';
+					}
+					else
+					{
+						$new_event_link = '';
+						$day_number = $day;
+					}
+
+					$var = Array(
+						'extra'		=> $day_params['extra'],
+						'new_event_link'=> $new_event_link,
+						'day_number'	=> $day_number
+					);
+					if($day_params['week'])
+					{
+
+//NDEE: style! m_w_table in month_day.tpl
+// week-hilite
+						//$var['new_event_link'] .= '<font size="-2"> &nbsp; '.
+						$var['new_event_link'] .= ' &nbsp; '.
+							(!$this->bo->printer_friendly?'<a href="'.$this->page('week','&date='.$date).'"><span id="calendar_weekinfo" class="calendar_weekinfo">' .$day_params['week'].'</span></a>' : '<span id="calendar_weekinfo" class="calendar_weekinfo">'.$day_params['week'].'</span>');
+					}
+
+					$p->set_var($var);
+
+					if(@$day_params['holidays'])
+					{
+						foreach($day_params['holidays'] as $key => $value)
+						{
+							$var = Array(
+								'day_events' => '<font face="'.$this->theme['font'].'" size="-1">'.$value.'</font>'.$GLOBALS['phpgw']->browser->br
+							);
+							$this->output_template_array($p,'daily_events','event',$var);
+						}
+					}
+
+					if($day_params['appts'])
+					{
+						$var = Array(
+							'week_day_font_size'	=> '2',
+							'events'		=> ''
+						);
+						$p->set_var($var);
+						$events = $this->bo->cached_events[$date];
+						foreach($events as $event)
+						{
+							if ($this->bo->rejected_no_show($event))
+							{
+								continue;	// user does not want to see rejected events
+							}
+							$p->set_var('day_events',$this->link_to_entry($event,$month,$day,$year));
+							$p->parse('events','event',True);
+							$p->set_var('day_events','');
+						}
+					}
+					$p->parse('daily_events','day_event',True);
+					$p->parse('column_data','month_daily',True);
+					$p->set_var('daily_events','');
+					$p->set_var('events','');
+/*					if($day_params['week'])
+					{
+						$var = Array(
+							'week_day_font_size'	=> '-2',
+							'events'		=> (!$this->bo->printer_friendly?'<a href="'.$this->page('week','&date='.$date).'">' .$day_params['week'].'</a>':$day_params['week'])
+						);
+						$this->output_template_array($p,'column_data','day_event',$var);
+						$p->set_var('events','');
+					} */
+				}
+				$p->parse('column_header','month_column',True);
+				$p->set_var('column_data','');
+			}
+			$this->bo->owner = $temp_owner;
+			return $p->fp('out','monthly_header');
+		}
+
+/***************************************************************************************/
+/*As funcoes abaixo
+	month_week_header()
+	month_display_week()
+	display_month_print()
+	month_day_of_week() - esta foi criada mas parte do codigo e de outra funcao da API (day_of_week());
+
+  foram duplicadas e modificadas para atender aas modificacoes do layout de impressao mensal da agenda de eventos;
+  TODO: otimizar o codigo
+
+  Rommel Cysne
+*/
+
+		function month_week_header($month,$year,$display_name = False)
+		{
+			$this->weekstarttime = $GLOBALS['phpgw']->datetime->get_weekday_start($year,$month,1);
+
+		//	$p = CreateObject('phpgwapi.Template',$this->template_dir);
+			$p->set_unknowns('remove');
+		//	$p->set_file(
+		//		Array (
+		//			'month_header' => 'month_header_print.tpl'
+		//		)
+		//	);
+	//		$p->set_block('month_header','monthly_header','monthly_header');
+	//		$p->set_block('month_header','column_title','column_title');
+
+/*			$var = Array(
+				'bgcolor'	=> $this->theme['th_bg'],
+				'font_color'	=> $this->theme['th_text']
+			);
+			/*if($this->bo->printer_friendly && @$this->bo->prefs['calendar']['print_black_white'])
+			{
+				$var = Array(
+					'bgcolor'	=> '',
+					'font_color'	=> ''
+				);
+			}*/
+	/*		$p->set_var($var);
+
+			$p->set_var('col_width','14');
+		/*	if($display_name == True)
+			{
+				$p->set_var('col_title',lang('name'));
+				$p->parse('column_header','column_title',True);
+				$p->set_var('col_width','12');
+			}
+*/
+			//for($i=0;$i<7;$i++)
+			//{
+			//	$p->set_var('col_title',lang($GLOBALS['phpgw']->datetime->days[$i]));
+			//	$p->parse('column_header','column_title',True);
+			//}
+//			return $p->fp('out','monthly_header');
+		}
+
+
+		function month_day_of_week($year,$month,$day)
+		{
+			$dia = Array(
+				0 => 'Domingo',
+				1 => 'Segunda',
+				2 => 'Ter&ccedil;a',
+				3 => 'Quarta',
+				4 => 'Quinta',
+				5 => 'Sexta',
+				6 => 'S&aacute;bado'
+			);
+
+			if($month > 2)
+			{
+				$month -= 2;
+			}
+				else
+			{
+				$month += 10;
+				$year--;
+			}
+			$day = (floor((13 * $month - 1) / 5) + $day + ($year % 100) + floor(($year % 100) / 4) + floor(($year / 100) / 4) - 2 * floor($year / 100) + 77);
+
+			$month_day = ($day - 7 * floor($day / 7)); //retorna o numero do dia da semana (Ex: domingo eh dia 0, terca eh 2);
+			$weekday = $dia[$month_day]; //retorna o nome do dia da semana de acordo com seu numero;
+
+			return ($weekday);
+
+		}
+
+		function month_display_week($startdate,$weekly,$cellcolor,$display_name = False,$owner=0,$monthstart=0,$monthend=0)
+		{
+			if($owner == 0)
+			{
+				$owner = $GLOBALS['phpgw_info']['user']['account_id'];
+			}
+
+			$temp_owner = $this->bo->owner;
+
+			$str = '';
+			$p = CreateObject('phpgwapi.Template',$this->template_dir);
+			$p->set_unknowns('keep');
+
+			$p->set_file(
+				Array(
+					'month_header'	=> 'month_header_print.tpl',
+					'month_day'	=> 'month_day_print.tpl'
+				)
+			);
+			$p->set_block('month_header','monthly_header','monthly_header');
+			$p->set_block('month_header','month_column','month_column');
+			$p->set_block('month_day','month_daily','month_daily');
+			$p->set_block('month_day','day_event','day_event');
+			$p->set_block('month_day','event','event');
+
+			$p->set_var('extra','');
+			$p->set_var('col_width','14');
+		/*	if($display_name)
+			{
+				$p->set_var('column_data',$GLOBALS['phpgw']->common->grab_owner_name($owner));
+				$p->parse('column_header','month_column',True);
+				$p->set_var('col_width','12');
+			}*/
+			$today = date('Ymd',$GLOBALS['phpgw']->datetime->users_localtime);
+			$daily = $this->set_week_array($startdate - $GLOBALS['phpgw']->datetime->tz_offset,$cellcolor,$weekly);
+			foreach($daily as $date => $day_params)
+			{
+				$year  = (int)substr($date,0,4);
+				$month = (int)substr($date,4,2);
+				$day   = (int)substr($date,6,2);
+				$var   = Array(
+					'column_data' => '',
+					'extra' => ''
+				);
+				$p->set_var($var);
+				if ($weekly || ($date >= $monthstart && $date <= $monthend))
+				{
+					//if ($day_params['new_event'])
+					//{
+					//	$new_event_link = ' <a href="'.$this->page('add','&date='.$date).'">'
+					//		. '<img src="'.$GLOBALS['phpgw']->common->image('calendar','new3').'" width="10" height="10" title="'.lang('New Entry').'" border="0" align="center">'
+					//		. '</a>';
+					//	$day_number = '<a href="'.$this->page('day','&date='.$date).'">'.$day.'</a>';
+					//}
+					//else
+					//{
+						$new_event_link = '';
+						$day_num = $day;
+						$dia_semana = $this->month_day_of_week($year,$month,$day_num);
+						$day_number = $dia_semana . ",  " . $day_num;
+					//}
+
+					$var = Array(
+						'extra'		=> $day_params['extra'],
+						'new_event_link'=> $new_event_link,
+						'day_number'	=> $day_number
+					);
+	/*				if($day_params['week'])
+					{
+
+//NDEE: style! m_w_table in month_day.tpl
+// week-hilite
+						//$var['new_event_link'] .= '<font size="-2"> &nbsp; '.
+	//					$var['new_event_link'] .= ' &nbsp; '.
+	//						(!$this->bo->printer_friendly?'<a href="'.$this->page('week','&date='.$date).'"><span id="calendar_weekinfo" class="calendar_weekinfo">' .$day_params['week'].'</span></a>' : '<span id="calendar_weekinfo" class="calendar_weekinfo">'.$day_params['week'].'</span>');
+					}
+	*/
+			
+
+					$p->set_var($var);
+
+	/*				if(@$day_params['holidays'])
+					{
+						foreach($day_params['holidays'] as $key => $value)
+						{
+							$var = Array(
+								'day_events' => '<font face="'.$this->theme['font'].'" size="-1">'.$value.'</font>'.$GLOBALS['phpgw']->browser->br
+							);
+							$this->output_template_array($p,'daily_events','event',$var);
+						
+					}
+	*/
+
+					if($day_params['appts'])
+					{
+						$var = Array(
+							'week_day_font_size'	=> '2',
+							'events'		=> ''
+						);
+						$p->set_var($var);
+						$events = $this->bo->cached_events[$date];
+						//eventos
+						//print_r($events);
+						foreach($events as $event)
+						{
+							if ($this->bo->rejected_no_show($event))
+							{
+								continue;	// user does not want to see rejected events
+							}
+							$p->set_var('day_events',$this->link_to_month_entry($event,$month,$day,$year));
+							$p->parse('events','event',True);
+							$p->set_var('day_events','');
+						}
+					}
+					$p->parse('daily_events','day_event',True);
+					$p->parse('column_data','month_daily',True);
+					$p->set_var('daily_events','');
+					$p->set_var('events','');
+				}
+				$p->parse('column_header','month_column',True);
+				$p->set_var('column_data','');
+			}
+			$this->bo->owner = $temp_owner;
+			return $p->fp('out','monthly_header');
+
+		}
+
+		function display_month_print($month,$year,$showyear,$owner=0)
+		{
+			if($this->debug)
+			{
+				echo '<!-- datetime:gmtdate = '.$GLOBALS['phpgw']->datetime->cv_gmtdate.' -->'."\n";
+			}
+
+			$this->bo->store_to_cache(
+				Array(
+					'syear'	=> $year,
+					'smonth'=> $month,
+					'sday'	=> 1
+				)
+			);
+
+			$monthstart = (int)(date('Ymd',mktime(0,0,0,$month    ,1,$year)));
+			$monthend   = (int)(date('Ymd',mktime(0,0,0,$month + 1,0,$year)));
+
+			$start = $GLOBALS['phpgw']->datetime->get_weekday_start($year, $month, 1);
+
+			$p = CreateObject('phpgwapi.Template',$this->template_dir);
+			$p->set_unknowns('keep');
+
+			$p->set_file(
+				Array(
+					'week' => 'month_day_print.tpl'
+				)
+			);
+			$p->set_block('week','m_w_table','m_w_table');
+			$p->set_block('week','event','event');
+
+			$var = Array(
+				'cols'      => 1,
+				'day_events'=> '' //$this->month_week_header($month,$year,False)
+			);
+//			$this->output_template_array($p,'row','event',$var);
+
+			$cellcolor = $this->theme['row_on'];
+
+			for($i = (int)($start + $GLOBALS['phpgw']->datetime->tz_offset);(int)(date('Ymd',$i)) <= $monthend;$i += 604800)
+			{
+				$cellcolor = $GLOBALS['phpgw']->nextmatchs->alternate_row_color($cellcolor);
+				$var = Array(
+					'day_events' => $this->month_display_week($i,False,$cellcolor,False,$owner,$monthstart,$monthend)
+				);
+				$this->output_template_array($p,'row','event',$var);
+			}
+			return $p->fp('out','m_w_table');
+		}
+
+
+/***************************************************************************************/
+
+		function display_month($month,$year,$showyear,$owner=0)
+		{
+			if($this->debug)
+			{
+				echo '<!-- datetime:gmtdate = '.$GLOBALS['phpgw']->datetime->cv_gmtdate.' -->'."\n";
+			}
+
+			$this->bo->store_to_cache(
+				Array(
+					'syear'	=> $year,
+					'smonth'=> $month,
+					'sday'	=> 1
+				)
+			);
+
+			$monthstart = (int)(date('Ymd',mktime(0,0,0,$month    ,1,$year)));
+			$monthend   = (int)(date('Ymd',mktime(0,0,0,$month + 1,0,$year)));
+
+			$start = $GLOBALS['phpgw']->datetime->get_weekday_start($year, $month, 1);
+
+			if($this->debug)
+			{
+				echo '<!-- display_month:monthstart = '.$monthstart.' -->'."\n";
+				echo '<!-- display_month:start = '.date('Ymd H:i:s',$start).' -->'."\n";
+			}
+
+			$p = CreateObject('phpgwapi.Template',$this->template_dir);
+			$p->set_unknowns('keep');
+
+			$p->set_file(
+				Array(
+					'week' => 'month_day.tpl'
+				)
+			);
+			$p->set_block('week','m_w_table','m_w_table');
+			$p->set_block('week','event','event');
+
+			$var = Array(
+				'cols'      => 1,
+				'day_events'=> $this->week_header($month,$year,False)
+			);
+			$this->output_template_array($p,'row','event',$var);
+
+			$cellcolor = $this->theme['row_on'];
+
+			for($i = (int)($start + $GLOBALS['phpgw']->datetime->tz_offset);(int)(date('Ymd',$i)) <= $monthend;$i += 604800)
+			{
+				$cellcolor = $GLOBALS['phpgw']->nextmatchs->alternate_row_color($cellcolor);
+				$var = Array(
+					'day_events' => $this->display_week($i,False,$cellcolor,False,$owner,$monthstart,$monthend)
+				);
+				$this->output_template_array($p,'row','event',$var);
+			}
+			return $p->fp('out','m_w_table');
+		}
+
+		function display_weekly($params)
+		{
+			if(!is_array($params))
+			{
+				$this->index();
+			}
+
+			$year = substr($params['date'],0,4);
+			$month = substr($params['date'],4,2);
+			$day = substr($params['date'],6,2);
+			$showyear = $params['showyear'];
+			$owners = $params['owners'];
+
+			$p = CreateObject('phpgwapi.Template',$this->template_dir);
+			$p->set_unknowns('keep');
+
+			$p->set_file(
+				Array(
+					'week'	=> 'month_day.tpl'
+				)
+			);
+			$p->set_block('week','m_w_table','m_w_table');
+			$p->set_block('week','event','event');
+
+			$start = $GLOBALS['phpgw']->datetime->get_weekday_start($year, $month, $day) + $GLOBALS['phpgw']->datetime->tz_offset;
+
+			$cellcolor = $this->theme['row_off'];
+
+			$true_printer_friendly = $this->bo->printer_friendly;
+
+			if(is_array($owners))
+			{
+				$display_name = True;
+				$counter = count($owners);
+				$owners_array = $owners;
+				$cols = 8;
+			}
+			else
+			{
+				$display_name = False;
+				$counter = 1;
+				$owners_array[0] = $owners;
+				$cols = 7;
+			}
+			$var = Array(
+				'cols'         => $cols,
+				'day_events'   => $this->week_header($month,$year,$display_name)
+			);
+			$this->output_template_array($p,'row','event',$var);
+
+			$tstart = $start - $GLOBALS['phpgw']->datetime->tz_offset;
+			$tstop = $tstart + 604800;
+			$original_owner = $this->bo->so->owner;
+			for($i=0;$i<$counter;$i++)
+			{
+				$this->bo->so->owner = $owners_array[$i];
+				$this->bo->so->open_box($owners_array[$i]);
+				$this->bo->store_to_cache(
+					Array(
+						'syear'  => date('Y',$tstart),
+						'smonth' => date('m',$tstart),
+						'sday'   => date('d',$tstart),
+						'eyear'  => date('Y',$tstop),
+						'emonth' => date('m',$tstop),
+						'eday'   => date('d',$tstop)
+					)
+				);
+				$p->set_var('day_events',$this->display_week($start,True,$cellcolor,$display_name,$owners_array[$i]));
+				$p->parse('row','event',True);
+			}
+			$this->bo->so->owner = $original_owner;
+			$this->bo->printer_friendly = $true_printer_friendly;
+			return $p->fp('out','m_w_table');
+		}
+
+		function view_event($event,$alarms=False)
+		{
+			if((!$event['participants'][$this->bo->owner] && !$this->bo->check_perms(PHPGW_ACL_READ,$event)))
+			{
+				return False;
+			}
+
+			$p = &$GLOBALS['phpgw']->template;
+
+			$p->set_file(
+				Array(
+					'view'	=> 'view.tpl'
+				)
+			);
+			$p->set_block('view','view_event','view_event');
+			$p->set_block('view','list','list');
+			$p->set_block('view','hr','hr');
+
+			$vars = $this->bo->event2array($event);
+
+			$vars['title']['tr_color'] = $this->theme['th_bg'];
+
+			foreach($vars['participants']['data'] as $user => $str)
+			{
+			if ($this->bo->check_perms(PHPGW_ACL_EDIT,0,$user) && ereg('^(.*) \((.*)\)$',$str,$parts))
+				{
+					$vars['participants']['data'][$user] = $parts[1].' (<a href="'.$this->page('edit_status','&cal_id='.$event['id'].'&owner='.$user).'">'.$parts[2].'</a>)';
+				}
+			}
+			$vars['participants']['data'] = implode("<br>\n",$vars['participants']['data']);
+			foreach($vars as $var)
+			{
+				if (strlen($var['data']))
+				{
+					$this->output_template_array($p,'row','list',$var);
+				}
+			}
+
+			if($alarms && count($event['alarm']))
+			{
+				$p->set_var('th_bg',$this->theme['th_bg']);
+				$p->set_var('hr_text',lang('Alarms'));
+				$p->parse('row','hr',True);
+				foreach($event['alarm'] as $key => $alarm)
+				{
+					if (($this->bo->so->owner == $alarm['owner']) || ($this->bo->so->cal->event['owner'] == $this->bo->so->owner)) // Show only alert from user who is requesting or alert owner
+					{	
+						$icon = '<img src="'.$GLOBALS['phpgw']->common->image('calendar',($alarm['enabled']?'enabled':'disabled')).'" width="13" height="13">';
+						$var = Array(					
+							'field'	=> $icon.$GLOBALS['phpgw']->common->show_date($alarm['time']),
+							'data'	=> lang('Email Notification for %1',$GLOBALS['phpgw']->common->grab_owner_name($alarm['owner']))
+						);
+						$this->output_template_array($p,'row','list',$var);
+					}
+				}
+			}
+			return True;
+		}
+
+		function nm_on_off()
+		{
+			if($GLOBALS['phpgw']->nextmatchs->alternate_row_color() == $this->theme['row_on'])
+			{
+				return '_on';
+			}
+			return '_off';
+		}
+
+		function slot_num($time,$set_day_start=0,$set_day_end=0)
+		{
+			static $day_start, $day_end, $interval=0;
+
+			if ($set_day_start) $day_start = $set_day_start;
+			if ($set_day_end)   $day_end   = $set_day_end;
+			if (!$interval)     $interval  = 60*$this->bo->prefs['calendar']['interval'];
+
+			if ($time > $day_end)
+			{
+				$time = $day_end;
+			}
+			$slot = (int)(($time - $day_start) / $interval);
+
+			return $slot < 0 ? 0 : 1+$slot;
+		}
+
+		function print_day($params)
+		{
+			if(!is_array($params))
+			{
+				$this->index();
+			}
+
+			print_debug('in print_day()');
+
+			$this->bo->store_to_cache(
+				Array(
+					'syear'  => $params['year'],
+					'smonth' => $params['month'],
+					'sday'   => $params['day'],
+					'eyear'  => $params['year'],
+					'emonth' => $params['month'],
+					'eday'   => $params['day']
+				)
+			);
+
+			$p = CreateObject('phpgwapi.Template',$this->template_dir);
+			$p->set_unknowns('keep');
+
+			$tpl = 'day_cal.tpl';
+			if((int)($GLOBALS['phpgw_info']['user']['preferences']['calendar']['mainscreen_showevents'])==2 &&
+				$GLOBALS['phpgw_info']['flags']['currentapp'] == 'home')
+			{
+				$tpl = 'day_list.tpl';
+			}
+			$templates = Array(
+				'day_cal'   => $tpl
+			);
+
+			$p->set_file($templates);
+			$p->set_block('day_cal','day','day');
+			$p->set_block('day_cal','day_row','day_row');
+			$p->set_block('day_cal','day_event_on','day_event_on');
+			$p->set_block('day_cal','day_event_off','day_event_off');
+			$p->set_block('day_cal','day_event_holiday','day_event_holiday');
+			$p->set_block('day_cal','day_time','day_time');
+
+			$date_to_eval = sprintf("%04d%02d%02d",$params['year'],$params['month'],$params['day']);
+
+			$day_start = mktime((int)($this->bo->prefs['calendar']['workdaystarts']),0,0,$params['month'],$params['day'],$params['year']);
+			$day_end = mktime((int)($this->bo->prefs['calendar']['workdayends']),0,1,$params['month'],$params['day'],$params['year']);
+			$daily = $this->set_week_array($GLOBALS['phpgw']->datetime->get_weekday_start($params['year'],$params['month'],$params['day']),$this->theme['row_on'],True);
+			print_debug('Date to Eval',$date_to_eval);
+			$events_to_show = array();
+			if($daily[$date_to_eval]['appts'])
+			{
+				$events = $this->bo->cached_events[$date_to_eval];
+				print_debug('Date',$date_to_eval);
+				print_debug('Count',count($events));
+				foreach($events as $event)
+				{
+					if ($this->bo->rejected_no_show($event))
+					{
+						continue;	// user does not want to see rejected events
+					}
+					if ($event['recur_type'])	// calculate start- + end-datetime for recuring events
+					{
+						$this->bo->set_recur_date($event,$date_to_eval);
+					}
+					$events_to_show[] = array(
+						'starttime' => $this->bo->maketime($event['start']),
+						'endtime'   => $this->bo->maketime($event['end']),
+						'content'   => $this->link_to_entry($event,$params['month'],$params['day'],$params['year'])
+					);
+				}
+			}
+			//echo "events_to_show=<pre>"; print_r($events_to_show); echo "</pre>\n";
+			$other = $GLOBALS['phpgw']->hooks->process(array(
+				'location'  => 'calendar_include_events',
+				'year'      => $params['year'],
+				'month'     => $params['month'],
+				'day'       => $params['day'],
+				'owner'     => $this->bo->owner	// num. id of the user, not necessary current user
+			));
+
+			if (is_array($other))
+			{
+				foreach($other as $evts)
+				{
+					if (is_array($evts))
+					{
+						$events_to_show = array_merge($events_to_show,$evts);
+					}
+				}
+				usort($events_to_show,create_function('$a,$b','return $a[\'starttime\']-$b[\'starttime\'];'));
+				//echo "events_to_show=<pre>"; print_r($events_to_show); echo "</pre>\n";
+			}
+
+			if (count($events_to_show))
+			{
+				$last_slot_end = -1;
+				foreach($events_to_show as $event)
+				{
+					$slot = $this->slot_num($event['starttime'],$day_start,$day_end);
+					$slot_end = isset($event['endtime']) ? $this->slot_num($event['endtime']-1) : $slot;	// -1 to not occupy eg. the 18.00 slot for a 17-18h date
+
+					if ($slot <= $last_slot_end)
+					{
+						$slot = $last_slot;
+						$slot_end = max($last_slot_end,$slot_end);
+					}
+					$rows[$slot] .= $event['content'];
+
+					print_debug('slot',$slot);
+					print_debug('row',$rows[$slot]);
+
+					$row_span[$slot] = 1 + $slot_end - $slot;
+
+					$last_slot = $slot;
+					$last_slot_end = $slot_end;
+					print_debug('Time',$GLOBALS['phpgw']->common->show_date($this->bo->maketime($events[$i]['start']) - $GLOBALS['phpgw']->datetime->tz_offset).' - '.$GLOBALS['phpgw']->common->show_date($this->bo->maketime($events[$i]['end']) - $GLOBALS['phpgw']->datetime->tz_offset));
+					print_debug('Slot',$slot);
+				}
+				//echo "rows=<pre>"; print_r($rows); echo "<br>row_span="; print_r($row_span); echo "</pre>\n";
+			}
+			$holiday_names = $daily[$date_to_eval]['holidays'];
+			if(!$holiday_names)
+			{
+				$row_to_print = $this->nm_on_off();
+			}
+			else
+			{
+				$row_to_print = '_holiday';
+				foreach($holiday_names as $name)
+				{
+					$rows[0] = '<center>'.$name.'</center>' . $rows[0];
+				}
+			}
+			$last_slot = $this->slot_num($day_end,$day_start,$day_end);
+			$rowspan = 0;
+			for ($slot = 0; $slot <= $last_slot; ++$slot)
+			{
+				$p->set_var('extras','');
+				if ($rowspan > 1)
+				{
+					$p->set_var('event','');
+					$rowspan--;
+				}
+				elseif (!isset($rows[$slot]))
+				{
+					$p->set_var('event','&nbsp;');
+					$row_to_print = $this->nm_on_off();
+					$p->parse('event','day_event'.$row_to_print);
+				}
+				else
+				{
+					$rowspan = (int)$row_span[$slot];
+					if ($rowspan > 1)
+					{
+						$p->set_var('extras',' rowspan="'.$rowspan.'"');
+					}
+					$p->set_var('event',$rows[$slot]);
+					$row_to_print = $this->nm_on_off();
+					$p->parse('event','day_event'.$row_to_print);
+				}
+				$open_link = $close_link = '';
+				$time = '&nbsp;';
+
+				if (0 < $slot && $slot < $last_slot)	// normal time-slot not before or after day_start/end
+				{
+					$time = $day_start + ($slot-1) * 60 * $this->bo->prefs['calendar']['interval'];
+					$hour = date('H',$time);
+					$min  = date('i',$time);
+					$time = $GLOBALS['phpgw']->common->formattime($hour,$min);
+
+					if(!$this->bo->printer_friendly && $this->bo->check_perms(PHPGW_ACL_ADD))
+					{
+						$open_link = ' <a href="'.$this->page('add',"&date=$date_to_eval&hour=$hour&minute=$min").'">';
+						$close_link = '</a> ';
+					}
+				}
+				$p->set_var(Array(
+					'open_link'  => $open_link,
+					'time'       => $time,
+					'close_link' => $close_link,
+					'tr_color'   => ''	// dummy to stop output_template_array to set it
+				));
+				$p->parse('time','day_time');
+
+				$p->parse('row','day_row',True);
+			}
+			return $p->fp('out','day');
+		}	// end function
+
+		function timematrix($param)
+		{
+			if(!is_array($param))
+			{
+				$this->index();
+			}
+
+			$date = $param['date'];
+			$starttime = $param['starttime'];
+			$endtime = $param['endtime'];
+			$participants = $param['participants'];
+			foreach($participants as $part => $nul)
+			{
+				$participants[$part] = $GLOBALS['phpgw']->common->grab_owner_name($part);
+				// Much better for processor  :)
+				$participants_id[]  .= $part;
+			}
+			uasort($participants,'strnatcasecmp');	// sort them after their fullname
+
+			if(!isset($this->bo->prefs['calendar']['interval']))
+			{
+				$this->bo->prefs['calendar']['interval'] = 15;
+				$GLOBALS['phpgw']->preferences->add('calendar','interval',15);
+				$GLOBALS['phpgw']->preferences->save_repository();
+			}
+			$increment = $this->bo->prefs['calendar']['interval'];
+			$interval = (int)(60 / $increment);
+
+			$pix = $GLOBALS['phpgw']->common->image('calendar','pix');
+
+			$str = '<center>'.lang($GLOBALS['phpgw']->common->show_date($date['raw'],'l'))
+				. ', '.$this->bo->long_date($date).'<br>'
+				. '<table width="85%" border="0" cellspacing="0" cellpadding="0" cols="'.((24 * $interval) + 1).'">'
+				. '<tr><td height="1" colspan="'.((24 * $interval) + 1).'" bgcolor="black"><img src="'.$pix.'"></td></tr>'
+				. '<tr><td width="15%"><font color="'.$this->theme['bg_text'].'" face="'.$this->theme['font'].'" size="-2">'.lang('Participant').'</font></td>';
+			for($i=0;$i<24;$i++)
+			{
+				for($j=0;$j<$interval;$j++)
+				{
+					$k = ($j == 0 ? sprintf('%02d',$i).'<br>':'').sprintf('%02d',$j*$increment);
+
+					$str .= '<td align="left" bgcolor="'.$this->theme['bg_color'].'"><font color="'.$phpgw_info['theme']['bg_text'].'" face="'.$this->theme['font'].'" size="-2">'
+						. '<a href="'.$this->page('add','&date='.$date['full'].'&hour='.$i.'&minute='.($increment * $j))."\" onMouseOver=\"window.status='".$i.':'.(($increment * $j)<=9?'0':'').($increment * $j)."'; return true;\">"
+						. $k."</a>&nbsp;</font></td>\n";
+				}
+			}
+			$str .= '</tr>'
+				. '<tr><td height="1" colspan="'.((24 * $interval) + 1).'" bgcolor="black"><img src="'.$pix.'"></td></tr>';
+			if(!$endtime)
+			{
+				$endtime = $starttime;
+			}
+			$owner = $this->bo->owner;
+			foreach($participants as $part => $fullname)
+			{
+				$str .= '<tr align="center">'
+					. '<td width="15%" align="left"><font color="'.$this->theme['bg_text'].'" face="'.$this->theme['font'].'" size="-2">'.$fullname.'</font></td>';
+
+				$this->bo->cached_events = Array();
+				$this->bo->so->owner = $part;
+				$this->bo->so->open_box($part);
+				$this->bo->store_to_cache(
+					Array(
+						'syear'	=> $date['year'],
+						'smonth'=> $date['month'],
+						'sday'	=> $date['day'],
+						'eyear'	=> 0,
+						'emonth'=> 0,
+						'eday'	=> $date['day'] + 1
+					)
+				);
+
+				if(!$this->bo->cached_events[$date['full']])
+				{
+					for($j=0;$j<24;$j++)
+					{
+						for($k=0;$k<$interval;$k++)
+						{
+							$str .= '<td height="1" align="left" bgcolor="'.$this->theme['bg_color'].'" color="#999999">&nbsp;</td>';
+						}
+						$str .= "\n";
+					}
+				}
+				else
+				{
+					$time_slice = $this->bo->prepare_matrix($interval,$increment,$part,$date['full']);
+					for($h=0;$h<24;$h++)
+					{
+						$hour = $h * 10000;
+						for($m=0;$m<$interval;$m++)
+						{
+							$index = ($hour + (($m * $increment) * 100));
+							switch($time_slice[$index]['marker'])
+							{
+								case '&nbsp':
+									$time_slice[$index]['color'] = $this->theme['bg_color'];
+									$extra = '';
+									break;
+								case '-':
+									$time_slice[$index]['color'] = $this->theme['bg01'];
+									$link = $this->page('view','&cal_id='.$time_slice[$index]['id'].'&date='.$date['full']);
+									$extra =' title="'.$time_slice[$index]['description'].'" onClick="location.href=\''.$link.'\';" style="cursor:pointer; cursor:hand;"';
+									break;
+							}
+							$str .= '<td bgcolor="'.$time_slice[$index]['color'].'" color="#999999"'.$extra.'><font color="'.$this->theme['bg_text'].'" face="'.$this->theme['font'].'" size="-2">'.$time_slice[$index]['marker'].'</font></td>';
+						}
+						$str .= "\n";
+					}
+				}
+				$str .= '</tr>'
+					. '<tr><td height="1" colspan="'.((24 * $interval) + 1).'" bgcolor="#999999"><img src="'.$pix.'"></td></tr>';
+			}
+			$this->bo->owner = $owner;
+			$this->bo->so->owner = $owner;
+			$this->bo->so->open_box($owner);
+			return $str.'</table></center>'."\n";
+		}
+
+		function get_response($cal_id)
+		{
+			$p = &$GLOBALS['phpgw']->template;
+			$p->set_file(
+				Array(
+  					'form_button'	=> 'form_button_script.tpl'
+				)
+			);
+
+			$ev = $this->bo->get_cached_event();
+			$response_choices = Array(
+				ACCEPTED	=> lang('Accept'),
+				REJECTED	=> lang('Reject'),
+				TENTATIVE	=> lang('Tentative')				
+			);
+			$str = '';
+			while(list($param,$text) = each($response_choices))
+			{
+				$var = Array(
+					'action_url_button'	=> $this->page('set_action','&cal_id='.$cal_id.'&action='.$param),
+					'action_text_button'	=> '  '.$text.'  ',
+					'action_confirm_button'	=> '',
+					'action_extra_field'	=> ''
+				);
+				$p->set_var($var);
+				$str .= '<td>'.$p->fp('out','form_button').'</td>'."\n";
+			}
+			if ($this->bo->return_to)
+			{
+				$var = Array(
+					'action_url_button'	=> $GLOBALS['phpgw']->link('/index.php','menuaction='.$this->bo->return_to),
+					'action_text_button'	=> lang('cancel'),
+					'action_confirm_button'	=> '',
+					'action_extra_field'	=> ''
+				);
+				$p->set_var($var);
+				$str .= '<td>'.$p->fp('out','form_button').'</td>'."\n";
+			}
+			$str = '<td><b>'.$GLOBALS['phpgw']->common->grab_owner_name($this->bo->owner).":</b></td>\n".$str;
+
+			return '<table width="100%"><tr align="center">'."\n".$str.'</tr></table>'."\n";
+		}
+
+		function accounts_popup()
+		{
+			$GLOBALS['phpgw']->accounts->accounts_popup('calendar');
+			
+		}
+
+		function edit_form($param)
+		{
+			if(!is_array($param))
+			{
+				$this->index();
+			}
+			
+			if(isset($param['event']))
+			{
+				$event = $param['event'];
+			}
+			
+			$hourformat = substr($this->bo->users_timeformat,0,1);
+			
+			// $sb = CreateObject('phpgwapi.sbox');
+			$sb = CreateObject('phpgwapi.sbox2');
+			$jscal = CreateObject('phpgwapi.jscalendar');	// before phpgw_header() !!!
+			
+			unset($GLOBALS['phpgw_info']['flags']['noheader']);
+			unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
+			$GLOBALS['phpgw_info']['flags']['noappheader'] = True;
+			$GLOBALS['phpgw_info']['flags']['noappfooter'] = True;
+			$GLOBALS['phpgw_info']['flags']['app_header'] = $event['id'] ? lang('Editing event') : lang('Adding event');
+			if ($param['plain'] != "True"){
+				$GLOBALS['phpgw']->common->phpgw_header();
+			}
+			else{
+				$GLOBALS['phpgw_info']['theme']['row_on'] = "F8F8F8";
+				$GLOBALS['phpgw_info']['theme']['row_off'] = "F8F8F8";
+			}
+
+			$p = &$GLOBALS['phpgw']->template;
+			$p->set_file(
+				Array(
+					'edit'		=> 'edit.tpl',
+					'form_button'	=> 'form_button_script.tpl'
+				)
+			);
+			$p->set_block('edit','edit_entry','edit_entry');
+			$p->set_block('edit','list','list');
+			$p->set_block('edit','hr','hr');
+			
+			$vars = Array(
+				'font'			=> $this->theme['font'],
+				'bg_color'		=> $this->theme['bg_text'],
+				'action_url'		=> $GLOBALS['phpgw']->link('/index.php',Array('menuaction'=>'calendar.bocalendar.update')),
+				'accounts_link'		=> $GLOBALS['phpgw']->link('/index.php','menuaction=calendar.uicalendar.accounts_popup'),
+				'common_hidden'	=> '<input type="hidden" name="cal[id]" value="'.$event['id'].'">'."\n"
+					. '<input type="hidden" name="cal[owner]" value="'.$event['owner'].'">'."\n"
+					. '<input type="hidden" name="cal[uid]" value="'.$event['uid'].'">'."\n"
+					. ($_GET['cal_id'] && $event['id'] == 0?'<input type="hidden" name="cal[reference]" value="'.$_GET['cal_id'].'">'."\n":
+					(@isset($event['reference'])?'<input type="hidden" name="cal[reference]" value="'.$event['reference'].'">'."\n":''))
+					. (@isset($GLOBALS['phpgw_info']['server']['deny_user_grants_access']) && $GLOBALS['phpgw_info']['server']['deny_user_grants_access']?
+					'<input type="hidden" name="participants[]" value="'.$this->bo->owner.'">'."\n":''),
+				'errormsg'		=> ($param['cd']?$GLOBALS['phpgw']->common->check_code($param['cd']):'')
+			);
+			
+			$p->set_var($vars);
+
+// Brief Description
+			$var['title'] = Array(
+				'tr_color' => $this->theme['th_bg'],
+				'field'	=> lang('Title'),
+				'data'	=> '<input name="cal[title]" size="45" maxlength="80" value="'.$event['title'].'">'
+			);
+
+// Full Description
+			$var['description'] = Array(
+				'field'	=> lang('Full Description'),
+				'data'	=> '<textarea name="cal[description]" rows="5" cols="40" wrap="virtual" maxlength="2048">'.$event['description'].'</textarea>'
+			);
+
+// Display Categories
+			if(strpos($event['category'],','))
+			{
+				$temp_cats = explode(',',$event['category']);
+				@reset($temp_cats);
+				while(list($key,$value) = each($temp_cats))
+				{
+					$check_cats[] = (int)$value;
+				}
+			}
+			elseif($event['category'])
+			{
+				$check_cats[] = (int)$event['category'];
+			}
+			else
+			{
+				$check_cats[] = 0;
+			}
+			$var['category'] = Array(
+				'field'	=> lang('Category'),
+				'data'	=> '<select name="categories[]" onchange="javascript:updateTitleField(this)" multiple size="5">'.$this->cat->formated_list('select','all',$check_cats,True).'</select>'
+			);
+
+// Location
+			$var['location'] = Array(
+				'field'	=> lang('Location'),
+				'data'	=> '<input name="cal[location]" size="45" maxlength="255" value="'.$event['location'].'">'
+			);
+
+// Date
+
+			$start = $this->bo->maketime($event['start']) - $GLOBALS['phpgw']->datetime->tz_offset;
+			$var['startdate'] = Array(
+				'field'	=> lang('Start Date'),
+/*
+				'data'	=> $GLOBALS['phpgw']->common->dateformatorder(
+				   $sb->getYears('start[year]',(int)$GLOBALS['phpgw']->common->show_date($start,'Y')),
+				   $sb->getMonthText('start[month]',(int)$GLOBALS['phpgw']->common->show_date($start,'n')),
+				   $sb->getDays('start[mday]',(int)$GLOBALS['phpgw']->common->show_date($start,'d'))
+				)
+*/
+				'data' => $jscal->input('start[str]',$start)
+			);
+
+// Time
+			if ($this->bo->prefs['common']['timeformat'] == '12')
+			{
+				$str .= '<input type="radio" name="start[ampm]" value="am"'.($event['start']['hour'] >= 12?'':' checked').'>am'."\n"
+					. '<input type="radio" name="start[ampm]" value="pm"'.($event['start']['hour'] >= 12?' checked':'').'>pm'."\n";
+			}
+			$var['starttime'] = Array(
+				'field'	=> lang('Start Time'),
+				'data'	=> '<input name="start[hour]" size="2" VALUE="'.$GLOBALS['phpgw']->common->show_date($start,$hourformat).'" maxlength="2">:<input name="start[min]" size="2" value="'.$GLOBALS['phpgw']->common->show_date($start,'i').'" maxlength="2">'."\n".$str
+			);
+
+// End Date
+			$end = $this->bo->maketime($event['end']) - $GLOBALS['phpgw']->datetime->tz_offset;
+			$var['enddate'] = Array(
+				'field'	=> lang('End Date'),
+/*
+				'data'	=> $GLOBALS['phpgw']->common->dateformatorder(
+				   $sb->getYears('end[year]',(int)$GLOBALS['phpgw']->common->show_date($end,'Y')),
+				   $sb->getMonthText('end[month]',(int)$GLOBALS['phpgw']->common->show_date($end,'n')),
+				   $sb->getDays('end[mday]',(int)$GLOBALS['phpgw']->common->show_date($end,'d'))
+				)
+*/
+				'data' => $jscal->input('end[str]',$end)
+			);
+
+// End Time
+			if ($this->bo->prefs['common']['timeformat'] == '12')
+			{
+				$str = '<input type="radio" name="end[ampm]" value="am"'.($event['end']['hour'] >= 12?'':' checked').'>am'."\n"
+					. '<input type="radio" name="end[ampm]" value="pm"'.($event['end']['hour'] >= 12?' checked':'').'>pm'."\n";
+			}
+			$var['endtime'] = Array(
+				'field'	=> lang('End Time'),
+				'data'	=> '<input name="end[hour]" size="2" VALUE="'.$GLOBALS['phpgw']->common->show_date($end,$hourformat).'" maxlength="2">:<input name="end[min]" size="2" value="'.$GLOBALS['phpgw']->common->show_date($end,'i').'" maxlength="2">'."\n".$str
+			);
+
+// Priority
+			$var['priority'] = Array(
+				'field'	=> lang('Priority'),
+				'data'	=> $sb->getPriority('cal[priority]',$event['priority'])
+			);
+
+			// Access
+			$var['access'] = Array(
+				'field'	=> lang('Type'),
+				'data'	=> '<select onchange="javascript:changeViewMode(this.value);" id="cal[type]" name="cal[type]" '.($event['type'] == 'H'?'DISABLED':'').'><option value="normal">'.lang('Normal').'</option><option value="private" '.(!$event['public']?'SELECTED':'').' >'. lang('Private').'</option><option value="hourAppointment" '.($event['type'] == 'H'?'SELECTED':'').' >'.lang('Hours Appointment').'</option></select>'
+			); //event['public']
+
+// Participants
+			if(!isset($GLOBALS['phpgw_info']['server']['deny_user_grants_access']) || !$GLOBALS['phpgw_info']['server']['deny_user_grants_access'])
+			{
+				switch($GLOBALS['phpgw_info']['user']['preferences']['common']['account_selection'])
+				{
+					case 'popup':
+						while (is_array($event['participants']) && list($id) = each($event['participants']))
+						{
+							if($id != (int)$event['owner'])
+							{
+								$str .= '<option value="' . $id.$event['participants'][$id] . '"'.($event['participants'][$id]?' selected':'').'>('.$GLOBALS['phpgw']->accounts->get_type($id)
+										.') ' . $GLOBALS['phpgw']->common->grab_owner_name($id) . '</option>' . "\n";
+							}
+						}
+						$var['participants'] = array
+						(
+							'field'	=> '<input type="button" value="' . lang('Participants') . '" onClick="accounts_popup();">' . "\n"
+									. '<input type="hidden" name="accountid" value="' . $accountid . '">',
+							'data'	=> "\n".'   <select name="participants[]" multiple size="7">' . "\n" . $str . '</select>'
+						);
+						break;
+					default:
+						foreach($event['participants'] as $id => $participant)
+						{
+							if (($id != $event['owner']) && ($id != ""))
+							{
+								$GLOBALS['phpgw']->accounts->get_account_name($id, $lid, $fname, $lname);
+								$cn = $fname.' '.$lname;							
+								$option = '    <option  value="' . $id.$participant . '">'.$cn.'</option>'."\n";
+								$str .= $option;
+							} 								
+						}
+						$str = utf8_decode($str);
+						$footer_ext_participantes =	'<br>&nbsp;&nbsp;'.lang("The email addresses must be separated by ','");						
+						
+						$var['participants'] = array
+						(
+							'field'	=> lang('Participants'),							
+							'data'	=> "
+									<table width='100%' border='0'>
+										<tr>
+											<td width='30%'>										
+												<center>Participantes</center>												
+											</td>
+											<td width='8%' >&nbsp;</td>
+											<td width='40%'>&nbsp;</td>
+										</tr>																		
+										<tr>		
+											<td width='30%'>											
+												<center><select id='user_list' name='participants[]' style='width: 220px' multiple size='7'>".$str."</select></center>										
+											</td>				
+											<td width='8%'>
+											<center>
+												<table width='100%' border='0'>									
+													<tr height='5'><td>&nbsp;</td></tr>									
+													<tr><td align='center'>									
+														<button type='button' onClick='javascript:openListUsers(340,533, "
+														.$event['owner'].
+														")'><img src='calendar/templates/celepar/images/add.png' style='vertical-align: middle;' >&nbsp;Adicionar</button>
+														</td>
+													</tr>							
+													<tr height='5'><td>&nbsp;</td></tr>
+													<tr><td  align='center'>
+															<button type='button' onClick='javascript:rem()'><img src='calendar/templates/celepar/images/rem.png' style='vertical-align: middle;' >&nbsp;Remover</button>
+														</td>
+													</tr>
+												</table>
+											</center>
+											</td>
+											<td width='40%'>&nbsp;</td>
+										</tr>
+										</table>
+									<script src='calendar/templates/celepar/js/edit.js' type='text/javascript'></script>				
+									"
+						);
+						// if ExpressoMail 1.2 has been installed and enabled, show the plugin using AJAX. 
+						if($GLOBALS['phpgw_info']['server']['cal_expressoMail']) {							
+							$module_name = 'expressoMail'.(str_replace("1.","1_",$GLOBALS['phpgw_info']['server']['cal_expressoMail']));
+
+							if($GLOBALS['phpgw_info']['user']['apps'][$module_name]){								
+								$ldap_manager = CreateObject('contactcenter.bo_ldap_manager');
+								$_SESSION['phpgw_info']['expressomail']['user'] = $GLOBALS['phpgw_info']['user'];
+								$_SESSION['phpgw_info']['expressomail']['user']['owner'] = $event['owner'];
+								$_SESSION['phpgw_info']['expressomail']['server'] = $GLOBALS['phpgw_info']['server'];
+								$_SESSION['phpgw_info']['expressomail']['ldap_server'] = $ldap_manager ? $ldap_manager->srcs[1] : null;
+								$context = $GLOBALS['phpgw_info']['server']['ldap_context'];
+								$user_context = array();
+								foreach(explode(",",$GLOBALS['phpgw_info']['user']['account_dn']) as $i => $dn_part){
+									if($i)
+										$user_context[] = $dn_part;
+								}
+								// Prepara o contexto do usuario com sua OU raiz, pois ele pode pertencer a uma OU de nivel N.
+								$user_ou = explode(",",str_replace($context,"",implode(",",$user_context)));								
+								$user_context = trim(strtolower($user_ou[count($user_ou) - 2].",".$context));
+								// Fim		
+								// Verifica o tipo da visualização da árvore LDAP, configurado no admin da Agenda
+								$recursive = $GLOBALS['phpgw_info']['server']['cal_type_tree_participants'] == '1' ? true : false;
+								$combo_org = $this->get_organizations(trim(strtolower($context)),$user_context, $recursive);
+								$footer_ext_participantes = lang("Tip: To search in the <b>Global Catalog</b>, type the <b>F9</b> key, like the ExpressoMail.");
+								// Begin load array lang
+								ob_start();
+        						@include($module_name.'/inc/load_lang.php');
+        						$load_lang_vars = ob_get_contents();
+        						ob_end_clean();
+								// End load array_lang
+								
+								$var['participants'] = array
+								(
+									'field'	=> lang('Participants'),							
+									'data'	=> '<input type="hidden" id="txt_loading" value="'.lang("Loading").'">' .
+											'<input type="hidden" id="txt_searching" value="'.lang("Searching").'">' .
+											'<input type="hidden" id="txt_users" value="'.lang("Users").'">' .							
+											'<input type="hidden" id="txt_groups" value="'.lang("Groups").'">' .
+											'<table width="100%" border="0">'.
+											'<tr>'.
+											'<td width="25%"><br>'.	
+											'<button type="button" onClick="javascript:add_user();"><img src="calendar/templates/celepar/images/add.png" style="vertical-align: middle;" >&nbsp;'.lang("Add").'</button>'.
+											'&nbsp;&nbsp;<button type="button" onClick="javascript:remove_user();"><img src="calendar/templates/celepar/images/rem.png" style="vertical-align: middle;" >&nbsp;'.lang("Remove").'</button>'.
+											'<br><br>&nbsp;&nbsp;<b>'.lang("Event's participants").'</b><br>'.
+											'	<select id="user_list" name="participants[]" style="width: 300px" multiple size="13">'.$str.'</select>'.
+											'</td>'.
+											'<td width="30px" valign="middle" align="center">&nbsp;'.
+											'</td>'.
+											'<td valign="bottom">'.
+											'	'.lang("Organization").': '.
+											'	<select name="org_context" id="combo_org" onchange="javascript:get_available_users(\''.$module_name.'\',this.value,\''.($recursive ? "" : "search").'\');">'.$combo_org.'</select>'.
+											'	<br>'.
+											'	<font color="red"><span id="cal_span_searching">&nbsp;</span></font>'.									
+											'	<br>'.lang("Search for").':'.
+											'	<input value="" id="cal_input_searchUser" size="35" autocomplete="off" onkeyup="javascript:optionFinderTimeout(this)"><br>'.
+											'	<b>'.lang("Available users and groups").'</b><br>'.
+											'	<select id="user_list_in" style="width: 300px" multiple size="13"></select>'.
+											'</td>'.
+											'</tr>'.
+											'</table>'.
+											'<script type="text/javascript" src="phpgwapi/js/wz_dragdrop/wz_dragdrop.js"></script>'.
+											'<script type="text/javascript" src="phpgwapi/js/dJSWin/dJSWin.js"></script>'.		
+											"<script src='calendar/templates/celepar/js/edit_exmail.js' type='text/javascript'></script>" .
+											$load_lang_vars.																			
+											"<script src='".$module_name."/js/connector.js' type='text/javascript'></script>".
+											"<script type='text/javascript'>var DEFAULT_URL = '".$module_name."/controller.php?action=';</script> ".											
+											"<script type='text/javascript'>" .
+											"var timeout_get_available_users = setTimeout('get_available_users(\"".$module_name."\",\'".$user_context."\',\'".($recursive ? "" : "search")."\')',1000);". 
+											"</script> "
+								);
+							}						
+						}						
+						
+						$var['participants']['data'] .= '<a id="a_ext_participants" title="'.lang("It types below the email addresses, if you want to invite other people out" .
+							" of this system").'" name="a_ext_participants" onClick="javascript:showExParticipants(this,\''.$module_name.'\')" href="#a_ext_participants"><b>'.lang("Inform").' '.lang("external participants").'</b>&nbsp;<img align="top" ' .
+							'src="calendar/templates/celepar/images/sent.gif"></a><table id="tbl_ext_participants" width="100%" border="0" style="display:none">'.
+							'<tr>'.
+							'<td>'.	
+							'&nbsp;&nbsp;<b>'.lang("external participants").'</b>&nbsp;<img align="top" src="calendar/templates/celepar/images/sent.gif">' .
+							'&nbsp;&nbsp;<a title="'.lang("Close").'" name="b_ext_participants" onClick="javascript:hideExParticipants(this,\''.$module_name.'\')" href="#a_ext_participants">['.lang("Close").']</a>&nbsp;'.														
+							'</td>'.
+							'</tr>'.
+							'<tr>'.
+							'<td>'.	
+							'&nbsp;&nbsp;>> '.lang("It types below the email addresses, if you want to invite other people out of this system").':'.
+							'&nbsp;&nbsp;<br><textarea name="ex_participants" id="ex_participants" cols="70" rows="2">'.$event['ex_participants'].'</textarea><br>&nbsp;&nbsp;'.
+							$footer_ext_participantes.
+							'</tr>'.							
+							'</table>';
+						break;
+						
+				}
+				if((($event['id'] > 0) && isset($event['participants'][$event['owner']])) || !$event['id'])
+				{
+					$checked = ' checked';
+				}
+				else
+				{
+					$checked = '';
+				}
+				$var['owner'] = Array(
+					'field'	=> $GLOBALS['phpgw']->common->grab_owner_name($event['owner']).' '.lang('Participates'),
+					'data'	=> '<input type="checkbox" name="participants[]" value="'.$event['owner'].$event['participants'][$event['owner']].'"'.$checked.'>'
+				);
+			}
+
+// Reminder
+			// The user must use "Alarm Management" to change/modify an alarm
+			// so only display the email reminder fields if this is a new event
+			// i.e. not editing an existing event
+
+			if ($event['id'] == 0) {
+				// get defaults
+				$days = $this->bo->prefs['calendar']['default_email_days'];
+				$hours = $this->bo->prefs['calendar']['default_email_hours'];
+				$min = $this->bo->prefs['calendar']['default_email_min'];
+				if (count($event['alarm']) > 1)
+				{
+					// this should not happen because when creating a new event
+					// only 1 alarm is displayed on the screen
+					// if the user wants more than 1 alarm they should
+					// use "Alarm Management"
+					echo '<!-- how did this happen, too many alarms -->'."\n";
+				}
+				// if there was an error pick up what the user entered
+				if (@isset($event['alarm']))
+				{
+					@reset($event['alarm']);
+					// just get the first one see above!!!
+					list($key,$alarm) = @each($event['alarm']);
+					$diff  = $start - $alarm['time'];
+					$days  = (int)($diff / (24*3600));
+					$hours = (int)(($diff - ($days * 24 * 3600))/3600);
+					$min   = (int)(($diff - ($days * 24 * 3600) - ($hours * 3600))/60);
+				}
+
+				// days
+				$dout = '<select name="cal[alarmdays]">'."\n";
+				for($i=0;$i<32;$i++)
+				{
+					$dout .= '<option value="'.$i.'"'.($i==$days?' selected':'').'>'.$i.'</option>'."\n";
+				}
+				$dout .= '</select>'."\n".' '.lang('days').' ';
+				// hours
+				$hout = '<select name="cal[alarmhours]">'."\n";
+				for($i=0;$i<25;$i++)
+				{
+					$hout .= '<option value="'.$i.'"'.($i==$hours?' selected':'').'>'.$i.'</option>'."\n";
+				}
+				$hout .= '</select>'."\n".' '.lang('hours').' ';
+				// minutes
+				$mout = '<select name="cal[alarmminutes]">'."\n";
+				for($i=0;$i<61;$i++)
+				{
+					$mout .= '<option value="'.$i.'"'.($i==$min?' selected':'').'>'.$i.'</option>'."\n";
+				}
+				$mout .= '</select>'."\n".' '.lang('minutes').' ';
+
+				$var['alarm'] = Array(
+					'field' => lang('Alarm'),
+					'data'	=> $dout.$hout.$mout.lang('before the event')
+				);
+
+			}
+
+// Repeat Type
+			$str = '';
+			foreach($this->bo->rpt_type as $type => $label)
+			{
+				$str .= '<option value="'.$type.'"'.($event['recur_type']==$type?' selected':'').'>'.lang($label).'</option>';
+			}
+			$var['recure_type'] = Array(
+				'field'	=> lang('Repeat Type'),
+				'data'	=> '<select name="cal[recur_type]">'."\n".$str.'</select>'."\n"
+			);
+
+			if($event['recur_enddate']['year'] != 0 && $event['recur_enddate']['month'] != 0 && $event['recur_enddate']['mday'] != 0)
+			{
+				$checked = ' checked';
+				$recur_end = $this->bo->maketime($event['recur_enddate']) - $GLOBALS['phpgw']->datetime->tz_offset;
+			}
+			else
+			{
+				$checked = '';
+				$recur_end = $this->bo->maketime($event['start']) + 86400 - $GLOBALS['phpgw']->datetime->tz_offset;
+			}
+
+			$var['recure_enddate'] = Array(
+				'field'	=> lang('Repeat End Date'),
+				'data'	=> '<input type="checkbox" name="cal[rpt_use_end]" value="y"'.$checked.'>'.lang('Use End Date').'  '.
+/*
+					$GLOBALS['phpgw']->common->dateformatorder(
+						$sb->getYears('recur_enddate[year]',(int)$GLOBALS['phpgw']->common->show_date($recur_end,'Y')),
+						$sb->getMonthText('recur_enddate[month]',(int)$GLOBALS['phpgw']->common->show_date($recur_end,'n')),
+						$sb->getDays('recur_enddate[mday]',(int)$GLOBALS['phpgw']->common->show_date($recur_end,'d'))
+					)
+*/
+					$jscal->input('recur_enddate[str]',$recur_end)
+			);
+
+			$i = 0; $boxes = '';
+			foreach ($this->bo->rpt_day as $mask => $name)
+			{
+				$boxes .= '<input type="checkbox" name="cal[rpt_day][]" value="'.$mask.'"'.($event['recur_data'] & $mask ? ' checked' : '').'>&nbsp;'.lang($name)."\n";
+				if (++$i == 5) $boxes .= '<br>';
+			}
+			$var['recure_day'] = Array(
+				'field'	=> lang('Repeat Day').'<br>'.lang('(for weekly)'),
+				'data'	=> $boxes
+			);
+
+			$var['recure_interval'] = Array(
+				'field'	=> lang('Interval'),
+				'data'	=> '<input name="cal[recur_interval]" size="4" maxlength="4" value="'.$event['recur_interval'].'">'
+			);
+//			$this->output_template_array($p,'row','list',Array('data' => '<script src="simple_show_hide.js" type="text/javascript"></script>'));
+
+			if (!isset($this->fields))
+			{
+				$this->custom_fields = CreateObject('calendar.bocustom_fields');
+				$this->fields = &$this->custom_fields->fields;
+				$this->stock_fields = &$this->custom_fields->stock_fields;
+			}
+			$this->output_template_array($p,'row','list',$var['access']);
+			unset($var['access']);
+
+			$preserved = False;
+			foreach($this->fields as $field => $data)
+			{
+				if (!$data['disabled'])
+				{
+					if (isset($var[$field]))
+					{
+						switch($field)
+						{
+							case 'startdate':
+								$this->output_template_array($p,'row','list',$var['startdate']);
+								$this->output_template_array($p,'row','list',$var['starttime']);
+								break;
+							case 'enddate':
+								$this->output_template_array($p,'row','list',$var['enddate']);
+								$this->output_template_array($p,'row','list',$var['endtime']);
+								break;
+							case 'recure_type':
+								$p->set_var('tr_color',$this->theme['th_bg']);
+								$p->set_var('hr_text','<center name="cal[rpt_label]"><b>'.lang('Repeating Event Information').'</b></center>');
+								$p->parse('row','hr',True);
+								$this->output_template_array($p,'row','list',$var['recure_type']);
+								$this->output_template_array($p,'row','list',$var['recure_enddate']);
+								$this->output_template_array($p,'row','list',$var['recure_day']);
+								$this->output_template_array($p,'row','list',$var['recure_interval']);
+								break;
+							default:
+								$this->output_template_array($p,'row','list',$var[$field]);
+						}
+					}
+					elseif (!isset($this->stock_fields[$field]))	// Custom field
+					{
+						$lang = lang($name = substr($field,1));
+						$size = 'SIZE='.($data['shown'] ? $data['shown'] : ($data['length'] ? $data['length'] : 30)).
+							' MAXLENGTH='.($data['length'] ? $data['length'] : 255);
+						$v = array(
+							'field'	=> $lang == $name.'*' ? $name : $lang,
+							'data'	=> '<input name="cal['.htmlspecialchars($field).']" '.$size.' value="'.$event['#'.$name].'">'
+						);
+						if ($data['title'])
+						{
+							$v['tr_color'] = $this->theme['th_bg'];
+						}
+						if (!$data['length'] && $data['title'])
+						{
+							$p->set_var('tr_color',$this->theme['th_bg']);
+							$p->set_var('hr_text','<center><b>'.$v['field'].'</b></center>');
+							$p->parse('row','hr',True);
+						}
+						else
+						{
+							$this->output_template_array($p,'row','list',$v);
+						}
+					}
+				}
+				else	// preserve disabled fields
+				{
+					switch ($field)
+					{
+						case 'owner':
+							$preserved[$field] = $event['id'] ? $event['participants'][$event['owner']] : 'A';
+							break;
+						case 'recure_type':
+							foreach(array('recur_type','recur_enddate','recur_data','recur_interval') as $field)
+							{
+								$preserved[$field] = $event[$field];
+							}
+							break;
+						case 'startdate':
+						case 'enddate':
+							$field = substr($field,0,-4);
+						default:
+							$preserved[$field] = $event[$field];
+					}
+				}
+			}
+			unset($var);
+			if (is_array($preserved))
+			{
+				//echo "preserving<pre>"; print_r($preserved); echo "</pre>\n";
+				$p->set_var('common_hidden',$p->get_var('common_hidden').'<input type="hidden" name="preserved" value="'.htmlspecialchars(serialize($preserved)).'">'."\n");
+			}
+			$p->set_var('submit_button',lang('Save'));
+
+			$delete_button = $cancel_button = '';
+			if ($event['id'] > 0)
+			{
+				$var = Array(
+					'action_url_button'	=> $this->page('delete','&cal_id='.$event['id']),
+					'action_text_button'	=> lang('Delete'),
+					'action_confirm_button'	=> "onClick=\"return confirm('".lang('Are you sure want to delete this entry?\\nThis will delete this entry for all users.')."')\"",
+					'action_extra_field'	=> '',
+					'button_id'	=>	'delete_button'
+				);
+				$p->set_var($var);
+				$delete_button = $p->fp('out','form_button');
+			}
+			$p->set_var('delete_button',$delete_button);
+			$p->set_var('alert_msg',lang('Required field (category) is empty'));
+
+			if ($this->bo->return_to)
+			{
+				$var = Array(
+					'action_url_button'	=> $GLOBALS['phpgw']->link('/index.php','menuaction='.$this->bo->return_to),
+					'action_text_button'	=> lang('Cancel'),
+					'action_confirm_button'	=> '',
+					'action_extra_field'	=> '',
+					'button_id'	=>	'cancel_button'
+				);
+				$p->set_var($var);
+				$cancel_button = $p->fp('out','form_button');
+			}
+			$p->set_var('cancel_button',$cancel_button);
+			$p->pparse('out','edit_entry');
+		}
+		
+		// modify list of an event's external participants (i.e. non pgpgw users)
+		//
+		function modify_ext_partlist()
+		{
+			$GLOBALS['phpgw_info']['flags']['noheader'] = True;
+			$GLOBALS['phpgw_info']['flags']['nonavbar'] = True;
+			$GLOBALS['phpgw_info']['flags']['noappheader'] = True;
+			$GLOBALS['phpgw_info']['flags']['noappfooter'] = True;
+
+			$total_contacts = 0;
+			$participant = array();
+			$control_data= array();
+
+			$control_data['action'] = '';
+			$control_data['delete'] = array();
+			$control_data['part'] = array();
+
+			$p = CreateObject('phpgwapi.Template',$this->template_dir);
+			$p->set_file(
+				Array(
+					'T_edit_partlist' => 'edit_partlist.tpl',
+					'T_edit_partlist_blocks' => 'edit_partlist_blocks.tpl'
+				)
+			);
+
+			$p->set_block('T_edit_partlist_blocks','B_alert_msg','V_alert_msg');
+			$p->set_block('T_edit_partlist_blocks','B_partlist','V_partlist');
+			$p->set_block('T_edit_partlist_blocks','B_participants_none','V_participants_none');
+			$p->set_block('T_edit_partlist_blocks','B_delete_btn','V_delete_btn');
+
+			global $query_addr;
+			$sb = CreateObject('phpgwapi.sbox2');
+			$addy = $sb->getAddress('addr','',$query_addr);
+
+			$add_ext  = $addy['doSearchFkt'];
+			$add_ext .= $addy['addr_title']!=lang('Address Book')?$addy['addr_title']:'';
+			$add_ext .= "&nbsp;".$addy['addr'].$addy['addr_nojs'];
+
+			$p->set_var('text_add_name',$add_ext);
+
+			if(isset($_GET['part']) && $_GET['part'])
+			{
+				$control_data['part'] = split(",", $_GET['part']);
+			}
+			else
+			{
+				$control_data['part'] = $_POST['participant'];
+				$control_data['action'] = $_POST['action'];
+				$control_data['delete'] = $_POST['delete'];
+			}
+
+			for ($i=0; $i<count($control_data['part']); $i++)
+			{
+				$id = $control_data['part'][$i];
+				list($contact) = $this->read_contact($id);
+
+				$participant[$id] = array();
+				$participant[$id]['name'] = $contact['n_given'].' '.$contact['n_family'];
+			}
+
+			if ($control_data['action'] == lang('Delete selected contacts'))
+			{
+				for ($i=0; $i<count($control_data['delete']); $i++)
+				{
+					$id = $control_data['delete'][$i];
+					unset($participant[$id]);
+				}
+			}
+
+			if ($control_data['action'] == lang('Add Contact'))
+			{
+				$id = $_POST['id_addr'];
+				if (isset($id) && (int)$id != 0)
+				{
+					list($contact) = $this->read_contact($id);
+					$participant[$id] = array();
+					$participant[$id]['name'] = $contact['n_given'].' '.$contact['n_family'];
+				}
+			}
+
+			// create list of currently selected contacts
+			//
+			while(list($id,$contact) = each($participant))
+			{
+				$p->set_var('hidden_delete_name','participant[]');
+				$p->set_var('hidden_delete_value',$id);
+				$p->set_var('ckbox_delete_name','delete[]');
+				$p->set_var('ckbox_delete_value',$id);
+				$p->set_var('ckbox_delete_participant',$contact['name']);
+				$p->parse('V_partlist','B_partlist',True);
+				$total_contacts++;
+			}
+
+			if ($total_contacts == 0)
+			{
+				// no contacts have been selected
+				// => clear the delete form, remove delete button and show the none block
+				//
+				$p->set_var('V_partlist','');
+				$p->set_var('V_delete_btn','');
+				$p->set_var('text_none',lang('None'));
+				$p->parse('V_participants_none','B_participants_none');
+			}
+			else
+			{
+				// at least one contact has been selected
+				// => clear the none block, fill the delete form and add delete button
+				//
+				$p->set_var('V_participants_none','');
+				$p->set_var('btn_delete_name','action');
+				$p->set_var('btn_delete_value',lang('Delete selected contacts'));
+				$p->parse('V_delete_btn','B_delete_btn');
+			}
+
+			$body_tags  = 'bgcolor="'.$GLOBALS['phpgw_info']['theme']['bg_color']
+							. '" alink="'.$GLOBALS['phpgw_info']['theme']['alink']
+							. '" link="'.$GLOBALS['phpgw_info']['theme']['link']
+							.'" vlink="'.$GLOBALS['phpgw_info']['theme']['vlink'].'"';
+
+			$form_action = $GLOBALS['phpgw']->link('/index.php', array('menuaction' => 'calendar.uicalendar.modify'));
+
+			$charset = lang('charset');
+			$p->set_var('charset',$charset);
+			$p->set_var('page_title',$GLOBALS['phpgw_flags']['currentapp']
+				. ' - ' .lang('External Participants'));
+			$p->set_var('font_family',$GLOBALS['phpgw_info']['theme']['font']);
+			$p->set_var('body_tags',$body_tags);
+			$p->set_var('form_method','POST');
+			$p->set_var('form_action',$form_action);
+			$p->set_var('text_add_contact',lang('External Participants'));
+			$p->set_var('text_contacts_selected',lang('Selected contacts (%1)',$total_contacts));
+			$p->set_var('btn_add_name','action');
+			$p->set_var('btn_add_value',lang('Add Contact'));
+			$p->set_var('btn_done_name','done');
+			$p->set_var('btn_done_value',lang('Done'));
+			$p->set_var('btn_done_js','copyback()');
+			$p->set_var('form1_name','ext_form');
+
+			$p->pfp('out','T_edit_partlist');
+		}
+
+		function read_contact($id)
+		{
+			$query_fields = Array(
+				'n_given' => 'n_given',
+				'n_family' => 'n_family',
+				'email' => 'email',
+				'email_home' => 'email_home'
+			);
+
+			/*
+			if ($this->rights & PHPGW_ACL_READ)
+			{
+				return $this->contacts->read_single_entry($id,$fields);
+			}
+			else
+			{
+				$rtrn = array(0 => array('No access' => 'No access'));
+				return $rtrn;
+			}
+			*/
+
+			$contacts = CreateObject('phpgwapi.contacts', False);
+			return $contacts->read_single_entry($id,$query_fields);
+		}
+
+		function build_part_list(&$users,$accounts,$owner)
+		{
+			if(!is_array($accounts))
+			{
+				return;
+			}
+			foreach($accounts as $id)
+			{
+				$id = (int)$id;
+				if($id == $owner)
+				{
+					continue;
+				}
+				elseif(!isset($users[$id]))
+				{
+					if($GLOBALS['phpgw']->accounts->exists($id) == True)
+					{
+						$users[$id] = Array(
+							'name'	=> $GLOBALS['phpgw']->common->grab_owner_name($id),
+							'type'	=> $GLOBALS['phpgw']->accounts->get_type($id)
+						);
+					}
+					if($GLOBALS['phpgw']->accounts->get_type($id) == 'g')
+					{
+						//$this->build_part_list($users,$GLOBALS['phpgw']->acl->get_ids_for_location($id,1,'phpgw_group'),$owner);
+					}
+				}
+			}
+			if (!function_exists('strcmp_name'))
+			{
+				function strcmp_name($arr1,$arr2)
+				{
+					if ($diff = strcmp($arr1['type'],$arr2['type']))
+					{
+						return $diff;	// groups before users
+					}
+					return strnatcasecmp($arr1['name'],$arr2['name']);
+				}
+			}
+			uasort($users,'strcmp_name');
+		}
+
+		function set_week_array($startdate,$cellcolor,$weekly)
+		{
+			$data = date("m");
+			for ($j=0,$datetime=$startdate;$j<7;$j++,$datetime += 86400)
+			{
+				$date = date('Ymd',$datetime + (60 * 60 * 2)); // +2h to be save when switching to and from dst, $datetime is alreay + TZ-Offset
+				print_debug('set_week_array : Date ',$date);
+
+				if($events = $this->bo->cached_events[$date])
+				{
+					print_debug('Date',$date);
+					print_debug('Appointments Found',count($events));
+
+					if (!$this->bo->prefs['calendar']['show_rejected'])
+					{
+						$appts = False;
+						foreach($events as $event)	// check for a not-rejected event
+						{
+							if (!$this->bo->rejected_no_show($event))
+							{
+								$appts = True;
+								break;
+							}
+						}
+					}
+					else
+					{
+						$appts = True;
+					}
+				}
+				else
+				{
+					$appts = False;
+				}
+
+				$holidays = $this->bo->cached_holidays[$date];
+				if($weekly)
+				{
+					$cellcolor = $GLOBALS['phpgw']->nextmatchs->alternate_row_color($cellcolor);
+				}
+
+				$day_image = '';
+				if($holidays)
+				{
+					$extra = ' bgcolor="'.$this->bo->holiday_color.'"';
+					$class = ($appts?'b':'').'minicalhol';
+					if ($date == $this->bo->today)
+					{
+						$day_image = ' background="'.$GLOBALS['phpgw']->common->image('calendar','mini_day_block').'"';
+					}
+				}
+				elseif ($date != $this->bo->today)
+				{
+					$extra = ' bgcolor="'.$cellcolor.'"';
+					$class = ($appts?'b':'').'minicalendar';
+				}
+				else
+				{
+					$extra = ' bgcolor="'.$GLOBALS['phpgw_info']['theme']['cal_today'].'"';
+					$class = ($appts?'b':'').'minicalendar';
+					$day_image = ' background="'.$GLOBALS['phpgw']->common->image('calendar','mini_day_block').'"';
+				}
+
+				if($this->bo->printer_friendly && @$this->bo->prefs['calendar']['print_black_white'])
+				{
+					$extra = '';
+				}
+
+				if(!$this->bo->printer_friendly && $this->bo->check_perms(PHPGW_ACL_ADD))
+				{
+					$new_event = True;
+				}
+				else
+				{
+					$new_event = False;
+				}
+				$holiday_name = Array();
+				if($holidays)
+				{
+					for($k=0;$k<count($holidays);$k++)
+					{
+						$holiday_name[] = $holidays[$k]['name'];
+					}
+				}
+				$week = '';
+				if (!$j || (!$weekly && $j && substr($date,6,2) == '01'))
+				{
+					$week = lang('week').' '.(int)((date('z',($startdate+(24*3600*4)))+7)/7);
+				}
+				$daily[$date] = Array(
+					'extra'		=> $extra,
+					'new_event'	=> $new_event,
+					'holidays'	=> $holiday_name,
+					'appts'		=> $appts,
+					'week'		=> $week,
+					'day_image'	=> $day_image,
+					'class'		=> $class
+				);
+			}
+
+			if($this->debug)
+			{
+				_debug_array($daily);
+			}
+
+			return $daily;
+		}
+		
+		function get_organizations($context, $selected='', $recursive = false)
+		{
+			$s = CreateObject('phpgwapi.sector_search_ldap');
+						
+			return ($recursive ? 
+				$s->get_organizations($context, $selected, false ,false) :
+				$s->get_sectors($selected, false, false));
+		}		
+	}
+?>
Index: /tags/calendar/0.9.3/inc/hook_home_month.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/hook_home_month.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/inc/hook_home_month.inc.php	(revision 2)
@@ -0,0 +1,27 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar                                                    *
+  * http://www.egroupware.org                                                *
+  * Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
+  *          http://www.radix.net/~cknudsen                                  *
+  * Written by Mark Peters <skeeter@phpgroupware.org>                        *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	$d1 = strtolower(substr(PHPGW_APP_INC,0,3));
+	if($d1 == 'htt' || $d1 == 'ftp' )
+	{
+		echo 'Failed attempt to break in via an old Security Hole!<br>'."\n";
+		$GLOBALS['phpgw']->common->phpgw_exit();
+	}
+	unset($d1);
+
+	$GLOBALS['extra_data'] = $GLOBALS['css']."\n".'<td>'."\n".'<table border="0" cols="3"><tr><td align="center" width="100%" valign="top">'
+		. ExecMethod('calendar.uicalendar.get_month')
+		.'</td>'."\n".'</tr>'."\n".'</table>'."\n".'</td>'."\n";
+?>
Index: /tags/calendar/0.9.3/inc/class.boholiday.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.boholiday.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/inc/class.boholiday.inc.php	(revision 2)
@@ -0,0 +1,453 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Holiday                                                     *
+  * http://www.egroupware.org                                                *
+  * Written by Mark Peters <skeeter@phpgroupware.org>                        *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	class boholiday
+	{
+		var $public_functions = Array(
+			'add'		=> True,
+			'delete_holiday'	=> True,
+			'delete_locale'	=> True,
+			'accept_holiday'	=> True,
+			
+			'read_entries'	=> True,
+			'read_entry'	=> True,
+			'add_entry'	=> True,
+			'update_entry'	=> True
+		);
+
+		var $debug = False;
+		var $base_url = '/index.php';
+
+		var $ui;
+		var $so;
+		var $owner;
+		var $year;
+
+		var $id;
+		var $total;
+		var $start;
+		var $query;
+		var $sort;
+
+		var $locales = Array();
+		var $holidays;
+		var $cached_holidays;
+
+		function boholiday()
+		{
+			$this->so = CreateObject('calendar.soholiday');
+
+			$this->start  = (int)get_var('start',array('POST','GET'));
+			$this->query  = get_var('query',array('POST','GET'));
+			$this->sort   = get_var('sort',array('POST','GET'));
+			$this->order  = get_var('order',array('POST','GET'));
+			$this->id     = get_var('id',array('POST','GET'));
+			$this->year   = get_var('year',array('POST','GET'),date('Y'));
+			$this->locale = get_var('locale',array('POST','GET'));
+			if ($this->locale)
+			{
+				$this->locales[] = $this->locale;
+			}
+
+			if($this->debug)
+			{
+				echo '<-- Locale = '.$this->locales[0].' -->'."\n";
+			}
+
+			$this->total = $this->so->holiday_total($this->locales[0],$this->query,$this->year);
+		}
+
+		/* Begin Calendar functions */
+		function read_entry($id=0)
+		{
+			if($this->debug)
+			{
+				echo "BO : Reading Holiday ID : ".$id."<br>\n";
+			}
+
+			if(!$id)
+			{
+				if(!$this->id)
+				{
+					return Array();
+				}
+				else
+				{
+					$id = $this->id;
+				}
+			}
+
+			return $this->so->read_holiday($id);
+		}
+
+		function delete_holiday($id=0)
+		{
+			if(!$id)
+			{
+				if($this->id)
+				{
+					$id = $this->id;
+				}
+			}
+
+			$this->ui = CreateObject('calendar.uiholiday');
+			if($id)
+			{
+				$this->so->delete_holiday($id);
+				$this->ui->edit_locale();
+			}
+			else
+			{
+				$this->ui->admin();
+			}
+		}
+
+		function delete_locale($locale='')
+		{
+			if(!$locale)
+			{
+				if($this->locales[0])
+				{
+					$locale = $this->locales[0];
+				}
+			}
+
+			if($locale)
+			{
+				$this->so->delete_locale($locale);
+			}
+			$this->ui = CreateObject('calendar.uiholiday');
+			$this->ui->admin();
+		}
+
+		function accept_holiday()
+		{
+			$send_back_to = str_replace('submitlocale','holiday_admin',$_SERVER['HTTP_REFERER']);
+			if(!@$this->locales[0])
+			{
+				Header('Location: '.$send_back_to);
+			}
+
+			$send_back_to = str_replace('&locale='.$this->locales[0],'',$send_back_to);
+			$file = './holidays.'.$this->locales[0];
+			if(!file_exists($file) && count($_POST['name']))
+			{
+				$c_holidays = count($_POST['name']);
+				$fp = fopen($file,'w');
+				for($i=0;$i<$c_holidays;$i++)
+				{
+					fwrite($fp,$this->locales[0]."\t".$_POST['name'][$i]."\t".$_POST['day'][$i]."\t".$_POST['month'][$i]."\t".$_POST['occurence'][$i]."\t".$_POST['dow'][$i]."\t".$_POST['observance'][$i]."\n");
+				}
+				fclose($fp);
+			}
+			Header('Location: '.$send_back_to);
+		}
+
+		function get_holiday_list($locale='', $sort='', $order='', $query='', $total='', $year=0)
+		{
+			$locale = ($locale?$locale:$this->locales[0]);
+			$sort = ($sort?$sort:$this->sort);
+			$order = ($order?$order:$this->order);
+			$query = ($query?$query:$this->query);
+			$year = ($$year?$$year:$this->year);
+			return $this->so->read_holidays($locale,$query,$order,$year);
+		}
+
+		function get_locale_list($sort='', $order='', $query='')
+		{
+			$sort = ($sort?$sort:$this->sort);
+			$order = ($order?$order:$this->order);
+			$query = ($query?$query:$this->query);
+			return $this->so->get_locale_list($sort,$order,$query);
+		}
+
+		function prepare_read_holidays($year=0,$owner=0)
+		{
+			$this->year = (isset($year) && $year > 0?$year:$GLOBALS['phpgw']->common->show_date(time() - $GLOBALS['phpgw']->datetime->tz_offset,'Y'));
+			$this->owner = ($owner?$owner:$GLOBALS['phpgw_info']['user']['account_id']);
+
+			if($this->debug)
+			{
+				echo 'Setting Year to : '.$this->year.'<br>'."\n";
+			}
+
+			if(@$GLOBALS['phpgw_info']['user']['preferences']['common']['country'])
+			{
+				$this->locales[] = $GLOBALS['phpgw_info']['user']['preferences']['common']['country'];
+			}
+			elseif(@$GLOBALS['phpgw_info']['user']['preferences']['calendar']['locale'])
+			{
+				$this->locales[] = $GLOBALS['phpgw_info']['user']['preferences']['calendar']['locale'];
+			}
+			else
+			{
+				$this->locales[] = 'US';
+			}
+
+			if($this->owner != $GLOBALS['phpgw_info']['user']['account_id'])
+			{
+				$owner_pref = CreateObject('phpgwapi.preferences',$owner);
+				$owner_prefs = $owner_pref->read_repository();
+				if(@$owner_prefs['common']['country'])
+				{
+					$this->locales[] = $owner_prefs['common']['country'];
+				}
+				elseif(@$owner_prefs['calendar']['locale'])
+				{
+					$this->locales[] = $owner_prefs['calendar']['locale'];
+				}
+				unset($owner_pref);
+			}
+
+			@reset($this->locales);
+			if($GLOBALS['phpgw_info']['server']['auto_load_holidays'] == True)
+			{
+				while(list($key,$value) = each($this->locales))
+				{
+					$this->auto_load_holidays($value);
+				}
+			}
+		}
+
+		function auto_load_holidays($locale)
+		{
+			if($this->so->holiday_total($locale) == 0)
+			{
+				@set_time_limit(0);
+
+				/* get the file that contains the calendar events for your locale */
+				/* "http://www.egroupware.org/cal/holidays.US.csv";                 */
+				$network = CreateObject('phpgwapi.network');
+				if(isset($GLOBALS['phpgw_info']['server']['holidays_url_path']) && $GLOBALS['phpgw_info']['server']['holidays_url_path'] != 'localhost')
+				{
+					$load_from = $GLOBALS['phpgw_info']['server']['holidays_url_path'];
+				}
+				else
+				{
+					$pos = strpos(' '.$GLOBALS['phpgw_info']['server']['webserver_url'],$_SERVER['HTTP_HOST']);
+					if($pos == 0)
+					{
+						switch($_SERVER['SERVER_PORT'])
+						{
+							case 80:
+								$http_protocol = 'http://';
+								break;
+							case 443:
+								$http_protocol = 'https://';
+								break;
+						}
+						$server_host = $http_protocol.$_SERVER['HTTP_HOST'].$GLOBALS['phpgw_info']['server']['webserver_url'];
+					}
+					else
+					{
+						$server_host = $GLOBALS['phpgw_info']['server']['webserver_url'];
+					}
+					$load_from = $server_host.'/calendar/egroupware.org';
+				}
+//				echo 'Loading from: '.$load_from.'/holidays.'.strtoupper($locale).'.csv'."<br>\n";
+				$lines = $network->gethttpsocketfile($load_from.'/holidays.'.strtoupper($locale).'.csv');
+				if (!$lines)
+				{
+					return false;
+				}
+				$c_lines = count($lines);
+				for($i=0;$i<$c_lines;$i++)
+				{
+//					echo 'Line #'.$i.' : '.$lines[$i]."<br>\n";
+					$holiday = explode("\t",$lines[$i]);
+					if(count($holiday) == 7)
+					{
+						$holiday['locale'] = $holiday[0];
+						$holiday['name'] = $GLOBALS['phpgw']->db->db_addslashes($holiday[1]);
+						$holiday['mday'] = (int)$holiday[2];
+						$holiday['month_num'] = (int)$holiday[3];
+						$holiday['occurence'] = (int)$holiday[4];
+						$holiday['dow'] = (int)$holiday[5];
+						$holiday['observance_rule'] = (int)$holiday[6];
+						$holiday['hol_id'] = 0;
+						$this->so->save_holiday($holiday);
+					}
+				}
+			}
+		}
+
+		function save_holiday($holiday)
+		{
+			$this->so->save_holiday($holiday);
+		}
+
+		function add()
+		{
+			if(@$_POST['submit'])
+			{
+				$holiday = $_POST['holiday'];
+
+				if(empty($holiday['mday']))
+				{
+					$holiday['mday'] = 0;
+				}
+				if(!isset($this->bo->locales[0]) || $this->bo->locales[0]=='')
+				{
+					$this->bo->locales[0] = $holiday['locale'];
+				}
+				elseif(!isset($holiday['locale']) || $holiday['locale']=='')
+				{
+					$holiday['locale'] = $this->bo->locales[0];
+				}
+				if(!isset($holiday['hol_id']))
+				{
+					$holiday['hol_id'] = $this->bo->id;
+				}
+
+				// some input validation
+
+				if (!$holiday['mday'] == !$holiday['occurence'])
+				{
+					$errors[] = lang('You need to set either a day or a occurence !!!');
+				}
+				if($holiday['year'] && $holiday['occurence'])
+				{
+					$errors[] = lang('You can only set a year or a occurence !!!');
+				}
+				else
+				{
+					$holiday['occurence'] = (int)($holiday['occurence'] ? $holiday['occurence'] : $holiday['year']);
+					unset($holiday['year']);
+				}
+
+	// Still need to put some validation in here.....
+
+				$this->ui = CreateObject('calendar.uiholiday');
+
+				if (is_array($errors))
+				{
+					$holiday['month'] = $holiday['month_num'];
+					$holiday['day']   = $holiday['mday'];
+					$this->ui->edit_holiday($errors,$holiday);
+				}
+				else
+				{
+					$this->so->save_holiday($holiday);
+					$this->ui->edit_locale($holiday['locale']);
+				}
+			}
+		}
+
+		function sort_holidays_by_date($holidays)
+		{
+			$c_holidays = count($holidays);
+			for($outer_loop=0;$outer_loop<($c_holidays - 1);$outer_loop++)
+			{
+				for($inner_loop=$outer_loop;$inner_loop<$c_holidays;$inner_loop++)
+				{
+					if($holidays[$outer_loop]['date'] > $holidays[$inner_loop]['date'])
+					{
+						$temp = $holidays[$inner_loop];
+						$holidays[$inner_loop] = $holidays[$outer_loop];
+						$holidays[$outer_loop] = $temp;
+					}
+				}
+			}
+			return $holidays;
+		}
+
+		function set_holidays_to_date($holidays)
+		{
+			$new_holidays = Array();
+			for($i=0;$i<count($holidays);$i++)
+			{
+//	echo "Setting Holidays Date : ".date('Ymd',$holidays[$i]['date'])."<br>\n";
+				$new_holidays[date('Ymd',$holidays[$i]['date'])][] = $holidays[$i];
+			}
+			return $new_holidays;
+		}
+
+		function read_holiday()
+		{
+			if(isset($this->cached_holidays))
+			{
+				return $this->cached_holidays;
+			}
+			$holidays = $this->so->read_holidays($this->locales,'','',$this->year);
+
+			if(count($holidays) == 0)
+			{
+				return $holidays;
+			}
+
+			$temp_locale = $GLOBALS['phpgw_info']['user']['preferences']['common']['country'];
+			for($i=0;$i<count($holidays);$i++)
+			{
+				$c = $i;
+				if($i == 0 || $holidays[$i]['locale'] != $holidays[$i - 1]['locale'])
+				{
+					if(is_object($holidaycalc))
+					{
+						unset($holidaycalc);
+					}
+					$GLOBALS['phpgw_info']['user']['preferences']['common']['country'] = $holidays[$i]['locale'];
+					$holidaycalc = CreateObject('calendar.holidaycalc');
+				}
+				$holidays[$i]['date'] = $holidaycalc->calculate_date($holidays[$i], $holidays, $this->year, $c);
+				if($c != $i)
+				{
+					$i = $c;
+				}
+			}
+			unset($holidaycalc);
+			$this->holidays = $this->sort_holidays_by_date($holidays);
+			$this->cached_holidays = $this->set_holidays_to_date($this->holidays);
+			$GLOBALS['phpgw_info']['user']['preferences']['common']['country'] = $temp_locale;
+			return $this->cached_holidays;
+		}
+		/* End Calendar functions */
+
+		function check_admin()
+		{
+			if(!@$GLOBALS['phpgw_info']['user']['apps']['admin'])
+			{
+				Header('Location: ' . $GLOBALS['phpgw']->link('/index.php'));
+			}
+		}
+
+		function rule_string($holiday)
+		{
+			if (!is_array($holiday))
+			{
+				return false;
+			}
+			$sbox = CreateObject('phpgwapi.sbox');
+			$month = $holiday['month'] ? lang($sbox->monthnames[$holiday['month']]) : '';
+			unset($sbox);
+
+			if (!$holiday['day'])
+			{
+				$occ = $holiday['occurence'] == 99 ? lang('last') : $holiday['occurence'].'.';
+
+				$dow_str = Array(lang('Sun'),lang('Mon'),lang('Tue'),lang('Wed'),lang('Thu'),lang('Fri'),lang('Sat'));
+				$dow = $dow_str[$holiday['dow']];
+				
+				$str = lang('%1 %2 in %3',$occ,$dow,$month);
+			}
+			else
+			{
+				$str = $GLOBALS['phpgw']->common->dateformatorder($holiday['occurence']>1900?$holiday['occurence']:'',$month,$holiday[day]);
+			}
+			if ($holiday['observance_rule'])
+			{
+				$str .= ' ('.lang('Observance Rule').')';
+			}
+			return $str;
+		}
+	}
+?>
Index: /tags/calendar/0.9.3/inc/class.socalendar.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.socalendar.inc.php	(revision 583)
+++ /tags/calendar/0.9.3/inc/class.socalendar.inc.php	(revision 583)
@@ -0,0 +1,423 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar                                                    *
+  * http://www.eGroupWare.org                                                *
+  * Maintained and further developed by RalfBecker@outdoor-training.de       *
+  * Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
+  *          http://www.radix.net/~cknudsen                                  *
+  * Originaly modified by Mark Peters <skeeter@phpgroupware.org>             *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	class socalendar
+	{
+//		var $debug = True;
+		var $debug = False;
+		var $cal;
+		var $db;
+		var $owner;
+		var $g_owner;
+		var $is_group = False;
+		var $datetime;
+		var $filter;
+		var $cat_id;
+		
+		function socalendar($param)
+		{
+			$this->db = $GLOBALS['phpgw']->db;
+			if(!is_object($GLOBALS['phpgw']->datetime))
+			{
+				$GLOBALS['phpgw']->datetime = createobject('phpgwapi.date_time');
+			}
+
+			$this->owner = (!isset($param['owner']) || $param['owner'] == 0?$GLOBALS['phpgw_info']['user']['account_id']:$param['owner']);
+			$this->filter = (isset($param['filter']) && $param['filter'] != ''?$param['filter']:$this->filter);
+			$this->cat_id = (isset($param['category']) && $param['category'] != ''?$param['category']:$this->cat_id);
+			if(isset($param['g_owner']) && is_array($param['g_owner']))
+			{
+				$this->is_group = True;
+				$this->g_owner = $param['g_owner'];
+			}
+			if($this->debug)
+			{
+				echo '<!-- SO Filter : '.$this->filter.' -->'."\n";
+				echo '<!-- SO cat_id : '.$this->cat_id.' -->'."\n";
+			}
+			$this->cal = CreateObject('calendar.socalendar_');
+			$this->open_box($this->owner);
+		}
+		
+		// It returns uidNumber and cn ( Retorna o uidNumber e o cn )
+		function search_uidNumber($mail)
+		{
+			$connection = $GLOBALS['phpgw']->common->ldapConnect();
+			$justthese = array("uidNumber","cn","mail");
+			$search = ldap_search($connection, $GLOBALS['phpgw_info']['server']['ldap_context'], "mail=" . $mail, $justthese);
+			$result = ldap_get_entries($connection, $search);
+			ldap_close($connection);
+			return $result;
+		}
+
+		function open_box($owner)
+		{
+			$this->cal->open('INBOX',(int)$owner);
+		}
+
+		function maketime($time)
+		{
+			return mktime($time['hour'],$time['min'],$time['sec'],$time['month'],$time['mday'],$time['year']);
+		}
+
+		function read_entry($id)
+		{
+			return $this->cal->fetch_event($id);
+		}
+
+		function list_events($startYear,$startMonth,$startDay,$endYear=0,$endMonth=0,$endDay=0,$owner_id=0)
+		{
+			$extra = '';
+			$extra .= (strpos($this->filter,'private')?'AND phpgw_cal.is_public=0 ':'');
+			//$extra .= ($this->cat_id?"AND phpgw_cal.category like '%".$this->cat_id."%' ":'');
+			if ($this->cat_id)
+			{
+				if (!is_object($GLOBALS['phpgw']->categories))
+				{
+					$GLOBALS['phpgw']->categories = CreateObject('phpgwapi.categories');
+				}
+				$cats = $GLOBALS['phpgw']->categories->return_all_children($this->cat_id);
+				$extra .= "AND (phpgw_cal.category".(count($cats) > 1 ? ' IN ('.implode(',',$cats).')' : '=\''.(int)$this->cat_id."'");
+				foreach($cats as $cat)
+				{
+					$extra .= " OR phpgw_cal.category LIKE '$cat,%' OR phpgw_cal.category LIKE '%,$cat,%' OR phpgw_cal.category LIKE '%,$cat'";
+				}
+				$extra .= ') ';
+			}
+			if($owner_id)
+			{
+				return $this->cal->list_events($startYear,$startMonth,$startDay,$endYear,$endMonth,$endDay,$extra,$GLOBALS['phpgw']->datetime->tz_offset,$owner_id);
+			}
+			else
+			{
+				return $this->cal->list_events($startYear,$startMonth,$startDay,$endYear,$endMonth,$endDay,$extra,$GLOBALS['phpgw']->datetime->tz_offset);
+			}
+		}
+
+		function list_repeated_events($syear,$smonth,$sday,$eyear,$emonth,$eday,$owner_id=0)
+		{
+			if(!$owner_id)
+			{
+				$owner_id = $this->is_group ? $this->g_owner : $this->owner;
+			}
+			if($GLOBALS['phpgw_info']['server']['calendar_type'] != 'sql' ||
+				!count($owner_id))	// happens with empty groups
+			{
+				return Array();
+			}
+
+			$starttime = mktime(0,0,0,$smonth,$sday,$syear) - $GLOBALS['phpgw']->datetime->tz_offset;
+			$endtime = mktime(23,59,59,$emonth,$eday,$eyear) - $GLOBALS['phpgw']->datetime->tz_offset;
+			$sql = "AND phpgw_cal.cal_type='M' AND phpgw_cal_user.cal_login IN (".
+				(is_array($owner_id) ? implode(',',$owner_id) : $owner_id).')';
+
+//			$member_groups = $GLOBALS['phpgw']->accounts->membership($this->user);
+//			@reset($member_groups);
+//			while(list($key,$group_info) = each($member_groups))
+//			{
+//				$member[] = $group_info['account_id'];
+//			}
+//			@reset($member);
+//			$sql .= ','.implode(',',$member).') ';
+//			$sql .= 'AND (phpgw_cal.datetime <= '.$starttime.') ';
+//			$sql .= 'AND (((phpgw_cal_repeats.recur_enddate >= '.$starttime.') AND (phpgw_cal_repeats.recur_enddate <= '.$endtime.')) OR (phpgw_cal_repeats.recur_enddate=0))) '
+			$sql .= ' AND (phpgw_cal_repeats.recur_enddate >= '.$starttime.' OR phpgw_cal_repeats.recur_enddate=0) '
+				. (strpos($this->filter,'private')?'AND phpgw_cal.is_public=0 ':'')
+				. ($this->cat_id?"AND phpgw_cal.category like '%".$this->cat_id."%' ":'')
+				. 'ORDER BY phpgw_cal.datetime ASC, phpgw_cal.edatetime ASC, phpgw_cal.priority ASC';
+
+			if($this->debug)
+			{
+				echo '<!-- SO list_repeated_events : SQL : '.$sql.' -->'."\n";
+			}
+
+			return $this->get_event_ids(True,$sql);
+		}
+
+		function list_events_keyword($keywords,$members='')
+		{
+			if (!$members)
+			{
+				$members[] = $this->owner;
+			}
+			$sql = 'AND (phpgw_cal_user.cal_login IN ('.implode(',',$members).')) AND '.
+				'(phpgw_cal_user.cal_login=' . (int)$this->owner . ' OR phpgw_cal.is_public=1) AND (';
+
+			$words = split(' ',$keywords);
+			foreach($words as $i => $word)
+			{
+				$sql .= $i > 0 ? ' OR ' : '';
+				$sql .= "(UPPER(phpgw_cal.title) LIKE UPPER('%".addslashes($word)."%') OR "
+						. "UPPER(phpgw_cal.description) LIKE UPPER('%".addslashes($word)."%') OR "
+						. "UPPER(phpgw_cal.location) LIKE UPPER('%".addslashes($word)."%') OR "
+						. "UPPER(phpgw_cal_extra.cal_extra_value) LIKE UPPER('%".addslashes($word)."%'))";
+			}
+			$sql .= ') ';
+
+			$sql .= (strpos($this->filter,'private')?'AND phpgw_cal.is_public=0 ':'');
+			$sql .= ($this->cat_id? "AND (phpgw_cal.category='$this->cat_id' OR phpgw_cal.category like '%,".$this->cat_id.",%') ":'');
+			$sql .= 'ORDER BY phpgw_cal.datetime DESC, phpgw_cal.edatetime DESC, phpgw_cal.priority ASC';
+
+			return $this->get_event_ids(False,$sql,True);
+		}
+
+		function read_from_store($startYear,$startMonth,$startDay,$endYear='',$endMonth='',$endDay='')
+		{
+			$events = $this->list_events($startYear,$startMonth,$startDay,$endYear,$endMonth,$endDay);
+			$events_cached = Array();
+			for($i=0;$i<count($events);$i++)
+			{
+				$events_cached[] = $this->read_entry($events[$i]);
+			}
+			return $events_cached;
+		}
+
+		function get_event_ids($search_repeats=False, $sql='',$search_extra=False)
+		{
+			return $this->cal->get_event_ids($search_repeats,$sql,$search_extra);
+		}
+
+		function find_uid($uid)
+		{
+			$sql = " AND (phpgw_cal.uid = '".$uid."') ";
+
+			$found = $this->cal->get_event_ids(False,$sql);
+			if(!$found)
+			{
+				$found = $this->cal->get_event_ids(True,$sql);
+			}
+			if(is_array($found))
+			{
+				return $found[0];
+			}
+			else
+			{
+				return False;
+			}
+		}
+
+		function add_entry(&$event)
+		{
+			return $this->cal->save_event($event);
+		}
+
+		function save_alarm($cal_id,$alarm,$id=0)
+		{
+			return $this->cal->save_alarm($cal_id,$alarm,$id);
+		}
+
+		function delete_alarm($id)
+		{
+			return $this->cal->delete_alarm($id);
+		}
+
+		function delete_alarms($cal_id)
+		{
+			return $this->cal->delete_alarms($cal_id);
+		}
+
+		function delete_entry($id)
+		{
+			return $this->cal->delete_event($id);
+		}
+
+		function expunge()
+		{
+			$this->cal->expunge();
+		}
+
+		function delete_calendar($owner)
+		{
+			$this->cal->delete_calendar($owner);
+		}
+
+		function change_owner($account_id,$new_owner)
+		{
+			if($GLOBALS['phpgw_info']['server']['calendar_type'] == 'sql')
+			{
+				$db2 = $this->cal->stream;
+				$this->cal->stream->query('SELECT cal_id FROM phpgw_cal_user WHERE cal_login='.$account_id,__LINE__,__FILE__);
+				while($this->cal->stream->next_record())
+				{
+					$id = $this->cal->stream->f('cal_id');
+					$db2->query('SELECT count(*) FROM phpgw_cal_user WHERE cal_id='.$id.' AND cal_login='.$new_owner,__LINE__,__FILE__);
+					$db2->next_record();
+					if($db2->f(0) == 0)
+					{
+						$db2->query('UPDATE phpgw_cal_user SET cal_login='.$new_owner.' WHERE cal_id='.$id.' AND cal_login='.$account_id,__LINE__,__FILE__);
+					}
+					else
+					{
+						$db2->query('DELETE FROM phpgw_cal_user WHERE cal_id='.$id.' AND cal_login='.$account_id,__LINE__,__FILE__);
+					}
+				}
+				$this->cal->stream->query('UPDATE phpgw_cal SET owner='.$new_owner.' WHERE owner='.$account_id,__LINE__,__FILE__);
+			}
+		}
+
+		function set_status($id,$status)
+		{
+			$this->cal->set_status($id,$this->owner,$status);
+		}
+
+		function get_alarm($cal_id)
+		{
+			if (!method_exists($this->cal,'get_alarm'))
+			{
+				return False;
+			}
+			return $this->cal->get_alarm($cal_id);
+		}
+
+		function read_alarm($id)
+		{
+			if (!method_exists($this->cal,'read_alarm'))
+			{
+				return False;
+			}
+			return $this->cal->read_alarm($id);
+		}
+
+		function read_alarms($cal_id)
+		{
+			if (!method_exists($this->cal,'read_alarms'))
+			{
+				return False;
+			}
+			return $this->cal->read_alarms($cal_id);
+		}
+
+		function find_recur_exceptions($event_id)
+		{
+			if($GLOBALS['phpgw_info']['server']['calendar_type'] == 'sql')
+			{
+				$arr = Array();
+				$this->cal->query('SELECT datetime FROM phpgw_cal WHERE reference='.$event_id,__LINE__,__FILE__);
+				if($this->cal->num_rows())
+				{
+					while($this->cal->next_record())
+					{
+						$arr[] = (int)$this->cal->f('datetime');
+					}
+				}
+				if(count($arr) == 0)
+				{
+					return False;
+				}
+				else
+				{
+					return $arr;
+				}
+			}
+			else
+			{
+				return False;
+			}
+		}
+
+		/* Begin mcal equiv functions */
+		function get_cached_event()
+		{
+			return $this->cal->event;
+		}
+		
+		function add_attribute($var,$value,$element='**(**')
+		{
+			$this->cal->add_attribute($var,$value,$element);
+		}
+
+		function event_init()
+		{
+			$this->cal->event_init();
+		}
+
+		function set_date($element,$year,$month,$day=0,$hour=0,$min=0,$sec=0)
+		{
+			$this->cal->set_date($element,$year,$month,$day,$hour,$min,$sec);
+		}
+
+		function set_start($year,$month,$day=0,$hour=0,$min=0,$sec=0)
+		{
+			$this->cal->set_start($year,$month,$day,$hour,$min,$sec);
+		}
+
+		function set_end($year,$month,$day=0,$hour=0,$min=0,$sec=0)
+		{
+			$this->cal->set_end($year,$month,$day,$hour,$min,$sec);
+		}
+
+		function set_title($title='')
+		{
+			$this->cal->set_title($title);
+		}
+
+		function set_description($description='')
+		{
+			$this->cal->set_description($description);
+		}
+		function set_ex_participants($ex_participants='')
+		{
+			$this->cal->set_ex_participants($ex_participants);
+		}
+
+		function set_class($class)
+		{
+			$this->cal->set_class($class);
+		}
+
+		function set_category($category='')
+		{
+			$this->cal->set_category($category);
+		}
+
+		function set_alarm($alarm)
+		{
+			$this->cal->set_alarm($alarm);
+		}
+
+		function set_recur_none()
+		{
+			$this->cal->set_recur_none();
+		}
+
+		function set_recur_daily($year,$month,$day,$interval)
+		{
+			$this->cal->set_recur_daily($year,$month,$day,$interval);
+		}
+
+		function set_recur_weekly($year,$month,$day,$interval,$weekdays)
+		{
+			$this->cal->set_recur_weekly($year,$month,$day,$interval,$weekdays);
+		}
+
+		function set_recur_monthly_mday($year,$month,$day,$interval)
+		{
+			$this->cal->set_recur_monthly_mday($year,$month,$day,$interval);
+		}
+
+		function set_recur_monthly_wday($year,$month,$day,$interval)
+		{
+			$this->cal->set_recur_monthly_wday($year,$month,$day,$interval);
+		}
+
+		function set_recur_yearly($year,$month,$day,$interval)
+		{
+			$this->cal->set_recur_yearly($year,$month,$day,$interval);
+		}
+		
+		/* End mcal equiv functions */
+	}
+?>
Index: /tags/calendar/0.9.3/inc/class.holidaycalc.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/class.holidaycalc.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/inc/class.holidaycalc.inc.php	(revision 2)
@@ -0,0 +1,33 @@
+<?php 
+  /**************************************************************************\
+  * eGroupWare - holidaycalc                                                 *
+  * http://www.egroupware.org                                                *
+  * Based on Yoshihiro Kamimura <your@itheart.com>                           *
+  *          http://www.itheart.com                                          *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	if (empty($GLOBALS['phpgw_info']['user']['preferences']['common']['country']))
+	{
+		$rule = 'US';
+	}
+	else
+	{
+		$rule = $GLOBALS['phpgw_info']['user']['preferences']['common']['country'];
+	}
+
+	$calc_include = PHPGW_INCLUDE_ROOT.'/calendar/inc/class.holidaycalc_'.$rule.'.inc.php';
+	if(@file_exists($calc_include))
+	{
+		include($calc_include);
+	}
+	else
+	{
+		include(PHPGW_INCLUDE_ROOT.'/calendar/inc/class.holidaycalc_US.inc.php');
+	}
+?>
Index: /tags/calendar/0.9.3/inc/hook_settings.inc.php
===================================================================
--- /tags/calendar/0.9.3/inc/hook_settings.inc.php	(revision 625)
+++ /tags/calendar/0.9.3/inc/hook_settings.inc.php	(revision 625)
@@ -0,0 +1,195 @@
+<?php
+	/**************************************************************************\
+	* eGroupWare - Calendar Preferences                                        *
+	* http://www.egroupware.org                                                *
+	* Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
+	*          http://www.radix.net/~cknudsen                                  *
+	* Modified by Mark Peters <skeeter@phpgroupware.org>                       *
+	* Modified by Ralf Becker <ralfbecker@outdoor-training.de>                 *
+	* --------------------------------------------                             *
+	*  This program is free software; you can redistribute it and/or modify it *
+	*  under the terms of the GNU General Public License as published by the   *
+	*  Free Software Foundation; either version 2 of the License, or (at your  *
+	*  option) any later version.                                              *
+	\**************************************************************************/
+
+
+	ExecMethod('calendar.bocalendar.check_set_default_prefs');
+
+	$default = array(
+		'day'          => lang('Daily'),
+		'week'         => lang('Weekly'),
+		'month'        => lang('Monthly'),
+		'year'         => lang('Yearly'),
+		'planner_cat'  => lang('Planner by category'),
+		'planner_user' => lang('Planner by user'),
+	);
+	create_select_box('default calendar view','defaultcalendar',$default,
+		'Which of calendar view do you want to see, when you start calendar ?');
+
+	/* Selection of list for home page is different from default calendar,
+	   since the decision for the front page is different for the decision
+	   for the main calendar page.  But the list could be added to the
+	   default list above, if requested.  - shrykedude. */
+	$mainpage = array(
+		'1' => lang('Yes'),
+		'0' => lang('No'),
+		'2' => lang('No').' - '.lang('show list of upcoming events'),
+	);
+	create_select_box('show default view on main screen','mainscreen_showevents',$mainpage,
+		'Displays your default calendar view on the startpage (page you get when you enter eGroupWare or click on the homepage icon)?');
+	unset($mainpage);
+/*
+	$summary = array(
+		'no'     => lang('Never'),
+		'daily'  => lang('Daily'),
+		'weekly' => lang('Weekly')
+	);
+	create_select_box('Receive summary of appointments','summary',$summary,
+		'Do you want to receive a regulary summary of your appointsments via email?<br>The summary is sent to your standard email-address on the morning of that day or on Monday for weekly summarys.<br>It is only sent when you have any appointments on that day or week.');
+*/
+	$updates = array(
+		'no'             => lang('Never'),
+		'add_cancel'     => lang('on invitation / cancelation only'),
+		'time_change_4h' => lang('on time change of more than 4 hours too'),
+		'time_change'    => lang('on any time change too'),
+		'modifications'  => lang('on all modification, but responses'),
+		'responses'      => lang('on participant responses too')
+	);
+	create_select_box('Receive email updates','receive_updates',$updates,
+		"Do you want to be notified about new or changed appointments? You be notified about changes you make yourself.<br>You can limit the notifications to certain changes only. Each item includes all the notification listed above it. All modifications include changes of title, description, participants, but no participant responses. If the owner of an event requested any notifcations, he will always get the participant responses like acceptions and rejections too.");
+
+	$update_formats = array(
+		'none'     => lang('None'),
+		'extended' => lang('Extended'),
+		'ical'     => lang('iCal / rfc2445')
+	);
+	create_select_box('Format of event updates','update_format',$update_formats,
+		'Extended updates always include the complete event-details. iCal\'s can be imported by certain other calendar-applications.');
+
+	$event_details = array(
+		'to-fullname' => lang('Fullname of person to notify'),
+		'to-firstname'=> lang('Firstname of person to notify'),
+		'to-lastname' => lang('Lastname of person to notify'),
+		'title'       => lang('Title of the event'),
+		'description' => lang('Description'),
+		'startdate'   => lang('Start Date/Time'),
+		'enddate'     => lang('End Date/Time'),
+		'olddate'     => lang('Old Startdate'),
+		'category'    => lang('Category'),
+		'location'    => lang('Location'),
+		'priority'    => lang('Priority'),
+		'participant'=> lang('Participants'),
+		'owner'       => lang('Owner'),
+		'repetition'  => lang('Repetitiondetails (or empty)'),
+		'action'      => lang('Action that caused the notify: Added, Canceled, Accepted, Rejected, ...'),
+		'link'        => lang('Link to view the event'),
+	);
+	create_notify('Notification messages for added events ','notifyAdded',5,50,
+		'This message is sent to every participant of events you own, who has requested notifcations about new events.<br>You can use certain variables which get substituted with the data of the event. The first line is the subject of the email.',
+		'',$event_details);
+	create_notify('Notification messages for canceled events ','notifyCanceled',5,50,
+		'This message is sent for canceled or deleted events.','',$event_details,False);
+	create_notify('Notification messages for modified events ','notifyModified',5,50,
+		'This message is sent for modified or moved events.','',$event_details,False);
+	create_notify('Notification messages for your responses ','notifyResponse',5,50,
+		'This message is sent when you accept, tentative accept or reject an event.',
+		'',$event_details,False);
+	create_notify('Notification messages for your alarms','notifyAlarm',5,50,
+		'This message is sent when you set an Alarm for a certain event. Include all information you might need.',
+		'',$event_details,False);
+
+	create_check_box('Show invitations you rejected','show_rejected',
+		'Should invitations you rejected still be shown in your calendar ?<br>You can only accept them later (eg. when your scheduling conflict is removed), if they are still shown in your calendar!');
+
+	create_check_box('Display status of events','display_status',
+		'Should the status of the event-participants (accept, reject, ...) be shown in brakets after each participants name ?');
+        create_check_box('Hide title and description of event when conflicts','hide_event_conflict',
+		                'When user invite other that time conflicts this option hide title and description even if the event is public');
+
+	$weekdaystarts = array(
+		'Monday'   => lang('Monday'),
+		'Sunday'   => lang('Sunday'),
+		'Saturday' => lang('Saturday')
+	);
+	create_select_box('weekday starts on','weekdaystarts',$weekdaystarts,
+		'This day is shown as first day in the week or month view.');
+
+	for ($i=0; $i < 24; ++$i)
+	{
+		$options[$i] = $GLOBALS['phpgw']->common->formattime($i,'00');
+	}
+	create_select_box('work day starts on','workdaystarts',$options,
+		'This defines the start of your dayview. Events before this time, are shown above the dayview.<br>This time is also used as a default starttime for new events.');
+	create_select_box('work day ends on','workdayends',$options,
+		'This defines the end of your dayview. Events after this time, are shown below the dayview.');
+	$intervals = array(
+		5	=> '5',
+		10	=> '10',
+		15	=> '15',
+		20	=> '20',
+		30	=> '30',
+		45	=> '45',
+		60	=> '60'
+	);
+	create_select_box('Intervals in day view','interval',$intervals,
+		'Defines the size in minutes of the lines in the day view.');
+	create_input_box('default appointment length (in minutes)','defaultlength',
+		'Default length of newly created events. The length is in minutes, eg. 60 for 1 hour.','',3);
+
+	$groups = $GLOBALS['phpgw']->accounts->membership($GLOBALS['phpgw_info']['user']['account_id']);
+	$options = array(-1 => lang('none'));
+	if (is_array($groups))
+	{
+		foreach($groups as $group)
+		{
+			$options[$group['account_id']] = $GLOBALS['phpgw']->common->grab_owner_name($group['account_id']);
+		}
+	}
+	create_select_box('Preselected group for entering the planner','planner_start_with_group',$options,
+		'This group that is preselected when you enter the planner. You can change it in the planner anytime you want.');
+
+	$planner_intervals = array(
+		1	=> '1',
+		2	=> '2',
+		3	=> '3',
+		4	=> '4',
+	);
+	create_select_box('Intervals per day in planner view','planner_intervals_per_day',
+		$planner_intervals,'Specifies the the number of intervals shown in the planner view.');
+
+	$defaultfilter = array(
+		'all'     => lang('all'),
+		'private' => lang('private only'),
+//		'public'  => lang('global public only'),
+//		'group'   => lang('group public only'),
+//		'private+public' => lang('private and global public'),
+//		'private+group'  => lang('private and group public'),
+//		'public+group'   => lang('global public and group public')
+	);
+	create_select_box('Default calendar filter','defaultfilter',$defaultfilter,
+		'Which events do you want to see when you enter the calendar.');
+
+	create_check_box('Set new events to private','default_private',
+		'Should new events created as private by default ?');
+
+	create_check_box('Print the mini calendars','display_minicals',
+		'Should the mini calendars by printed / displayed in the printer friendly views ?');
+
+	create_check_box('Print calendars in black & white','print_black_white',
+		'Should the printer friendly view be in black & white or in color (as in normal view)?');
+
+	$freebusy_url = $GLOBALS['phpgw_info']['server']['webserver_url'].'/calendar/freebusy.php?user='.$GLOBALS['phpgw_info']['user']['account_lid'].'&password='.$GLOBALS['phpgw_info']['user']['preferences']['calendar']['freebusy_pw'];
+	if ($freebusy_url[0] == '/')
+	{
+		$freebusy_url = ($_SERVER['HTTPS'] ? 'https://' : 'http://').$_SERVER['HTTP_HOST'].$freebusy_url;
+	}
+	$freebusy_help = lang('Should not loged in persons be able to see your freebusy information? You can set an extra password, different from your normal password, to protect this informations. The freebusy information is in iCal format and only include the times when you are busy. It does not include the event-name, description or locations. The URL to your freebusy information is %1.','<a href="'.$freebusy_url.'" target="_blank">'.$freebusy_url.'</a>');
+	create_check_box('Make freebusy information availible to not loged in persons?','freebusy',
+		$freebusy_help,'',False);
+	create_input_box('Password for not loged in users to your freebusy information?','freebusy_pw',
+		'If you dont set a password here, the information is availible to everyone, who knows the URL!!!');
+	create_check_box('Display status of events','display_status',
+		'Should the status of the event-participants (accept, reject, ...) be shown in brakets after each participants name ?');
+	create_check_box('Leave my calendar public','public_view',
+		'This option allow everybody to view your calendar in readmode.');
Index: /tags/calendar/0.9.3/freebusy.php
===================================================================
--- /tags/calendar/0.9.3/freebusy.php	(revision 2)
+++ /tags/calendar/0.9.3/freebusy.php	(revision 2)
@@ -0,0 +1,64 @@
+<?php
+	/**************************************************************************\
+	* eGroupWare - freebusy times as iCals                                     *
+	* http://www.egroupware.org                                                *
+	* Written by RalfBecker@outdoor-training.de                                *
+	* --------------------------------------------                             *
+	*  This program is free software; you can redistribute it and/or modify it *
+	*  under the terms of the GNU General Public License as published by the   *
+	*  Free Software Foundation; either version 2 of the License, or (at your  *
+	*  option) any later version.                                              *
+	\**************************************************************************/
+
+
+	$GLOBALS['phpgw_info'] = array(
+		'flags' => array(
+			'currentapp' => 'calendar',
+			'noheader'   => True,
+			'nofooter'   => True,
+		),
+	);
+	// check if we are loged in, by checking sessionid and kp3, as the sessionid get set automaticaly by php for php4-sessions
+	$sessionid = isset($_COOKIE['sessionid']) ? $_COOKIE['sessionid'] : @$_GET['sessionid'];
+	$kp3 = isset($_COOKIE['kp3']) ? $_COOKIE['kp3'] : @$_GET['kp3'];
+
+	if (!($loged_in = $sessionid && $kp3))
+	{
+		$GLOBALS['phpgw_info']['flags']['currentapp'] = 'login';
+		$GLOBALS['phpgw_info']['flags']['noapi'] = True;
+	}
+	include ('../header.inc.php');
+
+	function fail_exit($msg)
+	{
+		echo "<html>\n<head>\n<title>$msg</title>\n<meta http-equiv=\"content-type\" content=\"text/html; charset=".
+			$GLOBALS['phpgw']->translation->charset()."\" />\n</head>\n<body><h1>$msg</h1>\n</body>\n</html>\n";
+
+		$GLOBALS['phpgw']->common->phpgw_exit();
+	}
+
+	if (!$loged_in)
+	{
+		include ('../phpgwapi/inc/functions.inc.php');
+		$GLOBALS['phpgw_info']['flags']['currentapp'] = 'calendar';
+	}
+	$user  = is_numeric($_GET['user']) ? (int) $_GET['user'] : $GLOBALS['phpgw']->accounts->name2id($_GET['user']);
+
+	if (!($username = $GLOBALS['phpgw']->accounts->id2name($user)))
+	{
+		fail_exit(lang("freebusy: Unknow user '%1', wrong password or not availible to not loged in users !!!",$_GET['user']));
+	}
+	if (!$loged_in)
+	{
+		$GLOBALS['phpgw']->preferences->account_id = $user;
+		$GLOBALS['phpgw_info']['user']['preferences'] = $GLOBALS['phpgw']->preferences->read_repository();
+		$GLOBALS['phpgw_info']['user']['account_id'] = $user;
+		$GLOBALS['phpgw_info']['user']['account_lid'] = $username;
+
+		$cal_prefs = &$GLOBALS['phpgw_info']['user']['preferences']['calendar'];
+		if (!$cal_prefs['freebusy'] || !empty($cal_prefs['freebusy_pw']) && $cal_prefs['freebusy_pw'] != $_GET['password'])
+		{
+			fail_exit(lang("freebusy: Unknow user '%1', wrong password or not availible to not loged in users !!!",$_GET['user']));
+		}
+	}
+	ExecMethod('calendar.boicalendar.freebusy');
Index: /tags/calendar/0.9.3/csv_import.php
===================================================================
--- /tags/calendar/0.9.3/csv_import.php	(revision 204)
+++ /tags/calendar/0.9.3/csv_import.php	(revision 204)
@@ -0,0 +1,523 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar: CSV - Import                                      *
+  * http://www.egroupware.org                                                *
+  * Written by Ralf Becker <RalfBecker@outdoor-training.de>                  *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	$GLOBALS['phpgw_info']['flags'] = array(
+		'currentapp' => 'calendar',
+		'noheader'   => True
+	);
+	include('../header.inc.php');
+
+	if (!isset($GLOBALS['phpgw_info']['user']['apps']['admin']) ||
+	    !$GLOBALS['phpgw_info']['user']['apps']['admin'])		// no admin
+	{
+		$GLOBALS['phpgw']->redirect_link('/home.php');
+	}
+	if (isset($_FILES['csvfile']['tmp_name']))
+	{
+		$csvfile = $GLOBALS['phpgw_info']['server']['temp_dir'].'/calendar_import_'.basename($csvfile);
+		$GLOBALS['phpgw']->session->appsession('csvfile','',$csvfile);
+		$_POST['action'] = move_uploaded_file($_FILES['csvfile']['tmp_name'],$csvfile) ?
+			'download' : '';
+	}
+	else
+	{
+		$csvfile = $GLOBALS['phpgw']->session->appsession('csvfile');
+	}
+	if ($_POST['cancel'])
+	{
+		@unlink($csvfile);
+		$GLOBALS['phpgw']->redirect_link('/admin/index.php');
+	}
+	$GLOBALS['phpgw_info']['flags']['app_header'] = $GLOBALS['phpgw_info']['apps']['calendar']['title'].' - '.lang('Import CSV-File');
+	$GLOBALS['phpgw']->common->phpgw_header();
+
+	$GLOBALS['phpgw']->template->set_file(array('import_t' => 'csv_import.tpl'));
+	$GLOBALS['phpgw']->template->set_block('import_t','filename','filenamehandle');
+	$GLOBALS['phpgw']->template->set_block('import_t','fheader','fheaderhandle');
+	$GLOBALS['phpgw']->template->set_block('import_t','fields','fieldshandle');
+	$GLOBALS['phpgw']->template->set_block('import_t','ffooter','ffooterhandle');
+	$GLOBALS['phpgw']->template->set_block('import_t','imported','importedhandle');
+	$GLOBALS['phpgw']->template->set_block('import_t','import','importhandle');
+
+	if(($_POST['action'] == 'download' || $_POST['action'] == 'continue') && (!$_POST['fieldsep'] || !$csvfile || !($fp=fopen($csvfile,'rb'))))
+	{
+		$_POST['action'] = '';
+	}
+	$GLOBALS['phpgw']->template->set_var("action_url",$GLOBALS['phpgw']->link("/calendar/csv_import.php"));
+
+	$PSep = '||'; // Pattern-Separator, separats the pattern-replacement-pairs in trans
+	$ASep = '|>'; // Assignment-Separator, separats pattern and replacesment
+	$VPre = '|#'; // Value-Prefix, is expanded to \ for ereg_replace
+	$CPre = '|['; $CPreReg = '\|\['; // |{csv-fieldname} is expanded to the value of the csv-field
+	$CPos = ']';  $CPosReg = '\]';	// if used together with @ (replacement is eval-ed) value gets autom. quoted
+
+	function addr_id( $n_family,$n_given,$org_name )
+	{		// find in Addressbook, at least n_family AND (n_given OR org_name) have to match
+		$contacts = createobject('phpgwapi.contacts');
+
+		$addrs = $contacts->read(0,0,array('id'),'',"n_family=$n_family,n_given=$n_given,org_name=$org_name");
+		if(!count($addrs))
+		{
+			$addrs = $contacts->read(0,0,array('id'),'',"n_family=$n_family,n_given=$n_given");
+		}
+		if(!count($addrs))
+		{
+			$addrs = $contacts->read(0,0,array('id'),'',"n_family=$n_family,org_name=$org_name");
+		}
+
+		if (count($addrs))
+		{
+			return $addrs[0]['id'];
+		}
+
+		return False;
+	}
+
+	$cat2id = array( );
+
+	function cat_id($cats)
+	{
+		if (!$cats)
+		{
+			return '';
+		}
+
+		$cats = split('[,;]',$cats);
+
+		foreach($cats as $k => $cat)
+		{
+			if (isset($cat2id[$cat]))
+			{
+				$ids[$cat] = $cat2id[$cat];	// cat is in cache
+			}
+			else
+			{
+				if (!is_object($GLOBALS['phpgw']->categories))
+				{
+					$GLOBALS['phpgw']->categories = createobject('phpgwapi.categories');
+				}
+				if ($id = $GLOBALS['phpgw']->categories->name2id( addslashes($cat) ))
+				{	// cat exists
+					$cat2id[$cat] = $ids[$cat] = $id;
+				}
+				else
+				{	// create new cat
+					$GLOBALS['phpgw']->categories->add( array('name' => $cat,'descr' => $cat ));
+					$cat2id[$cat] = $ids[$cat] = $GLOBALS['phpgw']->categories->name2id( addslashes($cat) );
+				}
+			}
+		}
+		$id_str = implode( ',',$ids );
+
+		if (count($ids) > 1)		// multiple cats need to be in ','
+		{
+			$id_str = ",$id_str,";
+		}
+		return  $id_str;
+	}
+
+	if (!is_object($GLOBALS['phpgw']->html))
+	{
+		$GLOBALS['phpgw']->html = CreateObject('phpgwapi.html');
+	}
+
+	if ($_POST['next']) $_POST['action'] = 'next';
+	switch ($_POST['action'])
+	{
+	case '':	// Start, ask Filename
+		$GLOBALS['phpgw']->template->set_var('lang_csvfile',lang('CSV-Filename'));
+		$GLOBALS['phpgw']->template->set_var('lang_fieldsep',lang('Fieldseparator'));
+		$GLOBALS['phpgw']->template->set_var('lang_charset',lang('Charset of file'));
+		$GLOBALS['phpgw']->template->set_var('select_charset',
+			$GLOBALS['phpgw']->html->select('charset','',
+			$GLOBALS['phpgw']->translation->get_installed_charsets()+
+			array('utf-8' => 'utf-8 (Unicode)'),True));
+		$GLOBALS['phpgw']->template->set_var('fieldsep',$_POST['fieldsep'] ? $_POST['fieldsep'] : ',');
+		$GLOBALS['phpgw']->template->set_var('submit',lang('Import'));
+		$GLOBALS['phpgw']->template->set_var('enctype','ENCTYPE="multipart/form-data"');
+
+		$GLOBALS['phpgw']->template->parse('rows','filename');
+		break;
+
+	case 'continue':
+	case 'download':
+		$GLOBALS['phpgw']->preferences->read_repository();
+		$defaults = $GLOBALS['phpgw_info']['user']['preferences']['calendar']['cvs_import'];
+		if (!is_array($defaults))
+		{
+			$defaults = array();
+		}
+		$GLOBALS['phpgw']->template->set_var('lang_csv_fieldname',lang('CSV-Fieldname'));
+		$GLOBALS['phpgw']->template->set_var('lang_info_fieldname',lang('calendar-Fieldname'));
+		$GLOBALS['phpgw']->template->set_var('lang_translation',lang("Translation").' <a href="#help">'.lang('help').'</a>');
+		$GLOBALS['phpgw']->template->set_var('submit',
+			$GLOBALS['phpgw']->html->submit_button('convert','Import') . '&nbsp;'.
+			$GLOBALS['phpgw']->html->submit_button('cancel','Cancel'));
+		$GLOBALS['phpgw']->template->set_var('lang_debug',lang('Test Import (show importable records <u>only</u> in browser)'));
+		$GLOBALS['phpgw']->template->parse('rows','fheader');
+
+		$cal_names = array(
+			'title'		=> 'Title varchar(80)',
+			'description' => 'Description text',
+			'location'	=> 'Location varchar(255)',
+			'start'	=> 'Start Date: Timestamp or eg. YYYY-MM-DD hh:mm',
+			'end'	=> 'End Date: Timestamp or eg. YYYY-MM-DD hh:mm',
+			'participants' => 'Participants: comma separated user-id\'s or -names',
+			'category'	=> 'Categories: id\'s or names, comma separated (new ones got created)',
+			'priority'  => 'Priority: 1=Low, 2=Normal, 3=High',
+			'public'	=> 'Access: 1=public, 0=private',
+			'owner'		=> 'Owner: int(11) user-id/-name',
+			'modtime'	=> 'Modification date',
+//			'groups'	=> 'Groups (dont know what this field is for)',
+//			'cal_type'	=> 'cal_type: single_event=E (default) else M',
+		);
+		$custom_fields = CreateObject('calendar.bocustom_fields');
+		//echo "custom-fields=<pre>".print_r($custom_fields,True)."</pre>";
+		foreach ($custom_fields->fields as $name => $data)
+		{
+			if ($name[0] == '#')	// a custom field ?
+			{
+				$cal_names[$name] = $data['name'].': Custom field, varchar('.$data['length'].')';
+			}
+		}
+
+		// the next line is used in the help-text too
+		$mktime_lotus = "${PSep}0?([0-9]+)[ .:-]+0?([0-9]*)[ .:-]+0?([0-9]*)[ .:-]+0?([0-9]*)[ .:-]+0?([0-9]*)[ .:-]+0?([0-9]*).*$ASep@mktime(${VPre}4,${VPre}5,${VPre}6,${VPre}2,${VPre}3,${VPre}1)";
+
+		$cal_name_options = "<option value=\"\">none\n";
+		foreach($cal_names as $field => $name)
+		{
+			$cal_name_options .= "<option value=\"$field\">".$GLOBALS['phpgw']->strip_html($name)."\n";
+		}
+		$csv_fields = fgetcsv($fp,8000,$_POST['fieldsep']);
+		$csv_fields = $GLOBALS['phpgw']->translation->convert($csv_fields,$_POST['charset']);
+		$csv_fields[] = 'no CSV 1';					// eg. for static assignments
+		$csv_fields[] = 'no CSV 2';
+		$csv_fields[] = 'no CSV 3';
+		foreach($csv_fields as $csv_idx => $csv_field)
+		{
+			$GLOBALS['phpgw']->template->set_var('csv_field',$csv_field);
+			$GLOBALS['phpgw']->template->set_var('csv_idx',$csv_idx);
+			if ($def = $defaults[$csv_field])
+			{
+				list( $info,$trans ) = explode($PSep,$def,2);
+				$GLOBALS['phpgw']->template->set_var('trans',$trans);
+				$GLOBALS['phpgw']->template->set_var('cal_fields',str_replace('="'.$info.'">','="'.$info.'" selected>',$cal_name_options));
+			}
+			else
+			{
+				$GLOBALS['phpgw']->template->set_var('trans','');
+				$GLOBALS['phpgw']->template->set_var('cal_fields',$cal_name_options);
+			}
+			$GLOBALS['phpgw']->template->parse('rows','fields',True);
+		}
+		$GLOBALS['phpgw']->template->set_var('lang_start',lang('Startrecord'));
+		$GLOBALS['phpgw']->template->set_var('start',get_var('start',array('POST'),1));
+		$msg = ($safe_mode = ini_get('safe_mode') == 'On') ? lang('to many might exceed your execution-time-limit'):
+			lang('empty for all');
+		$GLOBALS['phpgw']->template->set_var('lang_max',lang('Number of records to read (%1)',$msg));
+		$GLOBALS['phpgw']->template->set_var('max',get_var('max',array('POST'),$safe_mode ? 200 : ''));
+		$GLOBALS['phpgw']->template->set_var('debug',get_var('debug',array('POST'),True)?' checked':'');
+		$GLOBALS['phpgw']->template->parse('rows','ffooter',True);
+		fclose($fp);
+
+		$hiddenvars = $GLOBALS['phpgw']->html->input_hidden(array(
+			'action'  => 'import',
+			'fieldsep'=> $_POST['fieldsep'],
+			'charset' => $_POST['charset']
+		));
+		$help_on_trans = "<a name=\"help\"></a><b>How to use Translation's</b><p>".
+			"Translations enable you to change / adapt the content of each CSV field for your needs. <br>".
+			"General syntax is: <b>pattern1 ${ASep} replacement1 ${PSep} ... ${PSep} patternN ${ASep} replacementN</b><br>".
+			"If the pattern-part of a pair is ommited it will match everything ('^.*$'), which is only ".
+			"usefull for the last pair, as they are worked from left to right.<p>".
+			"First example: <b>1${ASep}private${PSep}public</b><br>".
+			"This will translate a '1' in the CVS field to 'private' and everything else to 'public'.<p>".
+			"Patterns as well as the replacement can be regular expressions (the replacement is done via ereg_replace). ".
+			"If, after all replacements, the value starts with an '@' the whole value is eval()'ed, so you ".
+			"may use all php, phpgw plus your own functions. This is quiet powerfull, but <u>circumvents all ACL</u>.<p>".
+			"Example using regular expressions and '@'-eval(): <br><b>$mktime_lotus</b><br>".
+			"It will read a date of the form '2001-05-20 08:00:00.00000000000000000' (and many more, see the regular expr.). ".
+			"The&nbsp;[&nbsp;.:-]-separated fields are read and assigned in different order to @mktime(). Please note to use ".
+			"${VPre} insted of a backslash (I couldn't get backslash through all the involved templates and forms.) ".
+			"plus the field-number of the pattern.<p>".
+			"In addintion to the fields assign by the pattern of the reg.exp. you can use all other CSV-fields, with the ".
+			"syntax <b>${CPre}CVS-FIELDNAME$CPos</b>. Here is an example: <br>".
+			"<b>.+$ASep${CPre}Company$CPos: ${CPre}NFamily$CPos, ${CPre}NGiven$CPos$PSep${CPre}NFamily$CPos, ${CPre}NGiven$CPos</b><br>".
+			"It is used on the CVS-field 'Company' and constructs a something like <i>Company: FamilyName, GivenName</i> or ".
+			"<i>FamilyName, GivenName</i> if 'Company' is empty.<p>".
+			"You can use the 'No CVS #'-fields to assign cvs-values to more than on field, the following example uses the ".
+			"cvs-field 'Note' (which gots already assingned to the description) and construct a short subject: ".
+			"<b>@substr(${CPre}Note$CPos,0,60).' ...'</b><p>".
+			"Their is two important user-function for the calendar:<br>".
+			"<b>@addr_id(${CPre}NFamily$CPos,${CPre}NGiven$CPos,${CPre}Company$CPos)</b> ".
+			"searches the addressbook for an address and returns the id if it founds an exact match of at least ".
+			"<i>NFamily</i> AND (<i>NGiven</i> OR <i>Company</i>). This is necessary to link your imported calendar-entrys ".
+			"with the addressbook.<br>".
+			"<b>@cat_id(Cat1,...,CatN)</b> returns a (','-separated) list with the cat_id's. If a category isn't found, it ".
+			"will be automaticaly added. This function is automaticaly called if the category is not numerical!<p>".
+			"I hope that helped to understand the features, if not <a href='mailto:RalfBecker@outdoor-training.de'>ask</a>.";
+
+		$GLOBALS['phpgw']->template->set_var('help_on_trans',lang($help_on_trans));	// I don't think anyone will translate this
+		break;
+
+	case 'next':
+		$_POST['cal_fields'] = unserialize(stripslashes($_POST['cal_fields']));
+		$_POST['trans']       = unserialize(stripslashes($_POST['trans']));
+		// fall-through
+	case 'import':
+		$hiddenvars = $GLOBALS['phpgw']->html->input_hidden(array(
+			'action'  => 'continue',
+			'fieldsep'=> $_POST['fieldsep'],
+			'charset' => $_POST['charset'],
+			'start'   => $_POST['start']+(!$_POST['debug'] ? $_POST['max'] : 0),
+			'max'     => $_POST['max'],
+			'debug'   => $_POST['debug'],
+			'cal_fields' => $_POST['cal_fields'],
+			'trans'   => $_POST['trans']
+		));
+		@set_time_limit(0);
+		$fp=fopen($csvfile,'r');
+		$csv_fields = fgetcsv($fp,8000,$_POST['fieldsep']);
+		$csv_fields = $GLOBALS['phpgw']->translation->convert($csv_fields,$_POST['charset']);
+		$csv_fields[] = 'no CSV 1';						// eg. for static assignments
+		$csv_fields[] = 'no CSV 2';
+		$csv_fields[] = 'no CSV 3';
+
+		$cal_fields = array_diff($_POST['cal_fields'],array( '' ));	// throw away empty / not assigned entrys
+
+		$defaults = array();
+		foreach($cal_fields as $csv_idx => $info)
+		{	// convert $trans[$csv_idx] into array of pattern => value
+			$defaults[$csv_fields[$csv_idx]] = $info;
+			if ($_POST['trans'][$csv_idx])
+			{
+				$defaults[$csv_fields[$csv_idx]] .= $PSep.addslashes($_POST['trans'][$csv_idx]);
+			}
+		}
+
+		$GLOBALS['phpgw']->preferences->read_repository();
+		$GLOBALS['phpgw']->preferences->add('calendar','cvs_import',$defaults);
+		$GLOBALS['phpgw']->preferences->save_repository(True);
+
+		$log = "<table border=1>\n\t<tr><td>#</td>\n";
+
+		foreach($cal_fields as $csv_idx => $info)
+		{	// convert $trans[$csv_idx] into array of pattern => value
+			// if (!$debug) echo "<p>$csv_idx: ".$csv_fields[$csv_idx].": $info".($trans[$csv_idx] ? ': '.$trans[$csv_idx] : '')."</p>";
+			$pat_reps = explode($PSep,stripslashes($_POST['trans'][$csv_idx]));
+			$replaces = ''; $values = '';
+			if ($pat_reps[0] != '')
+			{
+				foreach($pat_reps as $k => $pat_rep)
+				{
+					list($pattern,$replace) = explode($ASep,$pat_rep,2);
+					if ($replace == '')
+					{
+						$replace = $pattern; $pattern = '^.*$';
+					}
+					$values[$pattern] = $replace;	// replace two with only one, added by the form
+					$replaces .= ($replaces != '' ? $PSep : '') . $pattern . $ASep . $replace;
+				}
+				$trans[$csv_idx] = $values;
+			} /*else
+				unset( $trans[$csv_idx] );*/
+
+			$log .= "\t\t<td><b>$info</b></td>\n";
+		}
+		if (!in_array('public',$cal_fields))	// autocreate public access if not set by user
+		{
+			$log .= "\t\t<td><b>isPublic</b></td>\n";
+		}
+/* maybe later ;-)
+		if (!in_array('cal_type',$cal_fields))	// autocreate single event if not set by user
+		{
+			$log .= "\t\t<td><b>recureing</b></td>\n";
+		}
+*/
+		$start = $_POST['start'] < 1 ? 1 : $_POST['start'];
+
+		// ignore empty lines, is_null($fields[0]) is returned on empty lines !!!
+		for($i = 1; $i < $start; ++$i)	// overread lines before our start-record
+		{
+			while(($fields = fgetcsv($fp,8000,$_POST['fieldsep'])) && is_null($fields[0])) ;
+		}
+		for($anz = 0; !$_POST['max'] || $anz < $_POST['max']; ++$anz)
+		{
+			while(($fields = fgetcsv($fp,8000,$_POST['fieldsep'])) && is_null($fields[0])) ;
+			if (!$fields)
+			{
+				break;	// EOF
+			}
+			$fields = $GLOBALS['phpgw']->translation->convert($fields,$_POST['charset']);
+
+			$log .= "\t</tr><tr><td>".($start+$anz)."</td>\n";
+
+			$values = array();
+			foreach($cal_fields as $csv_idx => $info)
+			{
+				//echo "<p>$csv: $info".($trans[$csv] ? ': '.$trans[$csv] : '')."</p>";
+				$val = $fields[$csv_idx];
+				if (isset($trans[$csv_idx]) && is_array($trans[$csv_idx]))
+				{
+					foreach($trans[$csv_idx] as $pattern => $replace)
+					{
+						if (ereg((string) $pattern,$val))
+						{
+							// echo "<p>csv_idx='$csv_idx',info='$info',trans_csv=".print_r($trans_csv).",ereg_replace('$pattern','$replace','$val') = ";
+							$val = ereg_replace((string) $pattern,str_replace($VPre,'\\',$replace),(string) $val);
+							// echo "'$val'</p>";
+
+							$reg = $CPreReg.'([a-zA-Z_0-9]+)'.$CPosReg;
+							while (ereg($reg,$val,$vars))
+							{	// expand all CSV fields
+								$val = str_replace($CPre.$vars[1].$CPos,$val[0] == '@' ? "'".addslashes($fields[array_search($vars[1],$csv_fields)])."'" : $fields[array_search($vars[1],$csv_fields)],$val);
+							}
+							if ($val[0] == '@')
+							{
+								// removing the $ to close security hole of showing vars, which contain eg. passwords
+								$val = 'return '.substr(str_replace('$','',$val),1).';';
+								// echo "<p>eval('$val')=";
+								$val = eval($val);
+								// echo "'$val'</p>";
+							}
+							if ($pattern[0] != '@' || $val)
+								break;
+						}
+					}
+				}
+				$values[$info] = $val;
+
+				$log .= "\t\t<td>$val</td>\n";
+			}
+			if (!in_array('public',$cal_fields))
+			{
+				$values['public'] = 1;	// public access if not set by user
+				$log .= "\t\t<td>".$values['public']."</td>\n";
+			}
+/* maybe later ;-)
+			if (!in_array('cal_type',$cal_fields))
+			{
+				$values['cal_type'] = 'E';	// single event if not set by user
+				$log .= "\t\t<td>".$values['cal_type']."</td>\n";
+			}
+*/
+			if(!$_POST['debug'] && count($values))	// dont import empty contacts
+			{
+				//echo "values=<pre>".print_r($values,True)."</pre>\n";
+				if (!is_numeric($values['owner']))
+				{
+					$values['owner'] = $GLOBALS['phpgw']->accounts->name2id($values['owner']);
+				}
+				if (!$values['owner'] || !$GLOBALS['phpgw']->accounts->exists($values['owner']))
+				{
+					$values['owner'] = $GLOBALS['phpgw_info']['user']['account_id'];
+				}
+				if (!is_object($calendar))
+				{
+					$calendar = createobject('calendar.socalendar',array());
+					$cal_owner = False;
+				}
+				if ($cal_owner != $values['owner'])
+				{
+					$calendar->open_box($cal_owner = $values['owner']);
+				}
+				// echo "<p>adding: ".dump_array($values)."</p>\n";
+				$calendar->event_init();		// set some reasonable defaults
+				$calendar->set_recur_none();
+
+				if ($values['priority'] < 1 || $values['priority'] > 3)
+				{
+					$values['priority'] = 2;
+				}
+				// convert the category name to an id
+				if ($values['category'] && !is_numeric($values['category']))
+				{
+					$values['category'] = cat_id($values['category']);
+				}
+				if (empty($values['title']))
+				{
+					$values['title'] = '('.lang('none').')';
+				}
+				foreach(array('owner','title','description','location','category','priority','public') as $name)
+				{
+					$calendar->add_attribute($name,$values[$name]);
+				}
+
+				if (!isset($values['modtime'])) $values['modtime'] = $values['start'];
+				// convert dates to timestamps
+				foreach(array('start','end','modtime') as $date)
+				{
+					if (isset($values[$date]) && !is_numeric($date))
+					{
+						// convert german DD.MM.YYYY format into ISO YYYY-MM-DD format
+						$values[$date] = ereg_replace('([0-9]{2}).([0-9]{2}).([0-9]{4})','\3-\2-\1',$values[$date]);
+						// remove fractures of seconds if present at the end of the string
+						if (ereg('(.*)\.[0-9]+',$values[$date],$parts)) $values[$date] = $parts[1];
+						$values[$date] = strtotime($values[$date]);
+					}
+					$datearr = $GLOBALS['phpgw']->datetime->localdates($values[$date]);
+					$calendar->set_date($date,$datearr['year'],$datearr['month'],$datearr['day'],
+						$datearr['hour'],$datearr['minute'],$datearr['second']);
+				}
+				// convert participants-names to user-id's
+				$participants = 0;
+				foreach(split('[,;]',$values['participants']) as $part_status)
+				{
+					list($part,$status) = explode('=',$part_status);
+					$valid_status = array('U'=>'U','u'=>'U','A'=>'A','a'=>'A','R'=>'R','r'=>'R','T'=>'T','t'=>'T');
+					$status = isset($valid_status[$status]) ? $valid_status[$status] : 'U';
+					if ($GLOBALS['phpgw']->accounts->exists($part))
+					{
+						$part = $GLOBALS['phpgw']->accounts->name2id($part);
+					}
+					if ($part && is_numeric($part))
+					{
+						$calendar->add_attribute('participants',$status,$part);
+						$participants++;
+					}
+				}
+				if (!$participants)		// no valid participants so far --> add the importing user/owner
+				{
+					$calendar->add_attribute('participants','A',$values['owner']);
+				}
+				// add custom-fields
+				foreach($values as $name => $val)
+				{
+					if ($name[0] == '#')
+					{
+						$calendar->add_attribute($name,$values[$name]);
+					}
+				}
+				//echo "add_entry(<pre>".print_r($calendar->cal->event,True).")</pre>\n";
+				$calendar->add_entry( $calendar->cal->event );
+			}
+		}
+		$log .= "\t</tr>\n</table>\n";
+
+		$GLOBALS['phpgw']->template->set_var('anz_imported',($_POST['debug'] ?
+			lang('%1 records read (not yet imported, you may go back and uncheck Test Import)',
+			$anz,'','') :
+			lang('%1 records imported',$anz)). '&nbsp;'.
+			(!$_POST['debug'] && $fields ? $GLOBALS['phpgw']->html->submit_button('next','Import next set') . '&nbsp;':'').
+			$GLOBALS['phpgw']->html->submit_button('continue','Back') . '&nbsp;'.
+			$GLOBALS['phpgw']->html->submit_button('cancel','Cancel'));
+		$GLOBALS['phpgw']->template->set_var('log',$log);
+		$GLOBALS['phpgw']->template->parse('rows','imported');
+		break;
+	}
+	$GLOBALS['phpgw']->template->set_var('hiddenvars',str_replace('{','&#x7B;',$hiddenvars));
+	$GLOBALS['phpgw']->template->pfp('phpgw_body','import');
+	$GLOBALS['phpgw']->common->phpgw_footer();
+
+?>
Index: /tags/calendar/0.9.3/index.php
===================================================================
--- /tags/calendar/0.9.3/index.php	(revision 2)
+++ /tags/calendar/0.9.3/index.php	(revision 2)
@@ -0,0 +1,43 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare - Calendar                                                    *
+  * http://www.egroupware.org                                                *
+  * Based on Webcalendar by Craig Knudsen <cknudsen@radix.net>               *
+  *          http://www.radix.net/~cknudsen                                  *
+  * Modified by Mark Peters <skeeter@phpgroupware.org>                       *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	$phpgw_flags = Array(
+		'currentapp'	=>	'calendar',
+		'noheader'	=>	True,
+		'nonavbar'	=>	True,
+		'noappheader'	=>	True,
+		'noappfooter'	=>	True,
+		'nofooter'	=>	True
+	);
+
+	$GLOBALS['phpgw_info']['flags'] = $phpgw_flags;
+	include('../header.inc.php');
+	if(!is_object($GLOBALS['phpgw']->datetime))
+	{
+		$GLOBALS['phpgw']->datetime = CreateObject('phpgwapi.date_time');
+	}
+
+	$parms = Array(
+#		'menuaction'=> 'calendar.uicalendar.index',
+		'date'		=> date('Ymd',$GLOBALS['phpgw']->datetime->users_localtime)
+	);
+
+	//echo 'Local DateTime: '.date('Ymd H:i:s',$GLOBALS['phpgw']->datetime->users_localtime).'<br>'."\n";
+
+#	$GLOBALS['phpgw']->redirect_link('/index.php',$parms);
+	ExecMethod('calendar.uicalendar.index',$parms);
+	$GLOBALS['phpgw']->common->phpgw_exit();
+
+?>
Index: /tags/calendar/0.9.3/templates/default/locales.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/locales.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/locales.tpl	(revision 2)
@@ -0,0 +1,60 @@
+<!-- BEGIN list -->
+<p>
+ <table border="0" width="45%" align="center">
+  <tr>
+   <td align="left">{left_next_matchs}</td>
+   {center}
+   <td align="right">{right_next_matchs}</td>
+  </tr>
+ </table>
+
+ <table border="0" width="70%" align="center">
+  <tr bgcolor="{th_bg}">
+   <td>&nbsp;{sort_name}</td>
+   {header_rule}
+   <td>{header_edit}</td>
+   <td>{header_delete}</td>
+   <td>{header_extra}</td>
+  </tr>
+
+  {rows}
+
+ </table>
+
+ <table border="0" width="70%" cellspacing="5" align="center">
+  <tr>
+   <td align="left">
+    <form method="POST" action="{new_action}">
+     <input type="submit" value="{lang_add}">
+    </form>
+   </td>
+   {back_button}
+   <td width="80%" align="right">
+    <form method="POST" action="{search_action}">
+     {lang_search}&nbsp;<input name="query">
+    </form>
+   </td>
+  </tr>
+ </table>
+<!-- END list -->
+<!-- BEGIN row -->
+ <tr bgcolor="{tr_color}">
+  <td>&nbsp;{group_name}</td>
+  {rule}
+  <td width="5%">{edit_link}</td>
+  <td width="5%">{delete_link}</td>
+  <td align="center" {extra_width}>{extra_link}</td>
+ </tr>
+<!-- END row -->
+<!-- BEGIN row_empty -->
+   <tr>
+    <td colspan="5" align="center">{message}</td>
+   </tr>
+<!-- END row_empty -->
+<!-- BEGIN back_button_form -->
+   <td align="center">
+    <form method="POST" action="{back_action}">
+     <input type="submit" value="{lang_back}">
+    </form>
+   </td>
+<!-- END back_button_form -->
Index: /tags/calendar/0.9.3/templates/default/form_button_script.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/form_button_script.tpl	(revision 663)
+++ /tags/calendar/0.9.3/templates/default/form_button_script.tpl	(revision 663)
@@ -0,0 +1,12 @@
+
+<!-- BEGIN form_button -->
+<nobr>
+<form action="{action_url_button}" method="post" name="{action_text_button}form">
+<div style="padding-top:15px; padding-right: 2px">
+	{action_extra_field} 
+	<input id="{button_id}" style="font-size:10px" type="submit" value="{action_text_button}" {action_confirm_button}>
+</div>
+</form>
+</nobr>
+
+<!-- END form_button -->
Index: /tags/calendar/0.9.3/templates/default/month.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/month.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/month.tpl	(revision 2)
@@ -0,0 +1,6 @@
+
+<table id="calendar_month_table" width="100%" border="0" bordercolor="#FFFFFF" cellspacing="2" cellpadding="2" cols={cols}>
+	{row}
+</table>
+
+
Index: /tags/calendar/0.9.3/templates/default/app_print.css
===================================================================
--- /tags/calendar/0.9.3/templates/default/app_print.css	(revision 360)
+++ /tags/calendar/0.9.3/templates/default/app_print.css	(revision 360)
@@ -0,0 +1,302 @@
+/* Este documento é um css somente para impressão do calendário no papel!
+O seu efeito não aparece na tela  */
+
+.calendar_print_main {
+	text-align:center;
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-size: 8px;
+	color: #000066;
+	background-color: #F7F7F7;
+/*	border: 1px solid #CCCCCC;*/
+	margin: 5px;
+	padding: 5px;
+	height: 700px;
+	width: 900px;
+}
+.button {
+	display: none;
+}
+
+
+.to_continue
+{
+	font-size: 9px;
+}
+
+A.minicalendar 
+{ 
+	color: #000000; 
+	font-size: 9px;
+	
+}
+
+A.bminicalendar 
+{ 
+	color: #336699; 
+	font-style: italic;
+	font-weight: bold;
+	font-size: 9px; 
+}
+
+A.minicalendargrey 
+{ 
+	color: #999999; 
+	font-size: 10px;
+	font-weight: bold;
+}
+
+A.bminicalendargrey 
+{ 
+	color: #336699; 
+	font-style: italic; 
+	font-size:10px; 
+}
+
+A.minicalhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #000000; 
+	font-size: 10px; 
+}
+
+A.bminicalhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #336699; 
+	font-size: 10px; 
+}
+
+A.minicalgreyhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #999999; 
+	font-size: 10px; 
+}
+
+A.bminicalgreyhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #999999; 
+	font-size: 10px; 
+}
+
+
+.event-on
+{ 
+	background: #D3DCE3;
+	border: #E8F0F0 1px solid;
+}
+
+.event-off
+{ 
+	background: #E8F0F0;
+	border: #D3DCE3 1px solid;
+}
+
+.event-holiday
+{
+	font-size: 100%;
+	background: #dac0c0;
+	color:#000000;
+	vertical-align: middle;
+}
+
+.time
+{
+	background: #D3DCE3;
+	color:#000000;
+	font-size: 10px;
+	font-weight: bold;
+	vertical-align: middle;
+	width: 5.2%;
+	text-align: right;
+	padding-right: 5px;
+	line-height: 11px;
+	border: #E8F0F0 1px solid;
+}
+
+
+.planner-cell
+{
+	cursor: pointer;
+	cursor: hand;
+	border: thin solid black;
+}
+
+/* common */
+.calendar_link_print
+{
+	text-align: center;
+	font-size: 10px;
+}
+
+//Mini Calendar
+
+.calendar_minical_table
+{
+	width: 180px;
+	font-weight: bold;
+}
+
+.calendar_minical_daytable
+{
+	width: 100%;
+}
+
+.calendar_minical_dayname
+{
+	font-size: 9px;
+	text-align: right;
+}
+
+.calendar_minical_hrule
+{
+	width: 96%;
+}
+
+/* Header */
+.calendar_dropbuttons
+{
+	align: center;
+	text-align: center;
+	vertical-align: bottom;
+	font-weight: bold;
+	font-size: 8px;
+}
+
+.calendar-weekidentifier
+{
+	font-size:16px;
+	font-weight: bold;
+	text-align: center;
+}
+
+.calendar_header
+{
+	font-size: 16px;
+	font-weight: bold;
+	text-align: center;
+}
+
+.calendar_dayview_table_header
+{
+	font-size: 13px;
+	font-weight: bold;
+	text-align: center;
+}
+
+.calendar_dayview_todo_header
+{
+	margin: 0px; 
+	padding: 2px;
+	font-weight: bold;
+}
+
+/* week view */
+.calendar_week_identifier_table
+{
+	border: 0px solid black;
+	width: 100%;
+}
+
+.calendar_week_identifier
+{
+	font-size: 13px;
+	text-align: center;
+	font-weight: bold;
+}
+
+.calendar_weekview_daytitle
+{
+	font-weight: bold;
+	font-size: 12px;
+	background: #D3DCE3;
+}
+
+.calendar_m_w_table
+{
+	table-layout:fixed;
+	overflow:hidden;
+	height: 95%;
+	width: 100%;
+	border: 0px #000000 solid;
+}
+
+.calendar_m_w_tablecell
+{
+	overflow:hidden;
+	vertical-align: top;
+	padding-left: 4px;
+	padding-right: 4px;
+	padding-bottom: 6px;
+	border: 1px solid #000000;
+}
+
+.screen_only
+{
+	display:none;
+}
+
+.calendar_m_w_table_daynumber
+{
+	font-weight: bold;
+	font-family: Arial;
+	font-size: 13px;
+	vertical-align: top;
+	background-color: #778899;
+	border: 1px solid #000000;
+	margin: 1px;
+	padding: 1px;
+}
+
+A.event_entry
+{
+	font-size:10px;
+}
+
+/* month view */
+
+.calendar_month_identifier
+{
+	font-size:22px;
+	font-weight: bold;
+}
+
+.calendar_user_identifier
+{
+	font-size:14px;
+	color: #009999;
+	font-weight: bold;
+}
+
+.calendar_week_minical_table
+{
+	width:100%;
+	border: 0px solid #000000
+}
+
+.calendar_weekinfo
+{
+	color: #000000;
+	padding-left: 2px;
+	padding-right: 2px;
+	font-size: 10px;
+	font-weight: bold;
+	font-style: italic;
+}
+
+.calendar_index_table
+{
+	background-color: #dddddd;
+	border-bottom-style: double;
+	border-bottom-width: medium;
+
+}
Index: /tags/calendar/0.9.3/templates/default/csv_import.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/csv_import.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/csv_import.tpl	(revision 2)
@@ -0,0 +1,74 @@
+<!-- BEGIN filename -->
+	  		<TR>
+	    		<TD>{lang_csvfile}</td>
+				<td><INPUT NAME="csvfile" SIZE=30 TYPE="file" VALUE="{csvfile}"></td>
+			</tr>
+			<tr>
+				<td>{lang_fieldsep}</td>
+				<td><input name="fieldsep" size=1 value="{fieldsep}"></td>
+			</tr>
+			<tr>
+				<td>{lang_charset}</td>
+				<td>
+			{select_charset}
+				</td>
+			</tr>
+			<tr><td>&nbsp;</td>
+				<td><INPUT NAME="convert" TYPE="submit" VALUE="{submit}"></TD>
+			</TR>
+<!-- END filename -->
+
+<!-- BEGIN fheader -->
+			<tr>
+				<td><b>{lang_csv_fieldname}</b></td>
+				<td><b>{lang_info_fieldname}</b></td>
+				<td><b>{lang_translation}</b></td>
+			</tr>
+<!-- END fheader -->
+
+<!-- BEGIN fields -->
+			<tr>
+				<td>{csv_field}</td>
+				<td><SELECT name="cal_fields[{csv_idx}]">{cal_fields}</select></td>
+				<td><input name="trans[{csv_idx}]" size=60 value="{trans}"></td>
+			</tr>
+<!-- END fields -->
+
+<!-- BEGIN ffooter -->
+			<tr>
+				<td rowspan="2" valign="middle" nowrap><br>{submit}</TD>
+				<td colspan="2"><br>
+					{lang_start} <INPUT name="start" type="text" size="5" value="{start}"> &nbsp; &nbsp;
+					{lang_max} <INPUT name="max" type="text" size="3" value="{max}"><td>
+			</tr>
+			<tr>
+				<td colspan="2"><INPUT name="debug" type="checkbox" value="1"{debug}> {lang_debug}</td>
+			</TR>
+			<tr><td colspan="3">&nbsp;<p>
+				{help_on_trans}
+			</td></tr>
+<!-- END ffooter -->
+
+<!-- BEGIN imported -->
+			<tr>
+				<td colspan=2 align=center>
+					{log}<p>
+					{anz_imported}
+				</td>
+			</TR>
+<!-- END imported -->
+
+<!-- BEGIN import -->
+<br/>
+<center>
+		<form {enctype} action="{action_url}" method="post">
+		<table>
+
+		{rows}
+
+		</table>
+		{hiddenvars}
+		</form>
+
+</center>
+<!-- END import -->
Index: /tags/calendar/0.9.3/templates/default/header.inc.php
===================================================================
--- /tags/calendar/0.9.3/templates/default/header.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/header.inc.php	(revision 2)
@@ -0,0 +1,225 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare                                                               *
+  * http://www.egroupware.org                                                *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	function add_col(&$tpl,$str)
+	{
+		$tpl->set_var('str',$str);
+		$tpl->parse('header_column','head_col',True);
+	}
+
+	function add_image_ahref($link,$image,$alt)
+	{
+		return '<a href="'.$link.'"><img src="'.$GLOBALS['phpgw']->common->image('calendar',$image).'" alt="'.$alt.'" title="'.$alt.'" border="0"></a>';
+	}
+
+	$refer = explode('.',$GLOBALS['HTTP_GET_VARS']['menuaction']);
+	$referrer = $refer[2];
+
+	$templates = Array(
+		'head_tpl'	=> 'head.tpl',
+		'form_button_dropdown'	=> 'form_button_dropdown.tpl',
+		'form_button_script'	=> 'form_button_script.tpl'
+	);
+	$tpl->set_file($templates);
+	$tpl->set_block('head_tpl','head','head');
+	$tpl->set_block('head_tpl','head_table','head_table');
+	$tpl->set_block('head_tpl','head_col','head_col');
+	$tpl->set_block('form_button_script','form_button');
+
+	if(floor(phpversion()) >= 4)
+	{
+		$tpl->set_var('cols',8);
+	}
+	else
+	{
+		$tpl->set_var('cols',7);
+	}
+
+	$today = date('Ymd',$GLOBALS['phpgw']->datetime->users_localtime);
+
+	$col_width = 12;
+
+	add_col($tpl,'  <td width="2%">&nbsp;</td>');
+
+	add_col($tpl,'  <td width="2%">'.add_image_ahref($this->page('day','&date='.$today),'today',lang('Today')).'</td>');
+
+	add_col($tpl,'  <td width="2%" align="left">'.add_image_ahref($this->page('week','&date='.$today),'week',lang('This week')).'</td>');
+
+	add_col($tpl,'  <td width="2%" align="left">'.add_image_ahref($this->page('month','&date='.$today),'month',lang('This month')).'</td>');
+
+	add_col($tpl,'  <td width="2%" align="left">'.add_image_ahref($this->page('year','&date='.$today),'year',lang('This Year')).'</td>');
+
+	if(floor(phpversion()) >= 4)
+	{
+		add_col($tpl,'  <td width="2%" align="left">'.add_image_ahref($this->page('planner','&date='.$today),'planner',lang('Planner')).'</td>');
+		$col_width += 2;
+	}
+
+	add_col($tpl,'  <td width="2%" align="left">'.add_image_ahref($this->page('matrixselect'),'view',lang('Daily Matrix View')).'</td>');
+
+	add_col($tpl,'  <td width="'.(100 - $col_width).'%" align="left"'.(floor(phpversion()) < 4?' colspan="2"':'').'>&nbsp;</td>');
+
+	$tpl->parse('row','head_table',True);
+
+	$tpl->set_var('header_column','');
+	$tpl->set_var('cols',$cols);
+
+	if($referrer!='view')
+	{
+		$remainder = 72;
+		
+		$date = (isset($GLOBALS['date'])?$GLOBALS['date']:'');
+		$date = (isset($GLOBALS['HTTP_GET_VARS']['date'])?$GLOBALS['HTTP_GET_VARS']['date']:$date);
+		$date = ($date=='' && isset($GLOBALS['HTTP_POST_VARS']['date'])?$GLOBALS['HTTP_POST_VARS']['date']:$date);
+
+		$base_hidden_vars = '<input type="hidden" name="from" value="'.$GLOBALS['HTTP_GET_VARS']['menuaction'].'">'."\n";
+		if(isset($GLOBALS['HTTP_GET_VARS']['cal_id']) && $GLOBALS['HTTP_GET_VARS']['cal_id'] != 0)
+		{
+			$base_hidden_vars .= '    <input type="hidden" name="cal_id" value="'.$GLOBALS['HTTP_GET_VARS']['cal_id'].'">'."\n";
+		}
+		if(isset($GLOBALS['HTTP_POST_VARS']['keywords']) && $GLOBALS['HTTP_POST_VARS']['keywords'])
+		{
+			$base_hidden_vars .= '    <input type="hidden" name="keywords" value="'.$GLOBALS['HTTP_POST_VARS']['keywords'].'">'."\n";
+		}
+		if(isset($GLOBALS['HTTP_POST_VARS']['matrixtype']) && $GLOBALS['HTTP_POST_VARS']['matrixtype'])
+		{
+			$base_hidden_vars .= '    <input type="hidden" name="matrixtype" value="'.$GLOBALS['HTTP_POST_VARS']['matrixtype'].'">'."\n";
+		}
+		if($date)
+		{
+			$base_hidden_vars .= '    <input type="hidden" name="date" value="'.$date.'">'."\n";
+		}
+		$base_hidden_vars .= '    <input type="hidden" name="month" value="'.$this->bo->month.'">'."\n";
+		$base_hidden_vars .= '    <input type="hidden" name="day" value="'.$this->bo->day.'">'."\n";
+		$base_hidden_vars .= '    <input type="hidden" name="year" value="'.$this->bo->year.'">'."\n";
+		
+		if(isset($GLOBALS['HTTP_POST_VARS']['participants']) && $GLOBALS['HTTP_POST_VARS']['participants'])
+		{
+			for ($i=0;$i<count($GLOBALS['HTTP_POST_VARS']['participants']);$i++)
+			{
+				$base_hidden_vars .= '    <input type="hidden" name="participants[]" value="'.$GLOBALS['HTTP_POST_VARS']['participants'][$i].'">'."\n";
+			}
+		}
+
+		$var = Array(
+			'form_width' => '28',
+			'form_link'	=> $this->page($referrer),
+			'form_name'	=> 'cat_id',
+			'title'	=> lang('Category'),
+			'hidden_vars'	=> $base_hidden_vars,
+			'form_options'	=> '<option value="0">'.lang('All').'</option>'.$this->cat->formated_list('select','all',$this->bo->cat_id,'True'),
+			'button_value'	=> lang('Go!')
+		);
+		$tpl->set_var($var);
+		$tpl->set_var('str',$tpl->fp('out','form_button_dropdown'));
+		$tpl->parse('header_column','head_col',True);
+
+		if($GLOBALS['HTTP_GET_VARS']['menuaction'] == 'calendar.uicalendar.planner')
+		{
+			$remainder -= 28;
+			print_debug('Sort By',$this->bo->sortby);
+
+			$form_options = '<option value="user"'.($this->bo->sortby=='user'?' selected':'').'>'.lang('User').'</option>'."\n";
+			$form_options .= '     <option value="category"'.((!isset($this->bo->sortby) || !$this->bo->sortby) || $this->bo->sortby=='category'?' selected':'').'>'.lang('Category').'</option>'."\n";
+		
+			$var = Array(
+				'form_width' => '28',
+				'form_link'	=> $this->page($referrer),
+				'form_name'	=> 'sortby',
+				'title'	=> lang('Sort By'),
+				'hidden_vars'	=> $base_hidden_vars,
+				'form_options'	=> $form_options,
+				'button_value'	=> lang('Go!')
+			);
+			$tpl->set_var($var);
+			$tpl->set_var('str',$tpl->fp('out','form_button_dropdown'));
+			$tpl->parse('header_column','head_col',True);
+		}
+
+		if($this->bo->check_perms(PHPGW_ACL_PRIVATE))
+		{
+			$remainder -= 28;
+			$form_options = '<option value=" all "'.($this->bo->filter==' all '?' selected':'').'>'.lang('All').'</option>'."\n";
+			$form_options .= '     <option value=" private "'.((!isset($this->bo->filter) || !$this->bo->filter) || $this->bo->filter==' private '?' selected':'').'>'.lang('Private Only').'</option>'."\n";
+		
+			$var = Array(
+				'form_width' => '28',
+				'form_link'	=> $this->page($referrer),
+				'form_name'	=> 'filter',
+				'title'	=> lang('Filter'),
+				'hidden_vars'	=> $base_hidden_vars,
+				'form_options'	=> $form_options,
+				'button_value'	=> lang('Go!')
+			);
+			$tpl->set_var($var);
+			$tpl->set_var('str',$tpl->fp('out','form_button_dropdown'));
+			$tpl->parse('header_column','head_col',True);
+		}
+
+		if((!isset($GLOBALS['phpgw_info']['server']['deny_user_grants_access']) || !$GLOBALS['phpgw_info']['server']['deny_user_grants_access']) && count($this->bo->grants) > 0)
+		{
+			$form_options = '';
+			$drop_down = $this->bo->list_cals();
+			foreach($drop_down as $key => $grant)
+			{
+				$form_options .= '    <option value="'.$grant['value'].'"'.($grant['grantor']==$this->bo->owner?' selected':'').'>'.$grant['name'].'</option>'."\n";
+			}
+		
+			$var = Array(
+				'form_width' => $remainder,
+				'form_link'	=> $this->page($referrer),
+				'form_name'	=> 'owner',
+				'title'	=> lang('User'),
+				'hidden_vars'	=> $base_hidden_vars,
+				'form_options'	=> $form_options,
+				'button_value'	=> lang('Go!')
+			);
+			$tpl->set_var($var);
+			$tpl->set_var('str',$tpl->fp('out','form_button_dropdown'));
+			$tpl->parse('header_column','head_col',True);
+		}
+	}
+
+	$hidden_vars = '    <input type="hidden" name="from" value="'.$GLOBALS['HTTP_GET_VARS']['menuaction'].'">'."\n";
+	if(isset($GLOBALS['HTTP_GET_VARS']['date']) && $GLOBALS['HTTP_GET_VARS']['date'])
+	{
+		$hidden_vars .= '    <input type="hidden" name="date" value="'.$GLOBALS['HTTP_GET_VARS']['date'].'">'."\n";
+	}
+	$hidden_vars .= '    <input type="hidden" name="month" value="'.$this->bo->month.'">'."\n";
+	$hidden_vars .= '    <input type="hidden" name="day" value="'.$this->bo->day.'">'."\n";
+	$hidden_vars .= '    <input type="hidden" name="year" value="'.$this->bo->year.'">'."\n";
+	if(isset($this->bo->filter) && $this->bo->filter)
+	{
+		$hidden_vars .= '    <input type="hidden" name="filter" value="'.$this->bo->filter.'">'."\n";
+	}
+	if(isset($this->bo->sortby) && $this->bo->sortby)
+	{
+		$hidden_vars .= '    <input type="hidden" name="sortby" value="'.$this->bo->sortby.'">'."\n";
+	}
+	if(isset($this->bo->num_months) && $this->bo->num_months)
+	{
+		$hidden_vars .= '    <input type="hidden" name="num_months" value="'.$this->bo->num_months.'">'."\n";
+	}
+	$hidden_vars .= '    <input name="keywords"'.($GLOBALS['HTTP_POST_VARS']['keywords']?' value="'.$GLOBALS['HTTP_POST_VARS']['keywords'].'"':'').'>';
+
+	$var = Array(
+		'action_url_button'	=> $this->page('search'),
+		'action_text_button'	=> lang('Search'),
+		'action_confirm_button'	=> '',
+		'action_extra_field'	=> $hidden_vars
+	);
+	$tpl->set_var($var);
+	$button = $tpl->fp('out','form_button');
+	$tpl->set_var('str','<td align="right" valign="bottom">'.$button.'</td>');
+	$tpl->parse('header_column','head_col',True);
+	$tpl->parse('row','head_table',True);
+?>
Index: /tags/calendar/0.9.3/templates/default/holiday.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/holiday.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/holiday.tpl	(revision 2)
@@ -0,0 +1,33 @@
+<!-- BEGIN form -->
+<center>
+{message}<br>
+<table border="0" width="80%" cellspacing="2" cellpadding="2"> 
+ <form name="form" action="{actionurl}" method="POST">
+  {hidden_vars}
+{rows}
+ <tr>
+  <td colspan="2">
+   <table width="100%" border="0" cellspacing="5">
+    <tr>
+     <td>
+      <input type="submit" name="submit" value="{lang_add}"></form>
+     </td>
+     <td>
+      {cancel_button}
+     </td>
+     <td align="right" width="80%">
+      {delete_button}
+     </td>
+    </tr>
+   </table>
+  <td>
+ </tr>
+</table>
+</center>
+<!-- END form -->
+<!-- BEGIN list -->
+ <tr bgcolor="{tr_color}">
+  <td valign="top" width="35%"><b>{field}:</b></td>
+  <td valign="top" width="65%">{data}</td>
+ </tr>
+<!-- END list -->
Index: /tags/calendar/0.9.3/templates/default/alarm.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/alarm.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/alarm.tpl	(revision 2)
@@ -0,0 +1,62 @@
+<!-- BEGIN alarm_management -->
+<form id="calendar_alarmform" action="{action_url}" method="post" name="alarmform">
+{hidden_vars}
+	<table id="calendar_alarmform_table" border="0" width="90%" align="center">
+		{rows}
+		<tr>
+			<td colspan="4">
+				<br>&nbsp;{input_days}&nbsp;{input_hours}&nbsp;{input_minutes}&nbsp;{input_owner}&nbsp;{input_add}<br>&nbsp;
+			</td>
+			<td align="right">
+				{input_cancel}
+			</td>
+		</tr>
+	</table>
+</form>
+<!-- END alarm_management -->
+
+<!-- BEGIN alarm_headers -->
+	<tr bgcolor="{tr_color}">
+		<th align="left" width="25%">{lang_time}</th>
+		<th align="left" width="30%">{lang_text}</th>
+		<th align="left" width="25%">{lang_owner}</th>
+		<th width="10%">{lang_enabled}</th>
+		<th width="10%">{lang_select}</th>
+	</tr>
+<!-- END alarm_headers -->
+
+<!-- BEGIN list -->
+	<tr bgcolor="{tr_color}">
+		<td>
+			<b>{field}:</b>
+		</td>
+		<td>
+			{data}
+		</td>
+		<td>
+			{owner}
+		</td>
+		<td align="center">
+			{enabled}
+		</td>
+		<td align="center">
+			{select}
+		</td>
+	</tr>
+<!-- END list -->
+
+<!-- BEGIN hr -->
+	<tr bgcolor="{th_bg}">
+		<td colspan="5" align="center">
+			<b>{hr_text}</b>
+		</td>
+	</tr>
+<!-- END hr -->
+
+<!-- BEGIN buttons -->
+	<tr>
+		<td colspan="6" align="right">
+			{enable_button}&nbsp;{disable_button}&nbsp;{delete_button}
+		</td>
+	</tr>
+<!-- END buttons -->
Index: /tags/calendar/0.9.3/templates/default/pref.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/pref.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/pref.tpl	(revision 2)
@@ -0,0 +1,22 @@
+<!-- BEGIN pref -->
+<p><b>{title}:</b><hr><p>
+<form action="{action_url}" method="POST">
+ <table border="0" align="center" width="90%">
+  {row}
+ </table>
+ <center><input type="submit" name="submit" value="{submit_lang}"></center>
+</form>
+<!-- END pref -->
+
+<!-- BEGIN pref_colspan -->
+  <tr bgcolor="{bg_color}">
+   <td colspan="2">{text}</td>
+  </tr>
+<!-- END pref_colspan -->
+
+<!-- BEGIN pref_list -->
+  <tr bgcolor="{bg_color}">
+   <td align="right">{field}</td>
+   <td align="center">{data}</td>
+  </tr>
+<!-- END pref_list -->
Index: /tags/calendar/0.9.3/templates/default/month_header.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/month_header.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/month_header.tpl	(revision 2)
@@ -0,0 +1,13 @@
+
+<!-- BEGIN monthly_header -->
+<tr class="calendar_m_w_table_header" colspan="{cols}" width="{col_width}%">
+{column_header}</tr>
+<!-- END monthly_header -->
+
+<!-- BEGIN column_title -->
+<th class="calendar_weekview_daytitle" width="14.28%">{col_title}</th>
+<!-- END column_title -->
+
+<!-- BEGIN month_column -->
+<td class="calendar_m_w_tablecell" colspan="1" width="{col_width}%"{extra}>{column_data}</td>
+<!-- END month_column -->
Index: /tags/calendar/0.9.3/templates/default/month_day_print.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/month_day_print.tpl	(revision 360)
+++ /tags/calendar/0.9.3/templates/default/month_day_print.tpl	(revision 360)
@@ -0,0 +1,26 @@
+
+<!-- BEGIN m_w_table -->
+
+<table id="calendar_m_w_table" class="calendar_m_w_table" border="0" width="100%">
+	<!-- from month_header.tpl -->
+	{row}
+</table>
+<!-- END m_w_table -->
+
+
+<table>
+<!-- BEGIN month_daily -->
+<tr><td style="font-size: 13px; font-weight: bold; text-decoration: underline;" width="10px">{day_number}</td>
+<td>{daily_events}</td>
+<!-- END month_daily -->
+
+<!-- BEGIN day_event -->
+
+<td>{events}</td>
+<!-- END day_event -->
+
+<!-- BEGIN event -->
+<td>{day_events}</td></tr>
+<!-- END event -->
+<br />
+</table>
Index: /tags/calendar/0.9.3/templates/default/footer.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/footer.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/footer.tpl	(revision 2)
@@ -0,0 +1,30 @@
+<!-- BEGIN footer_table -->
+       <hr clear="all">
+       <font size="-1">
+       <table border="0" width="100%" cellpadding="0" cellspacing="0">
+        <tr>
+{table_row}
+	</tr>
+       </table>
+<!-- END footer_table -->
+<!-- BEGIN footer_row -->
+         <td valign="top" width="33%">
+          <font size="-1">
+           <form action="{action_url}" method="post" name="{form_name}">
+            <B>{label}:</B>
+			{hidden_vars}
+            <select name="{form_label}" onchange="{form_onchange}">
+	     {row}
+	    </select>
+            <noscript><input type="submit" value="{go}"></noscript>
+	   </form>
+	  </font>
+	 </td>
+<!-- END footer_row -->
+<!-- BEGIN blank_row -->
+         <td>
+          {b_row}
+         </td>
+<!-- END blank_row -->
+
+
Index: /tags/calendar/0.9.3/templates/default/custom_fields.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/custom_fields.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/custom_fields.tpl	(revision 2)
@@ -0,0 +1,45 @@
+<!-- BEGIN custom_fields -->
+{lang_error}<br>
+<form action="{action_url}" method="post">
+ {hidden_vars}
+ <center>
+  <table border="0" width="90%">
+   <tr class="th">
+    <th align="left" width="30%">{lang_name}</th>
+    <th>{lang_length}</th>
+    <th>{lang_shown}</th>
+    <th>{lang_order}</th>
+    <th>{lang_title}</th>
+    <th>{lang_disabled}</th>
+    <th>&nbsp;</th>
+   </tr>
+   {rows}
+   <tr class="th">
+    <td>{name}</td>
+    <td align="center">{length}</td>
+    <td align="center">{shown}</td>
+    <td align="center">{order}</td>
+    <td align="center">{title}</td>
+    <td align="center">{disabled}</td>
+    <td align="center">{button}</td>
+   </tr>
+   <tr>
+    <td>{save_button} &nbsp; {cancel_button}</td>
+   </tr>
+  </table>
+ </center>
+</form>
+<br>
+<!-- END custom_fields -->
+
+<!-- BEGIN row -->
+   <tr bgcolor="{tr_color}">
+    <td>{name}</td>
+    <td align="center">{length}</td>
+    <td align="center">{shown}</td>
+    <td align="center">{order}</td>
+    <td align="center">{title}</td>
+    <td align="center">{disabled}</td>
+    <td align="center">{button}</td>
+   </tr>
+<!-- END row -->
Index: /tags/calendar/0.9.3/templates/default/search.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/search.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/search.tpl	(revision 2)
@@ -0,0 +1,29 @@
+<!-- BEGIN search -->
+<table id="calendar_search_table" width="90%">
+	<tr>
+		<td colspan="2" align="center" bgcolor="{th_bg}">
+			<b>{quantity}</b>
+		</td>
+	</tr>
+	{rows}
+</table>
+<!-- END search -->
+
+<!-- BEGIN search_list_header -->
+
+<!-- END search_list_header -->
+
+<!-- BEGIN search_list -->
+	<tr bgcolor="{tr_color}">
+		<td width="20%">
+			&nbsp;{date}
+		</td>
+		<td>
+			{link}
+		</td>
+	</tr>
+<!-- END search_list -->
+
+<!-- BEGIN search_list_footer -->
+
+<!-- END search_list_footer -->
Index: /tags/calendar/0.9.3/templates/default/overlap.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/overlap.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/overlap.tpl	(revision 2)
@@ -0,0 +1,30 @@
+<!-- BEGIN overlap -->
+<center><br />
+<table id="calendar_overlap_table">
+	<tr>
+		<td>
+			{overlap_text}
+		</td>
+	</tr>
+	<tr>
+		<td>
+			<ul>{overlap_list}</ul>
+		</td>
+	</tr>
+	<tr>
+		<td>
+			<table id="calendar_overlap_table2" cellspacing="5">
+				<tr>
+					<td>
+						{resubmit_button}
+					</td>
+					<td>
+						{reedit_button}
+					</td>
+				</tr>
+			</table>
+		</td>
+	</tr>
+</table>
+</center>
+<!-- END overlap -->
Index: /tags/calendar/0.9.3/templates/default/day_list.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/day_list.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/day_list.tpl	(revision 2)
@@ -0,0 +1,28 @@
+<!-- BEGIN day -->
+<div class="event-off">
+<table border="0" width="100%" cellpadding="0">
+	<tr>
+		<td class="event-on">
+{row}
+		</td>
+	</tr>
+</table>
+</div>
+<!-- END day -->
+<!-- BEGIN day_row -->
+    <font style="font-size: 8pt;">{event}</font>
+<!-- END day_row -->
+<!-- BEGIN day_event_on -->
+	<font class="event-on">{event}</font>
+<!-- END day_event_on -->
+<!-- BEGIN day_event_off -->
+	<font class="event-on">{event}</font>
+<!-- END day_event_off -->
+<!-- BEGIN day_event_holiday -->
+	{event}
+<!-- END day_event_holiday -->
+<!-- BEGIN day_time -->
+	{time}
+     <!--<td class="time" nowrap>{open_link}{time}{close_link}</td>-->
+<!-- END day_time -->
+
Index: /tags/calendar/0.9.3/templates/default/app.css
===================================================================
--- /tags/calendar/0.9.3/templates/default/app.css	(revision 360)
+++ /tags/calendar/0.9.3/templates/default/app.css	(revision 360)
@@ -0,0 +1,292 @@
+/* CSS Document */
+.calendar_print_main {
+	text-align:center;
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-size: 8px;
+	color: #000066;
+	background-color: #F7F7F7;
+/*	border: 1px solid #CCCCCC;*/
+	margin: 5px;
+	padding: 5px;
+	height: 116px;
+	width: 480px;
+}
+
+.button
+{
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-size: 14px;
+	color: #006699;
+	background-color: #D4D0C8;
+	border: 2px solid #666666;
+}
+.to_continue
+{
+	font-size: 9px;
+}
+
+A.minicalendar 
+{ 
+	color: #000000; 
+	font-size: 9px;
+	
+}
+
+A.bminicalendar 
+{ 
+	color: #336699; 
+	font-style: italic;
+	font-weight: bold;
+	font-size: 9px; 
+}
+
+A.minicalendargrey 
+{ 
+	color: #999999; 
+	font-size: 10px;
+	font-weight: bold;
+}
+
+A.bminicalendargrey 
+{ 
+	color: #336699; 
+	font-style: italic; 
+	font-size:10px; 
+}
+
+A.minicalhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #000000; 
+	font-size: 10px; 
+}
+
+A.bminicalhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #336699; 
+	font-size: 10px; 
+}
+
+A.minicalgreyhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #999999; 
+	font-size: 10px; 
+}
+
+A.bminicalgreyhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #999999; 
+	font-size: 10px; 
+}
+
+
+.event-on
+{ 
+	background: #D3DCE3;
+	border: #E8F0F0 1px solid;
+}
+
+.event-off
+{ 
+	background: #E8F0F0;
+	border: #D3DCE3 1px solid;
+}
+
+.event-holiday
+{
+	font-size: 100%;
+	background: #dac0c0;
+	color:#000000;
+	vertical-align: middle;
+}
+
+.time
+{
+	background: #D3DCE3;
+	color:#000000;
+	font-size: 10px;
+	font-weight: bold;
+	vertical-align: middle;
+	width: 5.2%;
+	text-align: right;
+	padding-right: 5px;
+	line-height: 11px;
+	border: #E8F0F0 1px solid;
+}
+
+
+.planner-cell
+{
+	cursor: pointer;
+	cursor: hand;
+	border: thin solid black;
+}
+
+/* common */
+.calendar_link_print
+{
+	text-align: center;
+	font-size: 10px;
+}
+
+/*Mini Calendar*/
+
+.calendar_minical_table
+{
+	width: 180px;
+	font-weight: bold;
+}
+
+.calendar_minical_daytable
+{
+	width: 100%;
+}
+
+.calendar_minical_dayname
+{
+	font-size: 9px;
+	text-align: right;
+}
+
+.calendar_minical_hrule
+{
+	width: 96%;
+}
+
+/* Header */
+.calendar_dropbuttons
+{
+	text-align: center;
+	vertical-align: bottom;
+	font-weight: bold;
+	font-size: 8px;
+}
+
+.calendar-weekidentifier
+{
+	font-size:16px;
+	font-weight: bold;
+	text-align: center;
+}
+
+.calendar_header
+{
+	font-size: 16px;
+	font-weight: bold;
+	text-align: center;
+}
+
+.calendar_dayview_table_header
+{
+	font-size: 13px;
+	font-weight: bold;
+	text-align: center;
+}
+
+.calendar_dayview_todo_header
+{
+	margin: 0px; 
+	padding: 2px;
+	font-weight: bold;
+}
+
+/* week view */
+.calendar_week_identifier_table
+{
+	border: 0px solid black;
+	width: 100%;
+}
+
+.calendar_week_identifier
+{
+	font-size: 13px;
+	text-align: center;
+	font-weight: bold;
+}
+
+.calendar_weekview_daytitle
+{
+	font-weight: bold;
+	font-size: 12px;
+	background: #D3DCE3;
+}
+
+.calendar_m_w_table
+{
+	table-layout:fixed;
+	overflow:auto;
+	height: 100%;
+	width: 100%;
+	border: 0px #000000 solid;
+}
+
+.calendar_m_w_tablecell
+{
+	vertical-align: top;
+	padding-left: 4px;
+	padding-right: 4px;
+	padding-bottom: 6px;
+}
+
+A.event_entry
+{
+	font-size:10px;
+}
+
+/* month view */
+
+.calendar_month_identifier
+{
+	font-size:14px;
+	font-weight: bold;
+}
+
+.calendar_user_identifier
+{
+	font-size:12px;
+	color: #009999;
+	font-weight: bold;
+}
+
+.calendar_week_minical_table
+{
+	width:100%;
+	border: 0px solid #000000
+}
+
+.calendar_weekinfo
+{
+	color: #000000;
+	padding-left: 2px;
+	padding-right: 2px;
+	font-size: 10px;
+	font-weight: bold;
+	font-style: italic;
+}
+
+.calendar_index_table
+{
+	background-color: #dddddd;
+	border-bottom-style: double;
+	border-bottom-width: medium;
+
+}
+
+.calendar_index_table
+{
+	background-color: #dddddd;
+	border-bottom-style: double;
+	border-bottom-width: medium;
+
+}
Index: /tags/calendar/0.9.3/templates/default/hr.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/hr.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/hr.tpl	(revision 2)
@@ -0,0 +1,6 @@
+ <tr>
+  <td colspan="2">
+   {hr_text}
+  </td>
+ </tr>
+
Index: /tags/calendar/0.9.3/templates/default/view.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/view.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/view.tpl	(revision 2)
@@ -0,0 +1,46 @@
+
+<!-- BEGIN view_event -->
+<center>
+<table id="calendar_view_event" border="0" width="90%">
+	{row}
+	<tr>
+		<td>
+			<table id="calendar_viewevent_button_left" cellspacing="5">
+				<tr>
+					{button_left}
+				</tr>
+			</table>
+		</td>
+	   <td align="center">
+			<table id="calendar_viewevent_button_center" cellspacing="5">
+				<tr>
+					{button_center}
+				</tr>
+			</table>
+		</td>
+		<td align="right">
+			<table id="calendar_viewevent_button_right" cellspacing="5">
+				<tr>
+					{button_right}
+				</tr>
+			</table>
+		</td>
+	</tr>
+</table>
+</center>
+<!-- END view_event -->
+
+<!-- BEGIN list -->
+	<tr bgcolor="{tr_color}">
+		<td valign="top" width="30%">&nbsp;<b>{field}:</b></td>
+		<td colspan="2" valign="top" width="70%">{data}</td>
+	</tr>
+<!-- END list -->
+
+<!-- BEGIN hr -->
+	<tr>
+		<td colspan="3" bgcolor="{th_bg}" align="center">
+			<b>{hr_text}</b>
+		</td>
+	</tr>
+<!-- END hr -->
Index: /tags/calendar/0.9.3/templates/default/delete_common.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/delete_common.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/delete_common.tpl	(revision 2)
@@ -0,0 +1,16 @@
+<!-- BEGIN form -->
+ <center>
+  <table border="0" with="65%">
+   <tr>
+    <td colspan="2" align="center">
+     {messages}
+    </td>
+   </tr>
+   <tr>
+    <td align="center">{no}</td>
+    <td align="center">{yes}</td>
+   </tr>
+  </table>
+ </center>
+<!-- END form -->
+
Index: /tags/calendar/0.9.3/templates/default/list.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/list.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/list.tpl	(revision 2)
@@ -0,0 +1,6 @@
+<!-- BEGIN list -->
+ <tr>
+  <td valign="top" width="35%"><b>{field}:</b></td>
+  <td valign="top" width="65%">{data}</td>
+ </tr>
+<!-- END list -->
Index: /tags/calendar/0.9.3/templates/default/mini_cal.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/mini_cal.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/mini_cal.tpl	(revision 2)
@@ -0,0 +1,42 @@
+
+<!-- BEGIN mini_cal -->
+
+	<table id="calendar_minical_table" class="calendar_minical_table" border=0 cellspacing="0" cellpadding="0">
+		<tr>
+			<td style="padding-left: 8px; font-weight: bold; text-align: left;">
+				{month}
+			</td>
+			<td align="right">
+				<!-- why empty? -->
+				{prevmonth}&nbsp;&nbsp;{nextmonth}
+			</td>
+		</tr>
+		<tr>
+			<td  style="padding-left: 8px; text-align: left;">
+<!--				<img src="{cal_img_root}" width="90%" height="1"> -->
+					<hr class="calendar_minical_hrule">
+			</td>
+		</tr>
+		<tr valign="top">
+			<td>
+				<table id="calendar_minical_daytable" class="calendar_minical_daytable" cellspacing="5" cellpadding="0">
+					<tr>{daynames}</tr>
+						{display_monthweek}
+				</table>
+
+			</td>
+	 	</tr>
+	</table>
+<!-- END mini_cal -->
+
+<!-- BEGIN mini_week -->
+	<tr>
+		{monthweek_day}
+	</tr>
+<!-- END mini_week -->
+
+<!-- BEGIN mini_day -->
+		<td class="calendar_minical_dayname" {day_image}>
+			{dayname}
+		</td>
+<!-- END mini_day -->
Index: /tags/calendar/0.9.3/templates/default/link_pict.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/link_pict.tpl	(revision 136)
+++ /tags/calendar/0.9.3/templates/default/link_pict.tpl	(revision 136)
@@ -0,0 +1,25 @@
+
+<!-- BEGIN link_pict -->
+{picture}
+<!-- END link_pict -->
+
+<!-- BEGIN link_open -->
+<div id="calendar_event_entry" style="overflow:hidden;">
+<a class="event_entry" href="{link_link}" onMouseOver="window.status='{lang_view}'; return true;" onMouseOut="window.status=''; return true;" title="{desc} {location}"><br>
+<!-- END link_open -->
+
+<!-- BEGIN pict -->
+ <img src="{pic_image}" width="{width}" height="{height}" title="{title}" border="0" />
+<!-- END pict -->
+
+<!-- BEGIN link_text_old -->
+<nobr>&nbsp;{time}&nbsp;</nobr> {title}&nbsp;{users_status}: <i>{desc}</i><!--({location})-->
+<!-- END link_text_old -->
+
+<!-- BEGIN link_text -->
+&nbsp;<FONT SIZE=1><span style="color: black">{time}</span> {users_status}<br><b>{title}</b><br><i>{desc}</i> {location}
+<!-- END link_text -->
+
+<!-- BEGIN link_close -->
+</a></div>
+<!-- END link_close -->
Index: /tags/calendar/0.9.3/templates/default/day.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/day.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/day.tpl	(revision 2)
@@ -0,0 +1,46 @@
+<!-- BEGIN day -->
+{printer_friendly}
+<table id="calendar_dayview_table" class="calendar_dayview_table" border="0" width="100%">
+	<tr>
+		<td valign="top" width="70%">
+			<table id="calendar_dayview1" border="0" width=100%>
+				<tr>
+					<td class="calendar_dayview_table_header">
+      					{date}&nbsp;<span class="calendar_user_identifier">:&nbsp;{username}&nbsp;:</span>
+						<br />
+     				</td>
+    			</tr>
+				{day_events}
+   			</table>
+   			<p align="center">{print}</p>
+  		</td>
+ 		 <td align="center" valign="top">
+  			 <table id="calendar_dayview2" width="100%">
+    			<tr>
+     				<td align="center">
+						{small_calendar}
+     				</td>
+    			</tr>
+    			<tr>
+     				<td align="center">
+      					<div class="th">
+       						<p class="calendar_dayview_todo_header">{lang_todos}</p>
+								{todos}
+      					</div>
+     				</td>
+    			</tr>
+   			</table>
+  		</td>
+ 	</tr>
+</table>
+<!-- END day -->
+
+<!-- BEGIN day_event -->
+	<tr>
+		<td>
+
+			{daily_events}
+
+		</td>
+	</tr>
+<!-- END day_event -->
Index: /tags/calendar/0.9.3/templates/default/vcal_import.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/vcal_import.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/vcal_import.tpl	(revision 2)
@@ -0,0 +1,10 @@
+<!-- vcardin form -->
+{vcal_header}
+    <form ENCTYPE="multipart/form-data" method="POST" action="{action_url}">
+      <table border=0>
+      <tr>
+       <td>{ical_lang}: <input type="file" name="uploadedfile"></td>
+       <td><input type="submit" name="action" value="{load_vcal}"></td>
+      </tr>
+      </table>
+     </form>
Index: /tags/calendar/0.9.3/templates/default/month_day.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/month_day.tpl	(revision 360)
+++ /tags/calendar/0.9.3/templates/default/month_day.tpl	(revision 360)
@@ -0,0 +1,21 @@
+
+<!-- BEGIN m_w_table -->
+
+<table id="calendar_m_w_table" class="calendar_m_w_table">
+	<!-- from month_header.tpl -->
+	{row}
+</table>
+<!-- END m_w_table -->
+
+<!-- BEGIN month_daily -->
+<span id="calendar_m_w_table_daynumber" style="font-size:10px">[ {day_number} ]</span>{new_event_link}<br />
+    {daily_events}
+<!-- END month_daily -->
+
+<!-- BEGIN day_event -->
+{events}
+<!-- END day_event -->
+
+<!-- BEGIN event -->
+{day_events}
+<!-- END event -->
Index: /tags/calendar/0.9.3/templates/default/preference_acl_row.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/preference_acl_row.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/preference_acl_row.tpl	(revision 2)
@@ -0,0 +1,8 @@
+   <tr bgcolor="{row_color}">
+    <td>{user}</td>
+    <td align="center"><input type="checkbox" name="{read}" value="Y"{read_selected}></td>
+    <td align="center"><input type="checkbox" name="{add}" value="Y"{add_selected}></td>
+    <td align="center"><input type="checkbox" name="{edit}" value="Y"{edit_selected}></td>
+    <td align="center"><input type="checkbox" name="{delete}" value="Y"{delete_selected}></td>
+    <td align="center"><input type="checkbox" name="{private}" value="Y"{private_selected}></td>
+   </tr>
Index: /tags/calendar/0.9.3/templates/default/edit.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/edit.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/edit.tpl	(revision 2)
@@ -0,0 +1,49 @@
+<!-- BEGIN edit_entry -->
+<script language="JavaScript">
+	self.name="first_Window";
+	function accounts_popup()
+	{
+		Window1=window.open('{accounts_link}',"Search","width=800,height=600,toolbar=no,scrollbars=yes,resizable=yes");
+	}
+</script>
+<center>
+<font color="#000000" face="{font}">
+
+<form action="{action_url}" method="post" name="app_form">
+{common_hidden}
+<table border="0" width="90%">
+ <tr>
+  <td colspan="2">
+   <center><font size="+1"><b>{errormsg}</b></font></center>
+  </td>
+ </tr>
+{row}
+ <tr>
+  <td>
+  <table><tr valign="top">
+  <td>
+  <div style="padding-top:15px; padding-right: 2px">
+  	<input style="font-size:10px" type="submit" value="{submit_button}" onClick="javascript:submitValues()"></div></form>
+  </td>
+  <td>{cancel_button}</td>
+  </tr></table>
+  </td>
+  <td align="right">{delete_button}</td>
+ </tr>
+</table>
+</font>
+</center>
+<!-- END edit_entry -->
+<!-- BEGIN list -->
+ <tr bgcolor="{tr_color}">
+  <td valign="top" width="25%">&nbsp;<b>{field}:</b></td>
+  <td valign="top" width="75%">{data}</td>
+ </tr>
+<!-- END list -->
+<!-- BEGIN hr -->
+ <tr bgcolor="{tr_color}">
+  <td colspan="2">
+   {hr_text}
+  </td>
+ </tr>
+<!-- END hr -->
Index: /tags/calendar/0.9.3/templates/default/matrix_query.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/matrix_query.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/matrix_query.tpl	(revision 2)
@@ -0,0 +1,25 @@
+<!-- BEGIN matrix_query -->
+<center>
+<form action="{action_url}" method="post" name="matrixform">
+<table border="0" width="90%">
+ <tr bgcolor="{th_bg}">
+  <td colspan="2" align="center"><b>{title}</b></td>
+ </tr>
+ {rows}
+ <tr>
+  <td>
+   <table cellspacing="5"><tr>
+    <td><input type="submit" value="{submit_button}"></form></td>
+    <td>{cancel_button}</td>
+   </tr></table>
+  </td>
+ </tr>
+</table>
+</center>
+<!-- END matrix_query -->
+<!-- BEGIN list -->
+ <tr bgcolor="{tr_color}">
+  <td valign="top" width="35%"><b>&nbsp;{field}:</b></td>
+  <td valign="top" width="65%">{data}</td>
+ </tr>
+<!-- END list -->
Index: /tags/calendar/0.9.3/templates/default/week.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/week.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/week.tpl	(revision 2)
@@ -0,0 +1,5 @@
+
+{printer_friendly}
+
+<!-- from month_day.tpl -->
+{week_display}
Index: /tags/calendar/0.9.3/templates/default/day_cal.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/day_cal.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/day_cal.tpl	(revision 2)
@@ -0,0 +1,24 @@
+<!-- BEGIN day -->
+<div class="th">
+ <table class="calendar_dayview_maintable" width="100%" cellpadding="0">
+{row}
+</table>
+ </div>
+<!-- END day -->
+<!-- BEGIN day_row -->
+    <tr>{time}{event}
+    </tr>
+<!-- END day_row -->
+<!-- BEGIN day_event_on -->
+     <td class="event-on"{extras}>&nbsp;{event}</td>
+<!-- END day_event_on -->
+<!-- BEGIN day_event_off -->
+     <td class="event-off"{extras}>&nbsp;{event}</td>
+<!-- END day_event_off -->
+<!-- BEGIN day_event_holiday -->
+     <td class="event-holiday"{extras}>&nbsp;{event}</td>
+<!-- END day_event_holiday -->
+<!-- BEGIN day_time -->
+     <td class="time" nowrap>{open_link}{time}{close_link}</td>
+<!-- END day_time -->
+
Index: /tags/calendar/0.9.3/templates/default/preference_acl.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/preference_acl.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/preference_acl.tpl	(revision 2)
@@ -0,0 +1,27 @@
+{errors}
+{title}
+<table border="0" align="center" width="70%">
+ <tr>
+  {nml}
+  <td width="40%">
+   <div align="center">
+    <form method="POST" action="{action_url}">
+{common_hidden_vars}
+     <input type="text" name="query" value="{search_value}">
+     <input type="submit" name="search" value="{search}">
+    </form>
+   </div>
+  </td>
+  {nmr}
+ </tr>
+</table>
+<form method="POST" action="{action_url}">
+ <table border="0" align="center" width="50%" cols="4">
+{row}
+ </table>
+{common_hidden_vars_form}
+ <input type="hidden" name="processed" value="{processed}">
+ <center><input type="submit" name="submit" value="{submit_lang}"></center>
+</form>
+
+
Index: /tags/calendar/0.9.3/templates/default/preference_colspan.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/preference_colspan.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/preference_colspan.tpl	(revision 2)
@@ -0,0 +1,8 @@
+  <tr bgcolor="{bg_color}">
+    <td>{string}</td>
+    <td align="center">{lang_read}</td>
+    <td align="center">{lang_add}</td>
+    <td align="center">{lang_edit}</td>
+    <td align="center">{lang_delete}</td>
+    <td align="center">{lang_private}</td>
+  </tr>
Index: /tags/calendar/0.9.3/templates/default/event_link.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/event_link.tpl	(revision 360)
+++ /tags/calendar/0.9.3/templates/default/event_link.tpl	(revision 360)
@@ -0,0 +1,41 @@
+
+<!-- BEGIN link_event_pict -->
+{picture}
+<!-- END link_event_pict -->
+
+<!-- BEGIN link_event_open -->
+<table>
+
+<!--<div id="calendar_event_entry" style="overflow:hidden;">-->
+<!--<a class="event_entry" href="{link_link}" onMouseOver="window.status='{lang_view}'; return true;" onMouseOut="window.status=''; return true;" title="{desc} {location}"><br />--><br />
+<!-- END link_event_open -->
+
+<!-- BEGIN event_pict -->
+<!--<img src="{pic_image}" width="{width}" height="{height}" title="{title}" border="0" />-->
+<!-- END event_pict -->
+
+<!-- BEGIN link_event_text_old -->
+<!--<nobr>&nbsp;{time}&nbsp;</nobr> {title}&nbsp;{users_status}: <i>{desc}</i>({location}) -->
+<!-- END link_event_text_old -->
+
+<!-- BEGIN link_event_text -->
+	<tr style="font-size: 14px;background: #dddddd;">
+		<td valign="top" style="color: black; font-size: 13px;">
+			<span>
+				{time}
+			</span>
+		</td>
+		<td style="font-size: 14px; border: #E8F0F0 1px solid;" colspan="3">
+			<span><b>{title}</b></span>
+			<br />
+			<span><i>{desc}</i></span>
+			<span>{location}</span>
+			<br />
+		</td>
+	</tr>
+<!-- END link_event_text -->
+
+<!-- BEGIN link_event_close -->
+<!--</a></div><br />-->
+</table>
+<!-- END link_event_close -->
Index: /tags/calendar/0.9.3/templates/default/year.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/year.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/year.tpl	(revision 2)
@@ -0,0 +1,35 @@
+<!-- BEGIN year -->
+{print}
+<center>
+<table id="calendar_year_table" border="0" cellspacing="3" cellpadding="4" cols=4>
+	<tr>
+		<td align="center">
+			{left_link}
+		</td>
+		<td align="center">
+			<font face="{font}" size="+1">{year_text}</font>
+		</td>
+		<td align="center">
+			{right_link}
+		</td>
+		{row}
+	</tr>
+</table>
+</center>
+<p>
+<div class="calendar_link_print">
+{printer_friendly}
+</div>
+<!-- END year -->
+
+<!-- BEGIN month -->
+<td valign="top">
+	{mini_month}
+</td>
+<!-- END month -->
+
+<!-- BEGIN month_sep -->
+</tr>
+<tr valign="top">
+<!-- END month_sep -->
+
Index: /tags/calendar/0.9.3/templates/default/head.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/head.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/head.tpl	(revision 2)
@@ -0,0 +1,16 @@
+
+<!-- BEGIN head -->
+{row}<br />
+<!-- END head -->
+
+<!-- BEGIN head_table -->
+<table id="calendar_head_table" class="calendar_head_table" border="0" width="100%" cols="{cols}" cellpadding="0" cellspacing="0">
+	<tr>
+		{header_column}
+	</tr>
+</table>
+<!-- END head_table -->
+
+<!-- BEGIN head_col -->
+{str}
+<!-- END head_col -->
Index: /tags/calendar/0.9.3/templates/default/month_print.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/month_print.tpl	(revision 360)
+++ /tags/calendar/0.9.3/templates/default/month_print.tpl	(revision 360)
@@ -0,0 +1,27 @@
+{printer_friendly}
+<table class="calendar_index_table" id="calendar_index_table"  width="100%" cols="5">
+	<tr>
+		<td align="left" width="33%">
+			<span class="calendar_user_identifier">
+					{username}
+			</span>
+		</td>
+		<td align="center" width="33%">
+			<span class="calendar_month_identifier">
+				{month_identifier}
+			</span>
+		</td>
+		<td align="right" style="width: 33%; font-size: 14px;">
+			<span class="calendar_user_identifier">
+				<p>Agenda de Eventos</p>
+			</span>
+		</td>
+	</tr>
+</table>
+{large_month}
+{teste}
+<p>
+<p>
+<div class="calendar_link_print">
+	{print}
+</div>
Index: /tags/calendar/0.9.3/templates/default/month_column.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/month_column.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/month_column.tpl	(revision 2)
@@ -0,0 +1,4 @@
+
+<td valign="top" colspan="1" width="{col_width}%"{extra}>
+	{column_data}
+</td>
Index: /tags/calendar/0.9.3/templates/default/body_email.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/body_email.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/body_email.tpl	(revision 2)
@@ -0,0 +1,27 @@
+<table boder='0' cellpading='0' cellspacing='0' width='100%'>
+<tr>
+			<td width='15%' valign='top'><b>{var1} ::</b></td>
+			<td>{vardata1}</td>
+</tr>	
+<tr>
+			<td width='15%' valign='top'><b>{var2} ::</b></td>
+			<td>{vardata2}</td>
+</tr>
+			<tr>
+			<td width='15%' valign='top'><b>{var3} ::</b></td>
+			<td>{vardata3}</td>
+</tr>
+<tr>
+			<td width='15%' valign='top'><b>{var4} ::</b></td>
+			<td>{vardata4}</td>
+</tr>
+<tr>
+			<td width='15%' valign='top'><b>$var5 ::</b></td>
+			<td>{vardata6}</td>
+</tr>
+<tr>
+		<td>
+			{vardata7}
+		</td>
+</tr>
+</table>
Index: /tags/calendar/0.9.3/templates/default/config.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/config.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/config.tpl	(revision 2)
@@ -0,0 +1,51 @@
+<!-- BEGIN header -->
+<form method="POST" action="{action_url}">
+<table border="0" align="center">
+   <tr bgcolor="{th_bg}">
+    <td colspan="2"><font color="{th_text}">&nbsp;<b>{title}</b></font></td>
+   </tr>
+<!-- END header -->
+
+<!-- BEGIN body -->
+   <tr bgcolor="{row_on}">
+    <td colspan="2">&nbsp;</td>
+   </tr>
+
+   <tr bgcolor="{row_off}">
+    <td colspan="2"><b>{lang_Calendar_settings}</b></td>
+   </tr>
+   <tr bgcolor="{row_on}">
+    <td>{lang_Do_you_wish_to_autoload_calendar_holidays_files_dynamically?}</td>
+    <td>
+     <select name="newsettings[auto_load_holidays]">
+      <option value=""{selected_auto_load_holidays_False}>{lang_No}</option>
+      <option value="True"{selected_auto_load_holidays_True}>{lang_Yes}</option>
+     </select>
+    </td>
+   </tr>
+   <tr bgcolor="{row_off}">
+    <td>{lang_Location_to_autoload_from}:</td>
+    <td>
+     <select name="newsettings[holidays_url_path]">
+      <option value="localhost"{selected_holidays_url_path_localhost}>localhost</option>
+      <option value="http://www.phpgroupware.org/cal"{selected_holidays_url_path_http://www.phpgroupware.org/cal}>www.phpgroupware.org</option>
+     </select>
+    </td>
+   </tr>
+<!-- END body -->
+
+<!-- BEGIN footer -->
+  <tr bgcolor="{th_bg}">
+    <td colspan="2">
+&nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td colspan="2" align="center">
+      <input type="submit" name="submit" value="{lang_submit}">
+      <input type="submit" name="cancel" value="{lang_cancel}">
+    </td>
+  </tr>
+</table>
+</form>
+<!-- END footer -->
Index: /tags/calendar/0.9.3/templates/default/index.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/index.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/default/index.tpl	(revision 2)
@@ -0,0 +1,32 @@
+{printer_friendly}
+<table id="calendar_index_table" border="0" width="100%" cols="5">
+	<tr>
+		<td align="left" valign="top" width="20%">
+			{small_calendar_prev}
+		</td>
+		<td align="center" valign="middle" width="15%">
+			<b>{prev_month_link}</b>
+		</td>
+		<td align="center" width="30%">
+			<span class="calendar_month_identifier">
+				{month_identifier}
+			</span>
+				<br />
+			<span class="calendar_user_identifier">
+				:&nbsp;{username}&nbsp;:
+			</span>
+		</td>
+		<td align="center" valign="middle" width="15%">
+			{next_month_link}
+		</td>
+		<td align="right" valign="top" width="20%">
+			{small_calendar_next}
+		</td>
+	</tr>
+</table>
+{large_month}
+<p>
+<p>
+<div class="calendar_link_print">
+	{print}
+</div>
Index: /tags/calendar/0.9.3/templates/default/month_header_print.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/month_header_print.tpl	(revision 360)
+++ /tags/calendar/0.9.3/templates/default/month_header_print.tpl	(revision 360)
@@ -0,0 +1,12 @@
+<!-- BEGIN monthly_header -->
+<tr class="calendar_m_w_table_header" colspan="{cols}" width="{col_width}%">
+{column_header}</tr>
+<!-- END monthly_header -->
+
+<!-- BEGIN column_title -->
+<tr bGCOLOR="#D3DCE3" width="14.28%">{col_title}</tr>
+<!-- END column_title -->
+
+<!-- BEGIN month_column -->
+<tr class="calendar_m_w_tablecell" colspan="1" width="{col_width}%"{extra}>{column_data}</tr>
+<!-- END month_column -->
Index: /tags/calendar/0.9.3/templates/default/form_button_dropdown.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/default/form_button_dropdown.tpl	(revision 663)
+++ /tags/calendar/0.9.3/templates/default/form_button_dropdown.tpl	(revision 663)
@@ -0,0 +1,13 @@
+<form action="{form_link}" method="post" name="{form_name}form">
+<td width="{form_width}%" align="center" valign="top" style="padding-top:16px">
+	<span style="font-size:10px"><b>{title}:</b>
+    {hidden_vars}    
+    <select name="{form_name}" onchange="document.{form_name}form.submit()">
+		{form_options}
+	</select>
+    <noscript>
+    	<input type="submit" value="{button_value}">
+    </noscript>
+	</span>
+</td>
+</form>
Index: /tags/calendar/0.9.3/templates/celepar/month_day.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/month_day.tpl	(revision 27)
+++ /tags/calendar/0.9.3/templates/celepar/month_day.tpl	(revision 27)
@@ -0,0 +1,21 @@
+
+<!-- BEGIN m_w_table -->
+
+<table id="calendar_m_w_table" class="calendar_m_w_table" border="0" width="100%">
+	<! from month_header.tpl -->
+	{row}
+</table>
+<!-- END m_w_table -->
+
+<!-- BEGIN month_daily -->
+<span class="screen_only">[ </span><span class="calendar_m_w_table_daynumber" >{day_number}</span><span class="screen_only"> ]</span>{new_event_link}<br />
+    {daily_events}
+<!-- END month_daily -->
+
+<!-- BEGIN day_event -->
+{events}
+<!-- END day_event -->
+
+<!-- BEGIN event -->
+{day_events}
+<!-- END event -->
Index: /tags/calendar/0.9.3/templates/celepar/app_print.css
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/app_print.css	(revision 27)
+++ /tags/calendar/0.9.3/templates/celepar/app_print.css	(revision 27)
@@ -0,0 +1,294 @@
+/* Este documento é um css somente para impressão do calendário no papel!
+O seu efeito não aparece na tela  */
+
+.calendar_print_main {
+	text-align:center;
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-size: 8px;
+	color: #000066;
+	background-color: #F7F7F7;
+	border: 1px solid #CCCCCC;
+	margin: 5px;
+	padding: 5px;
+	height: 700px;
+	width: 600px;
+}
+.button {
+	display: none;
+}
+
+
+.to_continue
+{
+	font-size: 9px;
+}
+
+A.minicalendar 
+{ 
+	color: #000000; 
+	font-size: 9px;
+	
+}
+
+A.bminicalendar 
+{ 
+	color: #336699; 
+	font-style: italic;
+	font-weight: bold;
+	font-size: 9px; 
+}
+
+A.minicalendargrey 
+{ 
+	color: #999999; 
+	font-size: 10px;
+	font-weight: bold;
+}
+
+A.bminicalendargrey 
+{ 
+	color: #336699; 
+	font-style: italic; 
+	font-size:10px; 
+}
+
+A.minicalhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #000000; 
+	font-size: 10px; 
+}
+
+A.bminicalhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #336699; 
+	font-size: 10px; 
+}
+
+A.minicalgreyhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #999999; 
+	font-size: 10px; 
+}
+
+A.bminicalgreyhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #999999; 
+	font-size: 10px; 
+}
+
+
+.event-on
+{ 
+	background: #D3DCE3;
+	border: #E8F0F0 1px solid;
+}
+
+.event-off
+{ 
+	background: #E8F0F0;
+	border: #D3DCE3 1px solid;
+}
+
+.event-holiday
+{
+	font-size: 100%;
+	background: #dac0c0;
+	color:#000000;
+	vertical-align: middle;
+}
+
+.time
+{
+	background: #D3DCE3;
+	color:#000000;
+	font-size: 10px;
+	font-weight: bold;
+	vertical-align: middle;
+	width: 5.2%;
+	text-align: right;
+	padding-right: 5px;
+	line-height: 11px;
+	border: #E8F0F0 1px solid;
+}
+
+
+.planner-cell
+{
+	cursor: pointer;
+	cursor: hand;
+	border: thin solid black;
+}
+
+/* common */
+.calendar_link_print
+{
+	text-align: center;
+	font-size: 10px;
+}
+
+//Mini Calendar
+
+.calendar_minical_table
+{
+	width: 180px;
+	font-weight: bold;
+}
+
+.calendar_minical_daytable
+{
+	width: 100%;
+}
+
+.calendar_minical_dayname
+{
+	font-size: 9px;
+	text-align: right;
+}
+
+.calendar_minical_hrule
+{
+	width: 96%;
+}
+
+/* Header */
+.calendar_dropbuttons
+{
+	align: center;
+	text-align: center;
+	vertical-align: bottom;
+	font-weight: bold;
+	font-size: 8px;
+}
+
+.calendar-weekidentifier
+{
+	font-size:16px;
+	font-weight: bold;
+	text-align: center;
+}
+
+.calendar_header
+{
+	font-size: 16px;
+	font-weight: bold;
+	text-align: center;
+}
+
+.calendar_dayview_table_header
+{
+	font-size: 13px;
+	font-weight: bold;
+	text-align: center;
+}
+
+.calendar_dayview_todo_header
+{
+	margin: 0px; 
+	padding: 2px;
+	font-weight: bold;
+}
+
+/* week view */
+.calendar_week_identifier_table
+{
+	border: 0px solid black;
+	width: 100%;
+}
+
+.calendar_week_identifier
+{
+	font-size: 13px;
+	text-align: center;
+	font-weight: bold;
+}
+
+.calendar_weekview_daytitle
+{
+	font-weight: bold;
+	font-size: 12px;
+	background: #D3DCE3;
+}
+
+.calendar_m_w_table
+{
+	table-layout:fixed;
+	overflow:hidden;
+	height: 95%;
+	width: 100%;
+	border: 0px #000000 solid;
+}
+
+.calendar_m_w_tablecell
+{
+	overflow:hidden;
+	vertical-align: top;
+	padding-left: 4px;
+	padding-right: 4px;
+	padding-bottom: 6px;
+	border: 1px solid #000000;
+}
+
+.screen_only
+{
+	display:none;
+}
+
+.calendar_m_w_table_daynumber
+{
+	font-weight: bold;
+	font-family: Arial;
+	font-size: 13px;
+	vertical-align: top;
+	background-color: #778899;
+	border: 1px solid #000000;
+	margin: 1px;
+	padding: 1px;
+}
+
+A.event_entry
+{
+	font-size:10px;
+}
+
+/* month view */
+
+.calendar_month_identifier
+{
+	font-size:18px;
+	font-weight: bold;
+}
+
+.calendar_user_identifier
+{
+	font-size:12px;
+	color: #009999;
+	font-weight: bold;
+}
+
+.calendar_week_minical_table
+{
+	width:100%;
+	border: 0px solid #000000
+}
+
+.calendar_weekinfo
+{
+	color: #000000;
+	padding-left: 2px;
+	padding-right: 2px;
+	font-size: 10px;
+	font-weight: bold;
+	font-style: italic;
+}
Index: /tags/calendar/0.9.3/templates/celepar/edit.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/edit.tpl	(revision 663)
+++ /tags/calendar/0.9.3/templates/celepar/edit.tpl	(revision 663)
@@ -0,0 +1,61 @@
+<!-- BEGIN edit_entry -->
+<style type="text/css">
+div#tipDiv {
+  position:absolute; visibility:hidden; left:0; top:0; z-index:10000;
+  background-color:#EFEFEF; border:1px solid #337;
+  width:220px; padding:3px;
+  color:#000; font-size:11px; line-height:1.2;
+  cursor: default;
+}
+</style>
+<script language="JavaScript">
+	self.name="first_Window";
+	function accounts_popup()
+	{
+		Window1=window.open('{accounts_link}',"Search","width=800,height=600,toolbar=no,scrollbars=yes,resizable=yes");
+	}
+</script>
+<center>
+<font color="#000000" face="{font}">
+
+<form action="{action_url}" method="post" name="app_form">
+{common_hidden}
+<table id="editFormTable" border="0" width="90%">
+ <tr>
+  <td colspan="2">
+   <center><font size="+1"><b id="formStatus">{errormsg}</b></font></center>
+  </td>
+ </tr>
+{row}
+ <tr>
+  <td>
+  <table><tr valign="top">
+  <td>
+  <div style="padding-top:15px; padding-right: 2px">
+  	<script language="JavaScript">
+		var alert_field = '{alert_msg}';
+	</script>
+  	<input id="submit_button" style="font-size:10px" type="submit" value="{submit_button}" onClick="return submitValues(alert_field);"></div></form>
+  </td>
+  <td>{cancel_button}</td>
+  </tr></table>
+  </td>
+  <td align="right">{delete_button}</td>
+ </tr>
+</table>
+</font>
+</center>
+<!-- END edit_entry -->
+<!-- BEGIN list -->
+ <tr bgcolor="{tr_color}">
+  <td valign="top" width="25%">&nbsp;<b>{field}:</b></td>
+  <td valign="top" width="75%">{data}</td>
+ </tr>
+<!-- END list -->
+<!-- BEGIN hr -->
+ <tr bgcolor="{tr_color}">
+  <td colspan="2">
+   {hr_text}
+  </td>
+ </tr>
+<!-- END hr -->
Index: /tags/calendar/0.9.3/templates/celepar/listUsers.php
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/listUsers.php	(revision 2)
+++ /tags/calendar/0.9.3/templates/celepar/listUsers.php	(revision 2)
@@ -0,0 +1,167 @@
+<?php			
+	
+	$GLOBALS['phpgw_info']['flags'] = array(
+		'noheader' => True,
+		'nonavbar' => True,
+		'currentapp' => 'calendar'		
+	);
+	
+	include('../../../header.inc.php');
+	include('../../../phpgwapi/templates/celepar/head.inc.php');
+
+	$owner = $GLOBALS['_GET']['owner'];
+	
+	if(!@is_object($GLOBALS['phpgw']->js))	{
+		$GLOBALS['phpgw']->js = CreateObject('phpgwapi.javascript');
+	}
+	
+	$GLOBALS['phpgw']->js->validate_file('jscode','scripts','preferences');		
+	$t = &$GLOBALS['phpgw']->template;						
+	// seta o Template
+	$t->set_file(array('addUser_t' => '../../../calendar/templates/celepar/listUsers.tpl'));
+	
+	$obj_account = CreateObject('phpgwapi.accounts',$this->bo->owner);
+
+	$post_select_organization = $_POST['select_organization'];
+	$post_select_sector = $_POST['select_sector'];
+	$change_organization = $_POST['change_organization'];
+	
+	$obj_org_sector = CreateObject('phpgwapi.sector_search_ldap');
+	if ((!$post_select_organization) && (!$post_select_sector)) //primeira vez
+	{
+		$user_org = $obj_account->get_organization($GLOBALS['phpgw_info']['user']['account_dn']);
+		$user_sector = $obj_account->get_sector($GLOBALS['phpgw_info']['user']['account_dn']);
+		$user_context = $obj_account->get_context($GLOBALS['phpgw_info']['user']['account_dn']);
+		
+		$organizations_info = $obj_org_sector->organization_search($GLOBALS['phpgw_info']['server']['ldap_context']);
+		@asort($organizations_info);
+		@reset($organizations_info);					
+		$sectors_info = $obj_org_sector->sector_search('ou='.$user_org.','.$GLOBALS['phpgw_info']['server']['ldap_context']);
+	}
+	else //mudou uma das combos
+	{
+		$user_org = $post_select_organization;
+		$user_sector = $post_select_sector;
+		if ($change_organization == "True")
+			$user_context = 'ou='.$user_org.','.$GLOBALS['phpgw_info']['server']['ldap_context'];
+		else
+			$user_context = $post_select_sector;
+		$organizations_info = $obj_org_sector->organization_search($GLOBALS['phpgw_info']['server']['ldap_context']);
+		@asort($organizations_info);
+		@reset($organizations_info);					
+		$sectors_info = $obj_org_sector->sector_search('ou='.$user_org.','.$GLOBALS['phpgw_info']['server']['ldap_context']);
+	}
+		
+	foreach($organizations_info as $organization)
+	{
+		$combo_organization .= '<option value="' . $organization . '"'; 	
+		
+		if (!$post_select_organization)
+		{
+			if(strtolower($organization) == strtolower($user_org))
+			{
+				$combo_organization .= ' selected';
+			}
+		}
+		else
+		{
+			if(strtolower($organization) == strtolower($post_select_organization))
+			{
+				$combo_organization .= ' selected';
+			}
+		}	
+		$combo_organization .= '>' .$organization.'</option>'."\n";
+	}
+	
+	$combo_sector .= '<option value="ou='.$user_org.','.$GLOBALS['phpgw_info']['server']['ldap_context'].'"> --------- </option>'."\n";
+	foreach($sectors_info as $sector)
+	{
+		if ($sector->sector_level == 1)
+		{
+			$sector->sector_name = '- '.$sector->sector_name;
+		}
+		else
+		{
+			$sector_space = '';
+			for ($i=1; $i < $sector->sector_level; $i++)
+				$sector_space = '---'.$sector_space;
+			$sector->sector_name = $sector_space.' '.$sector->sector_name;
+		}
+	
+		$combo_sector .= '<option value="' . $sector->sector_context . '"';
+
+		if (!$post_select_sector)
+		{
+			if($sector->sector_name == $user_sector)
+				$combo_sector .= ' selected';
+		}
+		else
+		{
+			if($sector->sector_context == $post_select_sector)
+				$combo_sector .= ' selected';
+		}
+		$combo_sector .= '>' .$sector->sector_name.'</option>'."\n";
+	}			
+	
+	// Monta lista de Grupos e Usuários
+	$users = Array();
+	$groups = Array();
+
+	$ds = $GLOBALS['phpgw']->common->ldapConnect();
+    if ($ds) 
+    {
+		$sr=ldap_list($ds, $user_context, ("(&(cn=*)(phpgwaccounttype=g))"));
+		$info = ldap_get_entries($ds, $sr);
+		for ($i=0; $i<$info["count"]; $i++)
+			$groups[$uids=$info[$i]["gidnumber"][0]] = Array('name'	=>	$uids=$info[$i]["cn"][0], 'type'	=>	g);
+
+		$sr=ldap_list($ds, $user_context, ("(&(cn=*)(phpgwaccounttype=u)(!(cn=lista*)))"));
+		$info = ldap_get_entries($ds, $sr);
+		for ($i=0; $i<$info["count"]; $i++)
+		{
+			if ($info[$i]["phpgwaccountvisible"][0] == '-1')
+				continue;
+			$users[$uids=$info[$i]["uidnumber"][0]] = Array('name'	=>	$uids=$info[$i]["cn"][0], 'type'	=>	u);
+		}
+	}
+	ldap_close($ds);
+    	
+	@asort($users);
+	@reset($users);	
+	@asort($groups);
+	@reset($groups);
+
+	$options ='';
+	if(count($groups))
+		$options .= '<option  value="-1" disabled>--------------------&nbsp;&nbsp;&nbsp;&nbsp;Grupos&nbsp;&nbsp;&nbsp;&nbsp;------------------- </option>'."\n";
+		
+	foreach($groups as $id => $user_array) {
+			$newId = $id.'U';
+			$options .= '<option  value="'.$newId.'">'.utf8_decode($user_array['name']).$array_app.'</option>'."\n";
+	}
+	
+	if(count($users))
+		$options .= '<option  value="-1" disabled>-------------------&nbsp;&nbsp;&nbsp;&nbsp;Usuários&nbsp;&nbsp;&nbsp;&nbsp;------------------ </option>'."\n";
+	
+	foreach($users as $id => $user_array) {
+		if($owner != $id){
+			$newId = $id.'U';
+			$options .= '<option  value="'.$newId.'">'.utf8_decode($user_array['name']).$array_app.'</option>'."\n";
+		}
+	}
+
+	$t->set_var ('lang_Organization',lang('Organization'));
+	$t->set_var ('lang_Sector',lang('Sector'));
+	$t->set_var ('lang_Calendar',lang('Calendar'));
+	$t->set_var ('lang_Add_Participants',lang('Add Participants'));
+	$t->set_var ('lang_to_Search',lang('to Search'));
+	$t->set_var ('lang_Close',lang('Close'));
+	$t->set_var ('lang_Add',lang('Add'));
+	
+	$t->set_var('options',$options);
+	$t->set_var('combo_organization', $combo_organization);
+	$t->set_var('combo_sector', $combo_sector);
+	$t->parse('out','addUser_t',true);
+	$t->p('out');
+	$GLOBALS['phpgw']->common->phpgw_exit();	
+?>
Index: /tags/calendar/0.9.3/templates/celepar/header.inc.php
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/header.inc.php	(revision 27)
+++ /tags/calendar/0.9.3/templates/celepar/header.inc.php	(revision 27)
@@ -0,0 +1,229 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare                                                               *
+  * http://www.egroupware.org                                                *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	function add_col(&$tpl,$str)
+	{
+		$tpl->set_var('str',$str);
+		$tpl->parse('header_column','head_col',True);
+	}
+
+	function add_image_ahref($link,$image,$alt)
+	{
+		return '<a href="'.$link.'"><img src="'.$GLOBALS['phpgw']->common->image('calendar',$image).'" alt="'.$alt.'" title="'.$alt.'" border="0"></a>';
+	}
+
+	$refer = explode('.',$GLOBALS['HTTP_GET_VARS']['menuaction']);
+	$referrer = $refer[2];
+
+	$templates = Array(
+		'head_tpl'	=> 'head.tpl',
+		'form_button_dropdown'	=> 'form_button_dropdown.tpl',
+		'form_button_script'	=> 'form_button_script.tpl'
+	);
+	$tpl->set_file($templates);
+	$tpl->set_block('head_tpl','head','head');
+	$tpl->set_block('head_tpl','head_table','head_table');
+	$tpl->set_block('head_tpl','head_col','head_col');
+	$tpl->set_block('form_button_script','form_button');
+
+	if(floor(phpversion()) >= 4)
+	{
+		$tpl->set_var('cols',8);
+	}
+	else
+	{
+		$tpl->set_var('cols',7);
+	}
+
+	$today = date('Ymd',$GLOBALS['phpgw']->datetime->users_localtime);
+
+	$col_width = 12;
+
+	add_col($tpl,'  <td width="2%">&nbsp;</td>');
+
+	add_col($tpl,'  <td width="2%">'.add_image_ahref($this->page('day','&date='.$today),'today',lang('Today')).'</td>');
+
+	add_col($tpl,'  <td width="2%" align="left">'.add_image_ahref($this->page('week','&date='.$today),'week',lang('This week')).'</td>');
+
+	add_col($tpl,'  <td width="2%" align="left">'.add_image_ahref($this->page('month','&date='.$today),'month',lang('This month')).'</td>');
+
+	add_col($tpl,'  <td width="2%" align="left">'.add_image_ahref($this->page('year','&date='.$today),'year',lang('This Year')).'</td>');
+
+	if(floor(phpversion()) >= 4)
+	{
+		add_col($tpl,'  <td width="2%" align="left">'.add_image_ahref($this->page('planner','&date='.$today),'planner',lang('Planner')).'</td>');
+		$col_width += 2;
+	}
+
+	//add_col($tpl,'  <td width="2%" align="left">'.add_image_ahref($this->page('matrixselect'),'view',lang('Daily Matrix View')).'</td>');
+
+	add_col($tpl,'  <td width="'.(100 - $col_width).'%" align="left"'.(floor(phpversion()) < 4?' colspan="2"':'').'>&nbsp;</td>');
+
+	$tpl->parse('row','head_table',True);
+
+	$tpl->set_var('header_column','');
+	$tpl->set_var('cols',$cols);
+
+	if($referrer!='view')
+	{
+		$remainder = 72;
+		
+		$date = (isset($GLOBALS['date'])?$GLOBALS['date']:'');
+		$date = (isset($GLOBALS['HTTP_GET_VARS']['date'])?$GLOBALS['HTTP_GET_VARS']['date']:$date);
+		$date = ($date=='' && isset($GLOBALS['HTTP_POST_VARS']['date'])?$GLOBALS['HTTP_POST_VARS']['date']:$date);
+
+		$base_hidden_vars = '<input type="hidden" name="from" value="'.$GLOBALS['HTTP_GET_VARS']['menuaction'].'">'."\n";
+		if(isset($GLOBALS['HTTP_GET_VARS']['cal_id']) && $GLOBALS['HTTP_GET_VARS']['cal_id'] != 0)
+		{
+			$base_hidden_vars .= '    <input type="hidden" name="cal_id" value="'.$GLOBALS['HTTP_GET_VARS']['cal_id'].'">'."\n";
+		}
+		if(isset($GLOBALS['HTTP_POST_VARS']['keywords']) && $GLOBALS['HTTP_POST_VARS']['keywords'])
+		{
+			$base_hidden_vars .= '    <input type="hidden" name="keywords" value="'.$GLOBALS['HTTP_POST_VARS']['keywords'].'">'."\n";
+		}
+		if(isset($GLOBALS['HTTP_POST_VARS']['matrixtype']) && $GLOBALS['HTTP_POST_VARS']['matrixtype'])
+		{
+			$base_hidden_vars .= '    <input type="hidden" name="matrixtype" value="'.$GLOBALS['HTTP_POST_VARS']['matrixtype'].'">'."\n";
+		}
+		if($date)
+		{
+			$base_hidden_vars .= '    <input type="hidden" name="date" value="'.$date.'">'."\n";
+		}
+		$base_hidden_vars .= '    <input type="hidden" name="month" value="'.$this->bo->month.'">'."\n";
+		$base_hidden_vars .= '    <input type="hidden" name="day" value="'.$this->bo->day.'">'."\n";
+		$base_hidden_vars .= '    <input type="hidden" name="year" value="'.$this->bo->year.'">'."\n";
+		
+		if(isset($GLOBALS['HTTP_POST_VARS']['participants']) && $GLOBALS['HTTP_POST_VARS']['participants'])
+		{
+			for ($i=0;$i<count($GLOBALS['HTTP_POST_VARS']['participants']);$i++)
+			{
+				$base_hidden_vars .= '    <input type="hidden" name="participants[]" value="'.$GLOBALS['HTTP_POST_VARS']['participants'][$i].'">'."\n";
+			}
+		}
+
+		$var = Array(
+			'form_width' => '28',
+			'form_link'	=> $this->page($referrer),
+			'form_name'	=> 'cat_id',
+			'title'	=> lang('Category'),
+			'hidden_vars'	=> $base_hidden_vars,
+			'form_options'	=> '<option value="0">'.lang('All').'</option>'.$this->cat->formated_list('select','all',$this->bo->cat_id,'True'),
+			'button_value'	=> lang('Go!')
+		);
+		$tpl->set_var($var);
+		$tpl->set_var('str',$tpl->fp('out','form_button_dropdown'));
+		$tpl->parse('header_column','head_col',True);
+
+		if($GLOBALS['HTTP_GET_VARS']['menuaction'] == 'calendar.uicalendar.planner')
+		{
+			$remainder -= 28;
+			print_debug('Sort By',$this->bo->sortby);
+
+			$form_options = '<option value="user"'.($this->bo->sortby=='user'?' selected':'').'>'.lang('User').'</option>'."\n";
+			$form_options .= '     <option value="category"'.((!isset($this->bo->sortby) || !$this->bo->sortby) || $this->bo->sortby=='category'?' selected':'').'>'.lang('Category').'</option>'."\n";
+		
+			$var = Array(
+				'form_width' => '28',
+				'form_link'	=> $this->page($referrer),
+				'form_name'	=> 'sortby',
+				'title'	=> lang('Sort By'),
+				'hidden_vars'	=> $base_hidden_vars,
+				'form_options'	=> $form_options,
+				'button_value'	=> lang('Go!')
+			);
+			$tpl->set_var($var);
+			$tpl->set_var('str',$tpl->fp('out','form_button_dropdown'));
+			$tpl->parse('header_column','head_col',True);
+		}
+
+		if($this->bo->check_perms(PHPGW_ACL_PRIVATE))
+		{
+			$remainder -= 28;
+			$form_options = '<option value=" all "'.($this->bo->filter==' all '?' selected':'').'>'.lang('All').'</option>'."\n";
+			$form_options .= '     <option value=" private "'.((!isset($this->bo->filter) || !$this->bo->filter) || $this->bo->filter==' private '?' selected':'').'>'.lang('Private Only').'</option>'."\n";
+		
+			$var = Array(
+				'form_width' => '28',
+				'form_link'	=> $this->page($referrer),
+				'form_name'	=> 'filter',
+				'title'	=> lang('Filter'),
+				'hidden_vars'	=> $base_hidden_vars,
+				'form_options'	=> $form_options,
+				'button_value'	=> lang('Go!')
+			);
+			$tpl->set_var($var);
+			$tpl->set_var('str',$tpl->fp('out','form_button_dropdown'));
+			$tpl->parse('header_column','head_col',True);
+		}
+//aqui !!
+
+		if((!isset($GLOBALS['phpgw_info']['server']['deny_user_grants_access']) || !$GLOBALS['phpgw_info']['server']['deny_user_grants_access']) && count($this->bo->grants) > 0)
+		{
+			$form_options = '';
+			
+			$drop_down = $this->bo->list_cals(); //hehe
+			
+			foreach($drop_down as $key => $grant)
+			{					
+				if(!strstr(($grant['value']),'g_')) 
+					$form_options .= '    <option value="'.$grant['value'].'"'.($grant['grantor']==$this->bo->owner?' selected':'').'>'.$grant['name'].'</option>'."\n";
+			}
+		
+			$var = Array(
+				'form_width' => $remainder,
+				'form_link'	=> $this->page($referrer),
+				'form_name'	=> 'owner',
+				'title'	=> lang('User'),
+				'hidden_vars'	=> $base_hidden_vars,
+				'form_options'	=> $form_options,
+				'button_value'	=> lang('Go!')
+			);
+			$tpl->set_var($var);
+			$tpl->set_var('str',$tpl->fp('out','form_button_dropdown'));
+			$tpl->parse('header_column','head_col',True);
+		}
+	}
+
+	$hidden_vars = '    <input type="hidden" name="from" value="'.$GLOBALS['HTTP_GET_VARS']['menuaction'].'">'."\n";
+	if(isset($GLOBALS['HTTP_GET_VARS']['date']) && $GLOBALS['HTTP_GET_VARS']['date'])
+	{
+		$hidden_vars .= '    <input type="hidden" name="date" value="'.$GLOBALS['HTTP_GET_VARS']['date'].'">'."\n";
+	}
+	$hidden_vars .= '    <input type="hidden" name="month" value="'.$this->bo->month.'">'."\n";
+	$hidden_vars .= '    <input type="hidden" name="day" value="'.$this->bo->day.'">'."\n";
+	$hidden_vars .= '    <input type="hidden" name="year" value="'.$this->bo->year.'">'."\n";
+	if(isset($this->bo->filter) && $this->bo->filter)
+	{
+		$hidden_vars .= '    <input type="hidden" name="filter" value="'.$this->bo->filter.'">'."\n";
+	}
+	if(isset($this->bo->sortby) && $this->bo->sortby)
+	{
+		$hidden_vars .= '    <input type="hidden" name="sortby" value="'.$this->bo->sortby.'">'."\n";
+	}
+	if(isset($this->bo->num_months) && $this->bo->num_months)
+	{
+		$hidden_vars .= '    <input type="hidden" name="num_months" value="'.$this->bo->num_months.'">'."\n";
+	}
+	$hidden_vars .= '    <input name="keywords"'.($GLOBALS['HTTP_POST_VARS']['keywords']?' value="'.$GLOBALS['HTTP_POST_VARS']['keywords'].'"':'').'>';
+
+	$var = Array(
+		'action_url_button'	=> $this->page('search'),
+		'action_text_button'	=> lang('Search'),
+		'action_confirm_button'	=> '',
+		'action_extra_field'	=> $hidden_vars
+	);
+	$tpl->set_var($var);
+	$button = $tpl->fp('out','form_button');
+	$tpl->set_var('str','<td align="right" valign="bottom">'.$button.'</td>');
+	$tpl->parse('header_column','head_col',True);
+	$tpl->parse('row','head_table',True);
+?>
Index: /tags/calendar/0.9.3/templates/celepar/week.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/week.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/celepar/week.tpl	(revision 2)
@@ -0,0 +1,3 @@
+{printer_friendly}
+<!-- from month_day.tpl -->
+{week_display}
Index: /tags/calendar/0.9.3/templates/celepar/month_header.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/month_header.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/celepar/month_header.tpl	(revision 2)
@@ -0,0 +1,12 @@
+<!-- BEGIN monthly_header -->
+<tr class="calendar_m_w_table_header" colspan="{cols}" width="{col_width}%">
+{column_header}</tr>
+<!-- END monthly_header -->
+
+<!-- BEGIN column_title -->
+<th bGCOLOR="#D3DCE3" width="14.28%">{col_title}</th>
+<!-- END column_title -->
+
+<!-- BEGIN month_column -->
+<td class="calendar_m_w_tablecell" colspan="1" width="{col_width}%"{extra}>{column_data}</td>
+<!-- END month_column -->
Index: /tags/calendar/0.9.3/templates/celepar/confirm.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/confirm.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/celepar/confirm.tpl	(revision 2)
@@ -0,0 +1,31 @@
+<!-- BEGIN list -->
+<html>
+<head>
+<title> .: Expresso :. </title>
+<link href='/phpgwapi/templates/celepar/login.css' rel='stylesheet' type='text/css'>
+</head>
+<body class='body'>
+<br>
+<center>
+<table border='0' cellpading='0' cellspacing='0'>
+	<tr>
+		<td class='td'><b><font face='Verdana, Arial, Helvetica, sans-serif'>{notify_message}</font></b></td>
+	</tr>
+	<tr>
+</table>
+</center>
+<br>
+<center>
+<table border='0' cellpading='0' cellspacing='0'>
+<tr>
+	<td>
+		<form>
+		<input type='submit' value='Ok' onclick='javascript:window.close()'>
+		</form>
+	</td>
+</tr>
+</table>
+</center>
+</body>
+</html>
+<!-- END list -->
Index: /tags/calendar/0.9.3/templates/celepar/listUsers.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/listUsers.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/celepar/listUsers.tpl	(revision 2)
@@ -0,0 +1,50 @@
+<html>
+	<head>
+		<title>{lang_Add_Participants}</title>
+	</head>
+	<body>
+		<form name="formAddUser" method="POST">	
+		 <center>	
+		  <table cellspacing="3" cellpadding="3">														
+		   <tr>
+			 <td>
+			  <div id="divAppboxHeader">{lang_Add_Participants}</div>
+			  <div id="divAppbox">
+			   <table border=0>
+				<tr><td>{lang_Organization}:</td></tr>
+				<tr><td><select name="select_organization" onchange="formAddUser.change_organization.value='True';formAddUser.submit()">.{combo_organization}.</select></td></tr>
+				<tr><td>{lang_Sector}:</td></tr>
+				<tr><td><select name="select_sector" onchange="formAddUser.submit()">.{combo_sector}.</select></td></tr>
+				<input type="hidden" name="change_organization" value="False">
+				<tr>
+				 <td>
+				  <select name="user_values" multiple style="width:250px" size="18" id="user_list_in">
+				  {options}
+				  </select>					
+				 </td>
+			    </tr>
+			    <tr><td align ="center"><font color="red"><span id="wait">&nbsp;</span></font></td></tr>				
+				<tr>
+				 <td>   			
+				  <center><font color="blue">{lang_to_Search}:</font>&nbsp;<input type="text" id="query" autocomplete="off" name="query" onkeyup="javascript:optionFinderTimeout(this)"></center>   			
+				 </td>
+				</tr>				
+				<tr><td>&nbsp;</td>	</tr>
+				<tr>
+				 <td>
+				  <center>
+				   <input type="button" class="button" value={lang_Add} onClick="javascript:adicionaListaCalendar()">
+				   <input type="button" value={lang_Close} onClick="javascript:window.close()">
+				  </center>
+				 </td>
+				</tr>		
+			   </table>
+			  </div>
+			 </td>	
+			</tr>
+		   </table>
+		  </center>				
+		 </form>
+	</body>
+</html>
+<script src="js/edit.js" type="text/javascript"></script>
Index: /tags/calendar/0.9.3/templates/celepar/footer.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/footer.tpl	(revision 57)
+++ /tags/calendar/0.9.3/templates/celepar/footer.tpl	(revision 57)
@@ -0,0 +1,34 @@
+<!-- BEGIN footer_table -->
+       <hr clear="all">
+       <font size="-1">
+       <table border="0" width="100%" cellpadding="0" cellspacing="0">
+        <tr>
+{table_row}
+	</tr>
+       </table>
+<!-- END footer_table -->
+<!-- BEGIN footer_row -->
+         <td valign="top" width="33%">
+          <font size="-1">
+           <form action="{action_url}" method="post" name="{form_name}">
+            <B>{label}:</B>
+			{hidden_vars}
+            <select name="{form_label}" onchange="{form_onchange}">
+	     {row}
+	    </select>
+			<input type="hidden" name="user" value="{user}">
+            <noscript><input type="submit" value="{go}"></noscript>
+	   </form>
+	  </font>
+	 </td>
+<!-- END footer_row -->
+<!-- BEGIN blank_row -->
+         <td>
+         {b_row}
+         </td>
+         <td>
+         {b_row2}
+         </td>
+<!-- END blank_row -->
+
+
Index: /tags/calendar/0.9.3/templates/celepar/publicView.php
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/publicView.php	(revision 2)
+++ /tags/calendar/0.9.3/templates/celepar/publicView.php	(revision 2)
@@ -0,0 +1,89 @@
+<?php 	
+	$user = $_POST['user'] ? $_POST['user'] : 
+		($_GET['user'] ? $_GET['user']: '');
+	
+	if($user) {
+		$organization = $_POST['organization'] ? $_POST['organization'] : 
+		($_GET['organization'] ? $_GET['organization']: '');
+		
+		if($organization)
+			$arg1 = $organization."-".$user;
+		else
+			$arg1 = $user;
+		
+		$params = "&account_name=".$arg1;
+	}
+	else
+		$params = '';
+?>
+<html>
+	<head><title>Visualizar Agenda</title>
+	<head>
+	<style type="text/css">
+		.grid_right{
+		border-style: groove;
+		border-width: 0px;
+		border-right-width: 1px;		
+		border-color: BLACK;		
+		}
+		.grid_top{
+		border-style: groove;
+		border-width: 0px;
+		border-top-width: 1px;		
+		border-color: BLACK;		
+		}
+	</style>
+	<LINK href="../../../phpgwapi/templates/celepar/css/celepar.css" type=text/css rel=StyleSheet>
+	<script language="Javascript">
+		function validate(){
+			if(document.login.user.value =="")	{
+				alert('Você deve digitar um nome no campo Usuário.');
+				document.login.user.focus();
+				return false;
+			}
+			
+			return true;
+		}
+	</script>
+	</head>
+	<body>
+	  <div align="center" valign="center">
+		<table cellspacing="0" cellpadding="5" width="100%" height="100%">			
+			<tr><td width="10%" valign="center"  class="grid_right"><br>
+				<table border="0" cellpadding="0" cellspacing="0" class="login" height="100%" width="100%">
+					<tr>
+						<td valign="top">
+	  					<FORM name="login" method="post" action="publicView.php" onSubmit="javascript:return validate()">
+							<table border="0" cellpadding="0" cellspacing="0" class="tableLogin">
+								<tr>
+									<td width="66" class="loginLabel" align="center"><b>Organização</b><br><input type="text" value="<?=$organization?>" name="organization" size="15"></td>
+								</tr>
+								<tr>									
+									<td>&nbsp;</td>
+								</tr>
+								<tr>
+									<td width="136" align="center" class="loginLabel"><b>Usuário</b><br><input name="user" size="15" value="<?=$user?>"></td>
+								</tr>
+								<tr>									
+									<td height="16">&nbsp;</td>
+								</tr>
+								<tr>
+									<td width="135" colspan="2" align="center">						
+									<input type="submit" value="Visualizar" name="submitit" class=button >
+									</td>
+									</tr>
+							</table>
+							</FORM>
+						</td>
+					</tr>
+				</table>								
+			</td>
+				<td width="90%" valign="top">
+					<iframe  width="100%" height="95%" src="../../../index.php?menuaction=calendar.uipublicview.publicView<?=$params?>"
+						marginwidth="0" marginheight="0"  topmargin="0" leftmargin="0" frameborder="0" scrolling="auto" noresize>
+					</iframe>
+			</td></tr>
+		</table>
+	  </div>
+	</body>
+</html>
Index: /tags/calendar/0.9.3/templates/celepar/head.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/head.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/celepar/head.tpl	(revision 2)
@@ -0,0 +1,25 @@
+<!-- BEGIN head -->
+<script language="Javascript">
+function openwindow(url)
+{ 
+	
+	var window_features = 	"scrollbars=yes,resizable=yes,location=no,menubar=no," + 
+							"personalbar=no,status=no,titlebar=no,toolbar=no," + 
+							"screenX=screen.width/3,screenY=screen.height/3,top=screen.height/3,left=screen.width/3,width=" + 
+							screen.width/4*3 + ",height=" + screen.height/8*3; 
+	
+	self.open(url,'', window_features); 
+}
+</script>
+{row}<br />
+<!-- END head -->
+<!-- BEGIN head_table -->
+<table id="calendar_head_table" class="calendar_head_table" border="0" width="100%" cols="{cols}" cellpadding="0" cellspacing="0">
+	<tr>
+		{header_column}
+	</tr>
+</table>
+<!-- END head_table -->
+<!-- BEGIN head_col -->
+{str}
+<!-- END head_col -->
Index: /tags/calendar/0.9.3/templates/celepar/body_email.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/body_email.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/celepar/body_email.tpl	(revision 2)
@@ -0,0 +1,32 @@
+<html>
+<head>
+<meta http-equiv="Content-Language" content="en" />
+<meta name="GENERATOR" content="PHPEclipse 1.0" />
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+<title>title</title>
+</head>
+<body bgcolor="#FFFFFF" text="#000000" link="#FF9966" vlink="#FF9966" alink="#FFCC99">
+<!-- BEGIN list -->
+<b><p align='left'>{subject}</p></b>
+<br>
+<table border='0' cellpadding='0' cellspacing='0' width='100%'>
+<tr><td width='30%' valign='top'><b>{var1} ::</b></td><td>{vardata1}</td></tr>	
+<tr><td width='30%' valign='top'><b>{var2} ::</b></td><td>{vardata2}</td></tr>
+<tr><td width='30%' valign='top'><b>{var3} ::</b></td><td>{vardata3}</td></tr>
+<tr><td width='30%' valign='top'><b>{var4} ::</b></td><td>{vardata4}</td></tr>
+<tr><td width='25%' valign='top'><b>{var8} ::</b></td><td>{vardata8}</td></tr>
+<tr><td width='25%' valign='top'><b>{var5} ::</b></td><td>{vardata6}</td></tr>
+</table>
+<br>
+<hr size='1' width='100%'>
+<table border='0' cellpadding='4' cellspacing='4' width='100%'>
+<tr>
+<td width='2%' align='left'>{varbuttom}</td>
+<td width='2%' align='left' valign='top'>{varbuttom1}</td>
+<td width='2%' align='left' valign='top'>{varbuttom2}</td>
+<td width='94%' align='left' valign='top'>{varbuttom3}</td>
+</tr>
+</table>
+<!-- END list -->
+</body>
+</html>
Index: /tags/calendar/0.9.3/templates/celepar/config.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/config.tpl	(revision 42)
+++ /tags/calendar/0.9.3/templates/celepar/config.tpl	(revision 42)
@@ -0,0 +1,75 @@
+<!-- BEGIN header -->
+<form method="POST" action="{action_url}">
+<table border="0" align="center">
+   <tr bgcolor="{th_bg}">
+    <td colspan="2"><font color="{th_text}">&nbsp;<b>{title}</b></font></td>
+   </tr>
+<!-- END header -->
+
+<!-- BEGIN body -->
+   <tr bgcolor="{row_on}">
+    <td colspan="2">&nbsp;</td>
+   </tr>
+   <tr bgcolor="{row_off}">
+    <td colspan="2"><b>{lang_Calendar_settings}</b></td>
+   </tr>
+   <tr bgcolor="{row_on}">
+    <td>{lang_Do_you_wish_to_autoload_calendar_holidays_files_dynamically?}</td>
+    <td>
+     <select name="newsettings[auto_load_holidays]">
+      <option value=""{selected_auto_load_holidays_False}>{lang_No}</option>
+      <option value="True"{selected_auto_load_holidays_True}>{lang_Yes}</option>
+     </select>
+    </td>
+   </tr>
+   <tr bgcolor="{row_off}">
+    <td>{lang_Location_to_autoload_from}:</td>
+    <td>
+     <select name="newsettings[holidays_url_path]">
+      <option value="localhost"{selected_holidays_url_path_localhost}>localhost</option>
+      <option value="http://www.phpgroupware.org/cal"{selected_holidays_url_path_http://www.phpgroupware.org/cal}>www.phpgroupware.org</option>
+     </select>
+    </td>
+   <tr bgcolor="{row_on}">
+    <td colspan="2">&nbsp;</td>
+   </tr>    
+   </tr>
+    <tr bgcolor="{row_off}">
+    <td colspan="2"><b>{lang_ExpressoMail_Plugin_Calendar}</b></td>
+   </tr>
+   <tr bgcolor="{row_on}">
+    <td>{lang_Select_module_version_expressoMail_(if_available)}</td>
+    <td>
+     <select name="newsettings[cal_expressoMail]">
+      <option value="False"{selected_cal_expressoMail_False}>{lang_dont_use_any_plugin}</option>
+      <option value="1.0"{selected_cal_expressoMail_1.0}>Expresso 1.0</option>
+      <option value="1.2"{selected_cal_expressoMail_1.2}>Expresso 1.2</option>
+     </select>
+    </td>
+   </tr>
+    <tr bgcolor="{row_off}">
+    <td>{lang_Select_type_tree_view}</td>
+    <td>
+     <select name="newsettings[cal_type_tree_participants]">      
+      <option value="2" {selected_cal_type_tree_participants_2}>{lang_first_level_with_recursive_search}</option>
+      <option value="1" {selected_cal_type_tree_participants_1}>{lang_all_levels_with_not_recursive_search}</option>      
+     </select>
+    </td>
+   </tr>
+<!-- END body -->
+
+<!-- BEGIN footer -->
+  <tr bgcolor="{th_bg}">
+    <td colspan="2">
+&nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td colspan="2" align="center">
+      <input type="submit" name="submit" value="{lang_submit}">
+      <input type="submit" name="cancel" value="{lang_cancel}">
+    </td>
+  </tr>
+</table>
+</form>
+<!-- END footer -->
Index: /tags/calendar/0.9.3/templates/celepar/grant_group_access.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/grant_group_access.tpl	(revision 421)
+++ /tags/calendar/0.9.3/templates/celepar/grant_group_access.tpl	(revision 421)
@@ -0,0 +1,65 @@
+<div align="center" style="width:100%">
+<input type="hidden" id="txt_loading" value="{lang_Loading}">
+<input type="hidden" id="txt_searching" value="{lang_Searching}">
+<input type="hidden" id="txt_users" value="{lang_Users}">
+<input type="hidden" id="txt_groups" value="{lang_Groups}">
+<input type="hidden" id="txt_confirm" value="{lang_confirm}">
+<input type="hidden" id="txt_success" value="{lang_success}">
+<input type="hidden" id="txt_exist" value="{lang_exist}">
+<input type="hidden" id="txt_nouser" value="{lang_nouser}">
+<input type="hidden" id="txt_nogroup" value="{lang_nogroup}">
+<input type="hidden" id="txt_nopermissiontype" value="{lang_nopermissiontype}">
+<input type="hidden" id="txt_typemoreletters" value="{lang_typemoreletters}">
+<input type="hidden" id="template_set" value="{template_set}">
+<table width="80%" border="0">
+<tr>
+<td align='center' valign="bottom"><br><b>{lang_User_to_grant_access}</b><br>
+	<font color="red"><span id="cal_span_searching1">&nbsp;</span></font>
+	<br>{lang_Search_for}: <input type="text" id="cal_input_searchUser1" name="cal_input_searchUser1" value="" size=30 autocomplete="off" onkeyup="javascript:search_object(this,'cal_span_searching1','user','u')"/>
+	<br><br>
+	<select id="user" style="width: 300px" size="13"></select>
+</td>
+<td width="20px" valign="middle" align="left"><br><br><br><br>
+<button type="button" onClick="javascript:add_user();"><img src="{template_set}/images/add.png" style="vertical-align: middle;" >{lang_Add}</button>
+<br><br><b>{lang_access_type}</b><br>
+<input type="checkbox" id="right_L" value="L"/>{lang_read}<br>
+<input type="checkbox" id="right_A" value="A"/>{lang_add}<br>
+<input type="checkbox" id="right_E" value="E"/>{lang_edit}<br>
+<input type="checkbox" id="right_R" value="R"/>{lang_delete}<br>
+<input type="checkbox" id="right_P" value="P"/>{lang_private}
+</td>
+<td align='center' valign="bottom"><br><b>{lang_Group_to_share_calendar}</b><br>
+	<font color="red"><span id="cal_span_searching2">&nbsp;</span></font>
+	<br>{lang_Search_for}:	<input type="text" id="cal_input_searchUser2" name="cal_input_searchUser2" value="" size=30 autocomplete="off" onkeyup="javascript:search_object(this,'cal_span_searching2','group','g')"/><br><br>
+	<select id="group" style="width: 300px" size="13"></select>
+</td>
+</tr>
+	<tr height="20px"></tr>
+	<tr bgcolor="{tr_color}" style="font-size:0.8em">
+		<th align="left" width="25%" nowrap>&nbsp;{lang_granted_user}</th>
+		<th align="center" width="1%">{lang_access_type}</th>
+		<th align="left" width="40%" nowrap>&nbsp;{lang_shared_group}</th>
+		<th width="1%">&nbsp;</th>
+	</tr>
+<tbody id='tbody_list' >
+<!-- BEGIN list -->
+	<tr id='{select}' bgcolor="{tr_color_header}">
+		<td>
+			<b>&nbsp;&nbsp;{granted_user}</b>
+		</td>
+		<td align="center">
+			{access_type}
+		</td>		
+		<td>
+			&nbsp;&nbsp;{shared_group}
+		</td>
+		<td align="center">
+			<button  title="{lang_Remove}" type="button" onClick="javascript:remove_user('{select}');"><img alt="{lang_Remove}" src="{template_set}/images/delete.png" style="vertical-align: middle;"/></button>
+		</td>
+	</tr>
+<!-- END list -->
+</tbody>
+</table>
+<br><br>
+</div>
+{scripts}
Index: /tags/calendar/0.9.3/templates/celepar/app.css
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/app.css	(revision 24)
+++ /tags/calendar/0.9.3/templates/celepar/app.css	(revision 24)
@@ -0,0 +1,290 @@
+/* CSS Document */
+.calendar_print_main {
+	text-align:center;
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-size: 8px;
+	color: #000066;
+	background-color: #F7F7F7;
+	border: 1px solid #CCCCCC;
+	margin: 5px;
+	padding: 5px;
+	height: 116px;
+	width: 480px;
+}
+
+.button
+{
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-size: 14px;
+	color: 006699;
+	background-color: #D4D0C8;
+	border: 2px solid #666666;
+}
+
+.to_continue
+{
+	font-size: 9px;
+}
+
+A.minicalendar 
+{ 
+	color: #000000; 
+	font-size: 9px;
+	
+}
+
+A.bminicalendar 
+{ 
+	color: #336699; 
+	font-style: italic;
+	font-weight: bold;
+	font-size: 9px; 
+}
+
+A.minicalendargrey 
+{ 
+	color: #999999; 
+	font-size: 10px;
+	font-weight: bold;
+}
+
+A.bminicalendargrey 
+{ 
+	color: #336699; 
+	font-style: italic; 
+	font-size:10px; 
+}
+
+A.minicalhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #000000; 
+	font-size: 10px; 
+}
+
+A.bminicalhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #336699; 
+	font-size: 10px; 
+}
+
+A.minicalgreyhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #999999; 
+	font-size: 10px; 
+}
+
+A.bminicalgreyhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #999999; 
+	font-size: 10px; 
+}
+
+
+.event-on
+{ 
+	background: #D3DCE3;
+	border: #E8F0F0 1px solid;
+}
+
+.event-off
+{ 
+	background: #E8F0F0;
+	border: #D3DCE3 1px solid;
+}
+
+.event-holiday
+{
+	font-size: 100%;
+	background: #dac0c0;
+	color:#000000;
+	vertical-align: middle;
+}
+
+.time
+{
+	background: #D3DCE3;
+	color:#000000;
+	font-size: 10px;
+	font-weight: bold;
+	vertical-align: middle;
+	width: 5.2%;
+	text-align: right;
+	padding-right: 5px;
+	line-height: 11px;
+	border: #E8F0F0 1px solid;
+}
+
+
+.planner-cell
+{
+	cursor: pointer;
+	cursor: hand;
+	border: thin solid black;
+}
+
+/* common */
+.calendar_link_print
+{
+	text-align: center;
+	font-size: 10px;
+}
+
+//Mini Calendar
+
+.calendar_minical_table
+{
+	width: 180px;
+	font-weight: bold;
+}
+
+.calendar_minical_daytable
+{
+	width: 100%;
+}
+
+.calendar_minical_dayname
+{
+	font-size: 9px;
+	text-align: right;
+}
+
+.calendar_minical_hrule
+{
+	width: 96%;
+}
+
+/* Header */
+.calendar_dropbuttons
+{
+	align: center;
+	text-align: center;
+	vertical-align: bottom;
+	font-weight: bold;
+	font-size: 8px;
+}
+
+.calendar-weekidentifier
+{
+	font-size:16px;
+	font-weight: bold;
+	text-align: center;
+}
+
+.calendar_header
+{
+	font-size: 16px;
+	font-weight: bold;
+	text-align: center;
+}
+
+.calendar_dayview_table_header
+{
+	font-size: 13px;
+	font-weight: bold;
+	text-align: center;
+}
+
+.calendar_dayview_todo_header
+{
+	margin: 0px; 
+	padding: 2px;
+	font-weight: bold;
+}
+
+/* week view */
+.calendar_week_identifier_table
+{
+	border: 0px solid black;
+	width: 100%;
+}
+
+.calendar_week_identifier
+{
+	font-size: 13px;
+	text-align: center;
+	font-weight: bold;
+}
+
+.calendar_weekview_daytitle
+{
+	font-weight: bold;
+	font-size: 12px;
+	background: #D3DCE3;
+}
+
+.calendar_m_w_table
+{
+	table-layout:fixed;
+	overflow:hidden;
+	height: 95%;
+	width: 100%;
+	border: 0px #000000 solid;
+}
+
+.calendar_m_w_tablecell
+{
+	overflow:hidden;
+	vertical-align: top;
+	padding-left: 4px;
+	padding-right: 4px;
+	padding-bottom: 6px;
+}
+
+.screen_only
+{
+	font-size: 10px;
+}
+
+.calendar_m_w_table_daynumber
+{
+	font-weight: bold;
+	font-size: 10px;
+}
+
+A.event_entry
+{
+	font-size:10px;
+}
+
+/* month view */
+
+.calendar_month_identifier
+{
+	font-size:14px;
+	font-weight: bold;
+}
+
+.calendar_user_identifier
+{
+	font-size:12px;
+	color: #009999;
+	font-weight: bold;
+}
+
+.calendar_week_minical_table
+{
+	width:100%;
+	border: 0px solid #000000
+}
+
+.calendar_weekinfo
+{
+	color: #000000;
+	padding-left: 2px;
+	padding-right: 2px;
+	font-size: 10px;
+	font-weight: bold;
+	font-style: italic;
+}
Index: /tags/calendar/0.9.3/templates/celepar/publicView.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/publicView.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/celepar/publicView.tpl	(revision 2)
@@ -0,0 +1,2 @@
+{week_display}
+</div>
Index: /tags/calendar/0.9.3/templates/celepar/view.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/view.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/celepar/view.tpl	(revision 2)
@@ -0,0 +1,46 @@
+
+<!-- BEGIN view_event -->
+<center>
+<table id="calendar_view_event" border="0" width="90%">
+	{row}
+	<tr>
+		<td>
+			<table id="calendar_viewevent_button_left" cellspacing="5">
+				<tr>
+					{button_left}
+				</tr>
+			</table>
+		</td>
+	   <td align="center">
+			<table id="calendar_viewevent_button_center" cellspacing="5">
+				<tr>
+					{button_center}
+				</tr>
+			</table>
+		</td>
+		<td align="right">
+			<table id="calendar_viewevent_button_right" cellspacing="5">
+				<tr>
+					{button_right}
+				</tr>
+			</table>
+		</td>
+	</tr>
+</table>
+</center>
+<!-- END view_event -->
+
+<!-- BEGIN list -->
+	<tr bgcolor="{tr_color}">
+		<td valign="top" width="30%">&nbsp;<b>{field}:</b></td>
+		<td colspan="2" valign="top" width="70%">{data}</td>
+	</tr>
+<!-- END list -->
+
+<!-- BEGIN hr -->
+	<tr>
+		<td colspan="3" bgcolor="{th_bg}" align="center">
+			<b>{hr_text}</b>
+		</td>
+	</tr>
+<!-- END hr -->
Index: /tags/calendar/0.9.3/templates/celepar/day.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/day.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/celepar/day.tpl	(revision 2)
@@ -0,0 +1,39 @@
+<!-- BEGIN day -->
+{printer_friendly}
+<table id="calendar_dayview_table" class="calendar_dayview_table" border="0" width="100%">
+	<tr>
+		<td valign="top" width="70%">
+			<table id="calendar_dayview1" border="0" width=100%>
+				<tr>
+					<td class="calendar_dayview_table_header">
+      					{date}&nbsp;<span class="calendar_user_identifier">:&nbsp;{username}&nbsp;:</span>
+						<br />
+     				</td>
+    			</tr>
+				{day_events}
+   			</table>
+   			<p align="center">{print}</p>
+  		</td>
+ 		 <td align="center" valign="top">
+  			 <table id="calendar_dayview2" width="100%">
+    			<tr>
+     				<td align="center">
+						{small_calendar}
+     				</td>
+    			</tr>
+
+   			</table>
+  		</td>
+ 	</tr>
+</table>
+<!-- END day -->
+
+<!-- BEGIN day_event -->
+	<tr>
+		<td>
+
+			{daily_events}
+
+		</td>
+	</tr>
+<!-- END day_event -->
Index: /tags/calendar/0.9.3/templates/celepar/js/edit_exmail.js
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/js/edit_exmail.js	(revision 638)
+++ /tags/calendar/0.9.3/templates/celepar/js/edit_exmail.js	(revision 638)
@@ -0,0 +1,345 @@
+/******************************************************************************\
+|**************************   CALENDAR MODULE   *******************************|
+|********** INCLUDE PARTICIPANTS - PLUGIN USING AJAX EXPRESSOMAIL COMPONENT  **|
+\******************************************************************************/
+var contacts = '';
+var array_lang = new Array();
+// onUnload edit message
+if(!document.all)
+{
+	var beforeunload = window.onbeforeunload;
+	window.onbeforeunload = function()
+	{
+		if ( typeof beforeunload == 'function' )
+			beforeunload();
+	};
+}
+	
+// Verifica versão do Firefox
+var agt = navigator.userAgent.toLowerCase();
+var is_firefox_0 = agt.indexOf('firefox/1.0') != -1 && agt.indexOf('firefox/0.') ? true : false;
+
+function optionFinderTimeout(obj)
+{
+	clearTimeout(finderTimeout);	
+	var oWait = document.getElementById("cal_span_searching");
+	oWait.innerHTML = document.getElementById("txt_searching").value + '...';
+	var finderTimeout = setTimeout("optionFinder('"+obj.id+"')",500);
+}
+function optionFinder(id) {
+	var oWait = document.getElementById("cal_span_searching");
+	var oText = document.getElementById(id);			
+	var select_available_users_tmp = document.getElementById('user_list_in')
+	for(var i = 0;i < select_available_users_tmp.options.length; i++)
+		select_available_users_tmp.options[i--] = null;
+
+	var RegExp_name = new RegExp("\\b"+oText.value, "i");
+
+	for(i = 0; i < select_available_users_clone.length; i++){
+		if (RegExp_name.test(select_available_users_clone[i].text) || select_available_users_clone[i].value =="-1")
+		{
+			sel = select_available_users_tmp.options;
+			option = new Option(select_available_users_clone[i].text,select_available_users_clone[i].value);
+			if( select_available_users_clone[i].value == "-1") option.disabled = true;
+			sel[sel.length] = option;
+		}
+	}	
+	oWait.innerHTML = '&nbsp;';
+}	
+		
+function get_available_users(path,context,type)
+{
+	var handler_get_available_users = function(data)
+	{	
+		select_available_users = document.getElementById('user_list_in');
+		
+		for(var i=0; i<select_available_users.options.length; i++){
+			select_available_users.options[i] = null;
+			i--;
+		}
+		var options = '###';
+		if (data) {
+			if(data.groups && data.groups.length > 0) {
+				data.groups = '<option  value="-1" disabled>------------------- '+document.getElementById("txt_groups").value+' ------------------ </option>' + data.groups;
+			}
+			
+			if(data.users && data.users.length > 0) {
+				data.users = '<option  value="-1" disabled>------------------- '+document.getElementById("txt_users").value+' ------------------ </option>' + data.users;
+			}
+			options +=  data.groups && data.groups.length > 0 ? data.groups : '';
+			options +=  data.users  && data.users.length  > 0 ? data.users  : '';
+			
+			if(is_firefox_0)
+				fixBugInnerSelect(select_available_users,options);
+			else
+				select_available_users.innerHTML = options;
+
+			select_available_users.outerHTML = select_available_users.outerHTML;
+			select_available_users.disabled = false;
+			select_available_users_clone = document.getElementById('user_list_in').cloneNode(true);
+			document.getElementById('cal_input_searchUser').value = '';
+		}
+	}	
+
+	document.getElementById('combo_org').value = context;
+	cExecute (path+'.ldap_functions.get_available_users&context='+context+'&type='+type, handler_get_available_users);
+}
+function add_user()
+{
+	var select_available_users = document.getElementById('user_list_in');
+	var select_users = document.getElementById('user_list');
+	var count_available_users = select_available_users.length;
+	var count_users = select_users.options.length;
+	var new_options = '';
+	
+	for (i = 0 ; i < count_available_users ; i++) {
+		if (select_available_users.options[i].selected)	{
+			if(document.all) {
+				if ( (select_users.innerHTML.indexOf('value='+select_available_users.options[i].value)) == '-1' ) {
+					new_options +=  '<option value='
+								+ select_available_users.options[i].value
+								+ '>'
+								+ select_available_users.options[i].text
+								+ '</option>';
+				}
+			}
+			else if ( (select_users.innerHTML.indexOf('value="'+select_available_users.options[i].value+'"')) == '-1' ) {
+					new_options +=  '<option value='
+								+ select_available_users.options[i].value
+								+ '>'
+								+ select_available_users.options[i].text
+								+ '</option>';
+			}
+		}
+	}
+
+	if (new_options != '') {
+
+		if(is_firefox_0)
+			fixBugInnerSelect(select_users,'###' + new_options + select_users.innerHTML);
+		else
+			select_users.innerHTML = '###' + new_options + select_users.innerHTML;
+
+		select_users.outerHTML = select_users.outerHTML;
+	}
+}
+
+function remove_user(){
+	select_users = document.getElementById('user_list');
+	
+	for(var i = 0;i < select_users.options.length; i++)
+		if(select_users.options[i].selected)
+			select_users.options[i--] = null;
+}
+
+function submitValues(){
+	var typeField = document.getElementById('cal[type]');
+	if (typeField && typeField.value == 'hourAppointment') {
+		if(document.getElementsByName('categories[]')[0].value == ""){
+			alert(alert_msg);
+			return false;
+		}
+	}
+	var select_in = document.getElementById('user_list');
+	for(i = 0; i < select_in.length; i++)
+	 	select_in.options[i].selected = true;
+}	
+
+function Element(id){
+	return document.getElementById(id);
+}
+
+function loadScript(scriptPath){
+
+	if(!connector)
+		throw new Error("Error : Connector is not loaded.");
+		
+  	if (document.getElementById('uploadscript_'+scriptPath)) {
+  		return;
+   	}
+  	
+	connector.oxmlhttp.open("GET", scriptPath, false);
+    connector.oxmlhttp.setRequestHeader('Content-Type','text/plain');
+	connector.oxmlhttp.send(null);
+	if(connector.oxmlhttp.status != 0 && connector.oxmlhttp.status != 200 || 	connector.oxmlhttp.status == 0 && connector.oxmlhttp.responseText.length == 0)
+		throw new Error("Error " + connector.oxmlhttp.status + "("+connector.oxmlhttp.statusText+") when loading script file '"+scriptPath+"'");
+	
+	var head = document.getElementsByTagName("head")[0];
+	var script = document.createElement("SCRIPT");
+	script.id = 'uploadscript_'+scriptPath;
+	script.type = 'text/javascript';		
+	script.text = connector.oxmlhttp.responseText;
+	head.appendChild(script);
+	return;	
+}
+
+function showExParticipants(el,path){
+	Element('tbl_ext_participants').style.display='';
+	el.style.display='none';
+	loadScript(path+"/js/DropDownContacts.js");
+	loadScript(path+"/js/common_functions.js");
+	loadScript(path+"/js/QuickCatalogSearch.js");
+	loadScript("calendar/templates/celepar/js/over_fn_exmail.js");
+	if(!contacts)
+		cExecute (path+'.db_functions.get_dropdown_contacts', save_contacts);
+}
+
+function hideExParticipants(el,path){
+	Element('a_ext_participants').style.display = '';
+	Element('tbl_ext_participants').style.display ='none';
+}
+
+function save_contacts(data){
+	contacts = data;	
+	var input_to = Element("ex_participants");
+	input_to.style.width = "100%";
+	input_to.setAttribute("wrap","soft");	
+	input_to.onfocus = function(){clearTimeout(parseInt(setTimeOutLayer)); search_contacts('onfocus', this.id);};
+	input_to.onblur = function(){setTimeOutLayer=setTimeout('search_contacts("lostfocus","'+this.id+'")',100);};
+	if (!is_ie)
+	{
+		input_to.rows = 2;
+		input_to.onkeypress = function (e)
+		{
+			if ((e.keyCode) == 120) //F9
+			{
+				emQuickSearch(input_to);
+			}
+			else 
+			{ 
+				if (((e.keyCode == 13) || ((e.keyCode == 38)||(e.keyCode == 40))) && (document.getElementById('tipDiv').style.visibility!='hidden'))
+				{
+					e.preventDefault();
+					search_contacts(e.keyCode,this.id);
+				}
+			}
+		}
+		input_to.onkeyup = function (e)
+		{
+			if ((e.keyCode != 13) && (e.keyCode != 38) && (e.keyCode != 40))
+			{
+				search_contacts(e.keyCode,this.id);
+			}
+		}
+	}
+	else
+	{
+		input_to.rows = 3;
+		input_to.onkeyup = function (e)
+		{
+			if ((window.event.keyCode) == 120) //F9
+			{
+				emQuickSearch(input_to);
+			}
+			else 
+			{ 
+				search_contacts(window.event.keyCode,this.id);
+			}	
+		}
+	}
+}
+
+function fixBugInnerSelect(objeto,innerHTML){
+/******
+* select_innerHTML - altera o innerHTML de um select independente se é FF ou IE
+* Corrige o problema de não ser possível usar o innerHTML no IE corretamente
+* Veja o problema em: http://support.microsoft.com/default.aspx?scid=kb;en-us;276228
+* Use a vontade mas coloque meu nome nos créditos. Dúvidas, me mande um email.
+* Versão: 1.0 - 06/04/2006
+* Autor: Micox - Náiron José C. Guimarães - micoxjcg@yahoo.com.br
+* Parametros:
+* objeto(tipo object): o select a ser alterado
+* innerHTML(tipo string): o novo valor do innerHTML
+*******/
+    objeto.innerHTML = ""
+    var selTemp = document.createElement("micoxselect")
+    var opt;
+    selTemp.id="micoxselect1"
+    document.body.appendChild(selTemp)
+    selTemp = document.getElementById("micoxselect1")
+    selTemp.style.display="none"
+    if(innerHTML.toLowerCase().indexOf("<option")<0){//se não é option eu converto
+        innerHTML = "<option>" + innerHTML + "</option>"
+    }
+    innerHTML = innerHTML.replace(/<option/g,"<span").replace(/<\/option/g,"</span")
+    selTemp.innerHTML = innerHTML
+    for(var i=0;i<selTemp.childNodes.length;i++){
+        if(selTemp.childNodes[i].tagName){
+            opt = document.createElement("OPTION")
+            for(var j=0;j<selTemp.childNodes[i].attributes.length;j++){
+                opt.setAttributeNode(selTemp.childNodes[i].attributes[j].cloneNode(true))
+            }
+            opt.value = selTemp.childNodes[i].getAttribute("value")
+            opt.text = selTemp.childNodes[i].innerHTML
+            if(document.all){ //IEca
+                objeto.add(opt)
+            }else{
+                objeto.appendChild(opt)
+            }                    
+        }    
+    }
+    document.body.removeChild(selTemp)
+    selTemp = null
+}
+
+function changeViewMode(eltype){
+	var chValue = eltype;
+
+	switch (chValue){
+		case 'hourAppointment':
+			var names=new Array('title','priority','location','alarmhours','alarmminutes','recur_type','rpt_use_end','recur_interval','rpt_label');
+			for (var i=0; i < names.length; i++)
+			{
+				var Field = document.getElementsByName('cal['+names[i]+']');
+				if (Field[0])
+					Field[0].parentNode.parentNode.style.display = "none";
+			}
+
+			Field = document.getElementsByName('participants[]');
+			Field[0].parentNode.parentNode.style.display = "none";
+			Field[1].parentNode.parentNode.style.display = "none";
+			Field = document.getElementById('txt_loading');
+			Field.parentNode.parentNode.style.display = "none";
+			Field = document.getElementsByName('cal[rpt_day][]');
+			Field[0].parentNode.parentNode.style.display = "none";
+			break;
+		default:
+			var names=new Array('title','priority','location','alarmhours','alarmminutes','recur_type','rpt_use_end','recur_interval','rpt_label');
+			for (var i=0; i < names.length; i++)
+			{
+				var Field = document.getElementsByName('cal['+names[i]+']');
+				if (Field[0])
+					Field[0].parentNode.parentNode.style.display = "";
+			}
+			Field = document.getElementsByName('participants[]');
+			Field[0].parentNode.parentNode.style.display = "";
+			Field[1].parentNode.parentNode.style.display = "";
+			Field = document.getElementById('txt_loading');
+			Field.parentNode.parentNode.style.display = "";
+			Field = document.getElementsByName('cal[rpt_day][]');
+			Field[0].parentNode.parentNode.style.display = "";
+			break;
+	}
+
+}
+function updateTitleField(select){
+	var typeField = document.getElementsByName('cal[type]');
+	if (typeField[0].value != 'hourAppointment')
+		return;
+	var titleField = document.getElementsByName('cal[title]');
+	var optionsArray = select.childNodes;
+	titleField[0].value = '';
+	for(option in optionsArray)
+		if (optionsArray[option].selected)
+			titleField[0].value += optionsArray[option].text + ' ';
+}
+
+var __onLoad = window.onload;
+window.onload = function(){ 
+	__onLoad();
+	var cal_type = document.getElementById('cal[type]').value;
+	changeViewMode(cal_type);
+	if(cal_type == 'hourAppointment'){
+		clearTimeout(timeout_get_available_users);
+	}
+}; 
Index: /tags/calendar/0.9.3/templates/celepar/js/edit.js
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/js/edit.js	(revision 638)
+++ /tags/calendar/0.9.3/templates/celepar/js/edit.js	(revision 638)
@@ -0,0 +1,101 @@
+/******************************************************************************\
+|**************************   MODULO   AGENDA   *******************************|
+|********** SCRIPT REFERENTE A CAIXA DE INCLUSAO DE PARTICIPANTES  ************|
+\******************************************************************************/
+
+// Variaveis Locais 
+	var select_in  = document.getElementById('user_list');
+	var select_out  = document.getElementById('user_list_in');	
+	var users_out = select_out.cloneNode(true);
+	var finderTimeout = '';
+																		
+// Funcoes				
+	function showExParticipants(el,path){
+		document.getElementById('tbl_ext_participants').style.display='';
+		el.style.display='none';
+	}
+	
+	function hideExParticipants(el,path){
+		document.getElementById('a_ext_participants').style.display = '';
+		document.getElementById('tbl_ext_participants').style.display ='none';
+	}
+							
+	function optionFinderTimeout(obj){
+
+		clearTimeout(finderTimeout);	
+		var oWait = document.getElementById("wait");
+		oWait.innerHTML = 'Buscando...';
+		finderTimeout = setTimeout("optionFinder('"+obj.id+"')",500);
+	}
+	function optionFinder(id) {	
+		var oWait = document.getElementById("wait");
+		var oText = document.getElementById(id);
+		for(var i = 0;i < select_out.options.length; i++)				
+			select_out.options[i--] = null;
+																							
+		for(i = 0; i < users_out.length; i++){																							
+			if(users_out[i].text.substring(0 ,oText.value.length).toUpperCase() == oText.value.toUpperCase()) {
+				sel = select_out.options;						
+				option = new Option(users_out[i].text,users_out[i].value);				
+				sel[sel.length] = option;
+			}
+		}
+		oWait.innerHTML = '&nbsp;';
+	}			
+									
+	function rem()
+	{
+		for(var i = 0;i < select_in.options.length; i++)				
+			if(select_in.options[i].selected)
+				select_in.options[i--] = null;																	
+	}
+													 									
+	function submitValues(alert_msg){
+		var typeField = document.getElementById('cal[type]');
+		if (typeField && typeField.value == 'hourAppointment')
+			if(document.getElementsByName('categories[]')[0].value == ""){
+				alert(alert_msg);
+				return false;
+				}
+		for(i = 0; i < select_in.length; i++)
+		 	select_in.options[i].selected = true;
+	}
+	
+	
+	
+	function openListUsers(newWidth,newHeight, owner){					
+		newScreenX  = screen.width - newWidth;		
+		newScreenY  = 0;		
+		window.open('calendar/templates/celepar/listUsers.php?owner='+owner,"","width="+newWidth+",height="+newHeight+",screenX="+newScreenX+",left="+newScreenX+",screenY="+newScreenY+",top="+newScreenY+",toolbar=no,scrollbars=yes,resizable=no");
+	}
+
+ 	function adicionaListaCalendar() 
+ 	{
+		var select = window.document.getElementById('user_list_in');
+		var selectOpener = window.opener.document.getElementById('user_list');
+		for (i = 0 ; i < select.length ; i++) {				
+
+			if (select.options[i].selected) {
+				isSelected = false;
+
+				for(var j = 0;j < selectOpener.options.length; j++) {																			
+					if(selectOpener.options[j].value == select.options[i].value){
+						isSelected = true;						
+						break;	
+					}
+				}
+
+				if(!isSelected){
+
+					option = window.opener.document.createElement('option');
+					option.value =select.options[i].value;
+					option.text = select.options[i].text;
+					selectOpener.options[selectOpener.options.length] = option;	
+				}
+				
+			}
+		}
+		selectOpener.options[selectOpener.options.length-1].selected = true;
+ 	}
+	
+// Fim        
Index: /tags/calendar/0.9.3/templates/celepar/js/search.js
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/js/search.js	(revision 421)
+++ /tags/calendar/0.9.3/templates/celepar/js/search.js	(revision 421)
@@ -0,0 +1,108 @@
+var searchTimeout;
+
+function lang(key){
+	return document.getElementById("txt_"+key).value;
+}
+
+function remove_user(id){
+	if(!confirm(lang("confirm")))
+		return true;	
+	var handler_rem_user = function(data){
+		if(data) {
+			var tr = document.getElementById(id);
+			tr.parentNode.removeChild(tr);
+		}
+	}	
+	cExecute ('calendar.uigroup_access.rem_user&id='+id, handler_rem_user);
+}
+function add_user(){
+	var select_users = document.getElementById("user");
+	var select_groups = document.getElementById("group");
+	var a_rights = new Array("L","A","E","R","P");
+	var rights = '';
+	for(var z = 0; z < a_rights.length; z++){
+		var check = document.getElementById("right_"+a_rights[z]);
+		if(check.checked){
+			rights += check.value;
+		}
+	}
+	if(!select_users.value){
+		alert(lang("nouser"));
+		return;
+	}
+	else if(!select_groups.value){
+		alert(lang("nogroup"));
+		return;
+	}
+	else if(!rights){
+		alert(lang("nopermissiontype"));
+		return;
+	}
+	
+	var str = select_users.value+";"+select_groups.value;
+	var handler_add_user = function(data){
+		
+		if(data){
+			var t = document.getElementById('tbody_list');
+			var tr = document.createElement("TR");
+			tr.bgColor = "#DCDCDC";
+			var td1 = document.createElement("TD");
+			var td2 = document.createElement("TD");
+			var td3 = document.createElement("TD");
+			var td4 = document.createElement("TD");
+			tr.id = str;
+			td1.innerHTML = "<b>&nbsp;&nbsp;"+select_users[select_users.selectedIndex].text+"</b>";
+			td2.innerHTML = rights;
+			td2.align = "center";
+			td3.innerHTML = "&nbsp;&nbsp;"+select_groups[select_groups.selectedIndex].text;
+			td4.innerHTML = "<button  title='remove' type='button' onClick='javascript:remove_user(\""+str+"\");'><img src='"+document.getElementById("template_set").value+"/images/delete.png' style='vertical-align: middle;'/></button>";
+			tr.appendChild(td1);
+			tr.appendChild(td2);
+			tr.appendChild(td3);
+			tr.appendChild(td4);
+			t.appendChild(tr);
+			alert(lang("success"));
+		}
+		else{
+			alert(lang("exist"));
+		}
+	}
+	cExecute ('calendar.uigroup_access.add_user&id='+str+"&rights="+rights, handler_add_user);
+	return true;
+		
+}
+function search_object(input, id_span, id_select, type)
+{
+	clearTimeout(searchTimeout);	
+	var spam = document.getElementById(id_span);
+	if (input.value.length <= 3){
+		spam.innerHTML = lang("typemoreletters").replace("X",4 - input.value.length);
+	}else{
+		spam.innerHTML = lang("searching")+'...';
+		searchTimeout = setTimeout("search_ldap('"+input.id+"','"+id_span+"','"+id_select+"','"+type+"')",750);
+	}
+}
+
+function search_ldap(id_input, id_span, id_select, type)
+{
+	var search = document.getElementById(id_input).value;
+	
+	var handler_search_user = function(data)
+	{
+		var spam = document.getElementById(id_span);
+		select_available_users = document.getElementById(id_select);
+		if (data.status == 'false')
+		{
+			spam.innerHTML = data.msg;
+			// Necessario, pois o IE6 tem um bug que retira o primeiro options se o innerHTML estiver vazio.
+			select_available_users.innerHTML = '#';
+			select_available_users.outerHTML = select_available_users.outerHTML;
+			return;
+		}	
+		spam.innerHTML = '';
+		// Necessario, pois o IE6 tem um bug que retira o primeiro options se o innerHTML estiver vazio.
+		select_available_users.innerHTML = '#' + data;
+		select_available_users.outerHTML = select_available_users.outerHTML;
+	}
+	cExecute ('calendar.uigroup_access.search_user&search='+search+"&type="+type, handler_search_user);
+}
Index: /tags/calendar/0.9.3/templates/celepar/js/over_fn_exmail.js
===================================================================
--- /tags/calendar/0.9.3/templates/celepar/js/over_fn_exmail.js	(revision 637)
+++ /tags/calendar/0.9.3/templates/celepar/js/over_fn_exmail.js	(revision 637)
@@ -0,0 +1,163 @@
+/******************************************************************************\
+|**************************   CALENDAR MODULE   *******************************|
+|********** PLUGIN USING AJAX EXPRESSOMAIL COMPONENT - OVERWRITE FUNCTIONS   **|
+\******************************************************************************/
+
+/******************************************************************************\
+|** Function      : emQuickSearch *********************************************|
+|** Original File : <expressoMail_module>/js/common_functions.js **************|
+\******************************************************************************/
+window.onresize = function(){};
+function emQuickSearch(el){
+
+	var emailList = el.value;
+	var field = el.id;
+	var ex_participants = Element("ex_participants");
+	var quickSearchKeyBegin;
+	var quickSearchKeyEnd;
+	
+	var handler_emQuickSearch = function(data){
+		window_DropDownContacts = Element('tipDiv');
+		if (window_DropDownContacts.style.visibility != 'hidden'){
+			window_DropDownContacts.style.visibility = 'hidden';
+		}
+		
+		if ((!data.status) && (data.error == "many results")){
+			alert(get_lang('More than %1 results. Please, try to refine your search.',200));
+			return false;
+		}
+			
+		if (data.length > 0){
+			QuickCatalogSearch.showList(data, quickSearchKeyBegin, quickSearchKeyEnd);
+		}
+		else
+			alert(get_lang('None result was found.'));
+		return true;
+	}
+	ex_participants.focus(); 				//mecessary for IE.
+	var i = getPosition(ex_participants); //inputBox.selectionStart;
+	var j = --i;
+
+    while ((j >= 0) && (emailList.charAt(j) != ',')){j--};
+    quickSearchKeyBegin = ++j;
+
+    while ((i <= emailList.length) && (emailList.charAt(i) != ',')){i++};
+    quickSearchKeyEnd = i;
+
+    var search_for = trim(emailList.substring(quickSearchKeyBegin, quickSearchKeyEnd));
+
+	if (search_for.length < 4){
+		alert(get_lang('Your search argument must be longer than 4 characters.'));
+		return false;
+	}
+	
+	cExecute ("expressoMail1_2.ldap_functions.quicksearch&search_for="+search_for+"&field="+field, handler_emQuickSearch);
+}
+
+/******************************************************************************\
+|** Function      : emQuickCatalogSearch.prototype.transfer_result ************|
+|** Original File : <expressoMail_module>/js/QuickCatalogSearch.js ************|
+\******************************************************************************/
+emQuickCatalogSearch.prototype.transfer_result = function (field, ID, begin, end){
+	cm = document.getElementById('select_QuickCatalogSearch');
+	option_selected = cm.options[cm.selectedIndex].value + ", ";
+	emailList = Element("ex_participants").value;		
+	new_emailList = emailList.substring(0, begin) + option_selected + emailList.substring((parseInt(end) + 2), emailList.length);
+	document.getElementById("ex_participants").value = new_emailList;
+	if(is_ie)
+		Element("i_blank").style.display = "none";
+	document.getElementById("ex_participants").focus();
+	this.arrayWin['window_QuickCatalogSearch'].close();
+}
+
+/******************************************************************************\
+|** Function      : emQuickCatalogSearch.prototype.close_QuickSearch_window ***|
+|** Original File : <expressoMail_module>/js/QuickCatalogSearch.js ************|
+\******************************************************************************/
+emQuickCatalogSearch.prototype.close_QuickSearch_window = function (field, ID){
+	if(is_ie)
+		Element("i_blank").style.display = "none";
+	document.getElementById("ex_participants").focus();
+	this.arrayWin['window_QuickCatalogSearch'].close();
+}
+
+/******************************************************************************\
+|** Function      : emQuickCatalogSearch.prototype.showWindow *****************|
+|** Original File : <expressoMail_module>/js/QuickCatalogSearch.js ************|
+\******************************************************************************/
+emQuickCatalogSearch.prototype.showWindow = function (div)
+{
+	if(! div) {
+		alert(get_lang('The list has no participant.'));
+		return;
+	}
+						
+	if(! this.arrayWin[div.id]) {
+		div.style.width = "700px";
+		div.style.height = "230px";
+		var title = get_lang('The results were found in the Global Catalog')+':';
+		var wHeight = div.offsetHeight + "px";
+		var wWidth =  div.offsetWidth   + "px";
+		div.style.width = div.offsetWidth - 5;
+
+		win = new dJSWin({			
+			id: 'QuickCatalogSearch_'+div.id,
+			content_id: div.id,
+			width: wWidth,
+			height: wHeight,
+			y:'300px',
+			top: '300px',
+			title_color: '#3978d6',
+			bg_color: '#eee',
+			title: title,						
+			title_text_color: 'white',
+			button_x_img: 'phpgwapi/images/winclose.gif',
+			border: true });
+		
+		this.arrayWin[div.id] = win;
+		win.draw();
+	}
+	else {
+		win = this.arrayWin[div.id];
+	}
+
+	if(is_ie) {	
+		var _IFrame = Element("i_blank");
+		if(_IFrame){
+    		_IFrame.style.display  = '' ;		
+		}
+		else {
+			_IFrame = document.body.appendChild(document.createElement('iframe'));
+			_IFrame.src = 'about:blank' ;
+		    _IFrame.frameBorder		= '0';
+		    _IFrame.scrolling		= 'no' ;
+		    _IFrame.style.left		= findPosX(div)  + document.body.scrollLeft -5;
+			_IFrame.style.top		= findPosY(div)  + document.body.scrollTop  -20;
+		    _IFrame.width			= 610;
+   		    _IFrame.style.border	= 0;
+			_IFrame.height			= 285;
+			_IFrame.border			= 0;
+			_IFrame.id				= "i_blank";
+		    _IFrame.style.position	= 'absolute';
+	   	    _IFrame.style.zIndex	= '5';
+    		_IFrame.style.display  = '' ;
+		}
+	}
+
+	win.open();
+	document.getElementById('select_QuickCatalogSearch').focus();
+}	
+
+
+/******************************************************************************\
+|** Function      :  DRAG *****************************************************|
+|** Original File : phpgwapi/js/wz_dragdrop/wz_dragdrop.js ********************|
+\******************************************************************************/
+var over_fn_DRAG = DRAG;
+DRAG = function (event){
+
+		if(is_ie)
+			return false;
+		else
+			over_fn_DRAG(event);
+}		
Index: /tags/calendar/0.9.3/templates/jerryr/head.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/jerryr/head.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/jerryr/head.tpl	(revision 2)
@@ -0,0 +1,12 @@
+<!-- BEGIN head -->
+{row}
+<!-- END head -->
+<!-- BEGIN head_table -->
+<table border="0" width="100%" cols="{cols}" cellpadding="0" cellspacing="0">
+ <tr>
+  {header_column} </tr>
+</table>
+<!-- END head_table -->
+<!-- BEGIN head_col -->
+{str}
+<!-- END head_col -->
Index: /tags/calendar/0.9.3/templates/jerryr/edit.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/jerryr/edit.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/jerryr/edit.tpl	(revision 2)
@@ -0,0 +1,48 @@
+<!-- BEGIN edit_entry -->
+<script language="JavaScript">
+	self.name="first_Window";
+	function accounts_popup()
+	{
+		Window1=window.open('{accounts_link}',"Search","width=800,height=600,toolbar=no,scrollbars=yes,resizable=yes");
+	}
+</script>
+<center>
+<font color="#000000" face="{font}">
+
+<form action="{action_url}" method="post" name="app_form">
+{common_hidden}
+<table class="calDayViewShadowBox" width="100%"><tr><td>
+<table class="calDayViewSideBoxes" width="100%">
+ <tr>
+  <td colspan="2">
+   <center><font size="+1"><b>{errormsg}</b></font></center>
+  </td>
+ </tr>
+{row}
+ <tr>
+  <td>
+   <table><tr valign="top">
+    <td><input type="submit" value="{submit_button}">&nbsp;</form></td>
+    <td>{cancel_button}</td>
+   </tr></table>
+  </td>
+  <td align="right">{delete_button}</td>
+ </tr>
+</table>
+</td></tr></table>
+</font>
+</center>
+<!-- END edit_entry -->
+<!-- BEGIN list -->
+ <tr bgcolor="{tr_color}">
+  <td valign="top" width="35%">&nbsp;<b>{field}:</b></td>
+  <td valign="top" width="65%">{data}</td>
+ </tr>
+<!-- END list -->
+<!-- BEGIN hr -->
+ <tr bgcolor="{tr_color}">
+  <td colspan="2">
+   {hr_text}
+  </td>
+ </tr>
+<!-- END hr -->
Index: /tags/calendar/0.9.3/templates/jerryr/index.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/jerryr/index.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/jerryr/index.tpl	(revision 2)
@@ -0,0 +1,27 @@
+{printer_friendly}
+<table border="0" width="100%" cols="5" class="calDayViewShadowBox">
+ <tr>
+  <td align="left" valign="top" width="20%">
+   {small_calendar_prev}</td>
+  <td align="center" valign="middle" width="20%">
+   <b>{prev_month_link}</b></td>
+  <td align="center" width="20%">
+   <font size="+2" color="#000000"><b>{month_identifier}</b></font>
+   <font size="+1" color="#000000"><br>{username}</font></td>
+  <td align="center" valign="middle" width="20%">
+   {next_month_link}</td>
+  <td align="right" valign="top" width="20%">
+   {small_calendar_next}</td>
+ </tr>
+ <tr>
+  <td colspan=5 width=100%>
+	<table width=100% class="calDayViewSideBoxes">
+		<tr>
+			<td>{large_month}</td>
+		</tr>
+	</table><p>{print}
+</td>
+</tr>
+</table>
+
+
Index: /tags/calendar/0.9.3/templates/jerryr/app.css
===================================================================
--- /tags/calendar/0.9.3/templates/jerryr/app.css	(revision 2)
+++ /tags/calendar/0.9.3/templates/jerryr/app.css	(revision 2)
@@ -0,0 +1,124 @@
+/* CSS Document */
+A.minicalendar 
+{ 
+	color: #666666; 
+	font-size: 12px;
+	
+}
+
+A.bminicalendar 
+{ 
+	color: #336699; 
+	font-style: italic;
+	font-weight: bold;
+	font-size: 10px; 
+}
+
+A.minicalendargrey 
+{ 
+	color: #999999; 
+	font-size: 10px;
+	font-weight: bold;
+}
+
+A.bminicalendargrey 
+{ 
+	color: #336699; 
+	font-style: italic; 
+	font-size:10px; 
+}
+
+A.minicalhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #000000; 
+	font-size: 10px; 
+}
+
+A.bminicalhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #336699; 
+	font-size: 10px; 
+}
+
+A.minicalgreyhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #999999; 
+	font-size: 10px; 
+}
+
+A.bminicalgreyhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #999999; 
+	font-size: 10px; 
+}
+
+
+.event-on
+{ 
+	background: #faf8f3;
+	border: #c9c9c9 1px solid;
+}
+
+.event-off
+{ 
+	background: #f4f2ed;
+	border: #c9c9c9 1px solid;
+}
+
+.event-holiday
+{
+	font-size: 100%;
+	background: #dac0c0;
+	color:#000000;
+	vertical-align: middle;
+}
+
+.time
+{
+	background: #f4f2ed;
+	color:#000000;
+	font-size: 10px;
+	font-weight: bold;
+	vertical-align: middle;
+	width: 5.2%;
+	text-align: right;
+	padding-right: 5px;
+	line-height: 11px;
+	border: #c9c9c9 1px solid;
+}
+
+
+.planner-cell
+{
+	cursor: pointer;
+	cursor: hand;
+	border: thin solid black;
+}
+
+
+// week view
+
+.calendar-weekidentifier
+{
+	font-size:16px;
+	font-weight: bold;
+}
+
+.calendar_header
+{
+	font-size:16px;
+	font-weight: bold;
+	text-align: center;
+}
Index: /tags/calendar/0.9.3/templates/jerryr/view.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/jerryr/view.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/jerryr/view.tpl	(revision 2)
@@ -0,0 +1,31 @@
+<!-- BEGIN view_event -->
+<center>
+<table border="0" width="100%" class="calDayViewShadowBox">
+<tr>
+<td>
+<table border="0" width="100%">
+  {row}
+  <tr>
+   <td><table cellspacing="5"><tr>{button_left}</tr></table></td>
+   <td align="center"><table cellspacing="5"><tr>{button_center}</tr></table></td>
+   <td align="right"><table cellspacing="5"><tr>{button_right}</tr></table></td>
+  </tr>
+ </table>
+</td>
+</tr>
+</table>
+</center>
+<!-- END view_event -->
+<!-- BEGIN list -->
+  <tr bgcolor="{tr_color}">
+   <td valign="top" width="30%">&nbsp;<b>{field}:</b></td>
+   <td colspan="2" valign="top" width="70%">{data}</td>
+  </tr>
+<!-- END list -->
+<!-- BEGIN hr -->
+ <tr>
+  <td colspan="3" bgcolor="{th_bg}" align="center">
+   <b>{hr_text}</b>
+  </td>
+ </tr>
+<!-- END hr -->
Index: /tags/calendar/0.9.3/templates/jerryr/mini_cal.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/jerryr/mini_cal.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/jerryr/mini_cal.tpl	(revision 2)
@@ -0,0 +1,36 @@
+<!-- BEGIN mini_cal -->
+<table width=100%><tr>
+						<td>
+							<table align="center" border=0 width="200" cellpadding=0 cellspacing=0 bgcolor="#faf8f3">
+								<tr>
+									<td width=8 class="calLtLtTitleBeige"></td>
+									<td width=8 class="calLtMidTitleBeige"></td>
+									<td  nowrap class="calDayTitleBeige" >{month}</td>
+									<td width=8 class="calRtMidTitleBeige" ></td>
+									<td width=8 class="calRtRtTitleBeige" ></td>
+								</tr>
+								<tr>
+									<td width=8 class="calLeftShadow"></td>
+									<td valign="top" colspan=3 ><table border="0" width="100%" cellspacing="7" cellpadding="0" valign="top" cols="7">
+    <tr>{daynames}    </tr>{display_monthweek}   </table></td>
+									<td width=8 class="calRightShadow"></td>
+								</tr>
+								
+								<tr class="calRowBottomShadow">
+									<td width=8 class="calLtLtFoot"></td>
+									<td width=8 class="calLtMidFoot"></td>
+									<td>&nbsp;</td>
+									<td width=8 class="calRtMidFoot"></td>
+									<td width=8 class="calRtRtFoot"></td>
+								</tr>	
+							</table>
+						</td>
+</tr></table>
+<!-- END mini_cal -->
+<!-- BEGIN mini_week -->
+    <tr>{monthweek_day}
+    </tr>
+<!-- END mini_week -->
+<!-- BEGIN mini_day -->
+     <td align="center"{day_image}><font size="-2">{dayname}</font></td>
+<!-- END mini_day -->
Index: /tags/calendar/0.9.3/templates/jerryr/week.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/jerryr/week.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/jerryr/week.tpl	(revision 2)
@@ -0,0 +1,61 @@
+{printer_friendly}
+<table border=0 align="center" class="calDayViewShadowBox" width="100%" cols="5" >
+<tr>
+<td>
+
+
+<table border=0 align="center" width="100%" cols="5" >
+<tr>
+
+  <td align="left" valign="top">
+   {small_calendar_prev}
+  </td>
+  <td align="center" valign="middle" >
+   <b>{prev_week_link}</b>
+  </td>
+  <td align="center" valign="top" >
+   {small_calendar_this}
+  </td>
+  <td align="center" valign="middle" >
+   <b>{next_week_link}</b>
+  </td>
+  <td align="right" valign="top" >
+   {small_calendar_next}
+  </td>
+ </tr>
+</table>
+
+
+
+
+<table><tr><td height="5"></td></tr></table>
+<table border=0  align="center" width=100%>
+	<tr>
+		<td>
+			<table  border="0" width="100%" cellpadding=0 cellspacing=0>
+				<tr>
+					<td width=8 class="calLtLtTitleBlue"></td>
+					<td width=8 class="calLtMidTitleBlue"></td>
+  					<td align="center" class="calDayTitleBlue"><b>{week_identifier}</b>&nbsp;&nbsp;{username}</td>
+					<td width=8 class="calRtMidTitleBlue" ></td>
+					<td width=8 class="calRtRtTitleBlue" ></td>
+				</tr>
+				<tr>
+					<td width=8 class="calLeftShadow"></td>
+					<td colspan=3>{week_display}</td>
+					<td width=8 class="calRightShadow"></td>
+				</tr>
+				<tr class="calRowBottomShadow">
+						<td class="calLtLtFoot"></td>
+						<td class="calLtMidFoot"></td>
+						<td>&nbsp;</td>
+						<td class="calRtMidFoot"></td>
+						<td class="calRtRtFoot"></td>
+					</tr>	
+			</table><p>{print}
+</td>
+	</tr>
+</table>
+</td>
+</tr>
+</table>
Index: /tags/calendar/0.9.3/templates/jerryr/day.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/jerryr/day.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/jerryr/day.tpl	(revision 2)
@@ -0,0 +1,76 @@
+<!-- BEGIN day -->
+{printer_friendly}
+<table border="0" width="100%" class="calDayViewShadowBox">
+	<tr>
+		<td valign="top" width="70%">
+   			<table border="0" cellpadding=0 cellspacing=0 width=100%>
+					<tr>
+						<td width=8 class="calLtLtTitleBlue"></td>
+						<td width=8 class="calLtMidTitleBlue"></td>
+						<td  nowrap class="calDayTitleBlue" >{date}&nbsp;&nbsp;{username}&nbsp;</td>
+						<td width=8 class="calRtMidTitleBlue" ></td>
+						<td width=8 class="calRtRtTitleBlue" ></td>
+					</tr>
+					<tr>
+						<td width=8 class="calLeftShadow"></td>
+						<td valign="top" colspan=3 >
+							<table width=100% cellpadding=0 cellspacing=0>{day_events}</table>
+						</td>
+						<td width=8 class="calRightShadow"></td>
+					</tr>
+					<tr class="calRowBottomShadow">
+						<td width=8 class="calLtLtFoot"></td>
+						<td width=8 class="calLtMidFoot"></td>
+						<td>&nbsp;</td>
+						<td width=8 class="calRtMidFoot"></td>
+						<td width=8 class="calRtRtFoot"></td>
+					</tr>	
+				</table><p>{print}</p>
+			</td>
+			<td width=5></td>
+			<td align="center" valign="top" >
+				<table cellpadding=0 cellspacing=0 width="100%">
+					<tr>
+						<td>{small_calendar}</td>
+					</tr>
+				</table>
+				<table height="5" border=0><tr><td></td></tr></table>
+				<table width=100% cellspacing=0 cellpadding=0>
+					<tr>
+						<td>
+							<table border=0 width="100%" cellpadding=0 cellspacing=0>
+								<tr>
+									<td width=8 class="calLtLtTitleRed"></td>
+									<td width=8 class="calLtMidTitleRed"></td>
+									<td  nowrap class="calDayTitleRed" >{lang_todos}</td>
+									<td width=8 class="calRtMidTitleRed" ></td>
+									<td width=8 class="calRtRtTitleRed" ></td>
+								</tr>
+								<tr>
+									<td width=8 class="calLeftShadow"></td>
+									<td valign="top" colspan=3 >	{todos}</td>
+									<td width=8 class="calRightShadow"></td>
+								</tr>
+								<tr class="calRowBottomShadow">
+									<td width=8 class="calLtLtFoot"></td>
+									<td width=8 class="calLtMidFoot"></td>
+									<td></td>
+									<td width=8 class="calRtMidFoot"></td>
+									<td width=8 class="calRtRtFoot"></td>
+								</tr>	
+							</table>
+						</td>
+					</tr>
+				</table>
+			</td>
+		</tr>
+	</table>
+<!-- END day -->
+<!-- BEGIN day_event -->
+    <tr>
+     <td>
+{daily_events}
+     </td>
+    </tr>
+<!-- END day_event -->
+
Index: /tags/calendar/0.9.3/templates/jerryr/footer.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/jerryr/footer.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/jerryr/footer.tpl	(revision 2)
@@ -0,0 +1,31 @@
+<!-- BEGIN footer_table -->
+		<tr><td height="10"></td></tr>
+       <font size="-1">
+       <table border="0" width="100%" cellpadding="0" cellspacing="0">
+        <tr>
+{table_row}
+	</tr>
+
+       <tr>
+<!-- END footer_table -->
+<!-- BEGIN footer_row -->
+         <td valign="top" width="33%">
+          <font size="-1">
+           <form action="{action_url}" method="post" name="{form_name}">
+            <B>{label}:</B>
+			{hidden_vars}
+            <select name="{form_label}" onchange="{form_onchange}">
+	     {row}
+	    </select>
+            <noscript><input type="submit" value="{go}"></noscript>
+	   </form>
+	  </font>
+	 </td>
+<!-- END footer_row -->
+<!-- BEGIN blank_row -->
+         <td>
+          {b_row}
+         </td>
+<!-- END blank_row -->
+<td>
+
Index: /tags/calendar/0.9.3/templates/jerryr/year.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/jerryr/year.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/jerryr/year.tpl	(revision 2)
@@ -0,0 +1,36 @@
+<!-- BEGIN year -->
+{print}
+<center>
+<table border="0" width="100%" class="calDayViewShadowBox">
+	<tr>
+		<td>
+<table width=100% border="0" cellspacing="3" cellpadding="4" cols=4>
+ <tr>
+  <td align="center">
+   {left_link}
+  </td>
+  <td align="center">
+   <font face="{font}" size="+1">{year_text}</font>
+  </td>
+  <td align="center">
+   {right_link}
+  </td>
+   {row}
+ </tr>
+</table><p>{printer_friendly}
+</td>
+</tr>
+</table>
+</center>
+
+<!-- END year -->
+<!-- BEGIN month -->
+<td valign="top">
+ {mini_month}
+</td>
+<!-- END month -->
+<!-- BEGIN month_sep -->
+ </tr>
+ <tr valign="top">
+<!-- END month_sep -->
+
Index: /tags/calendar/0.9.3/templates/edge-it/locales.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/locales.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/locales.tpl	(revision 2)
@@ -0,0 +1,60 @@
+<!-- BEGIN list -->
+<p>
+ <table border="0" width="45%" align="center">
+  <tr>
+   <td align="left">{left_next_matchs}</td>
+   {center}
+   <td align="right">{right_next_matchs}</td>
+  </tr>
+ </table>
+
+ <table border="0" width="70%" align="center">
+  <tr bgcolor="{th_bg}">
+   <td>&nbsp;{sort_name}</td>
+   {header_rule}
+   <td>{header_edit}</td>
+   <td>{header_delete}</td>
+   <td>{header_extra}</td>
+  </tr>
+
+  {rows}
+
+ </table>
+
+ <table border="0" width="70%" cellspacing="5" align="center">
+  <tr>
+   <td align="left">
+    <form method="POST" action="{new_action}">
+     <input type="submit" value="{lang_add}">
+    </form>
+   </td>
+   {back_button}
+   <td width="80%" align="right">
+    <form method="POST" action="{search_action}">
+     {lang_search}&nbsp;<input name="query">
+    </form>
+   </td>
+  </tr>
+ </table>
+<!-- END list -->
+<!-- BEGIN row -->
+ <tr bgcolor="{tr_color}">
+  <td>&nbsp;{group_name}</td>
+  {rule}
+  <td width="5%">{edit_link}</td>
+  <td width="5%">{delete_link}</td>
+  <td align="center" {extra_width}>{extra_link}</td>
+ </tr>
+<!-- END row -->
+<!-- BEGIN row_empty -->
+   <tr>
+    <td colspan="5" align="center">{message}</td>
+   </tr>
+<!-- END row_empty -->
+<!-- BEGIN back_button_form -->
+   <td align="center">
+    <form method="POST" action="{back_action}">
+     <input type="submit" value="{lang_back}">
+    </form>
+   </td>
+<!-- END back_button_form -->
Index: /tags/calendar/0.9.3/templates/edge-it/form_button_script.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/form_button_script.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/form_button_script.tpl	(revision 2)
@@ -0,0 +1,12 @@
+
+<!-- BEGIN form_button -->
+<nobr>
+<form action="{action_url_button}" method="post" name="{action_text_button}form">
+<div style="padding-top:15px; padding-right: 2px">
+	{action_extra_field} 
+	<input style="font-size:10px" type="submit" value="{action_text_button}" {action_confirm_button}>
+</div>
+</form>
+</nobr>
+
+<!-- END form_button -->
Index: /tags/calendar/0.9.3/templates/edge-it/month.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/month.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/month.tpl	(revision 2)
@@ -0,0 +1,6 @@
+
+<table id="calendar_month_table" width="100%" border="0" bordercolor="#FFFFFF" cellspacing="2" cellpadding="2" cols={cols}>
+	{row}
+</table>
+
+
Index: /tags/calendar/0.9.3/templates/edge-it/csv_import.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/csv_import.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/csv_import.tpl	(revision 2)
@@ -0,0 +1,74 @@
+<!-- BEGIN filename -->
+	  		<TR>
+	    		<TD>{lang_csvfile}</td>
+				<td><INPUT NAME="csvfile" SIZE=30 TYPE="file" VALUE="{csvfile}"></td>
+			</tr>
+			<tr>
+				<td>{lang_fieldsep}</td>
+				<td><input name="fieldsep" size=1 value="{fieldsep}"></td>
+			</tr>
+			<tr>
+				<td>{lang_charset}</td>
+				<td>
+			{select_charset}
+				</td>
+			</tr>
+			<tr><td>&nbsp;</td>
+				<td><INPUT NAME="convert" TYPE="submit" VALUE="{submit}"></TD>
+			</TR>
+<!-- END filename -->
+
+<!-- BEGIN fheader -->
+			<tr>
+				<td><b>{lang_csv_fieldname}</b></td>
+				<td><b>{lang_info_fieldname}</b></td>
+				<td><b>{lang_translation}</b></td>
+			</tr>
+<!-- END fheader -->
+
+<!-- BEGIN fields -->
+			<tr>
+				<td>{csv_field}</td>
+				<td><SELECT name="cal_fields[{csv_idx}]">{cal_fields}</select></td>
+				<td><input name="trans[{csv_idx}]" size=60 value="{trans}"></td>
+			</tr>
+<!-- END fields -->
+
+<!-- BEGIN ffooter -->
+			<tr>
+				<td rowspan="2" valign="middle" nowrap><br>{submit}</TD>
+				<td colspan="2"><br>
+					{lang_start} <INPUT name="start" type="text" size="5" value="{start}"> &nbsp; &nbsp;
+					{lang_max} <INPUT name="max" type="text" size="3" value="{max}"><td>
+			</tr>
+			<tr>
+				<td colspan="2"><INPUT name="debug" type="checkbox" value="1"{debug}> {lang_debug}</td>
+			</TR>
+			<tr><td colspan="3">&nbsp;<p>
+				{help_on_trans}
+			</td></tr>
+<!-- END ffooter -->
+
+<!-- BEGIN imported -->
+			<tr>
+				<td colspan=2 align=center>
+					{log}<p>
+					{anz_imported}
+				</td>
+			</TR>
+<!-- END imported -->
+
+<!-- BEGIN import -->
+<br/>
+<center>
+		<form {enctype} action="{action_url}" method="post">
+		<table>
+
+		{rows}
+
+		</table>
+		{hiddenvars}
+		</form>
+
+</center>
+<!-- END import -->
Index: /tags/calendar/0.9.3/templates/edge-it/header.inc.php
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/header.inc.php	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/header.inc.php	(revision 2)
@@ -0,0 +1,225 @@
+<?php
+  /**************************************************************************\
+  * eGroupWare                                                               *
+  * http://www.egroupware.org                                                *
+  * --------------------------------------------                             *
+  *  This program is free software; you can redistribute it and/or modify it *
+  *  under the terms of the GNU General Public License as published by the   *
+  *  Free Software Foundation; either version 2 of the License, or (at your  *
+  *  option) any later version.                                              *
+  \**************************************************************************/
+
+
+	function add_col(&$tpl,$str)
+	{
+		$tpl->set_var('str',$str);
+		$tpl->parse('header_column','head_col',True);
+	}
+
+	function add_image_ahref($link,$image,$alt)
+	{
+		return '<a href="'.$link.'"><img src="'.$GLOBALS['phpgw']->common->image('calendar',$image).'" alt="'.$alt.'" title="'.$alt.'" border="0"></a>';
+	}
+
+	$refer = explode('.',$GLOBALS['HTTP_GET_VARS']['menuaction']);
+	$referrer = $refer[2];
+
+	$templates = Array(
+		'head_tpl'	=> 'head.tpl',
+		'form_button_dropdown'	=> 'form_button_dropdown.tpl',
+		'form_button_script'	=> 'form_button_script.tpl'
+	);
+	$tpl->set_file($templates);
+	$tpl->set_block('head_tpl','head','head');
+	$tpl->set_block('head_tpl','head_table','head_table');
+	$tpl->set_block('head_tpl','head_col','head_col');
+	$tpl->set_block('form_button_script','form_button');
+
+	if(floor(phpversion()) >= 4)
+	{
+		$tpl->set_var('cols',8);
+	}
+	else
+	{
+		$tpl->set_var('cols',7);
+	}
+
+	$today = date('Ymd',$GLOBALS['phpgw']->datetime->users_localtime);
+
+	$col_width = 12;
+
+	add_col($tpl,'  <td width="2%">&nbsp;</td>');
+
+	add_col($tpl,'  <td width="2%">'.add_image_ahref($this->page('day','&date='.$today),'today',lang('Today')).'</td>');
+
+	add_col($tpl,'  <td width="2%" align="left">'.add_image_ahref($this->page('week','&date='.$today),'week',lang('This week')).'</td>');
+
+	add_col($tpl,'  <td width="2%" align="left">'.add_image_ahref($this->page('month','&date='.$today),'month',lang('This month')).'</td>');
+
+	add_col($tpl,'  <td width="2%" align="left">'.add_image_ahref($this->page('year','&date='.$today),'year',lang('This Year')).'</td>');
+
+	if(floor(phpversion()) >= 4)
+	{
+		add_col($tpl,'  <td width="2%" align="left">'.add_image_ahref($this->page('planner','&date='.$today),'planner',lang('Planner')).'</td>');
+		$col_width += 2;
+	}
+
+	add_col($tpl,'  <td width="2%" align="left">'.add_image_ahref($this->page('matrixselect'),'view',lang('Daily Matrix View')).'</td>');
+
+	add_col($tpl,'  <td width="'.(100 - $col_width).'%" align="left"'.(floor(phpversion()) < 4?' colspan="2"':'').'>&nbsp;</td>');
+
+	$tpl->parse('row','head_table',True);
+
+	$tpl->set_var('header_column','');
+	$tpl->set_var('cols',$cols);
+
+	if($referrer!='view')
+	{
+		$remainder = 72;
+		
+		$date = (isset($GLOBALS['date'])?$GLOBALS['date']:'');
+		$date = (isset($GLOBALS['HTTP_GET_VARS']['date'])?$GLOBALS['HTTP_GET_VARS']['date']:$date);
+		$date = ($date=='' && isset($GLOBALS['HTTP_POST_VARS']['date'])?$GLOBALS['HTTP_POST_VARS']['date']:$date);
+
+		$base_hidden_vars = '<input type="hidden" name="from" value="'.$GLOBALS['HTTP_GET_VARS']['menuaction'].'">'."\n";
+		if(isset($GLOBALS['HTTP_GET_VARS']['cal_id']) && $GLOBALS['HTTP_GET_VARS']['cal_id'] != 0)
+		{
+			$base_hidden_vars .= '    <input type="hidden" name="cal_id" value="'.$GLOBALS['HTTP_GET_VARS']['cal_id'].'">'."\n";
+		}
+		if(isset($GLOBALS['HTTP_POST_VARS']['keywords']) && $GLOBALS['HTTP_POST_VARS']['keywords'])
+		{
+			$base_hidden_vars .= '    <input type="hidden" name="keywords" value="'.$GLOBALS['HTTP_POST_VARS']['keywords'].'">'."\n";
+		}
+		if(isset($GLOBALS['HTTP_POST_VARS']['matrixtype']) && $GLOBALS['HTTP_POST_VARS']['matrixtype'])
+		{
+			$base_hidden_vars .= '    <input type="hidden" name="matrixtype" value="'.$GLOBALS['HTTP_POST_VARS']['matrixtype'].'">'."\n";
+		}
+		if($date)
+		{
+			$base_hidden_vars .= '    <input type="hidden" name="date" value="'.$date.'">'."\n";
+		}
+		$base_hidden_vars .= '    <input type="hidden" name="month" value="'.$this->bo->month.'">'."\n";
+		$base_hidden_vars .= '    <input type="hidden" name="day" value="'.$this->bo->day.'">'."\n";
+		$base_hidden_vars .= '    <input type="hidden" name="year" value="'.$this->bo->year.'">'."\n";
+		
+		if(isset($GLOBALS['HTTP_POST_VARS']['participants']) && $GLOBALS['HTTP_POST_VARS']['participants'])
+		{
+			for ($i=0;$i<count($GLOBALS['HTTP_POST_VARS']['participants']);$i++)
+			{
+				$base_hidden_vars .= '    <input type="hidden" name="participants[]" value="'.$GLOBALS['HTTP_POST_VARS']['participants'][$i].'">'."\n";
+			}
+		}
+
+		$var = Array(
+			'form_width' => '28',
+			'form_link'	=> $this->page($referrer),
+			'form_name'	=> 'cat_id',
+			'title'	=> lang('Category'),
+			'hidden_vars'	=> $base_hidden_vars,
+			'form_options'	=> '<option value="0">'.lang('All').'</option>'.$this->cat->formated_list('select','all',$this->bo->cat_id,'True'),
+			'button_value'	=> lang('Go!')
+		);
+		$tpl->set_var($var);
+		$tpl->set_var('str',$tpl->fp('out','form_button_dropdown'));
+		$tpl->parse('header_column','head_col',True);
+
+		if($GLOBALS['HTTP_GET_VARS']['menuaction'] == 'calendar.uicalendar.planner')
+		{
+			$remainder -= 28;
+			print_debug('Sort By',$this->bo->sortby);
+
+			$form_options = '<option value="user"'.($this->bo->sortby=='user'?' selected':'').'>'.lang('User').'</option>'."\n";
+			$form_options .= '     <option value="category"'.((!isset($this->bo->sortby) || !$this->bo->sortby) || $this->bo->sortby=='category'?' selected':'').'>'.lang('Category').'</option>'."\n";
+		
+			$var = Array(
+				'form_width' => '28',
+				'form_link'	=> $this->page($referrer),
+				'form_name'	=> 'sortby',
+				'title'	=> lang('Sort By'),
+				'hidden_vars'	=> $base_hidden_vars,
+				'form_options'	=> $form_options,
+				'button_value'	=> lang('Go!')
+			);
+			$tpl->set_var($var);
+			$tpl->set_var('str',$tpl->fp('out','form_button_dropdown'));
+			$tpl->parse('header_column','head_col',True);
+		}
+
+		if($this->bo->check_perms(PHPGW_ACL_PRIVATE))
+		{
+			$remainder -= 28;
+			$form_options = '<option value=" all "'.($this->bo->filter==' all '?' selected':'').'>'.lang('All').'</option>'."\n";
+			$form_options .= '     <option value=" private "'.((!isset($this->bo->filter) || !$this->bo->filter) || $this->bo->filter==' private '?' selected':'').'>'.lang('Private Only').'</option>'."\n";
+		
+			$var = Array(
+				'form_width' => '28',
+				'form_link'	=> $this->page($referrer),
+				'form_name'	=> 'filter',
+				'title'	=> lang('Filter'),
+				'hidden_vars'	=> $base_hidden_vars,
+				'form_options'	=> $form_options,
+				'button_value'	=> lang('Go!')
+			);
+			$tpl->set_var($var);
+			$tpl->set_var('str',$tpl->fp('out','form_button_dropdown'));
+			$tpl->parse('header_column','head_col',True);
+		}
+
+		if((!isset($GLOBALS['phpgw_info']['server']['deny_user_grants_access']) || !$GLOBALS['phpgw_info']['server']['deny_user_grants_access']) && count($this->bo->grants) > 0)
+		{
+			$form_options = '';
+			$drop_down = $this->bo->list_cals();
+			foreach($drop_down as $key => $grant)
+			{
+				$form_options .= '    <option value="'.$grant['value'].'"'.($grant['grantor']==$this->bo->owner?' selected':'').'>'.$grant['name'].'</option>'."\n";
+			}
+		
+			$var = Array(
+				'form_width' => $remainder,
+				'form_link'	=> $this->page($referrer),
+				'form_name'	=> 'owner',
+				'title'	=> lang('User'),
+				'hidden_vars'	=> $base_hidden_vars,
+				'form_options'	=> $form_options,
+				'button_value'	=> lang('Go!')
+			);
+			$tpl->set_var($var);
+			$tpl->set_var('str',$tpl->fp('out','form_button_dropdown'));
+			$tpl->parse('header_column','head_col',True);
+		}
+	}
+
+	$hidden_vars = '    <input type="hidden" name="from" value="'.$GLOBALS['HTTP_GET_VARS']['menuaction'].'">'."\n";
+	if(isset($GLOBALS['HTTP_GET_VARS']['date']) && $GLOBALS['HTTP_GET_VARS']['date'])
+	{
+		$hidden_vars .= '    <input type="hidden" name="date" value="'.$GLOBALS['HTTP_GET_VARS']['date'].'">'."\n";
+	}
+	$hidden_vars .= '    <input type="hidden" name="month" value="'.$this->bo->month.'">'."\n";
+	$hidden_vars .= '    <input type="hidden" name="day" value="'.$this->bo->day.'">'."\n";
+	$hidden_vars .= '    <input type="hidden" name="year" value="'.$this->bo->year.'">'."\n";
+	if(isset($this->bo->filter) && $this->bo->filter)
+	{
+		$hidden_vars .= '    <input type="hidden" name="filter" value="'.$this->bo->filter.'">'."\n";
+	}
+	if(isset($this->bo->sortby) && $this->bo->sortby)
+	{
+		$hidden_vars .= '    <input type="hidden" name="sortby" value="'.$this->bo->sortby.'">'."\n";
+	}
+	if(isset($this->bo->num_months) && $this->bo->num_months)
+	{
+		$hidden_vars .= '    <input type="hidden" name="num_months" value="'.$this->bo->num_months.'">'."\n";
+	}
+	$hidden_vars .= '    <input name="keywords"'.($GLOBALS['HTTP_POST_VARS']['keywords']?' value="'.$GLOBALS['HTTP_POST_VARS']['keywords'].'"':'').'>';
+
+	$var = Array(
+		'action_url_button'	=> $this->page('search'),
+		'action_text_button'	=> lang('Search'),
+		'action_confirm_button'	=> '',
+		'action_extra_field'	=> $hidden_vars
+	);
+	$tpl->set_var($var);
+	$button = $tpl->fp('out','form_button');
+	$tpl->set_var('str','<td align="right" valign="bottom">'.$button.'</td>');
+	$tpl->parse('header_column','head_col',True);
+	$tpl->parse('row','head_table',True);
+?>
Index: /tags/calendar/0.9.3/templates/edge-it/holiday.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/holiday.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/holiday.tpl	(revision 2)
@@ -0,0 +1,33 @@
+<!-- BEGIN form -->
+<center>
+{message}<br>
+<table border="0" width="80%" cellspacing="2" cellpadding="2"> 
+ <form name="form" action="{actionurl}" method="POST">
+  {hidden_vars}
+{rows}
+ <tr>
+  <td colspan="2">
+   <table width="100%" border="0" cellspacing="5">
+    <tr>
+     <td>
+      <input type="submit" name="submit" value="{lang_add}"></form>
+     </td>
+     <td>
+      {cancel_button}
+     </td>
+     <td align="right" width="80%">
+      {delete_button}
+     </td>
+    </tr>
+   </table>
+  <td>
+ </tr>
+</table>
+</center>
+<!-- END form -->
+<!-- BEGIN list -->
+ <tr bgcolor="{tr_color}">
+  <td valign="top" width="35%"><b>{field}:</b></td>
+  <td valign="top" width="65%">{data}</td>
+ </tr>
+<!-- END list -->
Index: /tags/calendar/0.9.3/templates/edge-it/pref.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/pref.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/pref.tpl	(revision 2)
@@ -0,0 +1,22 @@
+<!-- BEGIN pref -->
+<p><b>{title}:</b><hr><p>
+<form action="{action_url}" method="POST">
+ <table border="0" align="center" width="90%">
+  {row}
+ </table>
+ <center><input type="submit" name="submit" value="{submit_lang}"></center>
+</form>
+<!-- END pref -->
+
+<!-- BEGIN pref_colspan -->
+  <tr bgcolor="{bg_color}">
+   <td colspan="2">{text}</td>
+  </tr>
+<!-- END pref_colspan -->
+
+<!-- BEGIN pref_list -->
+  <tr bgcolor="{bg_color}">
+   <td align="right">{field}</td>
+   <td align="center">{data}</td>
+  </tr>
+<!-- END pref_list -->
Index: /tags/calendar/0.9.3/templates/edge-it/alarm.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/alarm.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/alarm.tpl	(revision 2)
@@ -0,0 +1,62 @@
+<!-- BEGIN alarm_management -->
+<form id="calendar_alarmform" action="{action_url}" method="post" name="alarmform">
+{hidden_vars}
+	<table id="calendar_alarmform_table" border="0" width="90%" align="center">
+		{rows}
+		<tr>
+			<td colspan="4">
+				<br>&nbsp;{input_days}&nbsp;{input_hours}&nbsp;{input_minutes}&nbsp;{input_owner}&nbsp;{input_add}<br>&nbsp;
+			</td>
+			<td align="right">
+				{input_cancel}
+			</td>
+		</tr>
+	</table>
+</form>
+<!-- END alarm_management -->
+
+<!-- BEGIN alarm_headers -->
+	<tr bgcolor="{tr_color}">
+		<th align="left" width="25%">{lang_time}</th>
+		<th align="left" width="30%">{lang_text}</th>
+		<th align="left" width="25%">{lang_owner}</th>
+		<th width="10%">{lang_enabled}</th>
+		<th width="10%">{lang_select}</th>
+	</tr>
+<!-- END alarm_headers -->
+
+<!-- BEGIN list -->
+	<tr bgcolor="{tr_color}">
+		<td>
+			<b>{field}:</b>
+		</td>
+		<td>
+			{data}
+		</td>
+		<td>
+			{owner}
+		</td>
+		<td align="center">
+			{enabled}
+		</td>
+		<td align="center">
+			{select}
+		</td>
+	</tr>
+<!-- END list -->
+
+<!-- BEGIN hr -->
+	<tr bgcolor="{th_bg}">
+		<td colspan="5" align="center">
+			<b>{hr_text}</b>
+		</td>
+	</tr>
+<!-- END hr -->
+
+<!-- BEGIN buttons -->
+	<tr>
+		<td colspan="6" align="right">
+			{enable_button}&nbsp;{disable_button}&nbsp;{delete_button}
+		</td>
+	</tr>
+<!-- END buttons -->
Index: /tags/calendar/0.9.3/templates/edge-it/month_header.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/month_header.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/month_header.tpl	(revision 2)
@@ -0,0 +1,13 @@
+
+<!-- BEGIN monthly_header -->
+<tr class="calendar_m_w_table_header" colspan="{cols}" width="{col_width}%">
+{column_header}</tr>
+<!-- END monthly_header -->
+
+<!-- BEGIN column_title -->
+<th class="calendar_weekview_daytitle" width="14.28%">{col_title}</th>
+<!-- END column_title -->
+
+<!-- BEGIN month_column -->
+<td class="calendar_m_w_tablecell" colspan="1" width="{col_width}%"{extra}>{column_data}</td>
+<!-- END month_column -->
Index: /tags/calendar/0.9.3/templates/edge-it/footer.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/footer.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/footer.tpl	(revision 2)
@@ -0,0 +1,30 @@
+<!-- BEGIN footer_table -->
+       <hr clear="all">
+       <font size="-1">
+       <table border="0" width="100%" cellpadding="0" cellspacing="0">
+        <tr>
+{table_row}
+	</tr>
+       </table>
+<!-- END footer_table -->
+<!-- BEGIN footer_row -->
+         <td valign="top" width="33%">
+          <font size="-1">
+           <form action="{action_url}" method="post" name="{form_name}">
+            <B>{label}:</B>
+			{hidden_vars}
+            <select name="{form_label}" onchange="{form_onchange}">
+	     {row}
+	    </select>
+            <noscript><input type="submit" value="{go}"></noscript>
+	   </form>
+	  </font>
+	 </td>
+<!-- END footer_row -->
+<!-- BEGIN blank_row -->
+         <td>
+          {b_row}
+         </td>
+<!-- END blank_row -->
+
+
Index: /tags/calendar/0.9.3/templates/edge-it/custom_fields.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/custom_fields.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/custom_fields.tpl	(revision 2)
@@ -0,0 +1,45 @@
+<!-- BEGIN custom_fields -->
+{lang_error}<br>
+<form action="{action_url}" method="post">
+ {hidden_vars}
+ <center>
+  <table border="0" width="90%">
+   <tr class="th">
+    <th align="left" width="30%">{lang_name}</th>
+    <th>{lang_length}</th>
+    <th>{lang_shown}</th>
+    <th>{lang_order}</th>
+    <th>{lang_title}</th>
+    <th>{lang_disabled}</th>
+    <th>&nbsp;</th>
+   </tr>
+   {rows}
+   <tr class="th">
+    <td>{name}</td>
+    <td align="center">{length}</td>
+    <td align="center">{shown}</td>
+    <td align="center">{order}</td>
+    <td align="center">{title}</td>
+    <td align="center">{disabled}</td>
+    <td align="center">{button}</td>
+   </tr>
+   <tr>
+    <td>{save_button} &nbsp; {cancel_button}</td>
+   </tr>
+  </table>
+ </center>
+</form>
+<br>
+<!-- END custom_fields -->
+
+<!-- BEGIN row -->
+   <tr bgcolor="{tr_color}">
+    <td>{name}</td>
+    <td align="center">{length}</td>
+    <td align="center">{shown}</td>
+    <td align="center">{order}</td>
+    <td align="center">{title}</td>
+    <td align="center">{disabled}</td>
+    <td align="center">{button}</td>
+   </tr>
+<!-- END row -->
Index: /tags/calendar/0.9.3/templates/edge-it/search.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/search.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/search.tpl	(revision 2)
@@ -0,0 +1,29 @@
+<!-- BEGIN search -->
+<table id="calendar_search_table" width="90%">
+	<tr>
+		<td colspan="2" align="center" bgcolor="{th_bg}">
+			<b>{quantity}</b>
+		</td>
+	</tr>
+	{rows}
+</table>
+<!-- END search -->
+
+<!-- BEGIN search_list_header -->
+
+<!-- END search_list_header -->
+
+<!-- BEGIN search_list -->
+	<tr bgcolor="{tr_color}">
+		<td width="20%">
+			&nbsp;{date}
+		</td>
+		<td>
+			{link}
+		</td>
+	</tr>
+<!-- END search_list -->
+
+<!-- BEGIN search_list_footer -->
+
+<!-- END search_list_footer -->
Index: /tags/calendar/0.9.3/templates/edge-it/overlap.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/overlap.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/overlap.tpl	(revision 2)
@@ -0,0 +1,30 @@
+<!-- BEGIN overlap -->
+<center><br />
+<table id="calendar_overlap_table">
+	<tr>
+		<td>
+			{overlap_text}
+		</td>
+	</tr>
+	<tr>
+		<td>
+			<ul>{overlap_list}</ul>
+		</td>
+	</tr>
+	<tr>
+		<td>
+			<table id="calendar_overlap_table2" cellspacing="5">
+				<tr>
+					<td>
+						{resubmit_button}
+					</td>
+					<td>
+						{reedit_button}
+					</td>
+				</tr>
+			</table>
+		</td>
+	</tr>
+</table>
+</center>
+<!-- END overlap -->
Index: /tags/calendar/0.9.3/templates/edge-it/day_list.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/day_list.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/day_list.tpl	(revision 2)
@@ -0,0 +1,28 @@
+<!-- BEGIN day -->
+<div class="event-off">
+<table border="0" width="100%" cellpadding="0">
+	<tr>
+		<td class="event-on">
+{row}
+		</td>
+	</tr>
+</table>
+</div>
+<!-- END day -->
+<!-- BEGIN day_row -->
+    <font style="font-size: 8pt;">{event}</font>
+<!-- END day_row -->
+<!-- BEGIN day_event_on -->
+	<font class="event-on">{event}</font>
+<!-- END day_event_on -->
+<!-- BEGIN day_event_off -->
+	<font class="event-on">{event}</font>
+<!-- END day_event_off -->
+<!-- BEGIN day_event_holiday -->
+	{event}
+<!-- END day_event_holiday -->
+<!-- BEGIN day_time -->
+	{time}
+     <!--<td class="time" nowrap>{open_link}{time}{close_link}</td>-->
+<!-- END day_time -->
+
Index: /tags/calendar/0.9.3/templates/edge-it/hr.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/hr.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/hr.tpl	(revision 2)
@@ -0,0 +1,6 @@
+ <tr>
+  <td colspan="2">
+   {hr_text}
+  </td>
+ </tr>
+
Index: /tags/calendar/0.9.3/templates/edge-it/app.css
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/app.css	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/app.css	(revision 2)
@@ -0,0 +1,257 @@
+/* CSS Document */
+
+.to_continue
+{
+	font-size: 9px;
+}
+
+A.minicalendar 
+{ 
+	color: #000000; 
+	font-size: 9px;
+	
+}
+
+A.bminicalendar 
+{ 
+	color: #336699; 
+	font-style: italic;
+	font-weight: bold;
+	font-size: 9px; 
+}
+
+A.minicalendargrey 
+{ 
+	color: #999999; 
+	font-size: 10px;
+	font-weight: bold;
+}
+
+A.bminicalendargrey 
+{ 
+	color: #336699; 
+	font-style: italic; 
+	font-size:10px; 
+}
+
+A.minicalhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #000000; 
+	font-size: 10px; 
+}
+
+A.bminicalhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #336699; 
+	font-size: 10px; 
+}
+
+A.minicalgreyhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #999999; 
+	font-size: 10px; 
+}
+
+A.bminicalgreyhol
+{ 
+	padding-left:3px;
+	padding-right:3px;
+	background: #dab0b0;
+	color: #999999; 
+	font-size: 10px; 
+}
+
+
+.event-on
+{ 
+	background: #D3DCE3;
+	border: #E8F0F0 1px solid;
+}
+
+.event-off
+{ 
+	background: #E8F0F0;
+	border: #D3DCE3 1px solid;
+}
+
+.event-holiday
+{
+	font-size: 100%;
+	background: #dac0c0;
+	color:#000000;
+	vertical-align: middle;
+}
+
+.time
+{
+	background: #D3DCE3;
+	color:#000000;
+	font-size: 10px;
+	font-weight: bold;
+	vertical-align: middle;
+	width: 5.2%;
+	text-align: right;
+	padding-right: 5px;
+	line-height: 11px;
+	border: #E8F0F0 1px solid;
+}
+
+
+.planner-cell
+{
+	cursor: pointer;
+	cursor: hand;
+	border: thin solid black;
+}
+
+/* common */
+.calendar_link_print
+{
+	text-align: center;
+	font-size: 10px;
+}
+
+//Mini Calendar
+
+.calendar_minical_table
+{
+	width: 180px;
+	font-weight: bold;
+}
+
+.calendar_minical_daytable
+{
+	width: 100%;
+}
+
+.calendar_minical_dayname
+{
+	font-size: 9px;
+	text-align: right;
+}
+
+.calendar_minical_hrule
+{
+	width: 96%;
+}
+
+/* Header */
+.calendar_dropbuttons
+{
+	align: center;
+	text-align: center;
+	vertical-align: bottom;
+	font-weight: bold;
+	font-size: 8px;
+}
+
+.calendar-weekidentifier
+{
+	font-size:16px;
+	font-weight: bold;
+	text-align: center;
+}
+
+.calendar_header
+{
+	font-size: 16px;
+	font-weight: bold;
+	text-align: center;
+}
+
+.calendar_dayview_table_header
+{
+	font-size: 13px;
+	font-weight: bold;
+	text-align: center;
+}
+
+.calendar_dayview_todo_header
+{
+	margin: 0px; 
+	padding: 2px;
+	font-weight: bold;
+}
+
+/* week view */
+.calendar_week_identifier_table
+{
+	border: 0px solid black;
+	width: 100%;
+}
+
+.calendar_week_identifier
+{
+	font-size: 13px;
+	text-align: center;
+	font-weight: bold;
+}
+
+.calendar_weekview_daytitle
+{
+	font-weight: bold;
+	font-size: 12px;
+	background: #D3DCE3;
+}
+
+.calendar_m_w_table
+{
+	table-layout:fixed;
+	overflow:auto;
+	height: 100%;
+	width: 100%;
+	border: 0px #000000 solid;
+}
+
+.calendar_m_w_tablecell
+{
+	vertical-align: top;
+	padding-left: 4px;
+	padding-right: 4px;
+	padding-bottom: 6px;
+}
+
+A.event_entry
+{
+	font-size:10px;
+}
+
+/* month view */
+
+.calendar_month_identifier
+{
+	font-size:14px;
+	font-weight: bold;
+}
+
+.calendar_user_identifier
+{
+	font-size:12px;
+	color: #009999;
+	font-weight: bold;
+}
+
+.calendar_week_minical_table
+{
+	width:100%;
+	border: 0px solid #000000
+}
+
+.calendar_weekinfo
+{
+	color: #000000;
+	padding-left: 2px;
+	padding-right: 2px;
+	font-size: 10px;
+	font-weight: bold;
+	font-style: italic;
+}
Index: /tags/calendar/0.9.3/templates/edge-it/view.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/view.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/view.tpl	(revision 2)
@@ -0,0 +1,46 @@
+
+<!-- BEGIN view_event -->
+<center>
+<table id="calendar_view_event" border="0" width="90%">
+	{row}
+	<tr>
+		<td>
+			<table id="calendar_viewevent_button_left" cellspacing="5">
+				<tr>
+					{button_left}
+				</tr>
+			</table>
+		</td>
+	   <td align="center">
+			<table id="calendar_viewevent_button_center" cellspacing="5">
+				<tr>
+					{button_center}
+				</tr>
+			</table>
+		</td>
+		<td align="right">
+			<table id="calendar_viewevent_button_right" cellspacing="5">
+				<tr>
+					{button_right}
+				</tr>
+			</table>
+		</td>
+	</tr>
+</table>
+</center>
+<!-- END view_event -->
+
+<!-- BEGIN list -->
+	<tr bgcolor="{tr_color}">
+		<td valign="top" width="30%">&nbsp;<b>{field}:</b></td>
+		<td colspan="2" valign="top" width="70%">{data}</td>
+	</tr>
+<!-- END list -->
+
+<!-- BEGIN hr -->
+	<tr>
+		<td colspan="3" bgcolor="{th_bg}" align="center">
+			<b>{hr_text}</b>
+		</td>
+	</tr>
+<!-- END hr -->
Index: /tags/calendar/0.9.3/templates/edge-it/delete_common.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/delete_common.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/delete_common.tpl	(revision 2)
@@ -0,0 +1,16 @@
+<!-- BEGIN form -->
+ <center>
+  <table border="0" with="65%">
+   <tr>
+    <td colspan="2" align="center">
+     {messages}
+    </td>
+   </tr>
+   <tr>
+    <td align="center">{no}</td>
+    <td align="center">{yes}</td>
+   </tr>
+  </table>
+ </center>
+<!-- END form -->
+
Index: /tags/calendar/0.9.3/templates/edge-it/list.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/list.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/list.tpl	(revision 2)
@@ -0,0 +1,6 @@
+<!-- BEGIN list -->
+ <tr>
+  <td valign="top" width="35%"><b>{field}:</b></td>
+  <td valign="top" width="65%">{data}</td>
+ </tr>
+<!-- END list -->
Index: /tags/calendar/0.9.3/templates/edge-it/mini_cal.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/mini_cal.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/mini_cal.tpl	(revision 2)
@@ -0,0 +1,42 @@
+
+<!-- BEGIN mini_cal -->
+
+	<table id="calendar_minical_table" class="calendar_minical_table" border=0 cellspacing="0" cellpadding="0">
+		<tr>
+			<td style="padding-left: 8px; font-weight: bold; text-align: left;">
+				{month}
+			</td>
+			<td align="right">
+				<!-- why empty? -->
+				{prevmonth}&nbsp;&nbsp;{nextmonth}
+			</td>
+		</tr>
+		<tr>
+			<td  style="padding-left: 8px; text-align: left;">
+<!--				<img src="{cal_img_root}" width="90%" height="1"> -->
+					<hr class="calendar_minical_hrule">
+			</td>
+		</tr>
+		<tr valign="top">
+			<td>
+				<table id="calendar_minical_daytable" class="calendar_minical_daytable" cellspacing="5" cellpadding="0">
+					<tr>{daynames}</tr>
+						{display_monthweek}
+				</table>
+
+			</td>
+	 	</tr>
+	</table>
+<!-- END mini_cal -->
+
+<!-- BEGIN mini_week -->
+	<tr>
+		{monthweek_day}
+	</tr>
+<!-- END mini_week -->
+
+<!-- BEGIN mini_day -->
+		<td class="calendar_minical_dayname" {day_image}>
+			{dayname}
+		</td>
+<!-- END mini_day -->
Index: /tags/calendar/0.9.3/templates/edge-it/link_pict.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/link_pict.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/link_pict.tpl	(revision 2)
@@ -0,0 +1,25 @@
+
+<!-- BEGIN link_pict -->
+{picture}
+<!-- END link_pict -->
+
+<!-- BEGIN link_open -->
+<div id="calendar_event_entry" style="overflow:hidden;">
+<a class="event_entry" href="{link_link}" onMouseOver="window.status='{lang_view}'; return true;" onMouseOut="window.status=''; return true;" title="{desc} {location}"><br>
+<!-- END link_open -->
+
+<!-- BEGIN pict -->
+ <img src="{pic_image}" width="{width}" height="{height}" title="{title}" border="0" />
+<!-- END pict -->
+
+<!-- BEGIN link_text_old -->
+<nobr>&nbsp;{time}&nbsp;</nobr> {title}&nbsp;{users_status}: <i>{desc}</i><!--({location})-->
+<!-- END link_text_old -->
+
+<!-- BEGIN link_text -->
+<nobr>&nbsp;<span style="color: black">{time}</span> {users_status}</nobr><br><b>{title}</b><br><i>{desc}</i> {location}
+<!-- END link_text -->
+
+<!-- BEGIN link_close -->
+</a></div>
+<!-- END link_close -->
Index: /tags/calendar/0.9.3/templates/edge-it/day.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/day.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/day.tpl	(revision 2)
@@ -0,0 +1,46 @@
+<!-- BEGIN day -->
+{printer_friendly}
+<table id="calendar_dayview_table" class="calendar_dayview_table" border="0" width="100%">
+	<tr>
+		<td valign="top" width="70%">
+			<table id="calendar_dayview1" border="0" width=100%>
+				<tr>
+					<td class="calendar_dayview_table_header">
+      					{date}&nbsp;<span class="calendar_user_identifier">:&nbsp;{username}&nbsp;:</span>
+						<br />
+     				</td>
+    			</tr>
+				{day_events}
+   			</table>
+   			<p align="center">{print}</p>
+  		</td>
+ 		 <td align="center" valign="top">
+  			 <table id="calendar_dayview2" width="100%">
+    			<tr>
+     				<td align="center">
+						{small_calendar}
+     				</td>
+    			</tr>
+    			<tr>
+     				<td align="center">
+      					<div class="th">
+       						<p class="calendar_dayview_todo_header">{lang_todos}</p>
+								{todos}
+      					</div>
+     				</td>
+    			</tr>
+   			</table>
+  		</td>
+ 	</tr>
+</table>
+<!-- END day -->
+
+<!-- BEGIN day_event -->
+	<tr>
+		<td>
+
+			{daily_events}
+
+		</td>
+	</tr>
+<!-- END day_event -->
Index: /tags/calendar/0.9.3/templates/edge-it/vcal_import.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/vcal_import.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/vcal_import.tpl	(revision 2)
@@ -0,0 +1,10 @@
+<!-- vcardin form -->
+{vcal_header}
+    <form ENCTYPE="multipart/form-data" method="POST" action="{action_url}">
+      <table border=0>
+      <tr>
+       <td>{ical_lang}: <input type="file" name="uploadedfile"></td>
+       <td><input type="submit" name="action" value="{load_vcal}"></td>
+      </tr>
+      </table>
+     </form>
Index: /tags/calendar/0.9.3/templates/edge-it/month_day.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/month_day.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/month_day.tpl	(revision 2)
@@ -0,0 +1,21 @@
+
+<!-- BEGIN m_w_table -->
+
+<table id="calendar_m_w_table" class="calendar_m_w_table">
+	<! from month_header.tpl -->
+	{row}
+</table>
+<!-- END m_w_table -->
+
+<!-- BEGIN month_daily -->
+<span id="calendar_m_w_table_daynumber" style="font-size:10px">[ {day_number} ]</span>{new_event_link}<br />
+    {daily_events}
+<!-- END month_daily -->
+
+<!-- BEGIN day_event -->
+{events}
+<!-- END day_event -->
+
+<!-- BEGIN event -->
+{day_events}
+<!-- END event -->
Index: /tags/calendar/0.9.3/templates/edge-it/preference_acl_row.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/preference_acl_row.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/preference_acl_row.tpl	(revision 2)
@@ -0,0 +1,8 @@
+   <tr bgcolor="{row_color}">
+    <td>{user}</td>
+    <td align="center"><input type="checkbox" name="{read}" value="Y"{read_selected}></td>
+    <td align="center"><input type="checkbox" name="{add}" value="Y"{add_selected}></td>
+    <td align="center"><input type="checkbox" name="{edit}" value="Y"{edit_selected}></td>
+    <td align="center"><input type="checkbox" name="{delete}" value="Y"{delete_selected}></td>
+    <td align="center"><input type="checkbox" name="{private}" value="Y"{private_selected}></td>
+   </tr>
Index: /tags/calendar/0.9.3/templates/edge-it/edit.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/edit.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/edit.tpl	(revision 2)
@@ -0,0 +1,51 @@
+<!-- BEGIN edit_entry -->
+<script language="JavaScript">
+	self.name="first_Window";
+	function accounts_popup()
+	{
+		Window1=window.open('{accounts_link}',"Search","width=800,height=600,toolbar=no,scrollbars=yes,resizable=yes");
+	}
+</script>
+<center>
+<font color="#000000" face="{font}">
+
+<form action="{action_url}" method="post" name="app_form">
+{common_hidden}
+<table border="0" width="90%">
+ <tr>
+  <td colspan="2">
+   <center><font size="+1"><b>{errormsg}</b></font></center>
+  </td>
+ </tr>
+{row}
+ <tr>
+  <td>
+   <table>
+   	<tr>
+    	<td valign="top">
+    	<div style="padding-top:15px; padding-right: 2px">
+    	<input style="font-size:10px" type="submit" value="{submit_button}">&nbsp;
+    	</div>
+    	</td>
+    	<td valign="top">{cancel_button}</td>
+   </tr></table></form>
+  </td>
+  <td align="right">{delete_button}</td>
+ </tr>
+</table>
+</font>
+</center>
+<!-- END edit_entry -->
+<!-- BEGIN list -->
+ <tr bgcolor="{tr_color}">
+  <td valign="top" width="35%">&nbsp;<b>{field}:</b></td>
+  <td valign="top" width="65%">{data}</td>
+ </tr>
+<!-- END list -->
+<!-- BEGIN hr -->
+ <tr bgcolor="{tr_color}">
+  <td colspan="2">
+   {hr_text}
+  </td>
+ </tr>
+<!-- END hr -->
Index: /tags/calendar/0.9.3/templates/edge-it/matrix_query.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/matrix_query.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/matrix_query.tpl	(revision 2)
@@ -0,0 +1,25 @@
+<!-- BEGIN matrix_query -->
+<center>
+<form action="{action_url}" method="post" name="matrixform">
+<table border="0" width="90%">
+ <tr bgcolor="{th_bg}">
+  <td colspan="2" align="center"><b>{title}</b></td>
+ </tr>
+ {rows}
+ <tr>
+  <td>
+   <table cellspacing="5"><tr>
+    <td><input type="submit" value="{submit_button}"></form></td>
+    <td>{cancel_button}</td>
+   </tr></table>
+  </td>
+ </tr>
+</table>
+</center>
+<!-- END matrix_query -->
+<!-- BEGIN list -->
+ <tr bgcolor="{tr_color}">
+  <td valign="top" width="35%"><b>&nbsp;{field}:</b></td>
+  <td valign="top" width="65%">{data}</td>
+ </tr>
+<!-- END list -->
Index: /tags/calendar/0.9.3/templates/edge-it/week.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/week.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/week.tpl	(revision 2)
@@ -0,0 +1,40 @@
+
+{printer_friendly}
+
+<!-- head table with mini calendars -->
+
+<table id="calendar_week_minical_table" class="calendar_week_minical_table">
+	<tr>
+		<td id="small_calendar_prev" align="left" valign="top" width="20%">
+			{small_calendar_prev}
+		</td>
+		<td  id="prev_week_link"  align="center" valign="middle" width="20%">
+			<b>{prev_week_link}</b>
+		</td>
+		<td  id="small_calendar_this"  align="center" valign="top" width="20%">
+			{small_calendar_this}
+		</td>
+		<td  id="next_week_link"  align="center" valign="middle" width="20%">
+			<b>{next_week_link}</b>
+		</td>
+		<td  id="small_calendar_right"  align="right" valign="top" width="20%">
+			{small_calendar_next}
+		</td>
+	</tr>
+</table>
+<br />
+<table id="calendar_week_identifier_table" class="calendar_week_identifier_table">
+	<tr>
+		<td align="center">
+			<span class="calendar_week_identifier">{week_identifier}&nbsp;&nbsp;</span>
+			<span class="calendar_user_identifier">::&nbsp;{username}&nbsp;::</span>
+		</td>
+	</tr>
+</table>
+<!-- from month_day.tpl -->
+{week_display}
+
+<div class="calendar_link_print">
+<br />
+{print}
+</div>
Index: /tags/calendar/0.9.3/templates/edge-it/day_cal.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/day_cal.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/day_cal.tpl	(revision 2)
@@ -0,0 +1,24 @@
+<!-- BEGIN day -->
+<div class="th">
+ <table class="calendar_dayview_maintable" width="100%" cellpadding="0">
+{row}
+</table>
+ </div>
+<!-- END day -->
+<!-- BEGIN day_row -->
+    <tr>{time}{event}
+    </tr>
+<!-- END day_row -->
+<!-- BEGIN day_event_on -->
+     <td class="event-on"{extras}>&nbsp;{event}</td>
+<!-- END day_event_on -->
+<!-- BEGIN day_event_off -->
+     <td class="event-off"{extras}>&nbsp;{event}</td>
+<!-- END day_event_off -->
+<!-- BEGIN day_event_holiday -->
+     <td class="event-holiday"{extras}>&nbsp;{event}</td>
+<!-- END day_event_holiday -->
+<!-- BEGIN day_time -->
+     <td class="time" nowrap>{open_link}{time}{close_link}</td>
+<!-- END day_time -->
+
Index: /tags/calendar/0.9.3/templates/edge-it/preference_acl.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/preference_acl.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/preference_acl.tpl	(revision 2)
@@ -0,0 +1,27 @@
+{errors}
+{title}
+<table border="0" align="center" width="70%">
+ <tr>
+  {nml}
+  <td width="40%">
+   <div align="center">
+    <form method="POST" action="{action_url}">
+{common_hidden_vars}
+     <input type="text" name="query" value="{search_value}">
+     <input type="submit" name="search" value="{search}">
+    </form>
+   </div>
+  </td>
+  {nmr}
+ </tr>
+</table>
+<form method="POST" action="{action_url}">
+ <table border="0" align="center" width="50%" cols="4">
+{row}
+ </table>
+{common_hidden_vars_form}
+ <input type="hidden" name="processed" value="{processed}">
+ <center><input type="submit" name="submit" value="{submit_lang}"></center>
+</form>
+
+
Index: /tags/calendar/0.9.3/templates/edge-it/preference_colspan.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/preference_colspan.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/preference_colspan.tpl	(revision 2)
@@ -0,0 +1,8 @@
+  <tr bgcolor="{bg_color}">
+    <td>{string}</td>
+    <td align="center">{lang_read}</td>
+    <td align="center">{lang_add}</td>
+    <td align="center">{lang_edit}</td>
+    <td align="center">{lang_delete}</td>
+    <td align="center">{lang_private}</td>
+  </tr>
Index: /tags/calendar/0.9.3/templates/edge-it/year.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/year.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/year.tpl	(revision 2)
@@ -0,0 +1,35 @@
+<!-- BEGIN year -->
+{print}
+<center>
+<table id="calendar_year_table" border="0" cellspacing="3" cellpadding="4" cols=4>
+	<tr>
+		<td align="center">
+			{left_link}
+		</td>
+		<td align="center">
+			<font face="{font}" size="+1">{year_text}</font>
+		</td>
+		<td align="center">
+			{right_link}
+		</td>
+		{row}
+	</tr>
+</table>
+</center>
+<p>
+<div class="calendar_link_print">
+{printer_friendly}
+</div>
+<!-- END year -->
+
+<!-- BEGIN month -->
+<td valign="top">
+	{mini_month}
+</td>
+<!-- END month -->
+
+<!-- BEGIN month_sep -->
+</tr>
+<tr valign="top">
+<!-- END month_sep -->
+
Index: /tags/calendar/0.9.3/templates/edge-it/head.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/head.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/head.tpl	(revision 2)
@@ -0,0 +1,16 @@
+
+<!-- BEGIN head -->
+{row}<br />
+<!-- END head -->
+
+<!-- BEGIN head_table -->
+<table id="calendar_head_table" class="calendar_head_table" border="0" width="100%" cols="{cols}" cellpadding="0" cellspacing="0">
+	<tr>
+		{header_column}
+	</tr>
+</table>
+<!-- END head_table -->
+
+<!-- BEGIN head_col -->
+{str}
+<!-- END head_col -->
Index: /tags/calendar/0.9.3/templates/edge-it/month_column.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/month_column.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/month_column.tpl	(revision 2)
@@ -0,0 +1,4 @@
+
+<td valign="top" colspan="1" width="{col_width}%"{extra}>
+	{column_data}
+</td>
Index: /tags/calendar/0.9.3/templates/edge-it/config.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/config.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/config.tpl	(revision 2)
@@ -0,0 +1,51 @@
+<!-- BEGIN header -->
+<form method="POST" action="{action_url}">
+<table border="0" align="center">
+   <tr bgcolor="{th_bg}">
+    <td colspan="2"><font color="{th_text}">&nbsp;<b>{title}</b></font></td>
+   </tr>
+<!-- END header -->
+
+<!-- BEGIN body -->
+   <tr bgcolor="{row_on}">
+    <td colspan="2">&nbsp;</td>
+   </tr>
+
+   <tr bgcolor="{row_off}">
+    <td colspan="2"><b>{lang_Calendar_settings}</b></td>
+   </tr>
+   <tr bgcolor="{row_on}">
+    <td>{lang_Do_you_wish_to_autoload_calendar_holidays_files_dynamically?}</td>
+    <td>
+     <select name="newsettings[auto_load_holidays]">
+      <option value=""{selected_auto_load_holidays_False}>{lang_No}</option>
+      <option value="True"{selected_auto_load_holidays_True}>{lang_Yes}</option>
+     </select>
+    </td>
+   </tr>
+   <tr bgcolor="{row_off}">
+    <td>{lang_Location_to_autoload_from}:</td>
+    <td>
+     <select name="newsettings[holidays_url_path]">
+      <option value="localhost"{selected_holidays_url_path_localhost}>localhost</option>
+      <option value="http://www.phpgroupware.org/cal"{selected_holidays_url_path_http://www.phpgroupware.org/cal}>www.phpgroupware.org</option>
+     </select>
+    </td>
+   </tr>
+<!-- END body -->
+
+<!-- BEGIN footer -->
+  <tr bgcolor="{th_bg}">
+    <td colspan="2">
+&nbsp;
+    </td>
+  </tr>
+  <tr>
+    <td colspan="2" align="center">
+      <input type="submit" name="submit" value="{lang_submit}">
+      <input type="submit" name="cancel" value="{lang_cancel}">
+    </td>
+  </tr>
+</table>
+</form>
+<!-- END footer -->
Index: /tags/calendar/0.9.3/templates/edge-it/index.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/index.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/index.tpl	(revision 2)
@@ -0,0 +1,32 @@
+{printer_friendly}
+<table id="calendar_index_table" border="0" width="100%" cols="5">
+	<tr>
+		<td align="left" valign="top" width="20%">
+			{small_calendar_prev}
+		</td>
+		<td align="center" valign="middle" width="15%">
+			<b>{prev_month_link}</b>
+		</td>
+		<td align="center" width="30%">
+			<span class="calendar_month_identifier">
+				{month_identifier}
+			</span>
+				<br />
+			<span class="calendar_user_identifier">
+				:&nbsp;{username}&nbsp;:
+			</span>
+		</td>
+		<td align="center" valign="middle" width="15%">
+			{next_month_link}
+		</td>
+		<td align="right" valign="top" width="20%">
+			{small_calendar_next}
+		</td>
+	</tr>
+</table>
+{large_month}
+<p>
+<p>
+<div class="calendar_link_print">
+	{print}
+</div>
Index: /tags/calendar/0.9.3/templates/edge-it/form_button_dropdown.tpl
===================================================================
--- /tags/calendar/0.9.3/templates/edge-it/form_button_dropdown.tpl	(revision 2)
+++ /tags/calendar/0.9.3/templates/edge-it/form_button_dropdown.tpl	(revision 2)
@@ -0,0 +1,13 @@
+<form action="{form_link}" method="post" name="{form_name}form">
+<td width="{form_width}%" align="center" valign="top" style="padding-top:16px">
+	<span style="font-size:10px"><b>{title}:</b>
+    {hidden_vars}    
+    <select name="{form_name}" onchange="document.{form_name}form.submit()">
+		{form_options}
+	</select>
+    <noscript>
+    	<input type="submit" value="{button_value}">
+    </noscript>
+	</span>
+</td>
+</form>
