//
//  setup.m
//  ZeroRec/Komadori
//
//  Created by AIG-Soft on 11/03/01.
//  Copyright 2011 AIG-Soft. All rights reserved.
//

#import "main.h"
#import "Setup.h"
#import "click.h"
#import "libs.h"

//-----------------------------------------
// 設定表
// NSTimeIntervalは整数位が秒、少数位がms単位のfloat値なのでCの配列にできる
// 必ず何処かにdef〜=デフォルト値を入れること
// 録画系インターバルの最小値は2.0。実測により、これ以下では無理があると思われるので。
// 小数点は第一位まで(EquFloat();lib.hの実装にも関係する)。
#ifdef USE_EXITDELAY
NSTimeInterval	tblExitDelay[]		 ={None,30.0,tMin(1),tMin(2),tMin(3),tMin(4),tMin(5),tMin(10)};
#endif
#ifdef USE_CONSTANT
NSTimeInterval	tblConstantInterval[]={
										None,
									#ifdef KOMADORI
										PIC1,	// こまどり君では1shotがデフォルト
									#endif
										2.5,3.0,4.0,5.0,10.0,15.0,20.0,30.0,45.0,60.0,90.0,120.0};
#endif

#if defined(USE_ALARM)
NSTimeInterval	tblAlarmLimit[]		 ={
										None,								// MOVでは無制限は出来ない
										tMin(1),tMin(2),tMin(5),tMin(10)	// MOVはiOSで上限10分なので
												,tMin(30),tMin(60)
									  };
NSTimeInterval	tblAlarmYokushi[]	 ={None,3.0,5.0,10.0,15.0,20.0,25.0,30.0};
#endif	// USE_ALARM

#if defined(USE_ALARM)||defined(USE_NSHOT)
NSTimeInterval	tblAlarmInterval[]	 ={None,2.5,3.0,4.0,5.0};
#ifdef USE_NSHOT
NSTimeInterval	tblAlarmPost[]		 ={None,1,2,3,4,5,6,8,10,12,24,30,60}; 				// 枚数；後でインターバルからポスト時間を計算する
#else	// 通常アラーム
NSTimeInterval	tblAlarmPost[]		 ={PIC1,5.0,10.0,20.0,30.0,45.0,60.0,90.0,120.0};	// 秒
#endif
#endif	// USE_ALARM

NSTimeInterval	tblPlaybackSpeed[]	 ={30.0,24.0,15.0,12.0,10.0,8.0,6.0,5.0,4.0,2.0,1.0};
NSTimeInterval	tblMaxPics[]		 ={
									#ifdef DEBUG
										50.0,100.0,
									#endif
										500.0,1000.0,2000.0,3000.0,4000.0,5000.0,6000.0,7000.0,8000.0,9000.0,10000.0
									};
//・表示文字列はこれから作成する
//・設定値は内容そのものを記録する；要素番号では記録しない；将来の変更時に対応できるようにするため

// 画像圧縮率;[Quality]で得る
CGFloat tblQuality[MAX_QUALITY]={0.3,0.45,0.6,0.8};

#ifdef USE_COLORSELECT
// 色定義 : aplhaはすべて1.0にする
RGB rgb[]={ // 色選択のtag値の順
	{0.0,0.0,0.0},		// 0
	{0.0,0.0,1.0},		// 1
	{0.6,0.4,0.2},		// 2
	{0.0,1.0,1.0},		// 3
	{0.0,1.0,0.0},		// 4
	{1.0,0.0,1.0},		// 5
	{1.0,0.5,0.0},		// 6
	{0.5,0.0,0.5},		// 7
	{1.0,0.0,0.0},		// 8
	{1.0,1.0,0.0},		// 9
	{0.33,0.33,0.33},	// 10
	{0.67,0.67,0.67},	// 11
	// 最後を白にすること
	{1.0,1.0,1.0}		// 12
}; // setyp._atrbColorはこの要素番号
// ここの数を変更したときはCOLORS;setup.hも変更すること
#define	COLOR_WHITE	((sizeof(rgb)/sizeof(RGB))-1) // 白の番号
//#if COLORS != COLOR_WHITE+1 // この式が何故かエラーが出るからコメント化;プリプロセッサ内ではsizeof(rgb)が決定しないからだと思われる
//#warning "COLORS;setup.hの数が正しくありません。"
//#endif
#endif	// USE_COLORSELECT

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

@implementation Setup

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

#ifdef USE_COLORSELECT
// 色番号から色を得る
UIColor *getColor(NSUInteger cno)
{
	return [UIColor colorWithRed:rgb[cno].r green:rgb[cno].g blue:rgb[cno].b alpha:1.0];
}

// 色選択のデフォルト色
// COLOR_WHITEはこのソースの中でしか参照できないから
NSUInteger getDefaultColorNo(void)
{
	// 変えてもかまわない
	return (COLOR_WHITE);
}

// 白色の番号
// COLOR_WHITEはこのソースの中でしか参照できないから
NSUInteger getWhiteColorNo(void)
{
	// 変えてはいけない
	return (COLOR_WHITE);
}

NSUInteger getColorPercent(NSUInteger cno,NSUInteger *r,NSUInteger *g)
{
	*r=(NSUInteger)(rgb[cno].r*100.0);
	*g=(NSUInteger)(rgb[cno].g*100.0);
	return ((NSUInteger)(rgb[cno].b*100.0));
}
#endif

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

- (void)setPictures:(NSUInteger)pics valno:(NSUInteger)no
{
#ifdef DEBUG
	if (no>=MAX_PICTURES) {
		nslog(@"no異常=%d",(int)no);
	}
#endif
	pictures[no]=pics;
}

- (void)incPictures:(NSUInteger)no
{
#ifdef DEBUG
	if (no>=MAX_PICTURES) {
		nslog(@"no異常=%d",(int)no);
	}
#endif
	pictures[no]++;
}

- (NSUInteger)getPictures:(NSUInteger)no
{
#ifdef DEBUG
	if (no>=MAX_PICTURES) {
		nslog(@"no異常=%d",(int)no);
	}
#endif
	return (pictures[no]);
}

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

- (void)setTmValues:(NSTimeInterval)tm valno:(NSUInteger)no
{
#ifdef DEBUG
	if (no>=MAX_TMValues) {
		nslog(@"no異常=%d",(int)no);
	}
#endif
	nslog(@"setTmValues:[%d]=%f",(int)no,tm);
	tmValues[no]=tm;
}

-(NSTimeInterval)getTmValues:(NSUInteger)no
{
#ifdef DEBUG
	if (no>=MAX_TMValues) {
		nslog(@"no異常=%d",(int)no);
	}
#endif
	nslog(@"getTmValues:%d=%f",(int)no,tmValues[no]);
	return(tmValues[no]);
}

// 実値から配列要素番号を得る
NSInteger searchTbl(NSTimeInterval *tbl,NSTimeInterval tm,NSUInteger cnt)
{
	nslog(@"searchTbl=%f,cnt=%d",tm,(int)cnt);
	for	(NSInteger i=0;i<cnt;i++) {
		// 浮動小数点比較では==は使えない
		// if (tbl[i]==tm) return(i);
		nslog(@"tbl[%d]=%f:%f,Δ=%f",(int)i,tbl[i],tm,tbl[i]-tm);
		if (EquFloat(tbl[i],tm)) return(i);
	}
	// ここに来てはいけない
	nslog(@"searchTbl異常:%f",tm);
	return(-1);
}

//-----------------------------------------
// 以下、内部ではCountTbl();Setup.hが使えるが、外部では使えないので関数化する

#ifdef USE_CONSTANT
NSUInteger countTblConstantInterval(void)
{
	return(CountTbl(tblConstantInterval));
}
#endif

#ifdef USE_EXITDELAY
NSUInteger countTblExitDelay(void)
{
	return(CountTbl(tblExitDelay));
}
#endif

#if defined(USE_ALARM)||defined(USE_NSHOT)
NSUInteger countTblAlarmPost(void)
{
	return(CountTbl(tblAlarmPost));
}
NSUInteger countTblAlarmInterval(void)
{
	return(CountTbl(tblAlarmInterval));
}
#endif

#if defined(USE_ALARM)
NSUInteger countTblAlarmYokushi(void)
{
	return(CountTbl(tblAlarmYokushi));
}
NSUInteger countTblAlarmLimit(void)
{
	return(CountTbl(tblAlarmLimit));
}
#endif

NSUInteger countTblPlaybackSpeed(void)
{
	return(CountTbl(tblPlaybackSpeed));
}
NSUInteger countTblMaxPics(void)
{
	return(CountTbl(tblMaxPics));
}

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

// NSTimeInterval系数値の表示用文字列作成
// Setup/ログ表示
-(NSString *)makeTimeIntervalMessage:(NSTimeInterval)tm fmin:(BOOL)fminute fchange:(NSUInteger)fchange
{
	NSString *fmt;
	if (tm==None) {
		return NSLocalizedString(@"NONE",@"なし");
	}
	if (EquFloat(tm,PIC1)) {
		return NSLocalizedString(
									#ifndef KOMADORI
										 @"1PIC"
									#else
										 @"1SHOT"
									#endif
										 ,@"1枚"
								 );
	}
	if (tm<1.0) { // 0.?秒
		return [NSString stringWithFormat:NSLocalStr(@"0SEC"),(NSUInteger)(tm*10.0)];
	}
	switch (fchange) {
		default:
			fmt=NSLocalStr(@"1SEC"); // ?秒
			break;
		case FMT_PLAYBACKSPEED:
			fmt=NSLocalStr(@"SEC1"); // 秒?枚
			break;
		case FMT_NSHOT:
			nslog(@"FMT_NSHOT");
		case FMT_MAXPICS:
			fmt=NSLocalStr(@"PICS"); // 枚
			break;
	}
	NSUInteger tmi=(NSUInteger)(tm);
	if (tm!=(NSTimeInterval)tmi) { // 小数点以下があるとき
		 // ?.?秒
		return [NSString stringWithFormat:NSLocalStr(@"1.5SEC"),tmi,(NSUInteger)(tm*10.0)-tmi*10];
	}
	if (tmi!=(NSUInteger)(tm/60.0)*60) {
		// 分で割り切れないときは、fminute指定を無視する＝秒表示にする
		fminute=NO;
	}
	if (fminute) { // ?分
		fmt=NSLocalStr(@"1MIN");
		tmi=(NSUInteger)(tm/60.0);
	} 
	return [NSString stringWithFormat:fmt,tmi];
}

-(NSString *)makeTimeIntervalMessage:(NSTimeInterval)tm fmin:(BOOL)fminute
{
	return [self makeTimeIntervalMessage:tm fmin:fminute fchange:FMT_NONE];
}
-(NSString *)makeTimeIntervalMessage:(NSTimeInterval)tm
{
	return [self makeTimeIntervalMessage:tm fmin:NO fchange:FMT_NONE];
}

// 指定されたテーブルを文字列にする
-(NSArray *)setTimeIntervalMessages:(NSTimeInterval *)tbl
							  count:(NSUInteger)cnt
							   fmin:(BOOL)fminute
							fchange:(NSUInteger)fchange
{
	NSMutableArray *mes=[[NSMutableArray alloc]init];
	for (NSUInteger i=0;i<cnt;i++) {
		[mes addObject:[self makeTimeIntervalMessage:tbl[i] fmin:fminute fchange:fchange]];
		// 終端は自動的に付くので、付加不要(というかnilを追加しようとすると例外が発生する)
	} // for
	return mes;
}

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

#ifdef USE_COLORSELECT
-(NSArray *)setAtrbPositionArray
{
	return	@[	NSLocalStr(@"NONE"),
				NSLocalizedString(@"TOPLEFT"	 ,@"上左"	),
				NSLocalizedString(@"TOPCENTER"	 ,@"上中央"	),
				NSLocalizedString(@"TOPRIGHT"	 ,@"上右"	),
				NSLocalizedString(@"BOTTOMLEFT"	 ,@"下左"	),
				NSLocalizedString(@"BOTTOMCENTER",@"下中央"	),
				NSLocalizedString(@"BOTTOMRIGHT" ,@"下右"	),
	 ];
}
#endif

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

NSString *textSegmentQuality(NSUInteger quality)
{
	switch(quality) {
		case QUALITY_LOW:
			return NSLocalizedString(@"LOW"		,@"低"	);
		case QUALITY_STD:
			return NSLocalizedString(@"STD"		,@"標準"	);
		case QUALITY_HIGH:
			return NSLocalizedString(@"HIGH"	,@"高"	);
		case QUALITY_SUPER:
			return NSLocalizedString(@"SUPER"	,@"超高"	);
	}
	// ここには来ないが念のため
	return(@"おかしい");
}

#ifdef USE_COUNT
-(void)makePicturesCount:(NSMutableString *)mstr textView:(UITextView *)textView
// 枚数カウント文字列を作る(文字列/表示)
{
	NSUInteger apics=pictures[PICTURE_ALARM];
	NSUInteger cpics=pictures[PICTURE_CONSTANT];
	//
	NSString *spc;
	//
	spc=leftString2(@"PICTURES_TOTAL",YES,textView);
	[mstr appendFormat:@"%@%@%08d\n",SPC2,spc,(int)(apics+cpics)];
	//
#if defined(USE_ALARM)
	spc=leftString2(@"PICTURES_ALARM",YES,textView);
	[mstr appendFormat:@"%@%@%08d\n",SPC4,spc,(int)apics];
	//
#endif
#ifdef USE_CONSTANT
	spc=leftString2(@"PICTURES_CONSTANT",YES,textView);
	[mstr appendFormat:@"%@%@%08d\n",SPC4,spc,(int)cpics];
#endif
	spc=leftString2(@"PICTURES_LATEST",YES,textView);
	[mstr appendFormat:@"%@%@%08d\n",SPC4,spc,(int)pictures[PICTURE_LATEST]];
}
#endif

#if defined(USE_ALARM)
// アラーム源の文字列化
-(void)makeAlarmSource:(NSMutableString *)mstr textView:(UITextView *)textView
{
	NSString *spc=leftString2(@"ALARMSHAKE"	,YES,textView);
	[mstr appendFormat:@"%@%@%@\n",SPC2,spc,mesONOFF(_falarmShake)];
	//
	// 英語時のみ
	if ([[NSLocalStr(@"JP") substringToIndex:1]isEqualToString:@"J"]) {
		// 英語:2行化
		[mstr appendFormat:@"%@%@\n",SPC2,NSLocalStr(@"ALARMROTATION")];
		spc=leftString2(@"",NO,textView);
		[mstr appendFormat:@"%@%@",SPC2,spc];
		[mstr appendFormat:@"%@%@\n",SPC2,mesONOFF(_falarmRotation)];
	} else {
		// 日本語
		spc=leftString2(@"ALARMROTATION",YES,textView);
		[mstr appendFormat:@"%@%@%@\n",SPC2,spc,mesONOFF(_falarmRotation)];
	}
	//
	spc=leftString2(@"ALARM3D"		,YES,textView);
	if (_falarm3D) { // 3Dアラーム諸元はON時のみ出力
		// RotationViewContollerの設定出力
		NSArray *nameArray=[_rotationControl nameDataSourceArray];
		[mstr appendFormat:@"%@%@%@\n",SPC2,spc,nameArray[_selectData]];
		[mstr appendFormat:@"%@%@\n"  ,SPC2,NSLocalizedString(@"THRESHOLD", @"しきい値")];
		[_rotationControl makeAlarm3D:mstr textView:textView selectData:_selectData];
		//
		spc=leftString2(@"ALARM3DLEVEL"	,YES,textView);
		NSString *str;
		switch (_falarm3DLevel) {
			case LEVEL_OFF:
				str=NSLocalStr(@"OFF");
				break;
			case LEVEL_WAIT_DISCONTINUE:
#ifdef USE_LEVEL3
				str=NSLocalStr(@"ON2");
#else
				str=NSLocalStr(@"ON");
#endif
				break;
			case LEVEL_FORCE_CANCEL:
				str=NSLocalStr(@"ON1");
				break;
			default: // 警告回避のため
				str=@"Error";
				break;
		}
		[mstr appendFormat:@"%@%@%@\n",SPC2,spc,str];
	} else {
		// 3Dアラーム設定なし
		[mstr appendFormat:@"%@%@%@\n",SPC2,spc,NSLocalStr(@"NONE")];
	}
}
#endif

// SETUPの設定を文字列化する(ログ出力)
-(void)makeSetupString1:(NSUInteger)tag mstr:(NSMutableString *)mstr
{
	nslog(@"makeSetupString1:tag=%d/mstr=%@",(int)tag,mstr);
	NSUInteger tmno;
	NSString *mes=@""; // 警告回避のため
	switch (tag) {
#ifdef USE_TIMER
		case SETUP_TIMER:
			[mstr appendFormat:@"%02d:%02d〜%02d:%02d\n",(int)_recStartHour,(int)_recStartMin,(int)_recEndHour,(int)_recEndMin];
			return;
#endif		
		case SETUP_CAMERADEVICE:
			switch (_cameraDevice) {
				case UIImagePickerControllerCameraDeviceRear:
					mes=NSLocalizedString(@"REAR"	,@"背面");
					break;
				case UIImagePickerControllerCameraDeviceFront:
					mes=NSLocalizedString(@"FRONT"	,@"前面");
					break;
			}
			break;
		case SETUP_CAMERAFLASHMODE:
			switch (_cameraFlashMode) {
				case UIImagePickerControllerCameraFlashModeOff:
					mes=NSLocalizedString(@"OFF"	,@"オフ");
					break;
				case UIImagePickerControllerCameraFlashModeAuto:
					mes=NSLocalizedString(@"AUTO"	,@"自動");
					break;
				case UIImagePickerControllerCameraFlashModeOn:
					mes=NSLocalizedString(@"ON"		,@"オン");
					break;
			}
			break;
#ifdef USE_CONSTANT		
		case SETUP_CONSTANTQUALITY:
			mes=textSegmentQuality(_constantQuality);
			break;
#endif
			//
#ifdef USE_COLORSELECT
		case SETUP_ATRBPOSITION:
			{
			NSArray *mary=[self setAtrbPositionArray];
			mes=mary[_atrbPosition]; // 配列の内容の文字列は固定アドレスにある＝消えないのでこれでいい
			}
			[mstr appendFormat:@"%@\n",mes];
			// このあと、呼び出し側で色の追加がされる
			return;
#endif
#if defined(USE_ALARM)
		case SETUP_ALARMLIMIT:
			[mstr appendFormat:@"%@\n",		[self makeTimeIntervalMessage:[self getTmValues:TMAlarmLimit]	fmin:YES]];
			return;
		case SETUP_FALARM1FILE:
			mes=mesONOFF(_falarm1file);
			break;
		case SETUP_FALARMRETRIGGER:
			mes=mesONOFF(_falarmRetrigger);
			break;
		case SETUP_ALARMSOURCE:
			// "アラーム源"までは表示済み
			break;
#endif
#ifdef USE_BLUETOOTH
		case SETUP_BLUETOOTHSHUTTER:
			mes=mesONOFF(_fbluetoothShutter);
			break;
#endif
#ifdef USE_EXITDELAY
		case SETUP_EXITDELAY:
			[mstr appendFormat:@"%@\n",		[self makeTimeIntervalMessage:[self getTmValues:TMExitDelay]	 fmin:YES]];
			return;
#endif
			//
		case SETUP_PLAYBACKSPEED:
			[mstr appendFormat:@"%@\n",		[self makeTimeIntervalMessage:[self getTmValues:TMPlaybackSpeed] fmin:NO fchange:FMT_PLAYBACKSPEED]];
			return;
	
		case SETUP_MAXPICS:
			[mstr appendFormat:@"%@\n",		[self makeTimeIntervalMessage:[self getTmValues:TMMaxPics]		 fmin:NO fchange:FMT_MAXPICS]];
			return;
#if defined(USE_ALARM)||defined(USE_NSHOT)
		case SETUP_ALARMQUALITY:
			mes=textSegmentQuality(_alarmQuality);
			break;
		case SETUP_ALARMPOST:
			#if defined(USE_NSHOT)
			[mstr appendFormat:@"%@\n",		[self makeTimeIntervalMessage:[self getTmValues:TMAlarmPost] 	 fmin:NO fchange:FMT_NSHOT]];
			return;
			#else
			tmno=TMAlarmPost;
			goto MAKE_TM_MESSGE;
			#endif
		case SETUP_ALARMINTERVAL:
			tmno=TMAlarmInterval;
			goto MAKE_TM_MESSGE;
#endif
#if defined(USE_ALARM)
		case SETUP_ALARMYOKUSHI:
			tmno=TMAlarmYokushi;
			goto MAKE_TM_MESSGE;
#endif
#ifdef USE_CONSTANT
		case SETUP_CONSTANTINTERVAL:
			tmno=TMConstantInterval;
#endif
		MAKE_TM_MESSGE:
			[mstr appendFormat:@"%@\n",[self makeTimeIntervalMessage:[self getTmValues:tmno] fmin:NO]];
			return;
			//
		//case SETUP_COUNTER: // ここでは処理しない
	}
	[mstr appendFormat:@"%@\n",mes];
}

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

// フロントカメラのチェック
// カメラ無しの時は起動させないのでここではチェックしない
UIImagePickerControllerCameraDevice CheckCameraDevice(UIImagePickerControllerCameraDevice _cameraDevice)
{
	nslog(@"カメラチェック");
	if (_cameraDevice==UIImagePickerControllerCameraDeviceFront
		&&
		![UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceFront]) {
		// 前面が指定されているが、前面カメラが無効なときは背面にする
		nslog(@"前面カメラ無効");
		_cameraDevice=UIImagePickerControllerCameraDeviceRear;
	}
	return(_cameraDevice);
}

// リアフラッシュのチェック
UIImagePickerControllerCameraFlashMode CheckCameraFlashMode(UIImagePickerControllerCameraFlashMode cameraFlashMode)
{
	nslog(@"フラッシュチェック(リアのみ；というかフロントはない)");
	// フラッシュがなくてもAutoは有効にできるらしい（要するに全OFFもAutoとみなしている）
	switch (cameraFlashMode) {
		case UIImagePickerControllerCameraFlashModeAuto:
		case UIImagePickerControllerCameraFlashModeOn:
			// auto/on指定時は実際にon出来るかチェックする
			nslog(@"リアフラッシュ:%d",[UIImagePickerController isFlashAvailableForCameraDevice:UIImagePickerControllerCameraDeviceRear]);
			if (![UIImagePickerController isFlashAvailableForCameraDevice:UIImagePickerControllerCameraDeviceRear]) {
				// リアフラッシュはONに出来ない
				cameraFlashMode=UIImagePickerControllerCameraFlashModeOff;
			}
		case UIImagePickerControllerCameraFlashModeOff:
			break;
	}
#if 0
#if 0
	if (cameraFlashMode==UIImagePickerControllerCameraFlashModeAuto
		&&
		![UIImagePickerController isFlashAvailableForCameraDevice:UIImagePickerControllerCameraFlashModeAuto]) {
		// 自動フラッシュが指定されているが、自動フラッシュが無効なときはOnにしてみる
		cameraFlashMode=UIImagePickerControllerCameraFlashModeOn;
	}
#endif
	nslog(@"リアフラッシュ:%d",[UIImagePickerController isFlashAvailableForCameraDevice:UIImagePickerControllerCameraDeviceRear]);
	if (cameraFlashMode==UIImagePickerControllerCameraFlashModeOn
		&&
		![UIImagePickerController isFlashAvailableForCameraDevice:UIImagePickerControllerCameraFlashModeOn]) {
		// フラッシュOnが指定されているが、フラッシュが無効なときはOffにする
		nslog(@"フラッシュOFF");
		cameraFlashMode=UIImagePickerControllerCameraFlashModeOff;
	}
#endif
	nslog(@"リアフラッシュ→:%d",(int)cameraFlashMode);
	return(cameraFlashMode);
}

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

#ifdef USE_TIMER
// 時間から配列に入れるべき位置を計算する
NSUInteger TimerPosition(NSUInteger hour,NSUInteger min)
{
	return (hour*TIMER_1HOUR+min/MIN_STEP);
}

-(BOOL)getRecTimer:(NSUInteger)pos
{
	return((BOOL)recPtrn[pos]);
}

// タイマーの時間設定を時間帯別ON/OFF表に展開する
// タイマーは、start〜endになるまでで、endのMIN_STEP分は録画されない
-(void)TransferTimer
{
	printSelf();
	NSUInteger i;
	NSUInteger spos=TimerPosition(_recStartHour,_recStartMin);
	NSUInteger epos=TimerPosition(_recEndHour  ,_recEndMin  );
	if (spos==epos) { // 24時間設定
		for (i=0;i<TIMER_1DAY;i++) {
			recPtrn[i]=(char)YES;
		}
		return;
	}
	// 24時間設定以外
	// 一旦全クリア
	for (i=0;i<TIMER_1DAY;i++) {
		recPtrn[i]=(char)NO;
	}
	if (epos==0) {
		// 〜00:00は23:55~59のところまでとなる
		epos=TIMER_1DAY;
	}
	if (epos>=spos) { // 日またぎなし
		for (;spos<epos;spos++) {
			recPtrn[spos]=(char)YES;
		}
		return;
	}
	// 日またぎ
	// 当日分前半
	for (i=0;i<epos;i++) {
		recPtrn[i]=(char)YES;
	}
	// 当日分後半
	for (;spos<TIMER_1DAY;spos++) {
		recPtrn[spos]=(char)YES;
	}
}

// 現在、タイマーの有効期間内かどうか（即時判定）
-(BOOL)checkRecTimer
{
//	printSelf();
	NSUInteger minute,hour;
	NSDate *date=[NSDate date];	// 一旦インスタンスに入れないとメモリリークを起こす
	minute=getHourMinSec(date,&hour,NULL);
	//	nslog(@"[%02d:%02d]",hour,minute);
	BOOL factive= [self getRecTimer:TimerPosition(hour,minute)];
	//	nslog(@"factive=%d",factive);
	return(factive);
}
#endif

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

// 最新画像表示などを保存する(次回表示するため)
-(void)saveLatestData
{
	printSelf();
	nslog(@"%@:%@",_latestDate,_latestEvent);
	NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
	[defaults setObject:_latestDate	 forKey:keyLatestDate];
	[defaults setObject:_latestEvent forKey:keyLatestAlarm];
	[defaults synchronize]; // 同期(即時反映);iOS4では必須
}

// 設定値の保存(プログラム内からの変更点のみ)
// 常に最新の構造でOK
-(void)saveSetup
{
	printSelf();
	NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
	[defaults setObject:programVersion		forKey:keyProgramVersion];	// これは外部設定(Root.strings)でも参照している
	//
	[defaults setInteger:_cameraDevice		forKey:keyCameraDevice];
	[defaults setInteger:_cameraFlashMode	forKey:keyCameraFlashMode];
#ifdef USE_COLORSELECT
	[defaults setInteger:_atrbPosition		forKey:keyAtrbPosition];
	[defaults setInteger:_atrbColor			forKey:keyAtrbColor];
#endif
#if defined(USE_ALARM)
	[defaults setBool:_falarmRetrigger		forKey:keyFalarmRetrigger];
	[defaults setFloat:tmAlarmLimit			forKey:keyAlarmLimit];
	//
	[defaults setBool:_falarmShake			forKey:keyFalarmShake];
	[defaults setBool:_falarmRotation		forKey:keyFalarmRotation];
	[defaults setBool:_falarm3D				forKey:keyFalarm3D];
	[defaults setInteger:_selectData		forKey:keySelectData];
	[defaults setInteger:_falarm3DLevel		forKey:keyFalarm3DLevel];
	[defaults setFloat:tmAlarmYokushi		forKey:keyAlarmYokushi];
#endif
#if defined(USE_ALARM)||defined(USE_NSHOT)
	[defaults setInteger:_alarmQuality		forKey:keyAlarmQuality];
	[defaults setBool:_falarm1file			forKey:keyFalarm1file];
	[defaults setFloat:tmAlarmPost			forKey:keyAlarmPost];
	[defaults setFloat:tmAlarmInterval		forKey:keyAlarmInterval];
#endif	// USE_ALARM/USE_NSHOT
	//
#ifdef USE_BLUETOOTH
	[defaults setBool:_fbluetoothShutter	forKey:keyBluetoothShutter];
#endif
#ifdef USE_CONSTANT
	[defaults setInteger:_constantQuality	forKey:keyConstantQuality];
#endif
#ifdef USE_EXITDELAY
	[defaults setFloat:tmExitDelay			forKey:keyExitDelay];
#endif
	[defaults setFloat:tmConstantInterval	forKey:keyConstantInterval];
	[defaults setFloat:tmPlaybackSpeed		forKey:keyPlaybackSpeed];
	[defaults setFloat:tmMaxPics			forKey:keyMaxPics];
#ifdef USE_TIMER
	[defaults setInteger:_recStartHour		forKey:keyRecStartHour];
	[defaults setInteger:_recStartMin		forKey:keyRecStartMin];
	[defaults setInteger:_recEndHour		forKey:keyRecEndHour];
	[defaults setInteger:_recEndMin			forKey:keyRecEndMin];
#endif
	//
	[defaults synchronize]; // 同期(即時反映);iOS4では必須
#ifdef USE_TIMER
	// 今回の設定によってタイマーパターンを再構築する
	[self TransferTimer];
#endif
}

// 一番最初のSETUP値設定
// アプリケーションインストール後/バージョンアップ後1回だけ
// mode=SET_SETUP_*
-(id)setupInit:(NSUInteger)mode
{
	printSelf();
	// デフォルト設定値
	switch (mode) {
		case SET_SETUP_ALL:
			// 内部
			_cameraDevice		=CheckCameraDevice(defCameraDevice);		// デフォルトが使えない機種の場合があるのでチェック付き
			_cameraFlashMode	=CheckCameraFlashMode(defCameraFlashMode);	// デフォルトが使えない機種の場合があるのでチェック付き
#ifdef USE_COLORSELECT
			_atrbPosition		=defAtrbPosition;
			_atrbColor			=defAtrbColor;
#endif
#if defined(USE_ALARM)
			_falarmRetrigger	=defFalarmRetrigger;
			tmAlarmLimit		=defAlarmLimit;
			_alarmQuality		=defAlarmQuality;
			tmAlarmPost			=defAlarmPost;
			tmAlarmYokushi		=defAlarmYokushi;
			tmAlarmInterval		=defAlarmInterval;
#endif
#if defined(USE_NSHOT)
			_falarmRetrigger	=NO;
			_alarmQuality		=defAlarmQuality;
			tmAlarmLimit		=None;
			tmAlarmPost			=defAlarmPost;
			tmAlarmYokushi		=None;
			tmAlarmInterval		=defAlarmInterval;
#endif // USE_ALARM
//
#ifdef USE_CONSTANT
			_constantQuality	=defConstantQuality;
			tmConstantInterval	=defConstantInterval;
#endif
#ifdef USE_EXITDELAY
			tmExitDelay			=defExitDelay;
#endif
#ifdef USE_TIMER
			_recStartHour		=defRecStartHour;
			_recStartMin		=defRecStartMin;
			_recEndHour			=defRecEndHour;
			_recEndMin			=defRecEndMin;
#endif
			// 外部
			fsound				=YES;
			_flaunchSound		=NO;
			_fantiSleep			=YES;
#ifdef USE_SETUPOUTPUT
			_fpdf				=NO;
#endif
		//
		case SET_SETUP_V11:
			tmPlaybackSpeed		=defPlaybackSpeed;
			tmMaxPics			=defMaxPics;
#ifdef USE_BLUETOOTH
			_fbluetoothShutter	=defBluetoothShutter;
#endif
		//
		case SET_SETUP_V15:	// setup v1.5
#if defined(USE_ALARM)
			_falarmShake		=defFalarmShake;
			_falarmRotation		=defFalarmRotation;
			_falarm3D			=defFalarm3D;
			_falarm1file		=defFalarm1file;
			_selectData			=defSelectData;
			_falarm3DLevel		=defFalarm3DLevel;
#endif
			//
		case SET_SETUP_V16:	// setup v1.6
#if defined(USE_NSHOT)
			_falarmShake		=NO;
			_falarmRotation		=NO;
			_falarm3D			=NO;
			_falarm1file		=defFalarm1file;
			_alarmQuality		=defAlarmQuality;
			tmConstantInterval	=defConstantInterval;	// 設定値範囲が変わるため初期化する
#endif
			break;
	}
	// 初期保存
	NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
	[defaults setBool:YES forKey:keyInitialSetup];		// 初期設定をした印(初版〜)
	[defaults setBool:YES forKey:keyInitialSetupV11];	// 初期設定をした印(V1.1〜)
	[defaults setBool:YES forKey:keyInitialSetupV15];	// 初期設定をした印(V1.5〜)
	[defaults setBool:YES forKey:keyInitialSetupV16];	// 初期設定をした印(V1.6〜)
	// 保存(内部)
	[self saveSetup];
	// 保存(外部)
	[defaults setBool:fsound		forKey:keyFsound];
#ifdef USE_SETUPOUTPUT
	[defaults setBool:_fpdf			forKey:keyFpdf];
#endif
	[defaults setBool:_flaunchSound	forKey:keyFlaunchSound];
	[defaults setBool:_fantiSleep	forKey:keyFantiSleep];
	return self;
}

// SETUP読み込み
-(void)loadSetup
{
	printSelf();
	NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
	// インストール直後かどうかを判定
	if ([defaults boolForKey:keyInitialSetup]==NO) { // 全くの初回
		nslog(@"SET_SETUP_ALL");
		[self setupInit:SET_SETUP_ALL];
	}
	else
	if ([defaults boolForKey:keyInitialSetupV11]==NO) { // setup v1.0からのとき(v1.1がない)
		nslog(@"SET_SETUP_V11");
		[self setupInit:SET_SETUP_V11];
	}
	else
	if ([defaults boolForKey:keyInitialSetupV15]==NO) { // setup v1.1からのとき(v1.5がない)
		nslog(@"SET_SETUP_V15");
		[self setupInit:SET_SETUP_V15];
	}
	else
	if ([defaults boolForKey:keyInitialSetupV16]==NO) { // setup v1.1からのとき(v1.6がない)
		nslog(@"SET_SETUP_V16");
		[self setupInit:SET_SETUP_V16];
	}
	else { // 最新版のsetupのとき
		nslog(@"最新版");
		_cameraDevice		=[defaults integerForKey:keyCameraDevice];
		_cameraFlashMode	=[defaults integerForKey:keyCameraFlashMode];
#ifdef USE_COLORSELECT
		_atrbPosition		=[defaults integerForKey:keyAtrbPosition];
		_atrbColor			=[defaults integerForKey:keyAtrbColor];
#endif
#if defined(USE_ALARM)
		_falarmRetrigger	=[defaults boolForKey:keyFalarmRetrigger];

		tmAlarmLimit		=[defaults floatForKey:keyAlarmLimit];
		_falarmShake		=[defaults boolForKey:keyFalarmShake];
		_falarmRotation		=[defaults boolForKey:keyFalarmRotation];
		_falarm3D			=[defaults boolForKey:keyFalarm3D];
		_selectData			=[defaults integerForKey:keySelectData];
		_falarm3DLevel		=[defaults integerForKey:keyFalarm3DLevel];
		_alarmQuality		=[defaults integerForKey:keyAlarmQuality];
		tmAlarmPost			=[defaults floatForKey:keyAlarmPost];
		tmAlarmYokushi		=[defaults floatForKey:keyAlarmYokushi];
		_falarm1file		=[defaults boolForKey:keyFalarm1file];
		tmAlarmInterval		=[defaults floatForKey:keyAlarmInterval];
#endif	// USE_ALARM
#if defined(USE_NSHOT)
		_falarmRetrigger	=NO;
		tmAlarmLimit		=None;
		_falarmShake		=NO;
		_falarmRotation		=NO;
		_falarm3D			=NO;
		tmAlarmPost			=[defaults floatForKey:keyAlarmPost];
		_alarmQuality		=[defaults integerForKey:keyAlarmQuality];
		tmAlarmYokushi		=None;
		_falarm1file		=[defaults boolForKey:keyFalarm1file];
		tmAlarmInterval		=[defaults floatForKey:keyAlarmInterval];
#endif	// USE_NSHOT
		//
#ifdef USE_BLUETOOTH
		_fbluetoothShutter	=[defaults boolForKey:keyBluetoothShutter];
#endif
#ifdef USE_CONSTANT
		_constantQuality	=[defaults integerForKey:keyConstantQuality];
		tmConstantInterval	=[defaults floatForKey:keyConstantInterval];
		nslog(@"setup:load;tmConstantInterval=%f",tmConstantInterval);
#endif
#ifdef USE_EXITDELAY
		tmExitDelay			=[defaults floatForKey:keyExitDelay];
#endif
		tmPlaybackSpeed		=[defaults floatForKey:keyPlaybackSpeed];
		nslog(@"setup:load;tmPlaybackSpeed=%f",tmPlaybackSpeed);
		tmMaxPics			=[defaults floatForKey:keyMaxPics];
		nslog(@"setup:load;maxPics=%f",tmMaxPics);
#ifdef USE_TIMER
		_recStartHour		=[defaults integerForKey:keyRecStartHour];
		_recStartMin		=[defaults integerForKey:keyRecStartMin];
		_recEndHour			=[defaults integerForKey:keyRecEndHour];
		_recEndMin			=[defaults integerForKey:keyRecEndMin];
		// 設定からタイマーパターンを構築する
		[self TransferTimer];
#endif
		// programVersionは「設定」での表示専用なので、プログラム中に取り込む必要なし
	}
}

// 「設定画面」分読み込み
-(void)readSetupOuter
{
	printSelf();
	NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
	fsound=[defaults boolForKey:keyFsound];		nslog(@"fsound=%d",fsound);
#ifdef USE_SETUPOUTPUT
	_fpdf =[defaults boolForKey:keyFpdf];		nslog(@"_fpdf=%d",_fpdf);
#endif
	_flaunchSound=[defaults boolForKey:keyFlaunchSound];	nslog(@"_flaunchSound=%d",_flaunchSound);
	_fantiSleep	 =[defaults boolForKey:keyFantiSleep];		nslog(@"_fantiSleep=%d",_fantiSleep);
	//
	clickOnOff(fsound);
}


//----------------------------------------------------
// 外部公開関数
//----------------------------------------------------

// アラーム録画があるかどうか
-(BOOL)isAlarmRec
{
	printSelf();
#if defined(USE_ALARM)||defined(USE_NSHOT)
	nslog(@"アラーム録画:%f",tmAlarmInterval);
	return (tmAlarmInterval!=None);
#else	// アラームがないとき：こまどり君にはアラーム録画はない
	nslog(@"アラーム録画:常になし");
	return (NO);
#endif
}

// 常時録画があるかどうか
-(BOOL)isSettingConstant
{
	printSelf();
#ifndef USE_CONSTANT
	// 常時録画が無効なときは常になし
	return(NO);
#else
	// 常時録画あるとき
	return (tmConstantInterval!=None);
#endif
}

// 1shot録画設定になっているかどうか
-(BOOL)isSetting1Shot
{
	printSelf();
#ifndef USE_1SHOT
	// 1shotがないとき
	return (NO);
#endif
#if (defined(USE_ALARM)||defined(NSHOT)) && defined(USE_CONSTANT)
	// アラームと常時録画両方があるときは、両方がOFFのとき	
	return (tmConstantInterval==None && tmAlarmInterval==None);
#endif
#ifdef USE_CONSTANT
	// 常時録画しかないとき
	// 浮動小数点の比較は、求める答えを得られないので対策している
	// tmConstantInterval==PIC1 は常に不一致になってしまう
	nslog(@"tmConstantInterval=%f:PIC1=%f:差分=%f",tmConstantInterval,PIC1,tmConstantInterval-PIC1);
	return (EquFloat(tmConstantInterval,PIC1));
#else
	// アラームのみの時
	return (tmAlarmInterval==None);
#endif	// USE_CONSTANT
}

// nShot録画設定になっているかどうか
-(BOOL)isSettingNShot
{
	printSelf();
#ifndef USE_NSHOT
	// nShotがないとき
	return (NO);
#endif
	return (tmAlarmInterval!=None);
}

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

@end
