/*
 * send [-f file] [-s subject] [-c Cc_list] to_list
 *
 * Open a MailApp Send window with the subject:, cc:, and to: as given.
 * The body of the message is taken from 'file' or the standard input.
 * (For a null body, use: -f "").  If the body of the message contains
 *    ^Subject:...
 *    ^Cc:...
 *    ^To:...
 * these will be appended to any information gleaned from the command line.
 *
 * If you make modifications, please alert the author.
 *
 * But if you simply use this program and it improves your lot in life 
 * even a little, express your gratitude by sending a picture postcard to 
 * B.L. McLanahan at the MIT Media Laboratory.  B.L. is Marvin Minsky's
 * assistant.  Tell B.L. this so it'll know it's from one of you:
 *
 *    Yo!  B.L. --
 *
 *    You must get totally cosmo mail, working with Marv and all,
 *    but if you haven't been getting enough lately, here's one from me:
 *    I woke up this morning and -- guess what?!
 *    I heard Dick Button feeding me instructions through a FILLING
 *    in my right MOLAR!  He was shouting something about
 *    my double toe-loop being flaccid!  Is that CRAZY or what?!!
 * 
 * Michael Hawley
 * MIT Media Laboratory
 * 20 Ames Street
 * Cambridge MA, 02139
 * mike@media-lab.mit.edu
 * Copyright (c) MIT Media Laboratory, January 1992
 */
#import <stdlib.h>
#import <stdio.h>
#import <appkit/Speaker.h>
#import "argv.h"

blank(s) char *s; { /* true if 's' is blank */
    while (*s == ' ' || *s=='\t' || *s == '\n') ++s;
    return !*s;
}

stripnl(s) char *s; { /* remove trailing \n and space from 's' */
    char *p = s + strlen(s)-1;
    while (p>=s && (*p=='\n' || *p == ' ' || *p == '\r')) *p-- = '\0';
}

append(s,t) char *s, *t; {
    if (*s) strcat(s," ");
    strcat(s,t);
}

strtolower(s) char *s; {
    while (*s){
        if (isupper(*s)) *s = tolower(*s);
        s++;
    }
}

match(a,b){
    char t[1024];
    strcpy(t,a);
    strtolower(t);
    return strncmp(t,b,strlen(b))==0;
}

char *
skipsp(s) char *s; {
    while (*s==' ' || *s=='\t' || *s == '\n') ++s;
    return s;
}

void
e(a,b,c,d) char *a; { fprintf(stderr,a,b,c,d); fprintf(stderr,"\n"); }


#define M 1024
char To[M] = "",
     Cc[M] = "",
     Subject[M]="",
     *LetterFile = (char *)0,
     Letter[64000] = "";

void
readLetter(){
    FILE *f;
    char *p;
    int h = 1, headerDone=0;
    if (LetterFile && blank(LetterFile)) return;
    f = LetterFile? fopen(LetterFile,"r") : stdin;
    if (!f) return e("%s: couldn't read '%s'",av0, LetterFile);
    p = Letter;
    while (fgets(p,4096,f)){
#define add(s,p) append(s,skipsp(index(p,':')+1)), headerDone++
        if (h && *p == '\n'){
            h = 0;
            if (headerDone) continue;
        }
        if (h && match(p,"subject:")) add(Subject,p); else
        if (h && match(p,"cc:"))      add(Cc,p);      else
        if (h && match(p,"to:"))      add(To,p);      else
        p += strlen(p), headerDone;
    }
    *p = '\0';
    fclose(f);
}

use(){
    e("Use: %s [-s subject] [-c cc_list] [-f file] to_list",av0);
    e("Open a 'Send' window in NeXT Mail.");
    e("  -s subj -- set 'Subject: ' field.");
    e("  -c cc   -- set 'Cc: ' field.");
    e("  -f file -- take body of message from 'file',");
    e("             If 'file' is \"\" use null body.");
    e("             If 'Subject:', 'Cc:', 'To:' appear in the body,");
    e("             append them to anything specified in the argument list.");
    e("If no '-f' option given, read body of message from stdin.");
    exit(1);
}

main(ac,av) char *av[]; {
    id s = [Speaker new];
    int i;

    for_each_argument {
    Case 'c': append(Cc,argument);
    Case 's': append(Subject,argument);
    Case 'f': LetterFile = argument;
    Default : use();
    }

    while (i<ac) append(To,av[i++]);
    readLetter();

    NXPortFromName("Mail", NULL); // make sure app is launched
    [s setSendPort:NXPortFromName("MailSendDemo", NULL)];

    stripnl(Subject);
    stripnl(To);
    stripnl(Cc);
    stripnl(Letter); if (*Letter) strcat(Letter,"\n");
#define call(a,b) [s performRemoteMethod:a with:b length:strlen(b)+1]
    call("setTo:",To);
    call("setSubject:",Subject);
    call("setCc:",Cc);
    call("setBody:",Letter);
}
