// // ScenesRegisterViewController.m // kneet // // Created by Jason Lee on 4/1/15. // Copyright (c) 2015 ntels. All rights reserved. // @import ObjectiveC.runtime; #import "JDObject.h" #import "RequestHandler.h" #import "SceneModel.h" #import "CustomTextField.h" #import "CustomLabel.h" #import "CustomImageView.h" #import "CustomButton.h" #import "CustomAlertView.h" #import "UIImageView+WebCache.h" #import "CustomRadioGroup.h" #import "CustomTextView.h" #import "ValidateUtil.h" #import "PredefinedDeviceViewController.h" #import "RegisterModeViewController.h" #import "RulesRegisterViewController.h" #import "ScenesRegisterViewController.h" #import "ActionPopTableView.h" #import "ScenesViewController.h" @interface ScenesRegisterViewController () { NSString *_sceneName, *_predSceneId; NSMutableArray *_actions; BOOL _isNotFirstLoading, _isCustomCreation; UIImage *_iconAction; NSMutableArray *_arrayForHeader; ActionPopTableView *_actionPopTableView; } @end #pragma mark - Class Definition @implementation ScenesRegisterViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. [self initUI]; [self prepareViewDidLoad]; } - (void)initUI { self.title = NSLocalizedString(@"멀티 제어 만들기",nil); _tableView.dataSource = self; _tableView.delegate = self; _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; _tableView.backgroundColor = [UIColor clearColor]; _tableView.tableFooterView = [[UIView alloc] init]; //this call table events; _isNotFirstLoading = YES; _iconAction = [UIImage imageNamed:@"tp_01_img_rule_rbox_icon_action"]; //Localization [_btnComplete setTitle:NSLocalizedString(@"완성", @"완성") forState:UIControlStateNormal]; [_btnCancel setTitle:NSLocalizedString(@"취소", @"취소") forState:UIControlStateNormal]; } - (void)prepareViewDidLoad { _isCustomCreation = YES; if (!_tmpPredScene && !_tmpSceneDetail) {//자유롭게 만들기 _predSceneId = @"0"; } else { //사전 정의 씬 상세 정보 조회 if (!_tmpSceneDetail) {//사전 정의 씬을 불러온 경우, _predSceneId = _tmpPredScene.predSceneId; [self requestPredefinedSceneDetail]; } else {//씬을 수정하는 경우, _sceneName = _tmpSceneDetail.sceneName; _predSceneId = _tmpSceneDetail.predSceneId; //FIXME : [self setSceneDetail]; } } } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; if (_isNotFirstLoading) { [_tableView reloadData]; } } #pragma mark - Main Logic //자유 선택 - 커스텀 씬 생성 시 사용 - (void)addItem:(ItemModel *)item { if (!_isCustomCreation) return; if (!_actions) { _actions = (NSMutableArray *)[[NSMutableArray alloc] init]; } if ([_actions indexOfObject:item] == NSNotFound) { [_actions addObject:item]; } else { NSInteger index = [_actions indexOfObjectPassingTest:^BOOL(ItemModel *obj, NSUInteger idx, BOOL *stop) { return [item.predActionSequence isEqualToString:obj.predActionSequence]; }]; if (index != NSNotFound) {//동일 액션이 있을경우, [_actions replaceObjectAtIndex:index withObject:item]; } } [_tableView reloadData]; } - (void)requestPredefinedSceneDetail { NSString *path = [NSString stringWithFormat:API_GET_PRESCENE_DETAIL, _predSceneId]; [[RequestHandler handler] sendAsyncGetRequestAPIPath:path parameters:nil modelClass:[PredefinedSceneDetailModel class] completion:^(id responseObject) { if (!responseObject) {//응답결과가 잘못되었거나 없을 경우, return; } PredefinedSceneDetailModel *predefinedSceneDetail = (PredefinedSceneDetailModel *) responseObject; if (predefinedSceneDetail) {//API 성공 , if (!_tmpSceneDetail) {//생성모드일 경우, [self setPredefinedSceneDetail:predefinedSceneDetail]; } // else {//수정모드일 경우, // [self matchSceneDetailWithPredefinedSceneDeatil:predefinedSceneDetail]; // } } } failure:^(id errorObject) { JDErrorModel *error = (JDErrorModel *)errorObject; [[JDFacade facade] alert:error.errorMessage]; }]; } //각 아이템별 카운트를 설정함 - (void)setPredefinedSceneDetail:(PredefinedSceneDetailModel *)predefinedSceneDetail {//각 아이템별 카운트를 설정함 _actions = (NSMutableArray *)[NSMutableArray arrayWithArray:predefinedSceneDetail.actions]; [_tableView reloadData]; } - (void)setSceneDetail {//각 아이템별 카운트를 설정함 _actions = [(NSMutableArray *)[NSMutableArray alloc] initWithArray:_tmpSceneDetail.actions copyItems:YES]; for (ItemModel *item in _actions) { NSIndexSet *isDeleted = [item.subItems indexesOfObjectsPassingTest:^BOOL(ItemSubModel *subItem, NSUInteger idx, BOOL *stop) { return [subItem.deleteYn boolValue]; }]; [item.subItems removeObjectsAtIndexes:isDeleted]; if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우, [item.predDevices removeObjectsAtIndexes:isDeleted]; } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우, [item.modes removeObjectsAtIndexes:isDeleted]; } } // [RulesRegisterViewController setSubItemsFromItem:_actions]; } - (void)matchSceneDetailWithPredefinedSceneDeatil:(PredefinedSceneDetailModel *)predSceneDetail { [RulesRegisterViewController appendItem:_actions withPredefinedRuleItems:predSceneDetail.actions isRuleMode:NO]; [_tableView reloadData]; } //서브아이템 배열을 리턴함. - (NSArray *)subItemsForType:(NSArray *)subActions itemSubType:(NSString *)actionSubTypeCode { NSMutableArray *rSubItems = [[NSMutableArray alloc] init]; if ([actionSubTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우, for (PredefinedDeviceModel *pdevice in subActions) { NSDictionary *rSubItem = @{@"source_id": pdevice.deviceId, @"source_sub_id": pdevice.nodeId, @"cmdcls_value": pdevice.cmdclsValue}; [rSubItems addObject:rSubItem]; } } else if ([actionSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우, for (ModeModel *mode in subActions) { NSDictionary *rSubItem = @{@"source_id": @"VAR", @"cmdcls_value": mode.modeId}; [rSubItems addObject:rSubItem]; } } return rSubItems; } //아이템 배열을 리턴함. - (NSArray *)actions:(NSArray *)items { //triggers, actions, conditions NSMutableArray *rItems = [[NSMutableArray alloc] init]; for (ItemModel *item in items) { NSDictionary *dic = nil; NSMutableArray *subItems = [[NSMutableArray alloc] init]; NSArray *pdevices = [self subItemsForType:item.predDevices itemSubType:ksItemSubTypeCodeDevice]; NSArray *modes = [self subItemsForType:item.modes itemSubType:ksItemSubTypeCodeMode]; if (pdevices && pdevices.count) { [subItems addObjectsFromArray:pdevices]; } if (modes && modes.count) { [subItems addObjectsFromArray:modes]; } if (subItems.count) { dic = @{@"pred_action_sequence": item.predActionSequence, @"item_name": item.itemName, @"item_sub_type_code": item.itemSubTypeCode, @"item_sub": subItems}; [rItems addObject:dic]; } } return rItems; } - (void)requestRegisterScene { NSArray *actions = [self actions:_actions]; //validate // if (!triggers || !triggers.count || !triggers[@"item_sub"] || ![((NSArray *)triggers[@"item_sub"]) count]) { if (!actions || !actions.count) { [[JDFacade facade] alert:NSLocalizedString(@"액션이 없습니다", @"액션이 없습니다")]; return; } //parameters NSDictionary *parameter = @{@"pred_scene_id" : _predSceneId, @"scene_name" : _sceneName, @"actions": actions ? actions : [NSNull null]}; NSString *path = [NSString stringWithFormat:API_POST_SCENE]; [[RequestHandler handler] sendAsyncPostRequestAPIPath:path parameters:parameter modelClass:[JDJSONModel class] completion:^(id responseObject) { if (!responseObject) {//응답결과가 잘못되었거나 없을 경우, return; } JDJSONModel *result = (JDJSONModel *) responseObject; if (result) {//API 성공 , [[JDFacade facade] toast:NSLocalizedString(@"등록되었습니다", @"등록되었습니다")]; [[JDFacade facade] gotoWishMenu:KNMenuIdScenes]; } } failure:^(id errorObject) { JDErrorModel *error = (JDErrorModel *)errorObject; [[JDFacade facade] alert:error.errorMessage]; }]; } - (void)requestModifyScene { NSArray *actions = [self actions:_actions]; //validate // if (!triggers || !triggers.count || !triggers[@"item_sub"] || ![((NSArray *)triggers[@"item_sub"]) count]) { if (!actions || !actions.count) { [[JDFacade facade] alert:NSLocalizedString(@"액션이 없습니다", @"액션이 없습니다")]; return; } //parameters NSDictionary *parameter = @{@"pred_scene_id" : _predSceneId, @"scene_name" : _sceneName, @"actions": actions ? actions : [NSNull null]}; NSString *path = [NSString stringWithFormat:API_POST_SCENE_MODIFY, _tmpSceneDetail.homegrpSceneId]; [[RequestHandler handler] sendAsyncPostRequestAPIPath:path parameters:parameter modelClass:[JDJSONModel class] completion:^(id responseObject) { _tmpSceneDetail.sceneName = _sceneName; _tmpSceneDetail.deleteCnt = @"0"; _tmpSceneDetail.actions = _actions; ScenesViewController *vc = [[JDFacade facade] viewControllerOnNaviationController:[ScenesViewController class]]; [vc updateScene:_tmpSceneDetail]; [[JDFacade facade] toast:NSLocalizedString(@"수정되었습니다", @"수정되었습니다")]; [self.navigationController popViewControllerAnimated:YES]; } failure:^(id errorObject) { JDErrorModel *error = (JDErrorModel *)errorObject; [[JDFacade facade] alert:error.errorMessage]; }]; } #pragma mark - UITableView DataSource & Delegate - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 2; } - (NSString *)titleForSectionHeader:(NSInteger)section { NSString *title = nil; switch (section) { case 0: title = NSLocalizedString(@"무엇을 실행할까요?", @"무엇을 실행할까요?"); break; case 1: title = NSLocalizedString(@"이름을 붙여주세요", @"이름을 붙여주세요"); break; } return title; } - (UIImage *)imageForSection:(NSInteger)section { UIImage *image = nil; switch (section) { case 0: image = _iconAction; break; case 1: break; } return image; } - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { UIView *view = _arrayForHeader.count > section ? _arrayForHeader[section] : nil; if (!view) { RulesCreateHeaderTableViewCell *hcell = (RulesCreateHeaderTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"HeaderCellIdentifier"]; CGFloat height = [self tableView:tableView heightForHeaderInSection:section]; hcell.frame = CGRectMake(0, 0, IPHONE_WIDTH, height); if (section == 0) { hcell.imgvTop.hidden = YES; hcell.constraintHeaderTitleTop.constant = 10; } view = [[UIView alloc] initWithFrame:hcell.frame]; [view addSubview:hcell]; hcell.lblHeaderTitle.text = [self titleForSectionHeader:section]; [_arrayForHeader insertObject:view atIndex:section]; } return view; } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { if (section == 0) { return 65.0f; } return 72.0f; } - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { return 0.01f; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { NSInteger count = 0; if (section == 1) {//title cell count = 1; } else if (section == 0) {//actions count = _actions.count + _isCustomCreation; } return count; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { CGFloat height = 0; if (indexPath.section == 0) { //calcualate subItemsText NSArray *items = _actions; if (indexPath.row == _actions.count) {//자유롭게 만들기 셀 (액션 추가) height = 60.0f; } else {//추가된 액션 표현. ItemModel *item = items[indexPath.row]; CGFloat adjustHeight = [RulesRegisterViewController heightForSubItems:item isTrigger:NO]; adjustHeight = adjustHeight > 0 ? adjustHeight + 15 + 20 : adjustHeight; //label top, bottom margin height = 60 + adjustHeight; } } else if (indexPath.section == 1) {//씬 이름입력 height = 89; } return height; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = nil; // NSLog(@"%s\n %zd", __PRETTY_FUNCTION__, indexPath.row); if (indexPath.section == 1) {//타이틀 셀 RulesCreateTitleTableViewCell *tcell = [tableView dequeueReusableCellWithIdentifier:@"TitleCellIdentifier"]; if (tcell == nil) { tcell = [[RulesCreateTitleTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"TitleCellIdentifier"]; } tcell.txtRuleTitle.text = [tcell.txtRuleTitle.text isEmptyString] ? _sceneName : tcell.txtRuleTitle.text; tcell.lblRuleTitle.text = [tcell.txtRuleTitle.text isEmptyString] ? @"입력" : tcell.txtRuleTitle.text; cell = tcell; } else {//액션즈 셀 RulesCreateTableViewCell *tcell = [tableView dequeueReusableCellWithIdentifier:@"CellIdentifier"]; if (tcell == nil) { tcell = [[RulesCreateTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CellIdentifier"]; } UIImage *bgImage = [UIImage imageNamed:@"tp_01_img_rule_rbox_bg"]; tcell.constraintImgvBgHeight.constant = 55.0f; [tcell.imgvBg setImage:bgImage]; if (indexPath.row == _actions.count) {//자유롭게 만들기 셀 (액션 추가) tcell.lblItemName.text = NSLocalizedString(@"자유 선택", @"자유 선택"); tcell.lblSubItems.hidden = YES; tcell.lineview.hidden = tcell.btnDeleteSubItems.hidden = tcell.lblSubItems.hidden; } else {//추가된 액션 NSArray *items = _actions; ItemModel *item = items[indexPath.row]; [RulesRegisterViewController fillCell:tcell item:item isTrigger:NO]; tcell.btnDeleteSubItems.value = item; if (![tcell.btnDeleteSubItems actionsForTarget:self forControlEvent:UIControlEventTouchUpInside]) { [tcell.btnDeleteSubItems addTarget:self action:@selector(btnDeleteSubItemsTouched:) forControlEvents:UIControlEventTouchUpInside]; } } tcell.imgvItem.image = [self imageForSection:indexPath.section]; cell = tcell; } return cell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section == 1) {//title cell //텍스트필드를 원상태로 되돌림 RulesCreateTitleTableViewCell *cell = (RulesCreateTitleTableViewCell *)[_tableView cellForRowAtIndexPath:indexPath]; [cell setSelected:YES animated:YES]; return; } else { NSIndexPath *ip = [NSIndexPath indexPathForItem:0 inSection:1]; //텍스트필드를 원상태로 되돌림 RulesCreateTitleTableViewCell *cell = (RulesCreateTitleTableViewCell *)[_tableView cellForRowAtIndexPath:ip]; if (!cell.txtRuleTitle.hidden && [cell.txtRuleTitle isFirstResponder]) { [cell.txtRuleTitle resignFirstResponder]; } } [tableView deselectRowAtIndexPath:indexPath animated:YES]; if (indexPath.row == _actions.count) {//자유롭게 만들기 셀 (액션 추가) //FIXME : 매번 로드를 해야되는가? if (!_actionPopTableView) { _actionPopTableView = [[ActionPopTableView alloc] initFromNib]; } _actionPopTableView.actions = _actions; [_actionPopTableView.tableView scrollsToTop]; [_actionPopTableView show]; } else {//사전 정의 액션, 수정 모드, 추가된 액션 NSArray *items = _actions; ItemModel *item = items[indexPath.row]; UIViewController *vc = nil; if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeDevice]) {//디바이스일 경우, PredefinedDeviceViewController *dvc = (PredefinedDeviceViewController *)[CommonUtil instantiateViewControllerWithIdentifier:@"PredefinedDeviceViewController" storyboardName:@"Rules"]; dvc.title = [self titleForSectionHeader:indexPath.section]; dvc.predSceneId = _predSceneId; dvc.tmpItem = item; vc = dvc; } else if ([item.itemSubTypeCode isEqualToString:ksItemSubTypeCodeMode]) {//모드일 경우, RegisterModeViewController *mvc = (RegisterModeViewController *)[CommonUtil instantiateViewControllerWithIdentifier:@"RegisterModeViewController" storyboardName:@"Rules"]; mvc.title = [self titleForSectionHeader:indexPath.section]; mvc.tmpItem = item; vc = mvc; } [self.navigationController pushViewController:vc animated:YES]; } } - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { // Remove seperator inset if ([cell respondsToSelector:@selector(setSeparatorInset:)]) { [cell setSeparatorInset:UIEdgeInsetsZero]; } // Prevent the cell from inheriting the Table View's margin settings if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) { [cell setPreservesSuperviewLayoutMargins:NO]; } // Explictly set your cell's layout margins if ([cell respondsToSelector:@selector(setLayoutMargins:)]) { [cell setLayoutMargins:UIEdgeInsetsZero]; } } #pragma mark - UI Events - (void)resetAllCheckbox { // [_tableView enumarateTableViewCellsUsingBlock:^(UITableViewCell *cell) { // ProductTableViewCell *pcell = (ProductTableViewCell *)cell; // pcell.chkSelect.checked = NO; // }]; } - (void)btnCancelSceneTouched:(id)sender { [self.navigationController popViewControllerAnimated:YES]; } - (void)btnDeleteSubItemsTouched:(id)sender { CustomButton *btnDeleteSubItems = (CustomButton *)sender; ItemModel *action = btnDeleteSubItems.value; action.predDevices = nil; action.cnt = @"0"; [_actions removeObject:btnDeleteSubItems.value]; [_tableView reloadData]; } - (void)btnCompleteSceneTouched:(id)sender { [self.view endEditing:YES]; //1.Validate Title RulesCreateTitleTableViewCell *tcell = (RulesCreateTitleTableViewCell *)[_tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1]]; //마지막 섹션 if (tcell && ![ValidateUtil validateTextfiled:tcell.txtRuleTitle type:ValidateTypeNull title:NSLocalizedString(@"이름", @"이름")]) { return; } if (!_tmpSceneDetail && !tcell) { [[JDFacade facade] alert:NSLocalizedString(@"이름을 입력하세요", @"이름을 입력하세요")]; return; } _sceneName = !tcell ? _sceneName : tcell.txtRuleTitle.text; if (!_tmpSceneDetail) {//생성 [self requestRegisterScene]; } else {//수정 [self requestModifyScene]; } } #pragma mark - MemoryWarning - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end