1 /* CardElement.m - this file is part of SOPE
3 * Copyright (C) 2006 Inverse groupe conseil
5 * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
7 * This file is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * This file is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
23 #import <Foundation/NSArray.h>
24 #import <Foundation/NSDictionary.h>
25 #import <Foundation/NSRange.h>
26 #import <Foundation/NSString.h>
28 #import "NSArray+NGCards.h"
29 #import "NSDictionary+NGCards.h"
30 #import "CardVersitRenderer.h"
32 #import "CardElement.h"
35 @implementation CardElement
37 + (id) elementWithTag: (NSString *) aTag
41 newElement = [self new];
42 [newElement autorelease];
43 [newElement setTag: aTag];
48 + (id) simpleElementWithTag: (NSString *) aTag
49 value: (NSString *) aValue
53 newElement = [self elementWithTag: aTag];
54 [newElement addValue: aValue];
59 + (id) simpleElementWithTag: (NSString *) aTag
60 singleType: (NSString *) aType
61 value: (NSString *) aValue
65 newElement = [self simpleElementWithTag: aTag
67 [newElement addType: aType];
72 + (id) elementWithTag: (NSString *) aTag
73 attributes: (NSDictionary *) someAttributes
74 values: (NSArray *) someValues
78 newElement = [self new];
79 [newElement autorelease];
80 [newElement setTag: aTag];
81 [newElement addAttributes: someAttributes];
82 [newElement addValues: someValues];
89 if ((self = [super init]))
94 values = [NSMutableArray new];
95 attributes = [NSMutableDictionary new];
106 [attributes release];
110 - (void) setParent: (CardGroup *) aParent
115 - (CardGroup *) parent
120 - (void) setTag: (NSString *) aTag
129 - (void) setGroup: (NSString *) aGroup
143 - (void) addValue: (NSString *) aValue
145 [values addObject: aValue];
148 - (void) addValues: (NSArray *) someValues
150 [values addObjectsFromArray: someValues];
153 - (void) addAttribute: (NSString *) anAttribute
154 value: (NSString *) aType
156 NSMutableArray *attrValues;
158 attrValues = [attributes objectForCaseInsensitiveKey: anAttribute];
161 attrValues = [NSMutableArray new];
162 [attrValues autorelease];
163 [attributes setObject: attrValues forKey: anAttribute];
166 [attrValues addObject: aType];
169 - (void) removeValue: (NSString *) aValue
170 fromAttribute: (NSString *) anAttribute
172 NSMutableArray *attrValues;
173 NSString *currentValue;
175 attrValues = [attributes objectForCaseInsensitiveKey: anAttribute];
178 currentValue = [attrValues valueForCaseInsensitiveString: aValue];
181 [attrValues removeObject: currentValue];
182 currentValue = [attrValues valueForCaseInsensitiveString: aValue];
187 - (void) addAttributes: (NSDictionary *) someAttributes
190 NSString *currentKey;
191 NSMutableArray *oldValues;
194 keys = [[someAttributes allKeys] objectEnumerator];
195 currentKey = [keys nextObject];
198 oldValues = [attributes objectForCaseInsensitiveKey: currentKey];
199 newValues = [someAttributes objectForKey: currentKey];
201 [oldValues addObjectsFromArray: newValues];
203 [attributes setObject: newValues forKey: currentKey];
204 currentKey = [keys nextObject];
208 - (void) addType: (NSString *) aType
210 [self addAttribute: @"type" value: aType];
223 - (NSDictionary *) attributes
228 - (BOOL) hasAttribute: (NSString *) anAttribute
229 havingValue: (NSString *) aValue
233 attribute = [attributes objectForCaseInsensitiveKey: anAttribute];
235 return (attribute && [attribute hasCaseInsensitiveString: aValue]);
238 - (void) setValue: (unsigned int) anInt
239 to: (NSString *) aValue
241 while ([values count] <= anInt)
242 [self addValue: @""];
243 [values replaceObjectAtIndex: anInt withObject: aValue];
246 - (NSString *) value: (unsigned int) anInt
250 if ([values count] <= anInt)
253 value = [values objectAtIndex: anInt];
258 - (unsigned int) _namedValue: (NSString *) aValueName
260 NSString *prefix, *value;
261 unsigned int count, max, result;
265 prefix = [NSString stringWithFormat: @"%@=", [aValueName uppercaseString]];
266 max = [values count];
269 while (result == NSNotFound && count < max)
271 value = [[values objectAtIndex: count] uppercaseString];
272 if ([value hasPrefix: prefix])
281 - (void) setNamedValue: (NSString *) aValueName
282 to: (NSString *) aValue
287 newValue = [NSString stringWithFormat: @"%@=%@",
288 [aValueName uppercaseString],
290 index = [self _namedValue: aValueName];
291 if (index == NSNotFound)
292 [self addValue: newValue];
296 [self setValue: index to: newValue];
298 [values removeObjectAtIndex: index];
302 - (NSString *) namedValue: (NSString *) aValueName
308 index = [self _namedValue: aValueName];
309 if (index == NSNotFound)
313 value = [values objectAtIndex: index];
314 equalSign = [value rangeOfString: @"="];
315 if (equalSign.location != NSNotFound)
316 value = [value substringFromIndex: equalSign.location + 1];
322 - (void) setValue: (unsigned int) anInt
323 ofAttribute: (NSString *) anAttribute
324 to: (NSString *) aValue
326 NSMutableArray *attrValues;
328 attrValues = [attributes objectForCaseInsensitiveKey: anAttribute];
331 attrValues = [NSMutableArray new];
332 [attrValues autorelease];
333 [attributes setObject: attrValues forKey: anAttribute];
336 while ([attrValues count] <= anInt)
337 [attrValues addObject: @""];
338 [attrValues replaceObjectAtIndex: anInt
342 - (NSString *) value: (unsigned int) anInt
343 ofAttribute: (NSString *) anAttribute
348 attrValues = [attributes objectForCaseInsensitiveKey: anAttribute];
349 if (attrValues && [attrValues count] > anInt)
350 value = [attrValues objectAtIndex: anInt];
357 - (NSString *) description
360 NSMutableString *str;
361 unsigned int count, max;
364 str = [NSMutableString stringWithCapacity:64];
365 [str appendFormat:@"<%p[%@]:", self, NSStringFromClass([self class])];
367 [str appendFormat: @"%@ (group: %@)\n", tag, group];
369 [str appendFormat: @"%@\n", tag, group];
371 attrs = [attributes allKeys];
375 [str appendFormat: @"\n %d attributes: {\n", [attrs count]];
376 for (count = 0; count < max; count++)
378 attr = [attrs objectAtIndex: count];
379 [str appendFormat: @" %@: %@\n",
380 attr, [attributes objectForKey: attr]];
382 [str appendFormat: @"}"];
385 max = [values count];
388 [str appendFormat: @"\n %d values: {\n", [values count]];
389 for (count = 0; count < max; count++)
390 [str appendFormat: @" %@\n", [values objectAtIndex: count]];
391 [str appendFormat: @"}"];
394 [str appendString:@">"];
407 enu = [values objectEnumerator];
408 value = [enu nextObject];
409 while (value && result)
411 result = ([value length] == 0);
412 value = [enu nextObject];
418 - (NSString *) versitString
421 CardVersitRenderer *renderer;
423 renderer = [CardVersitRenderer new];
424 string = [renderer render: self];
427 if ([string hasSuffix: @"\r\n"])
428 string = [string substringToIndex: [string length] - 2];
433 - (CardElement *) elementWithClass: (Class) elementClass
435 CardElement *newElement;
437 if ([self isKindOfClass: elementClass])
441 newElement = [elementClass new];
442 [newElement autorelease];
443 [newElement setTag: tag];
444 [newElement setValuesAsCopy: values];
445 [newElement setAttributesAsCopy: attributes];
447 [newElement setGroup: group];
450 [newElement setParent: parent];
451 [parent replaceThisElement: self
452 withThisOne: newElement];
459 - (void) setValuesAsCopy: (NSMutableArray *) someValues
466 - (void) setAttributesAsCopy: (NSMutableDictionary *) someAttributes
468 [attributes release];
469 attributes = someAttributes;
473 - (CardGroup *) searchParentOfClass: (Class) parentClass
480 while (current && !found)
481 if ([current isKindOfClass: parentClass])
484 current = [current parent];
491 - (id) copyWithZone: (NSZone *) aZone
495 new = [[self class] new];
496 [new setTag: [tag copyWithZone: aZone]];
497 [new setGroup: [group copyWithZone: aZone]];
498 [new setParent: parent];
499 [new setValuesAsCopy: [values copyWithZone: aZone]];
500 [new setAttributesAsCopy: [attributes copyWithZone: aZone]];