//
//  PrintPDFViewController.m
//  SIIMpaPrinterSample
//

#import "PrintPDFViewController.h"
#import "PrinterManager.h"
#import "ValueManager.h"
#import "ValueViewController.h"

@interface PrintPDFViewController () <UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate>
@property (strong, nonatomic) IBOutlet UITableView *tableView;
@end

@implementation PrintPDFViewController {
    UIView *_indicatorView;
    ValueViewController *_viewController;
    UIToolbar *_keyboardToolbar;
    UITextField *_startIndexTextField;
    UITextField *_endIndexTextField;
    UITextField *_widthTextField;
    UITextField *_bottomMarginTextField;

    NSInteger _sectionIndex;
    NSInteger _frameWidth;
    NSString *startIndexStr;
    NSString *endIndexStr;
    NSString *widthStr;
    NSString *bottomMarginStr;
    NSString *rotationStr;
    NSString *ditheringStr;

    NSInteger printPagesSelectedIndex;
    NSInteger printWidthSelectedIndex;
    NSInteger printBottomMarginSelectedIndex;
}

static NSUInteger const SIZE_OF_SECTION_TITLE_TABLE = 5;
static NSString *const SECTION_TITLE_TABLE[] = {
    PDF_PAGES_SECTION,
    PDF_ROTATION_SECTION,
    PDF_WIDTH_SECTION,
    PDF_BOTTOM_MARGIN_SECTION,
    PDF_DITHERING_SECTION,
};

static NSUInteger const SIZE_OF_PDF_ROTATION_TABLE = 2;
static NSString *const PDF_ROTATION_TABLE[] = {
    PDF_ROTATION_NONE,
    PDF_ROTATION_180
};

static NSUInteger const SIZE_OF_PDF_DITHERING_TABLE = 2;
static NSString *const PDF_DITHERING_TABLE[] = {
    PDF_DITHERING_DISABLE,
    PDF_DITHERING_ERROR_DIFFUSION
};

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    _sectionIndex = -1;
    self.tableView.delegate = (id <UITableViewDelegate>)self;
    self.tableView.dataSource = (id <UITableViewDataSource>)self;
    [self initIndicatorView];
    [self setupCloseKeyboardBar];
    [self setInitValue];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self reloadTableView];
    [self reloadViewSize];
}

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
        [self reloadViewSize];
    } completion:nil];
}

#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return SIZE_OF_SECTION_TITLE_TABLE;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    if (section < SIZE_OF_SECTION_TITLE_TABLE) {
        return SECTION_TITLE_TABLE[section];
    } else {
        return @"";
    }
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (([SECTION_TITLE_TABLE[section] isEqualToString:PDF_PAGES_SECTION] && printPagesSelectedIndex == 1) ||
        ([SECTION_TITLE_TABLE[section] isEqualToString:PDF_WIDTH_SECTION] && printWidthSelectedIndex == 1) ||
        ([SECTION_TITLE_TABLE[section] isEqualToString:PDF_BOTTOM_MARGIN_SECTION] && printBottomMarginSelectedIndex == 1)) {
        return 2;
    } else {
        return 1;
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    [cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
    cell.textLabel.text = @"";
    cell.textLabel.numberOfLines = 0;
    NSString *sectionTitle = SECTION_TITLE_TABLE[indexPath.section];
    if ([sectionTitle isEqualToString:PDF_PAGES_SECTION]) {
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.accessoryType = UITableViewCellAccessoryNone;
        if ([indexPath isEqual:[NSIndexPath indexPathForRow:0 inSection:indexPath.section]]){
            NSArray *segItems = [NSArray arrayWithObjects:@"All", @"Pages", nil];
            UISegmentedControl *seg = [[UISegmentedControl alloc] initWithItems:segItems];
            seg.frame = CGRectMake(20, 5, _frameWidth - 40, cell.frame.size.height - 10);
            seg.selectedSegmentIndex = printPagesSelectedIndex;
            seg.tag = indexPath.section;
            [seg addTarget:self action:@selector(segmentControlInsertRows:) forControlEvents:UIControlEventValueChanged];
            [cell.contentView addSubview:seg];
        }else {
            // When "Pages to print" segment is selected to "Pages", show textField for startIndex and endIndex input.
            _startIndexTextField = [[UITextField alloc] initWithFrame:CGRectMake(20, 0, _frameWidth / 3, cell.frame.size.height)];
            _startIndexTextField.returnKeyType = UIReturnKeyDone;
            _startIndexTextField.keyboardType = UIKeyboardTypeNumberPad;
            _startIndexTextField.clearButtonMode = YES;
            [_startIndexTextField setDelegate:self];
            _startIndexTextField.text = startIndexStr;
            _startIndexTextField.tag = 0;
            _keyboardToolbar.tag = 0;
            _startIndexTextField.inputAccessoryView = _keyboardToolbar;

            UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(_frameWidth / 2 - 20, 0, _frameWidth / 4, cell.frame.size.height)];
            label.text = @"~";

            _endIndexTextField = [[UITextField alloc] initWithFrame:CGRectMake(_frameWidth / 3 * 2, 0, _frameWidth / 3, cell.frame.size.height)];
            _endIndexTextField.returnKeyType = UIReturnKeyDone;
            _endIndexTextField.keyboardType = UIKeyboardTypeNumberPad;
            _endIndexTextField.clearButtonMode = YES;
            [_endIndexTextField setDelegate:self];
            _endIndexTextField.text = endIndexStr;
            _endIndexTextField.tag = 1;
            _endIndexTextField.inputAccessoryView = _keyboardToolbar;

            [cell.contentView addSubview:_startIndexTextField];
            [cell.contentView addSubview:label];
            [cell.contentView addSubview:_endIndexTextField];
        }
    } else if ([sectionTitle isEqualToString:PDF_ROTATION_SECTION]) {
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        cell.textLabel.text = rotationStr;
    } else if ([sectionTitle isEqualToString:PDF_WIDTH_SECTION]) {
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.accessoryType = UITableViewCellAccessoryNone;
        if ([indexPath isEqual:[NSIndexPath indexPathForRow:0 inSection:indexPath.section]]){
            NSArray *segItems = [NSArray arrayWithObjects:@"PDF Width", @"User Specify", nil];
            UISegmentedControl *seg = [[UISegmentedControl alloc] initWithItems:segItems];
            seg.frame = CGRectMake(20, 5, _frameWidth - 40, cell.frame.size.height - 10);
            seg.selectedSegmentIndex = printWidthSelectedIndex;
            seg.tag = indexPath.section;
            [seg addTarget:self action:@selector(segmentControlInsertRows:) forControlEvents:UIControlEventValueChanged];
            [cell.contentView addSubview:seg];
        }else {
            // When "Width" segment is selected to "User Specify", show textField for width input.
            _widthTextField = [[UITextField alloc] initWithFrame:CGRectMake(20, 0, _frameWidth - 20, cell.frame.size.height)];
            _widthTextField.contentVerticalAlignment= UIControlContentVerticalAlignmentCenter;
            _widthTextField.returnKeyType = UIReturnKeyDone;
            _widthTextField.keyboardType = UIKeyboardTypeNumberPad;
            _widthTextField.tag = indexPath.section;
            _widthTextField.clearButtonMode = YES;
            [_widthTextField setDelegate:self];
            _widthTextField.text = widthStr;
            _widthTextField.inputAccessoryView = _keyboardToolbar;
            [cell.contentView addSubview:_widthTextField];
        }
    } else if ([sectionTitle isEqualToString:PDF_BOTTOM_MARGIN_SECTION]) {
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.accessoryType = UITableViewCellAccessoryNone;
        if ([indexPath isEqual:[NSIndexPath indexPathForRow:0 inSection:indexPath.section]]){
            NSArray *segItems = [NSArray arrayWithObjects:@"PDF Margin", @"User Specify", nil];
            UISegmentedControl *seg = [[UISegmentedControl alloc] initWithItems:segItems];
            seg.frame = CGRectMake(20, 5, _frameWidth - 40, cell.frame.size.height - 10);
            seg.selectedSegmentIndex = printBottomMarginSelectedIndex;
            seg.tag = indexPath.section;
            [seg addTarget:self action:@selector(segmentControlInsertRows:) forControlEvents:UIControlEventValueChanged];
            [cell.contentView addSubview:seg];
        }else {
            // When "Bottom Margin" segment is selected to "User Specify", show textField for bottomMargin input.
            _bottomMarginTextField = [[UITextField alloc] initWithFrame:CGRectMake(20, 0, _frameWidth - 20, cell.frame.size.height)];
            _bottomMarginTextField.contentVerticalAlignment= UIControlContentVerticalAlignmentCenter;
            _bottomMarginTextField.returnKeyType = UIReturnKeyDone;
            _bottomMarginTextField.keyboardType = UIKeyboardTypeNumberPad;
            _bottomMarginTextField.tag = indexPath.section;
            _bottomMarginTextField.clearButtonMode = YES;
            [_bottomMarginTextField setDelegate:self];
            _bottomMarginTextField.text = bottomMarginStr;
            _bottomMarginTextField.inputAccessoryView = _keyboardToolbar;
            [cell.contentView addSubview:_bottomMarginTextField];
        }
    } else if ([sectionTitle isEqualToString:PDF_DITHERING_SECTION]) {
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        cell.textLabel.text = ditheringStr;
    }
    return cell;
}

#pragma mark - TextField
- (void)segmentControlInsertRows:(UISegmentedControl*)seg {
    NSInteger section = seg.tag;
    NSInteger selectedIndex = seg.selectedSegmentIndex;
    if ([SECTION_TITLE_TABLE[section] isEqualToString: PDF_PAGES_SECTION]) {
        printPagesSelectedIndex = selectedIndex;
    } else if ([SECTION_TITLE_TABLE[section] isEqualToString: PDF_WIDTH_SECTION]) {
        printWidthSelectedIndex = selectedIndex;
    } else if ([SECTION_TITLE_TABLE[section] isEqualToString: PDF_BOTTOM_MARGIN_SECTION]) {
        printBottomMarginSelectedIndex = selectedIndex;
    }
    [_tableView beginUpdates];
    NSIndexPath *indexPaths = [NSIndexPath indexPathForRow:1 inSection:section];
    if (selectedIndex == 1) {
        // Show textfield for value input.
        [_tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPaths] withRowAnimation:UITableViewRowAnimationNone];
        [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPaths] withRowAnimation:UITableViewRowAnimationNone];
    } else {
        if ([_tableView numberOfRowsInSection:section] == 2) {
            // Hide textfield.
            [_tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPaths] withRowAnimation:UITableViewRowAnimationNone];
        }
    }
    [_tableView endUpdates];
    [_tableView reloadData];
}

- (void)setupCloseKeyboardBar {
    _keyboardToolbar = [[UIToolbar alloc] init];
    _keyboardToolbar.barStyle  = UIBarStyleDefault;
    _keyboardToolbar.translucent = YES;
    _keyboardToolbar.tintColor = nil;
    [_keyboardToolbar sizeToFit];

    UIBarButtonItem* closeButton = [[UIBarButtonItem alloc] initWithTitle:@"close" style:UIBarButtonItemStylePlain target:self action:@selector(closeButtonOnClicked)];
    UIBarButtonItem *spacer1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
    UIBarButtonItem *spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
    [_keyboardToolbar setItems:[NSArray arrayWithObjects:spacer, spacer1, closeButton, nil]];
}

- (void)closeButtonOnClicked {
    if ([_startIndexTextField isFirstResponder]) {
        [self textFieldShouldReturn:_startIndexTextField];
    }
    if ([_endIndexTextField isFirstResponder]) {
        [self textFieldShouldReturn:_endIndexTextField];
    }
    if ([_widthTextField isFirstResponder]) {
        [self textFieldShouldReturn:_widthTextField];
    }
    if ([_bottomMarginTextField isFirstResponder]) {
        [self textFieldShouldReturn:_bottomMarginTextField];
    }
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder];
    NSInteger tag = textField.tag;
    if (tag == 0) {
        if (![textField.text isEqualToString:@"0"] && [textField.text integerValue] == 0){ // Fail to convert input string to integer.
            textField.text = @"1";
        }
        startIndexStr = textField.text;
    } else if (tag == 1) {
        if (![textField.text isEqualToString:@"0"] && [textField.text integerValue] == 0){ // Fail to convert input string to integer.
            textField.text = @"100";
        }
        endIndexStr = textField.text;
    } else if ([SECTION_TITLE_TABLE[tag] isEqualToString: PDF_WIDTH_SECTION]) {
        if (![textField.text isEqualToString:@"0"] && [textField.text integerValue] == 0){ // Fail to convert input string to integer.
            textField.text = @"832";
        }
        widthStr = textField.text;
    } else if ([SECTION_TITLE_TABLE[tag] isEqualToString: PDF_BOTTOM_MARGIN_SECTION]) {
        if (![textField.text isEqualToString:@"0"] && [textField.text integerValue] == 0){ // Fail to convert input string to integer.
            textField.text = @"0";
        }
        bottomMarginStr = textField.text;
    }
    return YES;
}

#pragma mark - Navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
    if (0 <= indexPath.section && indexPath.section < SIZE_OF_SECTION_TITLE_TABLE) {
        NSString *sectionTitle = SECTION_TITLE_TABLE[indexPath.section];
        _sectionIndex = indexPath.section;
        if ([sectionTitle isEqualToString:PDF_ROTATION_SECTION]) {
            UITableViewCell *cell = sender;
            _viewController = [segue destinationViewController];
            NSMutableArray *valueData = [[NSMutableArray alloc] init];
            for (int i = 0; i < SIZE_OF_PDF_ROTATION_TABLE; i++) {
                [valueData addObject:PDF_ROTATION_TABLE[i]];
                if ([cell.textLabel.text isEqualToString:PDF_ROTATION_TABLE[i]]) {
                    _viewController.currentValueIndex = i;
                }
            }
            _viewController.tableData = valueData;
        } else if ([sectionTitle isEqualToString:PDF_DITHERING_SECTION]) {
            UITableViewCell *cell = sender;
            _viewController = [segue destinationViewController];
            NSMutableArray *valueData = [[NSMutableArray alloc] init];
            for (int i = 0; i < SIZE_OF_PDF_DITHERING_TABLE; i++) {
                [valueData addObject:PDF_DITHERING_TABLE[i]];
                if ([cell.textLabel.text isEqualToString:PDF_DITHERING_TABLE[i]]) {
                    _viewController.currentValueIndex = i;
                }
            }
            _viewController.tableData = valueData;
        }
    }
}

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender {
    NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
    if (0 <= indexPath.section && indexPath.section <= SIZE_OF_SECTION_TITLE_TABLE) {
        NSString *sectionTitle = SECTION_TITLE_TABLE[indexPath.section];
        if ([sectionTitle isEqualToString:PDF_ROTATION_SECTION]) {
            return YES;
        } else if ([sectionTitle isEqualToString:PDF_DITHERING_SECTION]) {
            return YES;
        } else {
            return NO;
        }
    } else {
        return NO;
    }
}


#pragma mark - Button Action
- (IBAction)printButtonOnClicked:(id)sender {
    NSInteger startIndex = -1;
    NSInteger endIndex = -1;
    NSInteger width = -1;
    NSInteger bottomMargin = -1;
    Rotate rotation = [rotationStr isEqualToString:PDF_ROTATION_NONE] ? SII_MPM_ROTATE_NONE : SII_MPM_ROTATE_180;
    Dithering dithering = [ditheringStr isEqualToString:PDF_DITHERING_DISABLE] ? SII_MPM_DITHERING_DISABLE : SII_MPM_DITHERING_ERRORDIFFUSION;

    if (printPagesSelectedIndex == 1) {
        // User Specify
        startIndex = [startIndexStr integerValue];
        endIndex = [endIndexStr integerValue];
    }

    if (printWidthSelectedIndex == 1) {
        // User Specify
        width = [widthStr integerValue];
    }

    if (printBottomMarginSelectedIndex == 1) {
        // User Specify
        bottomMargin = [bottomMarginStr integerValue];
    }

    dispatch_async([PrinterManager getDispatchQueue], ^{
        [self startLoadingView];
        BOOL success = YES;
        if ([self.file startAccessingSecurityScopedResource] == YES) {
            NSString *filePath = [self.file path];
            // Example of printing a PDF file:
            // To print all pages of a PDF file, set “startIndex” to -1.
            // To print pages 2 through 5, specify 2 for “startIndex” and 5 for “endIndex”.
            success = [PrinterManager printPDF:filePath startIndex:startIndex endIndex:endIndex rotate:rotation width:width bottomMargin:bottomMargin dithering:dithering];
            [self.file stopAccessingSecurityScopedResource];
            if (success == NO) {
                [self showMessageBox:@"" message:[NSString stringWithFormat:@"%@%@", @"Attempt to print pdf file failed.\n ErrorCode : ", [PrinterManager getErrorCodeText]]];
            }
        } else {
            [self showMessageBox:@"" message:@"Open File Failed."];
        }
        [self stopLoadingView];
    });
}

- (IBAction)closeButtonOnClicked:(id)sender {
    [self dismissViewControllerAnimated:YES completion:nil];
}

#pragma mark - Private
- (void)setInitValue {
    startIndexStr = @"1";
    endIndexStr = @"100";
    widthStr = @"832";
    rotationStr = PDF_ROTATION_NONE;
    bottomMarginStr = @"0";
    ditheringStr = PDF_DITHERING_ERROR_DIFFUSION;

    printPagesSelectedIndex = 0;
    printWidthSelectedIndex = 0;
    printBottomMarginSelectedIndex = 0;
}

- (void)initIndicatorView {
    _indicatorView = [[NSBundle mainBundle] loadNibNamed:@"IndicatorView" owner:self options:nil][0];
    _indicatorView.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
    _indicatorView.hidden = YES;
    [self.view addSubview:_indicatorView];
}

- (void)reloadTableView {
    if (0 < _sectionIndex && _sectionIndex < SIZE_OF_SECTION_TITLE_TABLE) {
        NSString *sectionTitle = SECTION_TITLE_TABLE[_sectionIndex];
        if ([sectionTitle isEqualToString:PDF_ROTATION_SECTION]) {
            for (int i = 0; i < SIZE_OF_PDF_ROTATION_TABLE; i++) {
                if (_viewController.currentValueIndex == i) {
                    rotationStr = PDF_ROTATION_TABLE[i];
                }
            }
        } else if ([sectionTitle isEqualToString:PDF_DITHERING_SECTION]) {
            for (int i = 0; i < SIZE_OF_PDF_DITHERING_TABLE; i++) {
                if (_viewController.currentValueIndex == i) {
                    ditheringStr = PDF_DITHERING_TABLE[i];
                }
            }
        }
    }

    _sectionIndex = -1;
    [self.tableView reloadData];
}

- (void)reloadViewSize {
    _frameWidth = (NSInteger)self.view.bounds.size.width;
    [self.tableView reloadData];
}

- (void)startLoadingView {
    dispatch_async(dispatch_get_main_queue(), ^{
        self->_indicatorView.hidden = NO;
    });
}

- (void)stopLoadingView {
    dispatch_async(dispatch_get_main_queue(), ^{
        self->_indicatorView.hidden = YES;
    });
}

- (void)showMessageBox:(NSString *)title message:(NSString *)message {
    dispatch_async(dispatch_get_main_queue(), ^{
        UIAlertController *alertController =  [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
        [alertController addAction:[UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
        }]];
        [self presentViewController:alertController animated:YES completion:nil];
    });
}

@end
