1//-----------------------------------------------------------------------------
2// Project     : VST SDK
3//
4// Category    : Helpers
5// Filename    : public.sdk/source/vst/interappaudio/PresetSaveViewController.mm
6// Created by  : Steinberg, 09/2013
7// Description : VST 3 InterAppAudio
8// Flags       : clang-format SMTGSequencer
9//
10//-----------------------------------------------------------------------------
11// LICENSE
12// (c) 2018, Steinberg Media Technologies GmbH, All Rights Reserved
13//-----------------------------------------------------------------------------
14// Redistribution and use in source and binary forms, with or without modification,
15// are permitted provided that the following conditions are met:
16//
17//   * Redistributions of source code must retain the above copyright notice,
18//     this list of conditions and the following disclaimer.
19//   * Redistributions in binary form must reproduce the above copyright notice,
20//     this list of conditions and the following disclaimer in the documentation
21//     and/or other materials provided with the distribution.
22//   * Neither the name of the Steinberg Media Technologies nor the names of its
23//     contributors may be used to endorse or promote products derived from this
24//     software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
34// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
35// OF THE POSSIBILITY OF SUCH DAMAGE.
36//-----------------------------------------------------------------------------
37
38#import "PresetSaveViewController.h"
39#import "pluginterfaces/base/funknown.h"
40
41//------------------------------------------------------------------------
42@interface PresetSaveViewController ()
43//------------------------------------------------------------------------
44{
45	IBOutlet UIView* containerView;
46	IBOutlet UITextField* presetName;
47
48	std::function<void (const char* presetPath)> callback;
49	Steinberg::FUID uid;
50}
51@end
52
53//------------------------------------------------------------------------
54@implementation PresetSaveViewController
55//------------------------------------------------------------------------
56
57//------------------------------------------------------------------------
58- (id)initWithCallback:(std::function<void (const char* presetPath)>)_callback
59{
60	self = [super initWithNibName:@"PresetSaveView" bundle:nil];
61	if (self)
62	{
63		callback = _callback;
64
65		self.modalPresentationStyle = UIModalPresentationOverCurrentContext;
66		self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
67
68		UIViewController* rootViewController =
69		    [[UIApplication sharedApplication].windows[0] rootViewController];
70
71		[rootViewController presentViewController:self
72		                                 animated:YES
73		                               completion:^{ [self showKeyboard]; }];
74	}
75	return self;
76}
77
78//------------------------------------------------------------------------
79- (void)viewDidLoad
80{
81	[super viewDidLoad];
82
83	containerView.layer.shadowOpacity = 0.5;
84	containerView.layer.shadowOffset = CGSizeMake (5, 5);
85	containerView.layer.shadowRadius = 5;
86}
87
88//------------------------------------------------------------------------
89- (void)showKeyboard
90{
91	[presetName becomeFirstResponder];
92}
93
94//------------------------------------------------------------------------
95- (void)removeSelf
96{
97	[self dismissViewControllerAnimated:YES completion:^{}];
98}
99
100//------------------------------------------------------------------------
101- (NSURL*)presetURL
102{
103	NSFileManager* fs = [NSFileManager defaultManager];
104	NSURL* documentsUrl = [fs URLForDirectory:NSDocumentDirectory
105	                                 inDomain:NSUserDomainMask
106	                        appropriateForURL:Nil
107	                                   create:YES
108	                                    error:NULL];
109	if (documentsUrl)
110	{
111		NSURL* presetPath = [[documentsUrl URLByAppendingPathComponent:presetName.text]
112		    URLByAppendingPathExtension:@"vstpreset"];
113		return presetPath;
114	}
115	return nil;
116}
117
118//------------------------------------------------------------------------
119- (BOOL)textFieldShouldReturn:(UITextField*)textField
120{
121	if ([textField.text length] > 0)
122	{
123		[self save:textField];
124		return YES;
125	}
126	return NO;
127}
128
129//------------------------------------------------------------------------
130- (IBAction)save:(id)sender
131{
132	if (callback)
133	{
134		NSURL* presetPath = [self presetURL];
135		NSFileManager* fs = [NSFileManager defaultManager];
136		if ([fs fileExistsAtPath:[presetPath path]])
137		{
138			// alert for overwrite
139			auto alertController = [UIAlertController
140			    alertControllerWithTitle:NSLocalizedString (
141			                                 @"A Preset with this name already exists",
142			                                 "Alert title")
143			                     message:NSLocalizedString (@"Save it anyway ?", "Alert message")
144			              preferredStyle:UIAlertControllerStyleAlert];
145			[alertController
146			    addAction:[UIAlertAction
147			                  actionWithTitle:NSLocalizedString (@"Save", "Alert Save Button")
148			                            style:UIAlertActionStyleDefault
149			                          handler:^(UIAlertAction* _Nonnull action) {
150				                        callback ([[[self presetURL] path] UTF8String]);
151				                        [self removeSelf];
152			                          }]];
153			[alertController
154			    addAction:[UIAlertAction
155			                  actionWithTitle:NSLocalizedString (@"Cancel", "Alert Cancel Button")
156			                            style:UIAlertActionStyleCancel
157			                          handler:^(UIAlertAction* _Nonnull action) {}]];
158			[self presentViewController:alertController animated:YES completion:nil];
159			return;
160		}
161		callback ([[presetPath path] UTF8String]);
162	}
163	[self removeSelf];
164}
165
166//------------------------------------------------------------------------
167- (IBAction)cancel:(id)sender
168{
169	if (callback)
170	{
171		callback (nullptr);
172	}
173	[self removeSelf];
174}
175
176//------------------------------------------------------------------------
177- (BOOL)prefersStatusBarHidden
178{
179	return YES;
180}
181
182@end
183