//
//  ENBPDevice.m
//  ENBLEProject
//
//  Created by lvwang2002 on 16/4/8.
//  Copyright © 2016年 Facebook. All rights reserved.
//

#import "ENBPDevice.h"
#define kStartCheck @"开始测量"
#define kStopCheck @"停止测量"

	// 发给血压计 (带校验码)
Byte SEND_CHECK_POWER_PRESSURE[] = { 0xcc, 0x85, 0x02, 0x03, 0x04, 0x04, 0x00, 0x01 };// 查询电量
Byte SEND_CONNECT_PRESSURE[] = { 0xcc, 0x85, 0x02, 0x03, 0x01, 0x01, 0x00, 0x01 };// 连接血压计
Byte SEND_START_PRESSURE[] = { 0xcc, 0x85, 0x02, 0x03, 0x01, 0x02, 0x00, 0x02 };// 开始测量
Byte SEND_STOP_PRESSURE[] = { 0xcc, 0x85, 0x02, 0x03, 0x01, 0x03, 0x00, 0x03 };// 停止测量
Byte SEND_CLOSE_PRESSURE[] = { 0xcc, 0x85, 0x02, 0x03, 0x01, 0x04, 0x00, 0x04 };// 关仪器

	// 收到血压计之后(血压计还会回复指令)匹配是否成功的字节数组 (带校验码)
Byte RECEIVE_CHECK_POWER_PRESSURE[] = { 0xaa, 0x85, 0x02, 0x04, 0x04, 0x04 };// 查询电量(数组中没有放入校验码,和数据，共3个字节)
Byte RECEIVE_CONNECT_PRESSURE[] = { 0xaa, 0x85, 0x02, 0x03, 0x01, 0x01, 0x00, 0x01 };// 连接血压计
Byte RECEIVE_START_PRESSURE[] = { 0xaa, 0x85, 0x02, 0x03, 0x01, 0x02, 0x00, 0x02 };// 开始测量
Byte RECEIVE_STOP_PRESSURE[] = { 0xaa, 0x85, 0x02, 0x03, 0x01, 0x03, 0x00, 0x03 };// 停止测量
Byte RECEIVE_CLOSE_PRESSURE[] = { 0xaa, 0x85, 0x02, 0x03, 0x01, 0x04, 0x00, 0x04 };// 关仪器
Byte RECEIVE_RESULT[] = { 0xaa, 0x85, 0x02, 0x0f, 0x01};// 接收结果

Byte error_state_a = 0x01;// 请检查血压计佩戴是否正确
Byte error_state_b = 0x02;// 血压计袖带过松或漏气
Byte error_state_c = 0x04;// 请保持安静 ，重新测量
Byte error_state_d = 0x07;// 血压计电量低，请充电
Byte error_state_e = 0x15;// 测量出错，请重新测量 EE21
@implementation ENBPDevice{
	BOOL _connected;
	NSArray *_characteristics;
}
-(id)initWithPeripheral:(CBPeripheral *)peripheral WithCentralManager:(CBCentralManager *)centerManager WithDevice:(BLEDevice *)device{
	self = [super initWithPeripheral:peripheral WithCentralManager:centerManager WithDevice:device];
	if(self){
		_connected = NO;
	}
	return self;
}

/**
 *  4.发现外围服务
 *
 *  @param peripheral 外围设备
 *  @param error      错误信息
 */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
	if (error){
		NSLog(@"didDiscoverServices : %@", [error localizedDescription]);
			//        [self cleanup];
		return;
	}
	
	for (CBService * service in _peripheral.services) {
		/**
		 *  查找自己需要的UUID的服务
		 */
		if ([[_device.advertisementData[@"kCBAdvDataServiceUUIDs"] firstObject] isEqual:service.UUID]) {
		
			/**
			 *  查找外围设备特性
			 */
			[_peripheral discoverCharacteristics:nil forService:service];
			return;
		
		}
	}
}

/**
 *  5.发现外围设备特性
 *
 *  @param peripheral 外围设备
 *  @param service    外围设备服务
 *  @param error      错误信息
 */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
	if (error){
		NSLog(@"didDiscoverCharacteristicsForService error : %@", [error localizedDescription]);
		return;
	}
	
	_characteristics = service.characteristics;
	/**
	 *  开启通知(外围设备发数据能收到) service.characteristics 里面两个FFF1(通知的) FFF2(写入的)
	 */
	
	[_peripheral setNotifyValue:YES forCharacteristic:[service.characteristics firstObject]];
	
	[_peripheral writeValue:[NSData dataWithBytes:SEND_CONNECT_PRESSURE length:8] forCharacteristic:[service.characteristics lastObject] type:CBCharacteristicWriteWithoutResponse];
}

/**
 *  6.发送数据到外围设备回调
 *
 *  @param peripheral     外围设备
 *  @param characteristic 外围设备特性
 *  @param error          错误信息
 */
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
	NSLog(@"%@---",error);
}

/**
 *  6.外围设备发送数据到蓝牙中心
 *
 *  @param peripheral     外围设备
 *  @param characteristic 外围设备特性
 *  @param error          错误信息
 */
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
		//    byte error_state_a = 0x01;// 请检查血压计佩戴是否正确
		//    byte error_state_b = 0x02;// 血压计袖带过松或漏气
		//    byte error_state_c = 0x04;// 请保持安静 ，重新测量
		//    byte error_state_d = 0x07;// 血压计电量低，请充电
		//    // byte error_state_e = 0x15;// 测量出错，请重新测量 EE21
	
		NSData *data = characteristic.value;
		Byte * byte = (Byte *)[data bytes];
	
		//判断是否是连接
		{
				NSData * connectData = [NSData dataWithBytes:RECEIVE_CONNECT_PRESSURE length:8];
				BOOL flag = NO;
				if (connectData.length == data.length) {
					for (int i=0; i<connectData.length; i++) {
						if (RECEIVE_CONNECT_PRESSURE[i] != byte[i]) {
							flag = YES;
							break;
						}
					}
				}else{
					flag = YES;
				}
		
				if(!flag){
					_connected = YES;
					if([self.deviceDelegate respondsToSelector:@selector(onConnectedBPWithDevice:)]){
							[(id)self.deviceDelegate onConnectedBPWithDevice:_device];
					};
					return;
				}
		}
	
		//获取电池电量
	{
		NSData * powerData = [NSData dataWithBytes:RECEIVE_CHECK_POWER_PRESSURE length:6];
		BOOL power = YES;
		if (data.length >= powerData.length) {
			for (NSInteger i = 0; i<powerData.length; i++) {
				if (RECEIVE_CHECK_POWER_PRESSURE[i] != byte[i]) {
					power = NO;
					break;
				}
			}
			
		}else{
			power = NO;
		}
		
		if(power){
			NSMutableArray * array = [NSMutableArray array];
			
			for(int i=0;i<[data length];i++){
				NSString *newHexStr = [NSString stringWithFormat:@"%x",byte[i]]; ///16进制数
				if([newHexStr length]==1){
					newHexStr = [NSString stringWithFormat:@"0%@",newHexStr];
				}
				
				[array addObject:newHexStr];
			}
			
			/** 计算电池电量 */
			unsigned long batteryPower = strtoul([[NSString stringWithFormat:@"%@%@",array[array.count - 3],array[array.count - 2]] UTF8String], 0, 16);
			NSLog(@"%ld",strtoul([[NSString stringWithFormat:@"%@%@",array[array.count - 3],array[array.count - 2]] UTF8String], 0, 16));
			
			if(batteryPower<3600){
				dispatch_async(dispatch_get_main_queue(), ^{
					if([self.deviceDelegate respondsToSelector:@selector(onLowPowerWithDevice:)]){
						[(id)self.deviceDelegate onLowPowerWithDevice:_device];
					}
				});
				return;
			}
			
			
			// 发送消息到外围设备
			[_peripheral writeValue:[NSData dataWithBytes:SEND_START_PRESSURE length:8] forCharacteristic:[_characteristics lastObject] type:CBCharacteristicWriteWithoutResponse];
			
			dispatch_async(dispatch_get_main_queue(), ^{
				if([self.deviceDelegate respondsToSelector:@selector(onBatteryPower:WithDevice:)]){
					[(id)self.deviceDelegate onBatteryPower:batteryPower WithDevice:_device];
				}
			});
			
			
			return;
		}
		
	}
	
		//血压过程数据
		{
			if (data.length == 13) {
				[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onDeviceStopTest) object:nil];
				
				NSMutableArray * array = [NSMutableArray array];
				for(int i=0;i<[data length];i++){
					NSString *newHexStr = [NSString stringWithFormat:@"%d",byte[i]]; ///10进制数
					if([newHexStr length]==1){
						newHexStr = [NSString stringWithFormat:@"0%@",newHexStr];
					}
					
					[array addObject:newHexStr];
				}
					// int d5 = UtilityBase.toTenInt(dataList
					// .get(totalSize - 7));
					//                NSLog(@"%@",array);
				NSInteger d4 = [array[array.count - 6] integerValue];
					// int d3 = UtilityBase.toTenInt(dataList
					// .get(totalSize - 5));
					// int d2 = UtilityBase.toTenInt(dataList
					// .get(totalSize - 4));
				NSInteger d1 = [array[array.count - 3] integerValue];
					// int d0 = UtilityBase.toTenInt(dataList
					// .get(totalSize - 2));
				NSInteger p = (d4 << 8) + (d4 ^ d1);
				
					//	self.numLabel.text = [NSString stringWithFormat:@"%03ld",(long)p];
				
				[self performSelector:@selector(onDeviceStopTest) withObject:nil afterDelay:6];
				dispatch_async(dispatch_get_main_queue(), ^{
					if([self.deviceDelegate respondsToSelector:@selector(onProgressValue:WithDevice:)]){
						[(id)self.deviceDelegate onProgressValue:p WithDevice:_device];
					}
				});
				return;
				
			}

		}
	
		//血压测量结果
		{
			if(data.length == 20){
				[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onDeviceStopTest) object:nil];
				NSData * resultData = [NSData dataWithBytes:RECEIVE_RESULT length:5];
				if (data.length >= resultData.length) {
			
					for (NSInteger i = 0; i<resultData.length; i++) {
						if (RECEIVE_RESULT[i] != byte[i]) {
							return;
						}
					}
				}
//		[self.noResponseTime invalidate];
//		self.noResponseTime = nil;
				NSMutableArray * array = [NSMutableArray array];
		
				for(NSInteger i=0;i<[data length];i++){
					NSString *newHexStr = [NSString stringWithFormat:@"%d",byte[i]]; ///10进制数
			
					[array addObject:newHexStr];
				}
				NSInteger pul_0 = [array[array.count - 2] integerValue];
				NSInteger pul_1 = [array[array.count - 3] integerValue];
				NSInteger dia_0 = [array[array.count - 4] integerValue];
				NSInteger dia_1 = [array[array.count - 5] integerValue];
				NSInteger sys_0 = [array[array.count - 6] integerValue];
				NSInteger sys_1 = [array[array.count - 7] integerValue];
		
				NSInteger pul = pul_1 ^ pul_0; // 脉搏
				NSInteger dia = dia_1 ^ dia_0; // 舒张压
				NSInteger sys = sys_1 ^ sys_0; // 收缩压
		
				NSString *result= [NSString stringWithFormat:@"脉搏:%ld舒张压:%ld收缩压:%ld",(long)pul,(long)dia,(long)sys];
				NSLog(@"result:%@",result);
//				[self saveAndPostWithPul:pul andDia:dia andSys:sys];
				NSDictionary *info = @{
																@"pul":@(pul),
																@"dia":@(dia),
																@"sys":@(sys)
															};
				
				dispatch_async(dispatch_get_main_queue(), ^{
					[(id)self.deviceDelegate onResult:info WithDevice:_device];
				});
				
				return;
			}
		}
	
		//血压测量错误
		{
			if (data.length == 8){
				[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onDeviceStopTest) object:nil];
					NSData * stopCheckData = [NSData dataWithBytes:RECEIVE_STOP_PRESSURE length:8];
					BOOL flag1 = NO;
					BOOL flag2 = NO;
					if (stopCheckData.length == data.length) {
							for (int i=0; i<stopCheckData.length; i++) {
								if (RECEIVE_STOP_PRESSURE[i] != byte[i]) {
									flag1 = YES;
						//                            break;
								}
				
								if (RECEIVE_CLOSE_PRESSURE[i] != byte[i]) {
									flag2 = YES;
								}
							}
					}
		
				if (flag1 == NO || flag2 == NO) {
//			self.startCheck = NO;
//			[self.noResponseTime invalidate];
//			self.noResponseTime = nil;
				}
		
					//  血压测量异常错误提示
				BOOL error = NO;
				NSString *errorInfo;
				if(byte[6] == error_state_a)        //  EE1
				{
//			[MBProgressHUD showLineMessage:@"请检查血压计佩戴是否正确"];
			errorInfo = @"请检查血压计佩戴是否正确";
					error = YES;
				}else if (byte[6] == error_state_b) //  EE2
						{
//					[MBProgressHUD showLineMessage:@"血压计袖带过松或漏气"];
					errorInfo = @"血压计袖带过松或漏气";
					error = YES;
						}else if (byte[6] == error_state_c)  //  EE4
								{
//							[MBProgressHUD showLineMessage:@"请保持安静重新测量"];
							errorInfo = @"请保持安静重新测量";
							error = YES;
								}else if (byte[6] == error_state_d)  //  EE7
										{
//									[MBProgressHUD showLineMessage:@"血压计电量低，请充电"];
									errorInfo = @"血压计电量低，请充电";
									error = YES;
										} else if (byte[6] == error_state_e) {  //  EE21
//											[MBProgressHUD showLineMessage:@"测量出错,请重新测量"];
											errorInfo = @"测量出错,请重新测量";
											error = YES;
										}
		
				if (error) {
//			self.startCheck = NO;
//			[self.noResponseTime invalidate];
//			self.noResponseTime = nil;
				//                    [self back];
					dispatch_async(dispatch_get_main_queue(), ^{
						if([self.deviceDelegate respondsToSelector:@selector(onError:WithDevice:)]){
							[(id)self.deviceDelegate onError:errorInfo WithDevice:_device];
						};
					});
				}
			}
			return;
		}
}

/* 开始测量 */
-(void)startTest{
	if(_peripheral == nil || _characteristics == nil){
		return;
	}
	
	if(_characteristics.count <= 0){
		return;
	}
	
	[_peripheral writeValue:[NSData dataWithBytes:SEND_CHECK_POWER_PRESSURE length:8] forCharacteristic:[_characteristics lastObject] type:CBCharacteristicWriteWithoutResponse];

}

/** 停止测量 */
-(void)stopTest{
	if(_peripheral == nil || _characteristics == nil){
		return;
	}
	
	if(_characteristics.count <= 0){
		return;
	}
	
	dispatch_async([[ENBLEDeviceManager shareDeviceManager] getPostQueue], ^{
		[_peripheral writeValue:[NSData dataWithBytes:SEND_STOP_PRESSURE length:8] forCharacteristic:[_characteristics lastObject] type:CBCharacteristicWriteWithoutResponse];
	});
}


-(void)onDeviceStopTest{
	dispatch_async(dispatch_get_main_queue(), ^{
		if([self.deviceDelegate respondsToSelector:@selector(onError:WithDevice:)]){
			[(id)self.deviceDelegate onError:@"设备停止测量" WithDevice:_device];
		}
	});
}

/** 得到设备显示名字 */
-(NSString *)getDeviceDisplayName{
	return @"脉搏波血压计";
}



@end
