ScanBookViewController.m 15.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
//
//  ScanBookViewController.m
//  PLUCdraft
//
//  Created by Alexander W. Moore on 2/3/15.
//  Copyright (c) 2015 Alexander W. Moore. All rights reserved.
//


#import "ScanBookViewController.h"
#import "SectionViewController.h"
#import "GlobalWebController.h"
13 14
#import "Book.h"
#import "BookBuilder.h"
15 16 17 18 19 20 21 22 23 24 25

static int BOOK_ID_LENGTH = 14;

@interface ScanBookViewController ()

@end

@implementation ScanBookViewController

@synthesize session;
@synthesize lblSection;
26
@synthesize scannedBookList;
27
@synthesize lastErrorReceived;
28

29 30 31 32
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
33
    //[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self.view action:@selector(endEditing:)]];
34
    
35 36 37 38 39 40 41 42
    //self.navigationItem.hidesBackButton = YES;
    [self initializeScanPage];

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
43 44
}

45 46
-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
47
    [self checkContScanning];
48 49 50
}

-(void)viewWillDisappear:(BOOL)animated {
51
    [super viewWillDisappear:animated];
52 53 54 55 56
    if ([[NSUserDefaults standardUserDefaults] boolForKey:@"switchOnOff"]) {
        [[Captuvo sharedCaptuvoDevice] stopDecoderScanning];
    }
}

57
-(void) webViewDidFinishLoad:(UIWebView *)webView {
58
    [self evaluateNextRTIAction:webView];
59 60
}

61 62 63 64 65 66 67 68 69 70 71
#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    
    // Return the number of rows in the section.
72
    return [self.scannedBookList count];
73 74 75 76 77 78 79
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ListPrototypeCell" forIndexPath:indexPath];
    
    // Configure the cell...
80
    Book *book = [self.scannedBookList objectAtIndex:indexPath.row];
81
    cell.textLabel.text = book.title;
82 83 84 85 86 87 88 89
    if (book.errorMsg != nil) {
        cell.contentView.backgroundColor = [UIColor redColor];
        cell.textLabel.backgroundColor = [UIColor redColor];
    }
    else {
        cell.contentView.backgroundColor = [UIColor whiteColor];
        cell.textLabel.backgroundColor = [UIColor whiteColor];
    }
90
    
91 92 93 94
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
95 96
    Book *book = self.scannedBookList[indexPath.row];
    NSString *bookID = book.barcode;
97
    NSString *callNum = [book.callnum stringByReplacingOccurrencesOfString:@" " withString:@" "];
98
    NSString *title = book.title;
99 100 101 102 103 104 105 106
    NSString *errorMsg = book.errorMsg;
    NSString *message;
    if (errorMsg != nil) {
         message = [NSString stringWithFormat:@"Book ID: %@\nCall Number: %@\nTitle: %@\nError: %@", bookID, callNum, title, errorMsg];
    }
    else {
        message = [NSString stringWithFormat:@"Book ID: %@\nCall Number: %@\nTitle: %@\n", bookID, callNum, title];
    }
107
    /*
108 109 110 111 112
    UIAlertView *messageAlert = [[UIAlertView alloc]
                                 initWithTitle:@"Book details" message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    
    // Display Alert Message
    [messageAlert show];
113 114 115 116 117 118 119
    */
    UIAlertController *messageAlert = [UIAlertController alertControllerWithTitle:@"Book Details" message:message preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
        [messageAlert dismissViewControllerAnimated:YES completion:nil];
    }];
    [messageAlert addAction: ok];
    [self presentViewController:messageAlert animated:YES completion:nil];
120 121 122 123 124 125 126 127 128 129 130 131 132
    
    [tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:NO];
}

#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
    
}

133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
-(IBAction)prepareForUnwindFromSettings:(UIStoryboardSegue *)sender {
    
}

#pragma mark - Helper Functions

//Secondary option for escaping keyboard
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    
    UITouch *touch = [[event allTouches] anyObject];
    if ([self.txtBookID isFirstResponder] && [touch view] != self.txtBookID) {
        [self.txtBookID resignFirstResponder];
    }
    [super touchesBegan:touches withEvent:event];
}
148

149 150 151 152 153 154 155
- (void)initializeScanPage {
    lblSection.text = session.section;
    self.lastErrorReceived = nil;
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(checkContScanning)
                                                 name:UIApplicationDidBecomeActiveNotification object:nil];
156
    
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
    //Initialize scanned book history tableView
    self.scannedBookList = [[NSMutableArray alloc] init];
    self.scannedBookTableView.delegate = self;
    self.scannedBookTableView.dataSource = self;
    [self.scannedBookTableView reloadData];
}

- (void)checkContScanning {
    BOOL enableContScanning = [[NSUserDefaults standardUserDefaults] boolForKey:@"switchOnOff"];
    if (enableContScanning) {
        [[Captuvo sharedCaptuvoDevice] startDecoderScanning];
        [[Captuvo sharedCaptuvoDevice] setDecoderGoodReadDelayInMilliSeconds:1500 persistSetting:NO];
    }
    else {
        [[Captuvo sharedCaptuvoDevice] setDecoderGoodReadDelayInMilliSeconds:500 persistSetting:NO];
    }

174 175
}

176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
- (void)evaluateNextRTIAction:(UIWebView *)webView {
    NSString *url = [[webView request] URL].absoluteString;
    NSString *base_dest_url;
#ifdef TESTING
    base_dest_url = @"http://162.223.19.75";
#else
    base_dest_url = @"http://192.168.1.131";
#endif
    //http://162.223.19.75/rti/RTIAction.aspx?location=1
    if ([url isEqualToString:[base_dest_url stringByAppendingString:@"/rti/Default.aspx"]]) {
        NSLog(@"Timed out!");
        [self performSegueWithIdentifier:@"segueScanToLogin" sender:nil];
    }
    else if ([url isEqualToString:[base_dest_url stringByAppendingString:@"/rti/RTIScan.aspx?location=1"]]) {
        NSLog(@"1: %@", url);
        [self updateScanHistory:YES];
    }
    else if ([url isEqualToString:[base_dest_url stringByAppendingString:@"/rti/RTIAction.aspx?location=1"]]) {
        NSLog(@"2: %@", url);
        //Disable scanning until error viewed
        //[[Captuvo sharedCaptuvoDevice] stopDecoderHardware];
        //Handle Error Message
        [self getErrorMsg:webView];
    }
    //Handle deeper errors
    else {
        NSLog(@"3: %@", url);
        /*
         UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"FATAL PAGE ERROR" message:@"Page not recognized, cannot proceed.  App will no longer work as expected." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
         [alert show];
         */
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"FATAL PAGE ERROR" message:@"Page not recognized, cannot proceed.  App will no longer work as expected." preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
            [alert dismissViewControllerAnimated:YES completion:nil];
        }];
        [alert addAction: ok];
        [self presentViewController:alert animated:YES completion:nil];
    }
214 215
}

216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
- (void)getErrorMsg:(UIWebView *)webView {
    //Get the error
    NSString *getErrorPath =
    [[NSBundle mainBundle] pathForResource:@"GetError" ofType:@"js"];
    NSString *getError = [NSString stringWithContentsOfFile:getErrorPath
                                                   encoding:NSUTF8StringEncoding
                                                      error:nil];
    
    NSString *error = [webView stringByEvaluatingJavaScriptFromString:getError];
    NSLog(@"%@", error);
    
    //Isolate error message
    //NSRegularExpression *errorRegex = [[NSRegularExpression alloc] initWithPattern:@"(.*),(.*),(.*)" options:0 error:nil];
    //NSTextCheckingResult *match = [errorRegex firstMatchInString:error options:0 range:NSMakeRange(0, [error length])];
    
    //NSString *bookID = [error substringWithRange:[match rangeAtIndex:1]];
    //NSString *title = [error substringWithRange:[match rangeAtIndex:2]];
    //NSString *errorMsg = [error substringWithRange:[match rangeAtIndex:3]];
    //error = [NSString stringWithFormat:@"Book ID: %@\nTitle: %@\nError: %@", bookID, title, errorMsg];
    
    //self.lastErrorReceived = errorMsg;
    self.lastErrorReceived = error;
    
    // Continue from error page
    NSString *goToScanPath =
    [[NSBundle mainBundle] pathForResource:@"GoToScan" ofType:@"js"];
    NSString *goToScan = [NSString stringWithContentsOfFile:goToScanPath
                                                   encoding:NSUTF8StringEncoding
                                                      error:nil];
    [webView stringByEvaluatingJavaScriptFromString:goToScan];
    /*
     UIAlertView *errorAlert =
     [[UIAlertView alloc] initWithTitle:@"Error Encountered"
     message:error
     delegate:self
     cancelButtonTitle:@"OK"
     otherButtonTitles:nil];
     [errorAlert show];
     */
    
    UIAlertController *errorAlert = [UIAlertController alertControllerWithTitle:@"Error Encountered" message:error preferredStyle:UIAlertControllerStyleAlert];
    
    ScanBookViewController *mainController = (ScanBookViewController *)errorAlert.parentViewController;
    
    UIAlertAction *ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
        [errorAlert dismissViewControllerAnimated:YES completion:nil];
    }];
    [errorAlert addAction: ok];
    [self presentViewController:errorAlert animated:YES completion:nil];
}

- (void)errorHandled {
    [[Captuvo sharedCaptuvoDevice] startDecoderHardware];
}

- (void)updateScanHistory:(BOOL) updateOnError {
    
    //If RTI error triggered, pop top book off list
    if (updateOnError && [self.scannedBookList count] > 0) {
        [self.scannedBookList removeObjectAtIndex:0];
    }
    
    // Get scanned codes - Testing GetScanned
    NSString *getScanPath =
    [[NSBundle mainBundle] pathForResource:@"GetScanned" ofType:@"js"];
    NSString *getScan = [NSString stringWithContentsOfFile:getScanPath
                                                  encoding:NSUTF8StringEncoding
                                                     error:nil];
    
    NSString *scanned =
    [self.webview stringByEvaluatingJavaScriptFromString:getScan];
    [self extractScannedBookInformation:scanned :updateOnError];
    
}

- (void)extractScannedBookInformation:(NSString *)scannedBooks :(BOOL)bookError {
    
    NSLog(@"%@", scannedBooks);
    //Create error holder for JSON parsing
    NSError *error = nil;
    
    //Convert string to JSON format
    NSData *jsonBooks = [scannedBooks dataUsingEncoding:NSUTF8StringEncoding];
    
    //Parse JSON object
    NSArray *books = [BookBuilder booksFromJSON:jsonBooks error:&error];
    
    //Check for errors (in JSON parsing)
    if (error != nil) {
        NSLog(@"ERROR: %@", error.localizedDescription);
    }
    //If no errors found in JSON parsing, update book list
    else {
        NSLog(@"SUCCESS");
        Book *book = [books objectAtIndex:0];
        
        //Fix Book Title
        book.title = [book.title stringByReplacingOccurrencesOfString:@" " withString:@" "];
        
        //Add top book to list
        [self.scannedBookList insertObject:book atIndex:0];
        
        //Check if last book had error
        if (bookError) {
            Book *book = [self.scannedBookList objectAtIndex:0];
            book.errorMsg = lastErrorReceived;
            lastErrorReceived = nil;
        }
        
        [self.scannedBookTableView reloadData];
    }
}

- (void)barcodeTextChanged {
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348
    NSCharacterSet* notDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
    if(self.txtBookID.text.length == BOOK_ID_LENGTH) {  //string is proper length
        if([self.txtBookID.text rangeOfCharacterFromSet:notDigits].location == NSNotFound) {  //string is numeric
            // SEND BOOK ID TO RTI
            NSString *barcode = self.txtBookID.text;
            
            NSString *stringStart = @"var code = '";
            NSString *stringEnd = @"';";
            NSString *newString = [stringStart stringByAppendingString:barcode];
            NSString *inputCode = [newString stringByAppendingString:stringEnd];
            
            NSString *scanPath =
            [[NSBundle mainBundle] pathForResource:@"ScanBarcode" ofType:@"js"];
            NSString *scan = [NSString stringWithContentsOfFile:scanPath
                                                       encoding:NSUTF8StringEncoding
                                                          error:nil];
            
            [self.webview stringByEvaluatingJavaScriptFromString:inputCode];
            [self.webview stringByEvaluatingJavaScriptFromString:scan];
349 350
            
            //Blink background green to indicate successful scan
351 352 353 354
            self.view.backgroundColor = [UIColor greenColor];
            [UIView animateWithDuration:1.0 animations:^{
                self.view.backgroundColor = [UIColor whiteColor];
            }];
355 356
            
            //Reset barcode textfield
357 358
            [self.txtBookID setText:@""];
            
359
            [self updateScanHistory:NO];
360
            
361
        } else {
362
            /*
363 364 365
             UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Invalid Book ID" message:@"Book ID must be numeric" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
             [alert show];
             */
366 367 368 369 370 371
            UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Invalid Book ID" message:@"Book ID must be numeric." preferredStyle:UIAlertControllerStyleAlert];
            UIAlertAction *ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
                [alert dismissViewControllerAnimated:YES completion:nil];
            }];
            [alert addAction: ok];
            [self presentViewController:alert animated:YES completion:nil];
372 373 374 375 376 377
        }
    } else {
        //if not 14 digits
        //UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Invalid Book ID" message:@"Book ID improper length" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
        //[alert show];
    }
Alex Moore's avatar
Alex Moore committed
378
    
379 380 381 382 383 384 385 386 387
}

- (IBAction)txtChange:(id)sender {
    [self barcodeTextChanged];
}

- (void)decoderDataReceived:(NSString *)data {
    [super decoderDataReceived:data];
    [self barcodeTextChanged];
Alex Moore's avatar
Alex Moore committed
388 389 390 391
    
    if ([[NSUserDefaults standardUserDefaults] boolForKey:@"switchOnOff"]) {
        [[Captuvo sharedCaptuvoDevice] startDecoderScanning];
    }
392
    
393 394
}

395
#pragma mark - UI Buttons
396

397 398 399
- (IBAction)exitBtnPressed:(id)sender {
    [self performSegueWithIdentifier:@"segueScanToLogin" sender:nil];
}
400 401

@end