1/*
2 * Copyright 2019-2019 Attila Kocsis. All rights reserved.
3 * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
4 */
5
6#include "entry_p.h"
7#if BX_PLATFORM_OSX
8
9#include <bx/allocator.h>
10#include <bx/filepath.h>
11#include <bx/string.h>
12#include <bx/readerwriter.h>
13#include <bx/process.h>
14#include <bx/semaphore.h>
15
16#import <AppKit/AppKit.h>
17
18#include "dialog.h"
19
20class Split
21{
22public:
23	Split(const bx::StringView& _str, char _ch)
24	: m_str(_str)
25	, m_token(_str.getPtr(), bx::strFind(_str, _ch).getPtr() )
26	, m_ch(_ch)
27	{
28	}
29
30	bx::StringView next()
31	{
32		bx::StringView result = m_token;
33		m_token = bx::strTrim(
34							  bx::StringView(m_token.getTerm()+1
35											 , bx::strFind(bx::StringView(m_token.getTerm()+1, m_str.getTerm() ), m_ch).getPtr() )
36							  , " \t\n"
37							  );
38		return result;
39	}
40
41	bool isDone() const
42	{
43		return m_token.isEmpty();
44	}
45
46private:
47	const bx::StringView& m_str;
48	bx::StringView m_token;
49	char m_ch;
50};
51
52
53bool openFileSelectionDialog(
54							 bx::FilePath& _inOutFilePath
55							 , FileSelectionDialogType::Enum _type
56							 , const bx::StringView& _title
57							 , const bx::StringView& _filter
58							 )
59{
60	NSMutableArray* fileTypes = [NSMutableArray arrayWithCapacity:10];
61	bx::Error err;
62
63	for (bx::LineReader lr(_filter); !lr.isDone() && err.isOk();)
64	{
65		const bx::StringView line = lr.next();
66		const bx::StringView sep  = bx::strFind(line, '|');
67
68		if (!sep.isEmpty() )
69		{
70			for (Split split(bx::strTrim(bx::StringView(sep.getPtr()+1, line.getTerm() ), " "), ' '); !split.isDone() && err.isOk();)
71			{
72				const bx::StringView token = split.next();
73
74				if ( token.getLength() >= 3 && token.getPtr()[0] == '*'
75					&& token.getPtr()[1] == '.' && bx::isAlphaNum(token.getPtr()[2]) )
76				{
77					NSString* extension = [[NSString alloc] initWithBytes:token.getPtr()+2 length:token.getLength()-2 encoding:NSASCIIStringEncoding];
78					[fileTypes addObject: extension];
79				}
80			}
81		}
82	}
83
84	__block NSString* fileName = nil;
85	bx::Semaphore semaphore;
86	bx::Semaphore* psemaphore = &semaphore;
87
88	CFRunLoopPerformBlock([[NSRunLoop mainRunLoop] getCFRunLoop],
89						  kCFRunLoopCommonModes,
90				    ^{
91						NSSavePanel* panel = nil;
92
93						if ( FileSelectionDialogType::Open == _type)
94						{
95							NSOpenPanel* openPanel = [NSOpenPanel openPanel];
96							openPanel.canChooseFiles = TRUE;
97							openPanel.allowsMultipleSelection = FALSE;
98							openPanel.canChooseDirectories = FALSE;
99							panel = openPanel;
100						}
101						else
102						{
103							panel = [NSSavePanel savePanel];
104						}
105
106						panel.message = [[NSString alloc] initWithBytes:_title.getPtr() length:_title.getLength() encoding:NSASCIIStringEncoding];
107						panel.directoryURL = [NSURL URLWithString:@(_inOutFilePath.getCPtr())];
108						panel.allowedFileTypes = fileTypes;
109
110						if ([panel runModal] == NSModalResponseOK)
111						{
112							NSURL* url = [panel URL];
113							if (nil != url)
114							{
115								fileName = [url path];
116								[fileName retain];
117							}
118					   	}
119						[panel close];
120						psemaphore->post();
121				   });
122
123	semaphore.wait();
124
125	if ( fileName != nil )
126	{
127		_inOutFilePath.set([fileName UTF8String]);
128		[fileName release];
129		return true;
130	}
131
132	return false;
133}
134
135#endif
136