//
//  RotationControl.h
//  制御部
//  ChariReco
//
//  Created by AIG-Soft on 11/07/13.
//  Copyright 2011 AIG-Soft. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <CoreMotion/CoreMotion.h>

// グラフ部データファイル名
#define	GRAPHFILE	@"GRAPH_SPECIFICATIONS.DAT"

// 通知名
#define	NOTIFICATION_ALARM	@"3DAlarm"
#define	NAME_ALARM_EDGE		@"Edge"		// 3Dアラームの先頭
#define	NAME_ALARM_LEVEL	@"Level"	// レベル判定時の途中


@protocol RotationControlStoreData <NSObject>
@required
-(void)rotationControlStoreData:(CMRotationRate *)xyz;
@end

//#define	JIKUBETU_MAXMINY	// min/maxYを軸別にするときはこれを有効にする

#ifdef JIKUBETU_MAXMINY
#define	_maxY(j,i)	maxY[j][i]
#define	_minY(j,i)	minY[j][i]
#else
#define	_maxY(j,i)	maxY[j]
#define	_minY(j,i)	minY[j]
#endif

enum { // データ源番号(dno)＝SegSelectDataの選択肢
	// 万が一この順番を変更するときは、しきい値設定ファイルを消すため、アプリを削除すること
	DATA_DEGREE=0,
	DATA_VELOCITY,
	DATA_ROTATION,
	//
	DATA_ALL
};

enum { // 表示するグラフの軸種類:gno=btn.tag値にもなる
	GRAPH_X=0,
	GRAPH_Y,
	GRAPH_Z,
	//
	GRAPH_ALL
};
#define MAX_GRAPH	GRAPH_ALL	// グラフ数

#define	DEF_TRUE_PEAK_MAX	(-999999.0)	// まずは最小値を最大に
#define	DEF_TRUE_PEAK_MIN	(+999999.0)	// 最大値を最小に設定しておく

typedef struct {
	// バージョン
	// 非常に冗長であるが、NSData経由で読み込むにはこれが一番楽なのでこうする
	float		version;
	// しきい値
	float		threshold1;		// しきい値1
	float		threshold2;		// しきい値2
	BOOL		fthreshold1;	// threshold1が有効かどうか
	BOOL		fthreshold2;	// threshold2が有効かどうか
	// Peak Hold
	//　min〜max間Peak
	float		peakMax;		// Peak値最大
	float		peakMin;		// Peak値最小
	// 上下限なしPeak(生Peak)
	float		truePeakMax;	// Peak値最大
	float		truePeakMin;	// Peak値最小
} GRAPH_SPECIFICATIONS;
// この内容を変えたときは、一旦古いバージョンで読み込んでから、変換して新バージョンに変換して書き出す
#define GRAPH_SPECIFICATIONS_VERSION	1.00	// versionに入れる


@interface RotationControl : NSObject
<RotationControlStoreData>
{
	// データ取得
	CMMotionManager		*motionManager;
	//
	NSTimeInterval		interval;		// サンプリング間隔(秒)
	//
	BOOL				fsetNortification;	// 通知を設定しているかどうか
	NSUInteger			counter;			// サンプリングを利用した簡易時間計測カウンター;単位はintervalで、１秒ならdatasPerSecである
	
	// データを格納する配列
	// データ上のx,y,zはデバイスに対する各次元方向
	// グラフのx(横),y(縦)軸とは異なるので注意
	// グラフ上は、x軸は時間、y軸がこのデータとなる
	// 本番用
	NSEnumerator		*em;			// 要素を高速で読み出すための列挙型
	NSMutableArray		*dArray;		// 各要素はCMRotationRate
	NSUInteger			samples;		// データ数
	// 保存用:c=copy
	NSMutableArray		*cdArray;		// 各要素はCMRotationRate
	NSUInteger			csamples;		// データ数

	// データ範囲；データ源別;軸別にも出来る
	float		_minY(DATA_ALL,GRAPH_ALL+1);	// +1はGRAPH_ALL用
	float		_maxY(DATA_ALL,GRAPH_ALL+1);	// +1はGRAPH_ALL用

	// グラフ諸元；データ源別・軸別
	GRAPH_SPECIFICATIONS	spec[DATA_ALL][MAX_GRAPH];

	// 本来軸の属性だが、dno,gnoによってアクセスされるのでこちらに置いている
	// 縦軸格子分割数
	NSUInteger	ycount[DATA_ALL][MAX_GRAPH+1];	// +1はGRAPH_ALL用

}

@property (nonatomic, weak) id<RotationControlStoreData> dataSource;	// Sampling時のデータ記録用デリゲート
@property (nonatomic, strong) NSOperationQueue *opQueueMotion;
@property (nonatomic) NSUInteger datasPerSec;	// 1秒間あたりのデータ数
@property (nonatomic) NSUInteger gno;			// 軸番号:GRAPH_X〜GRAPH_Z/GRAPH_ALL
@property (nonatomic) NSUInteger dno;			// データ源番号:DATA_VELOCITY〜DATA_DEGREE
@property (nonatomic) BOOL fpause;				// サンプリング一時停止フラグ
@property (nonatomic) NSUInteger fLevel;		// しきい値のレベル判定フラグ;現在のバージョンでは、全軸・全データ源共通
@property (nonatomic) NSUInteger levelCount;	// レベル判定時の連続カウンタ(上限あり;UINT_MAX;limits.h)

-(void)saveSettings:(NSString *)fname;
-(BOOL)readSettings:(NSString *)fname;

-(id)initWithSampling:(NSUInteger)sampling;
-(void)initialize:(NSUInteger)sampling;
-(void)stopRotationControl;
-(void)resetPeakHold;
-(void)resetThreshold;
-(void)selectData:(NSUInteger)dno_;
-(void)startSampling;
-(void)setAlarm3DNortification:(id)target_ selector:(SEL)selector_;
-(void)stopAlarm3DNortification;
-(void)setAlarm3DLevel:(NSUInteger)onoff;
-(BOOL)checkAllThreshold;

-(void)eraseData;
-(void)copyData;
-(void)copyBackupData;
-(BOOL)addData:(CMRotationRate *)xyz;
-(NSUInteger)getYcount;

-(BOOL)checkData1:(float *)f_ gno:(NSUInteger)no checkResult:(NSUInteger *)result;
enum { // result値
	CHANGE_NONE=0,
	CHANGE_MAX,		// 最大値更新
	CHANGE_MIN		// 最小値変更
};
#define	THRES1	CHANGE_MAX
#define	THRES2	CHANGE_MIN
-(NSString *)float2String:(float)f;
-(void)triggerAlarm3D:(BOOL)falarm;

-(GRAPH_SPECIFICATIONS *)specDnoGno;
-(GRAPH_SPECIFICATIONS *)specDnoGno:(NSUInteger)gno_;
-(GRAPH_SPECIFICATIONS *)specDnoGno:(NSUInteger)dno_ gno:(NSUInteger)gno_;
-(float)getDarray:(NSUInteger)index gno:(NSUInteger)gno_;
-(NSUInteger)getDarrayCount;
-(float)getMaxY;
-(float)getMinY;

float ExchangeValue(float f,NSUInteger dno,NSUInteger gno);
NSString *FloatString(NSUInteger dno,float f);

// 数値を文字列化するときのフォーマット指定
// 実際の有効精度がどれだけあるかは不明
// 使えそうな範囲のみ
#define	FMT_DATA_DEGREE		@"%+2.2f"	// -90〜+90
#define	FMT_DATA_VELOCITY	@"%+2.3f"	// -2π〜+2π(6.28)
#define	FMT_DATA_ROTATION	@"%+3.2f"	// -π〜+π*(180/3.14)=+-180

-(NSArray *)nameDataSourceArray;
-(void)makeAlarm3D:(NSMutableString *)mstr textView:(UITextView *)textView selectData:(NSUInteger)dno_;
-(void)makeAlarm3D:(NSMutableString *)mstr textView:(UITextView *)textView;

@end
