<?php

//CONSIDER: revise message view to enable viewing messge id linked to folder, compound key to guarantee found
class Mail_MailController extends Atmail_Controller_Base
{
	public function init()
	{
		parent::init();
		$contextSwitch = $this->_helper->getHelper('contextSwitch');
		$contextSwitch->addActionContext('index', 'xml')->addActionContext('read', 'xml')->initContext();
	}

	public function preDispatch()
	{
		//make debugging available in this context - can be safely left on because debugging is disabled if no debug flag set in Config
		$this->log = Zend_Registry::get('log');
		
		// Setup filters
		$this->filter = Atmail_Filter_Input_Controller::filterInput($this->_request);

		// Had to move this here to enable unit testing to work
		require_once 'library/jQuery/jQuery.php';
		$this->view->jsonIdsToRender = array();

		// simple Access Control, user has to be logged in to access any of these actions
		$authed = false;
		try
		{
			$authed = Atmail_FormAuth::authenticated();
		}
		catch(Exception $e){}

		if(!$authed)
		{
	        if (isset($_REQUEST['nosso']))
			{
				$this->_forward('index', 'auth'); 
				return;
			}

			$siteConfig = Zend_Registry::get('siteConfig');
			$micrositeURL = $siteConfig->sso->microsite->url;
			$atmailURL = $siteConfig->sso->atmail->url;
			$loginserviceURL = $siteConfig->sso->loginservice->url;
			$loginserviceEndpoint = $siteConfig->sso->loginservice->endpoint;

			// Zend_Registry::get('log')->debug( __METHOD__ . ' #' . __LINE__ . ': $micrositeURL = |' . $micrositeURL . '|');
			// Zend_Registry::get('log')->debug( __METHOD__ . ' #' . __LINE__ . ': $atmailURL = |' . $atmailURL . '|');
			// Zend_Registry::get('log')->debug( __METHOD__ . ' #' . __LINE__ . ': $loginserviceURL = |' . $loginserviceURL . '|');
			// Zend_Registry::get('log')->debug( __METHOD__ . ' #' . __LINE__ . ': $loginserviceEndpoint = |' . $loginserviceEndpoint . '|');

			if (array_key_exists('chtrsessionid', $_COOKIE))
			{
				// $this->log->debug(__METHOD__ . ' #' . __LINE__ . "Starting SSO....");

				$base_url = $loginserviceURL;
				$endpoint = $loginserviceEndpoint;

				$loginService = new Zend_Rest_Client($base_url);
				$loginService->getHttpClient()->setHeaders(array('Accept' => 'application/json'));
				$client = $loginService->getHttpClient();

				$chtrsessionid = $_COOKIE['chtrsessionid'];
				$chtrpkey = $_COOKIE['chtrpkey'];

				$client->setHeaders('Cookie', array(
				    "chtrsessionid=$chtrsessionid",
				    "chtrpkey=$chtrpkey"
				));

				$data = array();
				$data['appId'] = 'atmail';
				
				// $this->log->debug(__METHOD__ . ' #' . __LINE__ . "chtrsessionid: $chtrsessionid");
				// $this->log->debug(__METHOD__ . ' #' . __LINE__ . "chtrpkey: $chtrpkey");

				$response = $loginService->restGet($endpoint, $data);
				
				if ($response->getStatus() != 200) {
					header("Location: $micrositeURL/login/#/?targetUrl=$atmailURL", true, 302);
					exit();
				}
				$responseBody  = $response->getBody();

				// $this->log->debug(__METHOD__ . ' #' . __LINE__ . "Response: $response");
				// $this->log->debug(__METHOD__ . ' #' . __LINE__ . "##### Body: $responseBody");

				$charterSSO = new CharterSSO();
				$charterSSO->setCredentials($responseBody);

				$username = $charterSSO->getUsername();
				$password = $charterSSO->getPassword();

				// $this->log->debug(__METHOD__ . ' #' . __LINE__ . "##### Username: $username");
				// $this->log->debug(__METHOD__ . ' #' . __LINE__ . "##### Password: $password");

            	$addressArray  = imap_rfc822_parse_adrlist($username, 'charter.net');
	            $emailName = $addressArray[0]->mailbox;
	            $emailHost = $addressArray[0]->host;
	            $emailFull = $emailName . '@' . $emailHost;
   
	            $_REQUEST['emailName'] = $emailName;
            	$_REQUEST['emailDomain'] = $emailHost;
            	$_REQUEST['emailDomainDefault'] = '';
            	$_REQUEST['cssStyle'] = 'Original';
            	$_REQUEST['email'] = $emailFull;
            	$_REQUEST['password'] = $password;
            	$_REQUEST['requestedServer'] = 'imap.charter.net';
            	$_REQUEST['MailType'] = 'IMAP';
            	$_REQUEST['Language'] = '';
				
	            $_GET['emailName'] = $emailName;
            	$_GET['emailDomain'] = $emailHost;
            	$_GET['emailDomainDefault'] = '';
            	$_GET['cssStyle'] = 'Original';
            	$_GET['email'] = $emailFull;
            	$_GET['password'] = $password;
            	$_GET['requestedServer'] = 'imap.charter.net';
            	$_GET['MailType'] = 'IMAP';
            	$_GET['Language'] = '';

				$this->_forward('processlogin', 'auth', 'mail');
		        return;
			}
			else
			{		
				header("Location: $micrositeURL/login/#/?targetUrl=$atmailURL", true, 302);
				exit();
			}
		}

        $this->view->requestParams = $this->_request->getParams();

        // Hook for folks using an ?iosprofile link to config an iToy
        if (isset($this->view->requestParams['iosprofile']))
        {
            $this->_forward('iosstart', 'settings', 'mail');
            return;
        }

        $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->moduleBaseUrl . '/' . $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->view->account = $this->userData['Account']; // Used in the HTML template for the logged in user
        $this->_globalConfig = Zend_Registry::get('config')->global;
        $this->view->UserSettings = Zend_Registry::get('UserSettings');
        $this->_helper->pluginCall("postFetchUserSettings");
        $this->view->company_url = $this->_globalConfig['company_url'];
        $this->view->brandname = $this->_globalConfig['brandname'];
        if($this->view->company_url == NULL || empty($this->view->company_url))
        {
            $this->view->company_url = $this->view->siteBaseUrl;
        }

        // Calculate the user-agent for iOS
        if(!empty($_SERVER['HTTP_USER_AGENT']) && preg_match('/i(phone|pad|pod)/i', $_SERVER['HTTP_USER_AGENT']))   {
            $this->view->iOS = true;
        }

        //handle folder change requests here (allowing change from all actions/events) so that correct cache can be loaded (correct folder)
        $this->_currentConfig = array();

        //instantiate other mail stores if accounts found in ServiceAccounts
        $this->view->provider = new serviceproviderapi( array('Account' => $this->userData['Account']) );
        $this->view->allProviderAccounts = $this->view->provider->listAccounts();
        $this->view->socialAccounts = $this->view->provider->listAccountsOfType('SocialNetwork');



        if( isset($this->view->requestParams['refresh']) )
        {
            $this->_currentConfig['cacheRefresh'] = $this->view->requestParams['refresh'];
        }

        if( isset($this->view->requestParams['selectFolder']) && $this->view->requestParams['selectFolder'] != 'undefined' )
        {
            $selectFolder = urldecode($this->view->requestParams['selectFolder']);
            $this->_currentConfig['folder'] = $selectFolder;
            if( isset($this->session->pageNumber) )
            {
                $this->session->pageNumber = 1;
            }
        }

        //set up mail store config to connect directly to correct folder if about to exec a move action
        if( isset($this->view->requestParams['fromFolder']) )
        {
            $fromFolder = urldecode($this->view->requestParams['fromFolder']);
            $this->_currentConfig['folder'] = $fromFolder;
            if( isset($this->session->pageNumber) )
            {
                $this->session->pageNumber = 1;
            }
        }

        $this->_mailStoreConfig = array_merge($this->_globalConfig, $this->userData, $this->_currentConfig, $this->view->UserSettings);
        if( isset($this->view->UserSettings['ThreadLimit']) )
        {

            $this->_mailStoreConfig['threadsLimitMonths'] = $this->view->UserSettings['ThreadLimit'];

        }

        //check if SSL enabled in UserSettings
        $this->_mailStoreConfig['ssl'] = ($this->_mailStoreConfig['UseSSL']=='1'?'SSL':'');
        if( array_key_exists('refresh', $this->view->requestParams ) && $this->view->requestParams['refresh'] == 'true' )
        {
            $this->_mailStoreConfig['cacheRefresh'] = true;
        }
        $this->AtmailMailStorage = Atmail_Mail_Storage::getInstance($this->_mailStoreConfig);
        $this->AtmailMailStorageMain = &$this->AtmailMailStorage->getMailStore($this->_mailStoreConfig['namespaceName']);

        $cacheRefresh = (isset($this->_mailStoreConfig['cacheRefresh']) && $this->_mailStoreConfig['cacheRefresh'] == true);
        if( $cacheRefresh || $this->AtmailMailStorageMain->dataSource == 'cached' )
        {
            // test cache time passed
            if( $cacheRefresh || (time() - $this->AtmailMailStorageMain->updateCacheStamp) > 60 )
            {
                // too old or refresh required
                $this->AtmailMailStorageMain->updateCache();
            }
        }

        $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' );
        }

        if( array_key_exists('serviceProviders', $this->_globalConfig) && $this->_globalConfig['serviceProviders'] == true )
            $this->view->serviceProvidersEnabled = true;
        else
            $this->view->serviceProvidersEnabled = false;

        if( $this->view->serviceProvidersEnabled && array_key_exists('SIPEnabled', $this->_globalConfig) && $this->_globalConfig['SIPEnabled'] == true )
        {

            $this->view->SIPEnabled = true;
            $this->view->UCDBEnabled = (array_key_exists('UCDBEnabled', $this->_globalConfig) && $this->_globalConfig['UCDBEnabled'] == true );

        }
        else
        {

            $this->view->SIPEnabled = false;
            $this->view->UCDBEnabled = false;

        }

        if( $this->view->UCDBEnabled )
        {

            $this->view->SIPFolders = array();
            $this->view->SIPFolders["CDR"] = "Calls";

            if( $this->_globalConfig['SIPType'] == 'SAMSUNG' )
                $this->view->SIPFolders["SMS"] = "SMS";

        }

        if( $this->view->SIPEnabled )
        {

            $this->view->SIPServerType = $this->_globalConfig['SIPType'];
            $this->view->serviceProviders = new  serviceproviderapi( array('Account' => $this->userData['Account']) );
            $sipAccounts = $this->view->serviceProviders->listAccountsOfType('SIP');
            if( count($sipAccounts) > 0 )
            {

                $this->view->selectedSIPAccount = $sipAccounts[count($sipAccounts)-1]; //select last one until multi enabled
                if($this->view->selectedSIPAccount['SIP'] != '1')
                {

                    $this->view->SIPEnabled = false;
                    $this->view->UCDBEnabled = false;

                }

            }
            else
                $this->view->selectedSIPAccount = null;

            if( array_key_exists('SIPgwMode', $this->_globalConfig) )
                $this->view->SIPgwMode = $this->_globalConfig['SIPgwMode'];
            else
                $this->view->SIPgwMode = 'flashphoner';

        }
	}

	public function postDispatch()
	{
		//$this->AtmailMailStorageMain->saveCache();
	}

	public function indexAction()
	{
		
		$requestParams = $this->getRequest()->getParams();
		
		if( isset($requestParams['testing']) ){
			$this->view->testing = true;
    	}
       
		$this->view->mainFolders = array();
		$this->view->mainFolders['Inbox'] = $this->AtmailMailStorageMain->getMainFolderName();
		$this->view->mainFolders['Drafts'] = $this->AtmailMailStorageMain->getMainFolderName('Drafts');
		$this->view->mainFolders['Sent'] = $this->AtmailMailStorageMain->getMainFolderName('Sent');
		$this->view->mainFolders['Spam'] = $this->AtmailMailStorageMain->getMainFolderName('Spam');
        $this->view->mainFolders['Trash'] = $this->AtmailMailStorageMain->getMainFolderName('Trash');
		
		$this->AtmailMailStorageMain->selectFolder( $this->view->mainFolders['Inbox'] );
		$this->view->emails = $this->getInitMessageList();
		$this->view->currentFolder = $this->AtmailMailStorageMain->getCurrentFolder();
		$this->view->folders = $this->getImapFolders();
		
        // If iOS, hardcode to 2-pane, no option
      if( !empty($this->view->iOS) ){
            $this->session->listViewType = 'twoPane';
		}
            
		//TODO: if not in session dather default to user custom config

		$this->view->listViewType = $this->session->listViewType;
		$this->view->AtmailMailStorageMain = $this->AtmailMailStorageMain;
		// Return our base folders
		//change back to current folder
		// $this->AtmailMailStorageMain->selectFolder($this->view->currentFolder);

        license::u3($this);
	}

	public function getInitMessageList() {
		$limit  = $this->view->UserSettings['MsgNum'];
		$folder = $this->AtmailMailStorageMain->getCurrentFolder();
		$msgs   = array();
		$rawmsg = $this->AtmailMailStorageMain->getBasicHeadersPage(1,$limit);
		
		for($i = 0; $i < count($rawmsg); $i++){
			$flags  = str_replace("\\",'',join(',',$rawmsg[$i]['FLAGS']));
			$msgs[] = array(
				'basicHeaders' => $rawmsg[$i]['_basicHeaders'],
				'preview'      => $rawmsg[$i]['_preview'],
				'UID'          => $rawmsg[$i]['UID'],
				'flags'        => $flags,
				'size'			=> $rawmsg[$i]['RFC822.SIZE'],
				'attachments'  => $rawmsg[$i]['attachmentCount'],
				'acct'			=> '0',
				'acctName'     => 'Charter'
			);
		}
		return $msgs;
	}

	public function getImapFolders(){
		$folders  = $this->AtmailMailStorageMain->getFolders();
		$iterator = new RecursiveIteratorIterator($folders,RecursiveIteratorIterator::SELF_FIRST);
		$fstruct  = array();

		if($iterator){
			foreach($iterator as $local => $fldr){
				$global = $fldr->getGlobalName();
				$main   = in_array($local,array('INBOX','Drafts','Sent','Spam','Trash'));
				$unread = null;
				$total  = null;

				if($main){
					$unread = $this->AtmailMailStorageMain->getFolderUnreadCount($global);
					$total  = $this->AtmailMailStorageMain->countMessages($global);
				}

				$fstruct[$local] = array(
					'id'           => urlencode( base64_encode( $global ) ),
					'localName'    => $local,
					'unread'       => $unread,
					'hasChildren'  => $iterator->hasChildren(),
					'globalName'   => $global,
					'messageCount' => $total,
					'isMainFolder' => $main
				);
				
				natcasesort($fstruct);
			}	
		}	
		return $fstruct;
	}

	/**
	*   expects to get an ajax request for data on folder info
	*   @return JSON
	*/
	public function updatefoldertotalsAction()
	{
		
		//calculate folder message totals
		$folderTotals = array();
		$folders = new RecursiveIteratorIterator($this->AtmailMailStorageMain->getFolders(), RecursiveIteratorIterator::SELF_FIRST);
		
		//special ids for reserved folders
		$reservedFoldernamesGlobal = array();
		$reservedFoldernamesGlobal[] = $this->AtmailMailStorageMain->getMainFolderName('Inbox');
		$reservedFoldernamesGlobal[] = $this->AtmailMailStorageMain->getMainFolderName('Sent');
		$reservedFoldernamesGlobal[] = $this->AtmailMailStorageMain->getMainFolderName('Trash');
		$reservedFoldernamesGlobal[] = $this->AtmailMailStorageMain->getMainFolderName('Drafts');
		$reservedFoldernamesGlobal[] = $this->AtmailMailStorageMain->getMainFolderName('Spam');
                
		foreach( $folders as $localName => $folder )
		{
			
			//if folder not countable (corrupted etc. then flag as such but continue)
			try
			{
				// TODO: Count *UNREAD* messages
				//'name' => $folder->getGlobalName(), //not needed, causes confusion and corruption of ajax response
				
				
				if( in_array($folder->getGlobalName(), $reservedFoldernamesGlobal) )
				{
					
					$id = 'folder_' . strtolower($localName); //for CSS icons
					
				}
				else
				{
					
					$id = 'folder_' . safeId($folder->getGlobalName());
					
				}
				
				$folderTotals[] = array(
						//'name' => $folder->getGlobalName(), //not needed, causes confusion and corruption of ajax response
						'info' => array('unseen' => $this->AtmailMailStorageMain->countUnseenMessages($folder->getGlobalName())),
						'id' => $id,
						'name' => $folder->getGlobalName()
				);
			}
			catch ( Exception $e )
			{
				// silent fail
			}
			
		}
		
		// we output directly here!
		echo Zend_Json::encode($folderTotals);
		$this->_helper->viewRenderer->setNoRender();
		
		return;

	}

	public function findNewestEmail( $checkTime, $messages, $latest = false, $latestMessage = false )
	{
		$current = 0;
		// find the latest email
		foreach( (array) $messages as $message )
		{
			if($message == null) continue;
			
			if(array_key_exists('_basicHeaders', $message))
			{
				$current = strtotime($message['_basicHeaders']['date']);
				if( $latest === false || $current > $latest)
				{
					$latest=$current;
					$latestMessage = $message;
				}
			}
			else
			{
				// no basic headers, must be a thread holder
			}			
						
			if($message['_totalChildren'] != 1)
			{
				// found a threaded message
				$latestMessage = $this->findNewestEmail($checkTime, $message['_children'], $latest, $latestMessage);
				$latest = strtotime($latestMessage['_basicHeaders']['date']);
			}
			
			if(array_key_exists('FLAGS', $message) && !array_key_exists(Zend_Mail_Storage::FLAG_SEEN, $message['FLAGS']))
			{
				// found an unread, check if its within the last x mins
				if($current > $checkTime)
				{
					// yup, lets use
					$latest=$current;
					$latestMessage = $message;
					break;
				}
			}

		}
		
		return $latestMessage;
	}
	
	public function listfoldermessagesAction() 
	{
		$requestParams = $this->_request->getParams();
		$threadsEnabled = $this->AtmailMailStorageMain->getThreadsEnabled();

		$filterType = array_key_exists('filter',$requestParams)?$requestParams['filter']:'';
		if(in_array($filterType, array('unread', 'flagged')))
			unset($requestParams['filter']);

		$this->view->noMessageText = empty($filterType)? 'Found no messages matching search criteria.' : 'Found no messages matching ' . $filterType . ' filter.';

		//fork here to prep for searching folder instead of just listing
		$this->view->searching = false;
		$resultContext = 'messageList';
		if( isset($requestParams['searching']) && $requestParams['searching'] == 'true' )
		{
			$this->view->searching = true;
			$resultContext = $requestParams['resultContext'];

			if(isset($requestParams['filter']) && empty($requestParams['filter'])) {
				unset($requestParams['filter']);
			}
			
			if (!empty($requestParams['to'])      || 
			    !empty($requestParams['from'])    || 
			    !empty($requestParams['subject']) || 
			    !empty($requestParams['body'])    ||
			    isset($requestParams['unseen'])   ||
			    isset($requestParams['flagged'])  ||
				isset($requestParams['filter']))
			{
				$this->view->advancedSearching = true;
			}
			else
			{
				$this->view->searchQueryUTF8 = urldecode( urldecode( $this->view->requestParams['searchQuery'] ) );
			}	
		}

		$this->view->resultContext = $resultContext;
			
		if( isset($requestParams['listViewType']) )
		{
			$this->session->listViewType = $requestParams['listViewType'];
		}
		
		// Reset sort order, third click
		if( isset($requestParams['nosort']) )
		{
			$this->session->order = '';
			$this->session->sort = '';
		}

		//handle page changes
		$this->session->pageVolume = $this->view->UserSettings['MsgNum'];

		if(!isset($this->session->pageNumber) || (isset($this->session->pageNumber) && $this->session->pageNumber == 'undefined'))
		{
			$this->session->pageNumber = 1;
		}

		// Set sort method if defined in Config (this is a hidden setting not found in webadmin)
		if (isset($this->_globalConfig['defaultImapSort']) && in_array($this->_globalConfig['defaultImapSort'], array('DATE', 'ARRIVAL')))
		{
			$this->session->sort = $this->_globalConfig['defaultImapSort'];
		}
		
		if( !isset($this->session->sort) )
		{
			$this->session->sort = 'UID';
		}
		
		if( !isset($this->session->order) )
		{
			$this->session->order = 'REVERSE';
		}
		
		if( isset($requestParams['page']) && $requestParams['page'] != 'undefined' )
		{
			$this->session->pageNumber = $requestParams['page'];
		}
		
		if( isset($requestParams['quantity']) )
		{
			$this->session->pageVolume = $requestParams['quantity'];
		}
		
		if( isset($requestParams['sort']) )
		{
			$this->session->sort = $requestParams['sort'];
			$this->session->pageNumber = 1;
		}

		if( isset($requestParams['order']) )
		{
			$this->session->order = $requestParams['order'];
		}
		
		//flip sorting on from to sorting on to if browsing a sent folder
		if( $this->session->sort == 'from'
		&& 	strtolower($this->AtmailMailStorageMain->getCurrentFolder()) == strtolower($this->AtmailMailStorageMain->getMainFolderName('Sent')) )
		{
			$this->session->sort = 'to';
		}
		
		$this->AtmailMailStorageMain->setSortAndOrder($this->session->sort,$this->session->order);
		$this->view->AtmailMailStorageMain = $this->AtmailMailStorageMain;
		
		$this->view->pageVolume = $this->session->pageVolume;
		$this->view->pageNumber = $this->session->pageNumber;
		$this->view->sort = $this->session->sort;
		$this->view->order = $this->session->order;
		$this->view->listViewType = $this->session->listViewType;
		$this->view->currentFolder = $this->AtmailMailStorageMain->getCurrentFolder();
		
		//calling getFolderInfo() will set threadsEnabled
		$currentFolderInfo = $this->AtmailMailStorageMain->getFolderInfo(); 
		
		//disable threads for drafts and sent folders
		if( 
			$this->view->currentFolder == $this->AtmailMailStorageMain->getMainFolderName('Sent') || 
			$this->view->currentFolder == $this->AtmailMailStorageMain->getMainFolderName('Drafts') 
		)
		{
			$this->AtmailMailStorageMain->setThreadsEnabled(false);
		}
		
		$currentFolderObject = $this->AtmailMailStorageMain->getCurrentFolderObject(); 
		$this->view->currentFolderLocalNameUTF8 = $this->AtmailMailStorageMain->decodeUTF7( $currentFolderObject->getLocalName() );
        
		if( isset($requestParams['sort']) && !in_array('SORT', $this->AtmailMailStorageMain->getCapability() ) )
		{
			jQuery::addMessage('Remote mail server does not support sorting, ordered by id');
		}
		elseif( isset($requestParams['sort']) && $this->AtmailMailStorageMain->countTotalThreadMessages() > $this->AtmailMailStorageMain->getSortMaxLimit() )
		{
			jQuery::addMessage('Sorting disabled, too many messages, ordered by id');
		}
		elseif( !$threadsEnabled &&  isset($requestParams['sort']) && $this->AtmailMailStorageMain->countTotalMessages() > $this->AtmailMailStorageMain->getSortMaxLimit() )
		{
			jQuery::addMessage('Sorting disabled, too many messages, ordered by id');
		}
		
		$this->view->threadsEnabled = $this->AtmailMailStorageMain->getThreadsEnabled();		        
		$this->view->currentFolderURLEncoded = urlencode($this->view->currentFolder);
		$this->view->currentFolderDoubleURLEncoded = urlencode($this->view->currentFolderURLEncoded);
		
		//special ids for reserved folders
		$reservedFoldernamesGlobal = array();
		$reservedFoldernamesGlobal[] = $this->AtmailMailStorageMain->getMainFolderName();
		$reservedFoldernamesGlobal[] = $this->AtmailMailStorageMain->getMainFolderName('Sent');
		$reservedFoldernamesGlobal[] = $this->AtmailMailStorageMain->getMainFolderName('Trash');
		$reservedFoldernamesGlobal[] = $this->AtmailMailStorageMain->getMainFolderName('Drafts');
		$reservedFoldernamesGlobal[] = $this->AtmailMailStorageMain->getMainFolderName('Spam');
                
		if( in_array($this->view->currentFolder, $reservedFoldernamesGlobal) )
		{
			$folderObj = $this->AtmailMailStorageMain->getCurrentFolderObject($this->view->currentFolder);
			$localName = $folderObj->getLocalName();
			$id = 'folder_' . strtolower( $localName );
		}
		else
		{
			$id = 'folder_' . safeId($this->view->currentFolder);
		}

		//update current folder item in folder list with latest total
		jQuery('#Email div#' . $id . ' .unread:first strong:first')->updateTotal( $this->AtmailMailStorageMain->countUnseenMessages() );
		
		if( $this->view->searching )
		{
			if ($this->view->advancedSearching)
			{
				$preparedSearchQueryFinal = array();
				if (!empty($requestParams['to']))
				{
					$preparedSearchQueryFinal['to'] = array('field' => 'to', 'value' => $requestParams['to']);
				}
				if (!empty($requestParams['from']))
				{
					$preparedSearchQueryFinal['from'] = array('field' => 'from', 'value' => $requestParams['from']);
				}
				if (!empty($requestParams['subject']))
				{
					$preparedSearchQueryFinal['subject'] = array('field' => 'subject', 'value' => $requestParams['subject']);
				}
				if (!empty($requestParams['body']))
				{
					$preparedSearchQueryFinal['text'] = array('field' => 'text', 'value' => $requestParams['body']);
				}
				if (!empty($requestParams['goBack']) && $requestParams['goBack'] > 0)
				{
					$since =  date("j-M-Y", strtotime("-{$requestParams['goBack']} months"));
					$preparedSearchQueryFinal['since'] = array('field' => 'since', 'value' => $since);
				}
				if (isset($requestParams['unseen'])) {
					$preparedSearchQueryFinal['unseen'] = array('field' => 'raw', 'value' => 'unseen');
				}
				if (isset($requestParams['flagged'])) {
					$preparedSearchQueryFinal['flagged'] = array('field' => 'raw', 'value' => 'flagged');
				}
				if (isset($requestParams['filter'])) {
					$preparedSearchQueryFinal['filter'] = array('field' => 'filter', 'value' => $requestParams['filter']);
				}
				
			} else {
				
				//try split the query by tokens else search to, from, subject.
				$tokensPos = array(
					'from:'    => array('start' => -1, 'end' => -1, 'value' => null),
					'to:'      => array('start' => -1, 'end' => -1, 'value' => null),
					'subject:' => array('start' => -1, 'end' => -1, 'value' => null),
					'body:'    => array('start' => -1, 'end' => -1, 'value' => null),
					'text:'    => array('start' => -1, 'end' => -1, 'value' => null),
					'since:'    => array('start' => -1, 'end' => -1, 'value' => null),
					'before:'    => array('start' => -1, 'end' => -1, 'value' => null)
				);

				$this->view->searchQueryUTF8 = strtolower($this->view->searchQueryUTF8);			
				foreach( $tokensPos as $token => $pos )
				{
					if( ($pos = mb_strpos($this->view->searchQueryUTF8, $token, 0, 'UTF-8')) !== false )
					{
						$tokensPos[$token]['start'] = $pos;	
					}	
				}
				
				//if the lowest pos > -1 is not 0 then we have non token search as well
				$strlenSearch = mb_strlen($this->view->searchQueryUTF8);
				
				//now go through each one and build up the boundaries, trim and apply as a search term
				$lowestTokenStart = $strlenSearch;
				foreach( $tokensPos as $token => $vector )
				{
					$vector['end'] = $strlenSearch;
					//got start now find end
					foreach( $tokensPos as $testToken => $testVector)
					{
						//if tested token is after current token and is shorter than current length then switch 
						//(making sleection shorter and shorter intil we have just the one token)
						if( $testVector['start'] > $vector['start'] && $testVector['start'] < $vector['end'] )
						{
							$vector['end'] = $testVector['start'];
						}
					}
					
					//push start forward the length of the token and save $pos back into array
					if( $vector['start'] >= 0 && $vector['end'] >= 0 )
					{
						$vector['value'] = trim(mb_substr($this->view->searchQueryUTF8, $vector['start']+mb_strlen($token), $vector['end']-($vector['start']+mb_strlen($token))));
					}
					$tokensPos[$token] = $vector;
					
					//update lowestPos to try find if untokenised string present.
					if( $vector['start'] >= 0 && $vector['start'] < $lowestTokenStart )
					{
						$lowestTokenStart = $vector['start'];
					}
				}

				$preparedSearchQuery = array();
				$tokensFoundInSearchString = false;
				$this->view->textSearch = false;
				foreach( $tokensPos as $token => $vector )
				{
					if( $vector['value'] != null )
					{
						$tokensFoundInSearchString = true;
						$searchKey = mb_substr($token,0,-1);
						$words = mb_split("[ ]+", $vector['value'] );

						foreach($words as $word)
						{
							$preparedSearchQuery[] = array('field' => $searchKey, 'value' => $word);
						}

						if( $searchKey == 'body' || $searchKey == 'text' )
						{
							$this->view->textSearch = true;
						}
					}
				}
				if( $tokensFoundInSearchString == false )
				{
					$words = mb_split("[ ]+", $this->view->searchQueryUTF8 );
					foreach($words as $word)
					{
						$preparedSearchQuery[] = array('field' => 'raw', 'value' => 'OR FROM "' . $word . '" OR TO "' . $word . '" SUBJECT "' . $word . '"');
					}
				}
				else
				{
					//if tokens found and lowestTokenPos != 0 then add a raw string as well
					//if lowestPos > 0, then raw string between 0 and lowestToken
					if( $lowestTokenStart != 0 )
					{
						$words = mb_split("[ ]+", trim(mb_substr($this->view->searchQueryUTF8, 0, $lowestTokenStart)) );
						foreach($words as $word)
						{
							$preparedSearchQuery[] = array('field' => 'raw', 'value' => 'OR FROM "' . $word . '" OR TO "' . $word . '" SUBJECT "' . $word . '"');
						}
					}
				}

				//join all same type tokens that have been split //TODO: dont split them in the first place
				$seenTokens = array();
				$preparedSearchQueryFinal = array();
				foreach( $preparedSearchQuery as &$query )
				{
					if( in_array($query['field'], $seenTokens) )
					{
						$preparedSearchQueryFinal[$query['field']]['value'] .= ' ' . $query['value'];
					}
					else
					{
						$preparedSearchQueryFinal[$query['field']] = array('field' => $query['field'], 'value' => $query['value']);
						$seenTokens[] = $query['field'];
					}
				}
			}
			
			$searchResults = $this->view->AtmailMailStorageMain->search($preparedSearchQueryFinal);
			if (!empty($searchResults)) 
			{
				$this->view->messages = $this->view->AtmailMailStorageMain->getBasicHeadersPage($this->view->pageNumber, $this->view->pageVolume);
			}
			
			$this->view->totalMessages = count($searchResults);
			$this->view->AtmailMailStorageMain->setThreadsEnabled( false );
			$this->view->threadsEnabled = $this->view->AtmailMailStorageMain->getThreadsEnabled();
		}
		elseif( $this->view->threadsEnabled ) 
		{
			$this->view->messages = $this->view->AtmailMailStorageMain->getThreadsBasicHeadersPage($this->view->pageNumber, $this->view->pageVolume);
			$this->view->totalMessages = $this->view->AtmailMailStorageMain->countTotalThreadMessages();
		}
		else
		{
			$this->view->messages = $this->view->AtmailMailStorageMain->getBasicHeadersPage($this->view->pageNumber, $this->view->pageVolume);
			$this->view->totalMessages = $this->view->AtmailMailStorageMain->countTotalMessages();
		}
		
		$currentIdsString = "";
		if( !is_array($this->view->messages) )
		{
			$this->view->messages = array();
		}

		$this->view->hasThreads = count($this->view->totalMessages) > 1;

		$newEmailFavIcon = getFavicon(Zend_registry::get('config')->global['install_dir'], $this->view->siteBaseUrl, 'newemail');

		$originalEmailFavIcon = getFavicon(Zend_registry::get('config')->global['install_dir'], $this->view->siteBaseUrl, 'email');
		$checkTime = time() - 60 * 5;
		
		if(!$this->view->searching && ($this->view->UserSettings['AutoReload'] & Atmail_Enum::AUTORELOAD_FAVICON) && $id == 'folder_inbox')
		{
			$latestMessage = $this->findNewestEmail($checkTime, $this->view->messages);
				
			if($latestMessage !== false)
			{
			
				if(!array_key_exists(Zend_Mail_Storage::FLAG_SEEN, $latestMessage['FLAGS']))
				{
					$this->view->watchMessage = $latestMessage;
					// unseen latest
					jQuery::evalScript("
						myFavicon = '" . $newEmailFavIcon . "';
						if(myFavicon != '')
						{
							$('#favicon').attr('href', myFavicon);
							message = $('#" . $latestMessage['UID'] . "', '#Email');
							if(message.length)
							{
								message.attr('new', true);
								message.bind('click', function()
								{
									myFavicon = $('#favicon').attr('originalhref');	
									if(myFavicon != '')
									{
										$('#favicon').attr('href', myFavicon);
										newfavicon = $('#favicon').clone();
										$('#favicon').remove();
										$('body').append(newfavicon);
									}
								});
							}
							newfavicon = $('#favicon').clone();
							$('#favicon').remove();
							$('body').append(newfavicon);
						}
					");
				}
				else
				{
					jQuery::evalScript("
						myFavicon = $('#favicon').attr('originalhref');	
						if(myFavicon != '')
						{
							$('#favicon').attr('href', myFavicon);
							newfavicon = $('#favicon').clone();
							$('#favicon').remove();
							$('body').append(newfavicon);
						}
					");
				}
			}
		}
		foreach( $this->view->messages as $message )
		{
			$currentIdsString .= (array_key_exists("_latestUID", $message)?$message["_latestUID"]:$message['UID']) . ", ";
		}

		$resultContext = $resultContext . '[listFolder="' . $this->view->currentFolderDoubleURLEncoded . '"], #' . $resultContext . ':has(#listFolder[value="' . $this->view->currentFolderDoubleURLEncoded . '"])';

		if($this->session->listViewType == 'compact')
		{
			if( array_key_exists('refresh', $requestParams ) && $requestParams['refresh'] == 'true' )
			{
				$this->view->jsonIdsToRender['(#' . $resultContext . ') #primary_content_inner:first'] = 'mail/compactlist.phtml';
			}
			else
			{
				$this->view->jsonIdsToRender[$resultContext] = 'mail/indexlistmessagescompact.phtml';
			}
		}
		else
		{
			$this->view->jsonIdsToRender[$resultContext] = 'mail/indexlistmessages.phtml';
		}
		
		jQuery::evalScript("$('#action_get_mail a').enableActionSimpler()");

		//if refreshing then dont force load message view pane in case composing reply/reading etc. = only reload message list
		// if new messages, then play sound
		//if they are !on page 1 of some selected, then dont reload, just update folder count and beep
		
		$this->view->currentIdsMd5 = md5($currentIdsString);
		$this->view->firstCheckedUID = null;
		
		if( array_key_exists('refresh', $requestParams ) && $requestParams['refresh'] == 'true' )
		{
			$this->view->refresh = true;
			
			//if refreshing and no changes or no previous check, then send nothing back
			if( $requestParams['currentIdsMd5'] == '' || $requestParams['currentIdsMd5'] == $this->view->currentIdsMd5 )
			{
				$this->_helper->viewRenderer->setNoRender();
				return;
			}
			
			if( $requestParams['moreThanOneChecked'] == 'true' || $this->session->pageNumber != '1' )
			{
				unset($this->view->jsonIdsToRender['primary_content_inner:first']); //3 pane
				unset($this->view->jsonIdsToRender[$resultContext]); //2 pane
				jQuery::evalScript("window.currentIdsMd5 = '" . $this->view->currentIdsMd5 . "';");
			}
			
			if( array_key_exists('firstCheckedUID', $requestParams) )
			{
				$this->view->firstCheckedUID = $requestParams['firstCheckedUID'];
			}
			if( $this->view->UserSettings['AutoReload'] & Atmail_Enum::AUTORELOAD_AUDIO )
			{
				jQuery::evalScript("$('#jquery_jplayer:first').jPlayer('setFile', '" . $this->view->siteBaseUrl . "sounds/online.mp3', '" . $this->view->siteBaseUrl . "sounds/online.ogg').jPlayer('play');");	
			}
		}
		else
		{
			$this->view->refresh = false;
		}
		
		jQuery::evalScript("updateFolderActionButton();");
		
		$this->render('global/jsonresponse', null, true);		
	}
	
	public function foldercreateAction()
	{
		
		$requestParams = $this->_request->getParams();
		if( !isset($requestParams['folderNameNew']) )
		{

			throw new Atmail_Mail_Exception('Compulsory argument folderNameNew not present');

		}
		$currentFolder = $this->AtmailMailStorageMain->getCurrentFolder();

		//if main folder force to root folder (physically in INBOX. (main namespace root), but logically (according to UI) appears as a root folder)
		//special ids for reserved folders
		$mainFoldernamesGlobal = array();
		$mainFoldernamesGlobal[] = $this->AtmailMailStorageMain->getMainFolderName();
		$mainFoldernamesGlobal[] = $this->AtmailMailStorageMain->getMainFolderName('Sent');
		$mainFoldernamesGlobal[] = $this->AtmailMailStorageMain->getMainFolderName('Trash');
		$mainFoldernamesGlobal[] = $this->AtmailMailStorageMain->getMainFolderName('Drafts');
		$mainFoldernamesGlobal[] = $this->AtmailMailStorageMain->getMainFolderName('Spam');

		if( in_array($currentFolder, $mainFoldernamesGlobal) || (isset($requestParams['makeRootFolder']) && $requestParams['makeRootFolder'] == true) )
			$currentFolder = $this->AtmailMailStorageMain->getFolderNamespaceDefault();

		$folderNameNewAsOrigionallySuppliedFromJsEncoding = $requestParams['folderNameNew'];
		$folderNameNew = urldecode( $requestParams['folderNameNew'] );
		$folderNameNewUrlencodedDouble = urlencode( urlencode( $folderNameNew ) );
		$folderNameNewUTF7 = $this->AtmailMailStorageMain->encodeUTF7( $folderNameNew );
        $folderNameGlobalOrigional = urlencode($folderNameNewAsOrigionallySuppliedFromJsEncoding);
			
		try
		{
			
			$folderNameGlobalUTF7 = $this->AtmailMailStorageMain->createFolder( $folderNameNewUTF7, $currentFolder );

			// reselect current folder
			$currentFolder = $this->AtmailMailStorageMain->getCurrentFolder();
			$this->_renderFolders($currentFolder);
			return;

		}
		catch( Exception $e ) 
		{

            //$this->log->debug( __METHOD__ . ' #' . __LINE__ . ": exception:\n " . $e);
			//fail gracefully
			jQuery::evalScript('$("#nav_secondary li:last", "#Email").remove()');
			jQuery::addError( $this->view->translate('Unable to create folder.') );// . $e->getMessage() );
			
		}
		$this->render('global/jsonresponse', null, true);

	}

	public function folderrenameAction()
	{
		$this->AtmailMailStorageMain->connect();
		$log = Zend_Registry::get('log');
		$requestParams = $this->_request->getParams();
		$folderNameGlobalOldUTF7 = urldecode( $requestParams['folderNameGlobalOld'] );
		$folderNameGlobalOldUTF7UrlencodedDouble = urlencode(urlencode($folderNameGlobalOldUTF7));
		$folderNameLocalNewUTF8 = urldecode($requestParams['folderNameNew']);
        $folderNameLocalNewUTF7 = $this->AtmailMailStorageMain->encodeUTF7( $folderNameLocalNewUTF8 );
        
		//calculate folderNameGlobalNew from folderNameGlobalOld and folderNameNew
		$lastDelimiter = strrpos($folderNameGlobalOldUTF7, $this->AtmailMailStorageMain->getFolderDelimiterDefault());
		
		if( $lastDelimiter === false )
		{
			//not a subfolder
			$folderNameGlobalNewUTF7 = $folderNameLocalNewUTF7;
		
		}
		else
		{
			$folderNameGlobalNewUTF7 = substr($folderNameGlobalOldUTF7, 0, $lastDelimiter ) . $this->AtmailMailStorageMain->getFolderDelimiterDefault() . $folderNameLocalNewUTF7;
		
		}

		try
		{
		    
			// $this->log->debug( __METHOD__ . ' #' . __LINE__ . ": renaming: " . $folderNameGlobalOldUTF7 . ' to ' . $folderNameGlobalNewUTF7);
			
			$folderNameGlobalNewUTF7 = $this->AtmailMailStorageMain->renameFolder($folderNameGlobalOldUTF7, $folderNameGlobalNewUTF7);
		    $folderNameGlobalNewUTF7UrlencodedDouble = urlencode( urlencode( $folderNameGlobalNewUTF7 ) );
            
			if( strrpos( $folderNameGlobalNewUTF7, $this->AtmailMailStorageMain->getFolderDelimiterDefault() ) !== false )
			{
				
				$folderNameLocalNewUTF7 = substr($folderNameGlobalNewUTF7, (strrpos( $folderNameGlobalNewUTF7, $this->AtmailMailStorageMain->getFolderDelimiterDefault() )+1) );
            }
			else
			{
				
				$folderNameLocalNewUTF7 = $folderNameGlobalNewUTF7;
				
			}
						
			$folderNameLocalNewUTF8 = $this->AtmailMailStorageMain->decodeUTF7( $folderNameLocalNewUTF7 );
			$folderNameLocalNewUTF8HtmlEntities = htmlentities($folderNameLocalNewUTF8, ENT_QUOTES, 'UTF-8' );

			//update 3pane title if current folder
			jQuery('#Email:has(div[foldernameglobal=' . $folderNameGlobalOldUTF7UrlencodedDouble . ']) #viewFolder')->html( $folderNameLocalNewUTF8HtmlEntities );

			//update link
			jQuery('#Email #nav_secondary div[foldernameglobal=' . $folderNameGlobalOldUTF7UrlencodedDouble . ']')->updateChildrenGlobalFolder( $folderNameGlobalOldUTF7UrlencodedDouble,$folderNameGlobalNewUTF7UrlencodedDouble );
			jQuery('#Email #nav_secondary div[foldernameglobal=' . $folderNameGlobalOldUTF7UrlencodedDouble . '] a span.label')->html( $folderNameLocalNewUTF8HtmlEntities );
			jQuery('#Email #nav_secondary div[foldernameglobal=' . $folderNameGlobalOldUTF7UrlencodedDouble . '] a')->attr('href', $this->view->moduleBaseUrl . '/mail/listfoldermessages/selectFolder/' . $folderNameGlobalNewUTF7UrlencodedDouble);
			jQuery('#Email #nav_secondary div[folderNameglobal=' . $folderNameGlobalOldUTF7UrlencodedDouble . ']')->attr('id', 'folder_' . safeId($folderNameGlobalNewUTF7) ); //for css icons
			jQuery('#Email #nav_secondary div[foldernameglobal=' . $folderNameGlobalOldUTF7UrlencodedDouble . ']')->attr('folderNameGlobal', $folderNameGlobalNewUTF7UrlencodedDouble);
			jQuery('#Email #nav_secondary li span.spinner')->hide();

			// update any views or composer forms
			// but there is lots of other places, known issues -> needs consolidation of all folder name references
			jQuery('input#listFolder[value=' . $folderNameGlobalOldUTF7UrlencodedDouble . ']')->attr('value', $folderNameGlobalNewUTF7UrlencodedDouble);
			jQuery('div[listFolder=' . $folderNameGlobalOldUTF7UrlencodedDouble . ']')->attr('listFolder', $folderNameGlobalNewUTF7UrlencodedDouble);
		}
		catch( Exception $e )
		{
			
			$folderNameLocalNewUTF8HtmlEntities = htmlentities($folderNameLocalNewUTF8, ENT_QUOTES, 'UTF-8' );
			//jQuery('#Email #nav_secondary li[folderNameGlobal=' . $folderNameGlobalOldUTF7UrlencodedDouble . '] a span.label')->html( htmlspecialchars( $this->AtmailMailStorageMain->decodeUTF7($folderNameGlobalOldUTF7) ) );
			jQuery::addError('Unable to rename folder to ' . $folderNameLocalNewUTF8HtmlEntities );
			jQuery('#Email #nav_secondary li span.spinner')->hide();
			
		}
		$this->render('global/jsonresponse', null, true);
	}
	
	private function _moveFolderContentsToTrash($folderObject)
	{
		$this->AtmailMailStorageMain->selectFolder($folderObject->getGlobalName());
		$messages = $this->AtmailMailStorageMain->getBasicHeaders();
				
		$messageUIDsToMove = array();				
		foreach($messages as $message)
		{
			$messageUIDsToMove[] = (int) $message['UID'];
		}

		if(count($messageUIDsToMove))
		{
			$this->AtmailMailStorageMain->moveMessage($messageUIDsToMove , $this->AtmailMailStorageMain->getMainFolderName('Trash'));
		}
	}
	
	public function folderremoveAction()
	{
		
		$requestParams = $this->_request->getParams();

		$preserveList = array();
		$preserveList[] = $this->AtmailMailStorageMain->getMainFolderName('Inbox');
		$preserveList[] = $this->AtmailMailStorageMain->getMainFolderName('Sent');
		$preserveList[] = $this->AtmailMailStorageMain->getMainFolderName('Trash');
		$preserveList[] = $this->AtmailMailStorageMain->getMainFolderName('Drafts');
		$preserveList[] = $this->AtmailMailStorageMain->getMainFolderName('Spam');

		$folderNameGlobalUTF7 = urldecode( $requestParams['folderNameGlobal'] );
		if( in_array($folderNameGlobalUTF7, $preserveList) )
		{
			throw new Atmail_Mail_Exception( $this->view->translate('Cannot remove a main folder') );
		}
		
		//TODO: only switch to root folder if not selected or sub folder.
		$rootFolderGlobalUTF7 = $this->AtmailMailStorageMain->getMainFolderName();
		
		$rootFolderGlobalUTF7UrlencodedDouble = urlencode( urlencode( $rootFolderGlobalUTF7 ) );
		$this->AtmailMailStorageMain->selectFolder( $rootFolderGlobalUTF7 ); //change to inbox first
		jQuery('#Email #nav_secondary div[folderNameGlobal=' . $rootFolderGlobalUTF7UrlencodedDouble . '] a')->click();
				
        try 
		{
		    
			$listOfDeletedFolders = array();
			$folderObject = $this->AtmailMailStorageMain->getFolderObjectByName( $folderNameGlobalUTF7 );
			
			if( $folderObject == null )
			{
				
				throw new Exception( $this->view->translate('Unable to remove folder. Folder not found') );
				
			}
			$foldersRemoved = 0;
			foreach( new RecursiveIteratorIterator( $folderObject, RecursiveIteratorIterator::SELF_FIRST) as $object )
			{
				$this->_moveFolderContentsToTrash($object);			
				$this->AtmailMailStorageMain->selectFolder( $rootFolderGlobalUTF7 );			
				$listOfDeletedFolders[] = $object->getGlobalName();
				$this->AtmailMailStorageMain->removeFolder( $object->getGlobalName() );
				$foldersRemoved++;
				
			}
			
			//remove parent (for some reason ::SELF_FIRST is not including self)
			if( !in_array($folderNameGlobalUTF7, $listOfDeletedFolders) )
			{
				$this->_moveFolderContentsToTrash($folderObject);			
				$this->AtmailMailStorageMain->selectFolder( $rootFolderGlobalUTF7 );				
				$this->AtmailMailStorageMain->removeFolder( $folderNameGlobalUTF7 );
				$foldersRemoved++;
				
			}

		   	//call a cleanup on the head node that was deleted
			$folderNameGlobalUTF7UrlencodedDouble = urlencode( urlencode( $folderNameGlobalUTF7 ) );
			jQuery('#Email #nav_secondary div[folderNameGlobal=' . $folderNameGlobalUTF7UrlencodedDouble  . ']:last')->removeTreeNode();
		
		}
		catch( Exception $e) 
		{
		
		   jQuery::addError('Error:' . $e->getMessage() );
			
		}

		//jQuery::addMessage('Folder successfully removed');
		//jQuery('#Email #nav_secondary li[folderNameGlobal=' . $requestParams['folderNameGlobal'] . ']')->remove();
		//jQuery('#Email #nav_secondary div[folderNameGlobal=' . urlencode( urlencode($folderNameGlobal) ) . ']:last')->remove();
		$this->render('global/jsonresponse', null, true);
	}

	/**
	* Handle events to set flags
	* ZF flag action accepts an array of all flags and values so can set multiple flags.
	* Implimented to only change one flag at a time while preserving the other flags
	* Recent flag will probably fall away on setFlags
	*/
	public function flagmessageAction()
	{
		
		$params = $this->getRequest()->getParams();
		
		$appendFlag = $params['appendFlag'];
		$setFlag = $params['flag'];
		$selectFolder = $params['selectFolder'];
		
		$UIDs = $params['mailId'];
		if( !is_array($UIDs) )
			$UIDs = array($UIDs);
		$mode = "";
		
		//sanitize UIDs
		foreach( $UIDs as &$UID )
			$UID = (int)$UID;
		
		if( isset($appendFlag) && $appendFlag == 'true' )
			$mode = "+";
		
		$wantedFlags = array();
        if($setFlag == 'seen')
			$wantedFlags[] = Zend_Mail_Storage::FLAG_SEEN;
		else if( $setFlag == 'unseen' )
		{
			$wantedFlags[] = Zend_Mail_Storage::FLAG_SEEN;
			$mode = "-";
		}
		else if( $setFlag == 'flagged' )
			$wantedFlags[] = Zend_Mail_Storage::FLAG_FLAGGED;
		else if( $setFlag == '-flagged' )
		{
			$wantedFlags[] = Zend_Mail_Storage::FLAG_FLAGGED;
			$mode = "-";
		}
		
		$this->AtmailMailStorageMain->connect();
		$this->AtmailMailStorageMain->setFlagsAdvanced($UIDs, $wantedFlags, $mode);

		//now update total
		//special ids for reserved folders
		$reservedFoldernamesGlobal = array();
		$reservedFoldernamesGlobal[] = $this->AtmailMailStorageMain->getMainFolderName();
		$reservedFoldernamesGlobal[] = $this->AtmailMailStorageMain->getMainFolderName('Sent');
		$reservedFoldernamesGlobal[] = $this->AtmailMailStorageMain->getMainFolderName('Trash');
		$reservedFoldernamesGlobal[] = $this->AtmailMailStorageMain->getMainFolderName('Drafts');
		$reservedFoldernamesGlobal[] = $this->AtmailMailStorageMain->getMainFolderName('Spam');
        if( $selectFolder == 'undefined' )
        	$selectFolder = $this->AtmailMailStorageMain->getCurrentFolderObject()->getGlobalName();
        
		if( in_array($selectFolder, $reservedFoldernamesGlobal) )
		{
				
			$folderObj = $this->AtmailMailStorageMain->getCurrentFolderObject($selectFolder);
			$localName = $folderObj->getLocalName();
			$id = 'folder_' . strtolower( $localName );
			
		}
		else
			$id = 'folder_' . safeId($selectFolder);
		
		//update current folder item in folder list with latest total
		jQuery('#Email div#' . $id . ' .unread:first strong:first')->updateTotal( $this->AtmailMailStorageMain->countUnseenMessages() );
		
		//jQuery::addMessage('Messages successfully flagged as: ' . $setFlag);
		$this->render('global/jsonresponse', null, true);
		return;
		
	}
	
	public function emptyfolderAction()
	{
		
		$requestParams = $this->_request->getParams();

		if ($requestParams['deleteTrashOnLogout'])
		{
			$folderNameGlobalUTF7 = $this->AtmailMailStorageMain->getMainFolderName('Trash');
		}
		else
		{
			$folderNameGlobalUTF7 = urldecode( $requestParams['folder']);
		}
		
		//only allow use of this method for emptying trash and spam
		$allowedFolders = array();
		$allowedFolders[] = $this->AtmailMailStorageMain->getMainFolderName('Trash');
		$allowedFolders[] = $this->AtmailMailStorageMain->getMainFolderName('Spam');

		if( !in_array($folderNameGlobalUTF7, $allowedFolders) )
			throw new Atmail_Mail_Exception( $this->view->translate('Empty not allowed on this folder.') );
		
		try 
		{
		    
		    // select INBOX before we delete the current folder (Dovecot 2.x does not like you deleting a folder that is selected)
            $this->AtmailMailStorageMain->selectFolder($this->AtmailMailStorageMain->getMainFolderName());
            
			$listOfDeletedFolders = array();
			$folderObject = $this->AtmailMailStorageMain->getFolderObject( $folderNameGlobalUTF7 );
			
			if( $folderObject == null )
				throw new Exception( $this->view->translate('Unable to remove folder. Folder not found') );
			
			$foldersRemoved = 0; //looks like trash cant contain subfolders anyway.
			foreach( new RecursiveIteratorIterator( $folderObject ) as $object )
			{

				$this->log->debug( __METHOD__ . ' #' . __LINE__ . ": Deleting: " . $object->getGlobalName());
				
				$this->AtmailMailStorageMain->removeFolder( $object->getGlobalName() );
				$listOfDeletedFolders[] = $object->getGlobalName();
				$foldersRemoved++;
				$folderNameGlobalUTF7UrlencodedDouble = urlencode( urlencode( $object->getGlobalName() ) );
				jQuery('#Email #nav_secondary div[folderNameGlobal=' . $folderNameGlobalUTF7UrlencodedDouble  . ']:last')->removeTreeNode();
				
				
			}
			
			//remove parent (for some reason ::SELF_FIRST is not including self)
			if( !in_array($folderNameGlobalUTF7, $listOfDeletedFolders) )
			{
			
				$this->log->debug( __METHOD__ . ' #' . __LINE__ . ": Deleting head: " . $folderNameGlobalUTF7 );
				$this->AtmailMailStorageMain->removeFolder( $folderNameGlobalUTF7 );
				$foldersRemoved++;
				
			}
			$folderNameGlobalUTF7UrlencodedDouble = urlencode( urlencode( $folderNameGlobalUTF7 ) );
			//jQuery('#Email #nav_secondary div[folderNameGlobal=' . $folderNameGlobalUTF7UrlencodedDouble  . ']:last')->removeTreeNode();
		    $folderNameGlobalUTF7 = $this->AtmailMailStorageMain->createFolder( $folderNameGlobalUTF7, null, true );
		    
		    // re-select the folder that was deleted/re-created
		    $this->AtmailMailStorageMain->selectFolder($folderNameGlobalUTF7);
		
		}
		catch( Exception $e) 
		{
			// If we get here it's likely that deletion of a folder was not permitted,
			// try instead to mark as deleted then expunge
		    try {
				$this->AtmailMailStorageMain->selectFolder($folderNameGlobalUTF7);
				$uids = array();
				$uidList = $this->AtmailMailStorageMain->getUniqueIds();
				foreach ($uidList as $uid) {
					$uids[] = $uid['UID'];
				}
				$this->AtmailMailStorageMain->removeMessage($uids);
			} catch (Exception $e) {
				jQuery::addError('Error:' . $e->getMessage() );
			}			
		}
		
		if ($requestParams['deleteTrashOnLogout']) {
			$this->_forward('logout', 'auth', 'mail', array('trashEmptied' => 1));
			return;
		}
		
		//jQuery::evalScript("$.php('" . $this->view->moduleBaseUrl . "/mail/listfoldermessages/selectFolder/$folderNameGlobalUTF7');");
		jQuery::evalScript("$('#nav_secondary li div[foldernameglobal=" . $folderNameGlobalUTF7 . "] a', '#Email').trigger('click');");
		$this->render('global/jsonresponse', null, true);
	}

	public function movetofolderAction()
	{
		
		$requestParams = $this->_request->getParams();
		
		//fromFolder already handled by mailstore setup in Predispatch to eliminate redundant folder changes on the IMAP server
		$this->AtmailMailStorageMain->connect();
		$moveSuccess = true;
        
		//if this move request is comming from search results then disable threadding so that threaded messages not moved with moved search results
        if( isset( $requestParams['searching']) && $requestParams['searching'] == 'true' || isset($requestParams['disableThread']) )
		{
	
			$this->AtmailMailStorageMain->setThreadsEnabled( false );
	
		}
		$threadsEnabled = $this->AtmailMailStorageMain->getThreadsEnabled();

		if( !isset($requestParams['unseen']))
		{
			$requestParams['unseen'] = array();
		}

		if( isset($requestParams['mailId']) && is_array($requestParams['mailId']) && count($requestParams['mailId']) > 0 )
		{
			
			$UIDArray = $requestParams['mailId'];
			$plural = 's';
			$unseenArray = $requestParams['unseen'];
			$unseenCount = 0;
			foreach( $UIDArray as $UID )
			{
				
				if ($this->_globalConfig['enableSpamReporting'] == 1)
				{
					$spamFolder = $this->AtmailMailStorageMain->getMainFolderName("Spam");
					
					if ($requestParams['fromFolder'] == $spamFolder)
					{
						$this->_reportSpam(false, $spamFolder, $UID);
					}
					elseif ($requestParams['toFolder'] == $spamFolder)
					{
						$this->_reportSpam(true, $requestParams['fromFolder'], $UID);
					}
				}
					
				if( isset($unseenArray[$UID]) )
				{
					
					//total unread count for thread
					$unseenCount += $unseenArray[$UID];
					
				}
				
			}
			
		}
		else
		{
			
			$UIDArray = array($requestParams['UID']);
			$plural = '';
			//total unread count for thread
			$unseenCount = (isset($requestParams['unseen'])?$requestParams['unseen']:0 );
			
		}
		
		$removeCount = count($UIDArray);
		
		try
		{
			
			//now get all thread uids related to these uids
			$allThreadUIDs = array();
			$otherThreadUIDs = array();

			foreach( $UIDArray as $v )
			{
			
				if( $threadsEnabled )
				{
				
					$otherThreadUIDs = $this->AtmailMailStorageMain->recursivelyGetAllThreadUIDs( $this->AtmailMailStorageMain->getThread($v) );
				
				}
				
				// add to notice is thread messages were also found and moved
				if( count($otherThreadUIDs) > 1)
				{
					$plural = ' and threads ';
				}

				if( is_array($otherThreadUIDs) )
				{
					$allThreadUIDs = array_merge($allThreadUIDs, $otherThreadUIDs);
				}
				else
				{
					$allThreadUIDs[] = $v;
				}
			}

			//catch servers which dont support threads and just add the origional requested uids.
			if( count($allThreadUIDs) == 0 )
			{
				$allThreadUIDs = $UIDArray;
			}
			
			$fromFolder = urldecode($requestParams['fromFolder']);
			$toFolder = urldecode($requestParams['toFolder']);
			if(!isset($requestParams['actuallyDelete']))
			{
				$requestParams['actuallyDelete'] = false;
			}
			
			$actuallyDelete = $requestParams['actuallyDelete'];
			
			if( $fromFolder == $this->AtmailMailStorageMain->getMainFolderName('Trash') && $toFolder == $this->AtmailMailStorageMain->getMainFolderName('Trash') )
			{
				
				$actuallyDelete = true;
				
			}

			if( $actuallyDelete ) 
	 		{
					$this->AtmailMailStorageMain->removeMessage($allThreadUIDs);
			}
	 		else
	 		{
				try
				{
					$this->AtmailMailStorageMain->moveMessage($allThreadUIDs , $toFolder);
				}
				catch(Exception $e)
				{
					if($e->getMessage() == "Unable to copy message.")
					{
						// unable to move the email to the trash. Is the user trying to
						// prompt the user
						$this->AtmailMailStorageMain->removeMessage($allThreadUIDs);
						$actuallyDelete = true;
					}
					else
					{
						// rethrow the exception
						throw $e;
					}
				}
			}
			
			if( isset( $requestParams['expectJson'] ) ) 
			{
			
				$this->renderSuccess();
				return;	
				
			}

		}
		catch ( Exception $e )
		{

			$moveSuccess = false;
			$message = $e->getMessage();

		}

		if( $moveSuccess )
		{
			// Remove the selected entries
			$totalUIDs = count($UIDArray);
			$script = 	"panelContext = $('#primary_content_inner .messagesListForm', getVisiblePanelContext()); " . 
						"messageListContext = $('#primary_content_inner .messagesListForm ', '#messageList');" . 
						"if($('#primary_content_inner .messagesListForm .messages tbody', getVisiblePanelContext()).length>0) panelContext = $('#primary_content_inner .messagesListForm .messages tbody', getVisiblePanelContext());";
								
			foreach($UIDArray as $v)
			{
				if($totalUIDs > 10)
				{
					// fast delete rows
					$script .= "panelContext.children('#$v').remove();";
				}
				else
				{
					$script .= "panelContext.children('#$v').addClass('removing').hideMailRow();";
				}
						    
                //if this request comes from search results then we need to also cull the moved messages out of the current folder (showing in #messageList context)
				if( !isset($requestParams['searching']) || $requestParams['searching'] === 'true' )
				{
					$script .= "messageListContext.children('#$v').addClass('removing').hideMailRow();";
				}
				// TODO: If you move a message and you still have that panel open, need to change the ID returned from copy, so click forward still works
			}
			jQuery::evalScript($script . 'enableMailActions();');
			
			$lastUID = $UIDArray[count($UIDArray) - 1];
			
			if( isset($requestParams['searching']) && $requestParams['searching'] === 'true' )
			{
				$resultContext = '#' . $requestParams['resultContext'];
			}
			else
			{
				$resultContext = '#messageList';
			}
			
			 if($resultContext == '#')
			{
				$resultContext .= "messageList";	
			}

			jQuery::evalScript("var selector = $('.messagesListForm #$lastUID', '" . $resultContext . "'); if(selector.length==0) { selector = $('.messagesListForm div:first', '" . $resultContext . "'); } selector.getMailRow('" . $resultContext . "');");

			// Update the folder count for the "new" folder
			if( $requestParams['fromFolder'] != $this->AtmailMailStorageMain->getMainFolderName('Trash') || $toFolder != $this->AtmailMailStorageMain->getMainFolderName('Trash') )
			{	
				jQuery('#Email div[foldernameglobal=' . urlencode(urlencode($toFolder)) . '] .unread strong')->updateCount( $unseenCount );
			}

			// Increment down our original folder
			jQuery('#Email div[foldernameglobal=' . urlencode(urlencode($this->AtmailMailStorageMain->getCurrentFolder())) . '] .unread strong')->updateCount( '-' . $unseenCount );
			jQuery($resultContext . ' #messageListCompact')->updatePagnation('-' . $removeCount);
			jQuery($resultContext . ' #messagesListForm')->updatePagnation('-' . $removeCount);
		} 
		else
		{
			// the message was hidden in the list so we need to un-hide
			jQuery::evalScript("messageListContext = $('#primary_content_inner .messagesListForm ', '#messageList');" .
			                   "$('tr.hidden', messageListContext).show();");
			jQuery::addError('Error moving message' . $plural . '. ' . $message);
		}

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

	private function _renderFolders($currentFolder)
	{
		$this->view->currentFolder = $currentFolder;		// $this->AtmailMailStorageMain->getCurrentFolder();
		$this->view->foldersObject = $this->AtmailMailStorageMain->getFolders();
		$this->view->folders = new RecursiveIteratorIterator($this->view->foldersObject, RecursiveIteratorIterator::SELF_FIRST);

		// convert recursiveIteratorIterator to array
		// as natcasesort expects them
		if($this->view->folders)
		{
			$flat = array();
			foreach($this->view->folders as $key=>$value)
			{
				if(!is_array($value))
				{
					$flat[$key] = (string)$value;
				}
			}
		}

		$this->view->folders = $flat;
		natcasesort($this->view->folders);

		$this->view->mainFolders = array();
		$this->view->mainFolders['Inbox'] = $this->AtmailMailStorageMain->getMainFolderName();
		$this->view->mainFolders['Drafts'] = $this->AtmailMailStorageMain->getMainFolderName('Drafts');
		$this->view->mainFolders['Sent'] = $this->AtmailMailStorageMain->getMainFolderName('Sent');
		$this->view->mainFolders['Spam'] = $this->AtmailMailStorageMain->getMainFolderName('Spam');
		$this->view->mainFolders['Trash'] = $this->AtmailMailStorageMain->getMainFolderName('Trash');

		switch($this->view->UserSettings['DefaultView'])
		{
			case "2p" :
				$this->session->listViewType = 'twoPane'; // other available view is compact
			break;
			case "3p" :
				$this->session->listViewType = 'compact'; // other available view is compact
			break;
			default:
				$this->session->listViewType = 'compact'; // other available view is twoPane
		}

		//TODO: if not in session dather default to user custom config

		$this->view->listViewType = $this->session->listViewType;
		$this->view->AtmailMailStorageMain = $this->AtmailMailStorageMain;
		// Return our base folders
		//change back to current folder
		$this->AtmailMailStorageMain->selectFolder($this->view->currentFolder);

		$user = users::get($this->userData['Account']);

		try
		{
			$this->view->group = groups::get( $user['Ugroup'] );
			if($this->view->group == false)
			{
				$this->view->group = groups::get( 'default' );
			}
		}
		catch( exception $e )
		{
			$this->view->group = groups::get( 'default' );
		}

        license::u3($this);
		jQuery('#Email #secondary')->html( iconv("UTF-8", "UTF-8//TRANSLIT", $this->view->partial('mail/indexfolderlist.phtml', $this->view)) );
		jQuery::evalScript('resetMessagesDroppables()');

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

	}

	public function movefolderAction()
	{
		$this->_helper->viewRenderer->setNoRender();
		$requestParams = $this->_request->getParams();
		
		//fromFolder already handled by mailstore setup in Predispatch to eliminate redundant folder changes on the IMAP server
		$this->AtmailMailStorageMain->connect();
		$moveSuccess = true;
        
		try
		{
			$fromFolder = urldecode($requestParams['from']);
			$toFolder = urldecode($requestParams['to']);

			$pos = strrpos($fromFolder, '.');
			if($pos === FALSE) {
				require_once 'Atmail/Mail/Protocol/Exception.php';
				throw new Atmail_Mail_Protocol_Exception('cannot move folder. Invalid dest fold name.');
			}

			$fromFolderSubname = substr($fromFolder, $pos);
			$toFolder .= $fromFolderSubname;
			
			$this->AtmailMailStorageMain->renameFolder($fromFolder, $toFolder);

		}
		catch ( Exception $e )
		{

			$moveSuccess = false;
			$message = $e->getMessage();
		}

		if($moveSuccess)
		{
			$this->_renderFolders($toFolder);
			return;
		}
		else
		{
			//jQuery::addError('Move folder failed.');
			$this->render('global/jsonresponse', null, true);
			return;
		}
	}
	
	private function _reportSpam($isSpam, $folder, $uid)
	{
		$email = ($isSpam)? $this->_globalConfig['reportSpamAddress'] : $this->_globalConfig['reportNotSpamAddress'];
		
		// perform rough check for valid looking email adress,
		// return if looks invalid
		if (!preg_match("/^[^@]+@[a-z0-9.\-]+$/i", $email))
		{
			return;
		}
		
		$this->AtmailMailStorageMain->connect();
		$message = $this->AtmailMailStorageMain->getMessage($uid);

		//get subject to use as email filename
		$message->getHeaders();
		$message->processHeaders( array('uniqueid' => $uid) );
		$messageArray = messageHandling::returnPreparedMessageArray($message, array('unpackAllAttachments' => true, 'tmpFolderBaseName' => users::getTmpFolder(), 'folder' => $folder, 'uniqueId' => $uid));
		
		$subject = $messageArray['headers']['subject'];

		$filename = "email.eml"; //$this->getSafeFileNameFromSubject($rawSubject) . '.eml';
		//compose manual filename if subject was not suitable
		//if( $filename == '.eml' )
		//	$filename = 'email' . $manualAttachmentCounter++ . '.eml';

		//TODO: fetch raw message content from cached file
		$messageHeader = $this->AtmailMailStorageMain->getRawHeader($uid);
		$messageContent = $this->AtmailMailStorageMain->getRawContent($uid);
						
		$messageHeader = preg_replace('/X-Atmail-Bcc:.*\n/','',$messageHeader); 
		$rawemail = $messageHeader . $messageContent;

		$bytesWritten =  file_put_contents (users::getTmpFolder() . $filename, $rawemail );
		$attachment = array();
		$attachment['mimeType'] = 'message/rfc822';
		$attachment['filenameFS'] = $filename;
		$attachment['filenameOriginal'] = $filename;
		$attachment['tmpUrl'] = users::getTmpFolder() . $filename;
		$attachment['sizeRaw'] = $bytesWritten;
		
		$noErrorYet = true;

		// Only use the default SMTP settings if no alternate SMTP server is
		// set for spam reporting
		if (empty($this->_globalConfig['reportSpamSmtpServer']))
		{
			$smtpServer = $this->_globalConfig['smtphost'];
			
			// 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( );
		}
		else
		{
			$smtpServer = $this->_globalConfig['reportSpamSmtpServer'];
			$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($smtpServer, $config);
		$this->_helper->pluginCall("postCreateSmtpTransport", $transport);
		$newMessage = new Atmail_Mail( $this->charset );
		$newMessage->setMessageId(true);

		// Set the from, first to the ReplyTo defined in the settings, else the account login name
		// First process sender details and compile complete from and optional replyto address
		// At this stage dont accept custom replyTo or emailFrom from the compose form, take from userSettings

		//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;
			$requestParams['fromAddress'] = $this->view->UserSettings['Account'] . '@' . $configDovecot['default_domain'];
		}

		if( isset($this->view->UserSettings['RealName']) && strlen($this->view->UserSettings['RealName']) > 0 )
		{
			// ZF does not quote the realname, so lets do it
			$requestParams['fromRealname'] = $this->view->UserSettings['RealName'];
			$requestParams['fromRealname'] = trim($requestParams['fromRealname'], " \t\n\r\0\x0B");
		}
		else
			$requestParams['fromRealname'] = '';
		
		if( strlen($requestParams['fromRealname']) > 0 )
			$newMessage->setFrom( $requestParams['fromAddress'], $requestParams['fromRealname'] );
		else
			$newMessage->setFrom( $requestParams['fromAddress']);
		
		if( isset($this->view->UserSettings['ReplyTo']) && strlen($this->view->UserSettings['ReplyTo']) > 0 )
			$requestParams['replyToAddress'] = $this->view->UserSettings['ReplyTo'];
		else
			$requestParams['replyToAddress'] = '';
		
		if( strlen( $requestParams['replyToAddress']) > 0 )
		{
			//not natively supported in current ZF version
			if( strlen($requestParams['fromRealname']) > 0 )
				$newMessage->setReplyTo( $requestParams['replyToAddress'], $requestParams['fromRealname'] );
			else
				$newMessage->setReplyTo( $requestParams['replyToAddress']);
		}

		$newMessage->addTo($email);

		// Set the X-Mailer to the Atmail version
		$newMessage->addHeader('X-Mailer', $this->xMailer . " " . $this->_globalConfig['version'] );
		$newMessage->addHeader('X-Originating-IP', $_SERVER['REMOTE_ADDR']);
				
		// Set the subject and misc fields
		$newMessage->setSubject( $requestParams['emailSubject'] );
		
		// Add the HTML and text parts
		//$html2text = new html2text($requestParams['emailBodyHtml']);
		//$emailBodyText = $html2text->get_text();
		$newMessage->setBodyText("");
					
		//$newMessage->setBodyHtml($requestParams['emailBodyHtml']);

		//Handle attachments
		$filename = urldecode($attachment['filenameFS']);
		$filenameOriginal = urldecode( $attachment['filenameOriginal'] );

		if( file_exists($attachment['tmpUrl']) )
		{
			if( $fileContents = file_get_contents($attachment['tmpUrl']) )
			{
				//encode attachment filename if needed
				$preferences = array(
					"input-charset" => "UTF-8",
					"output-charset" => "UTF-8",
					"line-length" => 76,
					"scheme" => "B"
				);
				$attachmentFilename = substr(iconv_mime_encode("", $filenameOriginal, $preferences),2);
				//according to RFC 2046 message/rfc822 mimme types must be 7bit, 8bit, or binary encoded
				$attachmentEncoding = Zend_Mime::ENCODING_8BIT;
				$attachmentDisposition = Zend_Mime::DISPOSITION_ATTACHMENT ;
				$newMessage->createAttachment(
						$fileContents,
						$attachment['mimeType'],
						$attachmentDisposition,
						$attachmentEncoding,
						$attachmentFilename
				);
			}
		}

		if( $noErrorYet )
		{
			// Send the message
			try
			{
				$newMessage->send($transport);
			}
			catch (Exception $e)
			{	
				return;
			}
		}
        
		// 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->view->UserSettings['Account']);
			$log->insert("Log_SendMail", array('LogIP' => $_SERVER['REMOTE_ADDR'], 'EmailTo' => $email, 'Account' => $this->view->UserSettings['Account']));
		}
		
		// cleanup	
		if( file_exists($attachment['tmpUrl']) )
		{
			@unlink($attachment['tmpUrl']);
		}
	}
	
}

