//---------------------------------------------------------------------------------------
//	MIMEContentType.m created by erik on Sun 23-Mar-1997
//	This code is part of the Alexandra Newsreader Project. For copyright details see
//	GNU public license version 2 or above. No warranties implied. Use at own risk.
//	More information can be found at <http://www.object-factory.com/Alexandra>.
//	@(#)$Id: MIMEContentType.m,v 1.3 1998/05/20 11:38:40 erik Exp $
//---------------------------------------------------------------------------------------

#import "Utilities.h"
#import "Message.h"

//---------------------------------------------------------------------------------------
//	constants and cached values
//---------------------------------------------------------------------------------------

NSString *MIMEApplicationContentType = @"application";
NSString *MIMEImageContentType		 = @"image";
NSString *MIMEAudioContentType		 = @"audio";
NSString *MIMEMessageContentType 	 = @"message";
NSString *MIMEMultipartContentType 	 = @"multipart";
NSString *MIMETextContentType 		 = @"text";
NSString *MIMEVideoContentType       = @"video";

NSString *MIMEAlternativeMPSubtype 	 = @"alternative";
NSString *MIMEMixedMPSubtype 		 = @"mixed";
NSString *MIMEParallelMPSubtype 	 = @"parallel";
NSString *MIMEDigestMPSubtype 		 = @"digest";

static NSDictionary *stringUniqueingTable = nil;


//---------------------------------------------------------------------------------------
    @implementation MIMEContentType
//---------------------------------------------------------------------------------------

#ifndef LITTLE_FOUNDATION
+ (void)initialize
#else
+ initialize
#endif
{
   	if(stringUniqueingTable == nil)
		{
	    NSArray	*strings;
   
   		strings = [NSArray arrayWithObjects:MIMEApplicationContentType, MIMEImageContentType, MIMEAudioContentType, MIMEMessageContentType, MIMEMultipartContentType, MIMETextContentType, MIMEVideoContentType, nil];
		stringUniqueingTable = [[NSDictionary dictionaryWithObjects:strings forKeys:strings] retain];
   		}
#ifndef LITTLE_FOUNDATION
#else
    return self;
#endif
}


//---------------------------------------------------------------------------------------

//---------------------------------------------------------------------------------------

+ (BOOL)isStandardMIMEContentType:(NSString *)string;
{
    return [stringUniqueingTable objectForKey:string] != nil;
}


+ (NSString *)uniquedMIMEContentType:(NSString *)string;
{
    return [stringUniqueingTable objectForKey:string];
}


//---------------------------------------------------------------------------------------
//	VALUE IMPLEMENTATION
//---------------------------------------------------------------------------------------

- (void)takeValueFromString:(NSString *)string;
{
    NSString	*value;
    NSScanner	*scanner;

	TRACE_IN
    scanner = [NSScanner scannerWithString:string];
    if([scanner scanCharactersFromSet:[NSCharacterSet MIMETokenCharacterSet] intoString:&value] == NO)
        [NSException raise:MIMEFormatException format:@"no type in '%@'", string];
    [self setContentType:value];
    if([scanner scanString:@"/" intoString:NULL] == YES)
		{
   		if([scanner scanCharactersFromSet:[NSCharacterSet MIMETokenCharacterSet] intoString:&value] == NO)
    	    [NSException raise:MIMEFormatException format:@"no subtype in '%@'", string];
		[self setContentSubtype:value];
		}
    else
        {
        // This is in no RFC, but writers do it anyway...
        if([self contentType] == MIMETextContentType)
            [self setContentSubtype:@"plain"];
        else
            [self setContentSubtype:@"unspecified"];
        }
}


- (void)appendValueToString:(NSMutableString *)string;
{
	TRACE_IN
	[string appendString:type];
	[string appendString:@"/"];
	[string appendString:subtype];
}


//---------------------------------------------------------------------------------------
//	accessor methods (read-only)
//---------------------------------------------------------------------------------------

- (void)setContentType:(NSString *)string;
{
	NSString	*uniquedString;

	TRACE_IN
	if(string == type)
		return;
    if([string rangeOfCharacterFromSet:[NSCharacterSet MIMENonTokenCharacterSet]].length != 0)
        [NSException raise:NSInvalidArgumentException format:@"invalid char in '%@'", string];
	string = [string lowercaseString];
    [type release];
    if((uniquedString = [MIMEContentType uniquedMIMEContentType:string]) != nil)
        type = [uniquedString retain];
    else
	    type = [string copyWithZone:[self zone]];
	[self invalidateStringRep];
}

- (NSString *)contentType;
{
    return type;
}


- (void)setContentSubtype:(NSString *)string;
{
	TRACE_IN
	if(string == subtype)
		return;
    if([string rangeOfCharacterFromSet:[NSCharacterSet MIMENonTokenCharacterSet]].length != 0)
        [NSException raise:NSInvalidArgumentException format:@"invalid char in '%@'", string];
    [subtype release];
    subtype = [[string lowercaseString] copyWithZone:[self zone]];
	[self invalidateStringRep];
}

- (NSString *)contentSubtype;
{
	TRACE_IN
    return subtype;
}
    

//---------------------------------------------------------------------------------------
//	NSObject Stuff
//---------------------------------------------------------------------------------------

- (void)dealloc
{
	TRACE_IN
	[type release];
	[subtype release];
	[super dealloc];
}


//---------------------------------------------------------------------------------------
    @end
//---------------------------------------------------------------------------------------
