RulesRegisterViewController.m 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426
  1. //
  2. // RulesRegisterViewController.m
  3. // kneet
  4. //
  5. // Created by Jason Lee on 3/19/15.
  6. // Copyright (c) 2015 ntels. All rights reserved.
  7. //
  8. @import ObjectiveC.runtime;
  9. #import "JDObject.h"
  10. #import "RequestHandler.h"
  11. #import "RuleModel.h"
  12. #import "DeviceModel.h"
  13. #import "UIImageView+WebCache.h"
  14. #import "CustomTextField.h"
  15. #import "CustomLabel.h"
  16. #import "CustomImageView.h"
  17. #import "CustomButton.h"
  18. #import "CustomAlertView.h"
  19. #import "CustomRadioGroup.h"
  20. #import "CustomTextView.h"
  21. #import "ValidateUtil.h"
  22. #import "PredefinedDeviceViewController.h"
  23. #import "RegisterModeViewController.h"
  24. #import "RegisterTimerViewController.h"
  25. #import "RulesRegisterViewController.h"
  26. #import "ActionPopTableView.h"
  27. #import "RegisterCmdClsViewController.h"
  28. #import "RegisterPushViewController.h"
  29. #import "RulesViewController.h"
  30. @implementation RulesCreateHeaderTableViewCell
  31. - (void)awakeFromNib {
  32. self.backgroundColor = [UIColor clearColor];
  33. }
  34. @end
  35. @interface RulesCreateTableViewCell () <CustomTextViewDelegate> {
  36. }
  37. @property (weak, nonatomic) ItemModel *item;
  38. @end
  39. @implementation RulesCreateTableViewCell
  40. - (void)awakeFromNib {
  41. self.backgroundColor = [UIColor clearColor];
  42. self.selectionStyle = UITableViewCellSelectionStyleNone;
  43. }
  44. - (void)textViewDidEndEditing:(UITextView *)textView {
  45. ItemSubModel *subItem = _item.pushes[0];
  46. subItem.cmdclsValue = textView.text;
  47. }
  48. - (IBAction)btnDeleteSubItemsTouched:(id)sender {
  49. // if ([_item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  50. // [_item.predDevices removeAllObjects];
  51. // } else if ([_item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  52. // [_item.modes removeAllObjects];
  53. // }
  54. //
  55. // UITableView *tableView = [(RulesRegisterViewController *)[JDFacade facade].currentViewController tableView];
  56. // if (tableView) {
  57. // [tableView reloadRowsAtIndexPaths:@[_indexPath] withRowAnimation:UITableViewRowAnimationNone];
  58. // }
  59. }
  60. @end
  61. @interface RulesCreateTitleTableViewCell () <CustomTextFieldDelegate> {
  62. }
  63. @end
  64. @implementation RulesCreateTitleTableViewCell
  65. - (void)awakeFromNib {
  66. self.selectionStyle = UITableViewCellSelectionStyleNone;
  67. self.backgroundColor = [UIColor clearColor];
  68. _txtRuleTitle.delegate = self;
  69. _txtRuleTitle.keyboardType = UIKeyboardTypeDefault;
  70. _txtRuleTitle.returnKeyType = UIReturnKeyDone;
  71. _txtRuleTitle.placeholder = NSLocalizedString(@"입력", @"입력");
  72. }
  73. - (void)didMoveToSuperview {
  74. _txtRuleTitle.customTextFieldSuperview = CustomTextFieldSuperviewIsViewController;
  75. }
  76. - (void)textFieldDidEndEditing:(UITextField *)textField {
  77. self.txtRuleTitle.hidden = YES;
  78. self.lblRuleTitle.text = [_txtRuleTitle.text isEmptyString] ? _txtRuleTitle.placeholder : _txtRuleTitle.text;
  79. self.lblRuleTitle.hidden = NO;
  80. self.imgvItem.hidden = NO;
  81. //TODO reload tableview?;
  82. }
  83. - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
  84. [super setSelected:selected animated:animated];
  85. if (self.txtRuleTitle.hidden && selected && animated && ![self.txtRuleTitle isFirstResponder]) {
  86. self.lblRuleTitle.hidden = YES;
  87. self.txtRuleTitle.hidden = NO;
  88. self.imgvItem.hidden = YES;
  89. [self.txtRuleTitle becomeFirstResponder];
  90. }
  91. }
  92. @end
  93. @interface RulesRegisterViewController () <UITableViewDelegate, UITableViewDataSource> {
  94. NSString *_ruleId, *_ruleName, *_predRuleId;
  95. NSMutableArray<ItemModel> *_triggers, *_actions, *_conditions;
  96. BOOL _isNotFirstLoading, _isCustomCreation;
  97. NSMutableArray *_arrayForHeader;
  98. UIImage *_iconTrigger, *_iconAction;
  99. ActionPopTableView *_actionPopTableView;
  100. NSArray<DeviceModel> *_geofencingDeviceList;
  101. }
  102. @end
  103. #pragma mark - Class Definition
  104. @implementation RulesRegisterViewController
  105. - (void)viewDidLoad {
  106. [super viewDidLoad];
  107. // Do any additional setup after loading the view.
  108. [self initUI];
  109. [self prepareViewDidLoad];
  110. }
  111. - (void)initUI {
  112. _tableView.dataSource = self;
  113. _tableView.delegate = self;
  114. _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
  115. _tableView.backgroundColor = [UIColor clearColor];
  116. _tableView.tableFooterView = [[UIView alloc] init]; //this call table events;
  117. _isNotFirstLoading = YES;
  118. _iconTrigger = [UIImage imageNamed:@"tp_01_img_rule_rbox_icon_trigger"];
  119. _iconAction = [UIImage imageNamed:@"tp_01_img_rule_rbox_icon_action"];
  120. //Localization
  121. [_btnComplete setTitle:NSLocalizedString(@"완성", @"완성") forState:UIControlStateNormal];
  122. [_btnCancel setTitle:NSLocalizedString(@"취소", @"취소") forState:UIControlStateNormal];
  123. }
  124. - (void)prepareViewDidLoad {
  125. _isCustomCreation = YES;
  126. if (!_tmpPredRule && !_tmpRuleDetail) {//자유롭게 만들기
  127. _predRuleId = @"0";
  128. } else {
  129. //사전 정의 씬 상세 정보 조회
  130. if (!_tmpRuleDetail) {//사전 정의 씬을 불러온 경우,
  131. _predRuleId = _tmpPredRule.predRuleId;
  132. [self requestPredefinedRuleDetail];
  133. } else {//룰을 수정하는 경우,
  134. _ruleName = _tmpRuleDetail.ruleName;
  135. _predRuleId = _tmpRuleDetail.predRuleId; //FIXME :
  136. [self setRuleDetail];
  137. [self matchRuleDetailWithPredefinedRuleDeatil:_tmpPredRuleDetail];
  138. }
  139. }
  140. }
  141. - (void)viewWillAppear:(BOOL)animated {
  142. [super viewWillAppear:animated];
  143. self.title = !_tmpRuleDetail ? NSLocalizedString(@"홈 규칙 만들기",@"홈 규칙 만들기") : NSLocalizedString(@"홈 규칙 편집", @"홈 규칙 편집");
  144. if (_isNotFirstLoading) {
  145. [_tableView reloadData];
  146. }
  147. }
  148. #pragma mark - Main Logic
  149. - (NSMutableArray<ItemModel> *)triggers {
  150. NSMutableArray<ItemModel> *tmpTriggers = [(NSMutableArray<ItemModel> *)[NSMutableArray alloc] init];
  151. for (ItemModel *trigger in _triggers) {
  152. if ([trigger.itemSubTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  153. if ((trigger.predDevices)) {
  154. // if ((trigger.predDevices && trigger.predDevices.count)) {
  155. [tmpTriggers addObject:trigger];
  156. break;
  157. }
  158. } else if ([trigger.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  159. if (trigger.modes) {
  160. // if (trigger.modes && trigger.modes.count) {
  161. [tmpTriggers addObject:trigger];
  162. break;
  163. }
  164. } else if ([trigger.itemSubTypeCode isEqualToString:ksItemSubTypeCodeTimer]) {//타이머일 경우,
  165. if (trigger.timers) {
  166. // if (trigger.timers && trigger.timers.count) {
  167. [tmpTriggers addObject:trigger];
  168. break;
  169. }
  170. } else if ([trigger.itemSubTypeCode isEqualToString:ksItemSubTypeCodeGeoFencing]) {//지오펜싱일 경우,
  171. if (trigger.mobileDevices) {
  172. // if (trigger.mobileDevices && trigger.mobileDevices.count) {
  173. [tmpTriggers addObject:trigger];
  174. break;
  175. }
  176. }
  177. }
  178. return tmpTriggers && tmpTriggers.count ? tmpTriggers : _triggers;
  179. }
  180. //자유 선택 - 커스텀 씬 생성 시 사용
  181. - (void)addItem:(ItemModel *)item {
  182. if (!_isCustomCreation)
  183. return;
  184. if (!_actions) {
  185. _actions = (NSMutableArray<ItemModel> *)[[NSMutableArray alloc] init];
  186. }
  187. if ([_actions indexOfObject:item] == NSNotFound) {
  188. [_actions addObject:item];
  189. }
  190. [_tableView reloadData];
  191. }
  192. - (void)requestPredefinedRuleDetail {
  193. NSString *path = [NSString stringWithFormat:API_GET_PRERULE_DETAIL, _predRuleId];
  194. [[RequestHandler handler] sendAsyncGetRequestAPIPath:path parameters:nil modelClass:[PredefinedRuleDetailModel class] completion:^(id responseObject) {
  195. if (!responseObject) {//응답결과가 잘못되었거나 없을 경우,
  196. return;
  197. }
  198. PredefinedRuleDetailModel *predefinedRuleDetail = (PredefinedRuleDetailModel *) responseObject;
  199. if (predefinedRuleDetail) {//API 성공 ,
  200. if (!_tmpRuleDetail) {//생성모드일 경우,
  201. [self setPredefinedRuleDetail:predefinedRuleDetail];
  202. }
  203. // else {//수정모드일 경우,
  204. // [self matchRuleDetailWithPredefinedRuleDeatil:predefinedRuleDetail];
  205. // }
  206. }
  207. } failure:^(id errorObject) {
  208. JDErrorModel *error = (JDErrorModel *)errorObject;
  209. [[JDFacade facade] alert:error.errorMessage];
  210. }];
  211. }
  212. //각 아이템별 카운트를 설정함
  213. - (void)setPredefinedRuleDetail:(PredefinedRuleDetailModel *)predefinedRuleDetail {//각 아이템별 카운트를 설정함
  214. _triggers = (NSMutableArray<ItemModel> *)[NSMutableArray arrayWithArray:predefinedRuleDetail.triggers];
  215. _actions = (NSMutableArray<ItemModel> *)[NSMutableArray arrayWithArray:predefinedRuleDetail.actions];
  216. _conditions = (NSMutableArray<ItemModel> *)[NSMutableArray arrayWithArray:predefinedRuleDetail.conditions];
  217. [_tableView reloadData];
  218. }
  219. + (ModeModel *)mode:(NSString *)modeId {
  220. ModeModel *foundedMode = nil;
  221. for (ModeModel *mode in [JDFacade facade].modeList) {
  222. if ([modeId isEqualToString:mode.modeId]) {
  223. foundedMode = mode;
  224. break;
  225. }
  226. }
  227. return foundedMode;
  228. }
  229. + (void)setSubItemsFromItem:(NSArray<ItemModel> *)items {
  230. for (ItemModel *item in items) {//트리거 설정
  231. NSString *subTypeCode = item.itemSubTypeCode;
  232. if ([subTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  233. item.predDevices = (NSMutableArray<PredefinedDeviceModel> *)[[NSMutableArray alloc] init];
  234. for (ItemSubModel *subItem in item.subItems) {
  235. PredefinedDeviceModel *pdevice = [[PredefinedDeviceModel alloc] initWithSubItem:subItem];
  236. [item.predDevices addObject:pdevice];
  237. }
  238. } else if ([subTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  239. item.modes = (NSMutableArray<ModeModel> *)[[NSMutableArray alloc] init];
  240. for (ItemSubModel *subItem in item.subItems) {
  241. ModeModel *mode = [[ModeModel alloc] initWithSubItem:subItem];
  242. [item.modes addObject:mode];
  243. }
  244. } else if ([subTypeCode isEqualToString:ksItemSubTypeCodeAppPush]) {//푸시일 경우,
  245. item.pushes = (NSMutableArray<ItemSubModel> *)[[NSMutableArray alloc] initWithArray:item.subItems];
  246. }
  247. }
  248. }
  249. - (void)setRuleDetail {//각 아이템별 카운트를 설정함
  250. _triggers = (NSMutableArray<ItemModel> *)[[NSMutableArray alloc] initWithArray:_tmpRuleDetail.triggers copyItems:YES];
  251. _actions = (NSMutableArray<ItemModel> *)[[NSMutableArray alloc] initWithArray:_tmpRuleDetail.actions copyItems:YES];
  252. _conditions = (NSMutableArray<ItemModel> *)[NSMutableArray arrayWithArray:_tmpRuleDetail.conditions];
  253. for (ItemModel *item in _triggers) {//트리거
  254. NSIndexSet *isDeleted = [item.subItems indexesOfObjectsPassingTest:^BOOL(ItemSubModel *subitem, NSUInteger idx, BOOL *stop) {
  255. return [subitem.deleteYn boolValue];
  256. }];
  257. [item.subItems removeObjectsAtIndexes:isDeleted];
  258. if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//집이 변할때 경우,
  259. [item.predDevices removeObjectsAtIndexes:isDeleted];
  260. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  261. [item.modes removeObjectsAtIndexes:isDeleted];
  262. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeGeoFencing]) {//지오펜싱일 경우,
  263. [item.mobileDevices removeObjectsAtIndexes:isDeleted];
  264. }
  265. }
  266. for (ItemModel *item in _actions) {//액션
  267. NSIndexSet *isDeleted = [item.subItems indexesOfObjectsPassingTest:^BOOL(ItemSubModel *subitem, NSUInteger idx, BOOL *stop) {
  268. return [subitem.deleteYn boolValue];
  269. }];
  270. [item.subItems removeObjectsAtIndexes:isDeleted];
  271. if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  272. [item.predDevices removeObjectsAtIndexes:isDeleted];
  273. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  274. [item.modes removeObjectsAtIndexes:isDeleted];
  275. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeAppPush]) {//푸시일 경우,
  276. [item.pushes removeObjectsAtIndexes:isDeleted];
  277. }
  278. }
  279. // [RulesRegisterViewController setSubItemsFromItem:_triggers];
  280. // [RulesRegisterViewController setSubItemsFromItem:_actions];
  281. // [RulesRegisterViewController setSubItemsFromItem:_conditions];
  282. }
  283. //룰 수정 시 - 아이템에 사전정의 아이템의 서브타입 코드를 넣어줌, 사전정의 아이템을 추가함.
  284. + (void)appendItem:(NSMutableArray<ItemModel> *)items withPredefinedRuleItems:(NSArray<ItemModel> *)predItems isRuleMode:(BOOL)isRuleMode {
  285. NSInteger i = 0;
  286. for (ItemModel *predItem in predItems) {
  287. NSInteger indx = [items indexOfObjectPassingTest:^BOOL(ItemModel *obj, NSUInteger idx, BOOL *stop) {
  288. if (isRuleMode) {//규칙 모드일 경우,
  289. return [obj.itemSubTypeCode isEqualToString:predItem.itemSubTypeCode];
  290. } else {//Scene 모드일 경우,
  291. return [obj.predActionSequence isEqualToString:predItem.predActionSequence];
  292. }
  293. }];
  294. if (indx == NSNotFound) {
  295. [items insertObject:predItem atIndex:i];
  296. } else {
  297. ((ItemModel *)items[i]).itemTypeCode = predItem.itemTypeCode;
  298. }
  299. i++;
  300. }
  301. }
  302. - (void)matchRuleDetailWithPredefinedRuleDeatil:(PredefinedRuleDetailModel *)predRuleDetail {
  303. [RulesRegisterViewController appendItem:_triggers withPredefinedRuleItems:predRuleDetail.triggers isRuleMode:YES];
  304. [RulesRegisterViewController appendItem:_actions withPredefinedRuleItems:predRuleDetail.actions isRuleMode:YES];
  305. [RulesRegisterViewController appendItem:_conditions withPredefinedRuleItems:predRuleDetail.conditions isRuleMode:YES];
  306. [_tableView reloadData];
  307. }
  308. //서브아이템 배열을 리턴함.
  309. - (NSArray *)subItemsForType:(NSArray *)subItems itemSubType:(NSString *)itemSubTypeCode {
  310. NSMutableArray *rSubItems = [[NSMutableArray alloc] init];
  311. if ([itemSubTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  312. for (PredefinedDeviceModel *pdevice in subItems) {
  313. NSDictionary *rSubItem = @{@"source_id": pdevice.deviceId,
  314. @"source_sub_id": pdevice.nodeId,
  315. @"condition_type_code": pdevice.conditionTypeCode ? pdevice.conditionTypeCode : [NSNull null],
  316. @"cmdcls_value": pdevice.cmdclsValue,
  317. @"data_type_code": pdevice.dataTypeCode,
  318. };
  319. [rSubItems addObject:rSubItem];
  320. }
  321. } else if ([itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  322. for (ModeModel *mode in subItems) {
  323. NSDictionary *rSubItem = @{@"source_id": @"VAR",
  324. @"cmdcls_value": mode.modeId};
  325. [rSubItems addObject:rSubItem];
  326. }
  327. } else if ([itemSubTypeCode isEqualToString:ksItemSubTypeCodeAppPush]) {//푸시일 경우,
  328. //at once.
  329. for (ItemSubModel *subItem in subItems) {
  330. NSDictionary *rSubItem = @{
  331. @"source_id": subItem.sourceId,
  332. @"cmdcls_value": subItem.cmdclsValue,
  333. @"condition_type_code" : subItem.conditionTypeCode,
  334. @"data_type_code": @"03"};
  335. [rSubItems addObject:rSubItem];
  336. }
  337. } else if ([itemSubTypeCode isEqualToString:ksItemSubTypeCodeTimer]) {//타이머일 경우,
  338. for (ItemSubModel *subItem in subItems) {
  339. NSDictionary *rSubItem = @{@"hour": subItem.hour,
  340. @"minute": subItem.minute};
  341. [rSubItems addObject:rSubItem];
  342. }
  343. } else if ([itemSubTypeCode isEqualToString:ksItemSubTypeCodeGeoFencing]) {//지오펜싱일 경우,
  344. for (DeviceModel *device in subItems) {
  345. NSDictionary *rSubItem = @{@"source_id": device.deviceId,
  346. @"source_sub_id": device.nodeId,
  347. @"condition_type_code": device.conditionTypeCode,
  348. @"cmdcls_value": device.cmdclsValue,
  349. @"data_type_code": device.dataTypeCode,
  350. };
  351. [rSubItems addObject:rSubItem];
  352. }
  353. }
  354. return rSubItems;
  355. }
  356. //아이템 배열을 리턴함.
  357. - (NSArray *)items:(NSArray<ItemModel> *)items {
  358. //triggers, actions, conditions
  359. NSMutableArray *rItems = [[NSMutableArray alloc] init];
  360. for (ItemModel *item in items) {
  361. NSDictionary *dic = nil;
  362. NSMutableArray *subItems = [[NSMutableArray alloc] init];
  363. NSArray *pdevices = [self subItemsForType:item.predDevices itemSubType:ksItemSubTypeCodeDevice];
  364. NSArray *modes = [self subItemsForType:item.modes itemSubType:ksItemSubTypeCodeMode];
  365. NSArray *pushes = [self subItemsForType:item.pushes itemSubType:ksItemSubTypeCodeAppPush];
  366. NSArray *timers = [self subItemsForType:item.timers itemSubType:ksItemSubTypeCodeTimer];
  367. NSArray *geofencings = [self subItemsForType:item.mobileDevices itemSubType:ksItemSubTypeCodeGeoFencing];
  368. if (pdevices && pdevices.count) {//device
  369. [subItems addObjectsFromArray:pdevices];
  370. }
  371. if (modes && modes.count) {//mode
  372. [subItems addObjectsFromArray:modes];
  373. }
  374. if (pushes && pushes.count) {//push
  375. [subItems addObjectsFromArray:pushes];
  376. }
  377. if (timers && timers.count) {//timer
  378. [subItems addObjectsFromArray:timers];
  379. }
  380. if (geofencings && geofencings.count) {//geofence
  381. [subItems addObjectsFromArray:geofencings];
  382. }
  383. if (subItems.count) {
  384. dic = @{@"pred_item_sequence": item.predItemSequence,
  385. @"item_name": item.itemName,
  386. @"item_sub_type_code": item.itemSubTypeCode,
  387. @"item_sub": subItems};
  388. [rItems addObject:dic];
  389. }
  390. }
  391. return rItems;
  392. }
  393. - (NSArray *)conditions:(NSArray<ItemModel> *)items {//trigger만 해당됨.
  394. //conditions
  395. NSMutableArray *rConditions = [[NSMutableArray alloc] init];
  396. for (ItemModel *item in items) {
  397. ItemSubModel *subItem = nil;
  398. if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  399. subItem = item.predDevices && item.predDevices.count ? item.predDevices[0] : nil;
  400. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  401. subItem = item.modes[0];
  402. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeTimer]) {//타이머일 경우,
  403. subItem = item.timers[0];
  404. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeGeoFencing]) {//지오펜싱일 경우,
  405. subItem = item.mobileDevices && item.mobileDevices.count ? item.mobileDevices[0] : nil;
  406. }
  407. for (ItemModel *condition in subItem.conditions) {//컨디션 여부
  408. ItemModel *copyCondition = [condition copy];
  409. for (ItemSubModel *subCondition in copyCondition.subItems) {
  410. subCondition.cmdclsValueMsg = nil;
  411. subCondition.dueDate = nil;
  412. subCondition.daysOfWeek = nil;
  413. subCondition.dueTime = nil;
  414. subCondition.homeModes = nil;
  415. subCondition.externHeat = nil;
  416. }
  417. [rConditions addObject:[copyCondition toDictionary]];
  418. }
  419. }
  420. return rConditions;
  421. }
  422. - (void)requestRegisterRule {
  423. NSArray *triggers = [self items:[self triggers]];
  424. NSArray *actions = [self items:_actions];
  425. NSArray *conditions = [self conditions:[self triggers]];
  426. //validate
  427. if (!triggers || !triggers.count) {
  428. [[JDFacade facade] alert:NSLocalizedString(@"선택된 트리거가 없습니다", @"선택된 트리거가 없습니다")];
  429. return;
  430. }
  431. if (!actions || !actions.count) {
  432. [[JDFacade facade] alert:NSLocalizedString(@"액션이 없습니다", @"액션이 없습니다")];
  433. return;
  434. }
  435. //1.트리거 == 모드 && 액션 == 모드
  436. for (ItemModel *trigger in [self triggers]) {
  437. if ([trigger.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {
  438. for (ItemModel *action in _actions) {
  439. if ([action.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {
  440. [[JDFacade facade] alert:NSLocalizedString(@"'홈 모드가 바뀔 때'인 경우에는 실행 목록에서 '홈 모드 변경'을 선택할 수 없습니다", @"'홈 모드가 바뀔 때'인 경우에는 실행 목록에서 '홈 모드 변경'을 선택할 수 없습니다")];
  441. return;
  442. }
  443. }
  444. }
  445. }
  446. for (ItemModel *action in _actions) {
  447. if ([action.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {
  448. for (NSDictionary *condition in conditions) {//컨디션에 모드가 있을 경우,
  449. if ([condition[@"item_sub_type_code"] isEqualToString:ksItemSubTypeCodeMode]) {
  450. [[JDFacade facade] alert:NSLocalizedString(@"'홈 모드 변경'인 경우에는 추가 조건에서 '홈 모드'를 선택할 수 없습니다", @"'홈 모드 변경'인 경우에는 추가 조건에서 '홈 모드'를 선택할 수 없습니다")];
  451. return;
  452. }
  453. }
  454. }
  455. }
  456. //parameters
  457. NSDictionary *parameter = @{@"pred_rule_id" : _predRuleId,
  458. @"rule_name" : _ruleName,
  459. @"use_yn" : ksYES,
  460. @"triggers": triggers ? triggers : [NSNull null],
  461. @"actions": actions ? actions : [NSNull null],
  462. @"conditions": conditions ? conditions : [NSNull null]};
  463. NSString *path = [NSString stringWithFormat:API_POST_RULE];
  464. [[RequestHandler handler] sendAsyncPostRequestAPIPath:path parameters:parameter modelClass:[JDJSONModel class] completion:^(id responseObject) {
  465. if (!responseObject) {//응답결과가 잘못되었거나 없을 경우,
  466. return;
  467. }
  468. JDJSONModel *result = (JDJSONModel *) responseObject;
  469. if (result) {//API 성공 ,
  470. [[JDFacade facade] toast:NSLocalizedString(@"등록되었습니다", @"등록되었습니다")];
  471. [[JDFacade facade] gotoWishMenu:KNMenuIdRules];
  472. }
  473. } failure:^(id errorObject) {
  474. JDErrorModel *error = (JDErrorModel *)errorObject;
  475. [[JDFacade facade] alert:error.errorMessage];
  476. }];
  477. }
  478. - (void)requestModifyRule {
  479. NSArray *triggers = [self items:[self triggers]];
  480. NSArray *actions = [self items:_actions];
  481. NSArray *conditions = [self conditions:[self triggers]];
  482. //validate
  483. // if (!triggers || !triggers.count || !triggers[@"item_sub"] || ![((NSArray *)triggers[@"item_sub"]) count]) {
  484. if (!triggers || !triggers.count) {
  485. [[JDFacade facade] alert:NSLocalizedString(@"트리거가 없습니다", @"트리거가 없습니다")];
  486. return;
  487. }
  488. if (!actions || !actions.count) {
  489. [[JDFacade facade] alert:NSLocalizedString(@"액션이 없습니다", @"액션이 없습니다")];
  490. return;
  491. }
  492. //1.트리거 == 모드 && 액션 == 모드
  493. for (ItemModel *trigger in [self triggers]) {
  494. if ([trigger.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {
  495. for (ItemModel *action in _actions) {
  496. if ([action.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {
  497. [[JDFacade facade] alert:NSLocalizedString(@"'홈 모드가 바뀔 때'인 경우에는 실행 목록에서 '홈 모드 변경'을 선택할 수 없습니다", @"'홈 모드가 바뀔 때'인 경우에는 실행 목록에서 '홈 모드 변경'을 선택할 수 없습니다")];
  498. return;
  499. }
  500. }
  501. }
  502. }
  503. for (ItemModel *action in _actions) {
  504. if ([action.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {
  505. for (NSDictionary *condition in conditions) {//컨디션에 모드가 있을 경우,
  506. if ([condition[@"item_sub_type_code"] isEqualToString:ksItemSubTypeCodeMode]) {
  507. [[JDFacade facade] alert:NSLocalizedString(@"'홈 모드 변경'인 경우에는 추가 조건에서 '홈 모드'를 선택할 수 없습니다", @"'홈 모드 변경'인 경우에는 추가 조건에서 '홈 모드'를 선택할 수 없습니다")];
  508. return;
  509. }
  510. }
  511. }
  512. }
  513. //parameters
  514. NSDictionary *parameter = @{@"pred_rule_id" : _predRuleId,
  515. @"rule_name" : _ruleName,
  516. @"use_yn" : ksYES,
  517. @"triggers": triggers ? triggers : [NSNull null],
  518. @"actions": actions ? actions : [NSNull null],
  519. @"conditions": conditions ? conditions : [NSNull null]};
  520. NSString *path = [NSString stringWithFormat:API_POST_RULE_MODIFY, _tmpRuleDetail.homegrpRuleId];
  521. [[RequestHandler handler] sendAsyncPostRequestAPIPath:path parameters:parameter modelClass:[RuleModel class] completion:^(id responseObject) {
  522. if (!responseObject) {//응답결과가 잘못되었거나 없을 경우,
  523. return;
  524. }
  525. RuleModel *rule = (RuleModel *) responseObject;
  526. if (rule) {//API 성공 ,
  527. _tmpRuleDetail.ruleId = rule.ruleId;
  528. _tmpRuleDetail.ruleName = _ruleName;
  529. RulesViewController *vc = [[JDFacade facade] viewControllerOnNaviationController:[RulesViewController class]];
  530. [vc prepareViewDidLoad];
  531. [[JDFacade facade] toast:@"수정되었습니다."];
  532. [self.navigationController popViewControllerAnimated:YES];
  533. }
  534. } failure:^(id errorObject) {
  535. JDErrorModel *error = (JDErrorModel *)errorObject;
  536. [[JDFacade facade] alert:error.errorMessage];
  537. }];
  538. }
  539. #pragma mark - UITableView DataSource & Delegate
  540. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  541. return 3;
  542. }
  543. - (NSString *)titleForSectionHeader:(NSInteger)section {
  544. NSString *title = nil;
  545. switch (section) {
  546. case 0:
  547. title = NSLocalizedString(@"언제 실행할까요?", @"언제 실행할까요?");
  548. break;
  549. case 1:
  550. title = NSLocalizedString(@"무엇을 실행할까요?", @"무엇을 실행할까요?");
  551. break;
  552. case 2:
  553. title = NSLocalizedString(@"규칙에 이름을 붙여주세요", @"규칙에 이름을 붙여주세요");
  554. break;
  555. }
  556. return title;
  557. }
  558. - (UIImage *)imageForSection:(NSInteger)section {
  559. UIImage *image = nil;
  560. switch (section) {
  561. case 0:
  562. image = _iconTrigger;
  563. break;
  564. case 1:
  565. image = _iconAction;
  566. break;
  567. case 2:
  568. break;
  569. }
  570. return image;
  571. }
  572. - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
  573. UIView *view = _arrayForHeader.count > section ? _arrayForHeader[section] : nil;
  574. if (!view) {
  575. RulesCreateHeaderTableViewCell *hcell = (RulesCreateHeaderTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"HeaderCellIdentifier"];
  576. CGFloat height = [self tableView:tableView heightForHeaderInSection:section];
  577. hcell.frame = CGRectMake(0, 0, IPHONE_WIDTH, height);
  578. if (section == 0) {
  579. hcell.imgvTop.hidden = YES;
  580. hcell.constraintHeaderTitleTop.constant = 10;
  581. }
  582. view = [[UIView alloc] initWithFrame:hcell.frame];
  583. [view addSubview:hcell];
  584. hcell.lblHeaderTitle.text = [self titleForSectionHeader:section];
  585. [_arrayForHeader insertObject:view atIndex:section];
  586. }
  587. return view;
  588. }
  589. - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
  590. if (section == 0) {
  591. return 65.0f;
  592. }
  593. return 72.0f;
  594. }
  595. - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
  596. return 0.01f;
  597. }
  598. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  599. NSInteger count = 0;
  600. if (section == 2) {
  601. count = 1;
  602. } else if (section == 0) {
  603. count = [self triggers].count;
  604. } else if (section == 1) {
  605. count = _actions.count + _isCustomCreation;
  606. }
  607. // else if (section == 2) {
  608. // count = _conditions.count;
  609. // }
  610. return count;
  611. }
  612. + (CGFloat)heightForSubItems:(ItemModel *)item isTrigger:(BOOL)isTrigger {
  613. NSString *subTypeCode = item.itemSubTypeCode;
  614. CGFloat width = IPHONE_WIDTH - 80;
  615. CustomLabel *lblTemp = [[CustomLabel alloc] initWithFrame:CGRectMake(0, 0, width, 20)];
  616. lblTemp.font = [UIFont systemFontOfSize:kUIFontSize06];
  617. lblTemp.numberOfLines = 0;
  618. CGFloat titleHeight = 0.0f;
  619. if (isTrigger) {//triggers
  620. CGFloat twidth = IPHONE_WIDTH - 80 - 25;
  621. CustomLabel *lblTitle = [[CustomLabel alloc] initWithFrame:CGRectMake(0, 0, twidth, 55)];
  622. lblTitle.font = [UIFont systemFontOfSize:kUIFontSize01];
  623. lblTitle.numberOfLines = 0;
  624. //타이틀 사이즈를 구함.
  625. ItemSubModel *subItem = [RulesRegisterViewController subItemAndfillTriggerTitle:lblTitle item:item];
  626. if (subItem) {//삭제 버튼이 있을 경우,
  627. twidth = IPHONE_WIDTH - 80 - 25 - 30;
  628. }
  629. titleHeight = [CommonUtil getSizeFromString:lblTitle.text font:lblTitle.font width:twidth].height;
  630. titleHeight = titleHeight < 55.0f ? 0.0f : titleHeight - 55.0f; //원래 차지하는 사이즈만큼 빼줌.
  631. for (ItemModel *condition in subItem.conditions) {
  632. //TODO : 컨디션은 1개의 서브 컨디션을 갖음 (0.6 버전)
  633. ItemSubModel *subCondition = condition.subItems[0];
  634. [self fillConditionSubItemToLabel:lblTemp item:subCondition itemSubTypeCode:condition.itemSubTypeCode];
  635. }
  636. } else {//actions
  637. if ([subTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  638. [RulesRegisterViewController fillPredDeviceSubItemsToLabel:lblTemp item:item];
  639. } else if ([subTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  640. [RulesRegisterViewController fillModeSubItemsToLabel:lblTemp item:item];
  641. } else if ([subTypeCode isEqualToString:ksItemSubTypeCodeAppPush]) {//푸시일 경우,
  642. CGFloat twidth = IPHONE_WIDTH - 80 - 25;
  643. CustomLabel *lblTitle = [[CustomLabel alloc] initWithFrame:CGRectMake(0, 0, twidth, 55)];
  644. lblTitle.font = [UIFont systemFontOfSize:kUIFontSize01];
  645. lblTitle.numberOfLines = 0;
  646. //타이틀 사이즈를 구함.
  647. if (item.pushes && item.pushes.count) {//삭제 버튼이 있을 경우,
  648. twidth = IPHONE_WIDTH - 80 - 25 - 30;
  649. }
  650. titleHeight = [CommonUtil getSizeFromString:lblTitle.text font:lblTitle.font width:twidth].height;
  651. titleHeight = titleHeight < 55.0f ? 0.0f : titleHeight - 55.0f; //원래 차지하는 사이즈만큼 빼줌.
  652. [RulesRegisterViewController fillPushesSubItemsToLabel:lblTemp item:item];
  653. }
  654. }
  655. CGFloat height = [CommonUtil getSizeFromAttributeString:lblTemp.attributedText width:width].height;
  656. return height + titleHeight; //add margin
  657. }
  658. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  659. CGFloat height = 0;
  660. if (indexPath.section == 0 || indexPath.section == 1) {
  661. //calcualate subItemsText
  662. NSArray *items = nil;
  663. if (indexPath.section == 0) {
  664. items = [self triggers];
  665. } else if (indexPath.section == 1) {
  666. items = _actions;
  667. if (indexPath.row == _actions.count) {//자유롭게 만들기 셀 (액션 추가)
  668. height = 60.0f;
  669. return height;
  670. }
  671. }
  672. ItemModel *item = items[indexPath.row];
  673. CGFloat adjustHeight = [RulesRegisterViewController heightForSubItems:item isTrigger:indexPath.section == 0];
  674. adjustHeight = adjustHeight > 0 ? adjustHeight + 15 + 20 : adjustHeight;
  675. height = 60 + adjustHeight;
  676. } else if (indexPath.section == 2) {
  677. height = 89.0f;
  678. }
  679. return height;
  680. }
  681. + (void)fillPredDeviceSubItemsToLabel:(CustomLabel *)label item:(ItemModel *)item {
  682. for (PredefinedDeviceModel *pdevice in item.predDevices) {
  683. NSMutableAttributedString *subText = [[NSMutableAttributedString alloc] initWithAttributedString:label.attributedText];
  684. NSString *prefix = [item.predDevices.firstObject isEqual:pdevice] ? ksEmptyString: @", ";
  685. NSString *deviceName = [NSString stringWithFormat:@"%@(%@)", pdevice.deviceName, pdevice.nodeName];
  686. NSString *text = [NSString stringWithFormat:@"%@● %@", prefix, deviceName];
  687. NSDictionary *attrColor = @{NSForegroundColorAttributeName : [pdevice.deleteYn boolValue] ? kUITextColor02 : kUITextColor01};
  688. NSMutableAttributedString *attrDeviceName = [[NSMutableAttributedString alloc] initWithString:text];
  689. [attrDeviceName addAttributes:attrColor range:[text rangeOfString:deviceName]];
  690. if ([pdevice.deleteYn boolValue]) {
  691. NSDictionary *attrStrike = @{NSStrikethroughStyleAttributeName: @(NSUnderlineStyleSingle)};
  692. [attrDeviceName addAttributes:attrStrike range:[text rangeOfString:deviceName]];
  693. }
  694. [subText appendAttributedString:attrDeviceName];
  695. label.attributedText = subText;
  696. }
  697. }
  698. + (void)fillModeSubItemsToLabel:(CustomLabel *)label item:(ItemModel *)item {
  699. for (ModeModel *mode in item.modes) {
  700. NSMutableAttributedString *subText = [[NSMutableAttributedString alloc] initWithAttributedString:label.attributedText];
  701. NSString *prefix = [item.modes.firstObject isEqual:mode] ? ksEmptyString: @", ";
  702. NSString *modeName = [NSString stringWithFormat:@"%@● %@", prefix, mode.modeName];
  703. [subText appendAttributedString:[[NSAttributedString alloc] initWithString:modeName]];
  704. label.attributedText = subText;
  705. }
  706. }
  707. + (void)fillPushesSubItemsToLabel:(CustomLabel *)label item:(ItemModel *)item {
  708. if (item.pushes && item.pushes.count) {
  709. ItemSubModel *push = item.pushes.firstObject;
  710. NSMutableAttributedString *subText = [[NSMutableAttributedString alloc] initWithAttributedString:label.attributedText];
  711. [subText appendAttributedString:[[NSAttributedString alloc] initWithString:push.cmdclsValue]];
  712. label.attributedText = subText;
  713. }
  714. }
  715. + (void)fillConditionSubItemToLabel:(CustomLabel *)label item:(ItemSubModel *)subItem itemSubTypeCode:(NSString *)itemSubTypeCode {
  716. NSMutableAttributedString *subText = [[NSMutableAttributedString alloc] initWithAttributedString:label.attributedText];
  717. NSString *prefix = [label.attributedText.string isEmptyString] ? ksEmptyString : @"\n";
  718. NSString *cname = nil;
  719. if ([itemSubTypeCode isEqualToString:ksConditionSubTypeCodeDueDate]) {//기간
  720. cname = NSLocalizedString(@"기간", @"기간");
  721. } else if ([itemSubTypeCode isEqualToString:ksConditionSubTypeCodeDaysOfWeek]) {//요일
  722. cname = NSLocalizedString(@"요일", @"요일");
  723. } else if ([itemSubTypeCode isEqualToString:ksConditionSubTypeCodeDueTime]) {//시간
  724. cname = NSLocalizedString(@"시간", @"시간");
  725. } else if ([itemSubTypeCode isEqualToString:ksConditionSubTypeCodeHomeMode]) {//홈모드
  726. cname = NSLocalizedString(@"홈모드", @"홈모드");
  727. } else if ([itemSubTypeCode isEqualToString:ksConditionSubTypeCodeExternHeat]) {//바깥온도
  728. cname = NSLocalizedString(@"지역온도", @"지역온도");
  729. }
  730. NSString *deviceName = [NSString stringWithFormat:@"%@ ➜ %@ : %@", prefix, cname, subItem.cmdclsValueMsg];
  731. [subText appendAttributedString:[[NSAttributedString alloc] initWithString:deviceName]];
  732. label.attributedText = subText;
  733. }
  734. + (ItemSubModel *)subItemAndfillTriggerTitle:(CustomLabel *)label item:(ItemModel *)item {
  735. NSString *subTypeCode = item.itemSubTypeCode;
  736. ItemSubModel *subItem = nil;
  737. if ([subTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  738. PredefinedDeviceModel *pdevice = item.predDevices && item.predDevices.count ? item.predDevices[0] : nil;
  739. if (pdevice) {
  740. NSDictionary *attrColor = @{NSForegroundColorAttributeName : [pdevice.deleteYn boolValue] ? kUITextColor02 : kUITextColor01};
  741. NSString *condition = [pdevice.conditionTypeCode isEqualToString:@"02"] ? NSLocalizedString(@"미만 시", @"미만 시") : ksEmptyString;
  742. condition = [pdevice.conditionTypeCode isEqualToString:@"04"] ? NSLocalizedString(@"초과 시", @"초과 시") : condition;
  743. NSString *deviceName = [NSString stringWithFormat:@"\n%@ : %@ %@ %@", pdevice.deviceName, pdevice.nodeName, pdevice.cmdclsValue, condition];
  744. NSMutableAttributedString *attrDeviceName = [[NSMutableAttributedString alloc] initWithString:deviceName];
  745. [attrDeviceName addAttributes:attrColor range:[deviceName rangeOfString:deviceName]];
  746. if ([pdevice.deleteYn boolValue]) {
  747. NSDictionary *attrStrike = @{NSStrikethroughStyleAttributeName: @(NSUnderlineStyleSingle)};
  748. [attrDeviceName addAttributes:attrStrike range:[deviceName rangeOfString:deviceName]];
  749. }
  750. NSMutableAttributedString *titleText = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@", item.itemName]];
  751. [titleText appendAttributedString:attrDeviceName];
  752. NSDictionary *titleColor = @{NSForegroundColorAttributeName : kUITextColor02};
  753. [titleText setAttributes:titleColor range:[item.itemName rangeOfString:item.itemName]];
  754. label.attributedText = titleText;
  755. subItem = pdevice;
  756. }
  757. } else if ([subTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//홈모드일 경우,
  758. ModeModel *mode = item.modes && item.modes.count ? item.modes[0] : nil;
  759. if (mode) {
  760. NSString *modeTitle = [NSString stringWithFormat:NSLocalizedString(@"[%@]로 바뀔 때", @"[%@]로 바뀔 때"), mode.modeName];
  761. NSDictionary *titleColor = @{NSForegroundColorAttributeName : kUITextColor02};
  762. label.attributedText = [[NSMutableAttributedString alloc] initWithString:modeTitle attributes:titleColor];
  763. subItem = mode;
  764. }
  765. } else if ([subTypeCode isEqualToString:ksItemSubTypeCodeTimer]) {//타이머일 경우,
  766. subItem = item.timers && item.timers.count ? item.timers[0] : nil;
  767. if (subItem) {
  768. NSInteger phour = [subItem.hour integerValue];
  769. NSString *period = phour < 12 ? NSLocalizedString(@"오전", @"오전") : NSLocalizedString(@"오후", @"오후");
  770. if ([period isEqualToString:NSLocalizedString(@"오후", @"오후")]) {
  771. phour -= 12;
  772. }
  773. NSString *title = [NSString stringWithFormat:NSLocalizedString(@"%@ %zd시 %@분", @"%@ %zd시 %@분"), period, phour, subItem.minute];
  774. NSDictionary *titleColor = @{NSForegroundColorAttributeName : kUITextColor02};
  775. label.attributedText = [[NSMutableAttributedString alloc] initWithString:title attributes:titleColor];
  776. }
  777. } else if ([subTypeCode isEqualToString:ksItemSubTypeCodeGeoFencing]) {//지오펜싱일 경우,
  778. if (item.mobileDevices && item.mobileDevices.count) {
  779. NSString *geoMode = nil;
  780. NSMutableString *fam = [[NSMutableString alloc] init];
  781. for (DeviceModel *device in item.mobileDevices) {
  782. if (!geoMode) {
  783. subItem = device;
  784. geoMode = [device.cmdclsValue isEqualToString:@"TRUE"] ? NSLocalizedString(@"도착할 때", @"도착할 때") : NSLocalizedString(@"출발할 때", @"출발할 때");
  785. }
  786. NSString *prefix = [fam isEmptyString] ? @"" : @", ";
  787. [fam appendFormat:@"%@%@ (%@)", prefix, device.nickname, device.deviceName];
  788. }
  789. NSString *title = [NSString stringWithFormat:@"%@\n%@", geoMode, fam];
  790. NSDictionary *titleColor = @{NSForegroundColorAttributeName : kUITextColor02};
  791. NSMutableAttributedString *attrTitle = [[NSMutableAttributedString alloc] initWithString:title];
  792. [attrTitle setAttributes:titleColor range:[title rangeOfString:geoMode]];
  793. label.attributedText = attrTitle;
  794. }
  795. }
  796. return subItem;
  797. }
  798. + (void)fillCell:(RulesCreateTableViewCell *)cell item:(ItemModel *)item isTrigger:(BOOL)isTrigger {
  799. cell.lblItemName.attributedText = [[NSAttributedString alloc] initWithString:item.itemName];
  800. cell.lblSubItems.text = ksEmptyString;
  801. cell.lblSubItems.hidden = YES;
  802. NSString *subTypeCode = item.itemSubTypeCode;
  803. CGFloat titleHeight = 0.0f;
  804. CGFloat adjustHeight = 0.0f;
  805. cell.item = item;
  806. ItemSubModel *subItem = nil;
  807. if (isTrigger) {//triggers
  808. subItem = [RulesRegisterViewController subItemAndfillTriggerTitle:cell.lblItemName item:item];
  809. cell.lblSubItems.hidden = !(subItem.conditions && subItem.conditions.count);
  810. CGFloat deleteWidth = !subItem ? 0 : 30.0f;
  811. cell.constraintTitleLabelRight.constant = !subItem ? -20.0f : -50.0f;
  812. titleHeight = [CommonUtil getSizeFromAttributeString:cell.lblItemName.attributedText width:IPHONE_WIDTH - 80 - 25.0f - deleteWidth].height; //padding, image margin
  813. titleHeight = titleHeight <= 55.0f ? 0.0f : titleHeight - 55.0f;
  814. cell.btnDeleteSubItems.hidden = !subItem; //트리거가 있는 경우,
  815. //컨디션이 있을 경우,
  816. cell.lineview.hidden = cell.lblSubItems.hidden;
  817. if (!cell.lblSubItems.hidden) {//컨디션이 있을 경우,
  818. for (ItemModel *condition in subItem.conditions) {
  819. //TODO : 컨디션은 1개의 서브 컨디션을 갖음 (0.6 버전)
  820. ItemSubModel *subCondition = condition.subItems[0];
  821. [self fillConditionSubItemToLabel:cell.lblSubItems item:subCondition itemSubTypeCode:condition.itemSubTypeCode];
  822. adjustHeight = [CommonUtil getSizeFromAttributeString:cell.lblSubItems.attributedText width:IPHONE_WIDTH - 80].height;
  823. }
  824. }
  825. } else {//actions
  826. if ([subTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  827. cell.lblSubItems.hidden = !item.predDevices.count;
  828. cell.lineview.hidden = cell.btnDeleteSubItems.hidden = cell.lblSubItems.hidden;
  829. [self fillPredDeviceSubItemsToLabel:cell.lblSubItems item:item];
  830. adjustHeight = [CommonUtil getSizeFromAttributeString:cell.lblSubItems.attributedText width:IPHONE_WIDTH - 80].height; //subtract left, right margin
  831. } else if ([subTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  832. cell.lblSubItems.hidden = !item.modes.count;
  833. cell.lineview.hidden = cell.btnDeleteSubItems.hidden = cell.lblSubItems.hidden;
  834. [self fillModeSubItemsToLabel:cell.lblSubItems item:item];
  835. adjustHeight = [CommonUtil getSizeFromAttributeString:cell.lblSubItems.attributedText width:IPHONE_WIDTH - 80].height;
  836. } else if ([subTypeCode isEqualToString:ksItemSubTypeCodeAppPush]) {//푸시일 경우,
  837. cell.lblSubItems.hidden = !item.pushes.count;
  838. cell.lineview.hidden = cell.btnDeleteSubItems.hidden = cell.lblSubItems.hidden;
  839. //멤버 표시
  840. NSMutableAttributedString *pmem = [[NSMutableAttributedString alloc] init];
  841. for (ItemSubModel *subItem in item.pushes) {
  842. NSString *prefix = [pmem.string isEmptyString] ? @"\n" : @", ";
  843. NSDictionary *attrColor = @{NSForegroundColorAttributeName : [subItem.deleteYn boolValue] ? kUITextColor02 : kUITextColor01};
  844. NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@%@", prefix, subItem.sourceName]];
  845. [attrString addAttributes:attrColor range:[attrString.string rangeOfString:subItem.sourceName]];
  846. if ([subItem.deleteYn boolValue]) {
  847. NSDictionary *attrStrike = @{NSStrikethroughStyleAttributeName: @(NSUnderlineStyleSingle)};
  848. [attrString addAttributes:attrStrike range:[attrString.string rangeOfString:subItem.sourceName]];
  849. }
  850. [pmem appendAttributedString:attrString];
  851. }
  852. NSMutableAttributedString *title = [[NSMutableAttributedString alloc] initWithString:item.itemName];
  853. [title appendAttributedString:pmem];
  854. cell.lblItemName.attributedText = title;
  855. //타이틀 높이를 구함.
  856. CGFloat deleteWidth = (!item.pushes || !item.pushes.count) ? 0 : 30.0f;
  857. cell.constraintTitleLabelRight.constant = (!item.pushes || !item.pushes.count) ? -20.0f : -50.0f;
  858. titleHeight = [CommonUtil getSizeFromAttributeString:cell.lblItemName.attributedText width:IPHONE_WIDTH - 80 - 25.0f - deleteWidth].height; //padding, image margin
  859. titleHeight = titleHeight <= 55.0f ? 0.0f : titleHeight - 55.0f;
  860. [self fillPushesSubItemsToLabel:cell.lblSubItems item:item];
  861. adjustHeight = [CommonUtil getSizeFromAttributeString:cell.lblSubItems.attributedText width:IPHONE_WIDTH - 80].height;
  862. }
  863. if (adjustHeight > 0) {
  864. NSDictionary *titleColor = @{NSForegroundColorAttributeName : kUITextColor02};
  865. NSMutableAttributedString *attrItemName = [[NSMutableAttributedString alloc] initWithAttributedString:cell.lblItemName.attributedText];
  866. [attrItemName addAttributes:titleColor range:[item.itemName rangeOfString:item.itemName]];
  867. cell.lblItemName.attributedText = attrItemName;
  868. }
  869. }
  870. //배경 이미지 설정
  871. UIImage *bgImage = nil;
  872. if ([cell.lblSubItems.text isEmptyString]) {//서브아이템이 없을 경우, static title을 가져옴.
  873. // cell.lblSubItems.text = [ItemModel itemSubTypeString:subTypeCode];
  874. bgImage = subItem ? [UIImage imageNamed:@"tp_01_img_rule_rbox_bg_active"] : [UIImage imageNamed:@"tp_01_img_rule_rbox_bg"];
  875. cell.constraintImgvBgHeight.constant = 55.0f + titleHeight;
  876. } else {
  877. bgImage = [UIImage imageNamed:@"tp_01_img_rule_rbox_bg_active"];
  878. cell.constraintImgvBgHeight.constant = 55.0f + titleHeight + adjustHeight + 15 + 20; //label top, bottom margin add
  879. }
  880. [cell.imgvBg setImage:bgImage];
  881. }
  882. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  883. UITableViewCell *cell = nil;
  884. // NSLog(@"%s\n %zd, %zd", __PRETTY_FUNCTION__, indexPath.section, indexPath.row);
  885. if (indexPath.section == 2) {//타이틀 셀
  886. RulesCreateTitleTableViewCell *tcell = [tableView dequeueReusableCellWithIdentifier:@"TitleCellIdentifier"];
  887. if (tcell == nil) {
  888. tcell = [[RulesCreateTitleTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"TitleCellIdentifier"];
  889. }
  890. tcell.txtRuleTitle.text = [tcell.txtRuleTitle.text isEmptyString] ? _ruleName : tcell.txtRuleTitle.text;
  891. tcell.lblRuleTitle.text = [tcell.txtRuleTitle.text isEmptyString] ? NSLocalizedString(@"입력", @"입력") : tcell.txtRuleTitle.text;
  892. cell = tcell;
  893. } else {
  894. RulesCreateTableViewCell *tcell = [tableView dequeueReusableCellWithIdentifier:@"CellIdentifier"];
  895. if (tcell == nil) {
  896. tcell = [[RulesCreateTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CellIdentifier"];
  897. }
  898. NSArray *items = nil;
  899. if (indexPath.section == 0) {
  900. items = [self triggers];
  901. } else if (indexPath.section == 1) {
  902. items = _actions;
  903. UIImage *bgImage = [UIImage imageNamed:@"tp_01_img_rule_rbox_bg"];
  904. tcell.constraintImgvBgHeight.constant = 55.0f;
  905. [tcell.imgvBg setImage:bgImage];
  906. if (indexPath.row == _actions.count) {//자유롭게 만들기 셀 (액션 추가)
  907. tcell.lblItemName.text = NSLocalizedString(@"자유 선택", @"자유 선택");
  908. tcell.lblSubItems.hidden = YES;
  909. tcell.imgvItem.image = [self imageForSection:indexPath.section];
  910. tcell.lineview.hidden = tcell.btnDeleteSubItems.hidden = tcell.lblSubItems.hidden;
  911. return tcell;
  912. }
  913. }
  914. // else if (indexPath.section == 3) {
  915. // items = _conditions;
  916. //
  917. // }
  918. ItemModel *item = items[indexPath.row];
  919. [RulesRegisterViewController fillCell:tcell item:item isTrigger:indexPath.section == 0];
  920. tcell.indexPath = indexPath;
  921. tcell.btnDeleteSubItems.value = item;
  922. if (![tcell.btnDeleteSubItems actionsForTarget:self forControlEvent:UIControlEventTouchUpInside]) {
  923. [tcell.btnDeleteSubItems addTarget:self action:@selector(btnDeleteSubItemsTouched:) forControlEvents:UIControlEventTouchUpInside];
  924. }
  925. tcell.imgvItem.image = [self imageForSection:indexPath.section];
  926. cell = tcell;
  927. }
  928. return cell;
  929. }
  930. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  931. if (indexPath.section == 2) { //텍스트필드를 포커스
  932. RulesCreateTitleTableViewCell *cell = (RulesCreateTitleTableViewCell *)[_tableView cellForRowAtIndexPath:indexPath];
  933. [cell setSelected:YES animated:YES];
  934. return;
  935. } else {
  936. NSIndexPath *ip = [NSIndexPath indexPathForItem:0 inSection:2]; //텍스트필드를 원상태로 되돌림
  937. RulesCreateTitleTableViewCell *cell = (RulesCreateTitleTableViewCell *)[_tableView cellForRowAtIndexPath:ip];
  938. if (!cell.txtRuleTitle.hidden && [cell.txtRuleTitle isFirstResponder]) {
  939. [cell.txtRuleTitle resignFirstResponder];
  940. }
  941. }
  942. [tableView deselectRowAtIndexPath:indexPath animated:YES];
  943. NSArray *items = nil;
  944. if (indexPath.section == 0) {
  945. items = [self triggers];
  946. } else if (indexPath.section == 1) {
  947. items = _actions;
  948. if (indexPath.row == _actions.count) {//자유롭게 만들기 셀 (액션 추가)
  949. //FIXME : 매번 로드를 해야되는가?
  950. if (!_actionPopTableView) {
  951. _actionPopTableView = [[ActionPopTableView alloc] initFromNib];
  952. _actionPopTableView.isRuleMode = YES;
  953. }
  954. _actionPopTableView.actions = _actions;
  955. [_actionPopTableView.tableView scrollsToTop];
  956. [_actionPopTableView show];
  957. return;
  958. }
  959. }
  960. // else if (indexPath.section == 2) {
  961. // items = _conditions;
  962. // }
  963. ItemModel *item = items[indexPath.row];
  964. UIViewController *vc = nil;
  965. if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  966. if (indexPath.section == 0) {//트리거
  967. RegisterCmdClsViewController *cvc = (RegisterCmdClsViewController *)[CommonUtil instantiateViewControllerWithIdentifier:@"RegisterCmdClsViewController" storyboardName:@"Rules"];
  968. cvc.title = [self titleForSectionHeader:indexPath.section];
  969. cvc.tmpItem = item;
  970. vc = cvc;
  971. } else if (indexPath.section == 1){//액션
  972. PredefinedDeviceViewController *dvc = (PredefinedDeviceViewController *)[CommonUtil instantiateViewControllerWithIdentifier:@"PredefinedDeviceViewController" storyboardName:@"Rules"];
  973. dvc.title = [self titleForSectionHeader:indexPath.section];
  974. dvc.predRuleId = _predRuleId;
  975. dvc.tmpItem = item;
  976. vc = dvc;
  977. }
  978. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  979. RegisterModeViewController *mvc = (RegisterModeViewController *)[CommonUtil instantiateViewControllerWithIdentifier:@"RegisterModeViewController" storyboardName:@"Rules"];
  980. mvc.title = [self titleForSectionHeader:indexPath.section];
  981. mvc.isTrigger = indexPath.section == 0; //0 == trigger
  982. mvc.tmpItem = item;
  983. vc = mvc;
  984. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeAppPush]) {//푸시일 경우,
  985. RegisterPushViewController *tvc = (RegisterPushViewController *)[CommonUtil instantiateViewControllerWithIdentifier:@"RegisterPushViewController" storyboardName:@"Rules"];
  986. tvc.title = [self titleForSectionHeader:indexPath.section];
  987. tvc.tmpItem = item;
  988. vc = tvc;
  989. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeTimer]) {//타이머일 경우,
  990. RegisterTimerViewController *tvc = (RegisterTimerViewController *)[CommonUtil instantiateViewControllerWithIdentifier:@"RegisterTimerViewController" storyboardName:@"Rules"];
  991. tvc.title = [self titleForSectionHeader:indexPath.section];
  992. tvc.tmpItem = item;
  993. vc = tvc;
  994. }
  995. [self.navigationController pushViewController:vc animated:YES];
  996. }
  997. - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
  998. // Remove seperator inset
  999. if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
  1000. [cell setSeparatorInset:UIEdgeInsetsZero];
  1001. }
  1002. // Prevent the cell from inheriting the Table View's margin settings
  1003. if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
  1004. [cell setPreservesSuperviewLayoutMargins:NO];
  1005. }
  1006. // Explictly set your cell's layout margins
  1007. if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
  1008. [cell setLayoutMargins:UIEdgeInsetsZero];
  1009. }
  1010. }
  1011. #pragma mark - UI Events
  1012. - (void)resetAllCheckbox {
  1013. // [_tableView enumarateTableViewCellsUsingBlock:^(UITableViewCell *cell) {
  1014. // ProductTableViewCell *pcell = (ProductTableViewCell *)cell;
  1015. // pcell.chkSelect.checked = NO;
  1016. // }];
  1017. }
  1018. - (void)btnCompleteRuleTouched:(id)sender {
  1019. [self.view endEditing:YES];
  1020. //1.Validate Title
  1021. RulesCreateTitleTableViewCell *tcell = (RulesCreateTitleTableViewCell *)[_tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:2]]; //마지막 섹션
  1022. if (tcell && ![ValidateUtil validateTextfiled:tcell.txtRuleTitle type:ValidateTypeNull title:NSLocalizedString(@"이름", @"이름")]) {
  1023. return;
  1024. }
  1025. if (!_tmpRuleDetail && !tcell) {
  1026. [[JDFacade facade] alert:NSLocalizedString(@"이름을 입력하세요", @"이름을 입력하세요")];
  1027. return;
  1028. }
  1029. _ruleName = !tcell ? _ruleName : tcell.txtRuleTitle.text;
  1030. if (!_tmpRuleDetail) {//생성
  1031. [self requestRegisterRule];
  1032. } else {//수정
  1033. [self requestModifyRule];
  1034. }
  1035. }
  1036. - (IBAction)btnCancelRuleTouched:(id)sender {
  1037. [self.navigationController popViewControllerAnimated:YES];
  1038. }
  1039. - (void)btnDeleteSubItemsTouched:(id)sender {
  1040. CustomButton *btnDeleteSubItems = (CustomButton *)sender;
  1041. ItemModel *item = (ItemModel *)btnDeleteSubItems.value;
  1042. NSInteger section = 0;
  1043. if ([[self triggers] containsObject:item]) {//trigger
  1044. if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우,
  1045. item.predDevices = nil;
  1046. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우,
  1047. item.modes = nil;
  1048. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeTimer]) {//타이머일 경우,
  1049. item.timers = nil;
  1050. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeGeoFencing]) {//지오펜싱일 경우,
  1051. item.mobileDevices = nil;
  1052. }
  1053. } else if ([_actions containsObject:item]) {//해당 액션을 삭제함.
  1054. ItemModel *action = btnDeleteSubItems.value;
  1055. action.predDevices = nil;
  1056. action.pushes = nil;
  1057. action.modes = nil;
  1058. action.cnt = @"0";
  1059. [_actions removeObject:item];
  1060. section = 1;
  1061. }
  1062. [_tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationFade];
  1063. }
  1064. #pragma mark - MemoryWarning
  1065. - (void)didReceiveMemoryWarning {
  1066. [super didReceiveMemoryWarning];
  1067. // Dispose of any resources that can be recreated.
  1068. }
  1069. @end