<?php
class Mail_SettingsController extends Atmail_Controller_Action
{
	private $_settings;

	public function init()
	{
	
		$contextSwitch = $this->_helper->getHelper('contextSwitch');
		$contextSwitch	->addActionContext('index', 'xml')
				->addActionContext('read', 'xml')
				->initContext();
		$this->view->addHelperPath('library/Atmail/View/Helper/', 'Atmail_View_Helper');
		$this->view->version = generateVersionString(getVersionCurrentLocalCodebase());
	
	}

	public function preDispatch()
	{
		// Setup filters
		$this->filter = Atmail_Filter_Input_Controller::filterInput($this->_request);

		require_once 'library/jQuery/jQuery.php';

		if( $this->getRequest()->isXmlHttpRequest() || $this->getRequest()->isAjax )
		{
			$this->view->jsonIdsToRender = array();
			Zend_Registry::get('log')->info(__METHOD__ . ' isAJAX request');//show a hidden dialog box and include desired content
			$this->isAjax = true;
		}
		else
		{
			Zend_Registry::get('log')->info(__METHOD__ . ' normal HTML request');//show a hidden dialog box and include desired content
			$this->isAjax = false;
		}

		// 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
		{
			$this->view->UserSettings = Zend_Registry::get('UserSettings');
            $this->_helper->pluginCall('postFetchUserSettings');
			$this->view->requestParams = $this->_request->getParams();
			$this->view->setEncoding('UTF-8');
			$this->view->siteBaseUrl = Zend_Registry::get('siteBaseUrl');
			$this->view->appBaseUrl = $this->_request->getBaseUrl() . (strpos($this->_request->getBaseUrl(),'index.php')?'':'/index.php');
			$this->view->moduleBaseUrl = $this->view->appBaseUrl . ($this->view->requestParams['module']=='default'?'':'/' . $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->_globalConfig = Zend_Registry::get('config')->global;
            $this->view->global = $this->_globalConfig;
            $this->_helper->pluginCall('postFetchConfig');
			$this->_currentConfig = array();
			// iosstart.phtml runs stand alone, and needs style
			$this->view->cssStyle = 'original';
		}
			
		list($junk, $domain) = explode('@', $this->userData['Account']);
		
		$this->view->localDomain = (in_array($domain, domains::getList()) ? true : false); 
		$this->view->group = groups::get($this->view->UserSettings['Ugroup']);
		
		$this->view->Account = $this->userData['Account'];
		$this->view->configGlobal = $this->_globalConfig;
		
		//Zend_Registry::get('log')->debug( "\n" . print_r($this->view->Account, true) . "\n" . __METHOD__ . ' #' . __LINE__ . ": \$this->view->Account \n");
		
		//Zend_Registry::get('log')->debug( "\n" . print_r($this->view->configGlobal['SIPEnabled'], true) . "\n" . __METHOD__ . ' #' . __LINE__ . ": \$this->view->configGlobal['SIPEnabled'] \n");
		//Zend_Registry::get('log')->debug( "\n" . print_r($this->view->VOIPAvailable, true) . "\n" . __METHOD__ . ' #' . __LINE__ . ": \$this->view->VOIPAvailable \n");
		
		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;
		else
			$this->view->SIPEnabled = false;
		
		if( array_key_exists('SIPgwMode', $this->_globalConfig) )
			$this->view->SIPgwMode = $this->_globalConfig['SIPgwMode'];
		else
			$this->view->SIPgwMode = 'flashphoner';
		$this->view->VOIPAccountAvailable = false;
		
		if( $this->view->SIPEnabled )
		{

			$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
				$this->view->VOIPAccountAvailable = true;

				if($this->view->global['UserSIPGwEnabled'] != '1') {
					$this->view->userSIPGwEnabled = false;
				}
				else {
					$this->view->userSIPGwEnabled = true;
				}

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

		}

        $this->_helper->pluginCall('endControllerPreDispatch');

	}

	public function indexAction()
	{
		
		$this->view->ucsettings = users::getUCPlusSettings();
		
	}

	public function sipaccountpresaveAction()
	{
		$fields = $this->view->requestParams['fields'];
		$fields['Account'] = $this->view->selectedSIPAccount['Account'];
		$fields['Type'] = 'SIP';
		$fields['Provider'] = 'Atmail';
		$fields['Data'] = 'TESTING';

		$dbAdapter = Zend_Registry::get('dbAdapter');
		if( !empty($this->view->selectedSIPAccount) && !empty($this->view->selectedSIPAccount['Account']) )
		{

			//clean up any old testing accounts
			$dbAdapter->delete("ServiceAccounts", array(
				"Account = " .  $dbAdapter->quote( $this->view->selectedSIPAccount['Account'] ),
				"Type = 'SIP'",
				"Data = 'TESTING'",
			));
			
			$arr = array(
				'token' => md5($this->view->Account . $fields['AuthorizationName'] . $fields['Password']),
				'needverify' => 1,
			);

		}
		else
		{
			
			//new account being set so add it fresh
			$fields['Account'] = $this->view->Account;
			$this->view->selectedSIPAccount['Account'] = $this->view->Account;
			$fields['Type'] = 'SIP';
			$fields['Provider'] = 'Atmail';
			$fields['Data'] = '';
			$this->view->selectedSIPAccount = array('SIP' => '1');
			//$dbAdapter->insert("ServiceAccounts", $fields);
			$arr = array(
				'token' => md5($this->view->Account . $fields['AuthorizationName'] . $fields['Password']),
				'needverify' => 0,
			);
			
		}

		


		if($fields['SIP'] != $this->view->selectedSIPAccount['SIP'] || $fields['SIP']==0)
		{
			$dbAdapter->update("ServiceAccounts", array('SIP'=> $fields['SIP'] ), array(
				"Account=" . $dbAdapter->quote( $this->view->selectedSIPAccount['Account'] ),
				"Type='SIP'",
			));

			$arr['needverify'] = 0;
		}
		else
		{
			$dbAdapter->insert("ServiceAccounts", $fields);
		}
		
		$json = Zend_Json::encode($arr);
		$this->getResponse()->setHeader('Content-Type','application/x-javascript')->appendBody($json);
		$this->_helper->viewRenderer->setNoRender();
	}
	
	public function sipaccountsettingsAction()
	{

	}

	public function sipaccountsettingssaveAction()
	{
		$dbAdapter = Zend_Registry::get('dbAdapter');
		
		if($this->view->requestParams['save'] == '-1')
		{
			$dbAdapter->delete("ServiceAccounts", array(
				"Account = " .  $dbAdapter->quote( $this->view->selectedSIPAccount['Account'] ),
				"Type = 'SIP'",
				"Data = 'TESTING'",
			));
		}
		else
		{
			$fields = $this->view->requestParams['fields'];

			$dbAdapter->delete("ServiceAccounts", array(
				"Account = " .  $dbAdapter->quote( $this->view->selectedSIPAccount['Account'] ),
				"Type = 'SIP'",
				"Data = ''",
			));

			$dbAdapter->update("ServiceAccounts", array('Data'=>''), array(
				"Account = " .  $dbAdapter->quote( $this->view->selectedSIPAccount['Account'] ),
				"Type = 'SIP'",
				"Data = 'TESTING'",
			));

			jQuery::addMessage("The settings have been updated");
		}

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

	public function webmailAction()
	{
		
		try
		{
			$this->view->UserSettings = Zend_Registry::get('UserSettings');
		}
		catch( Exception $e )
		{
			// ignore - we have timed out
		}
		
		require_once 'application/models/calendar.php';
		
		$tzList =  calendar::getZoneInfoList();
		$this->view->timezoneList = '';
		
		foreach($tzList as $tz)
		{
			$this->view->timezoneList .= '<option value="' . $tz . '">' . $tz . '</option>';
		}
		
		$this->view->clientOnly = false;
		$localDomains = domains::getList();
		// TODO : This should have already been populated, but was removed when we stopped using the js session
		// for user settings. We require to revamp the whole user settings system
		list($user, $domain) = explode('@', $this->view->UserSettings['Account']);
		if( !in_array($domain, $localDomains) )
		{
			$this->view->clientOnly = true;
		}
		
		// Load the languages available
		$this->view->localeString = $this->view->UserSettings['Language'];
		$this->view->availableLocales = Atmail_Locale::getAvailableLocales();
		
		$this->filter->setData($this->view->UserSettings);
		$this->view->UserSettings = $this->filter->getEscapedData();
		$this->view->global = $this->_globalConfig;
		$this->view->availableThemes = findAvailableThemes();

		$this->render('webmail');
	}

	public function webmailsaveAction()
	{
		$requestParams = $this->_request->getParams();
		$UserSettings = array();
		$failed = false;
		
		if( isset($requestParams['fields']['ReplyTo']) && $requestParams['fields']['ReplyTo'] != '')
		{
			// validate the reply-to field
			$rfc822 = new Mail_RFC822; //appears to be buggy, fails to pass all addresses with utf-8 charset
			$rcpt = $rfc822->parseAddressList($requestParams['fields']['ReplyTo'], null, false);
		
			// check all replyto fields have user@domain
			if( is_array($rcpt) ) 
			{
				foreach( $rcpt as $email )
				{
					if($email->mailbox == '' || $email->host == '' || $email->host == 'localhost')
					{
						$failed = true;
					}
				}
			}
				
			if($failed)
			{
				unset($requestParams['fields']['ReplyTo']);
			}
		}
		if(array_key_exists('AutoReload_Bitfield', $requestParams['fields']))
		{
			unset($requestParams['fields']['AutoReload_Bitfield']);
		}
		
		foreach( array_keys($requestParams['fields']) as $field)
		{
			$UserSettings[$field] = $requestParams['fields'][$field];
		}
		
		if( isset($UserSettings['RealName']))
		{
			$UserSettings['RealName'] = str_replace('"', '', $UserSettings['RealName']);
			$UserSettings['RealName'] = html_entity_decode(html_entity_decode($UserSettings['RealName'], ENT_COMPAT, "UTF-8"), ENT_COMPAT, "UTF-8");
			
		}

		if( empty($UserSettings['ViewThreads']) && isset($UserSettings['ViewThreads']) )
		{
			$UserSettings['ViewThreads'] = 0;
		}
		
		try
		{
			$oldSettings = Zend_Registry::get('UserSettings');
			$oldDefaultView = $oldSettings['DefaultView'];
			unset($oldSettings);
			
			if( count($requestParams['fields']) > 2 && isset($UserSettings['DefaultView']) && $oldDefaultView != $UserSettings['DefaultView'])
			{		
				// view change, force reload of message view
				if($UserSettings['DefaultView'] == '2p')
				{
					jQuery::evalScript("$('#two_pane a').trigger('click');");
				}
				else 
				{
					jQuery::evalScript("$('#three_pane a').trigger('click');");
				}
			}
		}
		catch( Exception $e )
		{
			// ignore
		}
		
		if(isset($UserSettings['AutoReload']) && $UserSettings['AutoReload'])
		{
			jQuery::evalScript("checkAutoReload('" . $this->view->moduleBaseUrl . "', '', '#messageList' );");
		}
		else
		{
			jQuery::evalScript("disableAutoReload();");
		}
		
		users::saveAllUserData($this->userData['Account'], array('UserSettings' => $UserSettings));
		
		if($failed == true)
		{
			jQuery::addError( $this->view->translate('Reply-To address was invalid.') );
		}
		else
		{
			if((array_key_exists('LanguagePrev', $requestParams) && $requestParams['LanguagePrev'] != $UserSettings['Language']) || (array_key_exists('cssStyleTheme', $requestParams) && $requestParams['cssStyleThemePrev'] != $UserSettings['cssStyleTheme']))
			{
				jQuery::evalScript("location.href='" . $this->view->moduleBaseUrl . "/index'" );
			}
			else
			{
				if( !isset($requestParams['fields']['DefaultView']) || count($requestParams['fields']) > 2 )
				{
					jQuery::addMessage("The settings have been updated");
					jQuery::evalScript("$('#primary_content', '#global').scrollTop(0);");
				}
			}
		}


		// Next, update the global signature in the DOM
		if( isset($requestParams['fields']['Signature']))
			jQuery('#EmailSignature.Signature')->html($requestParams['fields']['Signature']);

		$this->render('global/jsonresponse', null, true);
	}
	
	public function updatequotaAction()
	{
		$requestParams = $this->_request->getParams();
		$totalQuota = round($this->userData['UserQuota'], 3);

        require_once('api.php');
        $api = new api(array($_SESSION));

		if(	($currentQuota = $api->getUsedQuota(array(Atmail_Quota::TYPE => Atmail_Quota::TYPE_MAILDIR, Atmail_Quota_Maildir::MAILDIR => $this->userData['MailDir']))) == -1)
		{
			// api backend failed, lets try legacy code
			$this->_mailStoreConfig = array_merge($this->_globalConfig, $this->userData, $this->_currentConfig, $this->view->UserSettings);
			$this->AtmailMailStorage = Atmail_Mail_Storage::getInstance($this->_mailStoreConfig);
			$this->AtmailMailStorageMain = &$this->AtmailMailStorage->getMailStore($this->_mailStoreConfig['namespaceName']);
			$currentQuota = $this->AtmailMailStorageMain->getQuota();
			$totalQuota = round($currentQuota[1] / 1024, 3);
			$currentQuota = round($currentQuota[0] / 1024, 1);
		}
        unset($api);
		if($currentQuota != -1)
		{
			$removeQuota = false;
			if( $totalQuota == 0 )
			{
				$removeQuota = true;
				$totalQuota = 1;
			}
			else if( ($currentQuota / $totalQuota) > 0.98 )
			{
				// over 95% of quota used
				$quotaMessageClass = "quota_exceeded_message";
				if( $currentQuota >= $totalQuota )
					$quotaMessage = $this->view->translate("You have exceeded your quota of") . " " . $totalQuota . $this->view->translate(" MB.");
				else
					$quotaMessage = $currentQuota . " " . $this->view->translate("of") . " " . $totalQuota . $this->view->translate(" MB used.");
			}
			else if( ($currentQuota / $totalQuota) > 0.80 )
			{
				// over 95% of quota used
				$quotaMessageClass = "quota_close_message";
				$quotaMessage = $currentQuota . " " . $this->view->translate("MB used.") . " " . $this->view->translate("You are approaching your quota of") . " " . $totalQuota . $this->view->translate(" MB.");
			}
			else
			{
				$quotaMessageClass = "quota_message";
				$quotaMessage = $currentQuota . " " . $this->view->translate("of") . " " . $totalQuota . $this->view->translate(" MB used.");
			}
			if(!$removeQuota)
			{
				jQuery::evalScript("$('#quotaMessage', '#settingsForm').addClass('" . $quotaMessageClass . "');");
				jQuery::evalScript("$('#quotaMessage', '#settingsForm').text('" . addslashes($quotaMessage) . "');");
				jQuery::evalScript("$('#quota_bar', '#settingsForm').progressbar('option', 'disabled', false); $('#quota_bar', '#settingsForm').progressbar('option', 'value', " . ($currentQuota / $totalQuota * 100.00) . "); $('#quota_bar .ui-progressbar-value', '#settingsForm').text('" . round($currentQuota / $totalQuota * 100.00) . "%');");
			}
			else
			{
				jQuery::evalScript("$('#currentQuota', '#settingsForm').fadeOut();");
			}
		}
		else
		{
			jQuery::evalScript("$('#currentQuota', '#settingsForm').fadeOut();");
		}
		
		$this->render('global/jsonresponse', null, true);	
	}
	public function calendarAction()
	{
		try
		{
			$this->view->UserSettings = Zend_Registry::get('UserSettings');
			if( $this->view->UserSettings['CalDavType'] == 'at' )
			{
				$this->view->caldavTypeText = "Atmail";
			}
			else if( $this->view->UserSettings['CalDavType'] == 'ap' )
			{
				$this->view->caldavTypeText = "Apple";
			}
			else if( $this->view->UserSettings['CalDavType'] == 'be' )
			{
				$this->view->caldavTypeText = "Bedework";
			}
			else if( $this->view->UserSettings['CalDavType'] == 'da' )
			{
				$this->view->caldavTypeText = "DAViCal";
			}
			else
			{
				$this->view->caldavTypeText = "Unknown";
			}

		}
		catch( Exception $e )
		{
			// ignore - we have timed out
		}

		$this->render('calendar');
	}

	public function calendarsaveAction()
	{

		// lets include the calendar object model and create a new instance !
		require_once 'application/models/calendar.php';

		$requestParams = $this->_request->getParams();
		$userSettings = array();
		$calendar_test_fail = false;
		if(isset($requestParams['fields']['CalDavView']))
		{
			$userSettings['CalDavView'] = ucfirst($requestParams['fields']['CalDavView']);
		}
		
		if(isset($requestParams['fields']['calDavUrl']))
		{
			$userSettings['calDavUrl'] = $requestParams['fields']['calDavUrl'];
		}
		
		if(isset($requestParams['fields']['CalDavUser']))
		{
			$userSettings['CalDavUser'] = $requestParams['fields']['CalDavUser'];
		}
		
		if(isset($requestParams['fields']['CalDavPass']))
		{
			$userSettings['CalDavPass'] = $requestParams['fields']['CalDavPass'];
		}
		
		if(isset($requestParams['fields']['CalDavType']))
		{
			$userSettings['CalDavType'] = (isset($requestParams['fields']['CalDavType']) ? $requestParams['fields']['CalDavType'] : 'Atmail');
		}

		if(isset($requestParams['calDavAuth']))
		{
			if($requestParams['calDavAuth'] == '')
			{
				$userSettings['CalDavUser'] = '';
				$userSettings['CalDavPass'] = '';	
			}
			
			$calendar_test_fail = false;
	
			// If no defined CalDavUser/CalDavPass, revert to the current logged in session details
			if( empty($userSettings['CalDavUser']) )
			{
				$CalDavUser = $this->userData['Account'];
			}
			else
			{
				$CalDavUser = $userSettings['CalDavUser'];
			}
	
			if( empty($userSettings['CalDavPass']) )
			{
				$CalDavPass = $this->userData['password'];
			}
			else
			{
				$CalDavPass = $userSettings['CalDavPass'];
			}
			
			$userSettings['CalDavUrl'] = trim($userSettings['CalDavUrl'], "/");
			$userSettings['CalDavUrl'] = $userSettings['CalDavUrl'] . "/";
			
			// sanity check the url
			if(strstr($userSettings['CalDavUrl'], "http") == NULL)
			{
				// there is no http protocol at the start of the string
				// lets fail.
				$calendar_test_fail = true;
			}
			else
			{
				// ok, we have a protocol
				// watch out, this could be a https protocol request
				list($junk, $domain) = explode("http", $userSettings['CalDavUrl']);
				list($junk, $domain) = explode("://", $domain);
				list($hostname, $junk) = explode("/", $domain);
				list($hostname, $port) = explode(":", $hostname);
	
				$validator = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL);
	
				if ($validator->isValid($hostname))
				{
					try
					{
						$temp_calendar = new calendar(array('Timezone' => $userSettings['TimeZone'], 'Type' => 'at', 'URL' => $userSettings['CalDavUrl'], 'Account' => $CalDavUser, 'Password' => $CalDavPass, 'Calendar' => "calendar", 'home', 'largeInstall' => '1') );
						$temp_calendar->ping();
						if( $temp_calendar->getServerAuthFailed() )
						{
							$calendar_test_fail = true;
						}
						$this->userSettings['CalDavType'] = $userSettings['CalDavType'] = $temp_calendar->getServerType();
	
						if($temp_calendar->GetCurrentPrincipal('') == false)
						{
							$calendar_test_fail = true;
						}
			
						$temp_calendar = null;
					}
					catch( Exception $e )
					{
						$calendar_test_fail = true;
					}
				} 
				else
				{
				    // hostname is invalid
					$calendar_test_fail = true;
				}			
			}
			// fake a connection error for the calendar client
			// it will force a reload
			jQuery::evalScript("_connection_error = true");
		}
		
		if( !$calendar_test_fail )
		{
			users::saveAllUserData($this->userData['Account'], array('UserSettings' => $userSettings));

			jQuery::evalScript("$('#Flash',  '#calendar').removeClass('flash_notice_error')");
			jQuery::evalScript("$('#Flash',  '#calendar').addClass('flash_notice')");
			jQuery::evalScript("$('#Flash', '#calendar').html('" . $this->view->translate('The settings have been updated.') . "');");
			jQuery::evalScript("$('#Flash', '#calendar').show();");
			jQuery::evalScript("$('#primary_content', '#calendar').scrollTop(0);");
		}
		else
		{
			// calendar test has failed.

			jQuery::evalScript("$('#Flash',  '#calendar').removeClass('flash_notice')");
			jQuery::evalScript("$('#Flash',  '#calendar').addClass('flash_notice_error')");
			jQuery::evalScript("$('#Flash',  '#calendar').show();");
			jQuery::evalScript("$('#caldavTypeText',  '#calendar').text('Unknown');");

			$error = addslashes($this->view->translate("Unable to communicate with server, incorrect username or incorrect password. Please check your details and try again."));

			// Prevent DOS attack
			sleep(2);

			jQuery::evalScript("$('#Flash',  '#calendar').html('$error');");
			jQuery::evalScript("$('#primary_content', '#calendar').scrollTop(0);");
		}

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

	public function abookAction()
	{

		require_once 'library/Atmail/Abook/Abook.php';
		$abook = new Atmail_Abook(array('protocol' => 'sql', 'Account' => $this->userData['Account']));
		$AbookServersObject = new Atmail_Abook_Servers( array('Account' => $this->userData['Account']) );
		$this->view->servers = $AbookServersObject->GetServers();

	}
	
	public function spamAction()
	{
		$this->view->spamSettings = users::getSpamSettings($this->userData['Account']);
		
		$this->filter->setData($this->view->spamSettings);
		$this->view->spamSettings = $this->filter->getEscapedData();
		
		if(!isset($this->view->spamSettings['whitelist_from']))
		{
			$this->view->spamSettings['whitelist_from']='';
		}
		if(!isset($this->view->spamSettings['blacklist_from']))
		{
			$this->view->spamSettings['blacklist_from']='';
		}
		
		$this->render('spam');
	}

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

		$SpamSettings = array(
			'required_score' => $requestParams['required_score'],
			'rewrite_header' => 'subject ' . $requestParams['rewrite_header'],
			'spam_treatment' => $requestParams['spam_treatment'],
			'whitelist_from' => $requestParams['whitelist_from'],
			'blacklist_from' => $requestParams['blacklist_from']
		);

		users::saveSpamSettings($this->userData['Account'], $SpamSettings);

		jQuery::evalScript("$('#Flash',  '#spam').show();");
		jQuery::evalScript("$('#primary_content', '#spam').scrollTop(0);");

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

	public function mailAction()
	{

		try
		{
			$this->view->UserSettings = Zend_Registry::get('UserSettings');
		}
		catch( Exception $e )
		{
			// ignore - we have timed out.
		}
		if( isset($this->view->UserSettings['AutoReply']) )
		{
			
			$this->view->UserSettings['AutoReply'] = htmlentities(base64_decode($this->view->UserSettings['AutoReply']));
			
		}
		
		$this->filter->setData($this->view->UserSettings);
		$this->view->UserSettings = $this->filter->getEscapedData();

		// This will render the template, mail.phtml, inside of views/scripts/settings/mail.phtml
		$this->render('mail');
	}

	public function mailsaveAction()
	{
		$requestParams = $this->_request->getParams();
        
		if( isset($requestParams['AutoReply']) )
		{
			
			$requestParams['AutoReply'] = base64_encode( html_entity_decode(html_entity_decode($requestParams['AutoReply'], ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8') );
			
		}
		$Users = array(
			'Forward' => $requestParams['Forward'],
			'AutoReply' => $requestParams['AutoReply']
		);
        
		users::saveAllUserData($this->userData['Account'], array('Users' => $Users));

		jQuery::evalScript("$('#Flash',  '#mailoptions').show();");
		jQuery::evalScript("$('#primary_content', '#mailoptions').scrollTop(0);");

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

	public function passwordAction()
	{
		$this->view->userSettings = Zend_Auth::getInstance()->getIdentity();
		$this->render('password');
	}
	
	public function changePasswordInLDAP($account, $oldPassword, $newPassword)
	{
		$atmailLdap = new Atmail_Ldap($account, Zend_Registry::get('config')->dovecot);
		$ldapOptions = $atmailLdap->ldapOptions();
		$ldapOptionsRoot = $atmailLdap->ldapCurrentRootDetails();
		try
		{
			/*
			 if using snake oil certificates
			 ensure /etc/openldap/ldap.conf contains
			 TLS_REQCERT=allow
			 and the Atmail Config table contains
				ldap_useSsl = true
				ldap_rootdn
				ldap_rootpw
			*/
			$successfullyConnectedToAtLeastOneServer = false;
			$hosts = explode(',', $ldapOptions['host']);
			foreach( $hosts as $host )
			{

				try
				{

					$ldapOptions['host'] = trim($host);
					// attempt connection for current user/pass
					$ldap = new Zend_Ldap($ldapOptions);
					$ldap->bind($atmailLdap->bindAuthDn, $oldPassword);

					// if we are here, no exception for user/pass failure
					// rebind with root to change password
					unset($ldap);
					$ldap = new Zend_Ldap($ldapOptions);
					$ldap->bind($ldapOptionsRoot['username'], $ldapOptionsRoot['password']);

				}
				catch( Zend_Ldap_Exception $e )
				{

					$error = $e->getMessage();
					preg_match('/0x51/', $error, $m);

					// Show if the LDAP server fails, network error (0x51)
					if($m[0] == '0x51')
						continue;
					else
					{

						$successfullyConnectedToAtLeastOneServer = true;
						throw $e;

					}

				}
				
			}
			if( !$successfullyConnectedToAtLeastOneServer )
			{
				
				throw new Exception("Unable to connect to LDAP server.");
				
			}
			try
			{
				$hm = $ldap->getEntry($atmailLdap->bindAuthDn);
			}
			catch(Zend_Ldap_Exception $e)
			{
				try
				{
					$result = $ldap->search("(userPrincipalName=$atmailLdap->bindAuthDn)", 'DC=MYDOMAINCOM,DC=GLOBAL');
					if(empty($result)) throw new Zend_Ldap_Exception('Could not query DN in search, no password updated');
					foreach ($result as $item)
					{
					    $atmailLdap->bindAuthDn = $item["dn"];
					}
					$hm = $ldap->getEntry($atmailLdap->bindAuthDn);
				}
				catch(Zend_Ldap_Exception $e2)
				{
					throw ($ldapType == 'openldap' ? $e : $e2);
				}
			}
			$activeField = 'userpassword';
			if($ldapType == 'activedirectory')
			{
				Zend_Ldap_Attribute::setPassword($hm, $newPassword, Zend_Ldap_Attribute::PASSWORD_UNICODEPWD);
				$activeField = 'unicodepwd';
			}
			else
			{
				Zend_Ldap_Attribute::setPassword($hm, $newPassword, Zend_Ldap_Attribute::PASSWORD_HASH_SHA);
			}

			foreach($hm as $k =>$v)
			{
				if($k != $activeField)
				{
					unset($hm[$k]);
				}
			}
			
			$ldap->update($atmailLdap->bindAuthDn, $hm);

			jQuery::evalScript("$('#Flash',  '#password').html('$error');");
			jQuery::evalScript("$('#primary_content', '#password').scrollTop(0);");
			
			Zend_Registry::get('log')->debug(__METHOD__ . " LDAP password change succeeded.");	

		}
		catch (Zend_Ldap_Exception $e)
		{
			switch($e->getCode())
			{
				case Zend_Ldap_Exception::LDAP_INVALID_CREDENTIALS :
				{
				     throw new Exception('Username or password invalid.');
				} break;
				default:
					throw $e;		
			}
		}		
		
	}

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

        $error = "";

        // Load password policy class library
        // Use require to halt execution if loading fails
        require_once('Atmail/PasswordPolicy.php');

        // Get password from submitted data or default
        $password = ( isset($requestParams['newPassword']) ) ? $requestParams['newPassword'] : false;

        $rules = Zend_Registry::get('config')->password;

		$pdo = Zend_Registry::get('dbAdapter');
		$stmt = $pdo->prepare('SELECT keyValue from Config where keyName = "authType"');
		if($stmt)
		{
			$stmt->execute();
			$result = $stmt->fetchAll();
			$result = strtoupper($result[0]['keyValue']);
		}
		
		if(strtoupper($result) == "LDAP")
		{
			$error = false;
			try
			{
				$this->changePasswordInLDAP($this->userData['Account'], $requestParams['currentPassword'], $requestParams['newPassword']);
			}
			catch(Exception $e)
			{
				
				jQuery::evalScript("$('#Flash',  '#password').removeClass('flash_notice')");
				jQuery::evalScript("$('#Flash',  '#password').addClass('flash_notice_error')");
				jQuery::evalScript("$('#Flash',  '#password').show();");

				$error = addslashes($this->view->translate("Existing password does not match. Please try again."));
				if( $e->getMessage() == "Unable to connect to LDAP server.")
					$error = "Unable to connect to password server. Please try again later.";
				
				// Prevent DOS attack
				sleep(2);

				jQuery::evalScript("$('#Flash',  '#password').html('$error');");
				jQuery::evalScript("$('#primary_content', '#password').scrollTop(0);");
			}
			if($error === false)
			{
				jQuery::evalScript("$('#Flash',  '#password').removeClass('flash_notice_error')");
				jQuery::evalScript("$('#Flash',  '#password').addClass('flash_notice')");
				jQuery::evalScript("$('#Flash', '#password').html('" . $this->view->translate('The settings have been updated.') . "');");
				jQuery::evalScript("$('#Flash',  '#password').show();");
				jQuery::evalScript("$('#primary_content', '#password').scrollTop(0);");
			}
		}
		else
		{
			$userSettings = array(
				'CalDavUrl' => $requestParams['calDavUrl'],
				'CalDavUser' => $requestParams['calDavUrlUser'],
				'CalDavPass' => $requestParams['calDavUrlPass'],
				'CalDavType' => $requestParams['CalDavType']
			);

			$auth = Zend_Auth::getInstance();
			$userData = $auth->getIdentity();
			$auth->getStorage()->read();

			$existingPassword = $userData['password'];


            if ($rules['use_password_policy'] == 1)
            {
                // Create password policy object
                // Pass rule array in constructor
                $policy = new PasswordPolicy($rules);

                // Validate submitted password
                $valid = $policy->validate($password);

                if( !$valid && isset($requestParams['newPassword']) )
                {
                    foreach( $policy->get_errors() as $k=>$invalid )
                    {
                        $error = $this->view->translate($invalid);
                    }

                    jQuery::evalScript("$('#Flash',  '#password').removeClass('flash_notice')");
                    jQuery::evalScript("$('#Flash',  '#password').addClass('flash_notice_error')");
                    jQuery::evalScript("$('#Flash',  '#password').show();");

                    // Prevent DOS attack
                    sleep(2);
                    jQuery::evalScript("$('#Flash',  '#password').html('$error');");
                    jQuery::evalScript("$('#primary_content', '#password').scrollTop(0);");
                }
            }
            else
            {
                if( strlen($password) < 6)
                {
                    $error = $this->view->translate('Password is too short. Must more than 6 characters/digits.');
                    jQuery::evalScript("$('#Flash',  '#password').removeClass('flash_notice')");
                    jQuery::evalScript("$('#Flash',  '#password').addClass('flash_notice_error')");
                    jQuery::evalScript("$('#Flash',  '#password').show();");

                    // Prevent DOS attack
                    sleep(2);
                    jQuery::evalScript("$('#Flash',  '#password').html('$error');");
                    jQuery::evalScript("$('#primary_content', '#password').scrollTop(0);");
                }
            }
            if(strlen($error) < 1){
    			if( $existingPassword != $requestParams['currentPassword'])
    			{
    				jQuery::evalScript("$('#Flash',  '#password').removeClass('flash_notice')");
    				jQuery::evalScript("$('#Flash',  '#password').addClass('flash_notice_error')");
    				jQuery::evalScript("$('#Flash',  '#password').show();");

    				$error = addslashes($this->view->translate("Existing password does not match. Please try again."));

    				// Prevent DOS attack
    				sleep(2);

    				jQuery::evalScript("$('#Flash',  '#password').html('$error');");
    				jQuery::evalScript("$('#primary_content', '#password').scrollTop(0);");

    			}
    			else
    			{

    				users::changePassword($this->userData['Account'], $requestParams['newPassword']);

    				// Next, update the users session, write the password to SessionData
    				$auth = Zend_Auth::getInstance();
    				$userData = $auth->getIdentity();

    				$userData['password'] = $requestParams['newPassword'];
    				$auth->getStorage()->write($userData);
    				$auth->getStorage()->read();

    				jQuery::evalScript("$('#Flash',  '#password').removeClass('flash_notice_error')");
    				jQuery::evalScript("$('#Flash',  '#password').addClass('flash_notice')");

    				jQuery::evalScript("$('#Flash', '#password').html('" . $this->view->translate('The settings have been updated.') . "');");
    				jQuery::evalScript("$('#Flash',  '#password').show();");
    				jQuery::evalScript("$('#primary_content', '#password').scrollTop(0);");
    			}
            }
		}
		$this->render('global/jsonresponse', null, true);
	}

	public function helpAction()
	{
		license::validate();
		$requestParams = $this->_request->getParams();
		$this->view->helpFile = $requestParams['helpFile'];
		$this->render('help');
	}

	public function filtersAction()
	{
		$this->_mailStoreConfig = array_merge($this->_globalConfig, $this->userData, $this->_currentConfig, $this->view->UserSettings);
	
		//get exisiting filter data
		require_once 'application/models/sieveFile.php';
		$this->view->filters = sieveFile::getFilters( $this->userData['Account'] );
		if(!isset($this->view->filters))
		{
			$this->view->filters = array();
		}
		
		$this->filter->setData($this->view->filters);
		$this->view->filters = $this->filter->getEscapedData();
		$this->AtmailMailStorage = Atmail_Mail_Storage::getInstance($this->_mailStoreConfig);
		$this->AtmailMailStorageMain = &$this->AtmailMailStorage->getMailStore($this->_mailStoreConfig['namespaceName']);
		$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] = $value;
	            }
    	    }
    	}
       
        $this->view->folders = $flat;

		ksort($this->view->folders);
	}
	
	/**
	 * @return success data so ui can render appropriate response {'success':'1/0', 'message':''}
	 */
	public function filtersaddAction()
	{
		
		
	}
	
	/**
	 * @return success data so ui can render appropriate response {'success':'1/0', 'message':''}
	 */
	public function filterseditAction()
	{
		
		$requestParams = $this->getRequest()->getParams();
		
		//only get filter data if filtersId set, else load up empty ready for add
		if( isset( $requestParams['filtersId']) )
		{
			//get exisiting filter data
			require_once 'application/models/sieveFile.php';
			$this->view->filters = sieveFile::getFilters( $this->userData['Account'] );
			$this->view->filter = $this->view->filters[$requestParams['filtersId']];
			$this->view->filtersId = $requestParams['filtersId'];
		}
		$this->_mailStoreConfig = array_merge($this->_globalConfig, $this->userData, $this->_currentConfig, $this->view->UserSettings);
		$this->AtmailMailStorage = Atmail_Mail_Storage::getInstance($this->_mailStoreConfig);
		$this->AtmailMailStorageMain = &$this->AtmailMailStorage->getMailStore($this->_mailStoreConfig['namespaceName']);
		$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] = $value;
	            }
    	    }
    	}
       
        $this->view->folders = $flat;
		natcasesort($this->view->folders);
		$this->render('filterform');
	}   
	
	/**
	 * @return success data so ui can render appropriate response {'success':'1/0', 'message':''}
	 */
	public function filterssaveAction()
	{
		
		
		$requestParams = $this->getRequest()->getParams();
		
		$filtersId = isset($requestParams['filtersId'])?$requestParams['filtersId']:false;
		$filter = $requestParams['filter'];
		foreach( $filter['matchElements'] as $elementsK => $elementV )
		{
			if( $filter['matchElements'][$elementsK]['matchType'] == 'isNot' )
			{
			
				$filter['matchElements'][$elementsK]['matchType'] = 'is';
				$filter['matchElements'][$elementsK]['not'] = true;
			
			}
			elseif( $filter['matchElements'][$elementsK]['matchType'] == 'doesNotContain' )
			{
			
				$filter['matchElements'][$elementsK]['matchType'] = 'contains';
				$filter['matchElements'][$elementsK]['not'] = true;
			
			}
			else
			{
			
				$filter['matchElements'][$elementsK]['not'] = false;
			}
		
		}
		
		//get exisiting filter data
		require_once 'application/models/sieveFile.php';
		$existingFilters = sieveFile::getFilters( $this->userData['Account'] );
		//replace existing node in filters with new node if saving, else append if new
		if( $filtersId === false )
		{
			
			$existingFilters[] = $filter;
			
		}
		else
		{
			
			$existingFilters[$filtersId] = $filter;
			
		}

		$result = sieveFile::setFilters( $this->userData['Account'], $existingFilters );
		if( $result === false )
		{
			
			$response = array('success' => '0', 'msg' => 'Failed saving filter.');
			
		}
		else
		{
			
			$response = array('success' => '1');
			
		}
		$this->_helper->viewRenderer->setNoRender();
		echo Zend_Json::encode( $response );
		
	}

	public function serverdeleteAction()
	{

		$this->_helper->viewRenderer->setNoRender();
		$requestParams = $this->getRequest()->getParams();
		
		$serverId = $requestParams['serverId'];
		
		$AbookServersObject = new Atmail_Abook_Servers( array('Account' => $this->userData['Account']) );

		$result = $AbookServersObject->DeleteServer($serverId[0]);
		
		if( $result === false )
		{			
			
			jQuery::addError( $this->view->translate('Failed deleting server.') );
				
		}
		else
		{
			
			jQuery::evalScript("$('#total_servers', '#abook').attr('value', $('#total_servers', '#abook').attr('value')-1); if($('#total_servers', '#abook').attr('value') < 1) $('#noservers', '#abook').show();");
			jQuery::evalScript("$('#abook').find('#serverID').each( function() { if( $(this).attr('value') == '" . $serverId[0] . "') { $(this).parent().fadeOut('slow', function() { $(this).remove() }); } })");
			jQuery::evalScript("$.php('" . $this->view->moduleBaseUrl . "/contacts/pushrefreshcontactsserverslist')");
			
		}
		$this->render('global/jsonresponse', null, true);
		
	}
	
	public function serversaveAction()
	{

		$requestParams = $this->getRequest()->getParams();
		
		$username = $requestParams['username'];
		$password = $requestParams['password'];
		$server = $requestParams['server'];
		
		if(strpos($server, ":") != false)
			list($server, $port) = explode(":", $server, 2);
		
		if(empty($username) || empty($password) || empty($server))
		{

			jQuery::addError( $this->view->translate('Please provide full account details. Please review and try again.') );
			if( strlen($server) == 0 )
				jQuery('#abook #server')->focus();
			elseif( strlen($username) == 0 )
				jQuery('#abook #username')->focus();
			if( strlen($password) == 0 )
				jQuery('#abook input#password')->focus();
			$this->render('global/jsonresponse', null, true);
			return;

		}
		$secure_connection = 0;//$requestParams['secure'];
		if($port == "")
			$port = '8800'; //$requestParams['port'];
		$url = 'addressbooks/users/' . $username . '/addressbook'; //$requestParams['url'];
		
		if($secure_connection)
			$url_protocol = 'https';
		else
			$url_protocol = 'http';	

		//first check that not already existing
		$AbookServersObject = new Atmail_Abook_Servers( array('Account' => $this->userData['Account']) );
		
		$existingServers = $AbookServersObject->GetServers();
		
		foreach( $existingServers as $existingServer )
		{
			
			if( $existingServer['server'] == $server && $existingServer['username'] == $username && $existingServer['password'] == $password )
			{
				
				jQuery::addError( $this->view->translate('Duplicate server details already found.') );
				jQuery('#abook #server')->focus();
				$this->render('global/jsonresponse', null, true);
				return;
			}
			
		}
		
		$server_id = $AbookServersObject->AddServer('carddav', $url_protocol, $server, $port, $username, $password, $url);

		if($server_id == FALSE)
		{
			jQuery::addError( $this->view->translate('The details provided are incorrect or the server is unsupported. Please review and try again.') );
			//focus on first field
			jQuery('#abook #server')->focus();
		}
		else
		{
			jQuery::addMessage( $this->view->translate('New CardDAV account created. Click the Contacts tab to navigate.') );
			jQuery::evalScript("$('#total_servers', '#abook').attr('value', $('#total_servers', '#abook').attr('value')+1); $('#noservers', '#abook').hide();");
			jQuery::evalScript("$('#serverList tbody', '#abook').append('<tr class=\"divide\"><td class=\"td1\">" . $server . "</td><td class=\"td2\">" . $port . "</td><td class=\"td3\">" . $username . "</td><td class=\"td4\">" . $url . "</td><td class=\"td5\"><a class=\"serverDelete\" href=\"#\">" . $this->view->translate('Delete') . "</a></td><input type=\"hidden\" id=\"serverID\" value=\"" . $server_id . "\" /></tr>');");
			jQuery::evalScript("perform_abook_settings_binds();");
			jQuery('#abook #server')->attr('value','');
			jQuery('#abook #username')->attr('value','');
			jQuery('#abook #password')->attr('value','');
			jQuery::evalScript("$.php('" . $this->view->moduleBaseUrl . "/contacts/pushrefreshcontactsserverslist')");
		}
		
		$this->render('global/jsonresponse', null, true);
		
	}

//AddServer
	
	/**
	 * @return success data so ui can render appropriate response {'success':'1/0', 'message':''}
	 */
	public function filtersdeleteAction()
	{
		
		$this->_helper->viewRenderer->setNoRender();
		$requestParams = $this->getRequest()->getParams();
		
		$filtersId = $requestParams['filtersId'];
		
		//get exisiting filter data
		require_once 'application/models/sieveFile.php';
		$existingFilters = sieveFile::getFilters( $this->userData['Account'] );
		
		foreach( $filtersId as $filterId )
		{
			
			//drop specified nodes in filters
			unset($existingFilters[$filterId]);
			
		}
		
		//reset keys
		$existingFilters = array_merge( $existingFilters );
		
		$result = sieveFile::setFilters( $this->userData['Account'], $existingFilters );
		if( $result === false )
		{
			
			$response = array('success' => '0', 'msg' => 'Failed deleting filter.');
			
		}
		else
		{
			
			$response = array('success' => '1');
			
		}
		echo Zend_Json::encode( $response );

	}
	
	public function filterslistAction() 
	{
		
		$this->_mailStoreConfig = array_merge($this->_globalConfig, $this->userData, $this->_currentConfig, $this->view->UserSettings);
		$this->AtmailMailStorage = Atmail_Mail_Storage::getInstance($this->_mailStoreConfig);
		$this->AtmailMailStorageMain = &$this->AtmailMailStorage->getMailStore($this->_mailStoreConfig['namespaceName']);
		$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] = $value;
	       			}
			}
    		}
       
        	$this->view->folders = $flat;
		natcasesort($this->view->folders);
		
		require_once 'application/models/sieveFile.php';
		$this->view->filters = sieveFile::getFilters( $this->userData['Account'] );
		
	}   

	public function iosAction()
	{
		
	}
	
	public function iosprofileAction()
	{		
		$this->_helper->viewRenderer->setNoRender();
		
		if (isset($this->_globalConfig['iosProfiles']) && $this->_globalConfig['iosProfiles'] == '1')
		{
			require_once 'library/Atmail/iOS/XmlProfile.php';
			$profile = new iOS_XML_Profile();

			$this->iosProfileArgs = array();
			$this->_helper->pluginCall('preIosProfileGenerate');
			header('Content-type: application/x-apple-aspen-config; chatset=utf-8');
			header('Content-Disposition: attachment; filename="atmail.mobileconfig"');
			echo $profile->generate($this->iosProfileArgs);
		}
		else 
		{
			echo "Sorry. Cannot download IOS profile, because this feature is turned off. Please contact admin.";
		}
	}

	public function iosstartAction()
	{
	
	}
	
	public function iosdoneAction()
	{

	}
}
