Skip to content
Snippets Groups Projects
TokenViewController.m 9.37 KiB
Newer Older
Petr Hruška's avatar
Petr Hruška committed
//
//  TokenViewController.m
//  ISDS
//
//  Created by Petr Hruška on 6/30/11.
//  Copyright 2011 CZ.NIC, z.s.p.o. All rights reserved.
//

#import "TokenViewController.h"
#import "OtpStatus.h"
#import "DownloadCookie.h"
#import "RequestManager.h"

#define CONTINUE_BUTTON_INDEX      0
#define CANCEL_BUTTON_INDEX        1

@implementation TokenViewController

@synthesize data=_data;
@synthesize cell=_cell;
@synthesize tableView=_tableView;
@synthesize doneButton=_doneButton;
@synthesize editing=_editing;
@synthesize delegate;

- (void)cancelNetworkOperations
{
    //TODO remove from queue
}

- (void)dealloc
{
    [self cancelNetworkOperations];
    [_data release];
    [_tableView release];
    [_doneButton release];
    [_editing release];
    [super dealloc];
}

- (void)viewDidUnload
{
    self.tableView = nil;
    self.doneButton = nil;
    [super viewDidUnload];
}

- (TokenCell*)cellAtIndex:(NSUInteger)index
{
    return (TokenCell*)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:index]];
}

/* return [self.data count] if the focus should not be set */
- (NSUInteger)initialFocusIndex
{
    NSUInteger index = 0;
    const NSUInteger count = [self.data count];
    
    while (index < count) {
        OtpStatus* status = [self.data objectAtIndex:index];
        
        if (status.status == OtpStatusShouldSendSms) {
            return count;
        } else if (status.status == OtpStatusEnterToken) {
            return index;
        }
        index++;
    }
    return index;
}

- (void)viewWillAppear:(BOOL)animated
{
    self.doneButton.title = NSLocalizedString(@"Done", nil);
    self.navigationItem.rightBarButtonItem = self.doneButton;
    
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    /* set focus */
    NSUInteger index = [self initialFocusIndex];
    if (index < [self.data count]) {
        TokenCell* cell = [self cellAtIndex:index];
        [cell setFocus];
    }

    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [self cancelNetworkOperations];
    [super viewWillAppear:animated];
}

- (NSUInteger)indexFromTask:(OtpTask*)task
{
    const NSUInteger count = [self.data count];
    for (NSUInteger index = 0; index < count; index++) {
        OtpStatus* status = [self.data objectAtIndex:index];
        if (status.task == task) return index;
    }
    return count;
}

- (void)setupAccounts:(NSArray*)accounts
{
    self.data = [NSMutableArray arrayWithCapacity:[accounts count]];
    for (ISDSAccount* account in accounts) {
        if (account.authType != ISDSAccountAuthPass) {
            OtpStatus* status = [[OtpStatus alloc] initWithAccount:account];
            [self.data addObject:status];
            [status release];
        }
    }
}

- (void)configureCell:(TokenCell*)cell withStatus:(OtpStatus*)status
{
    cell.boxName = [status.account boxName];
    cell.authType = status.account.authType;
    
    switch (status.status) {
        case OtpStatusShouldSendSms:
            cell.message = NSLocalizedString(@"click to send sms", nil);
            break;
        case OtpStatusRequestingSms:
            cell.message = NSLocalizedString(@"requesting sms", nil);
            break;
        case OtpStatusEnterToken:
            if (status.errorDescription != nil)
                cell.message = status.errorDescription;
            else
                cell.message = NSLocalizedString(@"enter code", nil);
            break;
        case OtpStatusRequestingCookie:
            cell.message = NSLocalizedString(@"requesting cookie", nil);
            break;
        case OtpStatusHasCookie:
            cell.message = NSLocalizedString(@"account authorized", nil);
            break;
    }

    [cell setStatus:status.status];
}

- (IBAction)sendSms:(id)sender
{/* FIXME
    TokenCell* cell = (TokenCell*)sender;
    NSUInteger index = cell.tag;
    OtpStatus* status = [self.data objectAtIndex:index];
    status.connection = [[OtpTask alloc] initWithAccount:status.account delegate:self];
    [status.connection release];
  */
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString* reuseIdentifier = @"TokenCell";
    
    TokenCell* cell = (TokenCell*)[tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
    if (cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:@"TokenCell" owner:self options:nil];
        cell = self.cell;
        self.cell = nil;
    }
    
    OtpStatus* status = [self.data objectAtIndex:[indexPath section]];
    [self configureCell:cell withStatus:status];
    [cell setupTag:indexPath.section];
    
    return cell;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [self.data count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 1;
}

- (OtpTask*)createTask:(OtpStatus*)status
{
    OtpTask* t;
    switch (status.account.authType) {
        case ISDSAccountAuthHotp:
            t = [[DownloadCookie alloc] initWithOtpStatus:status];
            t.otpDelegate = self;
            [t autorelease];
            break;
            
        default:
            t = nil;
            break;
    }
    
    return t;
}

- (void)done
{
    [self.delegate tokenViewControllerDone:self];
    [self.navigationController popViewControllerAnimated:YES];
}

- (void)downloadCookies
{
    NSUInteger taskCount = 0;
    
    for (OtpStatus* status in self.data) {
        if ([status tokenReady]) taskCount++;
    }
    
    if (!taskCount) {
        [self done];
        return;
    }
    
    NSMutableArray* tasks = [NSMutableArray arrayWithCapacity:taskCount];
    for (OtpStatus* status in self.data) 
        if ([status tokenReady]) {
            OtpTask* task = [self createTask:status];
            status.task = task;
            status.status = OtpStatusRequestingCookie;
            [tasks addObject:task];
        }
    
    RequestManager* rm = [RequestManager requestManager];
    [rm addTasks:tasks withPriority:YES];
    
    [self.tableView reloadData];    
}

- (void)showActionSheet
{
    UIActionSheet* actionSheet = [[UIActionSheet alloc] initWithTitle:NSLocalizedString(@"Some accounts are missing tokens. Do you with to continue?", nil) delegate:self cancelButtonTitle:NSLocalizedString(@"Cancel", nil) destructiveButtonTitle:NSLocalizedString(@"Continue", nil) otherButtonTitles: nil];
    
    [actionSheet showInView:self.view];
    [actionSheet release];
}

- (void)markMissingUnwanted
{
    for (OtpStatus* status in self.data) {
        if (![status tokenReady] && status.shouldHaveCookie) status.shouldHaveCookie = FALSE;
    }
}


- (IBAction)doneTouched
{
    if (self.editing)
        [self.editing resignFirstResponder];
    
    NSUInteger missingCount = 0;
    for (OtpStatus* status in self.data) {
        if (![status tokenReady] && status.shouldHaveCookie) missingCount++;
    }
    
    if (missingCount)
        [self showActionSheet];
    else 
        [self downloadCookies];
}

- (void)reloadSectionForIndex:(NSUInteger)index
{
    [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:index] withRowAnimation:UITableViewRowAnimationNone];
}

- (BOOL)hasAllWantedCookies
{
    for (OtpStatus* status in self.data)
        if (status.status != OtpStatusHasCookie && status.shouldHaveCookie) return NO;
        
    return YES;
}

#pragma mark - OtpTaskDelegate

- (void)taskSuccessfullyDone:(ISDSTask*)task
{
    NSUInteger index = [self indexFromTask:(OtpTask*)task];
    OtpStatus* status = [self.data objectAtIndex:index];
    switch (status.status) {
        case OtpStatusRequestingSms:
            status.status = OtpStatusEnterToken;
            [self reloadSectionForIndex:index];
            break;
        case OtpStatusRequestingCookie:
            status.status = OtpStatusHasCookie;
            if ([self hasAllWantedCookies])
                [self done];
            else
                [self reloadSectionForIndex:index];
            break;
            
        default:
            break;
    }
}

- (void)taskFailed:(ISDSTask*)task
{
    NSUInteger index = [self indexFromTask:(OtpTask*)task];
    if (index == [self.data count]) return;
    OtpStatus* status = [self.data objectAtIndex:index];
    status.status = OtpStatusEnterToken;
    status.errorDescription = task.errorDescription;
    [self reloadSectionForIndex:index];
}

#pragma mark - UITextFieldDelegate

- (void)setupTokenFromTextField:(UITextField *)textField
{
    NSUInteger index = textField.tag;
    OtpStatus* status = [self.data objectAtIndex:index];
    status.token = textField.text;
}

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    self.editing = textField;
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    [self setupTokenFromTextField:textField];
    self.editing = nil;
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    return NO;
}


- (BOOL)textFieldShouldClear:(UITextField *)textField
{
    if ([textField isFirstResponder])
        [textField resignFirstResponder];
    else
        textField.text = @"";
    
    return NO;
}

- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    switch (buttonIndex) {
        case CONTINUE_BUTTON_INDEX:
            // we will not ask next time
            [self markMissingUnwanted]; 
            [self downloadCookies];
            break;
        case CANCEL_BUTTON_INDEX:
            break;
    }
}

@end