RulesAddViewController.m 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. //
  2. // RulesAddViewController.m
  3. // kneet2
  4. //
  5. // Created by Jason Lee on 11/20/15.
  6. // Copyright © 2015 ntels. All rights reserved.
  7. //
  8. #import "JDObject.h"
  9. #import "RequestHandler.h"
  10. #import "ItemModel.h"
  11. #import "CustomLabel.h"
  12. #import "CustomButton.h"
  13. #import "CustomImageView.h"
  14. #import "CustomTableView.h"
  15. #import "UIImageView+WebCache.h"
  16. #import "RulesAddViewController.h"
  17. #import "CustomCheckBox.h"
  18. #import "DeviceSelectPopupView.h"
  19. #import "DeviceNodePopupView.h"
  20. #import "TriggerSelectPopupView.h"
  21. #import "DeviceModel.h"
  22. #import "CustomTextView.h"
  23. @implementation RulesAddHeaderTableViewCell
  24. @end
  25. @implementation RulesAddTableViewCell
  26. @end
  27. @implementation RulesAddPushTableViewCell
  28. @end
  29. @implementation RulesAddConditionHeaderTableViewCell
  30. @end
  31. @implementation RulesAddConditionTableViewCell
  32. @end
  33. @implementation RulesAddFooterTableViewCell
  34. @end
  35. @interface RulesAddViewController () <CustomTextViewDelegate> {
  36. NSMutableArray<ItemModel> *_triggers, *_actions, *_conditions, *_pushes;
  37. NSMutableArray<ItemModel> *_triggerDevices, *_actionDevices;
  38. BOOL _isNotFirstLoading, _isCustomCreation;
  39. NSMutableArray *_arrayForHeader, *_arrayForFooter;
  40. CustomButton *_btnTriggerAdd, *_btnPushAdd;
  41. CustomCheckBox *_chkConditions;
  42. }
  43. @end
  44. #pragma mark - Class Definition
  45. @implementation RulesAddViewController
  46. - (void)viewDidLoad {
  47. [super viewDidLoad];
  48. _arrayForHeader = [[NSMutableArray alloc] init];
  49. _arrayForFooter = [[NSMutableArray alloc] init];
  50. [self initUI];
  51. [self prepareViewDidLoad];
  52. }
  53. - (void)initUI {
  54. [self initTableViewAsDefaultStyle:_tableView];
  55. }
  56. - (void)prepareViewDidLoad {
  57. [self requestDeviceListForHome];
  58. }
  59. #pragma mark - Main Logic
  60. - (void)requestDeviceListForHome {
  61. //parameters
  62. NSDictionary *parameter = @{@"item_type_code": ksItemTypeCodeAction};
  63. NSString *path = [NSString stringWithFormat:API_GET_ITEM_DEVICES, ksItemTypeCodeAction];
  64. [[RequestHandler handler] sendAsyncGetRequestAPIPath:path parameters:parameter modelClass:[ItemListModel class] completion:^(id responseObject) {
  65. if (!responseObject) {//응답결과가 잘못되었거나 없을 경우,
  66. return;
  67. }
  68. ItemListModel *fetchedItemList = (ItemListModel *)responseObject;
  69. if (fetchedItemList && fetchedItemList.list && fetchedItemList.list.count) {//API 성공 ,
  70. _triggerDevices = fetchedItemList.list;
  71. _actionDevices = [(NSMutableArray<ItemModel> *)[NSMutableArray alloc] initWithArray:_triggerDevices copyItems:YES];
  72. }
  73. } failure:^(id errorObject) {
  74. JDErrorModel *error = (JDErrorModel *)errorObject;
  75. [[JDFacade facade] alert:error.errorMessage];
  76. }];
  77. }
  78. #pragma mark - UITableView DataSource & Delegate
  79. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  80. return 4;
  81. }
  82. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  83. NSInteger count = 0;
  84. if (section == 0) {//triggers
  85. count = _triggers && _triggers.count ? _triggers.count : 0;
  86. } else if (section == 1) {//actions
  87. NSArray *matchedSubItems = [_actions matchedArrayInSubArrays:@"subItems" objectName:ksCustomRadioButtonStatus condition:YES];
  88. count = matchedSubItems && matchedSubItems.count ? matchedSubItems.count : 0;
  89. } else if (section == 2) {//push-message
  90. count = _pushes && _pushes.count ? _pushes.count : 0;
  91. } else if (section == 3) {//conditions
  92. count = _chkConditions.checked ? 1 : 0;
  93. }
  94. return count;
  95. }
  96. - (NSString *)headerTitleForSection:(NSInteger)section {
  97. NSString *title = nil;
  98. if (section == 0) {//trigger
  99. title = @"이 때가 되면";
  100. if (_triggers && _triggers.count) {
  101. ItemModel *item = _triggers[0];
  102. if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {
  103. title = @"장치 상태가 바뀔 때";
  104. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeTimer]) {
  105. title = @"이 시간마다";
  106. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeHeat]) {
  107. title = @"더울때 / 추울때";
  108. } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeSun]) {
  109. title = @"해뜰때 / 질때";
  110. }
  111. }
  112. } else if (section == 1) {//action
  113. title = @"이 장치를 실행";
  114. // title = _actions && _actions.count ? @"선택됨" : title;
  115. } else if (section == 2) {//pushes
  116. title = @"알림 메시지";
  117. // title = _pushes && _pushes.count ? @"선택됨" : title;
  118. }
  119. // else if (section == 3) {//conditions
  120. // title = @"추가 조건";
  121. // title = _triggers && triggers.count ? @"선택됨" : title;
  122. // }
  123. return title;
  124. }
  125. - (void)addTargetToHeaderAddButton:(CustomButton *)btnAdd section:(NSInteger)section {
  126. if (section == 0) {
  127. _btnTriggerAdd = btnAdd;
  128. [btnAdd addTarget:self action:@selector(btnAddTriggerTouched:) forControlEvents:UIControlEventTouchUpInside];
  129. } else if (section == 1) {
  130. [btnAdd addTarget:self action:@selector(btnAddActionTouched:) forControlEvents:UIControlEventTouchUpInside];
  131. } else if (section == 2) {
  132. _btnPushAdd = btnAdd;
  133. [btnAdd addTarget:self action:@selector(btnAddPushMessageTouched:) forControlEvents:UIControlEventTouchUpInside];
  134. }
  135. }
  136. - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
  137. UIView *view = _arrayForHeader.count > section ? _arrayForHeader[section] : nil;
  138. if (!view) {
  139. if (section == 0 || section == 1 || section == 2) {//TODO : hide add button or not;
  140. RulesAddHeaderTableViewCell *hcell = (RulesAddHeaderTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"HeaderCellIdentifier"];
  141. view = [[UIView alloc] initWithFrame:hcell.contentView.frame];
  142. [view addSubview:hcell];
  143. hcell.lblTitle.text = [self headerTitleForSection:section];
  144. if (![hcell.btnAdd actionsForTarget:self forControlEvent:UIControlEventTouchUpInside]) {
  145. [self addTargetToHeaderAddButton:hcell.btnAdd section:section];
  146. }
  147. } else if (section == 3) {
  148. RulesAddConditionHeaderTableViewCell *hcell = (RulesAddConditionHeaderTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"ConditionHeaderCellIdentifier"];
  149. view = [[UIView alloc] initWithFrame:hcell.contentView.frame];
  150. [view addSubview:hcell];
  151. }
  152. if (_arrayForHeader.count == section) {
  153. [_arrayForHeader insertObject:view atIndex:section];
  154. }
  155. } else {
  156. if (section == 0 || section == 1 || section == 2) {
  157. RulesAddHeaderTableViewCell *hcell = (RulesAddHeaderTableViewCell *)view.subviews[0];
  158. hcell.lblTitle.text = hcell.lblTitle.text = [self headerTitleForSection:section];
  159. } else if (section == 3) {
  160. RulesAddConditionHeaderTableViewCell *hcell = (RulesAddConditionHeaderTableViewCell *)view.subviews[0];
  161. }
  162. }
  163. return view;
  164. }
  165. - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
  166. return 90.0f;
  167. }
  168. - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
  169. UIView *view = _arrayForFooter.count > section ? _arrayForFooter[section] : nil;
  170. if (!view) {
  171. RulesAddFooterTableViewCell *hcell = (RulesAddFooterTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"FooterCellIdentifier"];
  172. view = [[UIView alloc] initWithFrame:hcell.contentView.frame];
  173. [view addSubview:hcell];
  174. if (_arrayForHeader.count == section) {
  175. [_arrayForHeader insertObject:view atIndex:section];
  176. }
  177. }
  178. return view;
  179. }
  180. - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
  181. return 15.0f;
  182. }
  183. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  184. CGFloat height = 0.0f;
  185. NSInteger section = indexPath.section;
  186. if (section == 0) {//triggers
  187. height = 95;
  188. } else if (section == 1) {//actions
  189. height = 95;
  190. } else if (section == 2) {//push-message
  191. height = 115;
  192. } else if (section == 3) {//conditions
  193. height = 255;
  194. }
  195. return height;
  196. }
  197. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  198. NSInteger section = indexPath.section;
  199. UITableViewCell *cell = nil;
  200. if (section == 0) {//triggers
  201. ItemModel *item = _triggers[indexPath.row];
  202. ItemSubModel *subItem = [item.subItems matchedObjectName:ksCustomRadioButtonStatus condition:YES];
  203. RulesAddTableViewCell *tcell = (RulesAddTableViewCell *)[_tableView dequeueReusableCellWithIdentifier:@"RulesCellIdentifier"];
  204. tcell.lblItem.text = item.sourceName;
  205. tcell.lblSubItem.text = subItem.sourceSubName;
  206. //노드의 액션 값을 세팅함.
  207. if (subItem.cmdclsValueList && subItem.cmdclsValueList.count) {//커맨드클래스 밸루 리스트가 있을 경우,
  208. CmdClsValueModel *cmdclsValue = [subItem.cmdclsValueList matchedObjectName:ksCustomRadioButtonStatus condition:YES];
  209. tcell.lblCondition.text = [DeviceModel contentValueMsgByCmdClsCode:subItem.cmdclsCode cmdclsTypeId:(NSString *)subItem.cmdclsTypeId contentValue:cmdclsValue.cmdclsValue];
  210. } else {
  211. tcell.lblCondition.text = subItem.cmdclsValueMsg;
  212. }
  213. [tcell.imgvIcon sd_setImageWithURL:[NSURL URLWithString:subItem.imageFileName] placeholderImage:nil options:SDWebImageRefreshCached];
  214. if (![tcell.btnDelete actionsForTarget:self forControlEvent:UIControlEventTouchUpInside]) {
  215. [tcell.btnDelete addTarget:self action:@selector(btnDeleteTriggerTouched:) forControlEvents:UIControlEventTouchUpInside];
  216. }
  217. cell = tcell;
  218. } else if (section == 1) {//actions
  219. ItemModel *item = _actions[indexPath.row];
  220. //노드 액션이 선택된 노드만 출력함.
  221. NSInteger fcount = indexPath.row; //선택된 액션만 찾기 위한 인덱스
  222. NSArray *matchedSubItems = [_actions matchedArrayInSubArrays:@"subItems" objectName:ksCustomRadioButtonStatus condition:YES];
  223. ItemSubModel *subItem = nil;
  224. for (subItem in matchedSubItems) {
  225. if (fcount == 0) {
  226. break;
  227. } else {
  228. fcount--;
  229. }
  230. }
  231. RulesAddTableViewCell *tcell = (RulesAddTableViewCell *)[_tableView dequeueReusableCellWithIdentifier:@"RulesCellIdentifier"];
  232. tcell.lblItem.text = item.sourceName;
  233. [tcell.imgvIcon sd_setImageWithURL:[NSURL URLWithString:item.imageFileName] placeholderImage:nil options:SDWebImageRefreshCached];
  234. //노드의 액션 값을 세팅함.
  235. if (subItem.cmdclsValueList && subItem.cmdclsValueList.count) {//커맨드클래스 밸루 리스트가 있을 경우,
  236. CmdClsValueModel *cmdclsValue = [subItem.cmdclsValueList matchedObjectName:ksCustomRadioButtonStatus condition:YES];
  237. tcell.lblCondition.text = cmdclsValue.cmdclsValueMsg;
  238. } else {
  239. tcell.lblCondition.text = subItem.cmdclsValueMsg;
  240. }
  241. tcell.btnDelete.value = subItem;
  242. if (![tcell.btnDelete actionsForTarget:self forControlEvent:UIControlEventTouchUpInside]) {
  243. [tcell.btnDelete addTarget:self action:@selector(btnDeleteActionTouched:) forControlEvents:UIControlEventTouchUpInside];
  244. }
  245. cell = tcell;
  246. } else if (section == 2) {//push-message
  247. RulesAddPushTableViewCell *tcell = (RulesAddPushTableViewCell *)[_tableView dequeueReusableCellWithIdentifier:@"PushCellIdentifier"];
  248. tcell.txvMessage.delegate = self;
  249. cell = tcell;
  250. } else if (section == 3) {//conditions
  251. RulesAddTableViewCell *tcell = (RulesAddTableViewCell *)[_tableView dequeueReusableCellWithIdentifier:@"ConditionCellIdentifier"];
  252. cell = tcell;
  253. }
  254. return cell;
  255. }
  256. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  257. [tableView deselectRowAtIndexPath:indexPath animated:YES];
  258. }
  259. #pragma mark - TableView UI Events
  260. - (void)btnAddTriggerTouched:(id)sender {
  261. if (!_triggers) {
  262. _triggers = (NSMutableArray<ItemModel> *)[[NSMutableArray alloc] init];
  263. }
  264. TriggerSelectPopupView *tpopup = [[TriggerSelectPopupView alloc] initFromNib];
  265. tpopup.refTriggers = _triggers;
  266. tpopup.refDevices = _triggerDevices;
  267. [tpopup showWithCompletion:^(CustomAlertView *alertView, NSInteger buttonIndex) {
  268. if (buttonIndex == 0) {
  269. [_tableView reloadData];
  270. }
  271. }];
  272. }
  273. - (void)btnAddActionTouched:(id)sender {
  274. DeviceSelectPopupView *dpopup = [[DeviceSelectPopupView alloc] initFromNib];
  275. dpopup.refDevices = _actionDevices;
  276. dpopup.typeCode = ksItemTypeCodeTrigger;
  277. [dpopup showWithCompletion:^(CustomAlertView *alertView, NSInteger buttonIndex) {
  278. if (buttonIndex == 0) {//ok
  279. DeviceNodePopupView *npopup = [[DeviceNodePopupView alloc] initFromNib];
  280. npopup.refDevice = dpopup.selectedDevices[0];
  281. npopup.typeCode = ksItemTypeCodeTrigger;
  282. [npopup showWithCompletion:^(CustomAlertView *alertView, NSInteger buttonIndex) {
  283. //action add
  284. if (buttonIndex == 0) {//OK
  285. if (!_actions) {
  286. _actions = (NSMutableArray<ItemModel> *)[[NSMutableArray alloc] init];
  287. }
  288. [_actions addObject:npopup.refDevice];
  289. [_tableView reloadData];
  290. }
  291. }];
  292. }
  293. }];
  294. }
  295. - (void)btnAddPushMessageTouched:(id)sender {
  296. if (!_pushes) {
  297. _pushes = [(NSMutableArray<ItemModel> *)[NSMutableArray alloc] init];
  298. }
  299. if (!_pushes.count) {
  300. ItemModel *push = [[ItemModel alloc] init];
  301. push.itemSubTypeCode = ksItemSubTypeCodeAppPush;
  302. [_pushes addObject:push];
  303. }
  304. [_tableView reloadData];
  305. }
  306. - (void)btnDeleteTriggerTouched:(id)sender {
  307. if (_triggers && _triggers.count) {
  308. [_triggers removeAllObjects];
  309. }
  310. [_tableView reloadData];
  311. }
  312. - (void)btnDeleteActionTouched:(id)sender {
  313. CustomButton *btnDelete = (CustomButton *)sender;
  314. ItemSubModel *subItem = (ItemSubModel *)btnDelete.value;
  315. //선택 설정을 초기화
  316. [[JDFacade facade] setRadioButtonStatus:@NO object:subItem];
  317. for (CmdClsValueModel *cmdclsValue in subItem.cmdclsValueList) {
  318. cmdclsValue.isSelected = NO;
  319. }
  320. //액션과 일치하는 서브아이템을 삭제해줌.
  321. [_actions enumerateObjectsUsingBlock:^(ItemModel *action, NSUInteger idx, BOOL * _Nonnull stop) {
  322. NSArray *matchedArray = [action.subItems matchedArrayByObjectName:ksCustomRadioButtonStatus condition:YES];
  323. if (!matchedArray.count) {
  324. [_actions removeObject:action];
  325. }
  326. }];
  327. [_tableView reloadData];
  328. }
  329. #pragma mark - CustomTextView Delegate
  330. - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
  331. _btnPushAdd.hidden = textView.text.length > 0;
  332. NSLog(@"%s\n %zd", __PRETTY_FUNCTION__, textView.text.length);
  333. return textView.text.length < 120;
  334. }
  335. #pragma mark - UI Events
  336. - (IBAction)btnConfirmTouched:(id)sender {
  337. //validate
  338. }
  339. - (IBAction)btnCancelTouched:(id)sender {
  340. [[JDFacade facade] dismissModalStack:YES completion:nil];
  341. }
  342. #pragma mark - MemoryWarning
  343. - (void)didReceiveMemoryWarning
  344. {
  345. [super didReceiveMemoryWarning];
  346. // Dispose of any resources that can be recreated.
  347. }
  348. @end