//******************************************************************************
//
// 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;
	}
	
	//ビューモードアイコン画像読み込み
	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_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
			numOfRows = 4;
			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];
	}
	
	//ラベル設定
	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;
		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* pDevIdName = 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"};
    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;
    }
    
    //MIDI OUTの設定を取得
    [m_pUserConf setCategory:MT_CONF_CATEGORY_MIDI];
    [m_pUserConf setSection:MT_CONF_SECTION_MIDIOUT];
    pSelectedDevIdName = [m_pUserConf strValueForKey:pPortNameKeys[indexPath.row] defaultValue:@""];
    
    if ([pSelectedDevIdName length] == 0) {
        pLabel = @"(none)";
    }
    else {
        pLabel = @"(not found)";
        for (i = 0; i < m_OutDevCtrl.GetDevNum(); i++) {
            pDevIdName = m_OutDevCtrl.GetDevIdName(i);
            if ([pSelectedDevIdName isEqualToString:pDevIdName]) {
                pLabel = m_OutDevCtrl.GetDevDisplayName(i);
            }
        }
    }
    
    //テキスト設定
    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* pDevIdName = 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:@""];
    
    if ([pSelectedDevIdName length] == 0) {
        pLabel = @"(none)";
    }
    else {
        pLabel = @"(not found)";
        for (i = 0; i < m_InDevCtrl.GetDevNum(); i++) {
            pDevIdName = m_InDevCtrl.GetDevIdName(i);
            if ([pSelectedDevIdName isEqualToString:pDevIdName]) {
                pLabel = m_InDevCtrl.GetDevDisplayName(i);
            }
        }
    }
    
    //テキスト設定
    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];
	
	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 = @"Device";
	
	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);
	
	switch (indexPath.row) {
		case 0:
			pSelectedType = @"PianoRoll3D";
			break;			
		case 1:
			pSelectedType = @"PianoRoll2D";
			break;			
		case 2:
			pSelectedType = @"PianoRollRain";
			break;
		case 3:
			pSelectedType = @"PianoRollRain2D";
			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;
}


@end

