1/**
2 *  HotkeyController.m
3 *  Pcsxr
4 *
5 *  Created by Nicolas Pepin-Perreault on 12-12-10.
6 *
7 * Adapted from the Cocoa port of DeSMuMe
8 */
9
10#import "HotkeyController.h"
11
12#define INPUT_HOLD_TIME		0.1
13
14@interface HotkeyController ()
15@property (strong) NSButton *lastConfigButton;
16@property (strong) NSMutableDictionary *hotkeysList;
17@property (strong) NSDictionary *keyNameTable;
18@property (strong) NSMutableDictionary *hotkeyOutlets;
19@end
20
21@implementation HotkeyController
22
23@synthesize FastForward;
24@synthesize FrameLimit;
25@synthesize LoadState;
26@synthesize NextState;
27@synthesize PrevState;
28@synthesize SaveState;
29
30- (void)initialize
31{
32	self.lastConfigButton = nil;
33	self.configInput = 0;
34	self.hotkeysList = [[NSMutableDictionary alloc] initWithCapacity:16];
35    self.keyNameTable = [[NSDictionary alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"KeyNames" ofType:@"plist"]];
36    self.hotkeyOutlets = [[NSMutableDictionary alloc] initWithCapacity:8];
37
38    [self mapOutletToIdentifier:FastForward forIdentifier:@"FastForward"];
39	[self mapOutletToIdentifier:SaveState forIdentifier:@"SaveState"];
40    [self mapOutletToIdentifier:LoadState forIdentifier:@"LoadState"];
41    [self mapOutletToIdentifier:NextState forIdentifier:@"NextState"];
42    [self mapOutletToIdentifier:PrevState forIdentifier:@"PrevState"];
43    [self mapOutletToIdentifier:FrameLimit forIdentifier:@"FrameLimit"];
44}
45
46- (void)dealloc
47{
48	[[NSNotificationCenter defaultCenter] removeObserver:self];
49}
50
51- (void)mapOutletToIdentifier:(id)outlet forIdentifier:(NSString*)identifier1
52{
53    (self.hotkeyOutlets)[identifier1] = outlet;
54    [self setHotkeyDisplay:identifier1];
55}
56
57- (void)setHotkeyDisplay:(NSString*)keyIdent
58{
59    NSString *label = [self parseMappingDisplayString:keyIdent];
60    NSTextField *displayField = (self.hotkeyOutlets)[keyIdent];
61
62    if(displayField) {
63        [displayField setStringValue:label];
64    }
65}
66
67- (void)mouseDown:(NSEvent *)theEvent
68{
69	BOOL isHandled = [self handleMouseDown:theEvent];
70	if (!isHandled)
71	{
72		[super mouseDown:theEvent];
73	}
74}
75
76- (void)mouseDragged:(NSEvent *)theEvent
77{
78	[self mouseDown:theEvent];
79}
80
81- (void)rightMouseDown:(NSEvent *)theEvent
82{
83	BOOL isHandled = [self handleMouseDown:theEvent];
84	if (!isHandled)
85	{
86		[super rightMouseDown:theEvent];
87	}
88}
89
90- (void)rightMouseDragged:(NSEvent *)theEvent
91{
92	[self rightMouseDown:theEvent];
93}
94
95- (void)otherMouseDown:(NSEvent *)theEvent
96{
97	BOOL isHandled = [self handleMouseDown:theEvent];
98	if (!isHandled)
99	{
100		[super otherMouseDown:theEvent];
101	}
102}
103
104- (void)otherMouseDragged:(NSEvent *)theEvent
105{
106	[self otherMouseDown:theEvent];
107}
108
109- (BOOL) handleMouseDown:(NSEvent *)mouseEvent
110{
111	if (self.configInput != 0)
112	{
113		[self hotkeyCancel];
114	}
115
116	return YES;
117}
118
119- (void)keyDown:(NSEvent *)theEvent
120{
121	NSString *keyCode = [NSString stringWithFormat:@"%d", [theEvent keyCode]];
122	NSString *keyLabel = (NSString *) (self.keyNameTable)[keyCode];
123
124	if (self.configInput != 0)
125	{
126		// Save input
127        NSString *ident = [self.lastConfigButton identifier];
128        [self saveHotkey:ident device:@"NSEventKeyboard" deviceLabel:@"Keyboard" code:keyCode label:keyLabel];
129        [self setHotkeyDisplay:ident];
130		[self hotkeyCancel];
131	}
132}
133
134- (void)saveHotkey:(NSString*)keyIdent device:(NSString*)device deviceLabel:(NSString*)deviceLabel code:(NSString*)keyCode label:(NSString*)keyLabel
135{
136    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults] ;
137	NSMutableDictionary *tempUserMappings = [NSMutableDictionary dictionaryWithDictionary:[defaults dictionaryForKey:@"HotkeyBindings"]];
138	[tempUserMappings setValue:@{@"device": device,
139								 @"deviceName": deviceLabel,
140								 @"keyCode": keyCode,
141								 @"keyLabel": keyLabel} forKey:keyIdent];
142	[defaults setValue:tempUserMappings forKey:@"HotkeyBindings"];
143}
144
145- (NSString *) parseMappingDisplayString:(NSString *)keyString
146{
147	NSDictionary *userMappings = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"HotkeyBindings"];
148	NSDictionary *binding = (NSDictionary *)[userMappings valueForKey:keyString];
149
150    NSString *displayString = @"";
151    if(binding) {
152        NSString *deviceLabel = (NSString *)[binding valueForKey:@"deviceName"];
153        NSString *keyLabel = (NSString *)[binding valueForKey:@"keyLabel"];
154
155        displayString = [NSString stringWithString:deviceLabel];
156        displayString = [displayString stringByAppendingString:@": "];
157        displayString = [displayString stringByAppendingString:keyLabel];
158	}
159
160	return displayString;
161}
162
163- (IBAction) hotkeySet:(id)sender
164{
165	NSButton *theButton = (NSButton *)sender;
166
167	if (self.configInput && self.lastConfigButton != theButton)
168	{
169		[self.lastConfigButton setState:NSOffState];
170	}
171
172	if ([theButton state] == NSOnState)
173	{
174		self.lastConfigButton = theButton;
175		[self.hotkeysList removeAllObjects];
176		self.configInput = [theButton tag];
177	}
178	else
179	{
180		[self hotkeyCancel];
181	}
182
183}
184
185- (void) hotkeyCancel
186{
187	if (self.lastConfigButton != nil)
188	{
189		[self.lastConfigButton setState:NSOffState];
190		self.lastConfigButton = nil;
191	}
192
193	self.configInput = 0;
194}
195
196- (BOOL)acceptsFirstResponder
197{
198	return YES;
199}
200
201- (BOOL)becomeFirstResponder
202{
203	return YES;
204}
205
206- (BOOL)resignFirstResponder
207{
208	return YES;
209}
210
211@end
212