/*+++
 *  title:      MailProxy.m
 *  abstract:   Implementation of MailProxy class for mailapp-utilities.
 *  author:     Tom Hageman <tom@basil.icce.rug.nl>
 *  created:    February 1998
 *  modified:   (see RCS Log at end)
 *  copyleft:
 *
 *	Copyright (C) 1998  Tom R. Hageman, but otherwise perfect freeware.
 *
 *  description:
 *      (see corresponding *.h file)
 *---*/

static const char * const RCSid = ((void)&RCSid,
	"@(#)MailProxy.m,v 1.2 1998/02/15 17:03:17");
#define RCS_MailProxy_ID

#import "compat.h"
#import "mailutil.h"
#import <stdlib.h>
#import <mach/mach.h>

#define _MailProxy_common_ivars \
   char *hostname; \
   char *mailer; \
   BOOL isConnected;

#define _RELEASE_COMMON_IVARS \
   free(hostname); \
   free(mailer);

#if RHAPSODY

#  import <Message/NSMailDelivery.h>

#  define _MailProxy_ivars \
   _MailProxy_common_ivars

#  define _RELEASE_IVARS \
   _RELEASE_COMMON_IVARS

#else // NEXTSTEP || OPENSTEP

#  import "MailSpeaker.h"

#  define _MailProxy_ivars \
   _MailProxy_common_ivars \
   MailSpeaker *mailSpeaker;

#  if NEXTSTEP
#     define _RELEASE_IVARS \
   _RELEASE_COMMON_IVARS \
   [mailSpeaker free];
#  else // OPENSTEP
#     define _RELEASE_IVARS \
   _RELEASE_COMMON_IVARS \
   [mailSpeaker release];
#  endif

#endif

#import "MailProxy.h"


@implementation MailProxy

// Implementation feature tests.
+ (BOOL)canEditMessage
{
#if RHAPSODY
   return NO;
#else
   return YES;
#endif
}

+ (BOOL)canIncorporateNewMail
{
#if RHAPSODY
   return NO;
#else
   return YES;
#endif
}


- initWithMailer:(const char *)aMailer
   host:(const char *)aHostName
   forceLaunch:(BOOL)forceLaunch
{
   if ((self = [super init]))
   {
      if (aHostName == NULL) aHostName = "";
      hostname = strcpy(malloc(strlen(aHostName)+1), aHostName);
      // XXX find name of local host?

      if (!aMailer) aMailer = "";

#if RHAPSODY
      /* Message framework currently (DR1) only seems to support connection
         to MAIL_APP, on local host. */
      if (strcmp(hostname, "") != 0)
      {
	 [self release];
	 return nil;
      }
      aMailer = MAIL_APP;
      // Check if mailer is running.
      isConnected = ([[NSPortNameServer defaultPortNameServer]
		      portForName:[NSString stringWithCString:aMailer]] != nil);
#else
      mailSpeaker = [[MailSpeaker alloc] init];
      {
	 port_t mailPort = NXPortNameLookup(MAILSEND_PORTNAME, hostname);

	 if (mailPort == PORT_NULL && forceLaunch)
	 {
	    if ((mailPort = NXPortFromName(aMailer, hostname)) == PORT_NULL)
	    {
	       if (!*aMailer) aMailer = NXGetDefaultValue("GLOBAL", "Mailer");
	       if (!aMailer || !*aMailer) aMailer = MAIL_APP;
	       mailPort = NXPortFromName(aMailer, hostname);
	       if (mailPort == PORT_NULL)
	       {
		  aMailer = MAIL_APP;
		  mailPort = NXPortFromName(aMailer, hostname);
	       }
	       if (mailPort != PORT_NULL) port_deallocate(task_self(), mailPort);
	    }
	    mailPort = NXPortNameLookup(MAILSEND_PORTNAME, hostname);
	 }
	 if (mailPort != PORT_NULL)
	 {
	    [mailSpeaker setSendPort:mailPort];
	    isConnected = YES;
	 }
      }
#endif
      mailer = strcpy(malloc(strlen(aMailer)+1), aMailer);
   }
   return self;
}

#if NEXTSTEP
- free
{
   _RELEASE_IVARS
   return [super free];
}

- (void)release { [self free]; }
#else
- (void)dealloc
{
    _RELEASE_IVARS
    [super dealloc];
}
#endif


// Access methods.

- (const char *)hostname   { return hostname; }
- (const char *)mailer	   { return mailer; }
- (BOOL)isConnected	   { return isConnected; }

// Other methods.

- (BOOL)sendMailTo:(const char *)to
   subject:(const char *)subject
   body:(const char *)body
   cc:(const char *)cc 
   deliver:(BOOL)deliver
{
#if RHAPSODY
   NSMutableDictionary *headers = [NSMutableDictionary dictionary];
   NSAttributedString *messageBody = nil;

   if (!deliver) return NO;

   if (to)      [headers setObject:[NSString stringWithCString:to]      forKey:@"To"];
   if (subject)	[headers setObject:[NSString stringWithCString:subject] forKey:@"Subject"];
   if (cc)	[headers setObject:[NSString stringWithCString:cc]      forKey:@"Cc"];
   if (body)
   {
      messageBody = [[[NSAttributedString alloc]
		      initWithString:[NSString stringWithCString:body]] autorelease];
   }
   return [NSMailDelivery deliverMessage:messageBody headers:headers
	   format:NSASCIIMailFormat protocol:nil];
#else
   int status = 0;
   int window;

   if ([mailSpeaker openSend:&window] != 0) return NO;

   if (to)	status |= [mailSpeaker setTo:(char *)to		  inWindow:window];
   if (subject)	status |= [mailSpeaker setSubject:(char *)subject inWindow:window];
   if (cc)	status |= [mailSpeaker setCc:(char *)cc		  inWindow:window];
   if (body)	status |= [mailSpeaker setBody:(char *)body	  inWindow:window];

   if (deliver)
   {
      if (to && (subject || body)) status |= [mailSpeaker deliver:window];
   }
   return (status == 0);
#endif
}

- (BOOL)incorporateNewMail
{
#if RHAPSODY
   return NO;
#else
   return [mailSpeaker incorporateNewMail] == 0;
#endif
}

@end // MailProxy
