/*
  Copyright (C) 2000-2005 SKYRIX Software AG

  This file is part of SOPE.

  SOPE is free software; you can redistribute it and/or modify it under
  the terms of the GNU Lesser General Public License as published by the
  Free Software Foundation; either version 2, or (at your option) any
  later version.

  SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with SOPE; see the file COPYING.  If not, write to the
  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
  02111-1307, USA.
*/

#include "NGMimeMessage.h"
#include "common.h"

@implementation NGMimeMessage

static NGMimeType *defaultTextType = nil;
static NGMimeType *defaultDataType = nil;

+ (int)version {
  return 2;
}

+ (void)initialize {
  static BOOL isInitialized = NO;
  if (!isInitialized) {
    isInitialized = YES;
    
    defaultTextType = 
      [[NGMimeType mimeType:@"text/plain; charset=us-ascii"] retain];
    defaultDataType = 
      [[NGMimeType mimeType:@"application/octet-stream"] retain];
  }
}
  
+ (id)messageWithHeader:(NGHashMap *)_header {
  return [[[self alloc] initWithHeader:_header] autorelease];
}

- (id)init {
  return [self initWithHeader:nil];
}
- (id)initWithHeader:(NGHashMap *)_header {
  if ((self = [super init])) {
    self->header = [_header retain];
  }
  return self;
}

- (void)dealloc {
  [self->header   release];
  [self->body     release];
  [self->mimeType release];
  [super dealloc];
}

/* NGPart */

- (NSEnumerator *)valuesOfHeaderFieldWithName:(NSString *)_name {
  if ([_name isEqualToString:@"content-type"] == YES) {
    return [[NSArray arrayWithObject:[self contentType]] objectEnumerator];
  }
  return [self->header objectEnumeratorForKey:_name];
}
- (NSEnumerator *)headerFieldNames {
  return [self->header keyEnumerator];
}

- (void)setBody:(id)_body {
  ASSIGN(self->body,     _body);
  ASSIGN(self->mimeType, (id)nil);
}
- (id)body {
  return self->body;
}

/* NGMimePart */

- (NGMimeType *)autodetectContentType {
  NGMimeType *type = nil;
  
  if ((self->body != nil) &&
      ([self->body isKindOfClass:[NSData class]] == YES)) {
    const char *bytes = NULL;
    unsigned   length = 0;

    bytes  = [self->body bytes];
    length = [self->body length];
        
    while (length > 0) {
      if ((unsigned char)*bytes > 127) {
	break;
      }
      bytes++;
      length--;
    }
    type = (length > 0) ? defaultDataType : defaultTextType;
  }
  else
    type = defaultTextType;
  
  return type;
}

- (NGMimeType *)contentType {
  if (self->mimeType == nil) {
    NGMimeType *type = nil;
    
    if ((type = [self->header objectForKey:@"content-type"]) == nil)
      type = [self autodetectContentType];
    
    if (![type isKindOfClass:[NGMimeType class]])
      type = [NGMimeType mimeType:[type stringValue]];
    
    ASSIGNCOPY(self->mimeType, type);
  }
  return self->mimeType;
}

- (NSString *)contentId {
  return [[self->header objectForKey:@"content-id"] stringValue];
}

- (NSArray *)contentLanguage {
  return [self->header objectForKey:@"content-language"];
}

- (NSString *)contentMd5 {
  return [[self->header objectForKey:@"content-md5"] stringValue];
}

- (NSString *)encoding {
  return [[self->header objectForKey:@"content-transfer-encoding"] stringValue];
}

- (NSString *)contentDescription {
  return [self->header objectForKey:@"content-description"];
}

/* description */

- (NSString *)description {
  NSMutableString *d = [NSMutableString stringWithCapacity:64];
  id b = [self body];

  [d appendFormat:@"<%@[0x%08X]: header=%@",
       NSStringFromClass([self class]), self, self->header];

  if ([b isKindOfClass:[NSString class]] || [b isKindOfClass:[NSData class]]) {
    if ([b length] < 512)
      [d appendFormat:@" body=%@", b];
    else
      [d appendFormat:@" body[len=%i]", [b length]];
  }
  else
    [d appendFormat:@" body=%@", b];

  [d appendString:@">"];

  return d;
}

@end /* NGMimeMessage */
