//******************************************************************************
//
// MIDITrail / MTSettingViewCtrl
//
// 設定画面制御クラス
//
// Copyright (C) 2012-2019 WADA Masashi. All Rights Reserved.
//
//******************************************************************************

#import "MTSettingViewCtrl.h"
#import "MTParam.h"
#import <QuartzCore/QuartzCore.h>


//******************************************************************************
// プライベートメソッド定義
//******************************************************************************
@interface MTSettingViewCtrl ()

//テーブルセル作成：表示項目
- (UITableViewCell*)makeDisplayItemCellForIndexPath:(NSIndexPath*)indexPath;

//テーブルセル作成：MIDI OUT Device
- (UITableViewCell*)makeMIDIOUTCellForIndexPath:(NSIndexPath*)indexPath;

//テーブルセル作成：MIDI IN Device
- (UITableViewCell*)makeMIDIINCellForIndexPath:(NSIndexPath*)indexPath;

//テーブルセル作成：MIDI IN Device / Port A
- (UITableViewCell*)makeMIDIINCellForPortA;

//テーブルセル作成：MIDI IN Device / MIDI THRU
- (UITableViewCell*)makeMIDIINCellForMIDITHRU;

//テーブルセル作成：Internal Wavetable Synthsizer
- (UITableViewCell*)makeInternalSynthsizerCellForIndexPath:(NSIndexPath*)indexPath;

//テーブルセル作成：MIDI File
- (UITableViewCell*)makeMIDIFileCellForIndexPath:(NSIndexPath*)indexPath;

//テーブルセル作成：Graphic
- (UITableViewCell*)makeGraphicCellForIndexPath:(NSIndexPath*)indexPath;

// テーブルセル作成：Graphic / アンチエイリアシング
- (UITableViewCell*)makeGraphicCellForAntiAliaasing;

// テーブルセル作成：Graphic / 背景画像ファイル
- (UITableViewCell*)makeGraphicCellForBackgroundImage;

// テーブルセル作成：Graphic / 四分音符長拡大率
- (UITableViewCell*)makeGraphicCellForNoteLength;

//テーブルセル作成：Game Controller
- (UITableViewCell*)makeGameControllerCellForIndexPath:(NSIndexPath*)indexPath;

//テーブルセル選択イベント：ビューモード
- (void)onSelectViewModeCellForIndexPath:(NSIndexPath*)indexPath;

//テーブルセル選択イベント：表示項目
- (void)onSelectDisplayItemCellForIndexPath:(NSIndexPath*)indexPath;

//テーブルセル選択イベント：MIDI OUT Device
- (void)onSelectMIDIOUTCellForIndexPath:(NSIndexPath*)indexPath;

//テーブルセル選択イベント：Internal Synthesizer
- (void)onSelectInternalSynthesizerCellForIndexPath:(NSIndexPath*)indexPath;

//テーブルセル選択イベント：MIDI IN Device
- (void)onSelectMIDIINCellForIndexPath:(NSIndexPath*)indexPath;

//テーブルセル選択イベント：MIDI IN Device / Port A
- (void)onSelectMIDIINCellForPortA;

//テーブルセル選択イベント：MIDI IN Device / MIDI THRU
- (void)onSelectMIDIINCellForMIDITHRU;

//テーブルセル選択イベント：MIDI File
- (void)onSelectMIDIFileCellForIndexPath:(NSIndexPath*)indexPath;

//テーブルセル選択イベント：Graphic
- (void)onSelectGraphicCellForIndexPath:(NSIndexPath*)indexPath;

//テーブルセル選択イベント：Graphic / アンチエイリアンシング
- (void)onSelectGraphicCellForAntiAliasing;

//テーブルセル選択イベント：Graphic / 背景画像ファイル
- (void)onSelectGraphicCellForBackgroundImage;

// テーブルセル選択イベント：Graphic / 四分音符長拡大率
- (void)onSelectGraphicCellForNoteLength;

//テーブルセル選択イベント：Game Controller
- (void)onSelectGameControllerCellForIndexPath:(NSIndexPath*)indexPath;

//無線ゲームコントローラ検索完了イベントハンドラ
- (void)onCompleteWirelessControllerDiscovery;

//ゲームコントローラー接続通知
- (void)onGameControllerDidConnect;

//ゲームコントローラー切断通知
- (void)onGameControllerDidDisconnect;

//ゲームコントローラー表示更新
- (void)updateTableForGameController;

@end


@implementation MTSettingViewCtrl

//******************************************************************************
// 生成
//******************************************************************************
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    NSString* pMIDIOutDevNibName = nil;
    NSString* pMIDIInDevNibName = nil;
    NSString* pEncodingNibName = nil;
	NSString* pBGIMGNibName = nil;
	NSString* pWavetableNibName = nil;
	NSString* pNoteLengthNibName = nil;
	NSNotificationCenter* pCenter = nil;
    
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
	
    if (self) {
        //ビュー設定
		self.title = @"Settings";
		self.tabBarItem.image = [UIImage imageNamed:@"img/TabIcon"];
		
		//ビュー制御の生成
		if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
			//iPhone / iPod touch
            pMIDIOutDevNibName = @"MTSettingMIDIOutDevView_iPhone";
            pMIDIInDevNibName = @"MTSettingMIDIInDevView_iPhone";
			pEncodingNibName = @"MTSettingEncodingView_iPhone";
            pBGIMGNibName = @"MTSettingBGIMGView_iPhone";
			pWavetableNibName = @"MTSettingWavetableView_iPhone";
			pNoteLengthNibName = @"MTSettingNoteLengthView_iPhone";
		}
		else {
			//iPad
            pMIDIOutDevNibName = @"MTSettingMIDIOutDevView_iPad";
            pMIDIInDevNibName = @"MTSettingMIDIInDevView_iPad";
            pEncodingNibName = @"MTSettingEncodingView_iPad";
            pBGIMGNibName = @"MTSettingBGIMGView_iPad";
			pWavetableNibName = @"MTSettingWavetableView_iPad";
			pNoteLengthNibName = @"MTSettingNoteLengthView_iPad";
		}
        m_pSettingMIDIOutDevViewCtrl = [[MTSettingMIDIOutDevViewCtrl alloc] initWithNibName:pMIDIOutDevNibName bundle:nil];
        m_pSettingMIDIInDevViewCtrl = [[MTSettingMIDIInDevViewCtrl alloc] initWithNibName:pMIDIInDevNibName bundle:nil];
        m_pSettingEncodingViewCtrl = [[MTSettingEncodingViewCtrl alloc] initWithNibName:pEncodingNibName bundle:nil];
        m_pSettingBGIMGViewCtrl = [[MTSettingBGIMGViewCtrl alloc] initWithNibName:pBGIMGNibName bundle:nil];
		m_pSettingWavetableViewCtrl = [[MTSettingWavetableViewCtrl alloc] initWithNibName:pWavetableNibName bundle:nil];
		m_pSettingNoteLengthViewCtrl = [[MTSettingNoteLengthViewCtrl alloc] initWithNibName:pNoteLengthNibName bundle:nil];
    }
	
	//ゲームコントローラー接続/切断通知先登録
	pCenter = [NSNotificationCenter defaultCenter];
	[pCenter addObserver:self
				selector:@selector(onGameControllerDidConnect)
					name:GCControllerDidConnectNotification
				  object:nil];
	[pCenter addObserver:self
				selector:@selector(onGameControllerDidDisconnect)
					name:GCControllerDidDisconnectNotification
				  object:nil];
	
    return self;
}

//******************************************************************************
// ビュー登録完了
//******************************************************************************
- (void)viewDidLoad
{
	int result = 0;
	
    [super viewDidLoad];
	// Do any additional setup after loading the view.
	
	//ユーザ設定初期化
	m_pUserConf = [[YNUserConf alloc] init];
	if (m_pUserConf == nil) {
		result = YN_SET_ERR(@"Program error.", 0, 0);
		goto EXIT;
	}
	
	//ビューモードアイコン画像読み込み
	//TAG:シーン追加
	m_pImagePianoRoll3D   = [[UIImage imageNamed:@"img/ViewMode-PianoRoll3D"] retain];
	m_pImagePianoRoll2D   = [[UIImage imageNamed:@"img/ViewMode-PianoRoll2D"] retain];
	m_pImagePianoRollRain = [[UIImage imageNamed:@"img/ViewMode-PianoRollRain"] retain];
	m_pImagePianoRollRain2D = [[UIImage imageNamed:@"img/ViewMode-PianoRollRain2D"] retain];
	m_pImagePianoRollRing = [[UIImage imageNamed:@"img/ViewMode-PianoRollRing"] retain];
	
	//無線ゲームコントローラ検索状態
	m_isSearchingControllers = NO;
	
EXIT:;
	if (result != 0) YN_SHOW_ERR();
}

//******************************************************************************
// インターフェース自動回転確認
//******************************************************************************
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
	return YES;
}

//******************************************************************************
// インターフェース自動回転確認（iOS6以降）
//******************************************************************************
- (BOOL)shouldAutorotate
{
	//回転を許可する
	return YES;
}

//******************************************************************************
// インターフェース自動回転確認：回転方向（iOS6以降）
//******************************************************************************
- (NSUInteger)supportedInterfaceOrientations
{
	//全方向に対応する
	return UIInterfaceOrientationMaskAll;
}

//******************************************************************************
// ビュー表示
//******************************************************************************
- (void)viewWillAppear:(BOOL)animated
{
	int result = 0;
	
	//MIDI出力デバイス制御初期化
	result = m_OutDevCtrl.Initialize();
	if (result != 0) goto EXIT;
	
	//MIDI入力デバイス制御初期化
	result = m_InDevCtrl.Initialize();
	if (result != 0) goto EXIT;
	
	//テーブルビュー再表示
	[m_pTableView reloadData];
	
EXIT:;
	if (result != 0) YN_SHOW_ERR();
	return;
}

//******************************************************************************
// ビュー非表示
//******************************************************************************
- (void)viewWillDisappear:(BOOL)animated
{
	return;
}

//******************************************************************************
// セクション数
//******************************************************************************
-(NSInteger)numberOfSectionsInTableView:(UITableView*)tableView
{
	//セクション
	// 0. View Mode
	// 1. Display Item
	// 2. MIDI OUT Device
	// 3. Internal Wavetable Synthesizer
	// 4. MIDI IN Device
	// 5. MIDI File
	// 6. Graphic
	// 7. Game Controller
	
    return 8;
} 

//******************************************************************************
// セクションヘッダ
//******************************************************************************
- (NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section
{
	NSString* pSectionHeader = nil;
	
	switch(section) {
		case 0:
			pSectionHeader = @"View Mode";
			break;
		case 1:
			pSectionHeader = @"Display Item";
			break;
		case 2:
			pSectionHeader = @"MIDI OUT Device";
			break;
		case 3:
			pSectionHeader = @"Internal Wavetable Synthesizer";
			break;
		case 4:
			pSectionHeader = @"MIDI IN Device";
			break;
		case 5:
			pSectionHeader = @"MIDI File";
			break;
		case 6:
			pSectionHeader = @"Graphic";
			break;
		case 7:
			pSectionHeader = @"Game Controller";
			break;
		default:
			break;
    }
	
    return pSectionHeader;
} 

//******************************************************************************
// セクションごとの項目数
//******************************************************************************
- (NSInteger)tableView:(UITableView *)tableView
 numberOfRowsInSection:(NSInteger)section
{
	NSInteger numOfRows = 0;
	
	//NSLog(@"section %d", section);
	
	switch (section) {
		case 0:
			//View Mode
			//TAG:シーン追加
			numOfRows = 5;
			break;
		case 1:
			//Display Item
			numOfRows = 7;
			break;
		case 2:
			//MIDI OUT Device
            numOfRows = SM_MIDIOUT_PORT_NUM_MAX;
			break;
		case 3:
			//Internal Wavetable Synthesizer
			numOfRows = 1;
			break;
		case 4:
			//MIDI IN Device
            numOfRows = 2;
			break;
		case 5:
			//MIDI File
			numOfRows = 1;
			break;
		case 6:
			//Graphic
			numOfRows = 3;
			break;
		case 7:
			//Game Controller
			numOfRows = 1;
			break;
		default:
			break;
	}
	
	return numOfRows;
}

//******************************************************************************
// 項目表示内容
//******************************************************************************
- (UITableViewCell*)tableView:(UITableView*)tableView
		 cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
	UITableViewCell* pCell = nil;
	
	switch (indexPath.section) {
		case 0:
			//ビューモード
			pCell = [self makeViewModeCellForIndexPath:indexPath];
			break;
		case 1:
			//表示項目
			pCell = [self makeDisplayItemCellForIndexPath:indexPath];
			break;
		case 2:
			//MIDI OUT Device
			pCell = [self makeMIDIOUTCellForIndexPath:indexPath];
			break;
		case 3:
			//Internal Wavetable Synthesizer
			pCell = [self makeInternalSynthsizerCellForIndexPath:indexPath];
			break;
		case 4:
			//MIDI IN Device
			pCell = [self makeMIDIINCellForIndexPath:indexPath];
			break;
		case 5:
			//MIDI File
			pCell = [self makeMIDIFileCellForIndexPath:indexPath];
			break;
		case 6:
			//Graphic
			pCell = [self makeGraphicCellForIndexPath:indexPath];
			break;
		case 7:
			//Game Controller
			pCell = [self makeGameControllerCellForIndexPath:indexPath];
			break;
		default:
			break;
	}
	
    return pCell;
}

//******************************************************************************
// テーブルセル作成：ビューモード
//******************************************************************************
- (UITableViewCell*)makeViewModeCellForIndexPath:(NSIndexPath*)indexPath
{
    static NSString* pCellIdentifier = @"MTSettingViewCtrl_ViewMode";
	UITableViewCell* pCell = nil;
	NSString* pSelectedType = nil;
	NSString* pType = nil;
	
	//再利用可能セル生成
	pCell = [m_pTableView dequeueReusableCellWithIdentifier:pCellIdentifier];
	if (pCell == nil) {
		pCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
									   reuseIdentifier:pCellIdentifier];
	}
	
	//ラベル設定
	//TAG:シーン追加
	switch (indexPath.row) {
		case 0:
			pCell.textLabel.text = @"Piano Roll 3D";
			pCell.imageView.image = m_pImagePianoRoll3D;
			pCell.imageView.layer.cornerRadius = 8.0;
			pCell.imageView.layer.masksToBounds = YES;
			pType = @"PianoRoll3D";
			break;			
		case 1:
			pCell.textLabel.text = @"Piano Roll 2D";
			pCell.imageView.image = m_pImagePianoRoll2D;
			pCell.imageView.layer.cornerRadius = 8.0;
			pCell.imageView.layer.masksToBounds = YES;
			pType = @"PianoRoll2D";
			break;			
		case 2:
			pCell.textLabel.text = @"Piano Roll Rain";
			pCell.imageView.image = m_pImagePianoRollRain;
			pCell.imageView.layer.cornerRadius = 8.0;
			pCell.imageView.layer.masksToBounds = YES;
			pType = @"PianoRollRain";
			break;
		case 3:
			pCell.textLabel.text = @"Piano Roll Rain 2D";
			pCell.imageView.image = m_pImagePianoRollRain2D;
			pCell.imageView.layer.cornerRadius = 8.0;
			pCell.imageView.layer.masksToBounds = YES;
			pType = @"PianoRollRain2D";
			break;
		case 4:
			pCell.textLabel.text = @"Piano Roll Ring";
			pCell.imageView.image = m_pImagePianoRollRing;
			pCell.imageView.layer.cornerRadius = 8.0;
			pCell.imageView.layer.masksToBounds = YES;
			pType = @"PianoRollRing";
			break;
		default:
			break;
	}
	
	//選択中シーン種別を取得
	[m_pUserConf setCategory:MT_CONF_CATEGORY_VIEW];
	[m_pUserConf setSection:MT_CONF_SECTION_SCENE];
	pSelectedType = [m_pUserConf strValueForKey:@"Type" defaultValue:@"PianoRoll3D"];
	
	//チェックマーク設定
	pCell.accessoryType = UITableViewCellAccessoryNone;
	if ([pType isEqualToString:pSelectedType]) {
		pCell.accessoryType = UITableViewCellAccessoryCheckmark;
	}
	
	return pCell;
}

//******************************************************************************
// テーブルセル作成：表示項目
//******************************************************************************
- (UITableViewCell*)makeDisplayItemCellForIndexPath:(NSIndexPath*)indexPath
{
    static NSString* pCellIdentifier = @"MTSettingViewCtrl_DisplayItem";
	UITableViewCell* pCell = nil;
	UISwitch* pSwitch = nil;
	NSString* pItemName = nil;
	BOOL isAnimated = YES;
	int value = 0;
	int defaultValue = 1;
	
	//再利用可能セル生成
	pCell = [m_pTableView dequeueReusableCellWithIdentifier:pCellIdentifier];
	if (pCell == nil) {
		pCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
									   reuseIdentifier:pCellIdentifier];
		pSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
		pSwitch.userInteractionEnabled = NO; //ユーザ操作を透過
		pCell.accessoryView = pSwitch;
		isAnimated = NO;
	}
	
	switch (indexPath.row) {
		case 0:
			pCell.textLabel.text = @"Piano Keyboard";
			pItemName = @"PianoKeyboard";
			break;			
		case 1:
			pCell.textLabel.text = @"Ripple";
			pItemName = @"Ripple";
			break;			
		case 2:
			pCell.textLabel.text = @"Pitch Bend Motion";
			pItemName = @"PitchBendMotion";
			break;			
		case 3:
			pCell.textLabel.text = @"Stars";
			pItemName = @"Stars";
			break;			
		case 4:
			pCell.textLabel.text = @"Counter";
			pItemName = @"Counter";
			break;
		case 5:
			pCell.textLabel.text = @"Background Image";
			pItemName = @"BackgroundImage";
			break;
		case 6:
			pCell.textLabel.text = @"FPS";
			pItemName = @"FPS";
			defaultValue = 0;  //FPSはデフォルトOFF
			break;
		default:
			break;
	}
	
	//表示項目の表示設定を取得
	[m_pUserConf setCategory:MT_CONF_CATEGORY_VIEW];
	[m_pUserConf setSection:MT_CONF_SECTION_DISPLAY];
	value = [m_pUserConf intValueForKey:pItemName defaultValue:defaultValue];
	
	//スイッチ設定
	pSwitch = (UISwitch*)pCell.accessoryView;
	if (value == 1) {
		[pSwitch setOn:YES animated:isAnimated];
	}
	else {
		[pSwitch setOn:NO animated:isAnimated];
	}
	
	return pCell;
}

//******************************************************************************
// テーブルセル作成：MIDI OUT Device
//******************************************************************************
- (UITableViewCell*)makeMIDIOUTCellForIndexPath:(NSIndexPath*)indexPath
{
    int result = 0;
    static NSString* pCellIdentifier = @"MTSettingViewCtrl_MIDIOUT";
	UITableViewCell* pCell = nil;
	NSString* pSelectedDevIdName = nil;
	NSString* pSelectedDevDisplayName = nil;
    NSString* pDevIdName = nil;
	NSString* pDevDisplayName = nil;
    NSString* pLabel = nil;
    NSString* pPortNameKeys[] = {@"PortA", @"PortB", @"PortC", @"PortD", @"PortE", @"PortF"};
    NSString* pPortNameLabels[] = {@"Port A (default)", @"Port B", @"Port C", @"Port D", @"Port E", @"Port F"};
	NSString* pPortDevDisplayNameKey = nil;
    unsigned int i = 0;
    
	//再利用可能セル生成
	pCell = [m_pTableView dequeueReusableCellWithIdentifier:pCellIdentifier];
	if (pCell == nil) {
		pCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
									   reuseIdentifier:pCellIdentifier];
	}
    
    if (indexPath.row >= SM_MIDIOUT_PORT_NUM_MAX) {
        result = YN_SET_ERR(@"Program error.", indexPath.row, 0);
        goto EXIT;
    }
    
	pPortDevDisplayNameKey = [NSString stringWithFormat:@"%@_DevDisplayName", pPortNameKeys[indexPath.row]];
	
    //MIDI OUTの設定を取得
    [m_pUserConf setCategory:MT_CONF_CATEGORY_MIDI];
    [m_pUserConf setSection:MT_CONF_SECTION_MIDIOUT];
    pSelectedDevIdName = [m_pUserConf strValueForKey:pPortNameKeys[indexPath.row] defaultValue:@""];
	pSelectedDevDisplayName = [m_pUserConf strValueForKey:pPortDevDisplayNameKey defaultValue:@""];
    
    if ([pSelectedDevIdName length] == 0) {
        pLabel = @"(none)";
    }
    else {
        pLabel = @"(not found)";
        for (i = 0; i < m_OutDevCtrl.GetDevNum(); i++) {
            pDevIdName = m_OutDevCtrl.GetDevIdName(i);
			pDevDisplayName = m_OutDevCtrl.GetDevDisplayName(i);
			
			//選択デバイスのデバイス識別名称と一致する場合
			if ([pSelectedDevIdName isEqualToString:pDevIdName]) {
				//デバイス表示名称が保存されていない場合はデバイス識別名のみで判定
				if ([pSelectedDevDisplayName length] == 0) {
					pLabel = pDevDisplayName;
				}
				//デバイス表示名称が保存されている場合はデバイス表示名称の一致も判定
				else if ([pSelectedDevDisplayName isEqualToString:pDevDisplayName]) {
					pLabel = pDevDisplayName;
				}
            }
        }
    }
    
    //テキスト設定
    pCell.textLabel.text = pPortNameLabels[indexPath.row];
    pCell.detailTextLabel.text = pLabel;
    
    //階層マーク設定
    pCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
	
EXIT:;
    if (result != 0) YN_SHOW_ERR();
	return pCell;
}

//******************************************************************************
// テーブルセル作成：Internal Wavetable Synthsizer
//******************************************************************************
- (UITableViewCell*)makeInternalSynthsizerCellForIndexPath:(NSIndexPath*)indexPath
{
	static NSString* pCellIdentifier = @"MTSettingViewCtrl_InternalWavetableSynthsizer";
	UITableViewCell* pCell = nil;
	NSString* pWavetableFileName = nil;
	NSString* pLabel = nil;
	
	//再利用可能セル生成
	pCell = [m_pTableView dequeueReusableCellWithIdentifier:pCellIdentifier];
	if (pCell == nil) {
		pCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
									   reuseIdentifier:pCellIdentifier];
	}
	
	//Wavetableファイルの設定を取得
	[m_pUserConf setCategory:MT_CONF_CATEGORY_SYNTHESIZER];
	[m_pUserConf setSection:MT_CONF_SECTION_WAVETABLE];
	pWavetableFileName = [m_pUserConf strValueForKey:@"WavetableFileName" defaultValue:@""];
	
	if ([pWavetableFileName length] == 0) {
		pLabel = @"(none)";
	}
	else {
		pLabel = pWavetableFileName;
	}
	
	//テキスト設定
	pCell.textLabel.text = @"Wavetable File";
	pCell.detailTextLabel.text = pLabel;
	
	//階層マーク設定
	pCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
	
	return pCell;
}

//******************************************************************************
// テーブルセル作成：MIDI IN Device
//******************************************************************************
- (UITableViewCell*)makeMIDIINCellForIndexPath:(NSIndexPath*)indexPath
{
	UITableViewCell* pCell = nil;
	
	switch (indexPath.row) {
		case 0:
			//Port A
			pCell = [self makeMIDIINCellForPortA];
			break;
		case 1:
			//MIDI THRU
			pCell = [self makeMIDIINCellForMIDITHRU];
			break;
		default:
			break;
	}
	
	return pCell;
}

//******************************************************************************
// テーブルセル作成：MIDI IN Device / PortA
//******************************************************************************
- (UITableViewCell*)makeMIDIINCellForPortA
{
    int result = 0;
    static NSString* pCellIdentifier = @"MTSettingViewCtrl_MIDIINDevice_PortA";
    UITableViewCell* pCell = nil;
    NSString* pSelectedDevIdName = nil;
	NSString* pSelectedDevDisplayName = nil;
    NSString* pDevIdName = nil;
	NSString* pDevDisplayName = nil;
    NSString* pLabel = nil;
    unsigned int i = 0;
    
    //再利用可能セル生成
    pCell = [m_pTableView dequeueReusableCellWithIdentifier:pCellIdentifier];
    if (pCell == nil) {
        pCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
                                       reuseIdentifier:pCellIdentifier];
    }
	
    //MIDI INの設定を取得
    [m_pUserConf setCategory:MT_CONF_CATEGORY_MIDI];
    [m_pUserConf setSection:MT_CONF_SECTION_MIDIIN];
    pSelectedDevIdName = [m_pUserConf strValueForKey:@"PortA" defaultValue:@""];
	pSelectedDevDisplayName = [m_pUserConf strValueForKey:@"PortA_DevDisplayName" defaultValue:@""];
    
    if ([pSelectedDevIdName length] == 0) {
        pLabel = @"(none)";
    }
    else {
        pLabel = @"(not found)";
        for (i = 0; i < m_InDevCtrl.GetDevNum(); i++) {
            pDevIdName = m_InDevCtrl.GetDevIdName(i);
			pDevDisplayName = m_InDevCtrl.GetDevDisplayName(i);
			
			//選択デバイスのデバイス識別名称と一致する場合
            if ([pSelectedDevIdName isEqualToString:pDevIdName]) {
				//デバイス表示名称が保存されていない場合はデバイス識別名のみで判定
				if ([pSelectedDevDisplayName length] == 0) {
					pLabel = pDevDisplayName;
				}
				//デバイス表示名称が保存されている場合はデバイス表示名称の一致も判定
				else if ([pSelectedDevDisplayName isEqualToString:pDevDisplayName]) {
					pLabel = pDevDisplayName;
				}
			}
        }
    }
    
    //テキスト設定
    pCell.textLabel.text = @"Port A";
    pCell.detailTextLabel.text = pLabel;
    
    //階層マーク設定
    pCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    
EXIT:;
    if (result != 0) YN_SHOW_ERR();
	return pCell;
}

//******************************************************************************
// テーブルセル作成：MIDI IN Device / MIDI THRU
//******************************************************************************
- (UITableViewCell*)makeMIDIINCellForMIDITHRU
{
    static NSString* pCellIdentifier = @"MTSettingViewCtrl_MIDIINDevice_MIDITHRU";
	UITableViewCell* pCell = nil;
	UISwitch* pSwitch = nil;
	BOOL isAnimated = YES;
	int checkMIDITHRU = 0;
	
	//再利用可能セル生成
	pCell = [m_pTableView dequeueReusableCellWithIdentifier:pCellIdentifier];
	if (pCell == nil) {
		pCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
									   reuseIdentifier:pCellIdentifier];
		pSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
		pSwitch.userInteractionEnabled = NO; //ユーザ操作を透過
		pCell.accessoryView = pSwitch;
		isAnimated = NO;
	}
	
	//テキスト設定
	pCell.textLabel.text = @"MIDI THRU";
	
	//MIDI INの設定を取得
	[m_pUserConf setCategory:MT_CONF_CATEGORY_MIDI];
	[m_pUserConf setSection:MT_CONF_SECTION_MIDIIN];
	checkMIDITHRU = [m_pUserConf intValueForKey:@"MIDITHRU" defaultValue:1];
	
	//スイッチ設定
	pSwitch = (UISwitch*)pCell.accessoryView;
	if (checkMIDITHRU > 0) {
		[pSwitch setOn:YES animated:isAnimated];
	}
	else {
		[pSwitch setOn:NO animated:isAnimated];
	}
	
	return pCell;
}

//******************************************************************************
// テーブルセル作成：MIDI File
//******************************************************************************
- (UITableViewCell*)makeMIDIFileCellForIndexPath:(NSIndexPath*)indexPath
{
    static NSString* pCellIdentifier = @"MTSettingViewCtrl_MIDIFile";
	UITableViewCell* pCell = nil;
	NSString* pEncodingName = nil;
	
	//再利用可能セル生成
	pCell = [m_pTableView dequeueReusableCellWithIdentifier:pCellIdentifier];
	if (pCell == nil) {
		pCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
									   reuseIdentifier:pCellIdentifier];
	}
		
	//エンコーディング選択状態を取得
	pEncodingName = [m_pSettingEncodingViewCtrl selectedEncodingName];
	
	//テキスト設定
	pCell.textLabel.text = @"Character Encoding";
	pCell.detailTextLabel.text = pEncodingName;
	
	//階層マーク設定
	pCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
	
	return pCell;
}

//******************************************************************************
// テーブルセル作成：グラフィク
//******************************************************************************
- (UITableViewCell*)makeGraphicCellForIndexPath:(NSIndexPath*)indexPath
{
	UITableViewCell* pCell = nil;
	
	switch (indexPath.row) {
		case 0:
			//アンチエイリアシング
			pCell = [self makeGraphicCellForAntiAliaasing];
			break;
		case 1:
			//背景画像ファイル
			pCell = [self makeGraphicCellForBackgroundImage];
			break;
		case 2:
			//四分音符長拡大率
			pCell = [self makeGraphicCellForNoteLength];
			break;
		default:
			break;
	}
	
	return pCell;
}

//******************************************************************************
// テーブルセル作成：グラフィク / アンチエイリアシング
//******************************************************************************
- (UITableViewCell*)makeGraphicCellForAntiAliaasing
{
	static NSString* pCellIdentifier = @"MTSettingViewCtrl_Graphic_AntiAliasing";
	UITableViewCell* pCell = nil;
	UISwitch* pSwitch = nil;
	BOOL isAnimated = YES;
	int value = 0;
	
	//再利用可能セル生成
	pCell = [m_pTableView dequeueReusableCellWithIdentifier:pCellIdentifier];
	if (pCell == nil) {
		pCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
									   reuseIdentifier:pCellIdentifier];
		pSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
		pSwitch.userInteractionEnabled = NO; //ユーザ操作を透過
		pCell.accessoryView = pSwitch;
		isAnimated = NO;
	}
	
	//セル設定
	pCell.textLabel.text = @"Anti-aliasing";
	pCell.detailTextLabel.text = @"You have to restart MIDITrail to apply this setting.";
	pCell.detailTextLabel.textColor = UIColor.grayColor;
	
	//表示項目の表示設定を取得
	[m_pUserConf setCategory:MT_CONF_CATEGORY_GRAPHIC];
	[m_pUserConf setSection:MT_CONF_SECTION_AA];
	value = [m_pUserConf intValueForKey: @"EnableAntialias" defaultValue:0];
	
	//スイッチ設定
	pSwitch = (UISwitch*)pCell.accessoryView;
	if (value == 1) {
		[pSwitch setOn:YES animated:isAnimated];
	}
	else {
		[pSwitch setOn:NO animated:isAnimated];
	}
	
	return pCell;
}

//******************************************************************************
// テーブルセル作成：グラフィク / 背景画像ファイル
//******************************************************************************
- (UITableViewCell*)makeGraphicCellForBackgroundImage
{
	static NSString* pCellIdentifier = @"MTSettingViewCtrl_Graphic_BackgroundImage";
	UITableViewCell* pCell = nil;
	NSString* pImageFileName = nil;
	NSString* pLabel = nil;
	
	//再利用可能セル生成
	pCell = [m_pTableView dequeueReusableCellWithIdentifier:pCellIdentifier];
	if (pCell == nil) {
		pCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
									   reuseIdentifier:pCellIdentifier];
	}
	
	//背景画像の設定を取得
	[m_pUserConf setCategory:MT_CONF_CATEGORY_GRAPHIC];
	[m_pUserConf setSection:MT_CONF_SECTION_BGIMG];
	pImageFileName = [m_pUserConf strValueForKey:@"ImageFileName" defaultValue:@""];
	
	if ([pImageFileName length] == 0) {
		pLabel = @"(none)";
	}
	else {
		pLabel = pImageFileName;
	}
	
	//テキスト設定
	pCell.textLabel.text = @"Background Image";
	pCell.detailTextLabel.text = pLabel;
	
	//階層マーク設定
	pCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
	
	return pCell;
}

//******************************************************************************
// テーブルセル作成：グラフィク / 四分音符長拡大率
//******************************************************************************
- (UITableViewCell*)makeGraphicCellForNoteLength
{
	static NSString* pCellIdentifier = @"MTSettingViewCtrl_Graphic_NoteLength";
	UITableViewCell* pCell = nil;
	int mag = 0;
	
	//再利用可能セル生成
	pCell = [m_pTableView dequeueReusableCellWithIdentifier:pCellIdentifier];
	if (pCell == nil) {
		pCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
									   reuseIdentifier:pCellIdentifier];
	}
	
	//セル設定
	pCell.textLabel.text = @"Quarter Note Length";
	
	//拡大率取得
	mag = [m_pSettingNoteLengthViewCtrl selectedQuarterNoteLengthMag];
	pCell.detailTextLabel.text = [NSString stringWithFormat:@"%d %%", mag];
	
	//階層マーク設定
	pCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
	
	return pCell;
}

//******************************************************************************
// テーブルセル作成：ゲームコントローラー
//******************************************************************************
- (UITableViewCell*)makeGameControllerCellForIndexPath:(NSIndexPath*)indexPath
{
	static NSString* pCellIdentifier = @"MTSettingViewCtrl_GameController";
	UITableViewCell* pCell = nil;
	NSArray* pControllers = nil;
	GCController* pController = nil;
	
	//再利用可能セル生成
	pCell = [m_pTableView dequeueReusableCellWithIdentifier:pCellIdentifier];
	if (pCell == nil) {
		pCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
									   reuseIdentifier:pCellIdentifier];
	}
	
	pCell.textLabel.text = @"Gamepad";
	
	if (m_isSearchingControllers) {
		pCell.detailTextLabel.text = @"(searching...)";
	}
	else {
		//ゲームコントローラー検索
		//  コントローラーの制御はメインビューで行うため
		//  検索で見つかったコントローラーは表示するのみで記憶しない
		pCell.detailTextLabel.text = @"(not found)";
		pControllers = [GCController controllers];
		for (pController in pControllers) {
			//ゲームパッドをサポートしているコントローラを探す
			if (pController.gamepad != nil) {
				//最初に見つかったものを選択する
				pCell.detailTextLabel.text = pController.vendorName;
				break;
			}
		}
	}
	
	return pCell;
}

//******************************************************************************
// テーブルセル作成：列の高さ
//******************************************************************************
- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath
{
	CGFloat height = 0.0f;
	
	switch (indexPath.section) {
		case 0:
			//ビューモード
			height = 86.0f;
			break;
		default:
			//デフォルトの高さを返す
			height = m_pTableView.rowHeight;
			break;
	}
	
	return height;
}

//******************************************************************************
// テーブルセル選択イベント
//******************************************************************************
- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
	//選択状態解除
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
	
	switch (indexPath.section) {
		case 0:
			//View Mode
			[self onSelectViewModeCellForIndexPath:indexPath];
			break;
		case 1:
			//Display Item
			[self onSelectDisplayItemCellForIndexPath:indexPath];
			break;
		case 2:
			//MIDI OUT Device
			[self onSelectMIDIOUTCellForIndexPath:indexPath];
			break;
		case 3:
			//Internal Wavetable Synthsizer
			[self onSelectInternalSynthesizerCellForIndexPath:indexPath];
			break;
		case 4:
			//MIDI IN Device
			[self onSelectMIDIINCellForIndexPath:indexPath];
			break;
		case 5:
			//MIDI File
			[self onSelectMIDIFileCellForIndexPath:indexPath];
			break;
		case 6:
			//Graphic
			[self onSelectGraphicCellForIndexPath:indexPath];
			break;
		case 7:
			//Game Controller
			[self onSelectGameControllerCellForIndexPath:indexPath];
			break;
		default:
			break;
	}
	
	[tableView performSelector:@selector(reloadData) withObject:nil afterDelay:0.1f];
	
	return;
}

//******************************************************************************
// テーブルセル選択イベント：ビューモード
//******************************************************************************
- (void)onSelectViewModeCellForIndexPath:(NSIndexPath*)indexPath
{
	NSString* pSelectedType = nil;
	
	//NSLog(@"selected %d", indexPath.row);
	
	//TAG:シーン追加
	switch (indexPath.row) {
		case 0:
			pSelectedType = @"PianoRoll3D";
			break;			
		case 1:
			pSelectedType = @"PianoRoll2D";
			break;			
		case 2:
			pSelectedType = @"PianoRollRain";
			break;
		case 3:
			pSelectedType = @"PianoRollRain2D";
			break;
		case 4:
			pSelectedType = @"PianoRollRing";
			break;
		default:
			break;
	}
	
	//選択中シーン種別を保存
	[m_pUserConf setCategory:MT_CONF_CATEGORY_VIEW];
	[m_pUserConf setSection:MT_CONF_SECTION_SCENE];
	[m_pUserConf setStr:pSelectedType forKey:@"Type"];
	
	return;
}

//******************************************************************************
// テーブルセル選択イベント：表示項目
//******************************************************************************
- (void)onSelectDisplayItemCellForIndexPath:(NSIndexPath*)indexPath
{
	NSString* pItemName = nil;
	int value = 0;
	int defaultValue = 1;
	
	//NSLog(@"selected %d", indexPath.row);
	
	switch (indexPath.row) {
		case 0:
			pItemName = @"PianoKeyboard";
			break;			
		case 1:
			pItemName = @"Ripple";
			break;			
		case 2:
			pItemName = @"PitchBendMotion";
			break;			
		case 3:
			pItemName = @"Stars";
			break;			
		case 4:
			pItemName = @"Counter";
			break;
        case 5:
            pItemName = @"BackgroundImage";
            break;
		case 6:
			pItemName = @"FPS";
			defaultValue = 0;  //FPSはデフォルトOFF
			break;
		default:
			break;
	}
	
	//表示項目の表示設定を取得
	[m_pUserConf setCategory:MT_CONF_CATEGORY_VIEW];
	[m_pUserConf setSection:MT_CONF_SECTION_DISPLAY];
	value = [m_pUserConf intValueForKey:pItemName defaultValue:defaultValue];
	
	//選択状態を反転して保存
	value = (value == 1)? 0 : 1;
	[m_pUserConf setInt:value forKey:pItemName];
	
	return;
}

//******************************************************************************
// テーブルセル選択イベント：MIDI OUT Device
//******************************************************************************
- (void)onSelectMIDIOUTCellForIndexPath:(NSIndexPath*)indexPath
{
    int result = 0;
    NSString* pPortKeys[] = {@"PortA", @"PortB", @"PortC", @"PortD", @"PortE", @"PortF"};
    NSString* pPortLabels[] = {@"Port A", @"Port B", @"Port C", @"Port D", @"Port E", @"Port F"};
    
    //NSLog(@"selected %d", indexPath.row);
	
    if (indexPath.row >= SM_MIDIOUT_PORT_NUM_MAX) {
        result = YN_SET_ERR(@"Program error.", indexPath.row, 0);
        goto EXIT;
    }
    
    //MIDI OUTデバイス選択ビュー表示
    [m_pSettingMIDIOutDevViewCtrl setPortKey:pPortKeys[indexPath.row] portLabel:pPortLabels[indexPath.row]];
    [self.navigationController pushViewController:m_pSettingMIDIOutDevViewCtrl animated:YES];
	
EXIT:;
    if (result != 0) YN_SHOW_ERR();
	return;
}

//******************************************************************************
// テーブルセル選択イベント：Internal Wavetable Synthesizer
//******************************************************************************
- (void)onSelectInternalSynthesizerCellForIndexPath:(NSIndexPath*)indexPath
{
	//NSLog(@"selected %d", indexPath.row);
	
	if (indexPath.row == 0) {
		//Wavetableファイル選択ビュー表示
		[self.navigationController pushViewController:m_pSettingWavetableViewCtrl animated:YES];
	}
	
	return;
}

//******************************************************************************
// テーブルセル選択イベント：MIDI IN Device
//******************************************************************************
- (void)onSelectMIDIINCellForIndexPath:(NSIndexPath*)indexPath
{
	switch (indexPath.row) {
		case 0:
			//Port A
			[self onSelectMIDIINCellForPortA];
			break;
		case 1:
			//MIDI THRU
			[self onSelectMIDIINCellForMIDITHRU];
			break;
		default:
			break;
	}
	
	return;
}

//******************************************************************************
// テーブルセル選択イベント：MIDI IN Device / Port A
//******************************************************************************
- (void)onSelectMIDIINCellForPortA
{
    int result = 0;
	
    //MIDI OUTデバイス選択ビュー表示
    [m_pSettingMIDIInDevViewCtrl setPortKey:@"PortA" portLabel:@"Port A"];
    [self.navigationController pushViewController:m_pSettingMIDIInDevViewCtrl animated:YES];
    
EXIT:;
    if (result != 0) YN_SHOW_ERR();
	return;
}

//******************************************************************************
// テーブルセル選択イベント：MIDI IN Device / MIDI THRU
//******************************************************************************
- (void)onSelectMIDIINCellForMIDITHRU
{
	int checkMIDITHRU = 0;
	
	//MIDI INの設定を取得
	[m_pUserConf setCategory:MT_CONF_CATEGORY_MIDI];
	[m_pUserConf setSection:MT_CONF_SECTION_MIDIIN];
	checkMIDITHRU = [m_pUserConf intValueForKey:@"MIDITHRU" defaultValue:1];
	
	//選択状態を反転
	if (checkMIDITHRU == 0) {
		checkMIDITHRU = 1;
	}
	else {
		checkMIDITHRU = 0;
	}
	
	[m_pUserConf setInt:checkMIDITHRU forKey:@"MIDITHRU"];
	
	return;
}

//******************************************************************************
// テーブルセル選択イベント：MIDI File
//******************************************************************************
- (void)onSelectMIDIFileCellForIndexPath:(NSIndexPath*)indexPath
{
	//NSLog(@"selected %d", indexPath.row);
	
	if (indexPath.row == 0) {
		//エンコーディング選択ビュー表示
		[self.navigationController pushViewController:m_pSettingEncodingViewCtrl animated:YES];
	}
	
	return;
}

//******************************************************************************
// 選択エンコーディングID取得
//******************************************************************************
- (NSStringEncoding)selectedEncodingId
{
	return [m_pSettingEncodingViewCtrl selectedEncodingId];
}

//******************************************************************************
// テーブルセル選択イベント：グラフィック
//******************************************************************************
- (void)onSelectGraphicCellForIndexPath:(NSIndexPath*)indexPath
{
	switch (indexPath.row) {
		case 0:
			//アンチエイリアンシング
			[self onSelectGraphicCellForAntiAliasing];
			break;
		case 1:
			//背景画像ファイル
			[self onSelectGraphicCellForBackgroundImage];
			break;
		case 2:
			//四分音符長拡大率
			[self onSelectGraphicCellForNoteLength];
			break;
		default:
			break;
	}
	
	return;
}

//******************************************************************************
// テーブルセル選択イベント：グラフィック / アンチエイリアンシング
//******************************************************************************
- (void)onSelectGraphicCellForAntiAliasing
{
	int value = 0;
	
	//表示項目の表示設定を取得
	[m_pUserConf setCategory:MT_CONF_CATEGORY_GRAPHIC];
	[m_pUserConf setSection:MT_CONF_SECTION_AA];
	value = [m_pUserConf intValueForKey:@"EnableAntialias" defaultValue:0];
	
	//選択状態を反転して保存
	value = (value == 1)? 0 : 1;
	[m_pUserConf setInt:value forKey:@"EnableAntialias"];
	
	return;
}

//******************************************************************************
// テーブルセル選択イベント：グラフィック / 背景画像ファイル
//******************************************************************************
- (void)onSelectGraphicCellForBackgroundImage
{
	//背景画像選択ビュー表示
	[self.navigationController pushViewController:m_pSettingBGIMGViewCtrl animated:YES];
	
	return;
}

//******************************************************************************
// テーブルセル選択イベント：グラフィック / 四分音符長拡大率
//******************************************************************************
- (void)onSelectGraphicCellForNoteLength
{
	//四分音符長拡大率選択ビュー表示
	[self.navigationController pushViewController:m_pSettingNoteLengthViewCtrl animated:YES];
	
	return;
}

//******************************************************************************
// テーブルセル選択イベント：ゲームコントローラー
//******************************************************************************
- (void)onSelectGameControllerCellForIndexPath:(NSIndexPath*)indexPath
{
	//NSLog(@"selected %d", indexPath.row);
	
	if (m_isSearchingControllers) {
		//無線ゲームコントローラー検索停止
		[GCController stopWirelessControllerDiscovery];
		m_isSearchingControllers = NO;
	}
	else {
		//無線ゲームコントローラー検索開始
		NSLog(@"SEARCHING!");
		[GCController startWirelessControllerDiscoveryWithCompletionHandler:^{
			NSLog(@"TIME OUT!");
			[self onCompleteWirelessControllerDiscovery];}];
		m_isSearchingControllers = YES;
	}
	
	return;
}

//******************************************************************************
// 無線ゲームコントローラー検索完了イベントハンドラ
//******************************************************************************
- (void)onCompleteWirelessControllerDiscovery
{
	[self updateTableForGameController];
	return;
}

//******************************************************************************
// ゲームコントローラー接続通知
//******************************************************************************
- (void)onGameControllerDidConnect
{
	[self updateTableForGameController];
	return;
}

//******************************************************************************
// ゲームコントローラー切断通知
//******************************************************************************
- (void)onGameControllerDidDisconnect
{
	[self updateTableForGameController];
	return;
}

//******************************************************************************
// ゲームコントローラー表示更新
//******************************************************************************
- (void)updateTableForGameController
{
	NSIndexSet* pSections = nil;
	
	//無線ゲームコントローラー検索停止
	if (m_isSearchingControllers) {
		[GCController stopWirelessControllerDiscovery];
		m_isSearchingControllers = NO;
	}
	
	//ゲームコントローラセクション(9)表示更新
	pSections = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(9, 1)];
	[m_pTableView reloadSections:pSections withRowAnimation:UITableViewRowAnimationNone];
	
	return;
}

//******************************************************************************
// ファイル一覧更新
//******************************************************************************
- (int)updateFileList
{
	int result = 0;
	
	//背景画像のファイル一覧更新
	result = [m_pSettingBGIMGViewCtrl updateFileList];
	if (result != 0) goto EXIT;
	
	//Wavetableのファイル一覧更新
	result = [m_pSettingWavetableViewCtrl updateFileList];
	if (result != 0) goto EXIT;
	
EXIT:;
	return result;
}

@end

