<?php
class Mail_ViewmessageController extends Atmail_Controller_Action
{
	public function init()
	{
		parent::init();
		require_once('application/models/messageHandling.php');
	}

	public function preDispatch()
	{
		if( $this->getRequest()->isXmlHttpRequest() || $this->getRequest()->isAjax )
		{
			require_once 'library/jQuery/jQuery.php';
			$this->view->jsonIdsToRender = array();
			$this->isAjax = true;
			$this->view->jsonIdsToRender = array();
			$this->view->notices = array();
			$this->view->errors = array();
		}
		else
		{
			$this->isAjax = false;
		}

		// 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
		{
			//exposing the incoming vars to template becomes confusing with encoding, rather explicitly unpack and required vars into base form (e.g. UTF7 for folder names)
			$requestParams = $this->getRequest()->getParams();
			
			$this->view->setEncoding('UTF-8');
			$this->view->siteBaseUrl = Zend_Registry::get('siteBaseUrl');
			$this->view->appBaseUrl = $this->getRequest()->getBaseUrl() . (strpos($this->getRequest()->getBaseUrl(),'index.php')?'':'/index.php');
			$this->view->moduleBaseUrl = $this->view->appBaseUrl . DIRECTORY_SEPARATOR . ($this->view->requestParams['module']=='default'?'':$this->view->requestParams['module']) . DIRECTORY_SEPARATOR;
			$this->view->thisActionURL = $this->view->moduleBaseUrl . $this->view->requestParams['controller'] . DIRECTORY_SEPARATOR . $this->view->requestParams['action'] . DIRECTORY_SEPARATOR;
			
			$this->userData = Zend_Auth::getInstance()->getStorage()->read();
			$this->userData = Atmail_Password::processUser($this->userData);
			
			$this->_globalConfig = Zend_Registry::get('config')->global;
			$this->view->UserSettings = Zend_Registry::get('UserSettings');
			$this->view->enableSpellCheck = (isset($this->_globalConfig['enableSpellCheck']) ? $this->_globalConfig['enableSpellCheck'] : false);
			
			$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);

			$this->view->enableConfirmOnSend = $this->_globalConfig['enableConfirmOnSend'];

			//if this hit refers to a folder, connect to the store configured with this folder
			//TODO: this must be refactored in then refactoring cache
			$this->_currentConfig = array();
			if( isset($requestParams['folder']) )
			{
				$this->_currentConfig['folder'] = urldecode($requestParams['folder']);
			}
			else
			{
				$this->_currentConfig['folder'] = 'INBOX';	
			}

			$this->_mailStoreConfig = array_merge($this->_globalConfig, $this->userData, $this->_currentConfig);
			if( isset($this->view->UserSettings['ThreadLimit']) )
			{
				$this->_mailStoreConfig['threadsLimitMonths'] = $this->view->UserSettings['ThreadLimit'];
			}
			$this->_mailStoreConfig['UseSSL'] = $this->view->UserSettings['UseSSL'];
			$this->AtmailMailStorage = Atmail_Mail_Storage::getInstance($this->_mailStoreConfig);
			$this->AtmailMailStorageMain = &$this->AtmailMailStorage->getMailStore($this->_mailStoreConfig['namespaceName']);
			$this->view->tmpFolderBaseName = $this->_mailStoreConfig['tmpFolderBaseName'];
			if(!isset($requestParams['folder']))
			{
				$requestParams['folder'] = '';
			}
			
			$this->view->folderUTF7 = urldecode( $requestParams['folder'] );

			if( strpos( strtolower($this->AtmailMailStorageMain->getCurrentFolder()),'drafts') !== false )
			{
				$this->_forward('edit', 'composemessage', null, $requestParams);	
			}
			
			@date_default_timezone_set($this->view->UserSettings['TimeZone']);
			$this->AtmailMailStorageMain->setThreadsEnabled( $this->view->UserSettings['ViewThreads'] ); //will still be forced to false if !supported
			
			try
			{
				$this->view->group = groups::get( $this->userData['Ugroup'] );
				if($this->view->group == false)
				{
					$this->view->group = groups::get( 'default' );
				}
			}
			catch( exception $e )
			{
				$this->view->group = groups::get( 'default' );			
			}
			
		}
	}

	public function replyAction()
	{
		$this->view->requestParams = $this->getRequest()->getParams();
		$this->render('reply');
		
		// this can be cached
		$response = $this->getResponse();
		$response->setHeader('Cache-Control', 'public', true);
		$response->setHeader('Cache-Control', 'max-age=3800');
		$response->setHeader('Pragma', '', true);
    }

	public function indexAction()
	{
		$requestParams = $this->getRequest()->getParams();
			
		$this->view->uniqueId = null;
		if(isset($requestParams['uniqueId']) && is_numeric($requestParams['uniqueId']))
		{
			$this->view->uniqueId = $requestParams['uniqueId'];
		}
		
		//switch off threads if we know this message has no threads to speed up preparing message data
		if( isset($requestParams['threadChildrenUIDs']) && $requestParams['threadChildrenUIDs'] == 'false' )
		{
			$this->AtmailMailStorageMain->setThreadsEnabled(false);
			Zend_Registry::get('log')->debug( __METHOD__ . ' #' . __LINE__ . ": disabling threads for this hit");
		}
		
		//disable threadding of view messages for searching and viewing search result messages
		if( isset( $requestParams['searching']) && $requestParams['searching'] == 'true' )
		{
			
			$this->AtmailMailStorageMain->setThreadsEnabled( false );
			
		}
        
		$this->view->uniqueId = $requestParams['uniqueId'];
		//$this->view->viewmessageTabNumber = 0;
		if( isset($requestParams['viewmessageTabNumber']) )
		{
			
			$this->view->viewmessageTabNumber = $requestParams['viewmessageTabNumber'];
			
		}
		$this->view->AtmailMailStorageMain = $this->AtmailMailStorageMain;
		$folderUTF7 = urldecode( $requestParams['folder'] );
		$this->view->folderUTF7 = $folderUTF7;
		$this->AtmailMailStorageMain->connect();
		
		//updateFolderInfo will also set threadsEnabled
		$this->AtmailMailStorageMain->getFolderInfo();
		
		$this->currentFolder = $this->AtmailMailStorageMain->getCurrentFolder();
		
		// Are we viewing the spam folder?
		$this->view->inSpamFolder = (strtolower($this->currentFolder) == strtolower($this->AtmailMailStorageMain->getMainFolderName('Spam')));

		//are we viewing a sent or draft message

		if( 
			strtolower($this->currentFolder) == strtolower($this->AtmailMailStorageMain->getMainFolderName('Sent')) 
			|| strtolower($this->currentFolder) == strtolower($this->AtmailMailStorageMain->getMainFolderName('Drafts'))
		)
			$this->view->showToInstead = true;
		else
			$this->view->showToInstead = false;
		
		
		//check if loading message in other than default resultContext (viewable DOM panel)
		$resultContext = 'messageList';
		if( isset($requestParams['resultContext']) )
		{
			
			$resultContext = $requestParams['resultContext'];
			
		}
		$this->view->resultContext = $resultContext;      
		if(
			$this->AtmailMailStorageMain->getThreadsEnabled() 
			&& 
			( empty($requestParams['inline']) || $requestParams['inline'] == false ) 
		)
		{
			$this->view->thread = $this->AtmailMailStorageMain->getThread( $requestParams['uniqueId'] );
			$this->AtmailMailStorageMain->getThreadWithAllBasicHeaders($this->view->thread);
			$latestThreadChild = &$this->AtmailMailStorageMain->findLatestThreadChild($this->view->thread);
			$flags = $this->AtmailMailStorageMain->getFlags($latestThreadChild['UID']);
			$latestThreadChildMessage = $this->AtmailMailStorageMain->getMessage($latestThreadChild['UID']);
			$this->view->seen = isset($flags['\Seen']);
			$headers = $latestThreadChildMessage->getHeaders();
			$latestThreadChild['messageObject'] = &$latestThreadChildMessage;
			$latestThreadChild['messageArray'] = messageHandling::returnPreparedMessageArray($latestThreadChildMessage, array('tmpFolderBaseName' => users::getTmpFolder(), 'folder' => $folderUTF7, 'uniqueId' => $requestParams['uniqueId']));
		}
		else
		{
			//might have been forced here cos box > 2000 for make sure threadsEnabled = false
			$this->AtmailMailStorageMain->setThreadsEnabled( false );
			$this->view->message = array();
			$flags = $this->AtmailMailStorageMain->getFlags($requestParams['uniqueId']);
			$messageObject = $this->AtmailMailStorageMain->getMessage($requestParams['uniqueId']);
			$this->view->message['messageObject'] = &$messageObject;
			$this->view->seen = isset($flags['\Seen']);
			$this->view->message['messageObject']->getHeaders();
            $this->view->message['UID'] = $requestParams['uniqueId'];
			$this->_helper->pluginCall("postGetMessage");
			$this->view->message['messageArray'] = messageHandling::returnPreparedMessageArray($this->view->message['messageObject'], array('tmpFolderBaseName' => users::getTmpFolder(), 'folder' => $folderUTF7, 'uniqueId' => $requestParams['uniqueId']));           
		}

		// *** FILTER MESSAGE FROM ORIGINAL *** //
		$text = $this->view->message['messageArray']['bodyPreparedHtml'];

		//$text = strip_unsafe_tags($text);
		//TODO: TEXT LINK CREATION DISABLED, MUST BE MODIFIED TO ACT ON HTML BODY ONLY.
		//$text = convertPlainTextLinksToUrls($text);
		$user_settings = Zend_Registry::get('UserSettings');
		$this->view->changed = 0;
		$counter = 0;

		$md5 = md5($text);
		if($user_settings["DisplayEmailImages"] != 1)
		{
			$m = array();
			preg_match_all('/<img[^>]*>/im', $text, $m);

			foreach($m[0] as $img)
			{
				$originalImg = $img;
				$img = str_ireplace("src=", "src=\"" . $this->view->siteBaseUrl . "images/stop.png\" badsrc=", $img);

				if(strpos($img, 'title=') === false)
				{
					// no title for image
					$img = str_ireplace("<img", "<img title=\"" . $this->view->translate("Image blocked for privacy") . "\" ", $img);
				}
				else
				{
					$img = str_ireplace("title=", "title=\"" .$this->view->translate("Image blocked for privacy") . "\" badtitle=", $img);
				}

				if(strpos($img, 'class=') === false)
				{
					// no class for image
					$img = str_ireplace("<img", "<img class=\"badimagesdisabled\" ", $img);
				}
				else
				{
					$img = str_ireplace("class=", "class=\"badimagesdisabled\" badclass=", $img);
				}

				$text = str_replace($originalImg, $img, $text);
				$counter++;
			}
			$text = str_replace("background=", "background=\"" . $this->siteBaseUrl . "images/stop.png\" badbackground=", $text);
			$text = str_replace("background-image=", "background-image=\"" . $this->siteBaseUrl . "images/stop.png\" badbackground-image=", $text);
			$this->view->changed = $counter;
			$this->view->message['messageArray']['bodyHtml'] = $text;
			$this->view->message['messageArray']['displayImagesAnchor'] = (md5($text) != $md5);
		}

		$this->view->threadsEnabled = $this->AtmailMailStorageMain->getThreadsEnabled();
		$this->view->hasThreads = $this->view->threadsEnabled && isset($this->view->thread);

		$text = isset($this->view->message['messageArray']['bodyHtml']) ? $this->view->message['messageArray']['bodyHtml'] : $this->view->message['messageArray']['bodyPreparedHtml'];

		$text = $this->_helper->pluginCall("postFilterMessage", $text);
		if($text && $text != '' && $text != $this->view->message['messageArray']['bodyPreparedHtml'])
		{
			$this->view->message['messageArray']['bodyHtml'] = $text;
		}

		jQuery('#mail_info')->unblock();
		jQuery('#' . $resultContext . ' #primary_content')->unblock();
		
		if( isset($requestParams['drilldown']) && $requestParams['drilldown'] == true )
		{
			$this->view->drilldown = true;
			$this->render('threadedmessage');
		}
		elseif( isset($requestParams['compact']) )
		{
			$this->view->compact = 1;                      
			jQuery('#' . $resultContext . ' div#primary_content div#mail_info:first')->html( iconv("UTF-8", "UTF-8//IGNORE", $this->view->partial('viewmessage/threadedmessage.phtml', $this->view)) );
			if( isset($requestParams['searching']) && $requestParams['searching'] == 'true' )
			{

				$searchQuery = urldecode( urldecode( $requestParams['searchQuery'] ) );
				if($searchQuery != '')
				{
					$searchQuery = str_replace( "subject:", "", $searchQuery);
					$searchQuery = str_replace( "to:", "", $searchQuery);
					$searchQuery = str_replace( "from:", "", $searchQuery);
					$searchQuery = str_replace( "body:", "", $searchQuery);
					$searchQuery = str_replace( "text:", "", $searchQuery);
					$searchQuery = trim($searchQuery, " ");
					//jQuery('#' . $resultContext . ' div#primary_content div#mail_info:first')->highlight( $searchQuery );
					jQuery::evalScript('$("#' . $resultContext . ' div#primary_content iframe.messageIframe").load( function() {$("#' . $resultContext . ' div#primary_content iframe.messageIframe").contents().find("body").highlight("' . addslashes($searchQuery) . '") });');
				}
			}
			$this->render('global/jsonresponse', null, true);

		}
		elseif( isset($requestParams['viewmessageTabNumber']) )
		{
			if( $this->isAjax )
			{
                
				//get rendered content to put in your JSON packet this way if you need to control the order in which the JSON and this the Javascript gets executed
				//e.g. you cant highlight the search terms in the body until you have loaded the body content
				jQuery('#viewmessageTab' . $requestParams['viewmessageTabNumber'])->html( iconv("UTF-8", "UTF-8//IGNORE", $this->view->partial('viewmessage/threadedmessage.phtml', $this->view)) );
				if( isset($requestParams['searching']) && $requestParams['searching'] == 'true' )
				{

					$searchQuery = urldecode( urldecode( $requestParams['searchQuery'] ) );
					if($searchQuery != '')
					{
						$searchQuery = str_replace( "subject:", "", $searchQuery);
                                       		$searchQuery = str_replace( "to:", "", $searchQuery);
                                        	$searchQuery = str_replace( "from:", "", $searchQuery);
                                        	$searchQuery = str_replace( "body:", "", $searchQuery);
                                       		$searchQuery = str_replace( "text:", "", $searchQuery);
                                        	$searchQuery = trim($searchQuery, " ");
                                        	//jQuery('#viewmessageTab' . $requestParams['viewmessageTabNumber'] )->highlight( $searchQuery );
						jQuery::evalScript('$("#viewmessageTab' . $requestParams['viewmessageTabNumber'] .' div#primary_content iframe.messageIframe").load( function() {$("#viewmessageTab' . $requestParams['viewmessageTabNumber'] .' div#primary_content iframe.messageIframe").contents().find("body").highlight("' . addslashes($searchQuery) . '") });');
					}				
				}

				$this->render('global/jsonresponse', null, true);

			}
			else
			{

				$this->render('threadedmessage');

			}
			

		}
		else
		{	
            
			// is inline
			$this->view->inline = true;
			$this->view->messageArray = $this->view->message['messageArray'];
			$this->view->messagePanelContextName = $requestParams['messagePanelContextName'];
			$this->render('recursivelyrenderinlinemessage');

		}
		
	}   

	/**
	 * filename must be FS and URL safe
	 * filename is an Id composed of URL safe filename and uniqueId and folder	
  	 */

	public function getattachmentAction()
	{
		$this->_helper->viewRenderer->setNoRender();
		$requestParams = $this->getRequest()->getParams();
		$requiredArgs = array('folder', 'uniqueId', 'filenameOriginal');
		
		foreach( $requiredArgs as $requiredArg )
		{
			if( !array_key_exists( $requiredArg, $requestParams) )
			{
				throw new Atmail_Mail_Exception('invalid call to getattachment Action: required request argument missing: ' . $requiredArg);
			}
		}
        
		$tmpFolderBaseName = users::getTmpFolder();
		$filenameOriginal = urldecode( $requestParams['filenameOriginal'] ); //UTF-8
		$filenameOriginal = makeFSSafe( md5($filenameOriginal) );
		
		$folderUTF7 = urldecode($requestParams['folder']);
		if( array_key_exists('mimeType', $requestParams) )
		{
			$mimeType = base64_decode( $requestParams['mimeType'] );
		}

		// IE requires filenames to be rawurlencoded if multibyte chars are to be
		// displayed properly
		if( strpos($filenameOriginal, 'unknownfilename') !== false )
		{
			$filename = makeFSSafe( $filenameOriginal );
		}
		else
		{
			$filename = makeFSSafe( $folderUTF7 . $requestParams['uniqueId'] . md5($filenameOriginal) );
		}

		$filename = $tmpFolderBaseName . urldecode( $requestParams['filenameOriginal'] );
		
		if( isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') )
		{
		    $filenameOriginalHeader = rawurlencode( $filenameOriginal );
		}
		else
		{
			$filenameOriginalHeader = str_replace( '"','\"', $filenameOriginal );//properly escape double quotes as the header is wrapped in double quotes
		}

		// Check if attachment already on disk
		if( file_exists($filename) )
		{
			$this->log->debug( __METHOD__ . ' #' . __LINE__ . ": Attachment found on disk");
			
			$contentType = '';
			
			
				$extension = strtolower(substr($filenameOriginal, (strrpos($filenameOriginal,'.')+1) ));
				switch( $extension )
				{
					case 'doc':
						$contentType = 'application/msword';
						break;
					case 'gif':
						$contentType = 'image/gif';
						break;
					case 'ics':
						$contentType = 'text/calendar';
						break;
					case 'jpg':
					case 'jpeg':
						$contentType = 'image/jpeg';
						break;
					case 'htm':
					case 'html':
						$contentType = 'text/html';
						break;
					case 'pdf':
						$contentType = 'application/pdf';
						break;
					case 'png':
						$contentType = 'image/png';
						break;
					case 'txt':
						$contentType = 'text/plain';
						break;
					case 'xls':
						$contentType = 'application/x-msexcel';
						break;
					case 'xml':
						$contentType = 'text/xml';
						break;
					case 'zip':
						$contentType = 'application/x-compressed'; //or /x-zip-compressed or /zip or /x-zip
						break;
					case 'wmv':
						$contentType = 'video/x-wmv';
						break;
					case 'mp3':
						$contentType = 'octet/stream';
						break;
					case 'xlsx':
						$contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
						break;
					case 'docx':
						$contentType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
						break;
				}
				
				if( array_key_exists('mimeType', $requestParams) && $contentType == '' )
				{
					$mimeType = strtolower($mimeType);
					header("Content-Type: " . $mimeType );
					$contentType = $mimeType;
				}
				
				if($contentType == '')
				{
					$contentType = "text/plain";
				}
				
				if( isset($_SERVER['HTTP_USER_AGENT']) ) //needed for CLI UT (cant handle propper HTTP testing)
				{
					$contentType = strtolower($contentType);
					header("Content-Type: " . $contentType); //to assist with browser trying to render inside itself without poping download dialogue (e.g. images etc.)
				}
			
            
			if( isset($_SERVER['HTTP_USER_AGENT']) ) //needed for CLI UT (cant handle propper HTTP testing)
			{
				header("Pragma: ");
				header("Cache-Control: ");
				
				//force some types to be attachment and not attempt to play inline (e.g. Media Player cant play HTTPS streams)
				$forcedAttachments = array('video/x-wmv', 'audio/mpeg');
				if( in_array($contentType, $forcedAttachments) )
				{
					header("Content-Disposition: attachment; filename=\"" . $filenameOriginalHeader . "\"");
				}
				else
				{
					header("Content-Disposition: inline; filename=\"" . $filenameOriginalHeader . "\"");
				}
				header("Content-Length: " . filesize($filename) );
			}
			
			readfile($filename);
			return;
		}
		else
		{
			
			// Connect to the mailserver, get the message, and parse the attachment
			$this->AtmailMailStorageMain->connect();
			$message = $this->AtmailMailStorageMain->getMessage($requestParams['uniqueId']);
			$found = messageHandling::recursivelySearchMessageForAttachment($message, array('folder' => $folderUTF7, 'uniqueId' => $requestParams['uniqueId'], 'filename' => $filenameOriginal), $file);

			// Zend_Registry::get('log')->debug( "\n" . print_r($found, true) . "\n" . __METHOD__ . ' #' . __LINE__ . ": \$found \n");
						
			if( $found )
			{
                if( isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') )
                {
                    $filenameOriginalHeader = rawurlencode( $file['filename'] );
                }
                else
                {
                    $filenameOriginalHeader = str_replace( '"','\"', $file['filename'] );//properly escape double quotes as the header is wrapped in double quotes
                }

                if( strpos($filenameOriginal, 'unknownfilename') !== false )
                {
                    $filename = makeFSSafe( md5($filenameOriginal) );
                }
                else
                {
                    $filename = makeFSSafe( $folderUTF7 . $requestParams['uniqueId'] . md5($filenameOriginal) );
                }

                $filename = $tmpFolderBaseName . $filename;

				$bytesWritten = file_put_contents ($filename, $file['content'] );
				
				if( isset($_SERVER['HTTP_USER_AGENT']) ) //needed for CLI UT (cant handle propper HTTP testing)
				{
					header("Pragma: ");
					header("Cache-Control: ");
					//force some types to be attachment and not attempt to play inline (e.g. Media Player cant play HTTPS streams)
					if( in_array($file['mimeType'], array('video/x-wmv', 'audio/mpeg')) )
					{
						header("Content-Disposition: attachment; filename=\"" . $filenameOriginalHeader . "\"");
					}
                    else
					{
						header("Content-Disposition: inline; filename=\"" . $filenameOriginalHeader . "\"");
					}
					$file['mimeType'] = strtolower($file['mimeType']);
                    header("Content-Type: " . $file['mimeType']);
					header("Content-Length: " . $bytesWritten );
					
				}
				readfile($filename);
				return;
			}  
		}
		throw new Atmail_Mail_Exception('Attachment was not found: ' . $filenameOriginal);
	}
	
	/**
	 * filename must be FS and URL safe
	 * this should only get called from code generated by FilePreview plugin, if enabled/installed	
  	 */
	public function getthumbnailAction()
	{

		$this->_helper->viewRenderer->setNoRender();
		$requestParams = $this->getRequest()->getParams();
		$requiredArgs = array('folder', 'uniqueId', 'filenameOriginal');
		foreach( $requiredArgs as $requiredArg )
		{

			if( !array_key_exists( $requiredArg, $requestParams) )
				throw new Atmail_Mail_Exception('invalid call to getthumbnail Action: required request argument missing: ' . $requiredArg);

		}
		
		$filenameOriginal = urldecode( $requestParams['filenameOriginal'] ); //UTF-8
		$folderUTF7 = urldecode( $requestParams['folder'] );
		$tmpFolderBaseName = users::getTmpFolder();
			
		if( !array_key_exists('fileType', $requestParams) )
		{
			//create fileType from mimeType
			$requestParams['fileType'] = substr( $filenameOriginal, (strrpos($filenameOriginal,'.')+1) );
		}

		$resultContext = 'messageList';
		if( isset($requestParams['resultContext']) )
			$resultContext = $requestParams['resultContext'];
		
		$args = array(
			'context'	=> $resultContext,
			'cacheItemId' => $folderUTF7 . $requestParams['uniqueId'] . $filenameOriginal,
			'filename'	=> $filenameOriginal,
			'fileType'  => $requestParams['fileType'],
			'extendeddata' => array('requestParams' => $requestParams, 'moduleBaseUrl' => $this->view->moduleBaseUrl, 'folder' => $requestParams['folder'], 'uniqueId' => $requestParams['uniqueId'], 'tmpFolderBaseName' => users::getTmpFolder())
		);
		
		$filenameFS = $tmpFolderBaseName . makeFSSafe( $folderUTF7 . $requestParams['uniqueId'] . md5($filenameOriginal) );
		if( file_exists($filenameFS) )
		{
			
			$found = true;
			$file = file_get_contents($filenameFS);
			$resultContext = 'messageList';
			
			if( isset($requestParams['resultContext']) )
			{
				$resultContext = $requestParams['resultContext'];
			}

			$args = array(
				'context'	=> $resultContext,
				'cacheItemId' => $folderUTF7 . $requestParams['uniqueId'] . $filenameOriginal,
				'filename'	=> $filenameOriginal,
				'fileType'  => $requestParams['fileType'], 
				'content'	=> $file,
				'extendeddata' => array('requestParams' => $requestParams, 'moduleBaseUrl' => $this->view->moduleBaseUrl, 'folder' => $requestParams['folder'], 'uniqueId' => $requestParams['uniqueId'], 'tmpFolderBaseName' => users::getTmpFolder())
			);
		}
		else
		{
			
			// Connect to the mailserver (folder set in preDispatch _config), get the message, and find the attachment for making a thumbnail
			$this->AtmailMailStorageMain->connect();
			$message = $this->AtmailMailStorageMain->getMessage($requestParams['uniqueId']);
			$found = messageHandling::recursivelySearchMessageForAttachment($message, array('folder' => $requestParams['folder'], 'uniqueId' => $requestParams['uniqueId'], 'filename' => urldecode($filenameOriginal)), $file );
			if( !$found )
				throw new Atmail_Mail_Exception('Attachment was not found in message.');

			$resultContext = 'messageList';
			if( isset($requestParams['resultContext']) )
				$resultContext = $requestParams['resultContext'];

			$args = array(
				'context'	=> $resultContext,
				'cacheItemId' => $folderUTF7 . $requestParams['uniqueId'] . $filenameOriginal,
				'filename'	=> $filenameOriginal,
				'fileType'  => $requestParams['fileType'], 
				'content'	=> $file['content'],
				'extendeddata' => array('requestParams' => $requestParams, 'moduleBaseUrl' => $this->view->moduleBaseUrl, 'folder' => $requestParams['folder'], 'uniqueId' => $requestParams['uniqueId'], 'tmpFolderBaseName' => users::getTmpFolder())
			);
			
		}

		if( isset($requestParams['responseStatus']) &&
            ($requestParams['responseStatus'] == 'update' || $requestParams['responseStatus'] == 'accept' || $requestParams['responseStatus'] == 'tentative' || $requestParams['responseStatus'] == 'decline') )
		{

			$args['responseStatus'] = $requestParams['responseStatus'];
//Zend_Registry::get('log')->debug( __METHOD__ . ' #' . __LINE__ . ": Processing incoming calendar event response: " . $args['responseStatus']);
			
			
			//N.B. acceptFilePreview actually sends PHP.JSON response
			$response = $this->_helper->pluginCall('acceptFilePreview', $args);
//Zend_Registry::get('log')->debug( "\n\n" . print_r($response,true) . "\n" . __METHOD__ . ' #' . __LINE__ . ": \$response: \n\n");
			//use of this plugin, expects a PHP.JSON response (plugins don't use a uniform interface)
			$this->render('global/jsonresponse', null, true);

		}
		else
		{
	
			//N.B. createFilePreview actually sends the content response
			$this->_helper->pluginCall('createFilePreview', $args);
		
		}
	
	}
	
	public function downloadmessageAction() 
	{
			$this->_helper->viewRenderer->setNoRender();
			$requestParams = $this->getRequest()->getParams();
			
			$requiredArgs = array('folder', 'uniqueId');
			foreach( $requiredArgs as $requiredArg )
			{
				if( !array_key_exists( $requiredArg, $requestParams) )
				{
					throw new Atmail_Mail_Exception('invalid call to downloadmessage Action: required request argument missing: ' . $requiredArg);
				}
			}
	        $folderUTF7 = urldecode( $requestParams['folder'] );
			
			// Connect to the mailserver, get the message, and parse the attachment
			$this->AtmailMailStorageMain->connect();
			$message = $this->AtmailMailStorageMain->getMessage($requestParams['uniqueId']);
			
			
			if( $message )
			{
				//produce i18n fs safe filename from subject
				$mailHeader = $this->AtmailMailStorageMain->getRawHeader($requestParams['uniqueId']);
				$mailContent = $this->AtmailMailStorageMain->getRawContent($requestParams['uniqueId']);
			
				$message->getHeaders();
				$headers = $message->processHeaders( array('uniqueid' => $requestParams['uniqueId']) ); 
			
				$rawSubject = $headers['subject'];                  
				$filename = $this->getSafeFileNameFromSubject($rawSubject) . '.eml';
			
				//compose manual filename if subject was not suitable
				if( $filename == '.eml' )
				{
					$filename = 'email' . time() . '.eml';
				}
				
				header("Pragma: ");
				header("Cache-Control: ");
				header("Content-Disposition: attachment; filename=\"" . $filename . "\"");
				header("Content-Type: message/rfc822");
			    header("Content-Length: " . strlen($mailHeader . $mailContent) );
				
				//strip internel use only headers from headers             
				$mailHeader = preg_replace('/X-Atmail-Bcc:.*\n/','',$mailHeader); 
				
				echo $mailHeader . $mailContent;
				return;
			}  
			throw new Atmail_Mail_Exception('Attachment was not found: ' . $requestParams['uniqueId']);
	}
	
	public function sendreadreceiptAction()
	{
		
		$requestParams = $this->getRequest()->getParams();
		
		$message = &$this->AtmailMailStorageMain->getMessage($requestParams['uniqueId']);
		$headers = $message->getHeaders();
		
		// Decide if to enable SMTP auth or regular connection
		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( );
		
		if(PHP_OS == "Darwin")
			$config['name'] = php_uname('n');
		
        $transportClass = $this->_helper->pluginCall("smtpTransportClass");
        if (empty($transportClass))
            $transportClass = "Atmail_Mail_Transport_Smtp";

        $transport = new $transportClass($this->_globalConfig['smtphost'], $config);
		$this->charset = 'UTF-8';
        $newMessage = new Atmail_Mail( $this->charset );
        $newMessage->setMessageId(true);
        
		//format propper replyto address if short Account
		if( strpos($this->view->UserSettings['Account'], '@') !== false )
			$requestParams['fromAddress'] = $this->view->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') );
        	$requestParams['fromAddress'] = $this->view->UserSettings['Account'] . '@' . $configDovecot['default_domain'];
			
		}

		if( isset($this->view->UserSettings['RealName']) && strlen($this->view->UserSettings['RealName']) > 0 )
			$requestParams['fromRealname'] = $this->view->UserSettings['RealName'];
        else
			$requestParams['fromRealname'] = '';
        
		
		if( strlen($requestParams['fromRealname']) > 0 )
		{

			// Optionally encode the users name in the header
			if( containsUTF8($requestParams['fromRealname']) )
				$requestParams['fromRealname'] = Atmail_MIMEWords::encode_mimeword($requestParams['fromRealname'], "B", $this->charset);
        	//TODO: check if ZF wraps in ""
			$newMessage->setFrom( $requestParams['fromAddress'], $requestParams['fromRealname'] );


		}
		else
			$newMessage->setFrom( $requestParams['fromAddress']);

		$addressObjectsArray = getProcessedRecipientObjects( $headers['x-confirm-reading-to'] );
        foreach ($addressObjectsArray as $addressObject)
		{

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

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

			}
			else
			{

				$personal = $addressObject->personal;
				$mail = $addressObject->mailbox . '@' . $addressObject->host;

			}
			$personal = trim($personal, '"');
			$newMessage->addTo($mail, (strlen($personal)>0?$personal:null) );

		}

		$newMessage->addHeader('X-Mailer', "Atmail " . $this->_globalConfig['version'] );
		$newMessage->addHeader('in-reply-to', $headers['message-id'] );
        $newMessage->setSubject( $this->view->translate('Read:') . ' ' . $headers['subject'] );
				// Removing the footer_msg
        // $newMessage->setBodyText( "Message read.\n" . strip_tags($this->_globalConfig['footer_msg']));
        $newMessage->setBodyText( "Message read.\n");
		// Send the message
		try
		{
            
			$newMessage->send($transport);
            jQuery::addMessage($this->view->translate('Read receipt sent.'));
		}
		catch (Exception $e)
		{
        
    		$error = $e->getMessage();
			if( $error == 'Blocked' )
				$error = $this->view->translate('The server has rejected the email address. If you feel this address is legitimate please contact your administrator.');				
			elseif( $error == 'No recipient forward path has been supplied' )
				$error = $this->view->translate('Specify a recipient address');
			jQuery::addError( $error );
		
		}
		$this->render('global/jsonresponse', null, true);
		
	}
	
	//TODO: move this and duplicates to General.php
	private function getSafeFileNameFromSubject( $subject ) {
		return str_replace('.','_', str_replace('/','', str_replace('\\', '', strip_tags($subject))));
	}

}
                             
