//
//  RootViewController.m
//  ZeroRec/Komadori
//
//  Created by AIG-Soft on 11/02/24.
//  Copyright 2011 AIG-Soft. All rights reserved.
//

#import "AppDelegate.h"
#import "RootViewController.h"
#import "HelpViewController.h"
#import "SetupViewController.h"
#import "RecViewController.h"
#import "Setup.h"
#import "libs.h"
#import "UIScreen+is568screen.h"
#import "click.h"
#import "FileControl2.h"
#import	"LimitedSymbol.h"
#import "Log.h"				// これはUSE_LOGにかかわらず読み込むこと
#import "main.h"
#import "avi.h"
#ifdef	USE_BLUETOOTH
#import "Bluetooth.h"
#import	"RemoteViewController.h"
#endif
#ifdef	USE_BATTERY
#import "BatteryCheck.h"
#endif
#import "NSString+sizeWithFont.h"
#import "NSString+drawiOS7.h"
#import "UIActivityIndicatorView+show.h"

@interface RootViewController()
#ifdef USE_BLUETOOTH
<BluetoothDelegate>
#endif
{
	AppDelegate *app;
	Setup *setup;
}

@end

@implementation RootViewController

#pragma mark -　初期化

- (void)viewDidLoad
{
	printSelf();
	[super viewDidLoad];
	
	app=getAppDelegate();
	setup=app.setup;
	
	// 最初の1回だけでいい初期化処理
	// ボタン／ラベル名など表示(ローカライズ)
	self.title=NSLocalStr(PROGRAM_NAME); // プログラム名
	
	_labelLatest.text=NSLocalizedString(@"LATEST",@"最新");

#ifdef DISABLE_UPSIDE_REC
	alertSymbol =[[LimitedSymbol alloc]initWithImageView:imageAlert];
#endif
#ifdef	USE_BLUETOOTH
	bluetooth=nil;
#endif
	[self.view bringSubviewToFront:infoView]; // 情報領域を画像上に配置
	
	// ここではwindow=nilで情報が読めないのでwillApearに移動する

	// 前回の最新画像情報を読み込み
	[self loadLatestPicture];
}

- (void)viewWillAppear:(BOOL)animated
{
	printSelf();
	[super viewWillAppear:animated];
	
#ifdef USE_BLUETOOTH
	// 接続状態を表示
	nslog(@"bluetooth.fconnect=%d",bluetooth.fconnect);
	btnBluetoothStatus.hidden=!(bluetooth.fconnect==BT_CONNECT_OK);
#endif
	
	// AVIでは_imageViewを使う
	_imageView.hidden=NO;
	// windowのIBによる設定背景色を保存（初回だけ）
	if (winColor==nil) {
		winColor=app.window.backgroundColor;
		//nslog(@"window=%@",app.window);
		nslog(@"winColor=%@",winColor);
	} // 毎回やるとタイミングかなんかでclearColorになってしまうことがある
	// window背景色を消す
	app.window.backgroundColor=[UIColor clearColor];
	
	// 表示ごとに必要な初期化処理
	// 最終録画イベントと枚数を表示
#if defined(USE_ALARM) && defined(USE_CONSTANT)
	{
	UIColor *col;
	if ([_labelAlarm.text caseInsensitiveCompare:SYMBOL_ALARM]==NSOrderedSame) { // 大文字小文字の区別なしに比較して同じ時＝A/aどちらかで一致
		col=[UIColor redColor];
	} else {
		col=[UIColor blackColor];
	}
	_labelAlarm.textColor=col;
	}
#else
	// アラームがないときはイベントは消す
	_labelAlarm.hidden=YES;
#endif
#ifdef USE_COUNT
	NSUInteger pics=[setup getPictures:PICTURE_LATEST];
	_labelPictures.text =[NSString stringWithFormat:NSLocalStr(@"PICTURES"),pics]; // copy属性なのでこれで行ける
#else
	// 無効中はボタンそのものを消す
	_labelPictures.hidden=YES;
#endif
#ifdef	USE_BLUETOOTH
	if (bluetooth!=nil) {
		// 受信関数再登録
		// 画面遷移先で登録が変更されているので、ここ用に再設定する
		bluetooth.delegate=self;
//		[bluetooth setReceiveRoutine:self selector:@selector(receiveBluetoothMode:)];
	}
	{
	// Bluetoothシャッターの表示
	_btnBluetooth.enabled =setup.fbluetoothShutter;
	UIColor *col=[UIColor magentaColor];
	_btnBluetooth.tintColor=col;
	if (setup.fbluetoothShutter) {
		_btnRecPrepare.tintColor=col;
	} else {
		_btnRecPrepare.tintColor=[UIColor colorWithRed:rgbf(50) green:rgbf(126) blue:rgbf(254) alpha:1];
	}
	}
#else
	// 無効中はボタンそのものを消す
	// これはUIBarButtonItemなのでhiddenがない。透明なボタンで押しても無効にする
	[_btnBluetooth initWithImage:[UIImage imageNamed:@"clear.png"] style:UIBarButtonItemStylePlain target:nil action:nil];
	_btnBluetooth.enabled = NO;
#endif
	//
	printSelfs(@"End%@",@"");
}
			   
//----------------------------------------------
// 画面を回転して良いかどうか
//----------------------------------------------
// iOS6.0

-(BOOL)shouldAutorotate
{
	return shouldAutorotateByMain();
}
			   
- (NSUInteger)supportedInterfaceOrientations
{
	return (supportedInterfaceOrientationsByMain());
}

//--------------------------------------
// 終了・異常時処理
//--------------------------------------
			   
#ifdef DEBUG
- (void)didReceiveMemoryWarning
{
	[super didReceiveMemoryWarning];
}
			   
#endif
			   
#ifdef	USE_BLUETOOTH
// Bluetoothの解放処理
// プログラム終了時にも呼び出される
-(void)endOfBluetooth
{
	if (bluetooth!=nil) {
		if (bluetooth.fconnect!=BT_CONNECT_NONE) {
			[self disconnectBluetooth:YES];
		}
	}
}
#endif
			   
- (void)dealloc
{
	printSelf();
	// ここはroot開放時に通る＝プログラム終了時
#ifdef	USE_BLUETOOTH
	[self endOfBluetooth];
#endif
		
}

//----------------------------------
#pragma mark -
			   
#ifdef USE_ALARM
// labelAlarmの表示（イベント種類）
// event=EVENT_*
NSString *labelAlarmDisplay(UILabel *lblAlarm,NSUInteger event)
{
	printFuncs(@"%d",(int)event);
	UIColor *col;
	NSString *str;
	switch (event) {
		default: // 警告回避のため
		case EVENT_NONE:
			str=SYMBOL_NONE;
			col=[UIColor grayColor]; // こうしないと568画面＝下が黒地の時に見えなくなる
			break;
		case EVENT_ALARM:
		case EVENT_ALARM1:
			str=SYMBOL_ALARM;
			col=[UIColor redColor];
			break;
		case EVENT_CONSTANT:
			str=SYMBOL_CONSTANT;
			col=[UIColor whiteColor];
			break;
		case EVENT_1SHOT:
			str=SYMBOL_1SHOT;
			col=[UIColor whiteColor];
			break;
	}
	lblAlarm.text=str;
	lblAlarm.textColor=col;
	return (str);
}
#endif

-(void)setQuality:(CGFloat)quality_
{
	_quality=quality_;
}

//----------------------------------------------
// Bluetooth
//----------------------------------------------

#ifdef USE_BLUETOOTH
			   
// Bluetooth処理中処理
// ここは、bluetoothクラス内から呼び出されるため、この中での送受信はできない
- (void)bluetoothDidConnected:(Bluetooth *)bt
{
	printSelfs(@"fconnect=%d",bt.fconnect);
	switch (bt.fconnect) {
		case BT_CONNECT_OK:
			nslog(@"Bluetooth相互接続完了");
			btnBluetoothStatus.hidden=NO; // 通信中マーク表示
			[self performSelectorOnMainThread:@selector(setImageBluetoothInMainThread:) withObject:@(NO) waitUntilDone:NO];
			break;
		case BT_CONNECT_CANCEL:
			nslog(@"Bluetoothキャンセル");
			[self disconnectBluetooth:NO]; // close処理は走らない
		default:
			break;
	}
}

-(void)setImageBluetoothInMainThread:(NSNumber *)num
{
	printSelf();
	BOOL flag=[num boolValue];
	btnBluetoothStatus.hidden=flag;
}

-(void)bluetoothSelectShow:(MCBrowserViewController *)mvc
{
	[self presentViewController:mvc animated:YES completion:nil];
}
			   
// Bluetooth接続時は接続解除
-(void)disconnectBluetooth:(BOOL)fwithCommand
{
	if (bluetooth!=nil) {
		nslog(@"Bluetooth実接続解除");
		if (fwithCommand) {
			[bluetooth send:BT_COMMAND_DISCONNECT]; // 接続解除命令を発行
		}
		// 接続開放の印をつけるだけ；インスタンス自体はそのままにしておく
		bluetooth.fconnect=BT_CONNECT_NONE;
		btnBluetoothStatus.hidden=YES; // 通信中マーク消去
		[self performSelectorOnMainThread:@selector(setImageBluetoothInMainThread:) withObject:@(YES) waitUntilDone:NO];
	}
}

// コマンド受信関数
- (void)bluetoothDidRecieve:(NSData *)data peer:(MCPeerID *)peerID
{
	printSelf();
	// モード要請があった場合は、そのモードに変更する
	unichar c=[bluetooth readReceiveBuff];
	nslog(@"com=%c($%04x)",c,c);
	switch (c) {
		case BT_COMMAND_RESULT:
			nslog(@"レコーダー側からの応答無視");
			// どこから来てるかは不明(^_^;)
			break;
		case BT_COMMAND_RECEND:
			// リモコンからBT_COMMAND_RECENDを送ると、レコーダー側のRecCencel処理からBT_COMMAND_RECENDが送られてくるので、それを無視させる
			nslog(@"レコーダー側からのRecCancel無視");
			break;
		
		case BT_COMMAND_DISCONNECT:
			nslog(@"BT接続解除");
			[self disconnectBluetooth:NO];
			clickSound();
			break;
	}
}

// 接続先選択中にキャンセルした時呼び出される
// それは、リモコン画面の上に表示されている
-(void)bluetoothCancelConnect:(Bluetooth *)bt
{
	printSelf();
	bt.fremote=BT_REMOTE_CANCEL;
	// 相手をキャンセルさせたいけど接続できてないから無理
//	[self disconnectBluetooth:NO];
}

-(BOOL)connect:(BT_REMOTE)fremote
{
	printSelf();
	clickSound(); // クリック音
	if (bluetooth==nil) {
		// 初回接続時
		nslog(@"Bluetooth初回接続開始");
		bluetooth=[[Bluetooth alloc]init];
		bluetooth.delegate=self;
	} // else 接続回復
// 接続解除はbluetoothボタンへ移動
//	if (bluetooth.fconnect!=BT_CONNECT_NONE) {
//		// 接続時は接続終了
//		nslog(@"Bluetooth接続解除ボタン押下");
//		[self disconnectBluetooth:YES];
//		return YES;
//	}
	nslog(@"Bluetooth接続開始");
	// 接続ダイアログ表示
	bluetooth.fremote=fremote;
	[bluetooth open:NSLocalizedString(PROGRAM_NAME,@"Bluetooth接続名")]; // ホスト時はここで選択画面の表示命令がかかるが、
	nslog(@"Bluetooth接続表面上完了:%d",bluetooth.fconnect);
	// ダイアログは表示されたままここを通過する
	// でも、接続が完了/キャンセルするまでダイアログは消えない
	return NO;
}

#endif	// USE_BLUETOOTH

//----------------------------------------------
// ボタン押下時処理
//----------------------------------------------
#pragma mark ボタン押下

#ifdef USE_BLUETOOTH
-(IBAction)buttonBluetooth:(id)sender
{
	printSelf();
	if (bluetooth.fconnect!=BT_CONNECT_NONE) {
		// 接続時は接続終了
		nslog(@"Bluetooth接続解除ボタン押下");
		[self disconnectBluetooth:YES];
	}
}
#endif

-(IBAction)buttonAction:(UIBarButtonItem *)btn
{
	printSelfs(@"btn:%d",(int)btn.tag);

	switch (btn.tag) {
#ifdef USE_BLUETOOTH
		// 設定でbluetoothがONの時のみ此処に来る
		case BUTTON_BLUETOOTH:
			switch (bluetooth.fconnect) {
				default:
					nslog(@"他の状態の時は、先に一旦接続解除する:%d",bluetooth.fconnect);
					[self disconnectBluetooth:YES];
				case BT_CONNECT_NONE:
					nslog(@"未接続状態なのでまずは接続");
					if ([self connect:BT_REMOTE_YES]) break; // リモコンモードで接続失敗
					// 接続成功
				case BT_CONNECT_OK:
					// すでに接続が完了している
					nslog(@"リモコンモード");
					self.remoteViewController=[[RemoteViewController alloc]init];
					[self.remoteViewController open:bluetooth];
					// 選択画面表示の前にここまでは来てる
					// しかし、先に選択画面が表示されるため、remoteVCはviewDidLoad前で保留されている
					clickSound(); // クリック音
					[self.navigationController pushViewController:self.remoteViewController animated:YES];
					break;
			}
			break;
#endif

		case BUTTON_REC:
#ifdef USE_BLUETOOTH
			if (setup.fbluetoothShutter) {
				switch (bluetooth.fconnect) {
					default:
						nslog(@"他の状態の時は、先に一旦接続解除する");
						[self disconnectBluetooth:YES];
					case BT_CONNECT_NONE:
						nslog(@"未接続状態なのでまずは接続");
						if ([self connect:BT_REMOTE_NO]) break; // 受信側で接続失敗
						// 接続成功
					case BT_CONNECT_OK:
						// すでに接続が完了しているときは何もしない
						break;
				}
			}
#endif
			[self buttonRec]; // 実処理
			break;
		
		case BUTTON_HELP:
		{
			// ヘルプボタン押下から実表示までに非常に時間がかかることがあるのでIndicatorを回すようにした
			UIActivityIndicatorView *indicator=[UIActivityIndicatorView show:self.view style:UIActivityIndicatorViewStyleWhiteLarge fbackground:YES];

#ifdef USE_BLUETOOTH
			[self disconnectBluetooth:YES];
#endif
			[app.recViewController recEnd];
			//
			HelpViewController *helpViewController=[[HelpViewController alloc]init];
			[helpViewController open:@"help" title:@"HELPTITLE"];
			clickSound(); // クリック音
			[self.navigationController pushViewController:helpViewController animated:YES];

			// ActivityIndicatorを消す
			[indicator dismiss];
			break;
		
		}
		case BUTTON_SETTING:
#ifdef USE_BLUETOOTH
			[self disconnectBluetooth:YES];
#endif
			[app.recViewController recEnd];
			//
			SetupViewController	*setupViewController =[[SetupViewController alloc]init];
			clickSound(); // クリック音
			[self.navigationController pushViewController:setupViewController animated:YES];
			break;
	}
}

// Rec処理
-(void)buttonRec
{
	printSelf();
	clickSound(); // クリック音
#ifdef DISABLE_UPSIDE_REC
	// 上下不明方向の時は録画に移行させない
	if (checkDeviceOrientationOK()==NO) {
		[alertSymbol display:TM_ALERT_DISPLAY];
		return;
	}
	// ×が表示されていても方向がOKになったら録画へ行かせる
	imageAlert.hidden=YES;
#endif
	
#ifdef USE_BATTERY
	// 電池チェック
	BatteryCheck *batteryCheck=[[BatteryCheck alloc]init];
	BOOL f=[batteryCheck check];
	if (f) return; // →残量足りない
#endif
	//
	self.aviPath=nil;
	self.aviPathDelete=nil;
	if (app.recViewController.frec==REC_NONE) {
		// 以下の処理は重たいので、ActivityIndicatorを表示する
		UIActivityIndicatorView *indicator=[UIActivityIndicatorView show:self.view style:UIActivityIndicatorViewStyleWhiteLarge fbackground:YES];
		// 録画準備中
		app.recViewController.frec=REC_PREPARE;
		
		// 方向検出検出；盗撮防止のためと、オーバーレイの回転用
		[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
		// 回転に対する通知先の登録(停止はRecViewController:RecCancelにある)
		// 画面回転があるため、画面回転アラームのあり・なしにかかわらず登録する
		[[NSNotificationCenter defaultCenter] addObserver:app.recViewController
												 selector:@selector(orientationChanged:)
													 name:UIDeviceOrientationDidChangeNotification
												   object:nil];
		if (isJIKKI()) {
			nslog(@"実機：カメラ起動");
			// ここでボタンを変えても無効
			UIImagePickerController *imgPicker= [app.recViewController startImagePicker];
			// UIImagePickerControllerインスタンスの実体は recViewController.imgPickerに確保されている。
			// ここで代入しているのは、presentModalViewControllerによる画面表示のためのアドレスのみ。
			//
			// 初回のみ時間がかかる;この間は画面回転は認識されない
			// ↓ここで画面が変わるが、プログラム自体は進んでこのメソッドを抜ける
			[self presentViewController:imgPicker animated:YES completion:NULL];
			// ↑ここでIOKitのwarningが2つ出るが無視する
			// これ↑がカメラ起動待ちになる
			// オーバーレイの代わりに、ビューを表示する;そうでないとviewDidLoadが使えないため
#ifdef USE_BLUETOOTH
			[app.recViewController setBluetooth:bluetooth];
#endif
			// window背景色を復帰
			app.window.backgroundColor=winColor;
			[app.window addSubview:app.recViewController.view];
		}
		[indicator dismiss]; // ActivityIndicatorを消す
		//
		nslog(@"録画動作中のはず");
	} else { // 実機ではありえないが、シミュレーター上でのため
		[app.recViewController recEnd];
	}
}

//--------------------------------------

// 画像サイズの設定
-(void)setImageSize:(CGRect)imageSize_
{
	printSelfs(@"setImageSize=%@",NSStringFromCGRect(imageSize_));
	_imageSize=imageSize_;
}

#ifdef USE_COLORSELECT
// 日付写し込み位置計算
-(void)calcAtrbPoint:(NSString *)text font:(UIFont *)font
{
	CGSize size = [text sizeWithFont7:font]; // 描画文字列のサイズを得る
	switch (setup.atrbPosition) {
		case ATRB_POSITION_TOP_LEFT:
			atrbPoint.x=XOFST_ATRB;
			atrbPoint.y=YOFST_ATRB;
			break;
		case ATRB_POSITION_TOP_CENTER:
			atrbPoint.x=(_imageSize.size.width-size.width)/2;
			atrbPoint.y=YOFST_ATRB;
			break;
		case ATRB_POSITION_TOP_RIGHT:
			atrbPoint.x=_imageSize.size.width-size.width-XOFST_ATRB;
			atrbPoint.y=YOFST_ATRB;
			break;
		case ATRB_POSITION_BOTTOM_LEFT:
			atrbPoint.x=XOFST_ATRB;
			atrbPoint.y=_imageSize.size.height-size.height-YOFST_ATRB;
			break;
		case ATRB_POSITION_BOTTOM_CENTER:
			atrbPoint.x=(_imageSize.size.width -size.width)/2;
			atrbPoint.y= _imageSize.size.height-size.height-YOFST_ATRB;
			break;
		case ATRB_POSITION_BOTTOM_RIGHT:
			atrbPoint.x=_imageSize.size.width -size.width -XOFST_ATRB;
			atrbPoint.y=_imageSize.size.height-size.height-YOFST_ATRB;
			break;
	}
}
#endif

//--------------------------------------
// AVIファイル
//--------------------------------------

// ファイルエラー処理
-(void)fileError:(NSNotification *)notification
{
	NSString *errname=[notification userInfo][KEY_ERRNAME]; // ローカルに作られているので、先に保持しておく
	nslog(@"NotficationFileError:%@",[notification object]);
	Alert1([notification object],errname,nil);
	setLog(LOG_NAME_FERR);
#ifdef USE_BLUETOOTH
	if (bluetooth!=nil) {
		nslog(@"Bluetoothエラー通知");
		[bluetooth send:BT_COMMAND_ERROR];
	}
#endif
	[app.recViewController recEnd];
	// 画面も戻る
}

//--------------------------------------

// 各ファイルオープン
-(void)AVIfileOpen
{
	printSelf();
	fsaveAlbum=NO; // 念のため
	self.aviPath = makeFullPathForSaveDataFromDate(@"Rec.avi"); // フルパス名を保存（削除用）

	NSFileManager *fileManager=[NSFileManager defaultManager];
	if (![fileManager createFileAtPath:self.aviPath contents:nil attributes:nil]) {
		// ファイルが作成できない !!error!!
		self.aviPath=nil;
		nslog(@"ファイルが作成できません");
		FileError(@"ERR_TITLE_FILECREAT",@"ERR_MES_FILECREAT",nil);
	}
	// ファイルが作成できたとき、そのファイルを更新用としてアクセス出来るようにする
	self.fhAVI = [NSFileHandle fileHandleForUpdatingAtPath:self.aviPath]; // "w+"相当;あっちこっちで呼び出すものはcopyしておく
	if (self.fhAVI==nil) {
		self.aviPath=nil;
		nslog(@"ファイルを更新対象にできません");
		FileError(@"ERR_TITLE_FILEUPDATE",@"ERR_MES_FILEUPDATE",nil);
	}
	nslog(@"fhAVI=%@",self.fhAVI);
	
	NSUInteger playbackSpeed=(NSUInteger)[setup getTmValues:TMPlaybackSpeed];
//	nslog(@"再生速度=%d",playbackSpeed);
	StartAVI(self.fhAVI,_imageSize,playbackSpeed,AVI_MAX1JPEG);
	//
	aviPics=0; // ファイル内記録枚数
}

// 各ファイルのクローズ＆ファイルをアルバムへコピー
-(void)AVIfileClose
{
	printSelfs(@"aviPath=%@",self.aviPath);
	fsaveAlbum=NO;
	
	nslog(@"アルバムへコピー処理開始");
	[self.view setNeedsDisplay]; // 再描画要請（閉じる前の画像は表示する）
	// 再描画までの間にファイル処理を進めておく
	EndAVI(self.fhAVI);
	[self.fhAVI synchronizeFile]; // 確実にすべて書き出す
	[self.fhAVI closeFile]; // ファイルを閉じる
	self.fhAVI=nil; // copy属性なので

	if (aviPics>0) {
		// ファイルをアルバムへコピー
		self.aviPathDelete=self.aviPath; // 削除用に保管する（aviPathは次のファイルオープンに必要なので）
		if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(self.aviPath)) {
			nslog(@"アルバムへコピー可なのでコピー命令発行:aviPath=%@",self.aviPath);
			fsaveAlbum=YES; // アルバムへコピー中の印
			UISaveVideoAtPathToSavedPhotosAlbum(self.aviPath, self,@selector(image:didFinishSavingWithError:contextInfo:), NULL);
			// ↑はvoid関数なので、ここではエラーは取れない。そのかわり下記のimage:デリゲートで判定できる
			// 以下並行動作
		} else {
			nslog(@"このデバイスではアルバムにコピー出来ません");
			Alert1(@"ERROR", @"ALBUMCOPY", self);
		}
		aviPics=0;
		// 即次のAVIfileOpenが来る/RecEnd時はこれで終了
	} else { // 画像の入ってないAVIは消すだけ
		self.aviPathDelete=nil;
		fileDelete(self.aviPath);
		// Rec終了時のみだけなので次にAVIfileOpenは続かない
	}
	// 次のファイルオープンに備えaviPathは開放しておく
	self.aviPath=nil;
	nslog(@"アルバムへコピー命令発行終了");
}

// アルバム保存時のエラー判定
-(void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
	nslog(@"アルバム保存終了処理開始");
	if (self.aviPathDelete==nil) {
		nslog(@"何故か二重呼び出しされているので無視");
		return;
	}

	if (error) { // エラー !!error!!
		nslog(@"保存エラー:%@",error);
		nslog(@"contextInfo=%p",contextInfo);
		// 保存中にHOME+電源で画面撮影などすると出るようである
		FileError(@"ERR_TITLE_ALBUM",@"ERR_MES_ALBUM",nil);
	} else {
		nslog(@"保存正常終了");
		// 保存ができた時だけ、元ファイル削除
		fileDelete(self.aviPathDelete);
		self.aviPathDelete=nil;
	}
	fsaveAlbum=NO; // いずれにせよ保存処理終了
	nslog(@"アルバム保存終了処理終了");
}

// pathの削除
-(void)AVIfileDelete:(NSString *)path
{
	printSelf();
	fileDelete(path); // ファイル削除
	// 削除が終わったらpathを解放する
//	path=nil;
}

// アルバムへのコピー終了待ち
-(void)AVIwaitAlbumCopyEnd
{
	printSelf();
	while (fsaveAlbum) {
		// runUntilDate=指定時間までの間RunLoopに戻る
		EnterRunLoop(TM_CHECK_OPERATION);
	}
}

-(void)imageUpdateInMainThread:(UIImage *)image
{
	_imageView.image = image;
//	nslog(@"image=%@",image);
}

// 画像ファイルの書き出し
// アルバムじゃなくて、ファイルを開いて独自に保存する
-(void)AVIfileWrite:(UIImage *)image text:(NSString *)mes_
{
	printSelf();
	NSString *mes=[mes_ copy]; // 呼び出し側が開放してもいいように

	nslog(@"サイズに合わせて画像圧縮");
	// ImagePickerは回転してもframeが変更されない(縦横サイズが入れ替わらない)ので、別途回転を認識してサイズを与える必要がある
	printFrame(@"実録画時画像サイズ",_imageSize);
	//
	nslog(@"_imageSize=%f*%f",_imageSize.size.width,_imageSize.size.height);
	UIGraphicsBeginImageContext(_imageSize.size); // サイズでワーク確保
	[image drawInRect:_imageSize]; // 縮小処理
#ifdef USE_COLORSELECT
	if (setup.atrbPosition!=ATRB_POSITION_NONE) {
		// 日時写しこみ
		UIFont *font=[UIFont fontWithName:@"Times New Roman" size:28];
		NSString *text=setup.latestDate;
		[self calcAtrbPoint:text font:font]; // 描画位置の計算
		[text drawAtPoint7:atrbPoint withFont:font withColor:getColor(setup.atrbColor)];
	}
#endif
	image=UIGraphicsGetImageFromCurrentImageContext(); // 縮小後画像取得
	// 最新画像記録
#if 1
	[self performSelectorOnMainThread:@selector(imageUpdateInMainThread:) withObject:image waitUntilDone:NO];
#else
	_imageView.image = image; // 記録は必要；これを取り払っても(表示)速度も画面止まりも変わらない
	nslog(@"image=%@",image);
	// 表示はImagePickerViewに任せる
	//	[self.view setNeedsDisplay]; // 再描画要請；これを入れても画面更新が止まることがある
#endif
	
	nslog(@"画質=%f",_quality);
	// imageは直接記録できないので、再圧縮してNSData化して記録する
	// 再圧縮するので、元の画像(拡張子)が何であるかは関係ない
	NSData *data=UIImageJPEGRepresentation(image,_quality);
//	nslog(@"imgdata=%@",data);

	nslog(@"fhAVI=%@",self.fhAVI);
	AviMain(self.fhAVI,data,mes);
	//
	// 本当は最新画像は保存しておきたいが、メモリが切迫するので解放する
	//
	UIGraphicsEndImageContext(); // ワーク開放
	// 撮影枚数＋１;実撮影終了後にカウントする
	nslog(@"撮影枚数+1=%u;max=%ld",(int)aviPics+1,GetMaxPics());
	[setup incPictures:PICTURE_LATEST];
	
	if (++aviPics>=GetMaxPics()) {
		// 一定枚数ごとにファイル分割
		nslog(@"ファイル分割:aviPics=%d:GetMaxPics=%ld",(int)aviPics,GetMaxPics());
		// 前のファイルクローズ＆ファイルをアルバムへコピー（次のコピー＝分割タイミングまでには時間があるので、コピー終了待ちはしてない）
		[self AVIfileClose];
		// 次のファイルオープン
		[self AVIfileOpen];
	}
	//
	nslog(@"AVIfileWrite end");
}

//--------------------------------------
// 最新画像情報保存・読み出し
//--------------------------------------

-(void)setLabelDateAndAlarm:(NSString *)date Alarm:(NSString *)alarm
{
	printSelfs(@"date=%@",date);
	_labelDate.text =date;
#ifdef USE_ALARM
	nslog(@"alarm=%@",alarm);
	_labelAlarm.text=alarm;
#endif
}

// 最新画像表示などを保存する(次回表示するため)
-(void)saveLatestPicture
{
	printSelf();
	
	NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
	
	// 最新画像保存
	NSData *imgdata=[[NSData alloc]initWithData:UIImageJPEGRepresentation(_imageView.image,_quality)]; // 最新画像を再圧縮する
	[defaults setObject:imgdata forKey:keyLatestPicture];

	// 録画枚数/回数更新
	// KOMADORIでも内部的には枚数を数えておく
	for (NSUInteger i=PICTURE_LATEST;i<MAX_PICTURES;i++) {
		NSUInteger pics=[setup getPictures:i];
		nslog(@"(%d)key=%@:%d",(int)i,[NSString stringWithFormat:keyPictures,(int)i],(int)pics);
		[defaults setInteger:pics forKey:[NSString stringWithFormat:keyPictures,(int)i]];
	}
	[defaults synchronize]; // 同期(即時反映);iOS4では必須
	
	// 最新情報の記録
	[setup saveLatestData];
}

// 最新画像状態を復元
-(void)loadLatestPicture
{
	printSelf();
	// 最新録画画像を表示する
	NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
	id obj=[defaults objectForKey:keyLatestPicture];
	UIImage *img;
	if (obj!=nil) {
		nslog(@"記録画像");
		img=[[UIImage alloc]initWithData:obj]; // 画像展開
		
	} else { // 最新録画画像がないとき＝一番初期
		NSString *path=makeFullPathForResource(MAINVIEW_IMG,nil); // リソース内のパスを得る
		nslog(@"最初画像=%@",path);
		img=[[UIImage alloc]initWithContentsOfFile:path];

	}
	// こういう2段構えで代入しないとメモリリークが起きる
	nslog(@"imageView=%@",_imageView);
	_imageView.image=img;
	[self.view setNeedsDisplay]; // 再描画要請

	// 枚数/回数読み出し
	for (NSUInteger i=PICTURE_LATEST;i<MAX_PICTURES;i++) {
		[setup setPictures:[defaults integerForKey:[NSString stringWithFormat:keyPictures,(int)i]] valno:i]; // 見つからないときは0が入る
	}
	// 日時
	obj=[defaults objectForKey:keyLatestDate];
	_labelDate.text=dateFormatJtoE(obj); // copyされる
	nslog(@"_labelDate.text=%@",_labelDate.text);
#ifdef USE_ALARM
	// イベント
	obj=[defaults objectForKey:keyLatestAlarm];
	if (obj!=nil) {
		_labelAlarm.text=obj;
		nslog(@"labelAlarm=%@",_labelAlarm.text);
	} else {
		labelAlarmDisplay(_labelAlarm,EVENT_NONE);
		nslog(@"labelAlarm=%@(INIT)",_labelAlarm.text);
	}
#endif
}

//--------------------------------------

@end
