#import "MoneyBag.h" #import "Money.h" @interface MoneyBag (Privates) - (id)init; - (void)appendBag:(MoneyBag *)aBag; - (void)appendMoney:(Money *)aMoney; - (BOOL)contains:(Money *)aMoney; - (Money *)findMoney:(NSString *)currency; - (id)simplify; @end @implementation MoneyBag - (id)init { self = [super init]; fMonies = [[NSMutableArray alloc] init]; return self; } - (id)initWithMoneyArray:(NSArray *)array { NSEnumerator *e; Money *each; self = [self init]; e = [array objectEnumerator]; while ((each = [e nextObject]) != nil) { if (![each isZero]) [self appendMoney:each]; } return self; } - (id)initWithMoney:(Money *)money1 money:(Money *)money2 { self = [self init]; [self appendMoney:money1]; [self appendMoney:money2]; return self; } - (id)initWithMoney:(Money *)money bag:(MoneyBag *)bag { self = [self init]; [self appendMoney:money]; [self appendBag:bag]; return self; } - (id)initWithMoneyBag:(MoneyBag *)bag1 bag:(MoneyBag *)bag2 { self = [self init]; [self appendBag:bag1]; [self appendBag:bag2]; return self; } - (void)dealloc { [fMonies release]; [super dealloc]; } - (id)add:(id)money { return [money addMoneyBag:self]; } - (id)addMoney:(Money *)money { return [[[[MoneyBag alloc] initWithMoney:money bag:self] autorelease] simplify]; } - (id)addMoneyBag:(MoneyBag *)bag { return [[[[MoneyBag alloc] initWithMoneyBag:bag bag:self] autorelease] simplify]; } - (void)appendBag:(MoneyBag *)aBag { NSEnumerator *e = [aBag->fMonies objectEnumerator]; Money *each; while ((each = [e nextObject]) != nil) { [self appendMoney:each]; } } - (void)appendMoney:(Money *)aMoney { id old; id sum; old = [self findMoney:[aMoney currency]]; if (old == nil) { [fMonies addObject:aMoney]; return; } [fMonies removeObject:old]; sum = [old add:aMoney]; if ([sum isZero]) return; [fMonies addObject:sum]; } - (BOOL)contains:(Money *)aMoney { Money *m = [self findMoney:[aMoney currency]]; return [m amount] == [aMoney amount]; } - (BOOL)isEqual:(id)anObject { if ([self isZero]) if ([anObject conformsToProtocol:@protocol(IMoney)]) return [anObject isZero]; if ([anObject isMemberOfClass:[MoneyBag class]]) { MoneyBag *aMoneyBag; NSEnumerator *e; Money *m; aMoneyBag = (MoneyBag *)anObject; if ([aMoneyBag->fMonies count] != [fMonies count]) return NO; e = [fMonies objectEnumerator]; while ((m = [e nextObject]) != nil) { if (![aMoneyBag contains:m]) return NO; } return YES; } return NO; } - (Money *)findMoney:(NSString *)currency { NSEnumerator *e = [fMonies objectEnumerator]; Money *m; while ((m = [e nextObject]) != nil) { if ([[m currency] isEqualToString:currency]) return m; } return nil; } - (BOOL)isZero { return [fMonies count] == 0; } - (id)multiply:(int)factor { MoneyBag *result = [[[MoneyBag alloc] init] autorelease]; if (factor != 0) { NSEnumerator *e = [fMonies objectEnumerator]; Money *m; while ((m = [e nextObject]) != nil) { [result appendMoney:[m multiply:factor]]; } } return result; } - (id)negate { MoneyBag *result = [[[MoneyBag alloc] init] autorelease]; NSEnumerator *e = [fMonies objectEnumerator]; Money *m; while ((m = [e nextObject]) != nil) { [result appendMoney:[m negate]]; } return result; } - (id)simplify { if ([fMonies count] == 1) return [[fMonies objectEnumerator] nextObject]; return self; } - (id)subtract:(id)money { return [self add:[money negate]]; } - (NSString *)description { NSMutableString *buffer = [NSMutableString string]; NSEnumerator *e = [fMonies objectEnumerator]; Money *m; [buffer appendString:@"{"]; while ((m = [e nextObject]) != nil) [buffer appendString:[m description]]; [buffer appendString:@"}"]; return buffer; } @end