RulesConditionViewController.m 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. //
  2. // RulesConditionViewController.m
  3. // kneet2
  4. //
  5. // Created by Jason Lee on 11/25/15.
  6. // Copyright © 2015 ntels. All rights reserved.
  7. //
  8. #import "JDObject.h"
  9. #import "ItemModel.h"
  10. #import "CustomTableView.h"
  11. #import "CustomLabel.h"
  12. #import "CustomButton.h"
  13. #import "CustomImageView.h"
  14. #import "RulesConditionHomeModePopupView.h"
  15. #import "RulesAddViewController.h"
  16. #import "DeviceSelectPopupView.h"
  17. #import "DeviceNodePopupView.h"
  18. #import "UIImageView+WebCache.h"
  19. #import "RulesConditionViewController.h"
  20. #import "DurationPopupView.h"
  21. #define HEADER_TITLE_MODE @"이 홈모드에서만"
  22. #define HEADER_TITLE_DURATION @"이 기간동안"
  23. #define HEADER_TITLE_ACTION @"이 장치가 특정 상태일 때"
  24. #define HEADER_HEIGHT 38.0f
  25. @implementation RulesConditionHeaderTableViewCell
  26. @end
  27. @implementation RulesConditionDeviceTableViewCell
  28. @end
  29. @implementation RulesConditionTableViewCell
  30. @end
  31. @implementation RulesConditionFooterTableViewCell
  32. @end
  33. @interface RulesConditionViewController () <UITableViewDataSource, UITableViewDelegate> {
  34. CustomButton *_btnModeAdd, *_btnDurationAdd;
  35. NSMutableArray *_arrayForHeader;
  36. RulesConditionHomeModePopupView *_mpopup;
  37. DurationPopupView *_dpopup;
  38. }
  39. @property (weak, nonatomic, readonly) NSMutableArray<ItemSubModel> *modes;
  40. @property (weak, nonatomic, readonly) NSMutableArray<ItemSubModel> *durations;
  41. @property (weak, nonatomic, readonly) NSMutableArray<ItemSubModel> *pdevices;
  42. @end
  43. #pragma mark - Class Definition
  44. @implementation RulesConditionViewController
  45. - (void)viewDidLoad {
  46. [super viewDidLoad];
  47. // Do any additional setup after loading the view.
  48. [self initProperties];
  49. [self initUI];
  50. [self prepareViewDidLoad];
  51. }
  52. - (void)initProperties {
  53. _arrayForHeader = [[NSMutableArray alloc] init];
  54. }
  55. - (void)initUI {
  56. [self initTableViewAsDefaultStyle:_tableView];
  57. _tableView.scrollEnabled = NO;
  58. }
  59. - (void)prepareViewDidLoad {
  60. }
  61. - (CGFloat)tableHeight {
  62. CGFloat height = 0;
  63. height += self.modes.count > 0 ? HEADER_HEIGHT + 80 : 0;
  64. height += self.durations.count > 0 ? HEADER_HEIGHT + 80 : 0;
  65. height += self.pdevices.count > 0 ? HEADER_HEIGHT + (80 * self.pdevices.count) : 0;
  66. // if (_isShowingMode) {//규칙 상세일 경우,
  67. // height = self.modes.count > 0 ? height + 80 + HEADER_HEIGHT + 15: height;
  68. // height = self.durations.count > 0 ? height + 80 + HEADER_HEIGHT + 15: height;
  69. // height = self.pdevices.count > 0 ? height + (80 * self.pdevices.count) + HEADER_HEIGHT + 15 : height;
  70. //
  71. // } else {
  72. //
  73. // height += self.modes.count > 0 ? HEADER_HEIGHT + 80 : 0;
  74. // height += self.durations.count > 0 ? HEADER_HEIGHT + 80 : 0;
  75. // height += self.pdevices.count > 0 ? HEADER_HEIGHT + (80 * self.pdevices.count) : 0;
  76. //
  77. // }
  78. NSLog(@"height tableHeight %f", height);
  79. return height;
  80. }
  81. #pragma mark - Main Logic
  82. - (NSMutableArray<ItemSubModel> *)modes {
  83. ItemModel *mode = (ItemModel *)[_conditions objectKey:@"itemSubTypeCode" eqaulToString:ksConditionSubTypeCodeHomeMode];
  84. return mode.subItems;
  85. }
  86. - (NSMutableArray<ItemSubModel> *)durations {
  87. ItemModel *duration = (ItemModel *)[_conditions objectKey:@"itemSubTypeCode" eqaulToString:ksConditionSubTypeCodeDueDate];
  88. return duration.subItems;
  89. }
  90. - (NSMutableArray<ItemSubModel> *)pdevices {
  91. ItemModel *pdevice = (ItemModel *)[_conditions objectKey:@"itemSubTypeCode" eqaulToString:ksItemSubTypeCodeDevice];
  92. return pdevice.subItems;
  93. }
  94. //3개의 섹션이 있을 수 있는데 하위 로우가 있는 경우만 보여줘야 한다.
  95. -(NSInteger)getSectionCount {
  96. NSInteger sectionCount = 0;
  97. if ( self.modes.count > 0) sectionCount++;
  98. if ( self.durations.count > 0) sectionCount++;
  99. if ( self.pdevices.count > 0) sectionCount++;
  100. return sectionCount;
  101. }
  102. - (NSInteger)getRowCountFromSection:(NSInteger)sectionIdx {
  103. NSMutableArray *sections = [NSMutableArray new];
  104. if ( self.modes.count > 0) [sections addObject:self.modes];
  105. if ( self.durations.count > 0) [sections addObject:self.durations];
  106. if ( self.pdevices.count > 0) [sections addObject:self.pdevices];
  107. return [[sections objectAtIndex:sectionIdx] count];
  108. }
  109. - (NSString*)getHeaderTitle:(NSInteger)sectionIdx {
  110. NSMutableArray *sections = [NSMutableArray new];
  111. if ( self.modes.count > 0) [sections addObject:HEADER_TITLE_MODE];
  112. if ( self.durations.count > 0) [sections addObject:HEADER_TITLE_DURATION];
  113. if ( self.pdevices.count > 0) [sections addObject:HEADER_TITLE_ACTION];
  114. return [sections objectAtIndex:sectionIdx];
  115. }
  116. #pragma mark - UITableView DataSource & Delegate
  117. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  118. return [self getSectionCount];
  119. }
  120. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  121. return [self getRowCountFromSection:section];
  122. }
  123. - (NSString *)headerTitleForSection:(NSInteger)section {
  124. return [self getHeaderTitle:section];
  125. }
  126. //- (void)addTargetToHeaderAddButton:(CustomButton *)btnAdd section:(NSInteger)section {
  127. // if (section == 0) {
  128. // if (!_btnModeAdd) {
  129. // _btnModeAdd = btnAdd;
  130. // [btnAdd addTarget:self action:@selector(btnAddModeTouched:) forControlEvents:UIControlEventTouchUpInside];
  131. // }
  132. //
  133. // } else if (section == 1) {
  134. // if (!_btnDurationAdd) {
  135. // _btnDurationAdd = btnAdd;
  136. // [btnAdd addTarget:self action:@selector(btnAddDurationTouched:) forControlEvents:UIControlEventTouchUpInside];
  137. // }
  138. //
  139. // } else if (section == 2) {
  140. // [btnAdd addTarget:self action:@selector(btnAddDeviceTouched:) forControlEvents:UIControlEventTouchUpInside];
  141. // }
  142. //}
  143. - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
  144. BOOL hasHeader = [self getRowCountFromSection:section] || !_isShowingMode;
  145. UIView *view = _arrayForHeader.count > section ? _arrayForHeader[section] : nil;
  146. if (!view) {
  147. if (hasHeader) {
  148. RulesConditionHeaderTableViewCell *hcell = (RulesConditionHeaderTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"HeaderCellIdentifier"];
  149. hcell.width = IPHONE_WIDTH;
  150. view = [[UIView alloc] initWithFrame:hcell.contentView.frame];
  151. [view addSubview:hcell];
  152. hcell.lblTitle.text = [self headerTitleForSection:section];
  153. // hcell.btnAdd.hidden = _isShowingMode;
  154. //
  155. // if (!hcell.btnAdd.hidden && ![hcell.btnAdd actionsForTarget:self forControlEvent:UIControlEventTouchUpInside]) {
  156. // [self addTargetToHeaderAddButton:hcell.btnAdd section:section];
  157. // }
  158. } else {
  159. view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, IPHONE_WIDTH, CGFLOAT_MIN)];
  160. }
  161. if (_arrayForHeader.count == section) {
  162. [_arrayForHeader insertObject:view atIndex:section];
  163. }
  164. } else {
  165. if (hasHeader) {
  166. RulesConditionHeaderTableViewCell *hcell = (RulesConditionHeaderTableViewCell *)view.subviews[0];
  167. hcell.lblTitle.text = hcell.lblTitle.text = [self headerTitleForSection:section];
  168. }
  169. }
  170. if (!_isShowingMode) {
  171. [self checkHeaderButton:section];
  172. }
  173. return view;
  174. }
  175. - (void)checkHeaderButton:(NSInteger)section {
  176. if (section == 0) {//모드
  177. _btnModeAdd.hidden = self.modes.count > 0;
  178. }
  179. else if (section == 1) {//기간
  180. _btnDurationAdd.hidden = self.durations.count > 0;
  181. }
  182. }
  183. - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
  184. BOOL hasHeader = self.modes.count || self.durations.count || self.pdevices.count;
  185. return hasHeader ? HEADER_HEIGHT : CGFLOAT_MIN;
  186. }
  187. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  188. CGFloat height = 80.0f;
  189. return height;
  190. }
  191. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  192. UITableViewCell *cell = nil;
  193. NSString *headerTitle = [self getHeaderTitle:indexPath.section];
  194. SWITCH(headerTitle)
  195. {
  196. CASE(HEADER_TITLE_MODE)
  197. {
  198. cell = [self getCellModeWithTableView:tableView];
  199. break;
  200. }
  201. CASE(HEADER_TITLE_DURATION)
  202. {
  203. cell = [self getCellDurationWithTableView:tableView];
  204. break;
  205. }
  206. CASE(HEADER_TITLE_ACTION)
  207. {
  208. cell = [self getCellActionWithTableView:tableView indexPath:indexPath];
  209. break;
  210. }
  211. }
  212. return cell;
  213. }
  214. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  215. [super tableView:tableView didSelectRowAtIndexPath:indexPath];
  216. if (_isShowingMode) {
  217. return;
  218. }
  219. NSString *headerTitle = [self getHeaderTitle:indexPath.section];
  220. // if (EQUALS(headerTitle, HEADER_TITLE_ACTION)) {//actions
  221. //
  222. // ItemSubModel *subItem = self.pdevices[indexPath.row];
  223. // [RulesAddViewController modifyAction:subItem refDevices:_refDevices tableView:_tableView];
  224. // }
  225. }
  226. #pragma mark - makce row cell
  227. //모드 로우 셀 리턴
  228. -(UITableViewCell*)getCellModeWithTableView:(UITableView*)tableView {
  229. ItemSubModel *subCondition = self.modes[0];
  230. RulesConditionTableViewCell *tcell = (RulesConditionTableViewCell*)[tableView dequeueReusableCellWithIdentifier:@"ConditionCellIdentifier"];
  231. tcell.lblItem.text = subCondition.cmdclsValueMsg;
  232. [tcell.imgvIcon setImage:[UIImage imageNamed:@"img_rule_icon_homemode"]];
  233. tcell.btnDelete.hidden = _isShowingMode;
  234. if (!tcell.btnDelete.hidden) {
  235. tcell.btnDelete.value = subCondition;
  236. [tcell.btnDelete addTarget:self action:@selector(btnDeleteModeTouched:) forControlEvents:UIControlEventTouchUpInside];
  237. }
  238. tcell.bottomLine.hidden = YES;
  239. return tcell;
  240. }
  241. //기간 로우 셀 리턴
  242. -(UITableViewCell*)getCellDurationWithTableView:(UITableView*)tableView {
  243. ItemSubModel *subCondition = self.durations[0];
  244. RulesConditionTableViewCell *tcell = (RulesConditionTableViewCell*)[tableView dequeueReusableCellWithIdentifier:@"ConditionCellIdentifier"];\
  245. NSArray *dueDates = [subCondition.cmdclsValue componentsSeparatedByString:@"~"];
  246. tcell.lblItem.text = [NSString stringWithFormat:@"%@ ~ %@", dueDates.firstObject, dueDates.lastObject];
  247. [tcell.imgvIcon setImage:[UIImage imageNamed:@"img_rule_icon_calendar"]];
  248. tcell.btnDelete.hidden = _isShowingMode;
  249. if (!tcell.btnDelete.hidden) {
  250. tcell.btnDelete.value = subCondition;
  251. [tcell.btnDelete addTarget:self action:@selector(btnDeleteDurationTouched:) forControlEvents:UIControlEventTouchUpInside];
  252. }
  253. tcell.bottomLine.hidden = YES;
  254. return tcell;
  255. }
  256. //동작 로우 셀 리턴
  257. -(UITableViewCell*)getCellActionWithTableView:(UITableView*)tableView
  258. indexPath:(NSIndexPath*)indexPath {
  259. RulesConditionDeviceTableViewCell *tcell = (RulesConditionDeviceTableViewCell*)[tableView dequeueReusableCellWithIdentifier:@"DeviceCellIdentifier"];
  260. ItemSubModel *subItem = self.pdevices[indexPath.row];
  261. tcell.lblItem.text = subItem.sourceName;
  262. if ([subItem.deleteYn boolValue]) {//삭제된 노드가 있을 경우,
  263. [tcell.lblItem setStrikethrough:tcell.lblItem.text];
  264. }
  265. tcell.lblSubItem.text = subItem.sourceSubName;
  266. [tcell.imgvIcon sd_setImageWithURL:[NSURL URLWithString:subItem.imageFileName] placeholderImage:nil options:SDWebImageRefreshCached];
  267. //노드의 액션 값을 세팅함.
  268. if (subItem.cmdclsValueList && subItem.cmdclsValueList.count) {//커맨드클래스 밸루 리스트가 있을 경우,
  269. CmdClsValueModel *cmdclsValue = [subItem.cmdclsValueList matchedObjectName:ksCustomRadioButtonStatus condition:YES];
  270. tcell.lblCondition.text = cmdclsValue.cmdclsValueMsg;
  271. } else {
  272. if (subItem.cmdclsValueMsg) {
  273. tcell.lblCondition.text = subItem.cmdclsValueMsg;
  274. } else {
  275. NSString *condition = [subItem.conditionTypeCode isEqualToString:ksConditionTypeCodeGreatOrEqual] ? @"이상" : @"이하";
  276. tcell.lblCondition.text = [NSString stringWithFormat:@"%@%@ %@", subItem.cmdclsValue, subItem.unit, condition];
  277. }
  278. }
  279. // if (!_isShowingMode) {
  280. // [tcell.lblCondition setUnderLine:tcell.lblCondition.text];
  281. // }
  282. tcell.btnDelete.hidden = _isShowingMode;
  283. if (!tcell.btnDelete.hidden) {
  284. tcell.btnDelete.value = subItem;
  285. if (![tcell.btnDelete actionsForTarget:self forControlEvent:UIControlEventTouchUpInside]) {
  286. [tcell.btnDelete addTarget:self action:@selector(btnDeleteDeviceTouched:) forControlEvents:UIControlEventTouchUpInside];
  287. }
  288. } else {
  289. tcell.constraintConditionLabelRight.constant = 15.0f;
  290. }
  291. tcell.bottomLine.hidden = !(indexPath.row < self.pdevices.count);
  292. return tcell;
  293. }
  294. #pragma mark - add conditions
  295. //모드 추가
  296. - (void)btnAddModeTouched:(id)sender {
  297. ItemModel *mode = (ItemModel *)[_conditions objectKey:@"itemSubTypeCode" eqaulToString:ksConditionSubTypeCodeHomeMode];
  298. BOOL isNewTrigger = mode == nil;
  299. mode = isNewTrigger ? [[ItemModel alloc] init] : mode;
  300. if (!_mpopup) {
  301. _mpopup = [[RulesConditionHomeModePopupView alloc] initFromNib];
  302. }
  303. _mpopup.condition = mode;
  304. [_mpopup showWithCompletion:^(CustomAlertView *alertView, NSInteger buttonIndex) {
  305. if (buttonIndex == 0) {//OK
  306. if (isNewTrigger) {
  307. [_conditions addObject:mode];
  308. }
  309. [self updateTableView];
  310. }
  311. }];
  312. }
  313. //기간추가
  314. - (void)btnAddDurationTouched:(id)sender {
  315. ItemModel *dueDate = (ItemModel *)[_conditions objectKey:@"itemSubTypeCode" eqaulToString:ksConditionSubTypeCodeDueDate];
  316. BOOL isNewTrigger = dueDate == nil;
  317. dueDate = isNewTrigger ? [[ItemModel alloc] init] : dueDate;
  318. if (!_dpopup) {
  319. _dpopup = [[DurationPopupView alloc] initFromNib];
  320. }
  321. _dpopup.condition = dueDate;
  322. [_dpopup showWithCompletion:^(CustomAlertView *alertView, NSInteger buttonIndex) {
  323. if (buttonIndex == 0) {//OK
  324. if (isNewTrigger) {
  325. [_conditions addObject:dueDate];
  326. }
  327. [self updateTableView];
  328. }
  329. }];
  330. }
  331. //장치가 특정상태일때
  332. - (void)btnAddDeviceTouched:(id)sender {
  333. ItemModel *deviceCondition = (ItemModel *)[_conditions objectKey:@"itemSubTypeCode" eqaulToString:ksItemSubTypeCodeDevice];
  334. BOOL isNewTrigger = deviceCondition == nil;
  335. deviceCondition = isNewTrigger ? [[ItemModel alloc] init] : deviceCondition;
  336. DeviceSelectPopupView *dpopup = [[DeviceSelectPopupView alloc] initFromNib];
  337. dpopup.refDevices = _refDevices;
  338. dpopup.typeCode = ksItemTypeCodeTrigger;
  339. [dpopup showWithCompletion:^(CustomAlertView *alertView, NSInteger buttonIndex) {
  340. if (buttonIndex == 0) {//ok
  341. DeviceNodePopupView *npopup = [[DeviceNodePopupView alloc] initFromNib];
  342. npopup.refDevice = dpopup.selectedDevices[0];
  343. npopup.typeCode = ksItemTypeCodeTrigger;
  344. npopup.passAlreadyAdded = YES; //이미 추가 했어도 그 위에 덮어 씌움
  345. [npopup showWithCompletion:^(CustomAlertView *alertView, NSInteger buttonIndex) {
  346. //action add
  347. if (buttonIndex == 0) {//OK
  348. if (isNewTrigger) {
  349. deviceCondition.itemName = @"이 장치가 특정 상태일 때만";
  350. deviceCondition.itemSubTypeCode = ksItemSubTypeCodeDevice; //트리거 타입 설정
  351. deviceCondition.subItems = [(NSMutableArray<ItemSubModel> *)[NSMutableArray alloc] init];
  352. [_conditions addObject:deviceCondition];
  353. }
  354. ItemSubModel *snode = npopup.selectedNode;
  355. [deviceCondition.subItems removeAllObjects];
  356. [deviceCondition.subItems addObject: snode];
  357. // //존재 여부 확인
  358. // if (![deviceCondition.subItems objectByUsingPredicateFormat:@"sourceId == %@ && sourceSubId == %@", snode.sourceId, snode.sourceSubId]) {
  359. // [deviceCondition.subItems addObject: snode];
  360. // }
  361. [self updateTableView];
  362. }
  363. }];
  364. }
  365. }];
  366. }
  367. - (void)btnDeleteModeTouched:(id)sender {
  368. CustomButton *btnDelete = (CustomButton *)sender;
  369. ItemSubModel *mode = btnDelete.value;
  370. [self.modes removeObject:mode];
  371. [self updateTableView];
  372. }
  373. - (void)btnDeleteDurationTouched:(id)sender {
  374. CustomButton *btnDelete = (CustomButton *)sender;
  375. ItemSubModel *dueDate = btnDelete.value;
  376. [self.durations removeObject:dueDate];
  377. [self updateTableView];
  378. }
  379. - (void)btnDeleteDeviceTouched:(id)sender {
  380. CustomButton *btnDelete = (CustomButton *)sender;
  381. ItemSubModel *pdevice = btnDelete.value;
  382. //선택 설정을 초기화
  383. [[JDFacade facade] setRadioButtonStatus:@NO object:pdevice];
  384. for (CmdClsValueModel *cmdclsValue in pdevice.cmdclsValueList) {
  385. cmdclsValue.isSelected = NO;
  386. }
  387. [self.pdevices removeObject:pdevice];
  388. [self updateTableView];
  389. }
  390. - (void)updateTableView {
  391. CGFloat height = 0;
  392. height += self.modes.count > 0 ? HEADER_HEIGHT + 80 : 0;
  393. height += self.durations.count > 0 ? HEADER_HEIGHT + 80 : 0;
  394. height += self.pdevices.count > 0 ? HEADER_HEIGHT + (80 * self.pdevices.count) : 0;
  395. self.view.height = height;
  396. NSLog(@"height updateTableView %f", height);
  397. [_tableView reloadData];
  398. if ([self.parentViewController isKindOfClass:[RulesAddViewController class]]) {
  399. RulesAddViewController *rvc = (RulesAddViewController *)self.parentViewController;
  400. [rvc.tableView reloadData];
  401. }
  402. }
  403. #pragma mark - UI Events
  404. #pragma mark - MemoryWarning
  405. - (void)didReceiveMemoryWarning
  406. {
  407. [super didReceiveMemoryWarning];
  408. // Dispose of any resources that can be recreated.
  409. }
  410. @end