/* Copyright (c) 2004, Noah Sorscher
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 	• 	Redistributions of source code must retain the above copyright
 * 	notice, this list of conditions and the following disclaimer.
 * 	• 	Redistributions in binary form must reproduce the above copyright
 * 	notice, this list of conditions and the following disclaimer in the
 * 	documentation and/or other materials provided with the distribution.
 * 	• 	Neither the name of the Noah Sorscher nor the names of its
 * 	contributors may be used to endorse or promote products derived from
 * 	this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
//
//  tImageBuffer.m
//  Hootenanny
//
//  Created by Noah Sorscher on Sun Mar 30 2003.
//  Copyright (c) 2003 __MyCompanyName__. All rights reserved.
//

#import "tImageBuffer.h"
#import "tImageBufferItem.h"

@implementation tImageBuffer


- (tImageBuffer *)init
{
    theImages = [[NSMutableDictionary alloc] init];
    anchor = [[tImageBufferItem alloc] initWithImage:nil index:-1];
    [anchor setNext:anchor];
    [anchor setPrev:anchor];
    maxImages = 500;
    currentSize = 0;
    self = [super init];
    return self;
}

- (void)setMaxSize:(long)numImages
{
    maxImages = numImages;
    while (currentSize > maxImages)
        [self pop];
}

- (void)setImage:(NSImage *)anImage forIndex:(long)index
{
    if (nil == anImage) return;
    tImageBufferItem *buffer = nil;
    buffer = [theImages objectForKey:[NSNumber numberWithLong:index]];
    if (buffer != nil)
        [self removeObject:buffer];
    tImageBufferItem *item = [[tImageBufferItem alloc] initWithImage:anImage index:index];
    [self push:item];
    currentSize++;
    if (currentSize > maxImages)
        [self pop];
}

- (NSImage *)imageForIndex:(long)index
{
    tImageBufferItem *theObject = [theImages objectForKey:[NSNumber numberWithLong:index]];
    if (nil == theObject) return nil;
    [self extractObject:theObject];
    [self push:theObject];
    return [theObject image];
}

- (BOOL)hasImageForIndex:(long)index
{
    return nil != [theImages objectForKey:[NSNumber numberWithLong:index]];
}

- (void)removeObject:(tImageBufferItem *)item
{
    [self extractObject:item];
    [item release];
    currentSize--;
}

- (void)extractObject:(tImageBufferItem *)item
{
    tImageBufferItem *next, *prev;
    next = [item next];
    prev = [item prev];
    [prev setNext:next];
    [next setPrev:prev];
}

- (void)push:(tImageBufferItem *)item
{
    tImageBufferItem *next, *prev;
    next = [anchor next];
    prev = anchor;
    
    [prev setNext:item];
    
    [item setNext:next];
    [item setPrev:prev];
    
    [next setPrev:item];
    [theImages setObject:item forKey:[NSNumber numberWithLong:[item index]]];
}

- (void)pop
{
    if (currentSize == 0) return;
    tImageBufferItem *theObject = [anchor prev];
    [theImages removeObjectForKey:[NSNumber numberWithLong:[theObject index]]];
    [self removeObject:theObject];
}

- (void)empty
{
    tImageBufferItem *item;
    NSArray *keys = [theImages allKeys];
    int i, n = [keys count];
    for (i=0; i<n; i++) {
        item = [theImages objectForKey:[keys objectAtIndex:i]];
        [theImages removeObjectForKey:[keys objectAtIndex:i]];
        [item release];
    }
    currentSize = 0;
    [anchor setNext:anchor];
    [anchor setPrev:anchor];
}

@end
