//******************************************************************************
//
// MIDITrail / MTGraphicCfgDlg
//
// グラフィック設定ダイアログ
//
// Copyright (C) 2010-2022 WADA Masashi. All Rights Reserved.
//
//******************************************************************************

#import "MTParam.h"
#import "MTGraphicCfgDlg.h"
#import "MTSecurityScopedBookmark.h"


//##############################################################################
// 四分音符長拡大率 テキストフィールドクラス（エディットボックス）
//##############################################################################
@implementation MTQuarterNoteLengthMagTextField

//******************************************************************************
// テキストフィールド編集終了前イベント
//******************************************************************************
- (BOOL)textShouldEndEditing:(NSText *)textObject
{
	BOOL isOK = NO;
	
	isOK = [self isCorrectValue:[textObject string]];
	if (!isOK) {
		NSBeep();
	}
	
	return isOK;
}

//******************************************************************************
// 文字列チェック
//******************************************************************************
- (BOOL)isCorrect
{
	BOOL isOK = NO;
	
	isOK = [self isCorrectValue:[self stringValue]];
	
	return isOK;
}

//******************************************************************************
// 指定文字列チェック（内部処理用）
//******************************************************************************
- (BOOL)isCorrectValue:(NSString*)pValue
{
	BOOL isOK = NO;
	NSInteger value = 0;
	NSString* pStrValue = nil;
	
	//数値文字列かつ範囲内であることを確認
	value = [pValue integerValue];
	pStrValue = [[NSNumber numberWithInt:(int)value] stringValue];
	if ([pValue isEqualToString:pStrValue]) {
		if ((value >= MT_QNOTE_LENGTH_MAG_MIN) && (value <= MT_QNOTE_LENGTH_MAG_MAX)) {
			isOK = YES;
		}
	}
	return isOK;
}

@end


//##############################################################################
// グラフィック設定ダイアログクラス
//##############################################################################
@implementation MTGraphicCfgDlg

//******************************************************************************
// 生成
//******************************************************************************
- (id)init
{
	m_isEnableAntialias = NO;
	m_SampleMode = 0;
	m_SampleNum = 0;
	m_pImageFilePath = nil;
	m_pImageFileURL = nil;
	m_QuarterNoteLengthMag = 100;
	
	//Nibファイルを指定してウィンドウコントローラを生成
	return [super initWithWindowNibName:@"GraphicCfgDlg"];
}

//******************************************************************************
// 破棄
//******************************************************************************
- (void)dealloc
{
	[m_pUserConf release];
	[m_pImageFilePath release];
	[m_pImageFileURL 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
{	
	m_isChanged = NO;
	
	//モーダルウィンドウ表示
	[NSApp runModalForWindow:[self window]];
	
	//モーダル表示終了後はウィンドウを非表示にする
	[[self window] orderOut:self];
}

//******************************************************************************
// 変更確認
//******************************************************************************
- (BOOL)isCahnged
{
	return m_isChanged;
}

//******************************************************************************
// 背景画像ファイル選択ボタン押下
//******************************************************************************
- (IBAction)onBtnImageFileBrowse:(id)sender
{
	int result = 0;
	NSOpenPanel* pOpenPanel = nil;
	NSString* pImageFilePath = 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:@"jpg", @"png", nil];
	
	//ファイル選択パネル表示
	[pOpenPanel setAllowedFileTypes:pFileTypes];
	btn = [pOpenPanel runModal];
	
	//ファイル選択時の処理
	if (btn == NSModalResponseOK) {
		//エディットボックスに選択されたファイルのパスを設定
		pImageFilePath = [[pOpenPanel URL] path];
		[m_pEditImageFilePath setStringValue:pImageFilePath];
		
		m_pImageFileURL = [pOpenPanel URL];
		[m_pImageFileURL retain];
	}
	
EXIT:;
	if (result != 0) YN_SHOW_ERR();
	return;
}

//******************************************************************************
// 背景画像ファイルクリアボタン押下
//******************************************************************************
- (IBAction)onBtnImageFileClear:(id)sender
{
	int result = 0;
	
	[m_pEditImageFilePath setStringValue:@""];
	
	[m_pImageFileURL release];
	m_pImageFileURL = nil;
	
EXIT:;
	if (result != 0) YN_SHOW_ERR();
	return;
}

//******************************************************************************
// OKボタン押下
//******************************************************************************
- (IBAction)onOK:(id)sender
{
	int result = 0;
	
	//エディットボックスの入力値確認
	if (![m_pEditQuarterNoteLengthMag isCorrect]) {
		//問題ありの場合はダイアログを閉じない
		NSBeep();
		goto EXIT;
	}
	
	//設定保存
	result = [self saveConfFile];
	if (result != 0) goto EXIT;
	
	//ダイアログを閉じる
	m_isChanged = YES;
	[NSApp stopModal];
	
EXIT:;
	if (result != 0) YN_SHOW_ERR();
	return;
}

//******************************************************************************
// 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;
	
	//ユーザ設定値読み込み
	[self loadConfFile];
	
	//レンダリング情報初期化
	result = m_RendererInfo.Initialize();
	if (result != 0) goto EXIT;
	
	//アンチエイリアスポップアップボタン初期化
	result = [self initPopUpButtonAntiAlias];
	if (result != 0) goto EXIT;
	
	//背景画像ファイルパス初期化
	result = [self initBackgroundImageFilePath];
	if (result != 0) goto EXIT;
	
	//四分音符設定初期化
	result = [self initQuarterNote];
	if (result != 0) goto EXIT;
	
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;
	}
	
EXIT:;
	return result;
}

//******************************************************************************
// 設定ファイル読み込み
//******************************************************************************
- (void)loadConfFile
{
	int enableAntialiasing = 0;
	
	//アンチエイリアス設定
	[m_pUserConf setCategory:MT_CONF_CATEGORY_GRAPHIC];
	[m_pUserConf setSection:MT_CONF_SECTION_AA];
	enableAntialiasing = [m_pUserConf intValueForKey:@"EnableAntialias" defaultValue:0];
	if (enableAntialiasing == 0) {
		m_isEnableAntialias = NO;
		m_SampleMode = OGLMultisampleBit;
		m_SampleNum = 1;
	}
	else {
		m_isEnableAntialias = YES;
		m_SampleMode = [m_pUserConf intValueForKey:@"SampleMode" defaultValue:OGLMultisampleBit];
		m_SampleNum = [m_pUserConf intValueForKey:@"SampleNum" defaultValue:1];
	}
	
	//背景画像設定
	[m_pUserConf setCategory:MT_CONF_CATEGORY_GRAPHIC];
	[m_pUserConf setSection:MT_CONF_SECTION_BGIMG];
	m_pImageFilePath = [m_pUserConf strValueForKey:@"ImageFilePath" defaultValue:@""];
	[m_pImageFilePath retain];
	
	//四分音符設定
	[m_pUserConf setCategory:MT_CONF_CATEGORY_GRAPHIC];
	[m_pUserConf setSection:MT_CONF_SECTION_QNOTE];
	m_QuarterNoteLengthMag = [m_pUserConf intValueForKey:@"LengthMagnification" defaultValue:100];
	
	return;
}

//******************************************************************************
// アンチエリアスポップアップボタン初期化
//******************************************************************************
- (int)initPopUpButtonAntiAlias
{
	int result = 0;
	unsigned int index = 0;
	unsigned int itemIndex = 0;
	unsigned int selectedIndex = 0;
	bool isSupportAA = false;
	NSMenu* pMenu = nil;
	NSMenuItem* pItem = nil;
	NSString* pItemStr = nil;
	NSString* pSampleModeName = nil;
	OGLAntialiasInfo antialiasInfo;
	
	//アンチエイリアシングサポート確認
	if (m_RendererInfo.GetAntialiasInfoNum() > 0) {
		isSupportAA = true;
	}
	
	//メニュー生成
	pMenu = [[[NSMenu alloc] initWithTitle:@"AntiAlias"] autorelease];
	
	//先頭項目を登録
	if (isSupportAA) {
		pItemStr = @"OFF";
	}
	else {
		pItemStr = @"Not supported";
	}
	pItem = [[NSMenuItem alloc] initWithTitle:pItemStr action:nil keyEquivalent:@""];
	[pItem setTag:0];
	[pMenu addItem:pItem];
	[pItem release];
	itemIndex++;
	
	//マルチサンプル種別を追加登録
	for (index = 0; index < m_RendererInfo.GetAntialiasInfoNum(); index++) {
		result = m_RendererInfo.GetAntialiasInfo(index, &antialiasInfo);
		if (result != 0) goto EXIT;
		
		if (antialiasInfo.sampleMode == OGLSupersampleBit) {
			pSampleModeName = @"Super-sample";
		}
		else if (antialiasInfo.sampleMode == OGLMultisampleBit) {
			pSampleModeName = @"Multi-sample";
		}
		else {
			pSampleModeName = @"UNKNOWN";
		}
		
		//マルチサンプリング種別をコンボボックスに追加
		pItemStr = [NSString stringWithFormat:@"%@ %dx", pSampleModeName, antialiasInfo.sampleNum];
		pItem = [[NSMenuItem alloc] initWithTitle:pItemStr action:nil keyEquivalent:@""];
		[pItem setTag:index];
		[pMenu addItem:pItem];
		[pItem release];
		
		if (m_isEnableAntialias
		  && (antialiasInfo.sampleMode == m_SampleMode)
		  && (antialiasInfo.sampleNum == m_SampleNum)) {
			selectedIndex = itemIndex;
		}
		itemIndex++;
	}
	
	//アンチエイリアスのユーザ設定値がサポートされていない場合はアンチエイリアスを無効にする
	if (m_isEnableAntialias && (selectedIndex == 0)) {
		m_isEnableAntialias = NO;
		m_SampleMode = OGLMultisampleBit;
		m_SampleNum = 1;
	}
	
	//メニューをポップアップボタンに登録
	[m_pPopUpBtnAntiAlias setMenu:pMenu];
	//	[pMenu release];
	//リリースするとdeallocで落ちる
	
	//選択状態設定
	[m_pPopUpBtnAntiAlias selectItemAtIndex:selectedIndex];
	
	//アンチエイリアシングをサポートしていなければ不活性にする
	if (!isSupportAA) {
		[m_pPopUpBtnAntiAlias setEnabled:NO];
	}
	
	//同期
	[m_pPopUpBtnAntiAlias synchronizeTitleAndSelectedItem];
	
EXIT:;
	return result;
}

//******************************************************************************
// 背景画像ファイルパス初期化
//******************************************************************************
- (int)initBackgroundImageFilePath
{
	int result = 0;
	
	[m_pEditImageFilePath setStringValue:m_pImageFilePath];
	
	return result;
}

//******************************************************************************
// 四分音符設定初期化
//******************************************************************************
- (int)initQuarterNote
{
	int result = 0;
	NSString* pStrMag = nil;
	
	pStrMag = [[NSNumber numberWithInt:m_QuarterNoteLengthMag] stringValue];
	[m_pEditQuarterNoteLengthMag setStringValue:pStrMag];
	
	return result;
}

//******************************************************************************
// 設定ファイル保存
//******************************************************************************
- (int)saveConfFile
{
	int result = 0;
	
	//アンチエイリアス設定保存
	result = [self saveAntiAlias];
	if (result != 0) goto EXIT;
	
	//背景画像設定保存
	result = [self saveBackgroundImage];
	if (result != 0) goto EXIT;
	
	//四分音符長拡大率保存
	result = [self saveQuarterNote];
	if (result != 0) goto EXIT;
	
EXIT:;
	return result;
}

//******************************************************************************
// アンチエイリアス設定保存
//******************************************************************************
- (int)saveAntiAlias
{
	int result = 0;
	NSInteger index = 0;
	NSInteger selectedIndex = 0;
	int enableAntialias = 0;
	NSMenuItem* pItem = nil;
	OGLAntialiasInfo antialiasInfo;
	
	//選択された項目
	selectedIndex = [m_pPopUpBtnAntiAlias indexOfSelectedItem];
	
	//選択された項目に対応するマルチサンプリング種別
	if (selectedIndex == 0) {
		m_isEnableAntialias = NO;
		m_SampleMode = OGLMultisampleBit;
		m_SampleNum = 1;
	}
	else {
		pItem = [m_pPopUpBtnAntiAlias selectedItem];
		if (pItem == nil) {
			result = YN_SET_ERR(@"Program error.", 0, 0);
			goto EXIT;
		}
		index = [pItem tag];
		result = m_RendererInfo.GetAntialiasInfo(index, &antialiasInfo);
		if (result != 0) goto EXIT;
		
		m_isEnableAntialias = YES;
		m_SampleMode = antialiasInfo.sampleMode;
		m_SampleNum = antialiasInfo.sampleNum;
	}
	
	//設定保存
	enableAntialias = 0;
	if (m_isEnableAntialias) {
		enableAntialias = 1;
	}
	[m_pUserConf setCategory:MT_CONF_CATEGORY_GRAPHIC];
	[m_pUserConf setSection:MT_CONF_SECTION_AA];
	[m_pUserConf setInt:enableAntialias forKey:@"EnableAntialias"];
	[m_pUserConf setInt:m_SampleMode forKey:@"SampleMode"];
	[m_pUserConf setInt:m_SampleNum forKey:@"SampleNum"];
	
EXIT:;
	return result;
}

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

//******************************************************************************
// 四分音符設定保存
//******************************************************************************
- (int)saveQuarterNote
{
	int result = 0;
	NSString* pStrMag = nil;
	
	//エディットボックスの値を取得
	pStrMag = [m_pEditQuarterNoteLengthMag stringValue];
	m_QuarterNoteLengthMag = (int)[pStrMag integerValue];
	
	//設定保存
	[m_pUserConf setCategory:MT_CONF_CATEGORY_GRAPHIC];
	[m_pUserConf setSection:MT_CONF_SECTION_QNOTE];
	[m_pUserConf setInt:m_QuarterNoteLengthMag forKey:@"LengthMagnification"];
	
EXIT:;
	return result;
}

@end


