// // ThingsDetailViewController.m // kneet // // Created by Jason Lee on 3/16/15. // Copyright (c) 2015 ntels. All rights reserved. // #import "RequestHandler.h" #import "DeviceModel.h" #import "CustomImageView.h" #import "CustomLabel.h" #import "CustomTextField.h" #import "CustomButton.h" #import "UIImageView+WebCache.h" #import "CustomTableView.h" #import "ValidateUtil.h" #import "CommandClassControlDetailView.h" #import "ThingsViewController.h" #import "ThingsDetailViewController.h" #import "ModifyDeviceNamePopupView.h" #import "JYPullToRefreshController.h" @implementation ThingsDetailTitleTableViewCell @end @implementation ThingsDetailControlTableViewCell - (void)awakeFromNib { _controlContainer.pagingEnabled = YES; _controlContainer.scrollEnabled = NO; _pageControl.hidden = YES; } @end @implementation ThingsDetailOptionTableViewCell @end @interface ThingsDetailViewController () { DeviceDetailModel *_deviceDetail; ModifyDeviceNamePopupView *_mpopup; NSArray *_mandatoryNodes, *_optionalNodes; UIPageControl *_pageControl; NSTimer *_deviceBackgroundTimer; } @property (strong, nonatomic) JYPullToRefreshController *refreshController; @end #pragma mark - Class Definition @implementation ThingsDetailViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. [self initUI]; [self prepareViewDidLoad]; } - (void)initUI { //initialize tableView [self initTableViewAsDefaultStyle:_tableView]; _tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, IPHONE_WIDTH, 35.0f)]; [self setThingsDetailPopoverOptions]; [self initRefreshController]; } - (void)initRefreshController { //set refresh controls __weak typeof(self) weakSelf = self; self.refreshController = [[JYPullToRefreshController alloc] initWithScrollView:self.tableView]; self.refreshController.pullToRefreshHandleAction = ^{ [weakSelf requestDeviceDetail:@YES]; }; } - (void)setThingsDetailPopoverOptions { //set Popover Contents __weak typeof(self) weakSelf = self; _popooverOptionArray = [[NSMutableArray alloc] init]; [_popooverOptionArray addObject:@{@"menuName" : NSLocalizedString(@"새로 고침",nil), @"iconName": @"img_bg_morepopup_icon_refresh", @"target": weakSelf, @"selector": [NSValue valueWithPointer:@selector(requestDeviceDetail:)]}]; if ([JDFacade facade].loginUser.level > 10) { [_popooverOptionArray addObject:@{@"menuName" : NSLocalizedString(@"이름 변경", @"이름 변경"), @"iconName": @"img_bg_morepopup_icon_edit", @"target": weakSelf, @"selector": [NSValue valueWithPointer:@selector(modifyDeviceName)]}]; } } - (void)prepareViewDidLoad { [self requestDeviceDetail:@YES]; } - (void)modifyDeviceName { _mpopup = [[ModifyDeviceNamePopupView alloc] initFromNib]; _mpopup.txtDeviceName.text = _deviceDetail.deviceName; [_mpopup showWithCompletion:^(CustomAlertView *alertView, NSInteger buttonIndex) { if (buttonIndex == 0) {//OK [self requestDeviceUpdate]; } }]; } - (void)updateTitle { if (![JDFacade facade].loginUser.isHomehubOnline) { _lblTitle.text = @"홈허브 오프라인"; [_lblTitle setColor:kUITextColor01 text:_lblTitle.text]; return; } if (_deviceDetail && !_deviceDetail.isOnline) { _lblTitle.text = @"장치 상태를 확인하세요"; [_lblTitle setColor:kUITextColor02 text:_lblTitle.text]; return; } } #pragma mark - Main Logic - (void)requestDeviceDetail:(id)arg { BOOL showLoadingView = NO; if (arg) { showLoadingView = [arg isKindOfClass:[NSTimer class]] ? [((NSTimer *)arg).userInfo boolValue] : [arg boolValue]; } NSString *path = [NSString stringWithFormat:API_GET_DEVICE_DETAIL, _refDevice.deviceId]; [[RequestHandler handler] sendAsyncRequestAPIPath:path method:ksHTTPRequestGET parameters:nil modelClass:[DeviceDetailModel class] showLoadingView:showLoadingView completion:^(id responseObject) { if (!responseObject) {//응답결과가 잘못되었거나 없을 경우, return; } _deviceDetail = (DeviceDetailModel *)responseObject; if (_deviceDetail) {//API 성공 , [self setDeviceContents]; [self requestPollingDeviceStatusInBackground]; } //refresh controller if (self.refreshController && self.refreshController.refreshState == JYRefreshStateLoading) { [self.refreshController stopRefreshWithAnimated:YES completion:nil]; } } failure:^(id errorObject) { [self releaseDeviceTimer]; JDErrorModel *error = (JDErrorModel *)errorObject; [[JDFacade facade] alert:error.errorMessage]; }]; } //디바이스 상태를 3초마다 갱신함. - (void)requestPollingDeviceStatusInBackground { //schedul timer. if (!_deviceBackgroundTimer) { _deviceBackgroundTimer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(requestDeviceDetail:) userInfo:@NO repeats:YES]; } } - (void)setDeviceContents { [self updateTitle]; _mandatoryNodes = (NSArray *)[_deviceDetail.nodes filteredArrayUsingPredicateFormat:@"cmdclsMandatoryYn == %@", @"Y"]; _optionalNodes = (NSArray *)[_deviceDetail.nodes filteredArrayUsingPredicateFormat:@"cmdclsMandatoryYn == %@", @"N"]; [_tableView reloadData]; } - (void)requestDeviceUpdate { //parameters NSDictionary *parameter = @{@"device_name": _mpopup.txtDeviceName.text}; NSString *path = [NSString stringWithFormat:API_GET_DEVICE_UPDATE, _deviceDetail.deviceId]; [[RequestHandler handler] sendAsyncPostRequestAPIPath:path parameters:parameter modelClass:[JDJSONModel class] completion:^(id responseObject) { _refDevice.deviceName = _deviceDetail.deviceName = _mpopup.txtDeviceName.text; [_tableView reloadData]; //리스트를 다시 로드함. ThingsViewController *vc = [[JDFacade facade] viewControllerOnNaviationController:[ThingsViewController class]]; [vc.collectionView reloadData]; } failure:^(id errorObject) { JDErrorModel *error = (JDErrorModel *)errorObject; [[JDFacade facade] alert:error.errorMessage]; }]; } - (void)requestDeleteDevice { //parameters NSString *path = [NSString stringWithFormat:API_DELETE_DEVICE, _deviceDetail.deviceId]; [[RequestHandler handler] sendAsyncRequestAPIPath:path method:ksHTTPRequestDELETE parameters:nil modelClass:[JDJSONModel class] showLoadingView:YES completion:^(id responseObject) { [[JDFacade facade] toast:NSLocalizedString(@"장치가 삭제되었습니다", @"장치가 삭제되었습니다")]; // if ([JDFacade facade].loginHomeGroup.deviceId && ![[JDFacade facade].loginHomeGroup.deviceId isEmptyString]) { // if ([[JDFacade facade].loginHomeGroup.deviceId isEqualToString:_deviceDetail.deviceId]) {//현재 홈의 스마튼폰일 경우, // [JDFacade facade].loginHomeGroup.deviceId = nil; // [JDFacade facade].loginHomeGroup.deviceAuthorization = nil; // [JDFacade facade].loginHomeGroup.deviceKey = nil; // } // } //리스트를 다시 로드함. ThingsViewController *vc = [[JDFacade facade] viewControllerOnNaviationController:[ThingsViewController class]]; [vc prepareViewDidLoad]; [self.navigationController popToRootViewControllerAnimated:YES]; } failure:^(id errorObject) { JDErrorModel *error = (JDErrorModel *)errorObject; [[JDFacade facade] alert:error.errorMessage]; }]; } #pragma mark - UITableView DataSource & Delegate - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 3; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { NSInteger count = 1; if (section == 1) { count = _deviceDetail && _deviceDetail.nodes && _deviceDetail.nodes.count > 0; } else if (section == 2) {//optional nodes count = _optionalNodes.count; //두번째 이후부터 옵셔널 노드임. } return count; } - (CGFloat)heightForMandatoryNode { CGFloat height = 0; NodeModel *node = _deviceDetail.nodes.firstObject; if (node.cmdclsType == CmdClsTypeSwitchBinary || node.cmdclsType == CmdClsTypeValve) { height = 347.0f; //275 || 347 } else { height = 275.0f; } height += _mandatoryNodes.count > 1 ? 75 : 0; return height; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { CGFloat height = 86; NSInteger section = indexPath.section; if (section == 1) { height = [self heightForMandatoryNode] + 35.0f; } else if (section == 2) { height = 75; // if (indexPath.row == _deviceDetail.nodes.count - 2) { // height += 35; // } } return height; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = nil; NSInteger section = indexPath.section; if (section == 0) {//title ThingsDetailTitleTableViewCell *tcell = (ThingsDetailTitleTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"TitleCellIdentifier"]; tcell.lblDeviceName.text = _deviceDetail.deviceName; [tcell.imgvDevice sd_setImageWithURL:[NSURL URLWithString:_deviceDetail.imageFileName] placeholderImage:nil options:SDWebImageRefreshCached]; cell = tcell; } else if (section == 1) {//device control ThingsDetailControlTableViewCell *tcell = (ThingsDetailControlTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"ControlCellIdentifier"]; //뷰를 초기화함. [[tcell.controlContainer subviews] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { UIView *subview = (UIView *)obj; [subview removeFromSuperview]; }]; if (_deviceDetail) { tcell.controlContainer.scrollEnabled = _mandatoryNodes.count > 1; tcell.controlContainer.contentSize = CGSizeMake(IPHONE_WIDTH * _mandatoryNodes.count, [self heightForMandatoryNode]); tcell.controlContainer.showsHorizontalScrollIndicator = NO; if (tcell.controlContainer.scrollEnabled) { tcell.controlContainer.delegate = self; } tcell.pageControl.hidden = !tcell.controlContainer.scrollEnabled; if (!tcell.pageControl.hidden && !_pageControl) { _pageControl = tcell.pageControl; _pageControl.numberOfPages = _mandatoryNodes.count; } __block CGFloat width = 0; for (NodeModel *node in _mandatoryNodes) { node.refDevice = _refDevice; CommandClassControlView *controlView = [CommandClassControlDetailView viewForCommandClass:node.cmdclsType]; node.deviceId = _deviceDetail.deviceId; controlView.node = node; controlView.isMandatoryNode = [node.cmdclsMandatoryYn boolValue] && _mandatoryNodes.count > 1; tcell.controlContainer.hidden = !controlView; if (!tcell.controlContainer.hidden) { controlView.x = width; UIView *superview = tcell.controlContainer; [superview addSubview:controlView]; [controlView mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(controlView.frame.size); make.leading.equalTo(superview).offset(width); // make.trailing.equalTo(superview).offset(width+IPHONE_WIDTH); width += IPHONE_WIDTH; }]; } } } cell = tcell; } else if (section == 2) {//option control ThingsDetailOptionTableViewCell *tcell = (ThingsDetailOptionTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"OptionCellIdentifier"]; NodeModel *node = _deviceDetail.nodes[indexPath.row + _mandatoryNodes.count]; tcell.lblNodeName.text = node.nodeName; tcell.lblNodeValue.text = node.contentValueMsg; cell = tcell; } return cell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [super tableView:tableView didSelectRowAtIndexPath:indexPath]; } #pragma mark - UI Events - (IBAction)btnOptionTouched:(id)sender { [self toggleOptions:sender]; } - (IBAction)btnCloseTouched:(id)sender { [[JDFacade facade] dismissModalStack:YES completion:nil]; } #pragma mark - ScrollView Delegate - (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGFloat pageWidth = scrollView.frame.size.width; // you need to have a **iVar** with getter for scrollView CGFloat fractionalPage = scrollView.contentOffset.x / pageWidth; NSInteger page = lround(fractionalPage); _pageControl.currentPage = page; // you need to have a **iVar** with getter for pageControl } #pragma mark - MemoryWarning - (void)releaseDeviceTimer { if (_deviceBackgroundTimer) { [_deviceBackgroundTimer invalidate]; _deviceBackgroundTimer = nil; } } - (void)viewWillDisappear:(BOOL)animated { [self releaseDeviceTimer]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end