#import "DWSISize.h"
#import "DWCachedString.h"
#import "DWText.h"
#import "NSStringExtensions.h"


@implementation DWSISize

/* Initialization */

    + (id) sizeWithValue: (double) val; {
        return [[[DWSISize alloc] initWithValue: val] autorelease];
    }
    
    - (id) initWithValue: (double) val; {
        self = [self init];
        value = val;
        return self;
    }
    
    - (id) init; {
        self = [super init];
        displayPrecision = 1;
        showsSIUnits = YES;
        thousand = 1000;
        postfix = @"";
        zeroValue = @"-";
        minimumMagnitude = 1;
        return self;
    }
    
    - (id) copyWithZone: (id) zone; {
        return [self retain];
    }
    
    - (void) dealloc; {
        [image release];
        [tableString release];
        [description release];
        [super dealloc];
    }

    
#pragma mark -
/* Set */

    - (void) invalidateCaches; {
        [image release];		
        [tableString release];
        [description release];
        image = tableString = description = nil;
    }
    
    - (void) setValue: (double) val; {
        if (value != val) {
            value = val;
            [self invalidateCaches];
        }
    }

    - (void) setDisplayPrecision: (int) digits; {
        displayPrecision = digits;
        [self invalidateCaches];
    }	
    
    - (void) setShowsSIUnits: (BOOL) toSet; {
        showsSIUnits = toSet;
        [self invalidateCaches];
    }
    
    - (void) setPostfix: (id) theValue; {
        [postfix release];
        postfix = [theValue retain];
        [self invalidateCaches];
    }
    
    - (void) setZeroValue: (id) theValue; {
        [zeroValue release];
        zeroValue = [theValue retain];
        [self invalidateCaches];
    }
    
    - (void) setMinimumMagnitude: (int) theValue; {
        minimumMagnitude = theValue;
        [self invalidateCaches];
    }


#pragma mark -
/* Get */
    
    - (double) value; {
        return value;
    }

    - (float) floatValue; {
        return (float) value;
    }
    
    - (id) image; {
        if (!image) {
            id d = [self description];
            if (d) image = [[DWCachedString alloc] initWithString: d attributes: [DWText smallTextAttributes]];
        }
        return image;
    }
    
    - (DWTableString*) tableString; {
        if (!tableString) {
            id d = [self description];
            if (d) tableString = [[DWTableString alloc] initWithString: d attributes: [DWText smallTextAttributes]];
        }
        return tableString;
    }

    - (NSString*) description; 
    {
        if (description) return description;
        
        if (value == 0) {
            description = [zeroValue retain];
            return description;
        }
        
        if (!showsSIUnits) {

            description = [[NSString alloc] initWithFormat: [NSString stringWithFormat: @"%%.%if%%@", displayPrecision], value, postfix];
 
        } else {

            float mantissas = value;
            int magnitude = 0;

            NSString* postfixes = @"kMGTPEZYXVU";
        
            while (mantissas >= thousand || magnitude < minimumMagnitude) {
                mantissas = mantissas / thousand;
                magnitude ++;
            }
            
            if (magnitude > 0 && magnitude < (int)[postfixes length]) {
                description = [[NSString alloc] initWithFormat: [NSString stringWithFormat: @"%%.%if%%c%%@", displayPrecision], mantissas, [postfixes characterAtIndex: magnitude-1], postfix];
            } else if (magnitude == 0) {
                description = [[NSString alloc] initWithFormat: @"%.0f%@", mantissas, postfix];
            } else {
                description = [[NSString alloc] initWithFormat: [NSString stringWithFormat: @"%%.%if%%@", displayPrecision], mantissas, postfix];
            }
        }
        return description;
    }

@end