//******************************************************************************
//
// MIDITrail / MTMIDIOUTCfgDlg
//
// MIDI出力設定ダイアログ
//
// Copyright (C) 2010-2019 WADA Masashi. All Rights Reserved.
//
//******************************************************************************

#import "MTParam.h"
#import "MTMIDIOUTCfgDlg.h"
#import "MTSecurityScopedBookmark.h"

@implementation MTMIDIOUTCfgDlg

//******************************************************************************
// 生成
//******************************************************************************
- (id)init
{
	m_pWavetableFileURL = nil;
	
	//Nibファイルを指定してウィンドウコントローラを生成
	return [super initWithWindowNibName:@"MIDIOUTCfgDlg"];
}

//******************************************************************************
// 破棄
//******************************************************************************
- (void)dealloc
{
	[m_pUserConf release];
	[m_pUserConfWavetable release];
	[m_pWavetableFileURL release];
	[super dealloc];
}

//******************************************************************************
// ウィンドウ読み込み完了
//******************************************************************************
- (void)windowDidLoad
{
	int result = 0;
	
	//ウィンドウ表示項目初期化
	//  モーダル終了後に再度モーダル表示してもwindowDidLoadは呼び出されない
	result = [self initDlg];
	if (result != 0) goto EXIT;
	
EXIT:;
	if (result != 0) YN_SHOW_ERR();
}

//******************************************************************************
// モーダルウィンドウ表示
//******************************************************************************
- (void)showModalWindow
{	
	//モーダルウィンドウ表示
	[NSApp runModalForWindow:[self window]];
	
	//モーダル表示終了後はウィンドウを非表示にする
	[[self window] orderOut:self];
}

//******************************************************************************
// Wavetableファイル選択ボタン押下
//******************************************************************************
- (IBAction)onBtnWavetableFileBrowse:(id)sender
{
	int result = 0;
	NSOpenPanel* pOpenPanel = nil;
	NSString* pWavetableFilePath = nil;
	NSInteger btn = 0;
	NSArray* pFileTypes = nil;
	
	//ファイル選択パネル生成
	pOpenPanel = [NSOpenPanel openPanel];
	if (pOpenPanel == nil) {
		result = YN_SET_ERR(@"Program error.", 0, 0);
		goto EXIT;
	}
	
	//選択対象のファイル種別
	pFileTypes = [NSArray arrayWithObjects:@"dls", @"sf2", nil];
	
	//ファイル選択パネル表示
	[pOpenPanel setAllowedFileTypes:pFileTypes];
	btn = [pOpenPanel runModal];
	
	//ファイル選択時の処理
	if (btn == NSOKButton) {
		//エディットボックスに選択されたファイルのパスを設定
		pWavetableFilePath = [[pOpenPanel URL] path];
		[m_pEditWavetableFilePath setStringValue:pWavetableFilePath];
		
		m_pWavetableFileURL = [pOpenPanel URL];
		[m_pWavetableFileURL retain];
	}
	
EXIT:;
	if (result != 0) YN_SHOW_ERR();
	return;
}

//******************************************************************************
// Wavetableファイルクリアボタン押下
//******************************************************************************
- (IBAction)onBtnWavetableFileClear:(id)sender
{
	int result = 0;
	
	[m_pEditWavetableFilePath setStringValue:@""];
	
	[m_pWavetableFileURL release];
	m_pWavetableFileURL = nil;
	
EXIT:;
	if (result != 0) YN_SHOW_ERR();
	return;
}

//******************************************************************************
// OKボタン押下
//******************************************************************************
- (IBAction)onOK:(id)sender
{
	int result = 0;
	
	//設定保存
	result = [self save];
	if (result != 0) goto EXIT;
	
EXIT:;
	if (result != 0) YN_SHOW_ERR();
	//モーダル表示終了
	[NSApp stopModal];
}

//******************************************************************************
// Cancelボタン押下：またはESCキー押下
//******************************************************************************
- (IBAction)onCancel:(id)sender
{
	//モーダル表示終了
	[NSApp stopModal];
}

//******************************************************************************
// クローズボタン押下
//******************************************************************************
- (void)windowWillClose:(NSNotification*)aNotification
{
	//モーダル表示終了
	[NSApp stopModal];	
}

//******************************************************************************
// ダイアログ初期化
//******************************************************************************
- (int)initDlg
{
	int result = 0;
	
	//設定ファイル初期化
	result = [self initConfFile];
	if (result != 0) goto EXIT;
	
	//MIDI出力デバイス制御の初期化
	result = m_MIDIOutDevCtrl.Initialize();
	if (result != 0) goto EXIT;
	
	//MIDI出力デバイス選択ポップアップボタン初期化
	result = [self initPopUpButton:m_pPopUpBtnPortA portName:@"PortA"];
	if (result != 0) goto EXIT;
	result = [self initPopUpButton:m_pPopUpBtnPortB portName:@"PortB"];
	if (result != 0) goto EXIT;
	result = [self initPopUpButton:m_pPopUpBtnPortC portName:@"PortC"];
	if (result != 0) goto EXIT;
	result = [self initPopUpButton:m_pPopUpBtnPortD portName:@"PortD"];
	if (result != 0) goto EXIT;
	result = [self initPopUpButton:m_pPopUpBtnPortE portName:@"PortE"];
	if (result != 0) goto EXIT;
	result = [self initPopUpButton:m_pPopUpBtnPortF portName:@"PortF"];
	if (result != 0) goto EXIT;
	
	//Wavetableファイルパス初期化
	result = [self initWavetableFilePath];
	if (result != 0) goto EXIT;
	
EXIT:;
	return result;
}

//******************************************************************************
// ポップアップボタン初期化
//******************************************************************************
- (int)initPopUpButton:(NSPopUpButton*)pPopUpButton portName:(NSString*)pPortName
{
	int result = 0;
	unsigned int index = 0;
	NSInteger itemIndex = 0;
	NSInteger selectedIndex = 0;
	NSString* pSelectedDevIDname = nil;
	NSString* pDevIDname = nil;
	NSString* pDevDisplayName = nil;
	NSMenu* pMenu = nil;
	NSMenuItem* pItem = nil;
	
	//ユーザ選択デバイス識別名取得
	pSelectedDevIDname = [m_pUserConf strValueForKey:pPortName defaultValue:@""];
	
	//ユーザ選択デバイスがない場合は「選択なし」を選択状態にする
	if ([pSelectedDevIDname isEqual:@""]) {
		selectedIndex = 0;
	}
	
	//メニュー生成
	pMenu = [[[NSMenu alloc] initWithTitle:@"Port A"] autorelease];
	
	//メニュー項目「選択なし」をメニューに追加
	pItem = [[NSMenuItem alloc] initWithTitle:@"(none)" action:nil keyEquivalent:@""];
	[pItem setTag:index];
	[pMenu addItem:pItem];
	[pItem release];
	itemIndex++;
	
	for (index = 0; index < m_MIDIOutDevCtrl.GetDevNum(); index++) {
		//表示デバイス名をメニューに追加
		pDevIDname = m_MIDIOutDevCtrl.GetDevIdName(index);
		pDevDisplayName = m_MIDIOutDevCtrl.GetDevDisplayName(index);
		pItem = [[NSMenuItem alloc] initWithTitle:pDevDisplayName action:nil keyEquivalent:@""];
		[pItem setTag:index];
		[pMenu addItem:pItem];
		[pItem release];
		if ([pSelectedDevIDname isEqual:pDevIDname]) {
			selectedIndex = itemIndex;
		}
		itemIndex++;
	}
	
	//メニューをポップアップボタンに登録
	[pPopUpButton setMenu:pMenu];
	//	[pMenu release];
	//リリースするとdeallocで落ちる
	
	//選択状態設定
	[pPopUpButton selectItemAtIndex:selectedIndex];
	
	//同期
	[pPopUpButton synchronizeTitleAndSelectedItem];
	
EXIT:;
	return result;
}

//******************************************************************************
// 設定ファイル初期化
//******************************************************************************
- (int)initConfFile
{
	int result = 0;
	
	//ユーザ設定情報初期化
	[m_pUserConf release];
	m_pUserConf = [[YNUserConf alloc] init];
	if (m_pUserConf == nil) {
		YN_SET_ERR(@"Could not allocate memory.", 0, 0);
		goto EXIT;
	}
	//カテゴリ／セクション設定
	[m_pUserConf setCategory:MT_CONF_CATEGORY_MIDI];
	[m_pUserConf setSection:MT_CONF_SECTION_MIDIOUT];
	
	//ユーザ設定情報初期化：Wavetable用
	[m_pUserConfWavetable release];
	m_pUserConfWavetable = [[YNUserConf alloc] init];
	if (m_pUserConfWavetable == nil) {
		YN_SET_ERR(@"Could not allocate memory.", 0, 0);
		goto EXIT;
	}
	//カテゴリ／セクション設定
	[m_pUserConfWavetable setCategory:MT_CONF_CATEGORY_SYNTHESIZER];
	[m_pUserConfWavetable setSection:MT_CONF_SECTION_WAVETABLE];
	
EXIT:;
	return result;
}

//******************************************************************************
// Wavetableファイルパス初期化
//******************************************************************************
- (int)initWavetableFilePath
{
	int result = 0;
	NSString* pWavetableFilePath = nil;
	
	pWavetableFilePath = [m_pUserConfWavetable strValueForKey:@"WavetableFilePath" defaultValue:@""];
	[m_pEditWavetableFilePath setStringValue:pWavetableFilePath];
	
	return result;
}

//******************************************************************************
// 設定ファイル保存
//******************************************************************************
- (int)save
{
	int result = 0;
	
	//ポート設定保存
	result = [self savePortCfg:m_pPopUpBtnPortA portName:@"PortA"];
	if (result != 0) goto EXIT;
	result = [self savePortCfg:m_pPopUpBtnPortB portName:@"PortB"];
	if (result != 0) goto EXIT;
	result = [self savePortCfg:m_pPopUpBtnPortC portName:@"PortC"];
	if (result != 0) goto EXIT;
	result = [self savePortCfg:m_pPopUpBtnPortD portName:@"PortD"];
	if (result != 0) goto EXIT;
	result = [self savePortCfg:m_pPopUpBtnPortE portName:@"PortE"];
	if (result != 0) goto EXIT;
	result = [self savePortCfg:m_pPopUpBtnPortF portName:@"PortF"];
	if (result != 0) goto EXIT;
	
	//Wavetable設定保存
	result = [self saveWavetable];
	if (result != 0) goto EXIT;
	
EXIT:;
	return result;
}

//******************************************************************************
// ポート設定保存
//******************************************************************************
- (int)savePortCfg:(NSPopUpButton*)pPopUpBotton portName:(NSString*)pPortName
{
	int result = 0;
	NSInteger selectedIndex = 0;
	NSString* pDevIdName = nil;
	
	//選択された項目
	selectedIndex = [pPopUpBotton indexOfSelectedItem];
	
	//選択された項目に対応する識別用デバイス名
	if (selectedIndex == 0) {
		pDevIdName = @"";
	}
	else {
		pDevIdName = m_MIDIOutDevCtrl.GetDevIdName((unsigned int)(selectedIndex-1));
	}
	
	//設定保存
	[m_pUserConf setStr:pDevIdName forKey:pPortName];

EXIT:;
	return result;
}

//******************************************************************************
// Wavetable設定保存
//******************************************************************************
- (int)saveWavetable
{
	int result = 0;
	NSString* pWavetableFilePath = nil;
	
	//エディットボックスの値を取得
	pWavetableFilePath = [m_pEditWavetableFilePath stringValue];
	
	//設定保存
	[m_pUserConfWavetable setStr:pWavetableFilePath forKey:@"WavetableFilePath"];
	
	//Security Scoped Bookmark 保存
	//  URLはファイル選択パネルでファイル選択されたときのみオブジェクトが生成される
	//  ダイアログを開いて何もせずOKボタンが押されるケースもあるため
	//  URLのオブジェクトが存在するときのみ保存する
	if (m_pWavetableFileURL != nil) {
		result = MTSecurityScopedBookmark::SetBookmarkOfReadOnly(
						m_pWavetableFileURL,
						MT_CONF_SSBM_WAVETABLE_FILEURL
					);
		if (result != 0) goto EXIT;
	}
	
EXIT:;
	return result;
}

@end


