//******************************************************************************
//
// MIDITrail / MTMainWindowCtrl
//
// メインウィンドウ制御クラス
//
// Copyright (C) 2010-2022 WADA Masashi. All Rights Reserved.
//
//******************************************************************************

#import "YNBaseLib.h"
#import "MTMainWindowCtrl.h"


@implementation MTMainWindowCtrl

//******************************************************************************
// 生成
//******************************************************************************
- (id)init
{
	//nib読み込み
	self = [super initWithWindowNibName:@"MainWindow"];
	if (self == nil) goto EXIT;
	
	//タイマー開始
	m_pTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
												target:self
											  selector:@selector(timerControl:)
											  userInfo:nil
											   repeats:YES];
	
	m_isAppTermOnClose = YES;
	m_isCenter = YES;
	m_pWindowTitle = @"MIDITrail";
	
EXIT:;
	return self;
}

//******************************************************************************
// 破棄
//******************************************************************************
- (void)dealloc
{
	//NSLog(@"MTMainWindowCtrl dealloc");
	[m_pView release];
	[[self window] setContentView:nil];
	[m_pTimer invalidate];
	[super dealloc];
}

//******************************************************************************
// メインビュー生成
//******************************************************************************
- (int)createMainViewWithRendererParam:(OGLRedererParam)rendererParam
{
	int result = 0;
	NSRect rect;
	
	rect = [[self window] contentRectForFrameRect:[[self window] frame]];
	rect.origin.x = 0;
	rect.origin.y = 0;
	
	//メインビュー生成
	m_pView = [[MTMainView alloc] initWithFrame:rect
								  rendererParam:rendererParam];
	if (m_pView == nil) {
		result = YN_SET_ERR(@"Program error.", 0, 0);
		goto EXIT;
	}
	
	//ウィンドウにビューを登録
	[[self window] setContentView:m_pView];
	[m_pView setAutoresizesSubviews:NO];
	
EXIT:;
	return result;
}

//******************************************************************************
// メインビュー破棄
//******************************************************************************
- (void)deleteMainView
{
	//メインビュー破棄
	[m_pView terminate];
	[m_pView release];
	m_pView = nil;
	
	//ウィンドウのビュー登録を解除
	[[self window] setContentView:nil];
	
	m_pView = nil;
}

//******************************************************************************
// メインビュー取得
//******************************************************************************
- (MTMainView*)mainView
{
	return m_pView;
}

//******************************************************************************
// ウィンドウサイズ設定
//******************************************************************************
- (void)setWindowSize:(NSSize)size isApplyToViewArea:(bool)isApplyToViewArea;
{
	NSRect newWindowRect;
	NSRect curWindowFrame;
	NSRect curViewFrame;
	int framew = 0;
	int frameh = 0;
	
	//ウィドウのフレーム情報
	curWindowFrame = [[self window] frame];
	
	//クライアント領域のフレーム情報
	curViewFrame = [[[self window] contentView] frame];
	
	//枠のサイズ
	frameh = curWindowFrame.size.height - curViewFrame.size.height;
	framew = curWindowFrame.size.width - curViewFrame.size.width;
	
	//ウィンドウサイズ変更後のフレームサイズ
	newWindowRect.size.width = size.width;
	newWindowRect.size.height = size.height;
	
	//クライアント領域に指定サイズを適応する場合
	if (isApplyToViewArea) {
		newWindowRect.size.width = size.width + framew;
		newWindowRect.size.height = size.height + frameh;
	}
	
	//ウィンドウサイズ変更後のフレーム位置（スクリーン左下が原点）
	//  左辺の位置は変更しない
	//  上辺の位置を変更しないように下辺の位置を算出する
	newWindowRect.origin.x = curWindowFrame.origin.x;
	newWindowRect.origin.y = curWindowFrame.origin.y + (curWindowFrame.size.height - size.height);
	
	//ウィンドウサイズ設定：タイトルバーのサイズを含む
	[[self window] setFrame:newWindowRect display:YES animate:YES];
}

//******************************************************************************
// ウィンドウ位置設定
//******************************************************************************
- (void)setWindowPosition:(NSPoint)position
{
	NSRect screenRect;
	NSRect newRect;
	NSRect curFrame;
	
	//スクリーンのフレーム情報
	screenRect = [[NSScreen mainScreen] frame];
	
	//現在のフレーム情報
	curFrame = [[self window] frame];
	
	//ウィンドウ位置変更後のフレーム情報（スクリーン左下が原点）
	//  ウィンドウサイズは変更しない
	newRect.size.width = curFrame.size.width;
	newRect.size.height = curFrame.size.height;
	newRect.origin.x = position.x;
	newRect.origin.y = screenRect.size.height - position.y - curFrame.size.height;
	
	//ウィンドウサイズ設定：タイトルバーのサイズを含む
	[[self window] setFrame:newRect display:YES animate:YES];
	
	m_isCenter = NO;
}

//******************************************************************************
// ウィンドウタイトル設定
//******************************************************************************
- (void)setWindowTitle:(NSString*)pTitle
{
	[m_pWindowTitle release];
	m_pWindowTitle = pTitle;
	[m_pWindowTitle retain];
	
	[[self window] setTitle:m_pWindowTitle];
}

//******************************************************************************
//ウィンドウ表示
//******************************************************************************
- (void)showWindow
{
	//スクリーン中央に移動
	if (m_isCenter) {
		[self setPositionToCenterOfScreen];
	}
	
	//ウィンドウ表示
	[self showWindow:nil];
}

//******************************************************************************
// スクリーン中央に移動
//******************************************************************************
- (void)setPositionToCenterOfScreen
{
	NSPoint origin;
	NSRect screenRect;
	NSRect rect;
	
	//スクリーンのフレーム情報
	screenRect = [[NSScreen mainScreen] frame];
	
	//自ウィンドウの表示位置
	rect = [[self window] frame];
	
	//自ウィンドウの位置を算出：画面左下が原点
	origin.x = screenRect.origin.x + ((screenRect.size.width - rect.size.width) / 2);
	origin.y = screenRect.origin.y + ((screenRect.size.height - rect.size.height) / 2);
	
	//自ウィンドウの表示原点を設定
	[[self window] setFrameOrigin:origin];
}

//******************************************************************************
// タイマー処理
//******************************************************************************
- (void)timerControl:(NSTimer*)aTimer
{
	NSString* pTitle = nil;
	
	//ウィンドウタイトルにFPSを表示
	if (m_pView == nil) {
		pTitle = m_pWindowTitle;
	}
	else {
		pTitle = [NSString stringWithFormat:@"%@ - FPS:%.1f", m_pWindowTitle, [m_pView FPS]];
	}
	[[self window] setTitle:pTitle];
}

//******************************************************************************
// ウィンドウクローズ
//******************************************************************************
- (void)close
{
	m_isAppTermOnClose = NO;
	[super close];
}

//******************************************************************************
// クローズボタン押下
//******************************************************************************
- (void)windowWillClose:(NSNotification*)aNotification
{
	//アプリケーション終了
	if (m_isAppTermOnClose) {
		[NSApp terminate:self];
	}
}

//******************************************************************************
// フルスクリーン切り替え
//******************************************************************************
- (void)toggleFullScreen
{
	[[self window] toggleFullScreen:self];
	
	return;
}

//******************************************************************************
// フルスクリーン開始直前
//******************************************************************************
- (void)windowWillEnterFullScreen:(NSNotification *)notification
{
	NSRect fullscreenFrame;
	
	NSLog(@"windowWillEnterFullScreen start");
	
	m_WindowFrame = [[self window] frame];
	
	//シーン一時停止
	[m_pView pauseScene];
	
	//フレーム設定
	fullscreenFrame = [[NSScreen mainScreen] frame];
	[[self window] setFrame:fullscreenFrame display:true];
	
	//ビューポート更新
	[m_pView enterFullScreen];
	
	NSLog(@"windowWillEnterFullScreen end");
	
	return;
}

//******************************************************************************
// フルスクリーン開始直後
//******************************************************************************
- (void)windowDidEnterFullScreen:(NSNotification *)notification
{
	NSRect fullscreenFrame;
	
	NSLog(@"windowDidEnterFullScreen start");
	
	//フレーム設定
	fullscreenFrame = [[NSScreen mainScreen] frame];
	[[self window] setFrame:fullscreenFrame display:true];
	
	//ビューポート更新
	[m_pView enterFullScreen];
	
	//フルスクリーン変更通知
	[self sendFullScreenNotification];
	
	//シーン再開
	[m_pView resumeScene];
	
	NSLog(@"windowDidEnterFullScreen end");
	return;
}

//******************************************************************************
// フルスクリーン終了直前
//******************************************************************************
- (void)windowWillExitFullScreen:(NSNotification *)notification
{
	NSLog(@"windowWillExitFullScreen start");
	
	//シーン一時停止
	[m_pView pauseScene];
	
	//フレーム設定
	[[self window] setFrame:m_WindowFrame display:true];
	
	//ビューポート更新
	[m_pView exitFullScreen];
	
	NSLog(@"windowWillExitFullScreen end");
	return;
}

//******************************************************************************
// フルスクリーン終了直後
//******************************************************************************
- (void)windowDidExitFullScreen:(NSNotification *)notification
{
	NSLog(@"windowDidExitFullScreen start");
	
	//フレーム設定
	[[self window] setFrame:m_WindowFrame display:true];
	
	//ビューポート更新
	[m_pView exitFullScreen];
	
	//フルスクリーン変更通知
	[self sendFullScreenNotification];
	
	//シーン再開
	[m_pView resumeScene];
	
	NSLog(@"windowDidExitFullScreen end");
	return;
}

//******************************************************************************
// フルスクリーン変更通知送信
//******************************************************************************
- (void)sendFullScreenNotification
{
	NSNotification* pNotification = nil;
	NSNotificationCenter* pCenter = nil;
	
	//通知オブジェクトを作成
	pNotification = [NSNotification notificationWithName:@"onToggleFullScreen"
												  object:self
												userInfo:nil];
	
	//通知に対応する処理をメインスレッドに処理させる
	pCenter = [NSNotificationCenter defaultCenter];
	[pCenter performSelectorOnMainThread:@selector(postNotification:)
							  withObject:pNotification
						   waitUntilDone:NO];
	
	return;
}

//******************************************************************************
// フルスクリーン状態確認
//******************************************************************************
- (bool)isFullScreen
{
	bool isResult = false;
	
	if ( [[self window] styleMask] & NSWindowStyleMaskFullScreen) {
		isResult = true;
	}
	
	return isResult;
}

@end


