//
//  NSIndexSetEnumerator.m
//

#import "NSIndexSetEnumerator.h"

/*!
 * I made a little class to help me around some of my confusions regarding NSIndexSet.
 * This class allows you to enumerate through an NSIndexSet using the Apple-suggested
 * method of <code>-(unsigned int)getIndexes:(unsigned int *)indexBuffer
 * maxCount:(unsigned int)bufferSize inIndexRange:(NSRangePointer)range</code> using
 * simple enumerator-like messages. Currently it doesn't support buffering (ie. if you
 * have an IndexSet with one million entries, you'll end up with an internal array of
 * one million entries), but it seems to work ok for what it is.
 * Please note that this is NOT rigorously tested or supported code, I just thought I'd
 * share something that made my life a little easier (note also the extreme lack of code
 * comments :-) ) but the code is relatively self explanatory (I hope!). (docs from
 * http://www.cocoadev.com/index.pl?NSIndexSet / further docs added by Belkadan Software)
 *
 * @author Darren Ford
 */
@implementation NSIndexSetEnumerator

/*!
 * Initializes and returns a newly allocated enumerator with the specified <code>NSIndexSet</code>.
 */
- (id)initWithIndexSet:(NSIndexSet *)theSet
{
    NSRange myRange = NSMakeRange([theSet firstIndex], [theSet lastIndex] + 1);
    return [self initWithIndexSet:theSet range:myRange];
}

/*!
 * Initializes and returns a newly allocated enumerator with the specified <code>NSIndexSet</code>
 * and range. This enumerator will only enumerate the indexes in <code>myRange</code>. This is the
 * designated initializer.
 */
- (id)initWithIndexSet:(NSIndexSet *)theSet range:(NSRange)myRange
{
    self = [super init];
    if (!self) 
    {
        return nil;
    }

    m_uCurrentPosition = -1;
    
    m_uIndexCount = [theSet count];
    m_puIndexes = (unsigned int *)calloc(m_uIndexCount, sizeof(unsigned int));

    [theSet getIndexes:m_puIndexes maxCount:m_uIndexCount inIndexRange:&myRange];
   
    return self;
}

- (void)dealloc
{
//    NSLog(@"NSIndexSetEnumerator: deallocing");
    free(m_puIndexes);
    
    [super dealloc];
}

/*!
 * Provides the next index by means of the <code>pValue</code> pointer.
 * Returns <code>YES</code> if an index was placed in <code>pValue</code>,
 * <code>NO</code> if there are no more indexes.
 */
- (BOOL)nextIndex:(unsigned int *)pValue
{
    m_uCurrentPosition++;
    if (m_uCurrentPosition >= m_uIndexCount)
        return NO; // was FALSE
    *pValue = m_puIndexes[m_uCurrentPosition];
    return YES; // was TRUE
}

/*!
 * Returns the <code>i</code>'th index in the list of indexes. If <code>i</code>
 * is greater than the number of indexes, returns <code>NSNotFound</code>.
 */
- (unsigned int)indexAtIndex:(unsigned int)i
{
    if (i >= m_uIndexCount)
        return NSNotFound;
    return m_puIndexes[i];
}

/*!
 * Starts the enumerator back at the beginning of the list.
 */
- (void)reset
{
    m_uCurrentPosition = -1;
}

/*!
 * Returns the total number of indexes.
 */
- (unsigned int)count
{
    return m_uIndexCount;
}

@end
