//
//  SearchBarDataProvider.m
//
//

#import "SearchBarDataProvider.h"
#import "TextFieldDelegate.h"

#define SuppressPerformSelectorLeakWarning(Stuff) \
do { \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"") \
Stuff; \
_Pragma("clang diagnostic pop") \
} while (0)


@implementation SearchBarDataProvider {
	NSMutableArray * _actions;
	NSTimer * _actionBlockTimer;
	NSString * _searchTextBefore;
	TextFieldDelegate * _textFieldDelegate;
}

- (void)awakeFromNib {
	[super awakeFromNib];
	// observe and react to the keyboard
	_textFieldDelegate = [TextFieldDelegate.alloc init];
	_textFieldDelegate.viewController = self.viewController;
	[_textFieldDelegate awakeFromNib];
}

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
	
	if (_triggersActionOnInput) {
	}
	else {
		[self action];
		[self notifyObserversForKeyPath:@"contents.text"];
	}
	
	// Hide the keyboard
	[searchBar resignFirstResponder];

}

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
	
	// the iOS 7 cler button double-fires. we have to manually check.
	if ([searchText isEqualToString:_searchTextBefore]) return;
	_searchTextBefore = searchText;

	if (_triggersActionOnInput) {
		if ([searchText isEqualToString:@""]) [self action];
		else [self actionWithDelay];
		[self notifyObserversForKeyPath:@"contents.text"];
	}
}

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
	searchBar.text = @"";
	[self searchBar:searchBar textDidChange:@""];
	[searchBar resignFirstResponder];
}

- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
	[searchBar setShowsCancelButton:YES animated:YES];
	return YES;
}

- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar {
	[searchBar setShowsCancelButton:NO animated:YES];
	return YES;
}

- (id)valueForKeyPath:(NSString *)keyPath {
	if ([keyPath isEqualToString:@"contents.text"]) {
		return self.searchBar.text;
	}
	return [super valueForKeyPath:keyPath];
}

- (void)addTarget:(id)target action:(SEL)action forEvents:(NSString *)eventType {
	if (!target || !action) return;
	if (!_actions) _actions = @[].mutableCopy;
	[_actions addObject:@{ @"target": target, @"action": [NSValue valueWithPointer:action] }];
}

- (void)removeTarget:(id)target {
	for (NSDictionary * actionInfo in _actions.copy) {
		if ([actionInfo objectForKey:@"target"] == target) {
			[_actions removeObject:actionInfo];
		}
	}
}

- (void)actionWithDelay {
	if (_actionBlockTimer) return;
	_actionBlockTimer = [NSTimer scheduledTimerWithTimeInterval:.75 target:self selector:@selector(actionAfterDelay) userInfo:nil repeats:NO];
}

- (void)actionAfterDelay {
	_actionBlockTimer = nil;
	[self action];
}

- (void)action {
	for (NSDictionary * info in _actions) {
		id target = info[@"target"];
		SEL action = [info[@"action"] pointerValue];

SuppressPerformSelectorLeakWarning(
		[target performSelector:action withObject:self];
);
	}
}


- (void)setSearchBar:(UISearchBar *)searchBar {
	_searchBar = searchBar;
}

@end
