/*
	File:		CAccount.10.1.cpp

	Contains:	C++ implementation of account objects

	Copyright:	© 2003 by Apple Computer, Inc., all rights reserved.

 	NOT_FOR_OPEN_SOURCE <to be reevaluated at a later time>

	Change History:

		$Log: CAccount.10.1.cpp,v $
		Revision 1.1  2003/04/20 23:46:10  dasenbro
		Initial check-in.
		

	To Do:
*/

#include <stdlib.h>

#include "CAccount.10.1.h"
#include "CGlobals.h"

// Database
#include "Database.10.1.h"
#include "CMailSpool.10.1.h"
#include "CEnvelopeInfo.10.1.h"

// Utilities
#include "CString.h"
#include "CUtils.h"

#include "DSMgr.h"
#include "DSMailUser.h"


Boolean	CAccount_10_1::GetSetFields ( const eFieldDataRequest_10_1 inFieldRequest, const void *inObjDataPtr, void *outFieldData )
{
	Boolean			result			= false;
	CAccountData_10_1	*theData		= (CAccountData_10_1 *) inObjDataPtr;
	CAccount_10_1		*aTempObject	= NULL;
	char			*theDestString	= (char *) outFieldData;
	ObjID			*anObjIDPtr		= (ObjID *) outFieldData;
	char			numStr[256];

	switch ( inFieldRequest )
	{
		case kSetObjID:
			if(theData != NULL)
			{
				theData->fAccountID = *anObjIDPtr;
			}
			break;

		case kStringNameRequest:
			if ( theData->fReturnNameOk == kOkToReturnName_10_1 )
			{
				::sprintf( (char *)numStr, "%ld", theData->fMailUserID );
				if ( ::strlen( numStr ) != 0 )
				{
					CUtils::Strncpy( theDestString, numStr, kStr2IDMaxStringSize );
					result = true;
				}
			}
			break;

		case kObjectPINGRequest:
			// cause the objects constructor to get called, so we force a check of
			// the struct alignment...
			aTempObject = new CAccount_10_1;
			delete aTempObject;
			break;
	
		case k2ndIDTargetChk:
			result = true;
			break;

		default:
			result = false;
			break;
	}

	return result;
} // GetSetFields


//--------------------------------------------------------------------------------------------------
// * Find ()
//
//--------------------------------------------------------------------------------------------------

CAccount_10_1* CAccount_10_1::Find ( DSMailUser *inMailUser, CreateOnDemand inCreate )
{
	ObjID			anAcctID = 0;
	CAccount_10_1		*acctObj = NULL;
	OSErr			result = kNoErr;
	char			aString[ kCNameLen ];

	if (inMailUser == NULL)
	{
		return NULL;
	}

	try
	{
		// Change the user account ID to a string
		::sprintf( aString, "%lu", inMailUser->GetUserID() );

		result = gDB_10_1->GetObjDataByString( kAccountSignature, (char *)aString, anAcctID );
		if ( anAcctID != 0 )		// there is already an account for this user ID
		{
			acctObj = CAccount_10_1::FindByID( anAcctID );
			if ( acctObj != NULL )
			{
				acctObj->SetAccountName( inMailUser->GetUserName() );
				return( acctObj );
			}
		}
		
		// It't doesn't exist
		if ( (acctObj == nil) && (inCreate == kCreate) )
		{
			// We need to create the account we are looking for
			acctObj = CAccount_10_1::Create( inMailUser );
		}
	}

	catch ( ExceptionCode err )
	{
		if ( acctObj != NULL )
		{
			acctObj->Done( acctObj );
		}
		return NULL;
	}
	
	return( acctObj );

} // Find


//--------------------------------------------------------------------------------------------------
// * ObjectAllocNew ()
//
//--------------------------------------------------------------------------------------------------

CDBBaseObject_10_1 * CAccount_10_1::ObjectAllocNew ( void )
{
	return( new CAccount_10_1 );
} // ObjectAllocNew


//--------------------------------------------------------------------------------------------------
// * FindByID ()
//
//--------------------------------------------------------------------------------------------------

CAccount_10_1* CAccount_10_1::FindByID ( const ObjID inObjectID )
{
	return (CAccount_10_1 *) CDBMailBaseObject_10_1::MailUniversalFindByID(	inObjectID,
														CAccount_10_1::GetObjTypeConstant(),
														CAccount_10_1::GetObjVersConstant(),
														CAccount_10_1::GetObjSizeConstant(),
														CAccount_10_1::ObjectAllocNew );
} // FindByID


ObjID CAccount_10_1::GetObjectID	( void )
{
	return( this->GetAccountID() );
}

//--------------------------------------------------------------------------------------------------
//	* Done ()
//
//--------------------------------------------------------------------------------------------------

void CAccount_10_1::Done ( CAccount_10_1* &inPtr )
{
	CDBBaseObject *aDBObject = (CDBBaseObject *) inPtr;
	aDBObject->Done(aDBObject);

	inPtr = (CAccount_10_1 *)aDBObject;
} // Done


//--------------------------------------------------------------------------------------------------
//	* Create ()
//
//--------------------------------------------------------------------------------------------------

CAccount_10_1* CAccount_10_1::Create ( DSMailUser* inMailUser )
{
	CAccount_10_1		*theAccount = NULL;
	OSStatus		result		= kNoErr;
	ObjID			aNewID		= 0;
	ObjID			aJunkID		= 0;

	if (inMailUser == NULL)
	{
		return NULL;
	}


	try
	{
		theAccount = new CAccount_10_1;

		(gDB_10_1->GetBaseObjectCachePtr())->LockTheCache( CAccount_10_1::GetObjTypeConstant() );

		result = gDB_10_1->CreateObj( CAccount_10_1::GetObjTypeConstant(), aNewID, theAccount->GetObjectData() );

		if ( result == CMailDatabase::kDBNoErr )
		{
			theAccount->Use();

			if ( theAccount->GetObjectLock(true) == kNoErr )
			{
				// Set the account name and internet alias when we create the account
				theAccount->SetMailUserID( inMailUser->GetUserID() );
				theAccount->SetAccountName( inMailUser->GetUserName() );
//				theAccount->SetDirectoryPath( inMailUser->GetDirectoryPath() );

				// Mark the account as active
				theAccount->SetAccountState( kActive_10_1 );
				aJunkID = theAccount->GetIMAP4InboxID();

				theAccount->SetDirty();

				theAccount->ReleaseObjectLock( true );
				theAccount->Done(theAccount);

				theAccount = CAccount_10_1::FindByID( aNewID );
			}
			else
			{
				delete theAccount;
				theAccount = NULL;
			}
		}
		else
		{
			delete theAccount;
			theAccount = NULL;
		}

		// Just in case a disk full error deleted the account
		if ( theAccount != NULL )
		{
			// Display in the Log
		}

		(gDB_10_1->GetBaseObjectCachePtr())->UnLockTheCache(CAccount_10_1::GetObjTypeConstant());
	}
	catch ( ExceptionCode err )
	{
	}

	return( theAccount );
} // Create



void CAccount_10_1::SetDirty	( void )
{
	if ((this != NULL) && (this->GetAccountID() != 0))
	{
		this->setDirty();	// call the base class method
	}
}



//--------------------------------------------------------------------------------------------------
//	* Delete - [ static ]
//
//--------------------------------------------------------------------------------------------------

Boolean CAccount_10_1::Delete ( CAccount_10_1* inAcctObj )
{
	OSStatus			result;
	ObjID				objID		= 0;
	Boolean				deleted		= false;
	CMailSpool_10_1    *mailSpool	= nil;
	SDBIterator_10_1	iterator(gDB_10_1);

	try
	{
		(gDB_10_1->GetBaseObjectCachePtr())->LockTheCache(CAccount_10_1::GetObjTypeConstant());

		if ( inAcctObj->GetObjectLock( true ) == kNoErr )
		{
			result = gDB_10_1->CreateIterator( kMailSpoolSignature, &iterator, inAcctObj->GetAccountID() );
			if ( result == kNoErr )
			{
				while ( gDB_10_1->GetCurObject( &iterator, objID ) == kNoErr )
				{
					mailSpool = CMailSpool_10_1::FindByID( objID );
					if ( mailSpool != nil )
					{
						CMailSpool_10_1::Delete( mailSpool );
						mailSpool->Done( mailSpool );
						mailSpool = nil;
					}
				}
			}

			inAcctObj->ReleaseObjectLock(true);
			gDB_10_1->ReleaseIterator( &iterator );
		}

		result = gDB_10_1->RemoveObj( kAccountSignature, inAcctObj->GetAccountID() );
		deleted = (result == kNoErr);
		if ( deleted == true )
		{
			inAcctObj->fAccountData.fAccountID = 0;
		}

		(gDB_10_1->GetBaseObjectCachePtr())->UnLockTheCache(CAccount_10_1::GetObjTypeConstant());
	}
	catch ( ExceptionCode err )
	{
		if (mailSpool != NULL)
		{
			mailSpool->Done( mailSpool );
		}
		gDB_10_1->ReleaseIterator( &iterator );

		(gDB_10_1->GetBaseObjectCachePtr())->UnLockTheCache(CAccount_10_1::GetObjTypeConstant());
	}

	return ( deleted );

} // Delete



//--------------------------------------------------------------------------------------------------
//	* Count - [ static ]
//
//--------------------------------------------------------------------------------------------------

uInt32 CAccount_10_1::Count ( void )
{
	uInt32	aCount = 0;
	OSErr	result;

	result = gDB_10_1->GetObjectCount( kAccountSignature, aCount );

	if (result != kNoErr)
	{
		aCount = 0;
	}

	return aCount;
} // Count


#pragma mark -

CAccount_10_1::CAccount_10_1(void) :
	CDBMailBaseObject_10_1(	&fAccountData.fDBHeader,
				&fAccountData.fDBFooter,
				&fAccountData,
				CAccount_10_1::GetObjTypeConstant(),
				CAccount_10_1::GetObjVersConstant(),
				CAccount_10_1::GetObjSizeConstant() )
{
	fPOPContext							= NULL;

	fAccountData.fAccountID				= 0;
	fAccountData.fPOP3InboxID			= 0;
	fAccountData.fIMAP4InboxID			= 0;
	fAccountData.fMailUserID			= 0;
	fAccountData.fAccountState			= kUnknown_10_1;
	fAccountData.fNotify				= 0;
	fAccountData.fNotifyIPAddress		= 0;
	fAccountData.fNotifyIPAddrCache		= 0;
	fAccountData.fNotifyFailures		= 0;
	fAccountData.fReturnNameOk			= 0;
	fAccountData.fACLFolderSynch		= 0;

	fAccountData.fReserved2				= kReservedConst;

	::memset( &fAccountData.fAcctNameObj,   0, sizeof( TextStrObj ) );	// CName from DSMailUser
	::memset( &fAccountData.fDirPathObj,   0, sizeof( TextStrObj ) );	// Account Location

	fAcctNameStr	= nil;
	fDirPathStr		= nil;
}

CAccount_10_1::~CAccount_10_1()
{
	if ( fAcctNameStr != nil )
	{
		free( fAcctNameStr );
		fAcctNameStr = nil;
	}

	if ( fDirPathStr != nil )
	{
		free( fDirPathStr );
		fDirPathStr = nil;
	}
}

void	CAccount_10_1::ChkCompilerStructAlignment	( void )
{
	/*
		this dump was aquired by using the MPW command DumpSYM - TTE from the .xsym file produced
		from a Code Warrior Pro 1 Release Build of the AppleShare IP Mail Server for MacOS version 6.2
		
		this version of the structure is consider the "reference" standard for all future ASIP Mail Servers.
		If the structure does NOT match these offsets the version of the Mail Server that 
		you are compiling will _NOT_ be compatible with AppleShare IP 6.0, 6.1, or 6.2 (this also effects
		the AppleShare IP Mail Tool, and to a more limited extent the AppleShare IP Mail Admin since some
		of these structures are passed across the wire..)
		
		If _ANY_ of these Asserts "fire" you've got a backwards compatibility problem that _MUST_ be fixed!!
		
		this code wasn't put here for my personal amusement, this code was put here from a hard earned lesson
		that simple changes to headers/compilers _WILL_ break this stuff, better to know now than after we
		ship.  Look upon this code as a debugging AIDE, not an impediment.
		
		Type Name:  CAccountData_10_1		TINFO offset: 51646		(TINFO SYM file offset (hex): $1249BE)
			offset 0 NamedTypeOf fDBHeader TypeDef of "Type ID 248"
			offset 12 NamedTypeOf fAccountID unsigned long
			offset 16 NamedTypeOf fPOP3InboxID unsigned long
			offset 20 NamedTypeOf fIMAP4InboxID unsigned long
			offset 24 NamedTypeOf fASDUserID unsigned long
			offset 28 NamedTypeOf fReserved1 unsigned long
			offset 32 NamedTypeOf fReserved2 unsigned long
			offset 36 NamedTypeOf fAccountName CString
			offset 68 NamedTypeOf fInternetAlias TypeDef of "Type ID 326"
			offset 100 NamedTypeOf fAccountState TypeDef of "Type ID 327"
			offset 102 NamedTypeOf fFingerprint TypeDef of "Type ID 262"
			offset 118 NamedTypeOf fNotify unsigned byte
			offset 120 NamedTypeOf fNotifyIPAddress unsigned long
			offset 124 NamedTypeOf fNotifyIPAddrCache unsigned long
			offset 128 NamedTypeOf fNotifyFailures unsigned long
			offset 132 NamedTypeOf fDBFooter TypeDef of "Type ID 250"
	*/
	
	static Boolean	aRunOnceFlag = false;	
	if (aRunOnceFlag == false)
	{
		//FileFormatSaftyChk(CAccountData_10_1, fDBHeader,				0);
		//FileFormatSaftyChk(CAccountData_10_1, fAccountID,			12);
		//FileFormatSaftyChk(CAccountData_10_1, fPOP3InboxID,	 		16);
		//FileFormatSaftyChk(CAccountData_10_1, fIMAP4InboxID,	 		20);
		//FileFormatSaftyChk(CAccountData_10_1, fASDUserID,	 		24);
		//FileFormatSaftyChk(CAccountData_10_1, fReserved1,	 			28);
		//FileFormatSaftyChk(CAccountData_10_1, fReserved2,	 			32);
		//FileFormatSaftyChk(CAccountData_10_1, fAccountName,	 		36);
		//FileFormatSaftyChk(CAccountData_10_1, fInternetAlias,	 	68);
		//FileFormatSaftyChk(CAccountData_10_1, fAccountState,	 		100);
		//FileFormatSaftyChk(CAccountData_10_1, fFingerprint,	 		102);
		//FileFormatSaftyChk(CAccountData_10_1, fNotify,	 			118);
		//FileFormatSaftyChk(CAccountData_10_1, fNotifyIPAddress,		120);
		//FileFormatSaftyChk(CAccountData_10_1, fNotifyIPAddrCache,	124);
		//FileFormatSaftyChk(CAccountData_10_1, fNotifyFailures,		128);
		//FileFormatSaftyChk(CAccountData_10_1, fDBFooter,				132);
//		this->ReportBackwardCompatibility(sizeof(CAccountData_10_1),	136,	"CAccountData_10_1", "SIZEOF()");
//		this->ReportBackwardCompatibility(kAccountDataSize,		136,	"CAccountData_10_1", "kAccountDataSize");
	}
	
	aRunOnceFlag = true;
}


#pragma mark -

ObjID CAccount_10_1::GetAccountID ( void )
{
	return( fAccountData.fAccountID );
}

ObjID CAccount_10_1::GetPOP3InboxIDOnly ( void )
{
	return( fAccountData.fPOP3InboxID );
}

ObjID CAccount_10_1::GetIMAP4InboxIDOnly ( void )
{
	return( fAccountData.fIMAP4InboxID );
}

ObjID CAccount_10_1::GetPOP3InboxID ( CreateOnDemand inCreate )
{
	Boolean				found			= false;
	OSErr				result			= kNoErr;
	ObjID				spoolID			= 0;
	CMailSpool_10_1	   *spoolObj		= nil;
	SDBIterator_10_1	iterator(gDB_10_1);

	try
	{
		// Make sure the spool exists if we say it does
		if ( fAccountData.fPOP3InboxID != 0 )
		{
			spoolObj = CMailSpool_10_1::FindByID( fAccountData.fPOP3InboxID );
			if ( spoolObj == nil )
			{
				// Bad object ID
				this->SetPOP3InboxID (0);
			}
			else
			{
				spoolObj->Done( spoolObj );
			}
		}

		// Look for our POP3 inbox that may have been created, but never linked
		if ( fAccountData.fPOP3InboxID == 0 )
		{
			result = gDB_10_1->CreateIterator( kMailSpoolSignature, &iterator, this->GetAccountID() );
			if ( result == kNoErr )
			{
				while ( !found && (gDB_10_1->NextObject( &iterator, spoolID ) == kNoErr) )
				{
					spoolObj = CMailSpool_10_1::FindByID( spoolID );
					if ( spoolObj != nil )
					{
						if ( (CUtils::Stricmp( spoolObj->GetMailSpoolName(), "POP3 INBOX" ) == 0) &&
							 (spoolObj->GetParentID() == CMailSpool_10_1::kRootParent) )
						{
							// Found it.  Now set it and git...
							this->SetPOP3InboxID( spoolObj->GetMailSpoolID() );
							found = true;
						}

						spoolObj->Done( spoolObj );
					}
				}
			}
			gDB_10_1->ReleaseIterator( &iterator );
		}


		while ( fAccountData.fPOP3InboxID == 0 )// POP3 inbox mail spool does not exist yet
		{
			if (inCreate == kCreate)
			{
				if (this->GetObjectLock(true) == kNoErr)
				{
					if ( fAccountData.fPOP3InboxID == 0 )
					{
						// Create a MailSpool first
						spoolObj = CMailSpool_10_1::Create( CMailSpool_10_1::kPOP3Spool, "POP3 INBOX", this->GetAccountID() );
						if (spoolObj != NULL)
						{
							// Save the MailSpoolID
							this->SetPOP3InboxID( spoolObj->GetMailSpoolID() );

							// Save the AccountID in the MailSpool
							spoolObj->SetAccountID( this->GetAccountID() );
							spoolObj->Done( spoolObj );
						}
					}

					this->ReleaseObjectLock(true);
				}
			}
			else
			{
				break;
			}
		}

		return( fAccountData.fPOP3InboxID );
	}

	catch ( ExceptionCode err )
	{
		spoolObj->Done( spoolObj );

		return 0;
	}
}

void CAccount_10_1::SetPOP3InboxID (ObjID inMailSpoolID)
{
	if (fAccountData.fPOP3InboxID != inMailSpoolID)
	{
		fAccountData.fPOP3InboxID = inMailSpoolID;
		this->SetDirty();
	}
}


ObjID CAccount_10_1::GetIMAP4InboxID ( CreateOnDemand inCreate )
{
	Boolean				found			= false;
	OSErr				result			= kNoErr;
	ObjID				spoolID			= 0;
	CMailSpool_10_1	   *spoolObj		= nil;
	SDBIterator_10_1	iterator(gDB_10_1);

	try
	{
		// Make sure the spool exists if we say it does
		if ( fAccountData.fIMAP4InboxID != 0 )
		{
			spoolObj = CMailSpool_10_1::FindByID( fAccountData.fIMAP4InboxID );
			if ( spoolObj == nil )
			{
				// Bad object ID
				this->SetIMAP4InboxID(0);
				this->SetDirty();
			}
			else
			{
				spoolObj->Done( spoolObj );
			}
		}

		// Look for our INBOX that may have been created, but never linked
		if ( fAccountData.fIMAP4InboxID == 0 )
		{
			result = gDB_10_1->CreateIterator( kMailSpoolSignature, &iterator, this->GetAccountID() );
			if ( result == kNoErr )
			{
				while ( !found && (gDB_10_1->NextObject( &iterator, spoolID ) == kNoErr) )
				{
					spoolObj = CMailSpool_10_1::FindByID( spoolID );
					if ( spoolObj != nil )
					{
						if ( (CUtils::Stricmp( spoolObj->GetMailSpoolName(), "INBOX" ) == 0) &&
							 (spoolObj->GetParentID() == CMailSpool_10_1::kRootParent) )
						{
							// Found it.  Now set it and git...
							this->SetIMAP4InboxID( spoolObj->GetMailSpoolID() );
							found = true;
						}

						spoolObj->Done( spoolObj );
					}
				}
			}
			gDB_10_1->ReleaseIterator( &iterator );
		}


		while ( fAccountData.fIMAP4InboxID == 0 )	// IMAP4 inbox mail spool does not exist yet
		{
			if (inCreate == kCreate)
			{
				if (this->GetObjectLock(true) == kNoErr)
				{
					if (fAccountData.fIMAP4InboxID == 0)
					{
						// Create a MailSpool first
						spoolObj = CMailSpool_10_1::Create( CMailSpool_10_1::kIMAP4InBoxSpool,
															"INBOX",
															this->GetAccountID(), CMailSpool_10_1::kRootParent );
						if (spoolObj != NULL)
						{
							// Save the MailSpoolID
							this->SetIMAP4InboxID( spoolObj->GetMailSpoolID() );

							// Save the AccountID in the MailSpool
							spoolObj->SetAccountID(this->GetAccountID());
							spoolObj->Done (spoolObj);
						}
					}

					this->ReleaseObjectLock(true);
				}
			}
			else
			{
				break;
			}
		}

		return (fAccountData.fIMAP4InboxID);
	}

	catch ( ExceptionCode err )
	{
		spoolObj->Done( spoolObj );

		return( 0 );
	}
}

void CAccount_10_1::SetIMAP4InboxID (ObjID inMailSpoolID)
{
	if (fAccountData.fIMAP4InboxID != inMailSpoolID)
	{
		fAccountData.fIMAP4InboxID = inMailSpoolID;
		this->SetDirty();
	}
}

#pragma mark -

const char* CAccount_10_1::GetAccountName (void)
{
	sInt32		siResult	= kNoErr;

	if ( fAcctNameStr == nil )
	{
		siResult = CTextObjMgr::GetString( &fAccountData.fAcctNameObj, &fAcctNameStr );
	}

	return( fAcctNameStr );
//	return (fAccountData.fAccountName);
}

void CAccount_10_1::SetAccountName ( const char* inAccountName )
{
	sInt32		siResult	= kNoErr;

	this->GetAccountName();

	if ( (fAcctNameStr == nil) || (::strcmp( fAcctNameStr, inAccountName ) != 0) )
	{
		if ( fAcctNameStr != nil )
		{
			siResult = CTextObjMgr::RemoveString( &fAccountData.fAcctNameObj );

			free( fAcctNameStr );
			fAcctNameStr = nil;
		}

		siResult = CTextObjMgr::AddString( inAccountName, &fAccountData.fAcctNameObj );

		siResult = CTextObjMgr::GetString( &fAccountData.fAcctNameObj, &fAcctNameStr );

		this->SetDirty();
	}
}

void CAccount_10_1::SetAccountState( eAccountState_10_1 inAccountState )
{
	if ( fAccountData.fAccountState != inAccountState )
	{
		fAccountData.fAccountState = inAccountState;
		this->SetDirty();
	}
}

eAccountState_10_1 CAccount_10_1::GetAccountState( void )
{
	return( fAccountData.fAccountState );
}

void CAccount_10_1::SetMailUserID ( const ObjID inMailUserID )
{
	if ( (fAccountData.fMailUserID != inMailUserID) || (fAccountData.fReturnNameOk != kOkToReturnName_10_1) )
	{
		fAccountData.fMailUserID = inMailUserID;
		this->SetReturnNameOk( kOkToReturnName_10_1 );
		
		this->SetDirty();
	}
}

ObjID CAccount_10_1::GetMailUserID ( void )
{
	return( fAccountData.fMailUserID );
}


//--------------------------------------------------------------------------------------------------
//	* GetACLFolderSynchStamp ()
//
//--------------------------------------------------------------------------------------------------

uInt32 CAccount_10_1::GetACLFolderSynchStamp ( void )
{
	return( fAccountData.fACLFolderSynch );
} // GetACLFolderSynchStamp


//--------------------------------------------------------------------------------------------------
//	* SetACLFolderSynchStamp ()
//
//--------------------------------------------------------------------------------------------------

void CAccount_10_1::SetACLFolderSynchStamp ( const uInt32 inTimeStamp )
{
	if ( fAccountData.fACLFolderSynch != inTimeStamp )
	{
		fAccountData.fACLFolderSynch = inTimeStamp;
		this->SetDirty();
	}
} // SetACLFolderSynchStamp


const char * CAccount_10_1::GetDirectoryPath ( void )
{
	sInt32		siResult	= kNoErr;

	if ( fDirPathStr == nil )
	{
		siResult = CTextObjMgr::GetString( &fAccountData.fDirPathObj, &fDirPathStr );
	}

	return( fDirPathStr );
//	return fAccountData.fDirPath;

} // GetDirectoryPath


void CAccount_10_1::SetDirectoryPath ( const char *inDirPath )
{
	sInt32		siResult	= kNoErr;

	if ( (fDirPathStr == nil) || (::strcmp( fDirPathStr, inDirPath ) != 0) )
	{
		if ( fDirPathStr != nil )
		{
			siResult = CTextObjMgr::RemoveString( &fAccountData.fDirPathObj );

			free( fDirPathStr );
			fDirPathStr = nil;
		}

		siResult = CTextObjMgr::AddString( inDirPath, &fAccountData.fDirPathObj );

		siResult = CTextObjMgr::GetString( &fAccountData.fDirPathObj, &fDirPathStr );

		this->SetDirty();
	}
} // SetDirectoryPath


Boolean CAccount_10_1::Validate ( DSMailUser* inMailUser )
{
#pragma unused (inMailUser)

	return true;
} // Validate

#pragma mark -

//--------------------------------------------------------------------------------------------------
//	* GetNotifyIPAddress
//
//--------------------------------------------------------------------------------------------------

uInt32 CAccount_10_1::GetNotifyIPAddress ( void )
{
	return fAccountData.fNotifyIPAddress;
} // GetNotifyIPAddress



//--------------------------------------------------------------------------------------------------
//	* SetNotifyIPAddress
//
//--------------------------------------------------------------------------------------------------

void CAccount_10_1::SetNotifyIPAddress ( uInt32 inNotifyAddress )
{
	if ( fAccountData.fNotifyIPAddress != inNotifyAddress )
	{
		fAccountData.fNotifyIPAddress = inNotifyAddress;
		this->SetDirty();
	}
} // SetNotifyIPAddress



//--------------------------------------------------------------------------------------------------
//	* SetNotifyUserOn ()
//
//--------------------------------------------------------------------------------------------------

void CAccount_10_1::SetNotifyUserOn ( void )
{
	if ( (fAccountData.fNotify & kNotifyUser_10_1) == 0 )
	{
		fAccountData.fNotify |= kNotifyUser_10_1;
		this->SetDirty();
	}
} // SetNotifyUserOn


//--------------------------------------------------------------------------------------------------
//	* SetNotifyUserOff ()
//
//--------------------------------------------------------------------------------------------------

void CAccount_10_1::SetNotifyUserOff ( void )
{
	if ( (fAccountData.fNotify & kNotifyUser_10_1) != 0 )
	{
		fAccountData.fNotify &= ~kNotifyUser_10_1;
		this->SetDirty();
	}
} // SetNotifyUserOff


//--------------------------------------------------------------------------------------------------
//	* SetNotifyOn ()
//
//--------------------------------------------------------------------------------------------------

void CAccount_10_1::SetNotifyOn ( void )
{
	if ( (fAccountData.fNotify & kNotifyOn_10_1) == 0 )
	{
		fAccountData.fNotify |= kNotifyOn_10_1;
		this->SetDirty();
	}
} // SetNotifyOn


//--------------------------------------------------------------------------------------------------
//	* SetNotifyOff ()
//
//--------------------------------------------------------------------------------------------------

void CAccount_10_1::SetNotifyOff ( void )
{
	if ( (fAccountData.fNotify & kNotifyOn_10_1) != 0 )
	{
		fAccountData.fNotify &= ~kNotifyOn_10_1;
		this->SetDirty();
	}
} // SetNotifyOff


//--------------------------------------------------------------------------------------------------
//	* SetUseLastIPAddrOn ()
//
//--------------------------------------------------------------------------------------------------

void CAccount_10_1::SetUseLastIPAddrOn ( void )
{
	if ( (fAccountData.fNotify & kUseLastIP_10_1) == 0 )
	{
		fAccountData.fNotify |= kUseLastIP_10_1;
		this->SetDirty();
	}
} // SetUseLastIPAddrOn


//--------------------------------------------------------------------------------------------------
//	* SetUseLastIPAddrOff ()
//
//--------------------------------------------------------------------------------------------------

void CAccount_10_1::SetUseLastIPAddrOff ( void )
{
	if ( (fAccountData.fNotify & kUseLastIP_10_1) != 0 )
	{
		fAccountData.fNotify &= ~kUseLastIP_10_1;
		this->SetDirty();
	}
} // SetUseLastIPAddrOff


//--------------------------------------------------------------------------------------------------
//	* IsNotifyOn ()
//
//--------------------------------------------------------------------------------------------------

bool CAccount_10_1::IsNotifyOn ( void )
{
	bool	bResult	= false;

	if ( (fAccountData.fNotify & kNotifyOn_10_1) != 0 )
	{
		bResult = true;
	}

	return( bResult );

} // IsNotifyOn


//--------------------------------------------------------------------------------------------------
//	* UseLastIPAddress ()
//
//--------------------------------------------------------------------------------------------------

bool CAccount_10_1::UseLastIPAddress ( void )
{
	bool	bResult	= false;

	if ( (fAccountData.fNotify & kUseLastIP_10_1) != 0 )
	{
		bResult = true;
	}

	return( bResult );

} // UseLastIPAddress


//--------------------------------------------------------------------------------------------------
//	* IsNotifyPending
//
//--------------------------------------------------------------------------------------------------

Boolean CAccount_10_1::IsNotifyPending ( void )
{
	Boolean		bResult		= false;

	if ( (fAccountData.fNotify & kNotifyUser_10_1) != 0 )
	{
		bResult = true;
	}

	return( bResult );

} // IsNotifyPending


//--------------------------------------------------------------------------------------------------
//	* ResetNotifyFailures
//
//--------------------------------------------------------------------------------------------------

void CAccount_10_1::ResetNotifyFailures ( void )
{
	if ( fAccountData.fNotifyFailures != 0 )
	{
		fAccountData.fNotifyFailures = 0;
		this->SetDirty();
	}
} // ResetNotifyFailures



//--------------------------------------------------------------------------------------------------
//	* IncreaseNotifyFailures
//
//--------------------------------------------------------------------------------------------------

uInt32 CAccount_10_1::IncreaseNotifyFailures ( void )
{
	fAccountData.fNotifyFailures++;
	this->SetDirty();

	return( fAccountData.fNotifyFailures );

} // IncreaseNotifyFailures



//--------------------------------------------------------------------------------------------------
//	* GetAdminSetIPNotifyAddr ()
//
//--------------------------------------------------------------------------------------------------

uInt32 CAccount_10_1::GetAdminSetIPNotifyAddr ( void )
{
	return( fAccountData.fNotifyIPAddrCache );
} // GetAdminSetIPNotifyAddr



//--------------------------------------------------------------------------------------------------
//	* SetAdminSetIPNotifyAddr ()
//
//--------------------------------------------------------------------------------------------------

void CAccount_10_1::SetAdminSetIPNotifyAddr ( uInt32 inAdminSetIPAddr )
{
	if ( fAccountData.fNotifyIPAddrCache != inAdminSetIPAddr )
	{
		fAccountData.fNotifyIPAddrCache = inAdminSetIPAddr;
		this->SetDirty();
	}
} // SetAdminSetIPNotifyAddr




#pragma mark -


Boolean CAccount_10_1::Post ( ObjID inEnvelopeID, DSMailUser *inMailUser )
{
	Boolean			result			= false;
	eMUGError		theResult		= kMUGErrNoErr;
	CMailSpool_10_1	   *imapMailSpool	= NULL;
	CMailSpool_10_1	   *pop3MailSpool	= NULL;
	ObjID			junkIDNotUsed	= 0;
	uInt32			uiIPAddr		= 0;
	const char	   *ipAddress		= nil;

	if ( inMailUser != NULL )
	{
		if ( inMailUser->IsPOPLoginEnabled() == true )
		{
			if ( inMailUser->IsInboxShared() == false )
			{
				// GetPOP3SpoolID may create a mail spool if it does not already exist
				pop3MailSpool = CMailSpool_10_1::FindByID( this->GetPOP3InboxID() );
			}
			else
			{
				pop3MailSpool = CMailSpool_10_1::FindByID( this->GetIMAP4InboxID() );
			}

			if ( pop3MailSpool != nil )
			{
				result = pop3MailSpool->Post( inEnvelopeID, true, junkIDNotUsed );
				pop3MailSpool->Done( pop3MailSpool );
			}
		}

		if ( inMailUser->IsIMAPLoginEnabled() == true )
		{
			// GetIMAP4InboxID may create a mail spool if it does not already exist
			imapMailSpool = CMailSpool_10_1::FindByID( this->GetIMAP4InboxID() );
			if ( imapMailSpool != nil )
			{
				junkIDNotUsed	= 0;
				result = imapMailSpool->Post( inEnvelopeID, true, junkIDNotUsed );
				imapMailSpool->Done( imapMailSpool );
			}
		}

		// Mail Notification update
		if ( inMailUser->IsNotificationOn() == true )
		{
			// Get the last used IP address
			if ( inMailUser->UseLastIPAddress() == true )
			{
				SetUseLastIPAddrOn();
			}
			else
			{
				SetUseLastIPAddrOff();

				// Get the IP address from the user record in the directory
				ipAddress = inMailUser->GetNotifyIPAddress();
				if ( ipAddress != nil )
				{
//					CNetworkUtilities::StringToIPAddr( ipAddress, &uiIPAddr );
					SetAdminSetIPNotifyAddr( uiIPAddr );
				}
			}

			SetNotifyOn();
			SetNotifyUserOn();
//			CNotifyClient::WakeupNotifyClient();
		}
		else
		{
			SetNotifyUserOff();
			SetNotifyOff();
		}
	}
	else
	{
		// post to one or both inboxes ( if they exist )
		pop3MailSpool = CMailSpool_10_1::FindByID( this->GetPOP3InboxID(kDontCreate) );
		if ( pop3MailSpool != nil )
		{
			result = pop3MailSpool->Post( inEnvelopeID, true, junkIDNotUsed );
			pop3MailSpool->Done( pop3MailSpool );
		}

		imapMailSpool = CMailSpool_10_1::FindByID( this->GetIMAP4InboxID() );
		if ( imapMailSpool != nil )
		{
			result = imapMailSpool->Post( inEnvelopeID, true, junkIDNotUsed );
			imapMailSpool->Done( imapMailSpool );
		}
	}

	return ( result );
}

#pragma mark -

Boolean CAccount_10_1::GetPOPContext( DSMailUser *inDSMailUser, char* outPOPContext )
{
	return false;
}

void CAccount_10_1::ReleasePOPContext(char* inPOPContext)
{
}


//--------------------------------------------------------------------------------------------------
//	* GetReturnNameOk
//
//--------------------------------------------------------------------------------------------------

uInt32 CAccount_10_1::GetReturnNameOk ( void )
{
	return ( fAccountData.fReturnNameOk );
} // GetReturnNameOk


//--------------------------------------------------------------------------------------------------
//	* SetReturnNameOk
//
//--------------------------------------------------------------------------------------------------

void CAccount_10_1::SetReturnNameOk ( uInt32 inValue )
{
	if ( inValue != fAccountData.fReturnNameOk )
	{
		fAccountData.fReturnNameOk = inValue;
		this->SetDirty();
	}
} // SetReturnNameOk


