//
//  PhotoZoom.m
//  Images
//
//  Created by Hagbarðr on 4/18/19.
//

// TODO: implement fullscreen
// TODO: implement space between images

#import "PhotoZoom.h"
#import "PhotoZoomImageViewController.h"

@protocol InputDataSource <NSObject>
- (NSArray *)collectedValuesForKeyPath:(NSString *)keyPath;
- (void)navigateToItemAtIndex:(NSUInteger)index;
@end

@protocol DataSourceBase <NSObject>
- (NSInteger)numberOfItemsInSection:(NSInteger)section;
- (NSDictionary *)datasetForItemAtIndexPath:(NSIndexPath *)indexPath;
@end

@interface PhotoZoom(Private) <UIPageViewControllerDataSource, UIPageViewControllerDelegate> {
}
@end

@implementation PhotoZoom {
	NSArray * _imageInfos;
	CGFloat _spaceBetweenImages;
	NSArray * _bindingsInfo;
}

- (void)setImageURLs:(NSArray*)value {
	
	NSArray * urlStrings;
	if ([value isKindOfClass:[NSString class]]) {
		urlStrings = [[((NSString *)value) stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet] componentsSeparatedByString:@"\n"];
	} else if ([value isKindOfClass:[NSArray class]]) {
		NSMutableArray * array = @[].mutableCopy;
		for (id url in value) {
			if ([url isKindOfClass:[NSString class]])
			[array addObject:url];
		}
		urlStrings = array;
	} else if ([value isKindOfClass:NSClassFromString(@"DataSourceBase")]) {
		id<DataSourceBase> ds = (id<DataSourceBase>)value;
		NSMutableArray * array = @[].mutableCopy;
		for (NSInteger i = 0, c = [ds numberOfItemsInSection:0]; i < c; i++) {
			NSString * s = [NSString stringWithFormat:@"%@", [ds datasetForItemAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]]];
			[array addObject:s];
		}
		urlStrings = array;
	} else return;
	
	NSMutableArray * imageInfos = @[].mutableCopy;
	for (NSString * urlString in urlStrings) {
		if (![urlString isKindOfClass:[NSString class]]) {
			continue;
		}
		if ([urlString hasPrefix:@"file:"]) {
			NSString *filename = [urlString substringFromIndex:5];
			[imageInfos addObject:@{@"URL":[[NSBundle mainBundle] URLForResource:filename withExtension:nil]}];
		} else {
			NSURL *url = [NSURL URLWithString:urlString];
			if(url != nil) {
				[imageInfos addObject:@{@"URL":url}];
			}
		}
	}
	_imageInfos = imageInfos;
	[self loadGallery];
}

- (void)loadGallery {
	if(_imageInfos.count > 0 && self.viewController != nil) {
		PhotoZoomImageViewController *vc = [self viewControllerForPage:0];
		if(vc != nil) {
			[self.viewController setViewControllers:@[vc] direction:UIPageViewControllerNavigationDirectionForward animated:false completion:^(BOOL finished) {
			}];
		}
	}
}

- (void)setSpaceBetweenImages:(CGFloat)space {
	_spaceBetweenImages = space;
}

- (void)toggleFullScreen {
	// TODO: implement this
	//[self toggleNavigationBarVisibility];
	//[self toggleTabBarVisibility];
	//_isFullScreen = !_isFullScreen;
}

- (void)setInputDataSource:(id)inputDataSource {
	_inputDataSource = inputDataSource;
	
}

- (void)setBindingsInfoString:(NSString *)bindingsInfoString {
	NSError *error = nil;
	_bindingsInfo = [NSJSONSerialization JSONObjectWithData:[bindingsInfoString dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&error];
	if(_bindingsInfo != nil && !error) {
		[self prepare];
		[self loadGallery];
	}
}

- (void)awakeFromNib {
	[super awakeFromNib];
	// TODO: implement this
	self.viewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
	[self.viewController.view setFrame:self.bounds];
	[self.viewController.view setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];
	[self.viewController setDelegate:self];
	[self.viewController setDataSource:self];
	[self addSubview:self.viewController.view];
	[self setAllowsCircularScrolling:NO];
	[self prepare];
	[self loadGallery];
}

- (void)prepare {
	if (!_bindingsInfo || !_inputDataSource) {
		return;
	}
	// find the 'imageURLs' binding
	for (NSDictionary * bindingInfo in _bindingsInfo) {
		if ([bindingInfo[@"sourceKeyPath"] isEqualToString:@"imageURLs"]) {
			if ([bindingInfo[@"destination"] isEqualToString:[_inputDataSource valueForKey:@"identifier"]]) {
				NSArray * values = [_inputDataSource performSelector:@selector(collectedValuesForKeyPath:) withObject:bindingInfo[@"destinationKeyPath"]];
				[self setImageURLs:values];
			}
		}
	}
}

- (PhotoZoomImageViewController*)viewControllerForPage:(NSInteger)page {
	if(page < _imageInfos.count) {
		NSURL *url = nil;
		if([_imageInfos[page] isKindOfClass:[NSURL class]]) {
			url = _imageInfos[page];
		} else if ([_imageInfos[page] isKindOfClass:[NSDictionary class]] && [_imageInfos[page][@"URL"] isKindOfClass:[NSURL class]]) {
			url = _imageInfos[page][@"URL"];
		}
		if(url != nil) {
			PhotoZoomImageViewController *vc = [PhotoZoomImageViewController instantiateWithImageURL:url];
			vc.index = page;
			return vc;
		}
	}
	return nil;
}

#pragma mark - UIPageViewControllerDataSource

- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {
	NSInteger currentPage = [(PhotoZoomImageViewController*)viewController index];
	if(currentPage < 1) {
		if (_imageInfos.count > 1 && self.allowsCircularScrolling == true) {
			return [self viewControllerForPage:(_imageInfos.count-1)];
		}
		return nil;
	}
	return [self viewControllerForPage:(currentPage-1)];
}

- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {
	NSInteger currentPage = [(PhotoZoomImageViewController*)viewController index];
	if((currentPage+1) < _imageInfos.count) {
		return [self viewControllerForPage:(currentPage+1)];
	}
	if((currentPage+1) == _imageInfos.count && _imageInfos.count > 1 && self.allowsCircularScrolling == true) {
		return [self viewControllerForPage:0];
	}
	return nil;
}
/*
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController {
	return _imageInfos.count;
}

- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController {
	return 0;
}
*/
@end
