//
//  PrinterManager.m
//  SIIMpaPrinterSample
//

#import <ExternalAccessory/ExternalAccessory.h>
#import "PrinterManager.h"
#import <SIIMpaPrinterManager/SIIMpaPrinterManager.h>
#import "ValueManager.h"

@implementation PrinterManager

static SIIMpaPrinterManager *_printer;
static SIIMpaPrinterDiscovery *_discover;
static BOOL _threadComletion;
static NSString *_errorCodeText;
static dispatch_queue_t _gcd_printerManager;

#pragma mark - public functions
+ (void)InitialSetting:(FirstViewController *)view {
    _printer = [[SIIMpaPrinterManager alloc] init];
    _discover = [[SIIMpaPrinterDiscovery alloc] init];
    _gcd_printerManager = dispatch_queue_create("com.sii-ps.PrinterManager", DISPATCH_QUEUE_SERIAL);
}

+ (NSArray *)getBluetoothPrinterList {
    NSError *error = nil;
    [_discover startDiscoveryPrinter:nil target:nil prnIf:SII_MPM_PRN_IF_BT retry:1 timeout:3 error:&error];
    NSMutableArray *returnList = [[NSMutableArray alloc] init];
    NSMutableArray *printerList = [[NSMutableArray alloc] init];
    [_discover getFoundPrinter:&printerList error:nil];
    if (printerList != nil && printerList.count > 0) {
        for (int i = 0; i < printerList.count; i++) {
            SIIMpaDiscoveredPrinter *obj = [printerList objectAtIndex:i];
            if ([self isMPA40Printer:obj.printerModel]) {
                [returnList addObject:obj];
            }
        }
    }
    return returnList;
}

+ (void)startDiscoveryTcpPrinter {
    _threadComletion = NO;
    NSError *error = nil;
    PrinterManager *target = [[PrinterManager alloc] init];
    [_discover startDiscoveryPrinter:@selector(onDiscoveryFinished:) target:target prnIf:SII_MPM_PRN_IF_TCP retry:1 timeout:3 error:&error];
}

+ (void)cancelDiscoveryTcpPrinter {
    NSError *error = nil;
    [_discover cancelDiscoveryPrinter:&error];
}

+ (NSArray *)getLanPrinterList {
    NSMutableArray *returnList = [[NSMutableArray alloc] init];
    NSMutableArray *printerList = [[NSMutableArray alloc] init];
    [_discover getFoundPrinter:&printerList error:nil];
    if (printerList != nil && printerList.count > 0) {
        for (int i = 0; i < printerList.count; i++) {
            SIIMpaDiscoveredPrinter *obj = [printerList objectAtIndex:i];
            if ([self isMPA40Printer:obj.printerModel]) {
                [returnList addObject:obj];
            }
        }
    }
    return returnList;
}

+ (BOOL)discoverFinished {
    return _threadComletion;
}

+ (NSString *)getErrorCodeText {
    return _errorCodeText;
}

+ (dispatch_queue_t)getDispatchQueue {
    return _gcd_printerManager;
}

+ (BOOL)startCallBack:(UIViewController *)view sel:(SEL)sel {
    BOOL openResult = [self openPrinter];
    if (openResult == NO) {
        return NO;
    }
    NSError *error = nil;
    BOOL result = [_printer startCallbackFunction:sel target:view error:&error];
    if (result) {
        return YES;
    } else {
        _errorCodeText = [self convertErrorCodeToString:error];
        [_printer close:&error];
        return NO;
    }
}

+ (void)stopCallBack {
    NSError *error = nil;
    [_printer stopCallbackFunction:&error];
    [_printer close:&error];
}

+ (NSString *)getPrinterInformation:(NSString *)key {
    BOOL openResult = [self openPrinter];
    if (openResult == NO) {
        return nil;
    }
    NSError *error = nil;
    NSString *returnValue = nil;
    BOOL result;
    if ([key isEqualToString:KEY_TYPE_NV_MEM_CAP]) {
        NSInteger *value = nil;
        result = [_printer getPrinterInformationNumber:SII_MPM_GET_NV_MEM_CAP printerInfoValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%ld", (long)value];
    } else if  ([key isEqualToString:KEY_TYPE_NV_MEM_REM_CAP]) {
        NSInteger *value = nil;
        result = [_printer getPrinterInformationNumber:SII_MPM_GET_NV_MEM_REM_CAP printerInfoValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%ld", (long)value];
    } else if  ([key isEqualToString:KEY_TYPE_NV_MEM_KEYCODE_LIST]) {
        NSString *value = [NSString new];
        result = [_printer getPrinterInformationString:SII_MPM_GET_NV_MEM_KEYCODE_LIST printerInformationValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%@", value];
    } else if  ([key isEqualToString:KEY_TYPE_REM_USER_MEM_CAP]) {
        NSInteger *value = nil;
        result = [_printer getPrinterInformationNumber:SII_MPM_GET_REM_USER_MEM_CAP printerInfoValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%ld", (long)value];
    } else if  ([key isEqualToString:KEY_TYPE_REM_USER_MEM_CAP_DEFRAG]) {
        NSInteger *value = nil;
        result = [_printer getPrinterInformationNumber:SII_MPM_GET_REM_USER_MEM_CAP_DEFRAG printerInfoValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%ld", (long)value];
    } else if  ([key isEqualToString:KEY_TYPE_FUNC_SET_RESP]) {
        NSData *value = [NSData new];
        result = [_printer getPrinterInformation:SII_MPM_GET_FUNC_SET_RESP printerInformationValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%@", value];
    } else if  ([key isEqualToString:KEY_TYPE_PRN_ID_MODEL]) {
        NSInteger *value = nil;
        result = [_printer getPrinterInformationNumber:SII_MPM_GET_PRN_ID_MODEL printerInfoValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%ld", (long)value];
    } else if  ([key isEqualToString:KEY_TYPE_PRN_ID_TYPE]) {
        NSInteger *value = nil;
        result = [_printer getPrinterInformationNumber:SII_MPM_GET_PRN_ID_TYPE printerInfoValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%ld", (long)value];
    } else if  ([key isEqualToString:KEY_TYPE_PRN_ID_ROM_VER]) {
        NSInteger *value = nil;
        result = [_printer getPrinterInformationNumber:SII_MPM_GET_PRN_ID_ROM_VER printerInfoValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%ld", (long)value];
    } else if  ([key isEqualToString:KEY_TYPE_PRN_ID_FIRM_VER_MAIN]) {
        NSString *value = [NSString new];
        result = [_printer getPrinterInformationString:SII_MPM_GET_PRN_ID_FIRM_VER_MAIN printerInformationValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%@", value];
    } else if  ([key isEqualToString:KEY_TYPE_PRN_ID_MFR]) {
        NSString *value = [NSString new];
        result = [_printer getPrinterInformationString:SII_MPM_GET_PRN_ID_MFR printerInformationValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%@", value];
    } else if  ([key isEqualToString:KEY_TYPE_PRN_ID_MODEL_NAME]) {
        NSString *value = [NSString new];
        result = [_printer getPrinterInformationString:SII_MPM_GET_PRN_ID_MODEL_NAME printerInformationValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%@", value];
    } else if  ([key isEqualToString:KEY_TYPE_PRN_ID_FIRM_VER_BOOT]) {
        NSString *value = [NSString new];
        result = [_printer getPrinterInformationString:SII_MPM_GET_PRN_ID_FIRM_VER_BOOT printerInformationValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%@", value];
    } else if  ([key isEqualToString:KEY_TYPE_PRN_ID_FIRM_CHECKSUM_BOOT]) {
        NSInteger *value = nil;
        result = [_printer getPrinterInformationNumber:SII_MPM_GET_PRN_ID_FIRM_CHECKSUM_BOOT printerInfoValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%ld", (long)value];
    } else if  ([key isEqualToString:KEY_TYPE_PRN_ID_FIRM_CHECKSUM_MAIN]) {
        NSInteger *value = nil;
        result = [_printer getPrinterInformationNumber:SII_MPM_GET_PRN_ID_FIRM_CHECKSUM_MAIN printerInfoValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%ld", (long)value];
    } else if  ([key isEqualToString:KEY_TYPE_PRN_ID_FIRM_CHECKSUM]) {
        NSInteger *value = nil;
        result = [_printer getPrinterInformationNumber:SII_MPM_GET_PRN_ID_FIRM_CHECKSUM printerInfoValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%ld", (long)value];
    } else if  ([key isEqualToString:KEY_TYPE_MAINT_NUM_FEED_LINE]) {
        NSInteger *value = nil;
        result = [_printer getPrinterInformationNumber:SII_MPM_GET_MAINT_NUM_FEED_LINE printerInfoValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%ld", (long)value];
    } else if  ([key isEqualToString:KEY_TYPE_MAINT_NUM_HEAD_ACTIVE]) {
        NSInteger *value = nil;
        result = [_printer getPrinterInformationNumber:SII_MPM_GET_MAINT_NUM_HEAD_ACTIVE printerInfoValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%ld", (long)value];
    } else if  ([key isEqualToString:KEY_TYPE_MAINT_DRIVE_TIME]) {
        NSInteger *value = nil;
        result = [_printer getPrinterInformationNumber:SII_MPM_GET_MAINT_DRIVE_TIME printerInfoValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%ld", (long)value];
    } else if  ([key isEqualToString:KEY_TYPE_MAINT_NUM_FEED_LINE_INTEGRATION]) {
        NSInteger *value = nil;
        result = [_printer getPrinterInformationNumber:SII_MPM_GET_MAINT_NUM_FEED_LINE_INTEGRATION printerInfoValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%ld", (long)value];
    } else if  ([key isEqualToString:KEY_TYPE_MAINT_NUM_HEAD_ACTIVE_INTEGRATION]) {
        NSInteger *value = nil;
        result = [_printer getPrinterInformationNumber:SII_MPM_GET_MAINT_NUM_HEAD_ACTIVE_INTEGRATION printerInfoValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%ld", (long)value];
    } else if  ([key isEqualToString:KEY_TYPE_MAINT_DRIVE_TIME_INTEGRATION]) {
        NSInteger *value = nil;
        result = [_printer getPrinterInformationNumber:SII_MPM_GET_MAINT_DRIVE_TIME_INTEGRATION printerInfoValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%ld", (long)value];
    } else if  ([key isEqualToString:KEY_TYPE_HFONT_24_CHECKSUM]) {
        NSInteger *value = nil;
        result = [_printer getPrinterInformationNumber:SII_MPM_GET_HFONT_24_CHECKSUM printerInfoValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%ld", (long)value];
    } else if  ([key isEqualToString:KEY_TYPE_HFONT_24_ID]) {
        NSString *value = [NSString new];
        result = [_printer getPrinterInformationString:SII_MPM_GET_HFONT_24_ID printerInformationValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%@", value];
    } else if  ([key isEqualToString:KEY_TYPE_HFONT_24_INT_CHAR]) {
        NSString *value = [NSString new];
        result = [_printer getPrinterInformationString:SII_MPM_GET_HFONT_24_INT_CHAR printerInformationValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%@", value];
    } else if  ([key isEqualToString:KEY_TYPE_HFONT_16_CHECKSUM]) {
        NSInteger *value = nil;
        result = [_printer getPrinterInformationNumber:SII_MPM_GET_HFONT_16_CHECKSUM printerInfoValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%ld", (long)value];
    } else if  ([key isEqualToString:KEY_TYPE_HFONT_16_ID]) {
        NSString *value = [NSString new];
        result = [_printer getPrinterInformationString:SII_MPM_GET_HFONT_16_ID printerInformationValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%@", value];
    } else if  ([key isEqualToString:KEY_TYPE_HFONT_16_INT_CHAR]) {
        NSString *value = [NSString new];
        result = [_printer getPrinterInformationString:SII_MPM_GET_HFONT_16_INT_CHAR printerInformationValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%@", value];
    } else if  ([key isEqualToString:KEY_TYPE_FFONT_LANG]) {
        NSString *value = [NSString new];
        result = [_printer getPrinterInformationString:SII_MPM_GET_FFONT_LANG printerInformationValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%@", value];
    } else if  ([key isEqualToString:KEY_TYPE_FFONT_STANDARD]) {
        NSString *value = [NSString new];
        result = [_printer getPrinterInformationString:SII_MPM_GET_FFONT_STANDARD printerInformationValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%@", value];
    } else if  ([key isEqualToString:KEY_TYPE_FFONT_COMPANY]) {
        NSString *value = [NSString new];
        result = [_printer getPrinterInformationString:SII_MPM_GET_FFONT_COMPANY printerInformationValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%@", value];
    } else if  ([key isEqualToString:KEY_TYPE_FFONT_CHECKSUM]) {
        NSInteger *value = nil;
        result = [_printer getPrinterInformationNumber:SII_MPM_GET_FFONT_CHECKSUM printerInfoValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%ld", (long)value];
    } else if  ([key isEqualToString:KEY_TYPE_FFONT_DATA_SIZE]) {
        NSInteger *value = nil;
        result = [_printer getPrinterInformationNumber:SII_MPM_GET_FFONT_DATA_SIZE printerInfoValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%ld", (long)value];
    } else if  ([key isEqualToString:KEY_TYPE_FFONT_ROM_ID]) {
        NSInteger *value = nil;
        result = [_printer getPrinterInformationNumber:SII_MPM_GET_FFONT_ROM_ID printerInfoValue:&value error:&error];
        returnValue = [NSString stringWithFormat:@"%ld", (long)value];
    } else {
        result = NO;
        returnValue = @"";
    }
    if (result == NO) {
        _errorCodeText = [self convertErrorCodeToString:error];
    }
    [_printer close:&error];
    return returnValue;
}

+ (BOOL)printStandardModeReceipt {
    BOOL openResult = [self openPrinter];
    if (openResult == NO) {
        return NO;
    }
    NSError *error = nil;
    BOOL result;
    @try {
        // start standard mode
        result = [_printer selectStandardMode:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer setStandardModeArea:0 printAreaWidth:832 error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer setStandardModeAlignment:SII_MPM_ALIGN_CENTER error:&error];
        if (result == NO) {
            return NO;
        }
        // set line spacing and character spacing
        result = [_printer setLineSpacing:34 error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer setCharacterRightSpace:0 error:&error];
        if (result == NO) {
            return NO;
        }
        // print logo
        NSString *logoPath = [[NSBundle mainBundle] pathForResource:@"ReceiptLogo" ofType:@"jpg"];
        result = [_printer sendDataFile:logoPath dithering:SII_MPM_DITHERING_DISABLE error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer feedLine:2 error:&error];
        if (result == NO) {
            return NO;
        }
        // print date
        result = [_printer setCharacterFormatting:SII_MPM_CHAR_TYPE_FONT_A verticalScale:SII_MPM_CHAR_SCALE_X1 horizontalScale:SII_MPM_CHAR_SCALE_X1 underline:SII_MPM_CHAR_UNDERLINE_NONE bold:SII_MPM_CHAR_BOLD_OFF reverse:SII_MPM_CHAR_REVERSE_OFF rotate:SII_MPM_ROTATE_NONE error:&error];
        if (result == NO) {
            return NO;
        }
        NSDate *now = [NSDate date];
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm";
        NSString *time = [dateFormatter stringFromDate:now];
        NSString *receiptTime = [NSString stringWithFormat:@"%@%@\n", @"No.123456789   ", time];
        result = [_printer printText:receiptTime error:&error];
        if (result == NO) {
            return NO;
        }
        // print receipt contents
        NSMutableString *receiptContent = [NSMutableString stringWithCapacity:10];
        [receiptContent appendString:@"--------------------------------\n"];
        [receiptContent appendString:@"GRILLED CHICKEN BREAST   $ 18.50\n"];
        [receiptContent appendString:@"SIRLOIN STEAK            $ 32.00\n"];
        [receiptContent appendString:@"ROAST LAMB               $ 20.00\n"];
        [receiptContent appendString:@"SALAD                    $ 10.00\n"];
        [receiptContent appendString:@"COKE                     $  3.50\n"];
        [receiptContent appendString:@"ICE CREAM                $  5.00\n"];
        [receiptContent appendString:@"CHINESE NOODLE           $ 15.00\n"];
        [receiptContent appendString:@"SUKIYAKI                 $ 30.00\n"];
        [receiptContent appendString:@"SANDWICH                 $ 10.00\n"];
        [receiptContent appendString:@"PIZZA                    $ 20.00\n"];
        [receiptContent appendString:@"TEA                      $  3.50\n"];
        [receiptContent appendString:@"COFFEE                   $  3.50\n"];
        [receiptContent appendString:@"\n"];
        [receiptContent appendString:@"--------------------------------\n"];
        [receiptContent appendString:@"        SUBTOTAL        $ 174.50\n"];
        [receiptContent appendString:@"        SALES TAX       $   8.73\n"];
        [receiptContent appendString:@"        TOTAL           $ 183.23\n"];
        [receiptContent appendString:@"\n"];
        [receiptContent appendString:@"Thank you and see you again!\n"];
        result = [_printer printText:receiptContent error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer feedLine:2 error:&error];
        if (result == NO) {
            return NO;
        }
        // print barcode
        result = [_printer printBarcode:SII_MPM_TYPE_BARCODE_UPC_A text:@"12345678905"  moduleWidth:SII_MPM_MODULE_WIDTH_BARCODE_3 moduleHeight:162 hri:SII_MPM_HRI_BARCODE_BOTTOM_FONT_A nwRatio:SII_MPM_NWRATIO_BARCODE_1TO2 error:&error];
        if (result == NO) {
            return NO;
        }
        // print two dimendion barcode
        result = [_printer print2DCode:SII_MPM_TYPE_2DCODE_PDF417 text:@"ABC0123" mode:SII_MPM_MODE_2DCODE_PDF417_STANDARD moduleSize:SII_MPM_MODULE_SIZE_2DCODE_3 moduleHeight:10 column:0 row:0 errorCorrect:SII_MPM_ERR_CORRECTION_2DCODE_PDF417_0 error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer feedCutPosition:&error];
        return YES;
    }
    @finally {
        if (result == NO) {
            _errorCodeText = [self convertErrorCodeToString:error];
        }
        [_printer close:&error];
    }
}

+ (BOOL)printPageModeReceipt {
    BOOL openResult = [self openPrinter];
    if (openResult == NO) {
        return NO;
    }
    static int RECEIPT_WIDTH = 576;
    static int RECEIPT_HEIGHT = 1400;
    static int FONT_WIDTH = 12;
    static int FONT_HEIGHT = 24;
    static int LOGO_WIDTH = 384;
    static int LOGO_HEIGHT = 48;
    static int LINE_SPACE = 34;
    NSError *error = nil;
    BOOL result;
    @try {
        // draw outline
        result = [_printer selectPageMode:0 startY:0 width:RECEIPT_WIDTH height:RECEIPT_HEIGHT direction:SII_MPM_DIRECTION_LEFT_TO_RIGHT error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer printPageModeRectangle:0 startY:0 width:RECEIPT_WIDTH height:RECEIPT_HEIGHT thickness:2 error:&error];
        if (result == NO) {
            return NO;
        }
        // set line spacing and character spacing
        result = [_printer setLineSpacing:LINE_SPACE error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer setCharacterRightSpace:0 error:&error];
        if (result == NO) {
            return NO;
        }
        // draw logo
        NSInteger startX = (int)(RECEIPT_WIDTH - LOGO_WIDTH) / 2;
        NSInteger startY = 80;
        NSInteger height = LOGO_HEIGHT;
        result = [_printer selectPageMode:startX startY:startY width:RECEIPT_WIDTH - startX height:height direction:SII_MPM_DIRECTION_LEFT_TO_RIGHT error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer setPageModeVerticalPosition:0 error:&error];
        if (result == NO) {
            return NO;
        }
        NSString *logoPath = [[NSBundle mainBundle] pathForResource:@"ReceiptLogo" ofType:@"jpg"];
        result = [_printer sendDataFile:logoPath dithering:SII_MPM_DITHERING_DISABLE error:&error];
        if (result == NO) {
            return NO;
        }
        // draw date
        NSDate *now = [NSDate date];
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm";
        NSString *time = [dateFormatter stringFromDate:now];
        NSString *receiptTime = [NSString stringWithFormat:@"%@%@\n", @"No.123456789   ", time];
        startX = (int)(RECEIPT_WIDTH - ((FONT_WIDTH + 0) * receiptTime.length)) / 2;
        startY = startY + height + 80;
        height = FONT_HEIGHT;
        result = [_printer selectPageMode:startX startY:startY width:RECEIPT_WIDTH - startX height:height direction:SII_MPM_DIRECTION_LEFT_TO_RIGHT error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer setPageModeVerticalPosition:height error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer setCharacterFormatting:SII_MPM_CHAR_TYPE_FONT_A verticalScale:SII_MPM_CHAR_SCALE_X1 horizontalScale:SII_MPM_CHAR_SCALE_X1 underline:SII_MPM_CHAR_UNDERLINE_NONE bold:SII_MPM_CHAR_BOLD_OFF reverse:SII_MPM_CHAR_REVERSE_OFF rotate:SII_MPM_ROTATE_NONE error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer printText:receiptTime error:&error];
        if (result == NO) {
            return NO;
        }
        // draw receipt contents
        NSString *dummy = @"--------------------------------\n";
        startX = (int)(RECEIPT_WIDTH - ((FONT_WIDTH + 0) * dummy.length)) / 2;
        startY = startY + height + 40;
        height = LINE_SPACE * 21;
        result = [_printer selectPageMode:startX startY:startY width:RECEIPT_WIDTH - startX height:height direction:SII_MPM_DIRECTION_LEFT_TO_RIGHT error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer setPageModeVerticalPosition:FONT_HEIGHT error:&error];
        if (result == NO) {
            return NO;
        }
        NSMutableString *receiptContent = [NSMutableString stringWithCapacity:10];
        [receiptContent appendString:@"--------------------------------\n"];
        [receiptContent appendString:@"GRILLED CHICKEN BREAST   $ 18.50\n"];
        [receiptContent appendString:@"SIRLOIN STEAK            $ 32.00\n"];
        [receiptContent appendString:@"ROAST LAMB               $ 20.00\n"];
        [receiptContent appendString:@"SALAD                    $ 10.00\n"];
        [receiptContent appendString:@"COKE                     $  3.50\n"];
        [receiptContent appendString:@"COKE                     $  3.50\n"];
        [receiptContent appendString:@"ICE CREAM                $  5.00\n"];
        [receiptContent appendString:@"CHINESE NOODLE           $ 15.00\n"];
        [receiptContent appendString:@"SUKIYAKI                 $ 30.00\n"];
        [receiptContent appendString:@"SANDWICH                 $ 10.00\n"];
        [receiptContent appendString:@"PIZZA                    $ 20.00\n"];
        [receiptContent appendString:@"TEA                      $  3.50\n"];
        [receiptContent appendString:@"COFFEE                   $  3.50\n"];
        [receiptContent appendString:@"\n"];
        [receiptContent appendString:@"--------------------------------\n"];
        [receiptContent appendString:@"        SUBTOTAL        $ 174.50\n"];
        [receiptContent appendString:@"        SALES TAX       $   8.73\n"];
        [receiptContent appendString:@"        TOTAL           $ 183.23\n"];
        [receiptContent appendString:@"\n"];
        [receiptContent appendString:@"Thank you and see you again!\n"];
        result = [_printer printText:receiptContent error:&error];
        if (result == NO) {
            return NO;
        }
        // draw barcode
        startX = 100;
        startY = startY + height + 40;
        height = 200;
        result = [_printer selectPageMode:startX startY:startY width:RECEIPT_WIDTH - startX height:height direction:SII_MPM_DIRECTION_LEFT_TO_RIGHT error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer setPageModeVerticalPosition:162 error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer printBarcode:SII_MPM_TYPE_BARCODE_UPC_A text:@"12345678905"  moduleWidth:SII_MPM_MODULE_WIDTH_BARCODE_3 moduleHeight:162 hri:SII_MPM_HRI_BARCODE_BOTTOM_FONT_A nwRatio:SII_MPM_NWRATIO_BARCODE_1TO2 error:&error];
        if (result == NO) {
            return NO;
        }
        // draw two dimendion barcode
        startX = 150;
        startY = startY + height + 40;
        height = 100;
        result = [_printer selectPageMode:startX startY:startY width:RECEIPT_WIDTH - startX height:height direction:SII_MPM_DIRECTION_LEFT_TO_RIGHT error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer setPageModeVerticalPosition:height error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer print2DCode:SII_MPM_TYPE_2DCODE_PDF417 text:@"ABC0123" mode:SII_MPM_MODE_2DCODE_PDF417_STANDARD moduleSize:SII_MPM_MODULE_SIZE_2DCODE_3 moduleHeight:10 column:0 row:0 errorCorrect:SII_MPM_ERR_CORRECTION_2DCODE_PDF417_0 error:&error];
        if (result == NO) {
            return NO;
        }
        // output to printer
        result = [_printer printPageModeData:&error];
        if (result == NO) {
            return NO;
        }
        // exit pagemode
        result = [_printer selectStandardMode:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer feedCutPosition:&error];
        return YES;
    }
    @finally {
        if (result == NO) {
            _errorCodeText = [self convertErrorCodeToString:error];
        }
        [_printer close:&error];
    }
}

+ (BOOL)printText:(NSString *)text font:(NSInteger)font scale:(NSInteger)scale underline:(NSInteger)underline bold:(NSInteger)bold reverse:(NSInteger)reverse rotate:(NSInteger)rotate {
    BOOL openResult = [self openPrinter];
    if (openResult == NO) {
        return NO;
    }
    NSError *error = nil;
    BOOL result;
    @try {
        result = [_printer setStandardModeAlignment:SII_MPM_ALIGN_LEFT error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer setCharacterFormatting:font verticalScale:scale horizontalScale:scale underline:underline bold:bold reverse:reverse rotate:rotate error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer printText:text error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer feedDotLine:0 error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer feedCutPosition:&error];
        return YES;
    }
    @finally {
        if (result == NO) {
            _errorCodeText = [self convertErrorCodeToString:error];
        }
        [_printer close:&error];
    }
}

+ (BOOL)sendDataFile:(NSString *)filePath dithering:(NSInteger)dithering {
    BOOL openResult = [self openPrinter];
    if (openResult == NO) {
        return NO;
    }
    NSError *error = nil;
    BOOL result;
    @try {
        result = [_printer setStandardModeAlignment:SII_MPM_ALIGN_LEFT error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer sendDataFile:filePath dithering:dithering error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer feedCutPosition:&error];
        return YES;
    }
    @finally {
        if (result == NO) {
            _errorCodeText = [self convertErrorCodeToString:error];
        }
        [_printer close:&error];
    }
}

+ (BOOL)printPDF:(NSString *)filePath startIndex:(NSInteger)startIndex endIndex:(NSInteger)endIndex rotate:(Rotate)rotate width:(NSInteger)width bottomMargin:(NSInteger)bottomMargin dithering:(Dithering)dithering {
    BOOL openResult = [self openPrinter];
    if (openResult == NO) {
        return NO;
    }
    NSError *error = nil;
    BOOL result;
    @try {
        result = [_printer setStandardModeAlignment:SII_MPM_ALIGN_LEFT error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer printPDF:filePath startIndex:startIndex endIndex:endIndex rotate:rotate width:width bottomMargin:bottomMargin dithering:dithering error:&error];
        if (result == NO) {
            return NO;
        }
        return YES;
    }
    @finally {
        if (result == NO) {
            _errorCodeText = [self convertErrorCodeToString:error];
        }
        [_printer close:&error];
    }
}
+ (BOOL)printBarcode:(NSInteger)type text:(NSString *)text width:(NSInteger)width height:(NSInteger)height hri:(NSInteger)hri nwRatio:(NSInteger)nwRatio {
    BOOL openResult = [self openPrinter];
    if (openResult == NO) {
        return NO;
    }
    NSError *error = nil;
    BOOL result;
    NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding];
    @try {
        result = [_printer setStandardModeAlignment:SII_MPM_ALIGN_LEFT error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer printBarcode:type binary:data moduleWidth:width moduleHeight:height hri:hri nwRatio:nwRatio error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer feedCutPosition:&error];
        return YES;
    }
    @finally {
        if (result == NO) {
            _errorCodeText = [self convertErrorCodeToString:error];
        }
        [_printer close:&error];
    }
}

+ (BOOL)print2DCode:(NSInteger)type text:(NSString *)text mode:(NSInteger)mode moduleSize:(NSInteger)moduleSize moduleHeight:(NSInteger)moduleHeight column:(NSInteger)column row:(NSInteger)row errorCorrect:(NSInteger)errorCorrect {
    BOOL openResult = [self openPrinter];
    if (openResult == NO) {
        return NO;
    }
    NSError *error = nil;
    BOOL result;
    NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding];
    @try {
        result = [_printer setStandardModeAlignment:SII_MPM_ALIGN_LEFT error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer print2DCode:type binary:data mode:mode moduleSize:moduleSize moduleHeight:moduleHeight column:column row:row errorCorrect:errorCorrect error:&error];
        if (result == NO) {
            return NO;
        }
        result = [_printer feedCutPosition:&error];
        return YES;
    }
    @finally {
        if (result == NO) {
            _errorCodeText = [self convertErrorCodeToString:error];
        }
        [_printer close:&error];
    }
}

+ (NSString *)getVersion {
    return [_printer getVersion];
}

+ (NSString *)getWriteTimeout {
    NSInteger value = [_printer getWriteTimeout];
    return [NSString stringWithFormat:@"%ld", (long)value];
}

+ (NSString *)getResponseTimeout {
    NSInteger value = [_printer getResponseTimeout];
    return [NSString stringWithFormat:@"%ld", (long)value];
}

+ (NSString *)getCodePage {
    NSInteger value = [_printer getCharacterSet];
    if (value == SII_MPM_CODEPAGE_437) {
        return SETTINGS_CODEPAGE_437;
    } else if (value == SII_MPM_CODEPAGE_KATAKANA) {
        return SETTINGS_CODEPAGE_KATAKANA;
    } else if (value == SII_MPM_CODEPAGE_850) {
        return SETTINGS_CODEPAGE_850;
    } else if (value == SII_MPM_CODEPAGE_860) {
        return SETTINGS_CODEPAGE_860;
    } else if (value == SII_MPM_CODEPAGE_863) {
        return SETTINGS_CODEPAGE_863;
    } else if (value == SII_MPM_CODEPAGE_865) {
        return SETTINGS_CODEPAGE_865;
    } else if (value == SII_MPM_CODEPAGE_857) {
        return SETTINGS_CODEPAGE_857;
    } else if (value == SII_MPM_CODEPAGE_737) {
        return SETTINGS_CODEPAGE_737;
    } else if (value == SII_MPM_CODEPAGE_1252) {
        return SETTINGS_CODEPAGE_1252;
    } else if (value == SII_MPM_CODEPAGE_866) {
        return SETTINGS_CODEPAGE_866;
    } else if (value == SII_MPM_CODEPAGE_852) {
        return SETTINGS_CODEPAGE_852;
    } else if (value == SII_MPM_CODEPAGE_858) {
        return SETTINGS_CODEPAGE_858;
    } else if (value == SII_MPM_CODEPAGE_855) {
        return SETTINGS_CODEPAGE_855;
    } else if (value == SII_MPM_CODEPAGE_864) {
        return SETTINGS_CODEPAGE_864;
    } else if (value == SII_MPM_CODEPAGE_1250) {
        return SETTINGS_CODEPAGE_1250;
    } else if (value == SII_MPM_CODEPAGE_1251) {
        return SETTINGS_CODEPAGE_1251;
    } else if (value == SII_MPM_CODEPAGE_1253) {
        return SETTINGS_CODEPAGE_1253;
    } else if (value == SII_MPM_CODEPAGE_1254) {
        return SETTINGS_CODEPAGE_1254;
    } else {
        return @"Unknown";
    }
}

+ (NSString *)getInternationalCharacter {
    NSInteger value = [_printer getInternationalCharacterSet];
    if (value == SII_MPM_INT_CHAR_SET_USA) {
        return SETTINGS_INTERNATIONAL_CHARACTER_USA;
    } else if (value == SII_MPM_INT_CHAR_SET_FRANCE) {
        return SETTINGS_INTERNATIONAL_CHARACTER_FRANCE;
    } else if (value == SII_MPM_INT_CHAR_SET_GERMANY) {
        return SETTINGS_INTERNATIONAL_CHARACTER_GERMANY;
    } else if (value == SII_MPM_INT_CHAR_SET_UNITED_KINGDOM) {
        return SETTINGS_INTERNATIONAL_CHARACTER_UNITED_KINGDOM;
    } else if (value == SII_MPM_INT_CHAR_SET_DENMARK_1) {
        return SETTINGS_INTERNATIONAL_CHARACTER_DENMARK_1;
    } else if (value == SII_MPM_INT_CHAR_SET_SWEDEN) {
        return SETTINGS_INTERNATIONAL_CHARACTER_SWEDEN;
    } else if (value == SII_MPM_INT_CHAR_SET_ITALY) {
        return SETTINGS_INTERNATIONAL_CHARACTER_ITALY;
    } else if (value == SII_MPM_INT_CHAR_SET_SPAIN_1) {
        return SETTINGS_INTERNATIONAL_CHARACTER_SPAIN_1;
    } else if (value == SII_MPM_INT_CHAR_SET_JAPAN) {
        return SETTINGS_INTERNATIONAL_CHARACTER_JAPAN;
    } else if (value == SII_MPM_INT_CHAR_SET_NORWAY) {
        return SETTINGS_INTERNATIONAL_CHARACTER_NORWAY;
    } else if (value == SII_MPM_INT_CHAR_SET_DENMARK_2) {
        return SETTINGS_INTERNATIONAL_CHARACTER_DENMARK_2;
    } else if (value == SII_MPM_INT_CHAR_SET_SPAIN_2) {
        return SETTINGS_INTERNATIONAL_CHARACTER_SPAIN_2;
    } else if (value == SII_MPM_INT_CHAR_SET_LATIN_AMERICA) {
        return SETTINGS_INTERNATIONAL_CHARACTER_LATIN_AMERICA;
    } else if (value == SII_MPM_INT_CHAR_SET_ARABIA) {
        return SETTINGS_INTERNATIONAL_CHARACTER_ARABIA;
    } else {
        return @"Unknown";
    }
}

+ (void)setWriteTimeout:(NSString *)value {
    [_printer setWriteTimeout:[value intValue]];
}

+ (void)setResponseTimeout:(NSString *)value {
    [_printer setResponseTimeout:[value intValue]];
}

+ (void)setCodePage:(NSString *)value {
    NSError *error = nil;
    if ([value isEqualToString:SETTINGS_CODEPAGE_437]) {
        [_printer selectCharacterSet:SII_MPM_CODEPAGE_437 error:&error];
    } else if ([value isEqualToString:SETTINGS_CODEPAGE_KATAKANA]) {
        [_printer selectCharacterSet:SII_MPM_CODEPAGE_KATAKANA error:&error];
    } else if ([value isEqualToString:SETTINGS_CODEPAGE_850]) {
        [_printer selectCharacterSet:SII_MPM_CODEPAGE_850 error:&error];
    } else if ([value isEqualToString:SETTINGS_CODEPAGE_860]) {
        [_printer selectCharacterSet:SII_MPM_CODEPAGE_860 error:&error];
    } else if ([value isEqualToString:SETTINGS_CODEPAGE_863]) {
        [_printer selectCharacterSet:SII_MPM_CODEPAGE_863 error:&error];
    } else if ([value isEqualToString:SETTINGS_CODEPAGE_865]) {
        [_printer selectCharacterSet:SII_MPM_CODEPAGE_865 error:&error];
    } else if ([value isEqualToString:SETTINGS_CODEPAGE_857]) {
        [_printer selectCharacterSet:SII_MPM_CODEPAGE_857 error:&error];
    } else if ([value isEqualToString:SETTINGS_CODEPAGE_737]) {
        [_printer selectCharacterSet:SII_MPM_CODEPAGE_737 error:&error];
    } else if ([value isEqualToString:SETTINGS_CODEPAGE_1252]) {
        [_printer selectCharacterSet:SII_MPM_CODEPAGE_1252 error:&error];
    } else if ([value isEqualToString:SETTINGS_CODEPAGE_866]) {
        [_printer selectCharacterSet:SII_MPM_CODEPAGE_866 error:&error];
    } else if ([value isEqualToString:SETTINGS_CODEPAGE_852]) {
        [_printer selectCharacterSet:SII_MPM_CODEPAGE_852 error:&error];
    } else if ([value isEqualToString:SETTINGS_CODEPAGE_858]) {
        [_printer selectCharacterSet:SII_MPM_CODEPAGE_858 error:&error];
    } else if ([value isEqualToString:SETTINGS_CODEPAGE_855]) {
        [_printer selectCharacterSet:SII_MPM_CODEPAGE_855 error:&error];
    } else if ([value isEqualToString:SETTINGS_CODEPAGE_864]) {
        [_printer selectCharacterSet:SII_MPM_CODEPAGE_864 error:&error];
    } else if ([value isEqualToString:SETTINGS_CODEPAGE_1250]) {
        [_printer selectCharacterSet:SII_MPM_CODEPAGE_1250 error:&error];
    } else if ([value isEqualToString:SETTINGS_CODEPAGE_1251]) {
        [_printer selectCharacterSet:SII_MPM_CODEPAGE_1251 error:&error];
    } else if ([value isEqualToString:SETTINGS_CODEPAGE_1253]) {
        [_printer selectCharacterSet:SII_MPM_CODEPAGE_1253 error:&error];
    } else if ([value isEqualToString:SETTINGS_CODEPAGE_1254]) {
        [_printer selectCharacterSet:SII_MPM_CODEPAGE_1254 error:&error];
    }
}

+ (void)setInternationalCharacter:(NSString *)value {
    NSError *error = nil;
    if ([value isEqualToString:SETTINGS_INTERNATIONAL_CHARACTER_USA]) {
        [_printer selectInternationalCharacterSet:SII_MPM_INT_CHAR_SET_USA error:&error];
    } else if ([value isEqualToString:SETTINGS_INTERNATIONAL_CHARACTER_FRANCE]) {
        [_printer selectInternationalCharacterSet:SII_MPM_INT_CHAR_SET_FRANCE error:&error];
    } else if ([value isEqualToString:SETTINGS_INTERNATIONAL_CHARACTER_GERMANY]) {
        [_printer selectInternationalCharacterSet:SII_MPM_INT_CHAR_SET_GERMANY error:&error];
    } else if ([value isEqualToString:SETTINGS_INTERNATIONAL_CHARACTER_UNITED_KINGDOM]) {
        [_printer selectInternationalCharacterSet:SII_MPM_INT_CHAR_SET_UNITED_KINGDOM error:&error];
    } else if ([value isEqualToString:SETTINGS_INTERNATIONAL_CHARACTER_DENMARK_1]) {
        [_printer selectInternationalCharacterSet:SII_MPM_INT_CHAR_SET_DENMARK_1 error:&error];
    } else if ([value isEqualToString:SETTINGS_INTERNATIONAL_CHARACTER_SWEDEN]) {
        [_printer selectInternationalCharacterSet:SII_MPM_INT_CHAR_SET_SWEDEN error:&error];
    } else if ([value isEqualToString:SETTINGS_INTERNATIONAL_CHARACTER_ITALY]) {
        [_printer selectInternationalCharacterSet:SII_MPM_INT_CHAR_SET_ITALY error:&error];
    } else if ([value isEqualToString:SETTINGS_INTERNATIONAL_CHARACTER_SPAIN_1]) {
        [_printer selectInternationalCharacterSet:SII_MPM_INT_CHAR_SET_SPAIN_1 error:&error];
    } else if ([value isEqualToString:SETTINGS_INTERNATIONAL_CHARACTER_JAPAN]) {
        [_printer selectInternationalCharacterSet:SII_MPM_INT_CHAR_SET_JAPAN error:&error];
    } else if ([value isEqualToString:SETTINGS_INTERNATIONAL_CHARACTER_NORWAY]) {
        [_printer selectInternationalCharacterSet:SII_MPM_INT_CHAR_SET_NORWAY error:&error];
    } else if ([value isEqualToString:SETTINGS_INTERNATIONAL_CHARACTER_DENMARK_2]) {
        [_printer selectInternationalCharacterSet:SII_MPM_INT_CHAR_SET_DENMARK_2 error:&error];
    } else if ([value isEqualToString:SETTINGS_INTERNATIONAL_CHARACTER_SPAIN_2]) {
        [_printer selectInternationalCharacterSet:SII_MPM_INT_CHAR_SET_SPAIN_2 error:&error];
    } else if ([value isEqualToString:SETTINGS_INTERNATIONAL_CHARACTER_LATIN_AMERICA]) {
        [_printer selectInternationalCharacterSet:SII_MPM_INT_CHAR_SET_LATIN_AMERICA error:&error];
    } else if ([value isEqualToString:SETTINGS_INTERNATIONAL_CHARACTER_ARABIA]) {
        [_printer selectInternationalCharacterSet:SII_MPM_INT_CHAR_SET_ARABIA error:&error];
    }
}

+ (void)setLogFileSize:(NSString *)value {
    NSError *error = nil;
    if ([value isEqualToString:SETTINGS_LOG_FILE_SIZE_1M]) {
        [_printer setLog:0 logFileSize:SII_MPM_LOG_FILE_SIZE_1MB error:&error];
    } else if ([value isEqualToString:SETTINGS_LOG_FILE_SIZE_5M]) {
        [_printer setLog:0 logFileSize:SII_MPM_LOG_FILE_SIZE_5MB error:&error];
    } else if ([value isEqualToString:SETTINGS_LOG_FILE_SIZE_10M]) {
        [_printer setLog:0 logFileSize:SII_MPM_LOG_FILE_SIZE_10MB error:&error];
    } else if ([value isEqualToString:SETTINGS_LOG_FILE_SIZE_50M]) {
        [_printer setLog:0 logFileSize:SII_MPM_LOG_FILE_SIZE_50MB error:&error];
    }
}

#pragma mark - private functions
- (void)onDiscoveryFinished:(NSNumber *)event {
    _threadComletion = YES;
}

+ (BOOL)isMPA40Printer:(NSString *)name {
    if ([name rangeOfString:@"MP-A40"].location != NSNotFound) {
        return YES;
    } else {
        return NO;
    }
}

+ (NSString *)convertErrorCodeToString:(NSError *)error {
    enum ErrorCode errorCode = (NSInteger)[error code];
    NSString *errorCodeText = @"";
    switch(errorCode){
        case SII_MPM_SUCCESS:
            errorCodeText = @"SUCCESS";
            break;
        case SII_MPM_ERR_PARAM:
            errorCodeText = @"ERR_PARAM";
            break;
        case SII_MPM_ERR_OPENED:
            errorCodeText = @"ERR_OPENED";
            break;
        case SII_MPM_ERR_TIMEOUT:
            errorCodeText = @"ERR_TIMEOUT";
            break;
        case SII_MPM_ERR_NOT_OPENED:
            errorCodeText = @"ERR_NOT_OPENED";
            break;
        case SII_MPM_ERR_OFFLINE:
            errorCodeText = @"ERR_OFFLINE";
            break;
        case SII_MPM_ERR_CLOSE_FAIL:
            errorCodeText = @"ERR_CLOSE_FAIL";
            break;
        case SII_MPM_ERR_NOT_MONITORING:
            errorCodeText = @"ERR_NOT_MONITORING";
            break;
        case SII_MPM_ERR_INIT_FAILED:
            errorCodeText = @"ERR_INIT_FAILED";
            break;
        case SII_MPM_ERR_DATA_SIZE_ZERO:
            errorCodeText = @"ERR_DATA_SIZE_ZERO";
            break;
        case SII_MPM_ERR_OVER_MAX_DATA_SIZE:
            errorCodeText = @"ERR_OVER_MAX_DATA_SIZE";
            break;
        case SII_MPM_ERR_INVALID_DATA:
            errorCodeText = @"ERR_INVALID_DATA";
            break;
        case SII_MPM_ERR_INVALID_STATE:
            errorCodeText = @"ERR_INVALID_STATE";
            break;
        case SII_MPM_ERR_ACCESS:
            errorCodeText = @"ERR_ACCESS";
            break;
        case SII_MPM_ERR_CANCELED:
            errorCodeText = @"ERR_CANCELED";
            break;
        case SII_MPM_ERR_WRITE_FAULT:
            errorCodeText = @"ERR_WRITE_FAULT";
            break;
        case SII_MPM_ERR_FILE_INVALID:
            errorCodeText = @"ERR_FILE_INVALID";
            break;
        case SII_MPM_ERR_ENCODE_FAILED:
            errorCodeText = @"ERR_ENCODE_FAILED";
            break;
        case SII_MPM_ERR_NOT_FOUND:
            errorCodeText = @"ERR_NOT_FOUND";
            break;
        case SII_MPM_ERR_TRANSACTION_STOPPED:
            errorCodeText = @"ERR_TRANSACTION_STOPPED";
            break;
        case SII_MPM_ERR_PRINTER_STATUS_ERROR:
            errorCodeText = @"ERR_PRINTER_STATUS_ERROR";
            break;
        default:
            errorCodeText = @"unexpected error";
            break;
    }
    return errorCodeText;
}

+ (BOOL)openPrinter {
    NSError *error = nil;
    NSInteger portType = [self getPortType];
    NSInteger printerModel = [self getPrinterModel];
    NSString *address = [ValueManager getCurrentStringValue:KEY_TYPE_ADDRESS];
    NSInteger socketKeepingTime = [ValueManager getCurrentStringValue:KEY_TYPE_SOCKET_KEEP_TIME].integerValue;
    BOOL result = [_printer open:portType printerModel:printerModel address:address socketKeepingTime:socketKeepingTime error:&error];
    if (result) {
        return YES;
    } else {
        _errorCodeText = [self convertErrorCodeToString:error];
        return NO;
    }
}

+ (NSInteger)getPortType {
    if ([[ValueManager getCurrentStringValue:KEY_TYPE_PORTTYPE] isEqualToString:PORTTYPE_TCP_IP]) {
        return SII_MPM_PRN_IF_TCP;
    } else if ([[ValueManager getCurrentStringValue:KEY_TYPE_PORTTYPE] isEqualToString:PORTTYPE_BLUETOOTH]) {
        return SII_MPM_PRN_IF_BT;
    } else {
        return -1;
    }
}

+ (NSInteger)getPrinterModel {
    if ([[ValueManager getCurrentStringValue:KEY_TYPE_PRINTERMODEL] rangeOfString:@"MP-A40"].location != NSNotFound) {
        return SII_MPM_PRN_MODEL_MP_A40;
    } else {
        return -1;
    }
}

@end
