/**
 * @file    TepraPrint.h
 * @brief   TEPRA-Print SDK TepraPrint Class definition
 * @par     Copyright:
 * Copyright 2013-2019 KING JIM CO.,LTD.<BR>
 */

#import <Foundation/Foundation.h>

typedef NS_ENUM(NSInteger, TepraPrintTapeOperation) {
	TapeOperationFeed = 0,
	TapeOperationFeedAndCut = -1
};

typedef NS_ENUM(NSInteger, TepraPrintTapeWidth) {
	TapeWidthNone = 0,
	TapeWidth4mm = 1,
	TapeWidth6mm = 2,
	TapeWidth9mm = 3,
	TapeWidth12mm = 4,
	TapeWidth18mm = 5,
	TapeWidth24mm = 6,
	TapeWidth36mm = 7,
	TapeWidth24mmCable = 8,
	TapeWidth36mmCable = 9,
	TapeWidth50mm = 10,
	TapeWidth100mm = 11,
    TapeWidth50mmNew = 12,
    TapeWidthUnknown = -1
};


typedef NS_ENUM(NSInteger, TepraPrintTapeKind) {
    TapeKindNormal = 0,
    TapeKindTransfer = 1,
    TapeKindCable = 16,
    TapeKindIndex = 17,
    TapeKindBraille = 64,
    TapeKindOlefin = 80,
    TapeKindThermalPaper = 81,
    TapeKindTube = 82,
    TapeKindPET = 83,
    TapeKindDieCut1 = 84,
    TapeKindDieCut2 = 85,
    TapeKindDieCut3 = 86,
    TapeKindDieCut4 = 87,
    TapeKindDieCut5 = 88,
    TapeKindWideReserved1 = 89,
    TapeKindWideReserved2 = 90,
    TapeKindWideReserved3 = 91,
    TapeKindWideReserved4 = 92,
    TapeKindWideReserved5 = 93,
    TapeKindWideReserved6 = 94,
    TapeKindWideReserved7 = 95,
    TapeKindDieCutCircle = 96,
    TapeKindDieCutEllipse = 97,
    TapeKindDieCutRoundedCorners = 98,
    TapeKindDieCutReserved1 = 99,
    TapeKindDieCutReserved2 = 100,
    TapeKindDieCutReserved3 = 101,
    TapeKindDieCutReserved4 = 102,
    TapeKindDieCutReserved5 = 103,
    TapeKindDieCutReserved6 = 104,
    TapeKindDieCutReserved7 = 105,
    TapeKindDieCutReserved8 = 106,
    TapeKindDieCutReserved9 = 107,
    TapeKindDieCutReserved10 = 108,
    TapeKindDieCutReserved11 = 109,
    TapeKindDieCutReserved12 = 110,
    TapeKindDieCutReserved13 = 111,
    TapeKindHST = 112,
    TapeKindVinyl = 128,
    TapeKindCleaning = 144,
    TapeKindEquipmentManagement = 145,
    TapeKindRibbon = 146,
    TapeKindMagnet = 147,
    TapeKindLuminousLight = 148,
    TapeKindHighQualityPaper = 149,
    TapeKindIron = 150,
    TapeKindBigrollDieCut = 151,
    BrTapeKindPET = 201,
    BrTapeKindVinyl = 202,
    BrTapeKindHST = 203,
    BrTapeKindSelfLam = 204,
    BrTapeKindDieCutSelfLam1 = 210,
    BrTapeKindDieCutSelfLam2 = 211,
    BrTapeKindDieCutSelfLam3 = 212,
    BrTapeKindDieCutSelfLam4 = 213,
    TapeKindUnknown = -1
};

typedef NS_ENUM(NSInteger, TepraPrintPrintingPhase) {
	PrintingPhasePrepare = 1,
	PrintingPhaseProcessing = 2,
    PrintingPhaseWaitingForPrint = 3,
	PrintingPhaseComplete = 4
};

typedef NS_ENUM(NSInteger, TepraPrintConnectionStatus) {
    ConnectionStatusNoError = 0,
    ConnectionStatusConnectionFailed = -1,     /* Connection failed */
    ConnectionStatusDisconnected = -2,         /* Disconnect */
    ConnectionStatusDeviceBusy = -3,           /* Printer busy */
    ConnectionStatusOutOfMemory = -4,          /* Out of memory */
    ConnectionStatusDeviceError = -5,          /* Device error */
    ConnectionStatusCommunicationError = -6,   /* Communication error */
    ConnectionStatusOtherUsing = -1000         /* Other Using error */
};

typedef NS_ENUM(NSUInteger, TepraPrintStatusError) {
	StatusErrorNoError = 0x00,
	StatusErrorCutterError = 0x01,
	StatusErrorNoTapeCartridge = 0x06,
	StatusErrorHeadOverheated = 0x15,
	StatusErrorPrinterCancel = 0x20,
	StatusErrorCoverOpen = 0x21,
	StatusErrorLowVoltage = 0x22,
	StatusErrorPowerOffCancel = 0x23,
    StatusErrorTapeEjectError = 0x24,
	StatusErrorTapeFeedError = 0x30,
	StatusErrorInkRibbonSlack = 0x40,
	StatusErrorInkRibbonShort = 0x41,
	StatusErrorTapeEnd = 0x42,
	StatusErrorCutLabelError = 0x43,
	StatusErrorTemperatureError = 0x44,
	StatusErrorInsufficientParameters = 0x45,
    StatusErrorHalfCutterBladeNotSet = 0x50,
    StatusErrorFullCutterBladeNotSet = 0x51,
    StatusErrorHalfCutterBladeOff = 0x52,
    StatusErrorFullCutterBladeOff = 0x53,
    StatusErrorWinderCoverOpen = 0x54,
    StatusErrorVinylTapeTemperatureError = 0x55,
    StatusErrorWinderError = 0x56,
    StatusErrorHalfCutAllCut = 0x57,
    StatusErrorBigrollRecognitionAbnormality = 0x58,
    StatusErrorBigrollNonCompliant = 0x59,
    StatusErrorStopPrintingByAutoPowerOff = 0x5c,
    StatusErrorStopPrintingByPowerSupplyChange = 0x5d,
    StatusErrorWinderSet = 0x5e,
    StatusErrorWinderNotSet = 0x5f,
    StatusErrorWinderHalfCutAllCut = 0x60,

    StatusErrorConnectionFailed = 0xfffffff0,
    
    StatusErrorOtherUsing = 0xfffffffa,
    StatusErrorFirmwareUpdating = 0xfffffffb,
    StatusErrorDeviceUsing = 0xfffffffc,
    
    StatusErrorUnknownError = 0xffffffff
    
};

typedef NS_ENUM(NSInteger, TepraPrintTapeCut) {
    TapeCutEachLabel = 0,
    TapeCutAfterJob = 1,
    TapeCutNotCut = 2
};

typedef NS_ENUM(NSInteger, TepraPrintPrintSpeed) {
    PrintSpeedHigh = 0,
    PrintSpeedLow = 1,
    PrintSpeedMiddle = 2
};

typedef NS_ENUM(NSInteger, TepraPrintPrintMiddleSpeed) {
    PrintMiddleSpeedInvalid = 0,
    PrintMiddleSpeedValid = 1
};

typedef NS_ENUM(NSInteger, TepraPrintTapeSwitchMagnet) {
    TapeSwitchNonMagnet = 0,
    TapeSwitchMagnet = 1
};

typedef NS_ENUM(NSInteger, TepraPrintTapeSwitchBigroll) {
    TapeSwitchNonBigroll = 0,
    TapeSwitchBigroll = 1
};

typedef NS_ENUM(NSInteger, TepraPrintFullCut) {
    FullCutPermission = 0,
    FullCutProhibition = 1
};

typedef NS_ENUM(NSInteger, TepraPrintHalfCut) {
    HalfCutPermission = 0,
    HalfCutProhibition = 1
};

typedef NS_ENUM(NSInteger, TepraPrintDensity) {
    DensityNormal = 0,
    DensityPlus3 = 1
};

typedef NS_ENUM(NSInteger, TepraPrintPrintLowSpeed) {
    PrintLowSpeedInvalid = 0,
    PrintLowSpeedValid = 1
};

typedef NS_ENUM(NSInteger, TepraPrintMirror) {
    MirrorCorrectImage = 0,
    MirrorMirrorImage = 1
};

typedef NS_ENUM(NSInteger, TepraPrintWinder) {
    WinderPermission = 0,
    WinderProhibition = 1
};

typedef NS_ENUM(NSInteger, TepraPrintBatteryLevel) {
    BatteryLevelNoLowVoltage = 0,
    BatteryLevelWarningLowVoltage = 1,
    BatteryLevelErrorLowVoltage = 2
};

typedef NS_ENUM(NSInteger, TepraPrintBatteryType) {
    BatteryTypeAlkalineBattery = 0,
    BatteryTypeNickelHydrogenBattery = 1,
    BatteryTypeUnknownBattery = -1
};

typedef NS_OPTIONS(NSUInteger, TepraPrintObjectType) {
    ObjectTypeNone      = 0,
    ObjectTypeBarcode1D = 1 << 0,
    ObjectTypeBarcode2D = 1 << 1,
};

extern NSString *const TepraPrintParameterKeyCopies;        /* 1 ... 99 */
extern NSString *const TepraPrintParameterKeyTapeCut;       /* TepraPrintTapeCut */
extern NSString *const TepraPrintParameterKeyHalfCut;       /* YES:Half cut (BOOL) */
extern NSString *const TepraPrintParameterKeyPrintSpeed;    /* TepraPrintPrintSpeed */
extern NSString *const TepraPrintParameterKeyDensity;       /* -5 ... 5 */
extern NSString *const TepraPrintParameterKeyTapeWidth;     /* TepraPrintTapeWidth */
extern NSString *const TepraPrintParameterKeyPriorityPrintSetting; /* YES:Prioritize specified print settings (BOOL) */
extern NSString *const TepraPrintParameterKeyHalfCutContinuous; /* YES:Make half cut continuous separated labels (BOOL) */

extern NSString *const TepraPrintStatusKeyTapeKind;
extern NSString *const TepraPrintStatusKeyTapeWidth;
extern NSString *const TepraPrintStatusKeyDeviceError;

extern NSString *const TepraPrintTapeOptionKeyFullCut;
extern NSString *const TepraPrintTapeOptionKeyHalfCut;
extern NSString *const TepraPrintTapeOptionKeyDensity;
extern NSString *const TepraPrintTapeOptionKeyPrintSpeed;
extern NSString *const TepraPrintTapeOptionKeyMirror;
extern NSString *const TepraPrintTapeOptionKeyWinder;

extern NSString *const TepraPrintTapeSwitchKeyMagnet;
extern NSString *const TepraPrintTapeSwitchKeyBigroll;

@protocol TepraPrintDelegate;
@class TepraPrintDataProvider;
@class UIImage;

/**
 * TepraPrint
 * @brief   Management of a printer (print/status/tape cut/etc.)
 */
@interface TepraPrint : NSObject

/**
 * TepraPrint SDK version
 * @return version string
 */
+ (NSString *)version;

/**
 * set delegate
 */
@property (nonatomic, weak) id<TepraPrintDelegate> delegate;

/**
 * job progress
 * @return  Progress of a print
 */
@property(nonatomic, readonly) float progressOfPrint;
/**
 * page number of printing
 * @return  page number
 */
@property(nonatomic, readonly)  NSInteger pageNumberOfPrinting;

/**
 * set printer information
 * @param	printerInfo	Printer information
 */
- (void)setPrinterInformation:(NSDictionary *)printerInformation;

/**
 * print for application
 * @param	dataProvider Data provider of Application
 * @param   printParameter print parameter
 * @li @c   TepraPrintParameterKeyCopies 1 ... 99
 * @li @c   TepraPrintParameterKeyTapeCut TepraPrintTapeCut
 * @li @c   TepraPrintParameterKeyHalfCut YES:Half cut (BOOL)
 * @li @c   TepraPrintParameterKeyPrintSpeed TepraPrintPrintSpeed
 * @li @c   TepraPrintParameterKeyDensity  -5 ... 5
 */
- (void)doPrint:(TepraPrintDataProvider *)dataProvider printParameter:(NSDictionary *)printParameter;

/**
 * print for application
 * @param   printParameter print parameter
 * @li @c   TepraPrintParameterKeyCopies 1 ... 99
 * @li @c   TepraPrintParameterKeyTapeCut TepraPrintTapeCut
 * @li @c   TepraPrintParameterKeyHalfCut YES:Half cut (BOOL)
 * @li @c   TepraPrintParameterKeyPrintSpeed TepraPrintPrintSpeed
 * @li @c   TepraPrintParameterKeyDensity  -5 ... 5
 * @param   printData print data
 */
- (void)doPrint:(NSDictionary *)printParameter printData:(NSData *)printData;

/**
 * print for application
 * @param   printParameter print parameter
 * @li @c   TepraPrintParameterKeyCopies 1 ... 99
 * @li @c   TepraPrintParameterKeyTapeCut TepraPrintTapeCut
 * @li @c   TepraPrintParameterKeyHalfCut YES:Half cut (BOOL)
 * @li @c   TepraPrintParameterKeyPrintSpeed TepraPrintPrintSpeed
 * @li @c   TepraPrintParameterKeyDensity  -5 ... 5
 * @param   printData print data
 * @param   margin print margin
 */
- (void)doPrint:(NSDictionary *)printParameter printData:(NSData *)printData margin:(NSUInteger)margin;

/**
 * print for application
 * @param   printParameter print parameter
 * @li @c   TepraPrintParameterKeyCopies 1 ... 99
 * @li @c   TepraPrintParameterKeyTapeCut TepraPrintTapeCut
 * @li @c   TepraPrintParameterKeyHalfCut YES:Half cut (BOOL)
 * @li @c   TepraPrintParameterKeyPrintSpeed TepraPrintPrintSpeed
 * @li @c   TepraPrintParameterKeyDensity  -5 ... 5
 * @param   printDataArray print data array
 */
- (void)doPrint:(NSDictionary *)printParameter printDataArray:(NSArray *)printDataArray;

/**
 * print for application
 * @param   printParameter print parameter
 * @li @c   TepraPrintParameterKeyCopies 1 ... 99
 * @li @c   TepraPrintParameterKeyTapeCut TepraPrintTapeCut
 * @li @c   TepraPrintParameterKeyHalfCut YES:Half cut (BOOL)
 * @li @c   TepraPrintParameterKeyPrintSpeed TepraPrintPrintSpeed
 * @li @c   TepraPrintParameterKeyDensity  -5 ... 5
 * @param   printDataArray print data array
 * @param   margin print margin
 */
- (void)doPrint:(NSDictionary *)printParameter printDataArray:(NSArray *)printDataArray margin:(NSUInteger)margin;

/**
 * print for application
 * @param	dataProvider Data provider of Application
 * @param   printParameter print parameter
 * @li @c   TepraPrintParameterKeyCopies 1 ... 99
 * @li @c   TepraPrintParameterKeyTapeCut TepraPrintTapeCut
 * @li @c   TepraPrintParameterKeyHalfCut YES:Half cut (BOOL)
 * @li @c   TepraPrintParameterKeyPrintSpeed TepraPrintPrintSpeed
 * @li @c   TepraPrintParameterKeyDensity  -5 ... 5
 * @param   printData print data
 */
- (void)doPrint:(TepraPrintDataProvider *)dataProvider printParameter:(NSDictionary *)printParameter printData:(NSData *)printData;

/**
 * print for application
 * @param	dataProvider Data provider of Application
 * @param   printParameter print parameter
 * @li @c   TepraPrintParameterKeyCopies 1 ... 99
 * @li @c   TepraPrintParameterKeyTapeCut TepraPrintTapeCut
 * @li @c   TepraPrintParameterKeyHalfCut YES:Half cut (BOOL)
 * @li @c   TepraPrintParameterKeyPrintSpeed TepraPrintPrintSpeed
 * @li @c   TepraPrintParameterKeyDensity  -5 ... 5
 * @param   printDataArray print data array
 * @param   margin print margin
 */
- (void)doPrint:(TepraPrintDataProvider *)dataProvider printParameter:(NSDictionary *)printParameter printDataArray:(NSArray *)printDataArray margin:(NSUInteger)margin;

/**
 * get label image
 * @param	dataProvider Data provider of Application
 * @param   printParameter print parameter
 * @li @c   TepraPrintParameterKeyCopies 1 ... 99
 * @li @c   TepraPrintParameterKeyTapeCut TepraPrintTapeCut
 * @li @c   TepraPrintParameterKeyHalfCut YES:Half cut (BOOL)
 * @li @c   TepraPrintParameterKeyPrintSpeed TepraPrintPrintSpeed
 * @li @c   TepraPrintParameterKeyDensity  -5 ... 5
 */
- (UIImage *)labelImage:(TepraPrintDataProvider *)dataProvider printParameter:(NSDictionary *)printParameter;

/**
 * get label images
 * @param	dataProvider Data provider of Application
 * @param   printParameter print parameter
 * @li @c   TepraPrintParameterKeyCopies 1 ... 99
 * @li @c   TepraPrintParameterKeyTapeCut TepraPrintTapeCut
 * @li @c   TepraPrintParameterKeyHalfCut YES:Half cut (BOOL)
 * @li @c   TepraPrintParameterKeyPrintSpeed TepraPrintPrintSpeed
 * @li @c   TepraPrintParameterKeyDensity  -5 ... 5
 */
- (NSArray *)labelImages:(TepraPrintDataProvider *)dataProvider printParameter:(NSDictionary *)printParameter;

/**
 * tape feed and tape send
 * @param	mode feed or send
 * @li @c   TapeOperationFeed
 * @li @c   TapeOperationFeedAndCut
 */
- (void)doTapeFeed:(TepraPrintTapeOperation)mode;

/**
 * resume job
 */
- (void)resumeOfPrint;

/**
 * cancel job
 */
- (void)cancelPrint;

/**
 * get printer status
 * @return  NSDictionary status dictionary
 */
- (NSDictionary *)fetchPrinterStatus;

/**
 * get tape width from status dictionary
 * @param   status status dictionary
 * @return  TepraPrintTapeWidth
 */
- (TepraPrintTapeWidth)tapeWidthFromStatus:(NSDictionary *)status;

/**
 * get tape kind from status dictionary
 * @param   status status dictionary
 * @return  TepraPrintTapeKind
 */
- (TepraPrintTapeKind)tapeKindFromStatus:(NSDictionary *)status;

/**
 * get detection status of tape from status dictionary
 * @param   status dictionary
 * @return  NSDictionary
 */
- (NSDictionary *)tapeSwitchFromStatus:(NSDictionary *)status;

/**
 * get tape Option from status dictionary
 * @param   status dictionary
 * @return  NSDictionary
 */
- (NSDictionary *)tapeOptionFromStatus:(NSDictionary *)status;

/**
 * get device error from status dictionary
 * @param   status status dictionary
 * @return  TepraPrintDeviceStatus
 */
- (TepraPrintStatusError)deviceErrorFromStatus:(NSDictionary *)status;

/**
 * get Battery Level from status dictionary
 * @param   status dictionary
 * @return  TepraPrintBatteryLevel
 */
- (TepraPrintBatteryLevel)batteryLevelFromStatus:(NSDictionary *)status;

/**
 * set Battery Type
 * @param   TepraPrintBatteryType
 */
- (void)setBatteryType:(TepraPrintBatteryType)batteryType;

/**
 * get Battery Type
 * @return   TepraPrintBatteryType
 */
- (TepraPrintBatteryType)batteryType;

/**
 * tape width which can be used
 * @return  TepraPrintDeviceStatus
 */
- (NSArray *)kindOfTape;

/**
 * model name
 * @return  model name
 */
- (NSString *)modelName;

/**
 * printer resolution
 * @return  resolution (180/270/300/360)
 */
- (NSInteger)resolution;

/**
 * printer equipped with the half cut
 * @return YES:equipment
 */
- (BOOL)isSupportHalfCut;

/**
 * low-speed printing supported
 * @return YES:supported
 */
- (BOOL)isPrintSpeedSupport;

/**
 * winder connection status
 * @param  status dictionary
 * @return YES:connected
 */
- (BOOL)isTapeWinder:(NSDictionary *)status;

/**
 * bigroll availability
 * @param  status dictionary
 * @return YES:valid
 */
- (BOOL)isBigroll:(NSDictionary *)status;

/**
 * bigroll tape length
 * @param  status dictionary
 * @return NSInteger
 */
- (NSInteger)bigrollTapeLengthFromStatus:(NSDictionary *)status;

/**
 * bigroll tape usage length
 * @param  status dictionary
 * @return NSInteger
 */
- (NSInteger)bigrollTapeUsageLengthFromStatus:(NSDictionary *)status;

/**
 * Set object type (SR-R7900P only)
 * @param  type the object type
*/
- (void)setObjectType:(TepraPrintObjectType)type;

/**
 * Returns the printable area of the tape width
 * @param  width
 * @return NSInteger
*/
- (NSUInteger)printableSizeFromTape:(TepraPrintTapeWidth)width;


@end

/**
 * TepraPrintDelegate
 * @brief   TepraPrint delegate
 */
@protocol TepraPrintDelegate <NSObject>

@optional

/**
 * called when print phase changes
 * @param   tepraPrint caller
 * @param   jobPhase job phase TepraPrintJobPhase
 */
- (void)tepraPrint:(TepraPrint *)tepraPrint didChangePrintOperationPhase:(TepraPrintPrintingPhase)jobPhase;

/**
 * called when a print job is suspended
 * @param   tepraPrint caller
 * @param   errorStatus error status TepraPrintErrorStatus
 * @param   deviceStatus device status TepraPrintDeviceStatus
 */
- (void)tepraPrint:(TepraPrint *)tepraPrint didSuspendPrintOperation:(TepraPrintConnectionStatus)errorStatus deviceStatus:(TepraPrintStatusError)deviceStatus;

/**
 * called when a print job is aborted
 * @param   tepraPrint caller
 * @param   errorStatus error status TepraPrintErrorStatus
 * @param   deviceStatus device status TepraPrintDeviceStatus
 */
- (void)tepraPrint:(TepraPrint *)tepraPrint didAbortPrintOperation:(TepraPrintConnectionStatus)errorStatus deviceStatus:(TepraPrintStatusError)deviceStatus;

/**
 * called when tape feed phase changes
 * @param   tepraPrint caller
 * @param   jobPhase job phase TepraPrintJobPhase
 */
- (void)tepraPrint:(TepraPrint *)tepraPrint didChangeTapeFeedOperationPhase:(TepraPrintPrintingPhase)jobPhase;
/**
 * called when a tape feed is aborted
 * @param   tepraPrint caller
 * @param   errorStatus error status TepraPrintErrorStatus
 * @param   deviceStatus device status TepraPrintDeviceStatus
 */
- (void)tepraPrint:(TepraPrint *)tepraPrint didAbortTapeFeedOperation:(TepraPrintConnectionStatus)errorStatus deviceStatus:(TepraPrintStatusError)deviceStatus;

@end
