<?php
/**
* Calendar controller
*
* @package   calendar
* @subpackage   controller
* @author Atmail
* @copyright Atmail
*/

define('TOTAL_TIME_FOR_QUICKVIEW', 2592000); //60*60*24*30; (30 days)

//5184000; //60*60*24*60; (60 days)
function cmp_ar($a, $b)
{
	$a = strtotime($a['DateStartCal'] . " " . $a['DateStartTime']);
	$b = strtotime($b['DateStartCal'] . " " . $b['DateStartTime']);
	
    if ($a == $b)
    {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
}

class Mail_CalendarController extends Zend_Controller_Action
{
	public function init()
	{
		$contextSwitch = $this->_helper->getHelper('contextSwitch');
		$contextSwitch->addActionContext('index', 'xml')->addActionContext('read', 'xml')->initContext();
		$this->view->addHelperPath('library/Atmail/View/Helper/', 'Atmail_View_Helper');
		$this->view->global = Zend_Registry::get('config')->global;
	}
	
	public function preDispatch()
	{
		
		require_once 'library/jQuery/jQuery.php';

		// Setup filters
		$this->filter = Atmail_Filter_Input_Controller::filterInput($this->_request);
		
		// check if we have been authenticated... and redirect if not
		if(!Atmail_FormAuth::authenticated())
		{
			// we have most probably timed out, so lets kick them to the timeout bootstrap page
			// this will poison json responses, which will fire the php.error ( or ajax.error ) which can detect the special page
			$this->_forward('timeout', 'index', 'default');
			return;
		}
		else
		{
			// we are authenticated...
			if ( $this->getRequest()->isXmlHttpRequest()) 
			{
				require_once 'library/jQuery/jQuery.php';
				$this->view->jsonIdsToRender = array();
				Zend_Registry::get('log')->info(__METHOD__ . ' isAJAX request');//show a hidden dialog box and include desired content
				$this->isAjax = true;
			} 
			else 
			{
				Zend_Registry::get('log')->info(__METHOD__ . ' normal HTML request');//show a hidden dialog box and include desired content
				$this->isAjax = false;
			}

			// setup the view and session data
			$this->view->requestParams = $this->_request->getParams();
			$this->view->setEncoding('UTF-8');
			$this->view->siteBaseUrl = Zend_Registry::get('siteBaseUrl');
			$this->view->appBaseUrl = $this->_request->getBaseUrl() . (strpos($this->_request->getBaseUrl(),'index.php')?'':'/index.php');
			$this->view->moduleBaseUrl = $this->view->appBaseUrl . ($this->view->requestParams['module']=='default'?'':DIRECTORY_SEPARATOR . $this->view->requestParams['module']);
			$this->view->thisActionURL = $this->view->appBaseUrl . '/' . $this->view->requestParams['controller'] . '/' . $this->view->requestParams['action'];
			$this->view->notices = array();
			$this->view->errors = array();
			$this->session = new Zend_Session_Namespace(ATMAIL_NAMESPACE);
			
			$this->userData = Zend_Auth::getInstance()->getStorage()->read();
			$this->userData = Atmail_Password::processUser($this->userData);
			
            $this->_helper->pluginCall("postFetchUserData");

			$this->_globalConfig = Zend_Registry::get('config')->global;
			
			$this->UserSettings = Zend_Registry::get('UserSettings');
            $this->_helper->pluginCall("postFetchUserSettings");
			$this->_currentConfig = array();
		
			$this->view->autocompleteFetchThreshold = (isset($this->_globalConfig['autocompleteFetchThreshold']) ? $this->_globalConfig['autocompleteFetchThreshold'] : 50);
			$this->view->autocompleteCacheSize = (isset($this->_globalConfig['autocompleteCacheSize']) ? $this->_globalConfig['autocompleteCacheSize'] : 100);
			$this->view->autocompleteFetchSize = (isset($this->_globalConfig['autocompleteFetchSize']) ? $this->_globalConfig['autocompleteFetchSize'] : 25);
			$this->view->autocompleteMinFetchLength = (isset($this->_globalConfig['autocompleteMinFetchLength']) ? $this->_globalConfig['autocompleteMinFetchLength'] : 2);

			unset($this->_globalConfig);
		
			// lets include the calendar object model and create a new instance !
			require_once 'application/models/calendar.php';
			require_once 'application/models/users.php';

			// If no defined CalDavUser/CalDavPass in the UserSettings table, revert to the current logged in session details
			if(empty($this->UserSettings['CalDavUser']))
				$CalDavUser = $this->userData['Account'];
			else
				$CalDavUser = $this->UserSettings['CalDavUser'];
				
			if(empty($this->UserSettings['CalDavPass']))
				$CalDavPass = $this->userData['password'];
			else
				$CalDavPass = $this->UserSettings['CalDavPass'];

			$this->view->UserSettings = $this->UserSettings;

			$this->view->owner_username = $CalDavUser;
			$this->_calendar = new calendar(array('Timezone' => $this->UserSettings['TimeZone'], 'Type' => $this->UserSettings['CalDavType'], 'URL' => $this->UserSettings['CalDavUrl'], 'Account' => $CalDavUser, 'Password' => $CalDavPass, 'Calendar' => "calendar", 'home', 'largeInstall' => '0') );
		}
	}

	public function reminderAction()
	{	
		$requestParams = $this->_request->getParams();
		$this->view->description = $requestParams['description'];
		$this->view->time = $requestParams['time'];
		$this->view->date = $requestParams['date'];
		$this->view->day = $requestParams['day'];

		$this->view->overdue = $requestParams['overdue'];
		$this->view->id = $requestParams['id'];
		$this->view->href = $requestParams['href'];
		$this->view->url = $requestParams['url'];

		if($this->view->overdue < 0)
		{
			$days = (int)(-$requestParams['overdue'] / 1000 / 60 / 60 / 24);
			$hours = (int)((-$requestParams['overdue'] / 1000 / 60 / 60) - ($days * 24));
			$mins = (int)((-$requestParams['overdue'] / 1000 / 60 ) - (($days * 24 * 60) + ($hours * 60)));
			
			$this->view->overdueText = $this->view->translate("Overdue by") . " : " . $days . " " . $this->view->translate("Days") . " " . $hours . " " . $this->view->translate("Hours") . " " . $mins . " " . $this->view->translate("Minutes");			
		}
		else
		{
			$this->view->overdueText = "";
		}
		
		$this->view->reminderFavicon = getFavicon(Zend_registry::get('config')->global['install_dir'], $this->view->siteBaseUrl, 'reminder');
	}

	public function alarmsAction()
	{
		$now = new Date();
		// search +- 2 weeks
		$now->addDays(-14);
		$tomorrow = new Date();		
		$tomorrow->addDays(14);

		try
		{
			$this->view->alarms = $this->_calendar->checkAlarms($now->format("%Y-%m-%d %H:%M:00Z"), $tomorrow->format("%Y-%m-%d %H:%M:00Z"));

			foreach($this->view->alarms as $alarm)
			{
				$formattedEventDate = new Date($alarm['eventtime'][0]);
				$now = new Date();
				$now->convertTZByID($alarm['alarmtime']->getTZID());

				if ($alarm['trigger'] instanceof Date)
				{
					$alarm['alarmtime'] = $alarm['trigger'];
				}
				else
				{
					$alarm['alarmtime']->addSeconds($alarm['trigger']);
				}

				list($formattedDate, $formattedTime) = explode(' ', $formattedEventDate->getDate());
				$calculatedTimeout = ($alarm['alarmtime']->getTime() - $now->getTime());
				$max = 60 * 60 * 24 * 14;
				if(-$max < $calculatedTimeout && $calculatedTimeout < $max)
				{
					jQuery::evalScript("setAlarm('" . $this->view->appBaseUrl . "/mail/calendar/reminder', '" . $formattedDate . "', '" . $formattedTime . "', '" . $formattedEventDate->getDayName() . "', '" . mysql_escape_string($alarm['description']) . "', " . $calculatedTimeout . ",'" . $alarm['id'] . "','".$alarm['href']."');");
				}
			}
		}
		catch(Exception $e)
		{
			// an error
			// already logged by dav backend to phperr
		}
		$this->_helper->viewRenderer->setNoRender();
		$this->render('jsonresponse');
	}

	public function indexAction()
	{

		$today = getdate(time());
		$this->view->viewType = $this->UserSettings['CalDavView'];
		$this->view->CalDavType = $this->UserSettings['CalDavType'];

	}
	
	/** 
	 * email all the attendees then updated ics file (Cal client should transparently update/notify of already accepted entries and all recipients should be notified of changes)
	 */
	public function setattendeesAction()
	{

		$requestParams = $this->_request->getParams();
		$this->_helper->viewRenderer->setNoRender();
		//Process and clean attendees string into array
		if( !array_key_exists('attendees', $requestParams) )
		{
			echo Zend_Json::encode( array("result" => "Failed", "message" => "Missing attendees string parameter.", "status" => true) );
			return;
		}
		$attendeesArray = $this->cleanEmailAddresses($requestParams['attendees']);
		//for now, self will always be an attendee, until functionality added to support creating events where self will not attend (other cal clients reply to )
//Zend_Registry::get('log')->debug( "\n\n" . print_r($attendeesArray,true) . "\n" . __METHOD__ . ' #' . __LINE__ . ": \$attendeesArray: \n\n");
		$updatedEvent = $this->_calendar->setAttendees($requestParams['id'], $requestParams['href'], $attendeesArray);
		
		if( $updatedEvent !== false )
		{

			$result = $this->emailInviteToAttendees($requestParams['id'], $requestParams['href']);
			echo Zend_Json::encode($result);

		}
		else
			echo Zend_Json::encode( array("result" => "Failed", "message" => "Failed setting attendees", "status" => false) );

	}
	
	public function getattendeesAction()
	{

		$requestParams = $this->_request->getParams();
		$result = $this->_calendar->getAttendees($requestParams['id'], $requestParams['href']);
		$this->_helper->viewRenderer->setNoRender();
		echo Zend_Json::encode( array("result" => $result, "status" => true) );

	}
	
	private function getAccountEmailAddress()
	{
		
		if( strpos($this->UserSettings['Account'], '@') !== false )
			return $this->UserSettings['Account'];
		else
		{

			$configDovecot = Zend_Registry::get('config')->dovecot;
			if( !isset($configDovecot['default_domain']) || $configDovecot['default_domain'] == '' )
				throw new Exception( $this->view->translate('Unable to send, Administrator needs to set Default Domain in Admin > Services > POP3/IMAP') );
			return $this->UserSettings['Account'] . '@' . $configDovecot['default_domain'];

		}
		
	}
	
	private function emailInviteToAttendees( $uid, $calendarUrl) //TODO replace with calendar->emailICSToRecipients - very similar
	{
		
		$attendees = $this->_calendar->getAttendees($uid, $calendarUrl);
		//if no attendees, then no email to send so return
		if( $attendees === null )
			return array("result" => "Success", "message" => "", "status" => true);
		
		$event = $this->_calendar->getEvent($uid, $calendarUrl);
		//add the METHOD:REQUEST header (requests recipients to respond)
		$vCalendar = $event->getVObject();
		$vCalendar->add("METHOD", "REQUEST");
		$vCalendar->add("X-MS-OLK-FORCEINSPECTOROPEN", "TRUE");
		unset($vCalendar->vevent->{"last-modified"});
		$icsString = $vCalendar->serialize();
//Zend_Registry::get('log')->debug( "\n\n" . print_r($icsString,true) . "\n" . __METHOD__ . ' #' . __LINE__ . ": \$icsString: \n\n");
		
		
		$eventArray = $this->_calendar->get_record($uid, $calendarUrl);
		
		//required clean data (already processed/prepared)
		$this->_helper->pluginCall('preEmailSend');
		$noErrorYet = true;
		$this->_globalConfig = Zend_Registry::get('config')->global;
		if( !empty($this->_globalConfig['smtpauth_username']) && !empty($this->_globalConfig['smtpauth_password']) && !empty($this->_globalConfig['smtp_auth']) )
			$config = array( 'auth' => 'login', 'username' => $this->_globalConfig['smtpauth_username'], 'password' => $this->_globalConfig['smtpauth_password'] );
		else
			$config = array( );
		$transportClass = $this->_helper->pluginCall("smtpTransportClass");
		if( empty($transportClass) )
			$transportClass = "Atmail_Mail_Transport_Smtp";
		$transport = new $transportClass($this->_globalConfig['smtphost'], $config);
		$this->_helper->pluginCall("postCreateSmtpTransport", $transport);

		$newMessage = new Atmail_Mail( 'UTF-8' );
		$newMessage->setMessageId(true);
		$messageParams = array();
		if( strpos($this->UserSettings['Account'], '@') !== false )
			$messageParams['fromAddress'] = $this->UserSettings['Account'];
		else
		{

			$configDovecot = Zend_Registry::get('config')->dovecot;
			if( !isset($configDovecot['default_domain']) || $configDovecot['default_domain'] == '' )
				throw new Exception( $this->view->translate('Unable to send, Administrator needs to set Default Domain in Admin > Services > POP3/IMAP') );
			$messageParams['fromAddress'] = $this->UserSettings['Account'] . '@' . $configDovecot['default_domain'];

		}

		if( isset($this->UserSettings['RealName']) && strlen($this->UserSettings['RealName']) > 0 )
		{

			$messageParams['fromRealname'] = $this->UserSettings['RealName'];
			$messageParams['fromRealname'] = trim($messageParams['fromRealname'], " \t\n\r\0\x0B");

		}
		else
			$messageParams['fromRealname'] = '';
		
		if( strlen($messageParams['fromRealname']) > 0 )
			$newMessage->setFrom( $messageParams['fromAddress'], $messageParams['fromRealname'] );
		else
			$newMessage->setFrom( $messageParams['fromAddress']);
		
		if( isset($this->UserSettings['ReplyTo']) && strlen($this->UserSettings['ReplyTo']) > 0 )
			$messageParams['replyToAddress'] = $this->UserSettings['ReplyTo'];
		else
			$messageParams['replyToAddress'] = '';
		
		if( strlen( $messageParams['replyToAddress']) > 0 )
		{
			
			if( strlen($messageParams['fromRealname']) > 0 )
				$newMessage->setReplyTo( $messageParams['replyToAddress'], $messageParams['fromRealname'] );
			else
				$newMessage->setReplyTo( $messageParams['replyToAddress']);

		}

		$finalRecipients = array();
		$rcptLog = array();
		$addressObjectsArray = getProcessedRecipientObjects( implode(", ", $attendees) );
		foreach ($addressObjectsArray as $addressObject)
		{
			
			$personal = '';
			if( is_string($addressObject) )
			{
			
				preg_match('/(.*?)<(.*?)>/', $addressObject, $m);
				$personal = trim($m[1]);
				$mail = $m[2];
			
			}
			else
			{
			
				$personal = $addressObject->personalUTF8;
				$mail = $addressObject->address;
			
			}
			if( false && $mail == $messageParams['fromAddress'] )
				continue; //don't email event invite to self.
			$finalRecipients[] = array("personal" => strlen($personal)>0?$personal:null, "emailAddress" => $mail);
			$rcptLog[] = $mail;

		}
		
		// Set the X-Mailer to the Atmail version
		$xMailer = "Atmail";
		$newMessage->addHeader('X-Mailer', $xMailer . " " . $this->_globalConfig['version'] );
		$newMessage->addHeader('X-Originating-IP', $_SERVER['REMOTE_ADDR']);
		$newMessage->setSubject( $eventArray['Title'] . " scheduled for " . $eventArray['DateStartCal'] . " " . $eventArray['DateStartTime'] );
		//quote the timezone that this event was created with
		$timezoneString = "";
		if( $eventArray['timezone'] != null && $eventArray['timezone'] && strlen($eventArray['timezone']) > 0 )
			$timezoneString = " (" . $eventArray['timezone'] . ")";

		// Add the HTML and text parts
		$htmlEmailBodyWithHTMLLinks_CurrentlyDisabled = <<<EOF
			<div class="invitation" style="background:#ECECEC;padding:30px;"><div class="invite-center" style="background:#ffffff;margin:0 auto;border: 1px solid #cccccc;padding:20px;">
			<span style="font-weight:bold;display:block;font-size:17px;text-align:center;">You are invited to attend "{$eventArray['Title']}"</span>
			<table class="centered-block" style="margin-left: auto !important; margin-right: auto !important;">
			  <tr>
			    <td>
			      <div>
			        <div class="invite-text">
						<tr>
						<td style="color:#999999;margin-right:15px; font-size:13px; width:75px; float:left; display:block;">Time</td><td style="font-size:13px;">{$eventArray['DateStartCal']} {$eventArray['DateStartTime']}{$timezoneString}</td>
						</tr>
						<tr><td style="color:#999999;margin-right:15px; font-size:13px; width:75px; float:left; display:block;">Description</td><td style="font-size:13px;">{$eventArray['CalMessage']}</td>
						</tr>
						<tr><td style="color:#999999;margin-right:15px; font-size:13px; width:75px; float:left; display:block;">Location</td><td style="font-size:13px;">{$eventArray['Location']}</td></tr>

						<tr><td style="color:#999999;margin-right:15px; font-size:13px; width:75px; float:left; display:block;">Going?</td>

						<td><div onclick="$.php('{$acceptUrl}accept');" class="savecontact saveButton" style="float:left;" id="back_button"><a style="color:#0066CC; font-size:13px;" href="#">Yes</a>&nbsp; - &nbsp;</div>
						<div onclick="$.php('{$acceptUrl}tentative');" class="savecontact saveButton" style="float:left;" id="back_button"><a style="color:#0066CC; font-size:13px;" href="#">Maybe</a>&nbsp; - &nbsp;</div>
						<div onclick="$.php('{$acceptUrl}decline');" class="savecontact saveButton" style="float:left;" id="back_button"><a style="color:#0066CC; font-size:13px;" href="#">No</a></div></td>

						</tr>
					</div>
			      </div>
			    </td>
			  </tr>
			</table>

			</div></div>
EOF;

		$htmlEmailBody = <<<EOF
<div class="invitation" style="background:#ECECEC;padding:30px;"><div class="invite-center" style="background:#ffffff;margin:0 auto;border: 1px solid #ccc;padding:20px;">
<span style="font-weight:bold;display:block;font-size:17px;text-align:center;">You are invited to attend "{$eventArray['Title']}"</span>
<table class="centered-block" style="margin-left: auto !important; margin-right: auto !important;">
  <tr>
    <td>
      <div>
        <div class="invite-text">
			<tr>
			<td style="color:#999999;margin-right:15px; font-size:13px; width:75px; float:left; display:block;">Time</td><td style="font-size:13px;">{$eventArray['DateStartCal']} {$eventArray['DateStartTime']}{$timezoneString}</td>
			</tr>
			<tr><td style="color:#999999;margin-right:15px; font-size:13px; width:75px; float:left; display:block;">Description</td><td style="font-size:13px;">{$eventArray['CalMessage']}</td>
			</tr>
			<tr><td style="color:#999999;margin-right:15px; font-size:13px; width:75px; float:left; display:block;">Location</td><td style="font-size:13px;">{$eventArray['Location']}</td></tr>
		</div>
      </div>
    </td>
  </tr>
</table>

</div></div>
EOF;


//<br />
//Your Calendar application should be able to process this event attachment and return your response.
//EOF;
		require_once('class.html2text.inc');
		$html2text = new html2text($htmlEmailBody);
		$emailBodyText = $html2text->get_text();
		$newMessage->setBodyText($emailBodyText);
		if( !preg_match("'<body[^>]*>(.*?)</body>'i", $htmlEmailBody ) )
			$htmlEmailBody = '<body>' . $htmlEmailBody . '</body>';
		if( !preg_match("'<html[^>]*>(.*?)</html>'i", $htmlEmailBody ) )
			$htmlEmailBody = '<html>' . $htmlEmailBody . '</html>';
		$htmlEmailBody = str_replace('<body>', '<body style="font-family: \'Helvetica Neue\',Helvetica,Arial,sans-serif; font-size: 12px;">', $htmlEmailBody);
		$newMessage->setBodyHtml($htmlEmailBody);
		$attachmentFilename = $uid . ".ics";
		$newMessage->createAttachment($icsString,"text/calendar; method=REQUEST; charset=\"UTF-8\"",Zend_Mime::DISPOSITION_INLINE,Zend_Mime::ENCODING_7BIT, $attachmentFilename);
		
		// Send the message to each recipient so that we can build up a success fail list
		$successArray = array();
		$failArray = array();
		foreach( $finalRecipients as $recipientArray )
		{
			
			$newMessage->clearRecipients();
			$newMessage->addTo($recipientArray['emailAddress'], $recipientArray['personal'] );
			try
			{

				$this->_helper->pluginCall("preEmailSend", $newMessage);
				//throw new Exception("debug end here");
				$newMessage->send($transport);
				
				// If we are running the Webmail client, log the action to the DB - If server, the log-daemon process will log the action for us
				if($this->_globalConfig['install_type'] != 'server')
				{

					require_once('log.php');
					$log = new logEntry($this->UserSettings['Account']);
					foreach($rcptLog as $rcpt)
						$log->insert("Log_SendMail", array('LogIP' => $_SERVER['REMOTE_ADDR'], 'EmailTo' => $rcpt, 'Account' => $this->UserSettings['Account']));

				}
				$successArray[] = $recipientArray['personal']!=null?$recipientArray['personal']:$recipientArray['emailAddress'];
				

			}
			catch (Exception $e)
			{

				$this->_helper->pluginCall("emailSendFailed", $e);
				// Check if a plugin has given a custom error message
				if (!empty($this->emailSendFailedError))
					$error = $this->emailSendFailedError;
				else 
				{

					$error = $e->getMessage();
					if( strpos($error, 'Blocked') !== false )
						$error = $this->view->translate('The server has rejected the email address. If you feel this address is legitimate please contact your administrator.');
					else if( $error == 'No recipient forward path has been supplied' )
						$error = $this->view->translate('Email address not valid. Please use an email address which looks like user@example.com');
				}
				$failArray[] = $recipientArray['personal']!=null?$recipientArray['personal']:$recipientArray['emailAddress'];
//Zend_Registry::get('log')->debug( "\n\n" . print_r($error,true) . "\n" . __METHOD__ . ' #' . __LINE__ . ": \$error: \n\n");

			}
			
		}
		$responseMessage = '';
		//if( count($successArray) > 0 )
		//	$responseMessage = "Successfully sent invite to " . implode(", ", $successArray) . ". ";
		if( count($failArray) > 0 )
			$responseMessage .= "Event saved, but failed sending invite to " . implode(", ", $failArray) . ". ";
		return array("result" => "Complete", "message" => $responseMessage, "status" => true);
		
	}
	
	private function cleanEmailAddresses( $rawRecipientsString )
	{
		
		$finalRecipients = array();
		foreach( getProcessedRecipientObjects($rawRecipientsString) as $addressObject)
		{

			$personal = '';
			if( is_string($addressObject) )
			{

				preg_match('/(.*?)<(.*?)>/', $addressObject, $m);
				$personal = trim($m[1]);
				$mail = $m[2];

			}
			else
			{

				$personal = $addressObject->personalUTF8;
				$mail = $addressObject->address;

			}
			$finalRecipients[] = (strlen($personal)>0?$personal . ' <':'') . $mail . (strlen($personal)>0?'>':'');

		}
		return $finalRecipients;
		
	}
	
	public function snoozeAction()
	{

		$requestParams = $this->_request->getParams();
		$result = $this->_calendar->snoozeAlarm($requestParams['id'], $requestParams['href'], $requestParams['mins']);
		$requestParams['overdue'] = ($requestParams['mins'] * 60);
		jQuery::evalScript("if(typeof(Appointments) != 'undefined') Appointments.ChangeETAG('" . $requestParams['id'] . "', '". $result ."')");
		jQuery::evalScript("setAlarm('" . $this->view->appBaseUrl . "/mail/calendar/reminder', '" . $requestParams['date'] . "', '" . $requestParams['time'] . "', '" . $requestParams['day'] . "', '" . mysql_escape_string($requestParams['description']) . "', " . $requestParams['overdue'] . ",'" . $requestParams['id'] . "','".$requestParams['href']."');");
		
		$this->_helper->viewRenderer->setNoRender();
		$this->render('jsonresponse');

	}
	
	public function dismissAction()
	{
		$requestParams = $this->_request->getParams();

		$result = $this->_calendar->dismissAlarm($requestParams['id'], $requestParams['href']);
		jQuery::evalScript("if(typeof(Appointments) != 'undefined') Appointments.ChangeETAG('" . $requestParams['id'] . "', '". $result ."')");
		$this->_helper->viewRenderer->setNoRender();
		$this->render('jsonresponse');
	}
	
	public function editAction()
	{
		return $this->popupAction();
	}

	public function popupAction()
	{
		$this->view->invalid = false;
		sleep(1);
		$requestParams = $this->_request->getParams();
		try {
			$this->view->event = $this->_calendar->read_record( $requestParams['id'], $requestParams['relative_href']);
			$categoryListArray = array(
				'General' => $this->view->translate("General"),
				'Pending' => $this->view->translate("----Pending"),
				'Open' => $this->view->translate("----Open"),
				'Complete' => $this->view->translate("----Complete"),
				'Urgent' => $this->view->translate("----Urgent"),
				'Appointment' => $this->view->translate("----Appointment"),
				'Birthday' => $this->view->translate("Birthday"),
				'Friend' => $this->view->translate("----Friend"),
				'Family' => $this->view->translate("----Family"),
				'Colleague' => $this->view->translate("----Colleague"),
				'Other' => $this->view->translate("----Other"),
				'Business' => $this->view->translate("Business"),
				'Conference' => $this->view->translate("----Conference"),
				'Deadline' => $this->view->translate("----Deadline"),
				'Interview' => $this->view->translate("----Interview"),
				'Lunch' => $this->view->translate("----Lunch"),
				'Meeting' => $this->view->translate("----Meeting"),
				'Phone Call' => $this->view->translate("----Phone Call"),
				'Travel' => $this->view->translate("----Travel"),
				'Entertainment' => $this->view->translate("Entertainment"),
				'Concert' => $this->view->translate("----Concert"),
				'Movie' => $this->view->translate("----Movie"),
				'Performance' => $this->view->translate("----Performance"),
				'Sports' => $this->view->translate("----Sports"),
				'Television' => $this->view->translate("----Television"),
				'Friends and Family' => $this->view->translate("Friends and Family"),
				'Breakfast' => $this->view->translate("----Breakfast"),
				'Brunch' => $this->view->translate("----Brunch"),
				'Dinner' => $this->view->translate("----Dinner"),
				'Get Together' => $this->view->translate("----Get Together"),
				'Lunch' => $this->view->translate("----Lunch"),
				'Movie' => $this->view->translate("----Movie"),
				'Party' => $this->view->translate("----Party"),
				'Picnic-BBQ' => $this->view->translate("----Picnic-BBQ"),
				'School' => $this->view->translate("----School"),
				'Personal' => $this->view->translate("Personal"),
				'Doctor-Dentist' => $this->view->translate("----Doctor-Dentist"),
				'Fitness' => $this->view->translate("----Fitness"),
				'Haircut' => $this->view->translate("----Haircut"),
				'Pay Bills' => $this->view->translate("----Pay Bills"),
				'Shopping' => $this->view->translate("----Shopping"),
				'Task' => $this->view->translate("----Task"),
				'Vacation' => $this->view->translate("----Vacation"),
				'Special Event' => $this->view->translate("Special Event"),
				'Anniversary' => $this->view->translate("----Anniversary"),
				'Gathering' => $this->view->translate("----Gathering"),
				'Graduation' => $this->view->translate("----Graduation"),
				'Holiday' => $this->view->translate("----Holiday"),
				'Reunion' => $this->view->translate("----Reunion"),
				'Wedding' => $this->view->translate("----Wedding")
			);
			$availabiltyListArray = array(
				'Busy' => $this->view->translate("Busy"),
				'Free' => $this->view->translate("Free"),
				'Temporary' => $this->view->translate("Temporary"),
				'OutOfOffice' => $this->view->translate("OutOfOffice")
			);
			$alertListArray = array(
				'Minutes' => $this->view->translate("Minutes"),
				'Hours' => $this->view->translate("Hours"),
				'Days' => $this->view->translate("Days"),
				'Date' => $this->view->translate("Date"),
				'None' => $this->view->translate("None")
			);
			$alertPositionArray = array(
				'Before' => $this->view->translate("Before"),
				'After' => $this->view->translate("After")
			);
			$repeatListArray = array(
				array("0",$this->view->translate("None")), 
				array("10",$this->view->translate("Daily")), 
				array("11",$this->view->translate("Weekly")), 
				array("12",$this->view->translate("Monthly")), 
				array("13",$this->view->translate("Yearly"))
			);
			$tzList =  calendar::getZoneInfoList();
			
			$this->view->timezoneList = '';
			
			foreach($tzList as $tz)
			{
				$this->view->timezoneList .= '<option value="' . $tz . '">' . $tz . '</option>';
			}
			$this->view->popup = $requestParams['popup'];
			// sanitize event data
	//		$this->filter->setData($this->view->event['VCALENDAR']['VEVENT']);
	//		$this->view->event['VCALENDAR']['VEVENT'] = $this->filter->getEscapedData();

			$params = array_merge($_POST, $_GET);
			$this->view->params = array();
			$this->view->params['relative_href'] = $requestParams['relative_href'];
			$this->view->params['Permissions'] = 1;
			$this->view->params['id'] = substr($requestParams['id'], 1, strlen($requestParams['id']) - 1);
			$this->view->params['full_id'] = $requestParams['id'];

			$this->view->params['timezone'] = 'None';
			if(isset($this->view->event['VCALENDAR']['VTIMEZONE']))
			{
				$this->view->params['timezone'] = $this->view->event['VCALENDAR']['VTIMEZONE']['TZID'];		
			}
			$this->view->contextId = $requestParams['contextId'];
	
			if(substr($requestParams['id'], 0, 1) == "p")
			{
				$this->view->params['shared'] = 0;
			}
			else
			{
				$this->view->params['shared'] = 1;
			}

			$this->view->params['Disabled'] = 0;
			$this->view->params['Title']= ical_decode($this->view->event['VCALENDAR']['VEVENT']['SUMMARY']);
	
			if($this->view->params['Title'] == '')
			{
				$this->view->params['Title'] = "New Event";
			}
			if(isset($this->view->event['VCALENDAR']['VEVENT']['LOCATION']))
				$this->view->params['Location'] = $this->view->event['VCALENDAR']['VEVENT']['LOCATION'];
			else
				$this->view->params['Location'] = "";
	
			$this->view->params['shared-enabled'] = 1;
	
			// create the lists..
			$hourList = "";
			for($a=0;$a<24;$a++)
			{
				$hourList .= sprintf("<option value=\"%d\">%02d</option>", $a, $a);
			}
			
			$minuteList = "";
			for($a=0;$a<60;$a++)
			{
				$minuteList .= sprintf("<option value=\"%d\">%02d</option>", $a, $a);
			}
	
			$categoryList = "";
			foreach($categoryListArray as $categoryItemOriginal => $categoryItemTranslation)
			{
				$categoryList .= sprintf("<option value=\"%s\">%s</option>", $categoryItemOriginal, $categoryItemTranslation);
			}
	
			$availablityList = "";
			foreach($availabiltyListArray as $availableItemOriginal => $availableItemTranslation)
			{
				$english = trim(preg_replace("/([A-Z][^A-Z]*)/", ' ${1}', $availableItemOriginal));
				$availablityList .= sprintf("<option value=\"%s\">%s</option>", $availableItemOriginal, $availableItemTranslation);
			}
		
			$alertTypeList = "";
			foreach($alertListArray as $alertItemOriginal => $alertItemTranslation)
			{
				$alertTypeList .= sprintf("<option value=\"%s\">%s</option>", $alertItemOriginal, $alertItemTranslation);
			}
		
			$alertPositionList = "";
			foreach($alertPositionArray as $alertPositionOriginal => $alertPositionTranslation)
			{
				$alertPositionList .= sprintf("<option value=\"%s\">%s</option>", $alertPositionOriginal, $alertPositionTranslation);
			}
	
			$alert = caldav_extract_alarm($this->view->event, $this->view->params['relative_href']);
	
			$this->view->params['alertPosition'] = "Before";
			$this->view->params['alertType'] = (isset($alert['triggertype']) ? $alert['triggertype'] : 'None' );
			
			if($this->view->params['alertType'] == "Date")
			{
				// specified trigger date
				list($this->view->params['alertTrigger'], $junk) = explode(" ",$alert['alarmtime']->getDate());
				$this->view->params['alertTriggerStartHour'] = $alert['alarmtime']->getHour();
				$this->view->params['alertTriggerStartMinute'] = $alert['alarmtime']->getMinute();
			}
			else
			{
				if(isset($alert['trigger']) && $alert['trigger'] > 0)
				{
					$this->view->params['alertPosition'] = "After";
				}
				else if(isset($alert['trigger']))
				{
					$this->view->params['alertPosition'] = "Before";
					$alert['trigger'] *= -1;
				}
				else
				{
					$this->view->params['alertPosition'] = "Before";
					$alert['trigger'] = 0;			
				}
				$days = (int)($alert['trigger'] / 60 / 60 / 24);
				$hours = (int)(($alert['trigger'] / 60 / 60) - ($days * 24));
				$mins = (int)(($alert['trigger'] / 60 ) - (($days * 24 * 60) + ($hours * 60)));
				
				if(
					(!$hours && !$days && $mins)	// minutes only
				||	(($hours && $days) || ($mins && ($hours || $days))) // some sort of complex thing
				)
				{
					$this->view->params['alertTrigger'] = $mins + ($hours * 60) + ($days * 24 * 60);
					$this->view->params['alertType'] = "Minutes";					
				}
				else if (
					(!$mins && !$days && $hours) // hours only
				||	(!$mins && $hours && $days) // kinda of complex
				)
				{
					$this->view->params['alertTrigger'] = $hours + ($days * 24);
					$this->view->params['alertType'] = "Hours";	
				}
				else if (
					(!$mins && !$hours && $days) // days only
				)
				{
					$this->view->params['alertTrigger'] = $days;
					$this->view->params['alertType'] = "Days";
				}
				else
				{
					$this->view->params['alertTrigger'] = 0;
					$this->view->params['alertType'] = "None";			
				}		
			}
		
			$this->view->params['alertPositionList'] = str_replace("<option value=\"" . $this->view->params['alertPosition'] . "\">", "<option value=\"" . $this->view->params['alertPosition'] . "\" selected>", $alertPositionList);
			$this->view->params['alertTypeList'] = str_replace("<option value=\"" . $this->view->params['alertType'] . "\">", "<option value=\"" . $this->view->params['alertType'] . "\" selected>", $alertTypeList);
			
			$repeatList = "";
			foreach($repeatListArray as $repeatItem)
			{
				$repeatList .= sprintf("<option value=\"%s\">%s</option>", $repeatItem[0], $repeatItem[1]);
			}
	
			// start time
			// select the active hour
			list($startHour, $startMinute) = explode (":", $this->_calendar->caldav_strip_time($this->view->event['VCALENDAR']['VEVENT']['DTSTART']));
			$startHour = (int)$startHour;
			$this->view->params['startHour'] = $startHour;
			$this->view->params['startHourList'] = str_replace("<option value=\"{$startHour}\">", "<option value=\"{$startHour}\" selected>", $hourList);
	
			// select the active minute
			$startMinute = (int)$startMinute;
			$this->view->params['startMinute'] = $startMinute;
			$this->view->params['startMinuteList'] = str_replace("<option value=\"{$startMinute}\">", "<option value=\"{$startMinute}\" selected>", $minuteList);
	
			// end time
			// select the active hour
			list($endHour, $endMinute) = explode (":", $this->_calendar->caldav_strip_time($this->view->event['VCALENDAR']['VEVENT']['DTEND']));
			$endHour = (int)$endHour;
			$this->view->params['endHour'] = $endHour;
			$this->view->params['endHourList'] = str_replace("<option value=\"{$endHour}\">", "<option value=\"{$endHour}\" selected>", $hourList);
	
			// select the active minute
			$endMinute = (int)$endMinute;
			$this->view->params['endMinute'] = $endMinute;
			$this->view->params['endMinuteList'] = str_replace("<option value=\"{$endMinute}\">", "<option value=\"{$endMinute}\" selected>", $minuteList);
	
			$this->view->params['startDate'] = $this->_calendar->caldav_strip_date($this->view->event['VCALENDAR']['VEVENT']['DTSTART']);
			$this->view->params['endDate'] = $this->_calendar->caldav_strip_date($this->view->event['VCALENDAR']['VEVENT']['DTEND']);
	
			if($this->view->params['startHour'] == '0' && $this->view->params['startMinute'] == '0' 
			&& $this->view->params['endHour'] == '0' && $this->view->params['endMinute'] == '0')
			{
				$this->view->params['allDay'] = 1;	
			}


			// select the category
			if(!isset($this->view->event['VCALENDAR']['VEVENT']['CATEGORY']))
			$category = "General";
			else
			$category = $this->view->event['VCALENDAR']['VEVENT']['CATEGORY'];
			$this->view->params['categoryList'] = str_replace("<option value=\"{$category}\">", "<option value=\"{$category}\" selected>", $categoryList);
	
			// select the availabilty
			if(!isset($this->view->event['VCALENDAR']['VEVENT']['AVAILABILITY']))
				$available = "Busy";
			else
				$available = $this->view->event['VCALENDAR']['VEVENT']['AVAILABILITY'];
			$this->view->params['availabilityList'] = str_replace("<option value=\"{$available}\">", "<option value=\"{$available}\" selected>", $availablityList);
	
			$this->view->params['message'] = "";
			if(isset($this->view->event['VCALENDAR']['VEVENT']['DESCRIPTION']))
			{
				$this->view->params['message'] = $this->view->event['VCALENDAR']['VEVENT']['DESCRIPTION'];
			}
	
			// we must massage the datestart and dateend values
			// as they are currently in caldav format
			// ---- they need to be human readable !
			$this->view->params['DateStart'] = $this->_calendar->caldav_strip_date($this->view->event['VCALENDAR']['VEVENT']['DTSTART']);
			$this->view->params['DateEnd'] = $this->_calendar->caldav_strip_date($this->view->event['VCALENDAR']['VEVENT']['DTEND']);
			$this->view->params['RecurrenceArray'] = $this->_calendar->ical2RecurrenceArray($this->view->event);
			$repeat = $this->view->params['RecurrenceArray']['RecurrenceType'];
			
			$this->view->params['Recurrence'] = 1;
			if(!$repeat)
			{
				$this->view->params['Recurrence'] = 0;
			}
			$this->view->params['repeatList'] = str_replace("<option value=\"{$repeat}\">", "<option value=\"{$repeat}\" selected>", $repeatList);
		}
		catch (Exception $e) {
			$this->view->invalidEvent = true;
		}
		
	}
		
	public function modifypermissionsAction()
	{
		$requestParams = $this->_request->getParams();
		$categoryListArray = array("Read","Read/Write");

		// read the calendar
		$shared =0;
		$this->view->params = array();
		// $this->view->params['id'], $requestParams['relative_href']);
		$this->view->params['calendar_name'] = $requestParams['calendar_name'];
		$this->view->params['calendar_path'] = $requestParams['calendar_path'];
		$this->view->params['principal_path'] = $requestParams['principal_path'];

        // Determining the base URL
        $groupData = groups::get($this->UserSettings['Ugroup']);

        if ($groupData['WebDAVRootUrl']) {
            $caldavBaseUrl = $groupData['WebDAVRootUrl'];
        } else {
            $caldavBaseUrl = 'http://' . $_SERVER['HTTP_HOST'] . ':8008/'; //$this->view->siteBaseUrl . 'dav/server.php/';
        }

        $this->view->params['display_urls'] = false;
		if($fp = @fsockopen($_SERVER['HTTP_HOST'], 8008,$errno,$errstr,2))
		{
	        $this->view->params['display_urls'] = true;
			fclose($fp);
		}

		$this->view->params['server_url'] = $caldavBaseUrl;
		$this->view->params['principal_url'] = htmlspecialchars(urldecode($caldavBaseUrl . ltrim($requestParams['principal_path'], '/')));
		$this->view->params['calendar_url'] =  htmlspecialchars(urldecode($caldavBaseUrl . ltrim($requestParams['calendar_path'], '/')));
		$this->view->account = isset($requestParams['owner']) ? $requestParams['owner'] : $this->UserData['account'];

        $adapter = $this->_calendar->getAdapter();
        if ($adapter instanceof Atmail_Calendar_Adapter_IDelegation) {
            $this->view->supportsDelegates = true;
            $calendar = $adapter->getCalendarByUrl($requestParams['calendar_path']);
            list(
                $this->view->readAccess,
                $this->view->writeAccess
            ) = $adapter->getMembers($calendar);
        } else {
            $this->view->supportsDelegates = false;
        }
		
		$this->render('modifypermissions');
	}

	public function utf8_urldecode($str)
	{
	    $str = preg_replace("/%u([0-9a-f]{3,4})/i","&#x\\1;",urldecode($str));
		return html_entity_decode($str,null,'UTF-8');;
	}
  
	public function caldavglueAction()
	{
		// Basically mostly sniped from printday.php from a5.6
		// BUT
		// I've re-vamped to glue caldav support in
		// 1. Basically, same API wrapper
		// 2. All DB calls now communicate with a caldav server
		// 3. SAME XML RESPONSE.
		require_once('Mail/RFC822.php');	

		// Set our date format
		setlocale(LC_TIME, 'english');

		$param = $this->_request->getParams();

		$this->view->params = array();
		$this->view->func = $param['func'];
		$this->view->account = $this->userData['Account'];
		$this->view->calendar = $this->_calendar;
		if(!isset($param['json']))
			$param['json'] = 0;
		if(empty($param['ctag']))
			$param['ctag'] = '';

		$this->view->json = $param['json'];
		$this->view->CalDavType = $this->UserSettings['CalDavType'];
		$this->view->timezone = $this->UserSettings['TimeZone'];

		try
		{
			if ( $param['func'] == 'overview' )
			{
				$this->view->params['overview'] = true;
			}

			if ( $param['func'] == 'ping' )
			{
				if($this->_calendar->ping() == 'un')
				{
					// connection error or unknown server!
					jQuery::addError('Connecion error while trying to access calendar server.');
					jQuery::evalScript("connection_error();");
					$this->render('global/jsonresponse', null, true);
				}
				else
				{
					jQuery::evalScript("connection_success();");
					$this->render('global/jsonresponse', null, true);
				}
			}
			else if ( $param['func'] == 'freebusy' || $param['func'] == 'ajaxcal' || $param['func'] == 'overview')
			{
				// lets grab the event data for the selected day!
				$this->view->params['color'] = isset($param['color'])? $param['color'] : '';
				$this->view->params['month'] = isset($param['month'])? $param['month'] : strftime("%m");
				$this->view->params['calendarhref'] = isset($param['calendarhref'])? $param['calendarhref'] : '';
				$this->view->params['year']  = isset($param['year'])? $param['year'] : strftime("%Y");
				$this->view->params['day']   = isset($param['day'])? $param['day'] : strftime("%d");
				$this->view->params['Refresh'] = isset($param['Refresh']) ? $param['Refresh'] : false;
				foreach ( array('month', 'day', 'year') as $type)
				{
					$this->view->params[$type] = str_replace(' ', '', $this->view->params[$type]);
					if ( strlen($this->view->params[$type]) == 1 )
					{
						$this->view->params[$type] = '0' . $this->view->params[$type];
					}
				}
				$this->view->params['fulldate'] = strftime( "%A %B %e, %Y", strtotime("{$this->view->params['month']}/{$this->view->params['day']}/{$this->view->params['year']}"));

					$oldtz = date_default_timezone_get();
					date_default_timezone_set($this->view->timezone);
				if($this->view->json)
				{
					if(isset($param['start']))
					{
						$this->view->params['start'] = gmdate('Y-m-d', strtotime(gmdate('Y-m-d', $param['start'])));
					}
					else
					{
						$this->view->params['start'] = gmdate('Y-m-d', strtotime(gmdate('Y-m-d', time())));
					}

					if(isset($param['end']))
					{
						$this->view->params['end'] = gmdate('Y-m-d', strtotime(gmdate('Y-m-d', $param['end'])));
					}
					else
					{
						$this->view->params['end'] = gmdate('Y-m-d', strtotime(gmdate('Y-m-d', time() + TOTAL_TIME_FOR_QUICKVIEW )));
					}
				}
				else
				{
					$this->view->params['start'] = $param['start'];
					$this->view->params['end'] = $param['end'] ? $param['end'] : $param['start'];
				}

				$this->view->params['DateAlert'] = isset($param['DateAlert']) ? $param['DateAlert'] : 0;
				$this->view->params['md5client'] = isset($param['md5client']) ? $param['md5client'] : '';
				$this->view->params[Atmail_Enum::ID_LIMIT] = isset($param[Atmail_Enum::ID_LIMIT]) ? $param[Atmail_Enum::ID_LIMIT] : '0';
				$this->view->params['length'] = isset($param['length']) ? $param['length'] : '0';
				$this->view->extended = array_key_exists('extended',$param)?$param['extended'] : false;

				// call the calendar model to grab the details.
				$calendarhrefs = explode(',', $this->view->params['calendarhref']);
				$this->view->event_entries = array();
				$start = "{$this->view->params['start']} 00:00:00Z";
				$end = "{$this->view->params['end']} 23:59:59Z";
				foreach($calendarhrefs as $calendarhref)
				{
					$event_entries = $this->_calendar->getRange($start, $end, $this->view->params['DateAlert'], $calendarhref);
					$this->view->event_entries = array_merge($this->view->event_entries, $event_entries);
				}

				if(isset($param['position']))
				{
					// sort the data to date
					usort($this->view->event_entries, "cmp_ar");
					if($param['length'] == 0)
					{
						$this->view->event_entries = array_slice($this->view->event_entries, $param['position']);
					}
					else
					{
						$this->view->event_entries = array_slice($this->view->event_entries, $param['position'], $param['length']);
					}
				}
				date_default_timezone_set($oldtz);

			}
			else if( $param['func'] == 'total' )
			{
				$this->view->params['total'] = 0;
				$this->view->json = 1;
				$calendar_list = explode(",", $param['calendarhref']);

                $oldtz = date_default_timezone_get();
                date_default_timezone_set($this->view->timezone);

				if(isset($param['start']))
				{
					$this->view->params['start'] = gmdate('Y-m-d', strtotime(gmdate('Y-m-d', $param['start'])));
				}
				else
				{
					$this->view->params['start'] = gmdate('Y-m-d', strtotime(gmdate('Y-m-d', time())));
				}

				if(isset($param['end']))
				{
					$this->view->params['end'] = gmdate('Y-m-d', strtotime(gmdate('Y-m-d', $param['end'])));
				}
				else
				{
					$this->view->params['end'] = gmdate('Y-m-d', strtotime(gmdate('Y-m-d', time() + TOTAL_TIME_FOR_QUICKVIEW )));
				}

				$start = "{$this->view->params['start']} 00:00:00Z";
				$end = "{$this->view->params['end']} 23:59:59Z";

				if(count($calendar_list) > 0)
				{
					foreach($calendar_list as $calendarhref)
					{
						$amount = $this->_calendar->getCount($start, $end, $calendarhref);
						$this->view->params['total'] += $amount;
					}
				}
				else
				{
					$this->view->params['total'] = $this->_calendar->getCount($start, $end, '');
				}
                date_default_timezone_set($oldtz);
			}
			else if( $param['func'] == 'adduser' )
			{
				// make a calendar!

				// construct proxy username array
				if(strpos($param['proxy_username'], ',') != false)
				{
					$temp_proxy_usernames = explode(',', $param['proxy_username']);
				}
				else
				{
					$temp_proxy_usernames[] = $param['proxy_username'];
				}

				$proxy_usernames = array();
				$rfc822 = new Mail_RFC822;

				foreach($temp_proxy_usernames as $proxy_username)
				{
					if($proxy_username == '')
						continue;

					if($proxy_username[0] == '"' && $proxy_username[strlen($proxy_username)-1] == '"')
						$proxy_username = trim($proxy_username, '"');

					$proxy_usernames_rfc = $rfc822->parseAddressList( stripslashes(html_entity_decode($proxy_username,ENT_QUOTES, 'UTF-8')), null, false);
					if(count($proxy_usernames_rfc))
					{
						$proxy_usernames[] = $proxy_usernames_rfc[0]->mailbox . '@' . $proxy_usernames_rfc[0]->host;
					}
				}
				$this->_calendar->add_proxy($param['calendar_url'], $proxy_usernames, $param['mode']);
				$this->view->params['etag'] = time();
			}
			else if( $param['func'] == 'deluser' )
			{
				$etag = trim($param['etag'], '"');
				$group = $param['group'];
				$calendar_url = trim($param['calendar_url'], '"');
				$username = isset($param['username']) ? trim($param['username'], '"') : null;
				$proxy_username = trim($param['proxy_username'], '"');

				$rfc822 = new Mail_RFC822;

				$proxy_usernames = $rfc822->parseAddressList( stripslashes(html_entity_decode($proxy_username,ENT_QUOTES, 'UTF-8')), null, false);

				foreach($proxy_usernames as $name)
				{
					$proxy_username = $name->mailbox . '@' . $name->host;
				}
				$this->_calendar->del_proxy($calendar_url, $proxy_username, $param['mode'], $username);
			}
			else if( $param['func'] == 'getusers')
			{
				$this->view->user_entries = $this->_calendar->get_proxy($param['calendar_url']);
			}
			else if( $param['func'] == 'add' )
			{
				// add a new event!
				$this->view->params['relative_href'] = urldecode($param['relative_href']);
				$this->view->params['Msg_Title'] = (!empty($param['Msg_Title']) ? $param['Msg_Title'] : 'No Title');
				$this->view->params['Msg_Text']  = (!empty($param['Msg_Text']) ? $param['Msg_Text'] : '');
				$this->view->params['Msg_Type']  = (!empty($param['Msg_Type']) ? $param['Msg_Type'] : '');
				if(isset($param['endDate']))
				{
					$params['enddate']   = gmdate('Y-m-d', $param['endDate']);
				}

				if($this->view->json)
				{
					$this->view->params['date'] = gmdate('Y-m-d', $param['startDate']);
					$this->view->params['hour'] = gmdate('H', $param['startDate']);
					$this->view->params['minute'] = gmdate('i', $param['startDate']);
					if(isset($param['enddate']))
					{
						$this->view->params['enddate']   = gmdate('Y-m-d', $param['enddate']);
					}
					$this->view->params['endhour']   = gmdate('H', $param['endDate']);
					$this->view->params['endminute'] = gmdate('i', $param['endDate']);
				}
				else
				{
					$this->view->params['date']   = $param['date'];
					$this->view->params['hour']   = $param['hour'];
					$this->view->params['minute'] = $param['minute'];
					if(isset($param['enddate']))
					{
						$this->view->params['enddate']   = $param['enddate'];
					}
					$this->view->params['endhour']   = $param['endhour'];
					$this->view->params['endminute'] = $param['endminute'];

				}

				if(!array_key_exists('enddate', $this->view->params))
				{
					$this->view->params['enddate'] = $this->view->params['date'];
				}
			
				if(isset($this->view->params['enddate']))
				{
					$enddatesecs = strftime($this->view->params['enddate']);
				}

    			// Escape the <> chars

				foreach ( array('Msg_Text', 'Msg_Title') as $part )
				{
					$this->view->params[$part] = str_replace(array('<', '>'), array('&lt;', '&gt;'), $this->view->params[$part]);
				}

				$this->view->params['emailto'] = isset($param['emailto']) ? $param['emailto'] : "$this->userData['Account']";
				$msgto = preg_split('/,|;/', $this->view->params['emailto']);

				// The post is for another user, but reference the post in our calendar
				// This allows the maintainer to modify the post again
				if ( !preg_match("/$this->userData['Account']/i", $this->view->params['emailto']) )
				{
					$this->view->params['Parent'] = 1;
				}

				// Load the permission, find who can edit the post.
				if(isset($param['Permissions']))
				{
					$this->view->params['Permission'] = $param['Permissions'];
				}

				if(isset($param['Notify']))
				{
					$this->view->params['Notify']     = $param['Notify'];
				}

				// Optionally, load the vars if the user has selected to SMS notify the event
				if(isset($param['SMSnumber']))
				{
					$this->view->params['SMSnumber']    = $param['SMSnumber'];
				}
				if(isset($param['SMScountry']))
				{
					$this->view->params['SMScountry']   = $param['SMScountry'];
				}
				if(isset($param['NotifyAmount']))
				{
					$this->view->params['NotifyAmount'] = $param['NotifyAmount'];
				}
				if(isset($param['NotifyType']))
				{
					$this->view->params['NotifyType']   = $param['NotifyType'];
				}
				$this->view->params['Location']	 = $param['Location'];
				$this->view->params['AllDayEvent']  = isset($param['AllDayEvent']) ? $param['AllDayEvent'] : 0;

				// All the post in other users tables
				foreach ($msgto as $to)
				{
					
					// Lowercase the recipient
					$to = strtolower($to);

					// Clean whitespace
					$to = str_replace(' ', '', $to);

					if(isset($param['task']))
						$this->view->params['task'] = $param['task'];
					else
						$this->view->params['task'] = 0;

					$args = array(
							//'organizer' => $this->getAccountEmailAddress(),//suppress here will properly add the header with CN in the calendar model
							'task' => $this->view->params['task'],
							'title' => $this->view->params['Msg_Title'],
							'description' => $this->view->params['Msg_Text'],
							'dateStart' => strtotime("{$this->view->params['date']} {$this->view->params['hour']}:{$this->view->params['minute']}:00"),
							'dateEnd' => strtotime("{$this->view->params['enddate']} {$this->view->params['endhour']}:{$this->view->params['endminute']}:00"),
							'location' => $this->view->params['Location'],
							'allDayEvent' => $this->view->params['AllDayEvent'],
							'calendarUrl' => $this->view->params['relative_href']
						);

					$this->view->params['id'] = $this->_calendar->add_record($args);
					$this->view->params['status'] = $this->view->params['id'][1];
					$this->view->params['id'] = $this->view->params['id'][0];
				}
			}
			else if( $param['func'] == 'mkcal' )
			{
				// make a calendar!
				$delegate = isset($param['delegate']) && $param['delegate'];
				$name = trim(urldecode($param['name']), '"\\"/\'');
				$description = trim($param['description'], '"');
				$color = trim($param['color'], '"');

				$color = str_replace("#", "",$color);
				$order = trim($param['order'], '"');
				$json = trim($param['json'], '"');
				$calendar_owner = trim($param['calendar_owner'], '"');

				$new_cal = $this->_calendar->make_calendar($this->view->account, $name, $json, $delegate);

				if($new_cal == false)
				{
					$this->view->params['status'] = 'failed';
				}
				else
				{
					$relative_href = $new_cal->url;
					if($relative_href == false)
						throw new Exception("Missing href");
					$this->_calendar->update_calendar_ex($relative_href, 'http://apple.com/ns/ical/', 'calendar-color', '#' . strtoupper($color) . 'FF');
					$this->view->params['relative_href'] = $relative_href;
					$this->view->params['principal_url'] = $new_cal->principalUrl;
					$this->view->params['ctag'] = '';
					$this->view->params['etag'] = '';
					$this->view->params['name'] = $name;
					$this->view->params['description'] = $description;
					$this->view->params['color'] = $param['color'];
					$this->view->params['order'] = $order;
					$this->view->params['calendar_owner'] = $calendar_owner;
					$this->view->params['account'] = $this->view->account;
				}
			}
			else if( $param['func'] == 'delcal' )
			{
				// delete a calendar!
				if(!isset($param['ctag'])) $param['ctag'] = '';
				$ctag = $param['ctag'];
				$etag = $param['etag'];
				$relative_href = $param['relative_href'];
				list($username, $rubbish) = explode("/", $relative_href);
				$cal = $this->_calendar;

				$status = $cal->delete_calendar($relative_href, $ctag, $etag);
				$this->view->params['relative_href'] = $relative_href;
				$this->view->params['ctag'] = $ctag;
				$this->view->params['etag'] = $etag;
			}
			else if( $param['func'] == 'updatecalname')
			{
				// udpate a calendar!
				$ctag = (isset($param['ctag']) ? $param['ctag'] : '');
				$etag = (isset($param['etag']) ? $param['etag'] : '');
				$relative_href = $param['relative_href'];
				$title = $param['title'];
				$this->_calendar->update_calendar($relative_href, 'displayname', $title);
				$this->view->params['relative_href'] = $relative_href;
				$this->view->params['ctag'] = $ctag;
				$this->view->params['etag'] = $etag;
			}
			else if( $param['func'] == 'updatecalcolor')
			{
				// udpate a calendar!
				$ctag = $param['ctag'];
				$etag = $param['etag'];
				$relative_href = $param['relative_href'];
				$color = $param['color'];
				$this->_calendar->update_calendar_ex($relative_href, 'http://apple.com/ns/ical/', 'calendar-color', '#' . strtoupper($color) . 'FF');

				$this->view->params['relative_href'] = $relative_href;
				$this->view->params['ctag'] = $ctag;
				$this->view->params['etag'] = $etag;
			}
			else if( $param['func'] == 'updatecal' )
			{
				$args = array();

				if (preg_match('/^(p|s)(\d+)/', $param['id'], $m))
				{
					$id = $m[2];
					$shared = ($m[1] == 's');
				}
				else
				{
					$shared = 0;
				}
				$this->view->params['id'] = $param['id'];

				// We are updating the calendar entry

				$mappings = array(
					'id' => 'uid',
					'relative_href' => 'calendarurl',
					'calmessage' => 'description',
					'datestart' => 'datestart',
					'dateend' => 'dateend',
					'title' => 'title',
					'datestart' => 'datestart',
					'dateend' => 'dateend',
					'location' => 'location',
					'category' => 'category',
					'availablity' => 'availablity',
					'recurrencetype' => 'recurrencetype',
					'recurrenceendtype' => 'recurrenceendtype',
					'recurrenceendbydate' => 'recurrenceendbydate',
					'recurrenceendafterx' => 'recurrenceendafterx',
					'alerttype' => 'alerttype',
					'alerttrigger' => 'alerttrigger',
					'alertposition' => 'alertposition',
					'timezone' => 'timezone',
					'attendees' => 'attendees'
				);

				foreach($param as $k => $v)
				{
					$k = strtolower($k);

					foreach($mappings as $map_key => $map_val)
					{
						if($map_key == $k)
						{
							$args[$map_val] = $v;
							break;
						}
					}
				}

				$this->view->params['status'] = $this->_calendar->update_record( $args );

			}
			else if( $param['func'] == 'delete' )
			{
				$shared = 0;
				$this->view->params['id'] = $param['id'];
				$this->view->params['relative_href'] = $param['relative_href'];
				if (preg_match('/^(p|s)(\d+)/', $param['id'], $m))
				{
					$id = $m[2];
					$shared = ($m[1] == 's');
				}
				$this->view->params['status'] = $this->_calendar->delete_record( $this->view->params['id'], $shared, $this->view->params['relative_href']);
			}
			else if ( $param['func'] == "calname" )
			{
				$this->view->calNames = $this->_calendar->getCalNames();
			}
			else if ( $param['func'] == "read" )
			{
				// read the event
				$shared =0;

				$this->view->params['id'] = $param['id'];
				if (preg_match('/^(p|s)(\d+)/', $param['id'], $m))
				{
					$id = $m[2];
					$shared = ($m[1] == 's');
				}

				$this->view->event = $this->_calendar->read_record( $this->view->params['id']);
			}
			else if ( $param['func'] == "checkuser" )
			{
				$this->view->params['status'] = 0;
				$this->view->params['username']   = $param['username'];

				if($this->_calendar->search_record( $this->view->params['username'] ))
					$this->view->params['status'] = 1;
			}
		}
		catch(Exception $e)
		{
			// an error in the call, already logged by dav backend to stderr
		}
	}
}
