//
//  XTRecentGameFiles.m
//  XTads
//
//  Created by Rune Berg on 06/08/15.
//  Copyright (c) 2015 Rune Berg. All rights reserved.
//

#import "XTFileUtils.h"
#import "XTRecentGameFiles.h"


@interface XTRecentGameFiles ()

// Order: newest .. oldest
@property NSMutableArray *entries; // of XTRecentGameFilesEntry

@end


@implementation XTRecentGameFilesEntry

static NSString* persistedEntryKeyPrefix = @"XTadsRecentEntry";
static NSString* persistedEntryValueKeyGameFileUrl = @"gameFileUrl";
static NSString* persistedEntryValueKeyGameTitle = @"gameTitle";

+ (instancetype)entryWithGameFileUrl:(NSURL *)gameFileUrl gameTitle:(NSString *)gameTitle
{
	XTRecentGameFilesEntry *entry = [XTRecentGameFilesEntry new];
	entry.gameFileUrl = gameFileUrl;
	if (gameTitle != nil) {
		entry.gameTitle = gameTitle;
	} else {
		entry.gameTitle = [gameFileUrl lastPathComponent];
	}	
	return entry;
}

@end


@implementation XTRecentGameFiles

@synthesize maxNumberOfEntries = _maxNumberOfEntries;

static XTRecentGameFiles *singletonInstance = nil;

+ (instancetype)recentGameFiles
{
	if (singletonInstance == nil) {
		singletonInstance = [XTRecentGameFiles new];
	}
	return singletonInstance;
}

- (id)init
{
	self = [super init];
	if (self != nil) {
		_maxNumberOfEntries = 10;
		_entries = [NSMutableArray arrayWithCapacity:_maxNumberOfEntries];
	}
	return self;
}

- (NSUInteger)numberOfEntries
{
	return self.entries.count;
}

- (void)setMaxNumberOfEntries:(NSUInteger)maxNum
{
	_maxNumberOfEntries = maxNum;
	[self pruneExcessEntries];
}

- (NSUInteger)maxNumberOfEntries
{
	return _maxNumberOfEntries;
}

- (void)removeAllEntries
{
	[self.entries removeAllObjects];
}

- (void)persist;
{
	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
	
	NSUInteger persistedIndex = 0;
	for (XTRecentGameFilesEntry *entry in self.entries) {
		
		NSString *key = [self keyForPersistedEntry:persistedIndex];
		NSMutableDictionary *value = [NSMutableDictionary dictionary];
		if ([XTFileUtils isExistingFileUrl:entry.gameFileUrl]) {
			[value setObject:[entry.gameFileUrl absoluteString] forKey:persistedEntryValueKeyGameFileUrl];
			[value setObject:entry.gameTitle forKey:persistedEntryValueKeyGameTitle];
			[userDefaults setObject:value forKey:key];
			persistedIndex += 1;
		}
	}
	
	for (NSUInteger excessIndex = persistedIndex; excessIndex < 100; excessIndex++) {

		NSString *key = [self keyForPersistedEntry:excessIndex];
		[userDefaults removeObjectForKey:key];
	}
}

- (void)restoreFromPersisted
{
	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
	
	[self removeAllEntries];
	
	for (NSUInteger idx = 0; idx < self.maxNumberOfEntries; idx += 1) {
		NSString *key = [self keyForPersistedEntry:idx];
		NSDictionary *dict = [userDefaults objectForKey:key];
		if (dict != nil) {
			NSString *gameFileUrlString = [dict objectForKey:persistedEntryValueKeyGameFileUrl];
			NSURL *gameFileUrl = [NSURL URLWithString:gameFileUrlString];
			if ([XTFileUtils isExistingFileUrl:gameFileUrl]) {
				NSString *gameTitle = [dict objectForKey:persistedEntryValueKeyGameTitle];
				XTRecentGameFilesEntry *entry = [XTRecentGameFilesEntry entryWithGameFileUrl:gameFileUrl gameTitle:gameTitle];
				[self.entries addObject:entry];
			}
		}
	}
}

- (void)addNewestEntry:(XTRecentGameFilesEntry *)entry
{
	[self pruneDuplicatesOfEntry:entry];
	[self.entries insertObject:entry atIndex:0];
	[self pruneExcessEntries];
}

- (XTRecentGameFilesEntry *)entryAtIndex:(NSUInteger)index
{
	XTRecentGameFilesEntry *entry = [self.entries objectAtIndex:index];
	return entry;
}

//-------- Internal --------

- (NSString *)keyForPersistedEntry:(NSUInteger)index
{
	NSString *key = [NSString stringWithFormat:@"%@%lu", persistedEntryKeyPrefix, index];
	return key;
}

- (void)pruneDuplicatesOfEntry:(XTRecentGameFilesEntry *)entry
{
	for (NSUInteger idx = 0; idx < self.entries.count; idx++) {
		XTRecentGameFilesEntry *entryAtIndex = [self.entries objectAtIndex:idx];
		if ([entryAtIndex.gameFileUrl isEqualTo:entry.gameFileUrl]) {
			[self.entries removeObjectAtIndex:idx];
			break; // there can't be more than 1 duplicate
		}
	}
}

- (void)pruneExcessEntries
{
	for (NSInteger numToPrune = self.entries.count - self.maxNumberOfEntries;  // can be negative
		 numToPrune > 0;
		 numToPrune -= 1) {
		
		[self.entries removeLastObject];
	}
}

@end
