const fs = require("fs");
const java = require('java');
const joint = require("./Joint");

/**
 * BarCodeReader encapsulates an image which may contain one or several barcodes, it then can perform ReadBarCodes operation to detect barcodes.
 * @example
 * //This sample shows how to detect Code39 and Code128 barcodes.
 * let reader = new BarCodeReader("test.png", null,  [DecodeType.CODE_39_STANDARD, DecodeType.CODE_128]);
 * reader.readBarCodes().forEach(function(result, i, results)
 * {
 *    console.log("BarCode Type: " + result.getCodeTypeName());
 *    console.log("BarCode CodeText: " + result.getCodeText());
 * });
 */
class BarCodeReader extends joint.BaseJavaClass
{
    qualitySettings;
    recognizedResults;
    barcodeSettings;

    static get javaClassName()
    {
        return "com.aspose.mw.barcode.recognition.MwBarCodeReader";
    }

    /**
     * Initializes a new instance of the BarCodeReader<br>
     * @param image encoded as base64 string or path to image
     * @param rectangles array of object by type Rectangle
     * @param decodeTypes the array of objects by DecodeType
     */
    constructor(image, rectangles, decodeTypes)
    {
        if(image != null)
        {
            if (BarCodeReader.isPath(image))
            {
                image = BarCodeReader.loadImage(image);
            }
        }
        if (rectangles != null)
        {
            if (!Array.isArray(rectangles))
            {
                rectangles = [rectangles.toString()];
            }
            else
            {
                for (let i = 0; i < rectangles.length; i++)
                {
                    rectangles[i] = rectangles[i].toString();
                }
            }
        }
        if (decodeTypes != null)
        {
            if (!Array.isArray(decodeTypes))
            {
                decodeTypes = [decodeTypes];
            }
            for (let i = 0; i < decodeTypes.length; i++)
            {
                decodeTypes[i] = decodeTypes[i] + "";
            }
        }
        try
        {
            let java_class_link = new java.import(BarCodeReader.javaClassName);
            let java_class = null;
            if(image == null && rectangles == null && image == null)
                java_class = new java_class_link();
            else
                java_class = new java_class_link(image, rectangles, decodeTypes);
            super(java_class);
            this.init()
        } catch (e)
        {
            console.error("Invalid arguments");
            throw e;
        }
    }

    static construct(javaClass)
    {
        let barcodeReader = new BarCodeReader(null, null, null);
        barcodeReader.setJavaClass(javaClass);
        return barcodeReader;
    }

    static isPath(image)
    {
        if (image.length < 256 && image.includes("/") || image.includes("\\"))
        {
            if (fs.existsSync(image))
            {
                return true;
            }
            throw new joint.BarcodeException("Path " + image + " does not exist");
        }
        return false;
    }

    /**
     * Determines whether any of the given decode types is included into<br>
     * @param ...decodeTypes Types to verify.
     * @return bool Value is a true if any types are included into.
     */
    containsAny(...decodeTypes)
    {
        for (let i = 0; i < decodeTypes.length; i++)
        {
            decodeTypes[i] = decodeTypes[i] + "";
        }
        return this.getJavaClass().containsAnySync(decodeTypes);
    }

    static loadImage(image)
    {
        let is_path_to_image = false;
        is_path_to_image = fs.existsSync(image);

        if (is_path_to_image)
        {
            return fs.readFileSync(image).toString('base64');
        }
        else
        {
            return image;
        }
    }

    static convertToString(arg)
    {
        if (is_int(arg))
        {
            return strval(arg);
        }
        else if (arg instanceof Rectangle)
        {
            return "{[" + arg.toString() + "]}";
        }
        else if (is_array(arg))
        {
            let areasString = "{";

            for (let i = 0; i < sizeof(arg); i++)
            {
                areasString += "[" + arg[i].toString() + "]";
            }

            areasString += "}";

            return areasString;
        }
        else
        {
            return arg;
        }
    }

    init()
    {
        this.qualitySettings = new QualitySettings(this.getJavaClass().getQualitySettingsSync());
        this.barcodeSettings = BarcodeSettings.construct(this.getJavaClass().getBarcodeSettingsSync());
    }

    /**
     * Gets the timeout of recognition process in milliseconds.<br>
     *@example
     * let reader = new BarCodeReader("test.png", null, null);
     * reader.setTimeout(5000);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *    console.log("BarCode CodeText: " + result.getCodeText());
     * });
     * @return The timeout.
     */
    getTimeout()
    {
        return this.getJavaClass().getTimeoutSync();
    }

    /**
     * Sets the timeout of recognition process in milliseconds.
     *@example
     * let reader = new BarCodeReader("test.png", null, null);
     * reader.setTimeout(5000);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *    console.log("BarCode CodeText: " + result.getCodeText());
     * });
     * @param value The timeout.
     */
    setTimeout(value)
    {
        this.getJavaClass().setTimeoutSync(value);
    }

    /**
     * Enable checksum validation during recognition for 1D barcodes.<br>
     * Default is treated as Yes for symbologies which must contain checksum, as No where checksum only possible.<br>
     * Checksum never used: Codabar<br>
     * Checksum is possible: Code39 Standard/Extended, Standard2of5, Interleaved2of5, <br>
     * Matrix2of5, ItalianPost25, DeutschePostIdentcode, DeutschePostLeitcode, VIN<br>
     * Checksum always used: Rest symbologies<br>
     *
     * @example
     * //This sample shows influence of ChecksumValidation on recognition quality and results
     *
     * let generator = new BarcodeGenerator(EncodeTypes.EAN_13, "1234567890128");
     * generator.save("test.png");
     * let reader = new BarCodeReader("test.png", null,  DecodeType.EAN_13);
     * //checksum disabled
     * reader.setChecksumValidation(ChecksumValidation.OFF);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *     console.log("BarCode CodeText: " + result.getCodeText());
     *     console.log("BarCode Value: " + result.getExtended().getOneD().getValue());
     *     console.log("BarCode Checksum: " + result.getExtended().getOneD().getCheckSum());
     * });
     * let reader = new BarCodeReader("test.png", null,  DecodeType.EAN_13);
     * //checksum enabled
     * reader.setChecksumValidation(ChecksumValidation.ON);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *    console.log("BarCode CodeText: " + result.getCodeText());
     *    console.log("BarCode Value: " + result.getExtended().getOneD().getValue());
     *    console.log("BarCode Checksum: " + result.getExtended().getOneD().getCheckSum());
     * });
     *
     * The checksum validation flag.
     */
    getChecksumValidation()
    {
        return this.getJavaClass().getChecksumValidationSync();
    }

    /**
     *
     * Enable checksum validation during recognition for 1D barcodes.<br>
     * Default is treated as Yes for symbologies which must contain checksum, as No where checksum only possible.<br>
     * Checksum never used: Codabar<br>
     * Checksum is possible: Code39 Standard/Extended, Standard2of5, Interleaved2of5, Matrix2of5, ItalianPost25, DeutschePostIdentcode, DeutschePostLeitcode, VIN<br>
     * Checksum always used: Rest symbologies<br>
     *@example
     * This sample shows influence of ChecksumValidation on recognition quality and results
     *
     * let generator = new BarcodeGenerator(EncodeTypes.EAN_13, "1234567890128");
     * generator.save("test.png");
     * let reader = new BarCodeReader("test.png", null,  DecodeType.EAN_13);
     * //checksum disabled
     * reader.setChecksumValidation(ChecksumValidation.OFF);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *    console.log("BarCode CodeText: " + result.getCodeText());
     *    console.log("BarCode Value: " + result.getExtended().getOneD().getValue());
     *    console.log("BarCode Checksum: " + result.getExtended().getOneD().getCheckSum());
     * });
     * let reader = new BarCodeReader("test.png", null,  DecodeType.EAN_13);
     * //checksum enabled
     * reader.setChecksumValidation(ChecksumValidation.ON);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *    console.log("BarCode CodeText: " + result.getCodeText());
     *    console.log("BarCode Value: " + result.getExtended().getOneD().getValue());
     *    console.log("BarCode Checksum: " + result.getExtended().getOneD().getCheckSum());
     * });
     *
     * The checksum validation flag.
     */
    setChecksumValidation(value)
    {
        this.getJavaClass().setChecksumValidationSync(value);
    }

    /**
     * Strip FNC1, FNC2, FNC3 characters from codetext. Default value is false.
     *@example
     * //This sample shows how to strip FNC characters<br>
     *
     * let generator = new BarcodeGenerator(EncodeTypes.GS1Code128, "(02)04006664241007(37)1(400)7019590754");
     * generator.save("test.png");
     * let reader = new BarCodeReader("test.png", null,  DecodeType.CODE_128);
     * //StripFNC disabled
     * reader.setStripFNC(false);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *     console.log("BarCode CodeText: " + result.getCodeText());
     * });
     * let reader = new BarCodeReader("test.png", null,  DecodeType.CODE_128);
     * //StripFNC enabled
     * reader.setStripFNC(true);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *    console.log("BarCode CodeText: " + result.getCodeText());
     * });
     */
    getStripFNC()
    {
        return this.getJavaClass().getStripFNCSync();
    }

    /**
     * Strip FNC1, FNC2, FNC3 characters from codetext. Default value is false.
     *@example
     * //This sample shows how to strip FNC characters
     *
     * let generator = new BarcodeGenerator(EncodeTypes.GS1Code128, "(02)04006664241007(37)1(400)7019590754");
     * generator.save("test.png");
     * let reader = new BarCodeReader("test.png", null,  DecodeType.CODE_128);
     * //StripFNC disabled
     * reader.setStripFNC(false);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *    console.log("BarCode CodeText: " + result.getCodeText());
     * });
     * let reader = new BarCodeReader("test.png", null,  DecodeType.CODE_128);
     * //StripFNC enabled
     * reader.setStripFNC(true);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *    console.log("BarCode CodeText: " + result.getCodeText());
     * });
     *
     */
    setStripFNC(value)
    {
        this.getJavaClass().setStripFNCSync(value);
    }

    /**
     * Gets the Interpreting Type for the Customer Information of AustralianPost BarCode.Default is CustomerInformationInterpretingType.OTHER.
     */
    getCustomerInformationInterpretingType()
    {
        return this.getJavaClass().getCustomerInformationInterpretingTypeSync();
    }

    /**
     * Sets the Interpreting Type for the Customer Information of AustralianPost BarCode.Default is CustomerInformationInterpretingType.OTHER.
     */
    setCustomerInformationInterpretingType(value)
    {
        this.getJavaClass().setCustomerInformationInterpretingTypeSync(value);
    }

    abort()
    {
        this.getJavaClass().abortSync();
    }

    /**
     * Gets recognized BarCodeResult array
     * @example
     * //This sample shows how to read barcodes with BarCodeReader
     * let reader = new BarCodeReader("test.png", null,  [ DecodeType.CODE_39_STANDARD, DecodeType.CODE_128 ]);
     * reader.readBarCodes();
     * for(let i = 0; reader.getFoundCount() > i; ++i)
     *    console.log("BarCode CodeText: " +  reader.getFoundBarCodes()[i].getCodeText());
     *
     * @return recognized BarCodeResult array
     */
    getFoundBarCodes()
    {
        return this.recognizedResults;
    }

    /**
     * Gets recognized barcodes count
     * @example
     * //This sample shows how to read barcodes with BarCodeReader
     * let reader = new BarCodeReader("test.png", null,  [ DecodeType.CODE_39_STANDARD, DecodeType.CODE_128 ]);
     * reader.readBarCodes();
     * for(let i = 0; reader.getFoundCount() > i; ++i)
     *    console.log("BarCode CodeText: " + reader.getFoundBarCodes()[i].getCodeText());
     * Value: The recognized barcodes count
     */
    getFoundCount()
    {
        return this.getJavaClass().getFoundCountSync();
    }

    /**
     * Reads BarCodeResult from the image.
     * @example
     * //This sample shows how to read barcodes with BarCodeReader
     * let reader = new BarCodeReader("test.png", null,  [ DecodeType.CODE_39_STANDARD, DecodeType.CODE_128 ]);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *    console.log("BarCode CodeText: " + result.getCodeText());
     * });
     * let reader = new BarCodeReader("test.png", null,  [ DecodeType.CODE_39_STANDARD, DecodeType.CODE_128 ]);
     * reader.readBarCodes();
     * for(let i = 0; reader.getFoundCount() > i; ++i)
     *    console.log("BarCode CodeText: " + reader.getFoundBarCodes()[i].getCodeText());
     * @return Returns array of recognized {@code BarCodeResult}s on the image. If nothing is recognized, zero array is returned.
     */
    readBarCodes()
    {
        try
        {
            this.recognizedResults = [];
            let javaReadBarcodes = this.getJavaClass().readBarCodesSync();
            for (let i = 0; i < javaReadBarcodes.length; i++)
            {
                this.recognizedResults[i] = new BarCodeResult(javaReadBarcodes[i]);
            }
            return this.recognizedResults;
        }
        catch (e)
        {
            if((e.toString().includes("RecognitionAbortedException")))
            {
                throw new RecognitionAbortedException(e.toString(), null);
            }
            throw e;
        }
    }

    /**
     * QualitySettings allows to configure recognition quality and speed manually.
     * You can quickly set up QualitySettings by embedded presets: HighPerformance, NormalQuality,
     * HighQuality, MaxBarCodes or you can manually configure separate options.
     * Default value of QualitySettings is NormalQuality.
     * @return QualitySettings to configure recognition quality and speed.
     *
     * @example
     * //This sample shows how to use QualitySettings with BarCodeReader
     *
     * let reader = new BarCodeReader("test.png", null, null);
     *  //set high performance mode
     * reader.setQualitySettings(QualitySettings.getHighPerformance());
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *   console.log("BarCode CodeText: " + result.getCodeText());
     * });
     * let reader = new BarCodeReader("test.png", null,  [ DecodeType.CODE_39_STANDARD, DecodeType.CODE_128 ]);
     * //normal quality mode is set by default
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *   console.log("BarCode CodeText: " + result.getCodeText());
     * });
     * let reader = new BarCodeReader("test.png", null,  [ DecodeType.CODE_39_STANDARD, DecodeType.CODE_128 ]);
     * //set high performance mode
     * reader.setQualitySettings(QualitySettings.getHighPerformance());
     * //set separate options
     * reader.getQualitySettings().setAllowMedianSmoothing(true);
     * reader.getQualitySettings().setMedianSmoothingWindowSize(5);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *   console.log("BarCode CodeText: " + result.getCodeText());
     * });
     *
     */
    getQualitySettings()
    {
        return this.qualitySettings;
    }

    /**
     * QualitySettings allows to configure recognition quality and speed manually.
     * You can quickly set up QualitySettings by embedded presets: HighPerformance, NormalQuality,
     * HighQuality, MaxBarCodes or you can manually configure separate options.
     * Default value of QualitySettings is NormalQuality.
     *
     * @example
     * //This sample shows how to use QualitySettings with BarCodeReader
     * let reader = new BarCodeReader("test.png", null,  [ DecodeType.CODE_39_STANDARD, DecodeType.CODE_128 ]);
     * //set high performance mode
     * reader.setQualitySettings(QualitySettings.getHighPerformance());
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *   console.log("BarCode CodeText: " + result.getCodeText());
     * });
     * let reader = new BarCodeReader("test.png", null,  [ DecodeType.CODE_39_STANDARD, DecodeType.CODE_128 ]);
     * //normal quality mode is set by default
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *   console.log("BarCode CodeText: " + result.getCodeText());
     * });
     * let reader = new BarCodeReader("test.png", null,  [ DecodeType.CODE_39_STANDARD, DecodeType.CODE_128 ]);
     *  //set high performance mode
     * reader.setQualitySettings(QualitySettings.getHighPerformance());
     * //set separate options
     * reader.getQualitySettings().setAllowMedianSmoothing(true);
     * reader.getQualitySettings().setMedianSmoothingWindowSize(5);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *   console.log("BarCode CodeText: " + result.getCodeText());
     * });
     * QualitySettings to configure recognition quality and speed.
     */
    setQualitySettings(value)
    {
        this.getJavaClass().setQualitySettingsSync(value.getJavaClass());
    }

    /**
     * The main BarCode decoding parameters. Contains parameters which make influence on recognized data.
     * @return The main BarCode decoding parameters
     */
    getBarcodeSettings()
    {
        return this.barcodeSettings;
    }

    /**
     * A flag which force engine to detect codetext encoding for Unicode codesets.
     * @example
     * // This sample shows how to detect text encoding on the fly if DetectEncoding is enabled
     * image = "image.png";
     * let generator = new BarcodeGenerator(EncodeTypes.QR, "пїЅпїЅпїЅпїЅпїЅ"))
     * generator.getParameters().getBarcode().getQR().setCodeTextEncoding("UTF-8");
     * generator.save(image, BarCodeImageFormat.getPng());
     *     //detects encoding for Unicode codesets is enabled
     * let reader = new BarCodeReader(image, null, DecodeType.QR);
     * reader.setDetectEncoding(true);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *    console.log("BarCode CodeText: " + result.getCodeText());
     * });
     *     //detect encoding is disabled
     * let reader = new BarCodeReader(image, null, DecodeType.QR);
     * reader.setDetectEncoding(false);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *    console.log("BarCode CodeText: " + result.getCodeText());
     * });
     */
    getDetectEncoding()
    {
        return this.getJavaClass().getDetectEncodingSync();
    }

    /**
     * A flag which force engine to detect codetext encoding for Unicode codesets.
     * @example
     * //This sample shows how to detect text encoding on the fly if DetectEncoding is enabled
     * let image = "image.png";
     * let generator = new BarcodeGenerator(EncodeTypes.QR, "пїЅпїЅпїЅпїЅпїЅ");
     * generator.getParameters().getBarcode().getQR().setCodeTextEncoding("UTF-8");
     * generator.save(image, BarCodeImageFormat.getPng());
     * //detects encoding for Unicode codesets is enabled
     * let reader = new BarCodeReader(image, null, DecodeType.QR);
     * reader.setDetectEncoding(true);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *    console.log("BarCode CodeText: " + result.getCodeText());
     * });
     * //detect encoding is disabled
     * let reader = new BarCodeReader(image, null, DecodeType.QR);
     * reader.setDetectEncoding(true);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *    console.log("BarCode CodeText: " + result.getCodeText());
     * });
     */
    setDetectEncoding(value)
    {
        this.getJavaClass().setDetectEncodingSync(value);
    }

    /**
     * Sets bitmap image and areas for recognition.
     * Must be called before ReadBarCodes() method.
     * @example
     * //This sample shows how to detect Code39 and Code128 barcodes.
     * let bmp = "test.png";
     * let reader = new BarCodeReader();
     * reader.setBarCodeReadType([ DecodeType.CODE_39_STANDARD, DecodeType.CODE_128 ]);
     * var img = new Image();
     * img.src = 'path_to_image';
     * width = img.width;
     * height = img.height;
     * reader.setBarCodeImage(bmp, new Rectangle[] { new Rectangle(0, 0, width, height) });
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *    console.log("BarCode Type: " + result.getCodeTypeName());
     *    console.log("BarCode CodeText: " + result.getCodeText());
     * });
     * @param value The bitmap image for recognition.
     * @param areas areas list for recognition
     * @throws BarcodeException
     */
    setBarCodeImage(image, ...areas)
    {
        image = BarCodeReader.loadImage(image);
        let stringAreas = [];
        let isAllRectanglesNotNull = false;
        if (!(areas == null) && areas.length > 0)
        {
            for (let i = 0; i < areas.length; i++)
            {
                if (!(areas[i] == null))
                {
                    isAllRectanglesNotNull |= true;
                    stringAreas[i] = areas[i].toString();
                }
            }
            if (!isAllRectanglesNotNull)
            {
                stringAreas = [];
            }
        }
        if (stringAreas.length == 0)
        {
            this.getJavaClass().setBarCodeImageSync(image);
        }
        else
        {
            this.getJavaClass().setBarCodeImageSync(image, stringAreas);
        }
    }

    /**
     * Sets SingleDecodeType type array for recognition.
     * Must be called before readBarCodes() method.
     * @example
     * //This sample shows how to detect Code39 and Code128 barcodes.
     * let reader = new BarCodeReader();
     * reader.setBarCodeReadType([ DecodeType.CODE_39_STANDARD, DecodeType.CODE_128 ]);
     * reader.setBarCodeImage("test.png");
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *     console.log("BarCode Type: " + result.getCodeTypeName());
     *     console.log("BarCode CodeText: " + result.getCodeText());
     * });
     * @param types The SingleDecodeType type array to read.
     */
    setBarCodeReadType(...types)
    {
        for (let i = 0; i < types.length; i++)
        {
            types[i] = types[i] + "";
        }
        this.getJavaClass().setBarCodeReadTypeSync(types);
    }

    getBarCodeDecodeType()
    {
        return this.getJavaClass().getBarCodeDecodeTypeSync();
    }

    /**
     * Exports BarCode properties to the xml-file specified
     * @param xmlFile The name for the file
     * @return Whether or not export completed successfully.
     * Returns True in case of success; False Otherwise
     */
    exportToXml(xmlFile)
    {
        try
        {
            let xmlData = this.getJavaClass().exportToXmlSync();
            let isSaved = xmlData != null;
            if(isSaved)
                fs.writeFileSync(xmlFile, xmlData);
            return isSaved;
        }
        catch (ex)
        {
            let barcode_exception = new joint.BarcodeException(ex);
            throw barcode_exception;
        }
    }

    /**
     * Exports BarCode properties to the xml-file specified
     * @param xmlFile The name for the file
     * @return Whether or not export completed successfully. Returns True in case of success; False Otherwise
     */
    static importFromXml(xmlFile)
    {
        try
        {
            let xmlData = fs.readFileSync(xmlFile).toString();
            let java_class_link = new java.import(BarCodeReader.javaClassName);
            return BarCodeReader.construct(java_class_link.importFromXmlSync(xmlData.substring(3, xmlData.length)));
        }
        catch (ex)
        {
            let barcode_exception = new joint.BarcodeException(ex);
            throw barcode_exception;
        }
    }
}

/**
 * Stores a set of four Points that represent a Quadrangle region.
 */
class Quadrangle extends joint.BaseJavaClass
{
    static get javaClassName()
    {
        return "com.aspose.mw.barcode.recognition.MwQuadrangle";
    }

    leftTop;
    rightTop;
    rightBottom;
    leftBottom;

    /**
     * Represents a Quadrangle structure with its properties left uninitialized.Value: Quadrangle
     */
    static get EMPTY()
    {
        return new Quadrangle(new joint.Point(0, 0), new joint.Point(0, 0), new joint.Point(0, 0), new joint.Point(0, 0));
    }

    static construct(...args)
    {
        let quadrangle = Quadrangle.EMPTY;
        quadrangle.setJavaClass(args[0]);
        return quadrangle;
    }


    /**
     * Initializes a new instance of the Quadrangle structure with the describing points.
     *
     * @param leftTop A Point that represents the left-top corner of the Quadrangle.
     * @param rightTop A Point that represents the right-top corner of the Quadrangle.
     * @param rightBottom A Point that represents the right-bottom corner of the Quadrangle.
     * @param leftBottom A Point that represents the left-bottom corner of the Quadrangle.
     */
    constructor(leftTop, rightTop, rightBottom, leftBottom)
    {
        let java_link = java.import(Quadrangle.javaClassName);
        let javaClass = new java_link(leftTop.getJavaClass(), rightTop.getJavaClass(), rightBottom.getJavaClass(), leftBottom.getJavaClass());
        super(javaClass);
        this.init();
    }

    init()
    {
        this.leftTop = joint.Point.construct(this.getJavaClass().getLeftTopSync());
        this.rightTop = joint.Point.construct(this.getJavaClass().getRightTopSync());
        this.rightBottom = joint.Point.construct(this.getJavaClass().getRightBottomSync());
        this.leftBottom = joint.Point.construct(this.getJavaClass().getLeftBottomSync());
    }

    /**
     * Gets left-top corner Point of Quadrangle regionValue: A left-top corner Point of Quadrangle region
     */
    getLeftTop()
    {
        return this.leftTop;
    }

    /**
     * Gets left-top corner Point of Quadrangle regionValue: A left-top corner Point of Quadrangle region
     */
    setLeftTop(value)
    {
        this.leftTop = value;
        this.getJavaClass().setLeftTopSync(value.getJavaClass());
    }

    /**
     * Gets right-top corner Point of Quadrangle regionValue: A right-top corner Point of Quadrangle region
     */
    getRightTop()
    {
        return this.rightTop;
    }

    /**
     * Gets right-top corner Point of Quadrangle regionValue: A right-top corner Point of Quadrangle region
     */
    setRightTop(value)
    {
        this.rightTop = value;
        this.getJavaClass().setRightTopSync(value.getJavaClass());
    }

    /**
     * Gets right-bottom corner Point of Quadrangle regionValue: A right-bottom corner Point of Quadrangle region
     */
    getRightBottom()
    {
        return this.rightBottom;
    }

    /**
     * Gets right-bottom corner Point of Quadrangle regionValue: A right-bottom corner Point of Quadrangle region
     */
    setRightBottom(value)
    {
        this.rightBottom = value;
        this.getJavaClass().setRightBottomSync(value.getJavaClass());
    }

    /**
     * Gets left-bottom corner Point of Quadrangle regionValue: A left-bottom corner Point of Quadrangle region
     */
    getLeftBottom()
    {
        return this.leftBottom;
    }

    /**
     * Gets left-bottom corner Point of Quadrangle regionValue: A left-bottom corner Point of Quadrangle region
     */
    setLeftBottom(value)
    {
        this.leftBottom = value;
        this.getJavaClass().setLeftBottomSync(value.getJavaClass());
    }

    /**
     * Tests whether all Points of this Quadrangle have values of zero.Value: Returns true if all Points of this Quadrangle have values of zero; otherwise, false.
     */
    isEmpty()
    {
        return this.getJavaClass().isEmptySync();
    }

    /**
     * Determines if the specified Point is contained within this Quadrangle structure.
     *
     * @param pt The Point to test.
     * @return true if Point is contained within this Quadrangle structure; otherwise, false.
     */
    contains(pt)
    {
        return this.getJavaClass().containsSync(pt.getJavaClass());
    }

    /**
     * Determines if the specified point is contained within this Quadrangle structure.
     *
     * @param x The x point cordinate.
     * @param y The y point cordinate.
     * @return Returns true if point is contained within this Quadrangle structure; otherwise, false.
     */
    containsPoint(x, y)
    {
        return this.getJavaClass().containsSync(x, y);
    }

    /**
     * Determines if the specified Quadrangle is contained or intersect this Quadrangle structure.
     *
     * @param quad The Quadrangle to test.
     * @return Returns true if Quadrangle is contained or intersect this Quadrangle structure; otherwise, false.
     */
    containsQuadrangle(quad)
    {
        return this.getJavaClass().containsSync(quad.getJavaClass());
    }

    /**
     * Determines if the specified Rectangle is contained or intersect this Quadrangle structure.
     *
     * @param rect The Rectangle to test.
     * @return Returns true if Rectangle is contained or intersect this Quadrangle structure; otherwise, false.
     */
    containsRectangle(rect)
    {
        return this.getJavaClass().containsSync(rect.getJavaClass());
    }

    /**
     * Returns a value indicating whether this instance is equal to a specified Quadrangle value.
     *
     * @param other An Quadrangle value to compare to this instance.
     * @return true if obj has the same value as this instance; otherwise, false.
     */
    equals(other)
    {
        return this.getJavaClass().equalsSync(other.getJavaClass());
    }

    /**
     * Returns the hash code for this instance.
     *
     * @return A 32-bit signed integer hash code.
     */
    hashCode()
    {
        return this.getJavaClass().hashCodeSync();
    }

    /**
     * Returns a human-readable string representation of this Quadrangle.
     *
     * @return A string that represents this Quadrangle.
     */
    toString()
    {
        return this.getJavaClass().toStringSync();
    }

    /**
     * Creates Rectangle bounding this Quadrangle
     *
     * @return returns Rectangle bounding this Quadrangle
     */
    getBoundingRectangle()
    {
        return joint.Rectangle.construct(this.getJavaClass().getBoundingRectangleSync());
    }
}

/**
 * Stores a QR Structured Append information of recognized barcode
 * @example
 * //This sample shows how to get QR Structured Append data
 *
 * let reader = new BarCodeReader("test.png", null,  DecodeType.QR);
 * reader.readBarCodes().forEach(function(result, i, results)
 * {
 *    console.log("BarCode Type: " + result.getCodeTypeName());
 *    console.log("BarCode CodeText: " + result.getCodeText());
 *    console.log("QR Structured Append Quantity: " + result.getExtended().getQR().getQRStructuredAppendModeBarCodesQuantity());
 *    console.log("QR Structured Append Index: " + result.getExtended().getQR().getQRStructuredAppendModeBarCodeIndex());
 *    console.log("QR Structured Append ParityData: " + result.getExtended().getQR().getQRStructuredAppendModeParityData());
 * });
 */
class QRExtendedParameters extends joint.BaseJavaClass
{
    constructor(javaclass)
    {
        super(javaclass);
        this.init()
    }

    init()
    {
        // TODO: Implement init() method.
    }

    /**
     * Gets the QR structured append mode barcodes quantity. Default value is -1.Value: The quantity of the QR structured append mode barcode.
     */
    getQRStructuredAppendModeBarCodesQuantity()
    {
        return this.getJavaClass().getQRStructuredAppendModeBarCodesQuantitySync();
    }

    /**
     * Gets the index of the QR structured append mode barcode. Index starts from 0. Default value is -1.Value: The quantity of the QR structured append mode barcode.
     */
    getQRStructuredAppendModeBarCodeIndex()
    {
        return this.getJavaClass().getQRStructuredAppendModeBarCodeIndexSync();
    }

    /**
     * Gets the QR structured append mode parity data. Default value is -1.Value: The index of the QR structured append mode barcode.
     */
    getQRStructuredAppendModeParityData()
    {
        return this.getJavaClass().getQRStructuredAppendModeParityDataSync();
    }

    isEmpty()
    {
        return this.getJavaClass().isEmptySync();
    }

    /**
     * Returns a value indicating whether this instance is equal to a specified QRExtendedParameters value.
     *
     * @param obj An object value to compare to this instance.
     * @return true if obj has the same value as this instance; otherwise, false.
     */
    equals(obj)
    {
        return this.getJavaClass().equalsSync(obj.getJavaClass());
    }

    /**
     * Returns the hash code for this instance.
     *
     * @return A 32-bit signed integer hash code.
     */
    hashCode()
    {
        return this.getJavaClass().hashCodeSync();
    }

    /**
     * Returns a human-readable string representation of this QRExtendedParameters.
     *
     * @return A string that represents this QRExtendedParameters.
     */
    toString()
    {
        return this.getJavaClass().toStringSync();
    }
}

/**
 * Stores a MacroPdf417 metadata information of recognized barcode
 * @example
 * //This sample shows how to get Macro Pdf417 metadata
 * let generator = new BarcodeGenerator(EncodeTypes.MacroPdf417, "12345");
 * generator.getParameters().getBarcode().getPdf417().setPdf417MacroFileID(10);
 * generator.getParameters().getBarcode().getPdf417().setPdf417MacroSegmentsCount(2);
 * generator.getParameters().getBarcode().getPdf417().setPdf417MacroSegmentID(1);
 * generator.save("test.png");
 * let reader = new BarCodeReader("test.png", null,  DecodeType.MACRO_PDF_417);
 * reader.readBarCodes().forEach(function(result, i, results)
 * {
 *     console.log("BarCode Type: " + result.getCodeTypeName());
 *     console.log("BarCode CodeText: " + result.getCodeText());
 *     console.log("Macro Pdf417 FileID: " + result.getExtended().getPdf417().getMacroPdf417FileID());
 *     console.log("Macro Pdf417 Segments: " + result.getExtended().getPdf417().getMacroPdf417SegmentsCount());
 *     console.log("Macro Pdf417 SegmentID: " + result.getExtended().getPdf417().getMacroPdf417SegmentID());
 * });
 */
class Pdf417ExtendedParameters extends joint.BaseJavaClass
{
    constructor(javaclass)
    {
        super(javaclass);
        this.init()
    }

    init()
    {
        // TODO: Implement init() method.
    }

    /**
     * Gets the file ID of the barcode, only available with MacroPdf417.Value: The file ID for MacroPdf417
     */
    getMacroPdf417FileID()
    {
        return this.getJavaClass().getMacroPdf417FileIDSync();
    }

    /**
     * Gets the segment ID of the barcode,only available with MacroPdf417.Value: The segment ID of the barcode.
     */
    getMacroPdf417SegmentID()
    {
        return this.getJavaClass().getMacroPdf417SegmentIDSync();
    }

    /**
     * Gets macro pdf417 barcode segments count. Default value is -1.Value: Segments count.
     */
    getMacroPdf417SegmentsCount()
    {
        return this.getJavaClass().getMacroPdf417SegmentsCountSync();
    }

    /**
     * Macro PDF417 file name (optional).
     * @return File name.
     */
    getMacroPdf417FileName()
    {
        return this.getJavaClass().getMacroPdf417FileNameSync();
    }

    /**
     * Macro PDF417 file size (optional).
     * @return File size.
     */
    getMacroPdf417FileSize()
    {
        return this.getJavaClass().getMacroPdf417FileSizeSync();
    }

    /**
     * Macro PDF417 sender name (optional).
     * @return Sender name
     */
    getMacroPdf417Sender()
    {
        return this.getJavaClass().getMacroPdf417SenderSync();
    }

    /**
     * Macro PDF417 addressee name (optional).
     * @return Addressee name.
     */
    getMacroPdf417Addressee()
    {
        return this.getJavaClass().getMacroPdf417AddresseeSync();
    }

    /**
     * Macro PDF417 time stamp (optional).
     * @return Time stamp.
     */
    getMacroPdf417TimeStamp()
    {
        return new Date(this.getJavaClass().getMacroPdf417TimeStampSync() * 1000);
    }

    /**
     * Macro PDF417 checksum (optional).
     * @return Checksum.
     */
    getMacroPdf417Checksum()
    {
        return this.getJavaClass().getMacroPdf417ChecksumSync();
    }

    /**
     * Tests whether all parameters has only default values
     * Value: Returns {@code <b>true</b>} if all parameters has only default values; otherwise, {@code <b>false</b>}.
     */
    isEmpty()
    {
        return this.getJavaClass().isEmptySync();
    }

    /**
     * Returns a value indicating whether this instance is equal to a specified Pdf417ExtendedParameters value.
     *
     * @param obj An System.Object value to compare to this instance.
     * @return true if obj has the same value as this instance; otherwise, false.
     */
    equals(obj)
    {
        return this.getJavaClass().equalsSync(obj.getJavaClass());
    }

    /**
     * Returns the hash code for this instance.
     *
     * @return A 32-bit signed integer hash code.
     */
    hashCode()
    {
        return this.getJavaClass().hashCodeSync();
    }

    /**
     * Returns a human-readable string representation of this Pdf417ExtendedParameters.
     *
     * @return A string that represents this Pdf417ExtendedParameters.
     */
    toString()
    {
        return this.getJavaClass().toStringSync();
    }
}

/**
 * Stores special data of 1D recognized barcode like separate codetext and checksum
 * @example
 * //This sample shows how to get 1D barcode value and checksum
 * let generator = new BarcodeGenerator(EncodeTypes.EAN_13, "1234567890128");
 * generator.save("test.png");
 * let reader = new BarCodeReader("test.png", null,  DecodeType.EAN_13);
 * reader.readBarCodes().forEach(function(result, i, results)
 * {
 *    console.log("BarCode Type: " + result.getCodeTypeName());
 *    console.log("BarCode CodeText: " + result.getCodeText());
 *    console.log("BarCode Value: " + result.getExtended().getOneD().getValue());
 *    console.log("BarCode Checksum: " + result.getExtended().getOneD().getCheckSum());
 * });
 */
class OneDExtendedParameters extends joint.BaseJavaClass
{
    constructor(javaclass)
    {
        super(javaclass);
        this.init()
    }

    init()
    {
        // TODO: Implement init() method.
    }

    /**
     * Gets the codetext of 1D barcodes without checksum. Value: The codetext of 1D barcodes without checksum.
     */
    getValue()
    {
        return this.getJavaClass().getValueSync();
    }

    /**
     * Gets the checksum for 1D barcodes. Value: The checksum for 1D barcode.
     */
    getCheckSum()
    {
        return this.getJavaClass().getCheckSumSync();
    }

    /**
     * Tests whether all parameters has only default values
     * Value: Returns {@code <b>true</b>} if all parameters has only default values; otherwise, {@code <b>false</b>}.
     */
    isEmpty()
    {
        return this.getJavaClass().isEmptySync();
    }

    /**
     * Returns a value indicating whether this instance is equal to a specified OneDExtendedParameters value.
     *
     * @param obj An System.Object value to compare to this instance.
     * @return true if obj has the same value as this instance; otherwise, false.
     */
    equals(obj)
    {
        return this.getJavaClass().equalsSync(obj.getJavaClass());
    }

    /**
     * Returns the hash code for this instance.
     *
     * @return A 32-bit signed integer hash code.
     */
    hashCode()
    {
        return this.getJavaClass().hashCodeSync();
    }

    /**
     * Returns a human-readable string representation of this OneDExtendedParameters.
     *
     * @return A string that represents this OneDExtendedParameters.
     */
    toString()
    {
        return this.getJavaClass().toStringSync();
    }
}

/**
 * Stores special data of Code128 recognized barcode
 * Represents the recognized barcode's region and barcode angle
 * @example
 * //This sample shows how to get code128 raw values
 * let generator = new BarcodeGenerator(EncodeTypes.Code128, "12345");
 * generator.save("test.png");
 * let reader = new BarCodeReader("test.png", null,  DecodeType.CODE_128);
 * reader.readBarCodes().forEach(function(result, i, results)
 * {
 *    console.log("BarCode Type: " + result.getCodeTypeName());
 *    console.log("BarCode CodeText: " + result.getCodeText());
 *    console.log("Code128 Data Portions: " + result.getExtended().getCode128());
 * });
 */
class Code128ExtendedParameters extends joint.BaseJavaClass
{
    code128DataPortions;

    constructor(javaclass)
    {
        super(javaclass);
        this.init()
    }

    init()
    {
        this.code128DataPortions = Code128ExtendedParameters.convertCode128DataPortions(this.getJavaClass().getCode128DataPortionsSync());
    }

    static convertCode128DataPortions(javaCode128DataPortions)
    {
        let code128DataPortionsValues = javaCode128DataPortions;
        let code128DataPortions = [];
        for (let i = 0; i < code128DataPortionsValues.length; i++)
        {
            code128DataPortions[i] = Code128DataPortion.construct(code128DataPortionsValues[i]);
        }
        return code128DataPortions;
    }

    /**
     *  Gets Code128DataPortion array of recognized Code128 barcode Value of the Code128DataPortion.
     */
    getCode128DataPortions()
    {
        return this.code128DataPortions;
    }

    isEmpty()
    {
        return this.getJavaClass().isEmptySync();
    }

    /**
     * Returns a value indicating whether this instance is equal to a specified Code128ExtendedParameters value.
     *
     * @param obj An System.Object value to compare to this instance.
     * @return true if obj has the same value as this instance; otherwise, false.
     */
    equals(obj)
    {
        return this.getJavaClass().equalsSync(obj.getJavaClass());
    }

    /**
     * Returns the hash code for this instance.
     *
     * @return A 32-bit signed integer hash code.
     */
    hashCode()
    {
        return this.getJavaClass().hashCodeSync();
    }

    /**
     * Returns a human-readable string representation of this Code128ExtendedParameters.
     *
     * @return A string that represents this Code128ExtendedParameters.
     */
    toString()
    {
        return this.getJavaClass().toStringSync();
    }
}

/**
 * Barcode detector settings.
 */
class BarcodeSvmDetectorSettings extends joint.BaseJavaClass
{
    static get javaClassName()
    {
        return "com.aspose.mw.barcode.recognition.MwBarcodeSvmDetectorSettings";
    }

    /**
     * High performance detection preset.
     *
     * Default for {@code QualitySettings.PresetType.HighPerformance}
     */
    static get HighPerformance()
    {
        return 0;
    }

    /**
     * Normal quality detection preset.
     *
     * Default for {@code QualitySettings.PresetType.NormalQuality}
     */
    static get NormalQuality()
    {
        return 1;
    }

    /**
     * High quality detection preset.
     *
     * Default for {@code QualitySettings.PresetType.HighQualityDetection} and {@code QualitySettings.PresetType.HighQuality}
     */
    static get HighQuality()
    {
        return 2;
    }

    /**
     * Max quality detection preset.
     *
     * Default for {@code QualitySettings.PresetType.MaxQualityDetection} and {@code QualitySettings.PresetType.MaxBarCodes}
     */
    static get MaxQuality()
    {
        return 3;
    }

    scanWindowSizes;

    constructor(javaclass)
    {
        super(javaclass);
        this.init()
    }

    init()
    {
        this.scanWindowSizes = BarcodeSvmDetectorSettings.convertScanWindowSizes(this.getJavaClass().getScanWindowSizesSync());
        // TODO: Implement init() method.
    }

    static convertScanWindowSizes(javaScanWindowSizes)
    {
        let scanWindowSizes = [];
        for (let i = 0; i < javaScanWindowSizes.size(); i++)
        {
            scanWindowSizes[i] = javaScanWindowSizes.get(i);
        }
        return scanWindowSizes;
    }

    /**
     * Scan window sizes in pixels.<br>
     *
     * Allowed sizes are 10, 15, 20, 25, 30.<br>
     * Scanning with small window size takes more time and provides more accuracy but may fail in detecting very big barcodes.<br>
     * Combining of several window sizes can improve detection quality.
     */
    getScanWindowSizes()
    {
        return this.scanWindowSizes;
    }

    /**
     * Scan window sizes in pixels.<br>
     *
     * Allowed sizes are 10, 15, 20, 25, 30.<br>
     * Scanning with small window size takes more time and provides more accuracy but may fail in detecting very big barcodes.<br>
     * Combining of several window sizes can improve detection quality.
     */
    setScanWindowSizes(value)
    {
        this.scanWindowSizes = value;
        var ArrayList = java.import('java.util.ArrayList');
        var valueList = new ArrayList();
        value.forEach(function(item, i, value)
        {
            valueList.addSync(item);
        });
        this.getJavaClass().setScanWindowSizesSync(valueList);
    }

    /**
     * Similarity coefficient depends on how homogeneous barcodes are.<br>
     *
     * Use high value for for clear barcodes.<br>
     * Use low values to detect barcodes that ara partly damaged or not lighten evenly.<br>
     * Similarity coefficient must be between [0.5, 0.9]
     */
    getSimilarityCoef()
    {
        return this.getJavaClass().getSimilarityCoefSync();
    }

    /**
     * Similarity coefficient depends on how homogeneous barcodes are.<br>
     *
     * Use high value for for clear barcodes.<br>
     * Use low values to detect barcodes that ara partly damaged or not lighten evenly.<br>
     * Similarity coefficient must be between [0.5, 0.9]
     */
    setSimilarityCoef(value)
    {
        this.getJavaClass().setSimilarityCoefSync(value);
    }

    /**
     * Sets threshold for detected regions that may contain barcodes.<br>
     *
     * Value 0.7 means that bottom 70% of possible regions are filtered out and not processed further.<br>
     * Region likelihood threshold must be between [0.05, 0.9]<br>
     * Use high values for clear images with few barcodes.<br>
     * Use low values for images with many barcodes or for noisy images.<br>
     * Low value may lead to a bigger recognition time.<br>
     */
    getRegionLikelihoodThresholdPercent()
    {
        return this.getJavaClass().getRegionLikelihoodThresholdPercentSync();
    }

    /**
     * Sets threshold for detected regions that may contain barcodes.<br>
     *
     * Value 0.7 means that bottom 70% of possible regions are filtered out and not processed further.<br>
     * Region likelihood threshold must be between [0.05, 0.9]<br>
     * Use high values for clear images with few barcodes.<br>
     * Use low values for images with many barcodes or for noisy images.<br>
     * Low value may lead to a bigger recognition time.
     */
    setRegionLikelihoodThresholdPercent(value)
    {
        this.getJavaClass().setRegionLikelihoodThresholdPercentSync(value);
    }

    /**
     * Allows detector to skip search for diagonal barcodes.<br>
     *
     * Setting it to false will increase detection time but allow to find diagonal barcodes that can be missed otherwise.<br>
     * Enabling of diagonal search leads to a bigger detection time.
     */
    getSkipDiagonalSearch()
    {
        return this.getJavaClass().getSkipDiagonalSearchSync();
    }

    /**
     * Allows detector to skip search for diagonal barcodes.<br>
     *
     * Setting it to false will increase detection time but allow to find diagonal barcodes that can be missed otherwise.<br>
     * Enabling of diagonal search leads to a bigger detection time.
     */
    setSkipDiagonalSearch(value)
    {
        this.getJavaClass().setSkipDiagonalSearchSync(value);
    }

    /**
     * Window size for median smoothing.<br>
     *
     * Typical values are 3 or 4. 0 means no median smoothing.<br>
     * Default value is 0.<br>
     * Median filter window size must be between [0, 10]
     */
    getMedianFilterWindowSize()
    {
        return this.getJavaClass().getMedianFilterWindowSizeSync();
    }

    /**
     * Window size for median smoothing.<br>
     *
     * Typical values are 3 or 4. 0 means no median smoothing.<br>
     * Default value is 0.<br>
     * Median filter window size must be between [0, 10]
     */
    setMedianFilterWindowSize(value)
    {
        this.getJavaClass().setMedianFilterWindowSizeSync(value);
    }

    /**
     * High performance detection preset.<br>
     *
     * Default for QualitySettings.PresetType.HighPerformance
     */
    static getHighPerformance()
    {
        return new BarcodeSvmDetectorSettings(QualitySettings.HighPerformance);
    }

    /**
     * Normal quality detection preset.<br>
     *
     * Default for QualitySettings.PresetType.NormalQuality
     */
    static getNormalQuality()
    {
        return new BarcodeSvmDetectorSettings(QualitySettings.NormalQuality);
    }

    /**
     * High quality detection preset.<br>
     *
     * Default for QualitySettings.PresetType.HighQualityDetection and QualitySettings.PresetType.HighQuality
     */
    static getHighQuality()
    {
        return new BarcodeSvmDetectorSettings(QualitySettings.HighQuality);
    }

    /**
     * Max quality detection preset.<br>
     *
     * Default for QualitySettings.PresetType.MaxQualityDetection and QualitySettings.PresetType.MaxBarCodes
     */
    static getMaxQuality()
    {
        return new BarcodeSvmDetectorSettings(QualitySettings.MaxQuality);
    }
}

/**
 * Stores recognized barcode data like SingleDecodeType type, {@code string} codetext,<br>
 * BarCodeRegionParameters region and other parameters
 * @example
 * //This sample shows how to obtain BarCodeResult.
 * let generator = new BarcodeGenerator(EncodeTypes.Code128, "12345");
 * generator.save("test.png");
 * let reader = new BarCodeReader("test.png", null,  [ DecodeType.CODE_39_STANDARD, DecodeType.CODE_128 ]);
 * reader.readBarCodes().forEach(function(result, i, results)
 * {
 *     console.log("BarCode Type: " + result.getCodeTypeName());
 *     console.log("BarCode CodeText: " + result.getCodeText());
 *     console.log("BarCode Confidence: " + result.getConfidence());
 *     console.log("BarCode ReadingQuality: " + result.getReadingQuality());
 *     console.log("BarCode Angle: " + result.getRegion().getAngle());
 * });
 */
class BarCodeResult extends joint.BaseJavaClass
{
    region;
    extended;

    constructor(javaclass)
    {
        super(javaclass);
        this.init()
    }

    init()
    {
        this.region = new BarCodeRegionParameters(this.getJavaClass().getRegionSync());
        this.extended = new BarCodeExtendedParameters(this.getJavaClass().getExtendedSync());
    }

    /**
     *  Gets the reading quality. Works for 1D and postal barcodes. Value: The reading quality percent
     */
    getReadingQuality()
    {
        return this.getJavaClass().getReadingQualitySync();
    }

    /**
     *  Gets recognition confidence level of the recognized barcode Value: <br>
     *  BarCodeConfidence.Strong does not have fakes or misrecognitions, BarCodeConfidence.Moderate<br>
     * could sometimes have fakes or incorrect codetext because this confidence level for barcodews with weak cheksum or even without it,<br>
     * BarCodeConfidence.NONE always has incorrect codetext and could be fake recognitions
     */
    getConfidence()
    {
        return this.getJavaClass().getConfidenceSync();
    }

    /**
     *  Gets the code text Value: The code text of the barcode
     */
    getCodeText()
    {
        return this.getJavaClass().getCodeTextSync();
    }

    /**
     *  Gets the encoded code bytes Value: The code bytes of the barcode
     */
    getCodeBytes()
    {
        let str = this.getJavaClass().getCodeBytesSync();
        return str.split(",");
    }

    /**
     *  Gets the barcode type Value: The type information of the recognized barcode
     */
    getCodeType()
    {
        return this.getJavaClass().getCodeTypeSync();
    }

    /**
     *  Gets the name of the barcode type Value: The type name of the recognized barcode
     */
    getCodeTypeName()
    {
        return this.getJavaClass().getCodeTypeNameSync();
    }

    /**
     *  Gets the barcode region Value: The region of the recognized barcode
     */
    getRegion()
    {
        return this.region;
    }

    /**
     *  Gets extended parameters of recognized barcode Value: The extended parameters of recognized barcode
     */
    getExtended()
    {
        return this.extended;
    }

    /**
     * Returns a value indicating whether this instance is equal to a specified BarCodeResult value.
     *
     * @param other An BarCodeResult value to compare to this instance.
     * @return true if obj has the same value as this instance; otherwise, false.
     */
    equals(other)
    {
        return this.getJavaClass().equalsSync(other.getJavaClass());
    }

    /**
     * Returns the hash code for this instance.
     *
     * @return A 32-bit signed integer hash code.
     */
    hashCode()
    {
        return this.getJavaClass().hashCodeSync();
    }

    /**
     * Returns a human-readable string representation of this BarCodeResult.
     *
     * @return A string that represents this BarCodeResult.
     */
    toString()
    {
        return this.getJavaClass().toStringSync();
    }

    /**
     * Creates a copy of BarCodeResult class.
     *
     * @return Returns copy of BarCodeResult class.
     */
    deepClone()
    {
        return new BarCodeResult(this);
    }
}

/**
 * Represents the recognized barcode's region and barcode angle
 * @example
 * //This sample shows how to get barcode Angle and bounding quadrangle values
 * let generator = new BarcodeGenerator(EncodeTypes.Code128, "12345");
 * generator.save("test.png");
 * let reader = new BarCodeReader("test.png", null,  [ DecodeType.CODE_39_STANDARD, DecodeType.CODE_128 ]);
 * reader.readBarCodes().forEach(function(result, i, results)
 * {
 *    console.log("BarCode CodeText: " + result.getCodeText());
 *    console.log("BarCode Angle: " + result.getRegion().getAngle());
 *    console.log("BarCode Quadrangle: " + result.getRegion().getQuadrangle());
 * });
 */
class BarCodeRegionParameters extends joint.BaseJavaClass
{
    quad;
    rect;
    points;

    constructor(javaclass)
    {
        super(javaclass);
        this.init()
    }

    init()
    {
        this.quad = Quadrangle.construct(this.getJavaClass().getQuadrangleSync());
        this.rect = joint.Rectangle.construct(this.getJavaClass().getRectangleSync());
        this.points = BarCodeRegionParameters.convertJavaPoints(this.getJavaClass().getPointsSync());
        // TODO: Implement init() method.
    }

    static convertJavaPoints(javaPoints)
    {
        let points = [];
        for (let i = 0; i < javaPoints.length; i++)
        {
            points[i] = new joint.Point(javaPoints[i].getXSync(), javaPoints[i].getYSync());
        }

        return points;
    }

    /**
     *  Gets Quadrangle bounding barcode region Value: Returns Quadrangle bounding barcode region
     */
    getQuadrangle()
    {
        return this.quad;
    }

    /**
     *  Gets the angle of the barcode (0-360). Value: The angle for barcode (0-360).
     */
    getAngle()
    {
        return this.getJavaClass().getAngleSync();
    }

    /**
     *  Gets Points array bounding barcode region Value: Returns Points array bounding barcode region
     */
    getPoints()
    {
        return this.points;
    }

    /**
     *  Gets Rectangle bounding barcode region Value: Returns Rectangle bounding barcode region
     */
    getRectangle()
    {
        return this.rect;
    }

    /**
     * Returns a value indicating whether this instance is equal to a specified BarCodeRegionParameters value.<br>
     *
     * @param obj An System.Object value to compare to this instance.<br>
     * @return true if obj has the same value as this instance; otherwise, false.
     */
    equals(obj)
    {
        return this.getJavaClass().equalsSync(obj.getJavaClass());
    }

    /**
     * Returns the hash code for this instance.<br>
     *
     * @return A 32-bit signed integer hash code.
     */
    hashCode()
    {
        return this.getJavaClass().hashCodeSync();
    }

    /**
     * Returns a human-readable string representation of this BarCodeRegionParameters.<br>
     *
     * @return A string that represents this BarCodeRegionParameters.
     */
    toString()
    {
        return this.getJavaClass().toStringSync();
    }
}

class BarCodeExtendedParameters extends joint.BaseJavaClass
{
    _oneDParameters;
    _code128Parameters;
    _qrParameters;
    _pdf417Parameters;
    _dataBarParameters;

    constructor(javaclass)
    {
        super(javaclass);
        this.init()
    }

    init()
    {
        this._oneDParameters = new OneDExtendedParameters(this.getJavaClass().getOneDSync());
        this._code128Parameters = new Code128ExtendedParameters(this.getJavaClass().getCode128Sync());
        this._qrParameters = new QRExtendedParameters(this.getJavaClass().getQRSync());
        this._pdf417Parameters = new Pdf417ExtendedParameters(this.getJavaClass().getPdf417Sync());
        this._dataBarParameters = new DataBarExtendedParameters(this.getJavaClass().getDataBarSync());
    }

    /** Gets a DataBar additional information DataBarExtendedParameters  of recognized barcode<br>
     * @return mixed A DataBar additional information DataBarExtendedParameters of recognized barcode
     */
    getDataBar()
    {
        return this._dataBarParameters;
    }

    /**
     *  Gets a special data OneDExtendedParameters of 1D recognized barcode Value: A special data OneDExtendedParameters of 1D recognized barcode
     */
    getOneD()
    {
        return this._oneDParameters;
    }

    /**
     *  Gets a special data Code128ExtendedParameters of Code128 recognized barcode Value: A special data Code128ExtendedParameters of Code128 recognized barcode
     */
    getCode128()
    {
        return this._code128Parameters;
    }

    /**
     *  Gets a QR Structured Append information QRExtendedParameters of recognized barcode Value: A QR Structured Append information QRExtendedParameters of recognized barcode
     */
    getQR()
    {
        return this._qrParameters;
    }

    /**
     *  Gets a MacroPdf417 metadata information Pdf417ExtendedParameters of recognized barcode Value: A MacroPdf417 metadata information Pdf417ExtendedParameters of recognized barcode
     */
    getPdf417()
    {
        return this._pdf417Parameters;
    }

    /**
     * Returns a value indicating whether this instance is equal to a specified BarCodeExtendedParameters value.<br>
     *
     * @param obj An System.Object value to compare to this instance.
     * @return true if obj has the same value as this instance; otherwise, false.
     */
    equals(obj)
    {
        return this.getJavaClass().equalsSync(obj.getJavaClass());
    }

    /**
     * Returns the hash code for this instance.
     *
     * @return A 32-bit signed integer hash code.
     */
    hashCode()
    {
        return this.getJavaClass().hashCodeSync();
    }

    /**
     * Returns a human-readable string representation of this BarCodeExtendedParameters.
     *
     * @return A string that represents this BarCodeExtendedParameters.
     */
    toString()
    {
        return this.getJavaClass().toStringSync();
    }
}

/**
 * QualitySettings allows to configure recognition quality and speed manually.
 * You can quickly set up QualitySettings by embedded presets: HighPerformance, NormalQuality,
 * HighQuality, MaxBarCodes or you can manually configure separate options.
 * Default value of QualitySettings is NormalQuality.
 * @example
 * //This sample shows how to use QualitySettings with BarCodeReader
 * let reader = new BarCodeReader("test.png", null,  [ DecodeType.CODE_39_STANDARD, DecodeType.CODE_128 ]);
 * //set high performance mode
 * reader.setQualitySettings(QualitySettings.getHighPerformance());
 * reader.readBarCodes().forEach(function(result, i, results)
 * {
 *    console.log("BarCode CodeText: " + result.getCodeText());
 * });
 * let reader = new BarCodeReader("test.png", null,  [ DecodeType.CODE_39_STANDARD, DecodeType.CODE_128 ]);
 * //normal quality mode is set by default
 * reader.readBarCodes().forEach(function(result, i, results)
 * {
 *   console.log("BarCode CodeText: " + result.getCodeText());
 * });
 * let reader = new BarCodeReader("test.png", null,  [ DecodeType.CODE_39_STANDARD, DecodeType.CODE_128 ]);
 * //set high quality mode with low speed recognition
 * reader.setQualitySettings(QualitySettings.getHighQuality());
 * reader.readBarCodes().forEach(function(result, i, results)
 * {
 *   console.log("BarCode CodeText: " + result.getCodeText());
 * });
 * let reader = new BarCodeReader("test.png", null,  [ DecodeType.CODE_39_STANDARD, DecodeType.CODE_128 ]);
 * //set max barcodes mode, which tries to find all possible barcodes, even incorrect. The slowest recognition mode
 * reader.setQualitySettings(QualitySettings.getMaxBarCodes());
 * reader.readBarCodes().forEach(function(result, i, results)
 * {
 *   console.log("BarCode CodeText: " + result.getCodeText());
 * });
 * let reader = new BarCodeReader("test.png", null,  [ DecodeType.CODE_39_STANDARD, DecodeType.CODE_128 ]);
 * //set high performance mode
 * reader.setQualitySettings(QualitySettings.getHighPerformance());
 * //set separate options
 * reader.getQualitySettings().setAllowMedianSmoothing(true);
 * reader.getQualitySettings().setMedianSmoothingWindowSize(5);
 * reader.readBarCodes().forEach(function(result, i, results)
 * {
 *     console.log("BarCode CodeText: " + result.getCodeText());
 * });
 * let reader = new BarCodeReader("test.png", null,  [ DecodeType.CODE_39_STANDARD, DecodeType.CODE_128 ]);
 * //default mode is NormalQuality
 * //set separate options
 * reader.getQualitySettings().setAllowMedianSmoothing(true);
 * reader.getQualitySettings().setMedianSmoothingWindowSize(5);
 * reader.readBarCodes().forEach(function(result, i, results)
 * {
 *   console.log("BarCode CodeText: " + result.getCodeText());
 * });
 */
class QualitySettings extends joint.BaseJavaClass
{

    static get javaClassName()
    {
        return "com.aspose.mw.barcode.recognition.MwQualitySettings";
    }

    detectorSettings;

    constructor(qualitySettings)
    {
        super(QualitySettings.initQualitySettings(qualitySettings));
        if (qualitySettings instanceof QualitySettings)
        {
            this.applyAll(qualitySettings);
        }
        this.init();
    }

    static initQualitySettings(qualitySettings)
    {
        let javaClassName = "com.aspose.mw.barcode.recognition.MwQualitySettings";
        if (qualitySettings instanceof QualitySettings || (qualitySettings === null))
        {
            let QualitySettings = java.import(javaClassName);
            return new QualitySettings();
        }
        else
        {
            return qualitySettings;
        }
    }

    init()
    {
        this.detectorSettings = new BarcodeSvmDetectorSettings(this.getJavaClass().getDetectorSettingsSync());
    }

    /**
     * HighPerformance recognition quality preset. High quality barcodes are recognized well in this mode.<br>
     * @example
     * let reader = new BarCodeReader("test.png");
     * reader.setQualitySettings(QualitySettings.getHighPerformance());
     *
     *  Value:
     * HighPerformance recognition quality preset.
     */
    static getHighPerformance()
    {
        let JavaQualitySettings = java.import(QualitySettings.javaClassName);
        return new QualitySettings(JavaQualitySettings.getHighPerformanceSync());
    }

    /**
     * NormalQuality recognition quality preset. Suitable for the most of barcodes
     *
     * @example
     * let reader = new BarCodeReader("test.png");
     * reader.setQualitySettings(QualitySettings.getNormalQuality());
     *
     *  Value:
     * NormalQuality recognition quality preset.
     */
    static getNormalQuality()
    {
        let JavaQualitySettings = java.import(QualitySettings.javaClassName);
        return new QualitySettings(JavaQualitySettings.getNormalQualitySync());
    }

    /**
     * HighQualityDetection recognition quality preset. Same as NormalQuality but with high quality DetectorSettings
     *
     * @example
     * let reader = new BarCodeReader("test.png");
     * reader.setQualitySettings(QualitySettings.getHighQualityDetection());     *
     *
     *  Value:
     * HighQualityDetection recognition quality preset.
     */
    static getHighQualityDetection()
    {
        let JavaQualitySettings = java.import(QualitySettings.javaClassName);
        return new QualitySettings(JavaQualitySettings.getHighQualityDetectionSync());
    }

    /**
     * MaxQualityDetection recognition quality preset. Same as NormalQuality but with highest quality DetectorSettings.
     * Allows to detect diagonal and damaged barcodes.
     *
     * @example
     *let reader = new BarCodeReader("test.png");
     * reader.setQualitySettings(QualitySettings.getMaxQualityDetection());
     *
     *  Value:
     * MaxQualityDetection recognition quality preset.
     */
    static getMaxQualityDetection()
    {
        let JavaQualitySettings = java.import(QualitySettings.javaClassName);
        return new QualitySettings(JavaQualitySettings.getMaxQualityDetectionSync());
    }

    /**
     * HighQuality recognition quality preset. This preset is developed for low quality barcodes.
     *
     * @example
     *let reader = new BarCodeReader("test.png");
     * reader.setQualitySettings(QualitySettings.getHighQuality());
     *
     *  Value:
     * HighQuality recognition quality preset.
     */
    static getHighQuality()
    {
        let JavaQualitySettings = java.import(QualitySettings.javaClassName);
        return new QualitySettings(JavaQualitySettings.getHighQualitySync());
    }

    /**
     * MaxBarCodes recognition quality preset. This preset is developed to recognize all possible barcodes, even incorrect barcodes.
     *
     * @example
     * let reader = new BarCodeReader("test.png");
     * reader.setQualitySettings(QualitySettings.getMaxBarCodes());
     *
     *  Value:
     * MaxBarCodes recognition quality preset.
     */
    static getMaxBarCodes()
    {
        let JavaQualitySettings = java.import(QualitySettings.javaClassName);
        return new QualitySettings(JavaQualitySettings.getMaxBarCodesSync());
    }


    /**
     * Allows engine to recognize inverse color image as additional scan. Mode can be used when barcode is white on black background.
     *  Value:
     * Allows engine to recognize inverse color image.
     */
    getAllowInvertImage()
    {
        return this.getJavaClass().getAllowInvertImageSync();
    }

    /**
     * Allows engine to recognize inverse color image as additional scan. Mode can be used when barcode is white on black background.
     *  Value:
     * Allows engine to recognize inverse color image.
     */
    setAllowInvertImage(value)
    {
        this.getJavaClass().setAllowInvertImageSync(value);
    }

    /**
     * Allows engine to recognize barcodes which has incorrect checksumm or incorrect values.
     * Mode can be used to recognize damaged barcodes with incorrect text.
     *  Value:
     * Allows engine to recognize incorrect barcodes.
     */
    getAllowIncorrectBarcodes()
    {
        return this.getJavaClass().getAllowIncorrectBarcodesSync();
    }

    /**
     * Allows engine to recognize barcodes which has incorrect checksumm or incorrect values.
     * Mode can be used to recognize damaged barcodes with incorrect text.
     *  Value:
     * Allows engine to recognize incorrect barcodes.
     */
    setAllowIncorrectBarcodes(value)
    {
        this.getJavaClass().setAllowIncorrectBarcodesSync(value);
    }

    /**
     *  Allows engine to recognize tiny barcodes on large images. Ignored if <see cref="AllowIncorrectBarcodes"/> is set to True. Default value: False.
     * @return If True, allows engine to recognize tiny barcodes on large images.
     */
    getReadTinyBarcodes()
    {
        return this.getJavaClass().getReadTinyBarcodesSync();
    }

    /**
     * Allows engine to recognize tiny barcodes on large images. Ignored if <see cref="AllowIncorrectBarcodes"/> is set to True. Default value: False.
     * @param value If True, allows engine to recognize tiny barcodes on large images.
     */
    setReadTinyBarcodes(value)
    {
        this.getJavaClass().setReadTinyBarcodesSync(value);
    }

    /**
     * Allows engine to recognize 1D barcodes with checksum by checking more recognition variants. Default value: False.
     * @return If True, allows engine to recognize 1D barcodes with checksum.
     */
    getCheckMore1DVariants()
    {
        return this.getJavaClass().getCheckMore1DVariantsSync();
    }

    /**
     * Allows engine to recognize 1D barcodes with checksum by checking more recognition variants. Default value: False.
     * @param value If True, allows engine to recognize 1D barcodes with checksum.
     */
    setCheckMore1DVariants(value)
    {
        this.getJavaClass().setCheckMore1DVariantsSync(value);
    }

    /**
     * Allows engine to recognize color barcodes on color background as additional scan. Extremely slow mode.
     *  Value:
     * Allows engine to recognize color barcodes on color background.
     */
    getAllowComplexBackground()
    {
        return this.getJavaClass().getAllowComplexBackgroundSync();
    }

    /**
     * Allows engine to recognize color barcodes on color background as additional scan. Extremely slow mode.
     *  Value:v
     * Allows engine to recognize color barcodes on color background.
     */
    setAllowComplexBackground(value)
    {
        this.getJavaClass().setAllowComplexBackgroundSync(value);
    }

    /**
     * Allows engine to enable median smoothing as additional scan. Mode helps to recognize noised barcodes.
     *  Value:
     * Allows engine to enable median smoothing.
     */
    getAllowMedianSmoothing()
    {
        return this.getJavaClass().getAllowMedianSmoothingSync();
    }

    /**
     * Allows engine to enable median smoothing as additional scan. Mode helps to recognize noised barcodes.
     *  Value:
     * Allows engine to enable median smoothing.
     */
    setAllowMedianSmoothing(value)
    {
        this.getJavaClass().setAllowMedianSmoothingSync(value);
    }

    /**
     * Window size for median smoothing. Typical values are 3 or 4. Default value is 3. AllowMedianSmoothing must be set.
     *  Value:
     * Window size for median smoothing.
     */
    getMedianSmoothingWindowSize()
    {
        return this.getJavaClass().getMedianSmoothingWindowSizeSync();
    }

    /**
     * Window size for median smoothing. Typical values are 3 or 4. Default value is 3. AllowMedianSmoothing must be set.
     *  Value:
     * Window size for median smoothing.
     */
    setMedianSmoothingWindowSize(value)
    {
        this.getJavaClass().setMedianSmoothingWindowSizeSync(value);
    }

    /**
     * Allows engine to recognize regular image without any restorations as main scan. Mode to recognize image as is.
     *  Value:
     * Allows to recognize regular image without any restorations.
     */

    getAllowRegularImage()
    {
        return this.getJavaClass().getAllowRegularImageSync();
    }

    /**
     * Allows engine to recognize regular image without any restorations as main scan. Mode to recognize image as is.
     *  Value:
     * Allows to recognize regular image without any restorations.
     */

    setAllowRegularImage(value)
    {
        this.getJavaClass().setAllowRegularImageSync(value);
    }

    /**
     * Allows engine to recognize decreased image as additional scan. Size for decreasing is selected by internal engine algorithms.
     * Mode helps to recognize barcodes which are noised and blurred but captured with high resolution.
     *  Value:
     * Allows engine to recognize decreased image
     */
    getAllowDecreasedImage()
    {
        return this.getJavaClass().getAllowDecreasedImageSync();
    }

    /**
     * Allows engine to recognize decreased image as additional scan. Size for decreasing is selected by internal engine algorithms.
     * Mode helps to recognize barcodes which are noised and blurred but captured with high resolution.
     *  Value:
     * Allows engine to recognize decreased image
     */
    setAllowDecreasedImage(value)
    {
        this.getJavaClass().setAllowDecreasedImageSync(value);
    }

    /**
     * Allows engine to recognize image without small white spots as additional scan. Mode helps to recognize noised image as well as median smoothing filtering.
     *  Value:
     * Allows engine to recognize image without small white spots.
     */

    getAllowWhiteSpotsRemoving()
    {
        return this.getJavaClass().getAllowWhiteSpotsRemovingSync();
    }

    /**
     * Allows engine to recognize image without small white spots as additional scan. Mode helps to recognize noised image as well as median smoothing filtering.
     *  Value:
     * Allows engine to recognize image without small white spots.
     */
    setAllowWhiteSpotsRemoving(value)
    {
        this.getJavaClass().setAllowWhiteSpotsRemovingSync(value);
    }

    /**
     * Allows engine for 1D barcodes to recognize regular image with different params as additional scan. Mode helps to recongize low height 1D barcodes.
     *  Value:
     * Allows engine for 1D barcodes to run additional scan.
     */
    getAllowOneDAdditionalScan()
    {
        return this.getJavaClass().getAllowOneDAdditionalScanSync();
    }

    /**
     * Allows engine for 1D barcodes to recognize regular image with different params as additional scan. Mode helps to recongize low height 1D barcodes.
     *  Value:
     * Allows engine for 1D barcodes to run additional scan.
     */
    setAllowOneDAdditionalScan(value)
    {
        this.getJavaClass().setAllowOneDAdditionalScanSync(value);
    }

    /**
     * Allows engine for 1D barcodes to quickly recognize high quality barcodes which fill almost whole image.
     * Mode helps to quickly recognize generated barcodes from Internet.
     *  Value:
     * Allows engine for 1D barcodes to quickly recognize high quality barcodes.
     */
    getAllowOneDFastBarcodesDetector()
    {
        return this.getJavaClass().getAllowOneDFastBarcodesDetectorSync();
    }

    /**
     * Allows engine for 1D barcodes to quickly recognize high quality barcodes which fill almost whole image.
     * Mode helps to quickly recognize generated barcodes from Internet.
     *  Value:
     * Allows engine for 1D barcodes to quickly recognize high quality barcodes.
     */
    setAllowOneDFastBarcodesDetector(value)
    {
        this.getJavaClass().setAllowOneDFastBarcodesDetectorSync(value);
    }

    /**
     * Allows engine for Postal barcodes to recognize slightly noised images. Mode helps to recognize sligtly damaged Postal barcodes.
     *  Value:
     * Allows engine for Postal barcodes to recognize slightly noised images.
     */
    getAllowMicroWhiteSpotsRemoving()
    {
        return this.getJavaClass().getAllowMicroWhiteSpotsRemovingSync();
    }

    /**
     * Allows engine for Postal barcodes to recognize slightly noised images. Mode helps to recognize sligtly damaged Postal barcodes.
     *  Value:
     * Allows engine for Postal barcodes to recognize slightly noised images.
     */
    setAllowMicroWhiteSpotsRemoving(value)
    {
        this.getJavaClass().setAllowMicroWhiteSpotsRemovingSync(value);
    }

    /**
     * Allows engine for 1D barcodes to quickly recognize middle slice of an image and return result without using any time-consuming algorithms.
     * @return Allows engine for 1D barcodes to quickly recognize high quality barcodes.
     */
    getFastScanOnly()
    {
        return this.getJavaClass().getFastScanOnlySync();
    }

    /**
     * Allows engine for 1D barcodes to quickly recognize middle slice of an image and return result without using any time-consuming algorithms.
     * @param value Allows engine for 1D barcodes to quickly recognize high quality barcodes.
     */
    setFastScanOnly(value)
    {
        this.getJavaClass().setFastScanOnlySync(value);
    }

    /**
     * Allows engine to recognize barcodes with salt and paper noise type. Mode can remove small noise with white and black dots.
     *  Value:
     * Allows engine to recognize barcodes with salt and paper noise type.
     */
    getAllowSaltAndPaperFiltering()
    {
        return this.getJavaClass().getAllowSaltAndPaperFilteringSync();
    }

    /**
     * Allows engine to recognize barcodes with salt and paper noise type. Mode can remove small noise with white and black dots.
     *  Value:
     * Allows engine to recognize barcodes with salt and paper noise type.
     */
    setAllowSaltAndPaperFiltering(value)
    {
        this.getJavaClass().setAllowSaltAndPaperFilteringSync(value);
    }

    /**
     * Allows engine to use gap between scans to increase recognition speed. Mode can make recognition problems with low height barcodes.
     *  Value:
     * Allows engine to use gap between scans to increase recognition speed.
     */
    getAllowDetectScanGap()
    {
        return this.getJavaClass().getAllowDetectScanGapSync();
    }

    /**
     * Allows engine to use gap between scans to increase recognition speed. Mode can make recognition problems with low height barcodes.
     *  Value:
     * Allows engine to use gap between scans to increase recognition speed.
     */
    setAllowDetectScanGap(value)
    {
        this.getJavaClass().setAllowDetectScanGapSync(value);
    }

    /**
     * Allows engine for Datamatrix to recognize dashed industrial Datamatrix barcodes.
     * Slow mode which helps only for dashed barcodes which consist from spots.
     *  Value:
     * Allows engine for Datamatrix to recognize dashed industrial barcodes.
     */
    getAllowDatamatrixIndustrialBarcodes()
    {
        return this.getJavaClass().getAllowDatamatrixIndustrialBarcodesSync();
    }

    /**
     * Allows engine for Datamatrix to recognize dashed industrial Datamatrix barcodes.
     * Slow mode which helps only for dashed barcodes which consist from spots.
     *  Value:
     * Allows engine for Datamatrix to recognize dashed industrial barcodes.
     */
    setAllowDatamatrixIndustrialBarcodes(value)
    {
        this.getJavaClass().setAllowDatamatrixIndustrialBarcodesSync(value);
    }

    /**
     * Allows engine for QR/MicroQR to recognize damaged MicroQR barcodes.
     *  Value:
     * Allows engine for QR/MicroQR to recognize damaged MicroQR barcodes.
     */
    getAllowQRMicroQrRestoration()
    {
        return this.getJavaClass().getAllowQRMicroQrRestorationSync();
    }

    /**
     * Allows engine for QR/MicroQR to recognize damaged MicroQR barcodes.
     *  Value:
     * Allows engine for QR/MicroQR to recognize damaged MicroQR barcodes.
     */
    setAllowQRMicroQrRestoration(value)
    {
        this.getJavaClass().setAllowQRMicroQrRestorationSync(value);
    }

    /**
     * Allows engine for 1D barcodes to recognize barcodes with single wiped/glued bars in pattern.
     *  Value:
     * Allows engine for 1D barcodes to recognize barcodes with single wiped/glued bars in pattern.
     */
    getAllowOneDWipedBarsRestoration()
    {
        return this.getJavaClass().getAllowOneDWipedBarsRestorationSync();
    }

    /**
     * Allows engine for 1D barcodes to recognize barcodes with single wiped/glued bars in pattern.
     *  Value:
     * Allows engine for 1D barcodes to recognize barcodes with single wiped/glued bars in pattern.
     */
    setAllowOneDWipedBarsRestoration(value)
    {
        this.getJavaClass().setAllowOneDWipedBarsRestorationSync(value);
    }

    /**
     * Barcode detector settings.
     */
    getDetectorSettings()
    {
        return this.detectorSettings;
    }

    /**
     * Barcode detector settings.
     */
    setDetectorSettings(value)
    {
        this.getJavaClass().setDetectorSettingsSync(value);
        this.detectorSettings = value;
    }

    /**
     * apply all values from Src setting to this
     * @param Src source settings
     */
    applyAll(Src)
    {
        this.setAllowInvertImage(Src.getAllowInvertImage());
        this.setAllowIncorrectBarcodes(Src.getAllowIncorrectBarcodes());
        this.setAllowComplexBackground(Src.getAllowComplexBackground());
        this.setAllowMedianSmoothing(Src.getAllowMedianSmoothing());
        this.setMedianSmoothingWindowSize(Src.getMedianSmoothingWindowSize());
        this.setAllowRegularImage(Src.getAllowRegularImage());
        this.setAllowDecreasedImage(Src.getAllowDecreasedImage());
        this.setAllowWhiteSpotsRemoving(Src.getAllowWhiteSpotsRemoving());
        this.setAllowOneDAdditionalScan(Src.getAllowOneDAdditionalScan());
        this.setAllowOneDFastBarcodesDetector(Src.getAllowOneDFastBarcodesDetector());
        this.setAllowMicroWhiteSpotsRemoving(Src.getAllowMicroWhiteSpotsRemoving());
        this.setAllowSaltAndPaperFiltering(Src.getAllowSaltAndPaperFiltering());
        this.setAllowDetectScanGap(Src.getAllowDetectScanGap());
    }
}

/**
 * Contains the data of subtype for Code128 type barcode
 */
class Code128DataPortion extends joint.BaseJavaClass
{
    static get javaClassName()
    {
        return "com.aspose.mw.barcode.recognition.MwCode128DataPortion";
    }

    /**
     * Creates a new instance of the {@code Code128DataPortion} class with start code symbol and decoded codetext.
     *
     * @param code128SubType A start encoding symbol
     * @param data A partial codetext
     */
    constructor(code128SubType, data)
    {
        let java_link = java.import(Code128DataPortion.javaClassName);
        let code128DataPortion = new java_link(code128SubType + "", data);
        super(code128DataPortion);
        this.init();
    }

    static construct(javaClass)
    {
        let code128DataPortion = new Code128DataPortion(0, "");
        code128DataPortion.setJavaClass(javaClass);
        return code128DataPortion;
    }

    /**
     * Gets the part of code text related to subtype.
     *
     * @return The part of code text related to subtype
     */
    getData()
    {
        return this.getJavaClass().getDataSync();
    }

    /**
     * Gets the part of code text related to subtype.
     *
     * @return The part of code text related to subtype
     */
    setData(value)
    {
        this.getJavaClass().setDataSync(value);
    }

    /**
     * Gets the type of Code128 subset
     *
     * @return The type of Code128 subset
     */
    getCode128SubType()
    {
        return this.getJavaClass().getCode128SubTypeSync();
    }

    /**
     * Gets the type of Code128 subset
     *
     * @return The type of Code128 subset
     */
    setCode128SubType(value)
    {
        this.getJavaClass().setCode128SubTypeSync(value);
    }

    init()
    {
    }

    /**
     * Returns a human-readable string representation of this {@code Code128DataPortion}.
     * @return A string that represents this {@code Code128DataPortion}.
     */
    toString()
    {
        return this.getJavaClass().toStringSync();
    }
}

/**
 * Stores a DataBar additional information of recognized barcode
 *@example
 *  let reader = new BarCodeReader("c:\\test.png", DecodeType.DATABAR_OMNI_DIRECTIONAL);
 * reader.readBarCodes().forEach(function(result, i, results)
 * {
 *    console.log("BarCode Type: " + result.getCodeTypeName());
 *    console.log("BarCode CodeText: " + result.getCodeText());
 *    console.log("QR Structured Append Quantity: " + result.getExtended().getQR().getQRStructuredAppendModeBarCodesQuantity());
 * });
 */
class DataBarExtendedParameters extends joint.BaseJavaClass
{

    init()
    {
        // TODO: Implement init() method.
    }

    /**
     * Gets the DataBar 2D composite component flag. Default value is false.
     * @return The DataBar 2D composite component flag.
     */
    is2DCompositeComponent()
    {
        return this.getJavaClass().is2DCompositeComponentSync();
    }

    /**
     * Returns a value indicating whether this instance is equal to a specified DataBarExtendedParameters value.<br>
     * @param obj DataBarExtendedParameters value to compare to this instance.<br>
     * @return true if obj has the same value as this instance; otherwise, false<br>.
     */
    equals(obj)
    {
        return this.getJavaClass().equalsSync(obj.getJavaClass());
    }

    /**
     * Returns the hash code for this instance.
     * @return A 32-bit signed integer hash code.
     */
    hashcode()
    {
        return this.getJavaClass().hashcodeSync();
    }

    /**
     * Returns a human-readable string representation of this <see cref="DataBarExtendedParameters"/>.
     * @return A string that represents this <see cref="DataBarExtendedParameters"/>.
     */
    toString()
    {
        return this.getJavaClass().toStringSync();
    }
}

/**
 * AustraliaPost decoding parameters. Contains parameters which make influence on recognized data of AustraliaPost symbology.
 */
class AustraliaPostSettings extends joint.BaseJavaClass
{
    static get javaClassName()
    {
        return "com.aspose.mw.barcode.recognition.MwAustraliaPostSettings";
    }

    init()
    {
    }

    /**
     * AustraliaPostSettings constructor
     */
    constructor(settings)
    {
        if (settings != null)
        {
            super(settings.getJavaClass());
        } else
        {
            let java_link = java.import(AustraliaPostSettings.javaClassName);
            let australiaPostSettings = new java_link();
            super(australiaPostSettings);
        }
    }

    static construct(javaClass)
    {
        let australiaPostSettings = new AustraliaPostSettings(null);
        australiaPostSettings.setJavaClass(javaClass);
        return australiaPostSettings;
    }

    /**
     * Gets or sets the Interpreting Type for the Customer Information of AustralianPost BarCode.DEFAULT is CustomerInformationInterpretingType.OTHER.
     * @return The interpreting type (CTable, NTable or Other) of customer information for AustralianPost BarCode
     */
    getCustomerInformationInterpretingType()
    {
        return this.getJavaClass().getCustomerInformationInterpretingTypeSync();
    }

    /**
     * Gets or sets the Interpreting Type for the Customer Information of AustralianPost BarCode.DEFAULT is CustomerInformationInterpretingType.OTHER.
     * @param value The interpreting type (CTable, NTable or Other) of customer information for AustralianPost BarCode
     */
    setCustomerInformationInterpretingType(value)
    {
        this.getJavaClass().setCustomerInformationInterpretingTypeSync(value);
    }

    /**
     * The flag which force AustraliaPost decoder to ignore last filling patterns in Customer Information Field during decoding as CTable method.
     * CTable encoding method does not have any gaps in encoding table and sequnce "333" of filling paterns is decoded as letter "z".
     *
     * Example
     *
     * let generator = new BarcodeGenerator(EncodeTypes.AUSTRALIA_POST, "5912345678AB");
     * generator.getParameters().getBarcode().getAustralianPost().setAustralianPostEncodingTable(CustomerInformationInterpretingType.C_TABLE);
     * let image = generator.generateBarCodeImage(BarcodeImageFormat.PNG);
     * let reader = new BarCodeReader(image, null, DecodeType.AUSTRALIA_POST);
     * reader.getBarcodeSettings().getAustraliaPost().setCustomerInformationInterpretingType(CustomerInformationInterpretingType.C_TABLE);
     * reader.getBarcodeSettings().getAustraliaPost().setIgnoreEndingFillingPatternsForCTable(true);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *     console.log("BarCode Type: ".result.getCodeType());
     *     console.log("BarCode CodeText: ".result.getCodeText());
     * });
     *
     * @return The flag which force AustraliaPost decoder to ignore last filling patterns during CTable method decoding
     */
    getIgnoreEndingFillingPatternsForCTable()
    {
        return this.getJavaClass().getIgnoreEndingFillingPatternsForCTableSync();
    }

    setIgnoreEndingFillingPatternsForCTable(value)
    {
        this.getJavaClass().setIgnoreEndingFillingPatternsForCTableSync(value);
    }
}

class BarcodeSettings extends joint.BaseJavaClass
{

    _australiaPost;

    static get javaClassName()
    {
        return "com.aspose.mw.barcode.recognition.MwBarcodeSettings";
    }

    /**
     * BarcodeSettings copy constructor
     * @param settings The source of the data
     */
    constructor(settings)
    {
        if (settings != null)
        {
            super(settings.getJavaClass());
        } else
        {
            let java_link = java.import(BarcodeSettings.javaClassName);
            let barcodeSettings = new java_link();
            super(barcodeSettings);
        }
    }

    /**
     * BarcodeSettings copy constructor
     * @param settings The source of the data
     */
    static construct(javaClass)
    {
        let barcodeSettings = new BarcodeSettings(null);
        barcodeSettings.setJavaClass(javaClass);
        return barcodeSettings;
    }

    init()
    {
        this._australiaPost = AustraliaPostSettings.construct(this.getJavaClass().getAustraliaPostSync());
    }

    /**
     * Enable checksum validation during recognition for 1D and Postal barcodes.
     * Default is treated as Yes for symbologies which must contain checksum, as No where checksum only possible.
     * Checksum never used: Codabar, PatchCode, Pharmacode, DataLogic2of5
     * Checksum is possible: Code39 Standard/Extended, Standard2of5, Interleaved2of5, ItalianPost25, Matrix2of5, MSI, ItalianPost25, DeutschePostIdentcode, DeutschePostLeitcode, VIN
     * Checksum always used: Rest symbologies
     *
     * Example
     *
     * let generator = new BarcodeGenerator(EncodeTypes.EAN_13, "1234567890128");
     * generator.save("c:/test.png", BarcodeImageFormat.PNG);
     * let reader = new BarCodeReader("c:/test.png", DecodeType.EAN_13);
     * //checksum disabled
     * reader.getBarcodeSettings().setChecksumValidation(ChecksumValidation.OFF);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *      console.log ("BarCode CodeText: ".result.getCodeText());
     *      console.log ("BarCode Value: " + result.getExtended().getOneD().getValue());
     *      console.log ("BarCode Checksum: " + result.getExtended().getOneD().getCheckSum());
     * });
     * let reader = new BarCodeReader("c:/test.png", DecodeType.EAN_13);
     * //checksum enabled
     * reader.getBarcodeSettings().setChecksumValidation(ChecksumValidation.ON);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *      console.log ("BarCode CodeText: " + result.CodeText);
     *      console.log ("BarCode Value: " + result.getExtended().getOneD().getValue());
     *      console.log ("BarCode Checksum: " + result.getExtended().getOneD().getCheckSum());
     * });
     * @return Enable checksum validation during recognition for 1D and Postal barcodes.
     */
    getChecksumValidation()
    {
        return this.getJavaClass().getChecksumValidationSync();
    }

    /**
     * Enable checksum validation during recognition for 1D and Postal barcodes.
     * Default is treated as Yes for symbologies which must contain checksum, as No where checksum only possible.
     * Checksum never used: Codabar, PatchCode, Pharmacode, DataLogic2of5
     * Checksum is possible: Code39 Standard/Extended, Standard2of5, Interleaved2of5, ItalianPost25, Matrix2of5, MSI, ItalianPost25, DeutschePostIdentcode, DeutschePostLeitcode, VIN
     * Checksum always used: Rest symbologies
     *
     * Example
     *
     * let generator = new BarcodeGenerator(EncodeTypes.EAN_13, "1234567890128");
     * generator.save("c:/test.png", BarcodeImageFormat.PNG);
     * let reader = new BarCodeReader("c:/test.png", DecodeType.EAN_13);
     * //checksum disabled
     * reader.getBarcodeSettings().setChecksumValidation(ChecksumValidation.OFF);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *      console.log ("BarCode CodeText: ".result.getCodeText());
     *      console.log ("BarCode Value: " + result.getExtended().getOneD().getValue());
     *      console.log ("BarCode Checksum: " + result.getExtended().getOneD().getCheckSum());
     * });
     * let reader = new BarCodeReader("c:/test.png", DecodeType.EAN_13);
     * //checksum enabled
     * reader.getBarcodeSettings().setChecksumValidation(ChecksumValidation.ON);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *      console.log ("BarCode CodeText: " + result.CodeText);
     *      console.log ("BarCode Value: " + result.getExtended().getOneD().getValue());
     *      console.log ("BarCode Checksum: " + result.getExtended().getOneD().getCheckSum());
     * });
     * @param value  Enable checksum validation during recognition for 1D and Postal barcodes.
     */
    setChecksumValidation(value)
    {
        this.getJavaClass().setChecksumValidationSync(value);
    }

    /**
     * Strip FNC1, FNC2, FNC3 characters from codetext. Default value is false.
     *
     * Example
     *
     * let generator = new BarcodeGenerator(EncodeTypes.GS_1_CODE_128, "(02)04006664241007(37)1(400)7019590754");
     * generator.save("c:/test.png", BarcodeImageFormat.PNG);
     * let reader = new BarCodeReader("c:/test.png", DecodeType.CODE_128);
     *
     * //StripFNC disabled
     * reader.getBarcodeSettings().setStripFNC(false);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *     console.log ("BarCode CodeText: ".result.getCodeText());
     * });
     *
     * let reader = new BarCodeReader("c:/test.png", DecodeType.CODE_128);
     *
     * //StripFNC enabled
     * reader.getBarcodeSettings().setStripFNC(true);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *     console.log ("BarCode CodeText: ".result.getCodeText());
     * });
     *
     * @return Strip FNC1, FNC2, FNC3 characters from codetext. Default value is false.
     */
    getStripFNC()
    {
        return this.getJavaClass().getStripFNCSync();
    }

    /**
     * Strip FNC1, FNC2, FNC3 characters from codetext. Default value is false.
     *
     * Example
     *
     * let generator = new BarcodeGenerator(EncodeTypes.GS_1_CODE_128, "(02)04006664241007(37)1(400)7019590754");
     * generator.save("c:/test.png", BarcodeImageFormat.PNG);
     * let reader = new BarCodeReader("c:/test.png", DecodeType.CODE_128);
     *
     * //StripFNC disabled
     * reader.getBarcodeSettings().setStripFNC(false);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *     console.log ("BarCode CodeText: ".result.getCodeText());
     * });
     *
     * let reader = new BarCodeReader("c:/test.png", DecodeType.CODE_128);
     *
     * //StripFNC enabled
     * reader.getBarcodeSettings().setStripFNC(true);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *     console.log ("BarCode CodeText: ".result.getCodeText());
     * });
     *
     * @param value  Strip FNC1, FNC2, FNC3 characters from codetext. Default value is false.
     */
    setStripFNC(value)
    {
        this.getJavaClass().setStripFNCSync(value);
    }

    /**
     * The flag which force engine to detect codetext encoding for Unicode codesets. Default value is true.
     *
     * Example
     *
     * let generator = new BarcodeGenerator(EncodeTypes.QR, "Слово"))
     * $im = generator.generateBarcodeImage(BarcodeImageFormat.PNG);
     *
     * //detects encoding for Unicode codesets is enabled
     * let reader = new BarCodeReader(im, DecodeType.QR);
     * reader.getBarcodeSettings().setDetectEncoding(true);
     * reader.readBarCodes().forEach(function(result, i, results)
     * {
     *     console.log ("BarCode CodeText: ".result.getCodeText());
     * });
     * //detect encoding is disabled
     * let reader = new BarCodeReader(im, DecodeType.QR);
     * reader.getBarcodeSettings().setDetectEncoding(false);
     * reader.readBarCodes().forEach(function(result, i, results)
     *     console.log ("BarCode CodeText: " + result.getCodeText());
     *
     * @return The flag which force engine to detect codetext encoding for Unicode codesets
     */
    getDetectEncoding()
    {
        return this.getJavaClass().getDetectEncodingSync();
    }

    setDetectEncoding(value)
    {
        this.getJavaClass().setDetectEncodingSync(value);
    }

    /**
     * Gets AustraliaPost decoding parameters
     * @return The AustraliaPost decoding parameters which make influence on recognized data of AustraliaPost symbology
     */
    getAustraliaPost()
    {
        return this._australiaPost;
    }
}

class RecognitionAbortedException extends Error
{
    javaClass;

    static get javaClassName()
    {
        return "com.aspose.mw.barcode.recognition.MwRecognitionAbortedException";
    }
    /**
     * Gets the execution time of current recognition session
     * @return The execution time of current recognition session
     */
    getExecutionTime()
    {
        return this.javaClass.getExecutionTimeSync();
    }

    /**
     * Sets the execution time of current recognition session
     * @param value The execution time of current recognition session
     */
    setExecutionTime(value)
    {
        this.javaClass.setExecutionTimeSync(value);
    }

    /**
     * Initializes a new instance of the <see cref="RecognitionAbortedException" /> class with specified recognition abort message.
     * @param message The error message of the exception.
     * @param executionTime The execution time of current recognition session.
     */
    constructor(message, executionTime)
    {
        super(message);
        let java_class_link = new java.import(RecognitionAbortedException.javaClassName);
        if(message != null && executionTime != null)
        {
            this.javaClass = new java_class_link(message, executionTime);
        }
        else if (executionTime != null)
        {
            this.javaClass = new java_class_link(executionTime);
        }
        else
            this.javaClass = new java_class_link();
    }

    static construct(javaClass)
    {
        let exception = new RecognitionAbortedException(null, null);
        exception.javaClass = javaClass;
        return exception;
    }

    init()
    {

    }
}

/**
 * Specify the type of barcode to read.
 * @example
 * //This sample shows how to detect Code39 and Code128 barcodes.
 * let reader = new BarCodeReader("test.png", null,  [ DecodeType.CODE_39_STANDARD, DecodeType.CODE_128 ]);
 * reader.readBarCodes().forEach(function(result, i, results)
 * {
 *    console.log("BarCode Type: " + result.getCodeTypeName());
 *    console.log("BarCode CodeText: " + result.getCodeText());
 * });
 *
 * @enum
 */
DecodeType =
    {
        /**
         * Unspecified decode type.
         */
        NONE: -1,

        /**
         * Specifies that the data should be decoded with {@code <b>CODABAR</b>} barcode specification
         */
        CODABAR: 0,

        /**
         * Specifies that the data should be decoded with {@code <b>CODE 11</b>} barcode specification
         */
        CODE_11: 1,

        /**
         * Specifies that the data should be decoded with {@code <b>Standard CODE 39</b>} barcode specification
         */
        CODE_39_STANDARD: 2,

        /**
         * Specifies that the data should be decoded with {@code <b>Extended CODE 39</b>} barcode specification
         */
        CODE_39_EXTENDED: 3,

        /**
         * Specifies that the data should be decoded with {@code <b>Standard CODE 93</b>} barcode specification
         */
        CODE_93_STANDARD: 4,

        /**
         * Specifies that the data should be decoded with {@code <b>Extended CODE 93</b>} barcode specification
         */
        CODE_93_EXTENDED: 5,

        /**
         * Specifies that the data should be decoded with {@code <b>CODE 128</b>} barcode specification
         */
        CODE_128: 6,

        /**
         * Specifies that the data should be decoded with {@code <b>GS1 CODE 128</b>} barcode specification
         */
        GS_1_CODE_128: 7,

        /**
         * Specifies that the data should be decoded with {@code <b>EAN-8</b>} barcode specification
         */
        EAN_8: 8,

        /**
         * Specifies that the data should be decoded with {@code <b>EAN-13</b>} barcode specification
         */
        EAN_13: 9,

        /**
         * Specifies that the data should be decoded with {@code <b>EAN14</b>} barcode specification
         */
        EAN_14: 10,

        /**
         * Specifies that the data should be decoded with {@code <b>SCC14</b>} barcode specification
         */
        SCC_14: 11,

        /**
         * Specifies that the data should be decoded with {@code <b>SSCC18</b>} barcode specification
         */
        SSCC_18: 12,

        /**
         * Specifies that the data should be decoded with {@code <b>UPC-A</b>} barcode specification
         */
        UPCA: 13,

        /**
         * Specifies that the data should be decoded with {@code <b>UPC-E</b>} barcode specification
         */
        UPCE: 14,

        /**
         * Specifies that the data should be decoded with {@code <b>ISBN</b>} barcode specification
         */
        ISBN: 15,

        /**
         * Specifies that the data should be decoded with {@code <b>Standard 2 of 5</b>} barcode specification
         */
        STANDARD_2_OF_5: 16,

        /**
         * Specifies that the data should be decoded with {@code <b>INTERLEAVED 2 of 5</b>} barcode specification
         */
        INTERLEAVED_2_OF_5: 17,

        /**
         * Specifies that the data should be decoded with {@code <b>Matrix 2 of 5</b>} barcode specification
         */
        MATRIX_2_OF_5: 18,

        /**
         * Specifies that the data should be decoded with {@code <b>Italian Post 25</b>} barcode specification
         */
        ITALIAN_POST_25: 19,

        /**
         * Specifies that the data should be decoded with {@code <b>IATA 2 of 5</b>} barcode specification. IATA (International Air Transport Association) uses this barcode for the management of air cargo.
         */
        IATA_2_OF_5: 20,

        /**
         * Specifies that the data should be decoded with {@code <b>ITF14</b>} barcode specification
         */
        ITF_14: 21,

        /**
         * Specifies that the data should be decoded with {@code <b>ITF6</b>} barcode specification
         */
        ITF_6: 22,

        /**
         * Specifies that the data should be decoded with {@code <b>MSI Plessey</b>} barcode specification
         */
        MSI: 23,

        /**
         * Specifies that the data should be decoded with {@code <b>VIN</b>} (Vehicle Identification Number) barcode specification
         */
        VIN: 24,

        /**
         * Specifies that the data should be decoded with {@code <b>DeutschePost Ident code</b>} barcode specification
         */
        DEUTSCHE_POST_IDENTCODE: 25,

        /**
         * Specifies that the data should be decoded with {@code <b>DeutschePost Leit code</b>} barcode specification
         */
        DEUTSCHE_POST_LEITCODE: 26,

        /**
         * Specifies that the data should be decoded with {@code <b>OPC</b>} barcode specification
         */
        OPC: 27,

        /**
         *  Specifies that the data should be decoded with {@code <b>PZN</b>} barcode specification. This symbology is also known as Pharma Zentral Nummer
         */
        PZN: 28,

        /**
         * Specifies that the data should be decoded with {@code <b>Pharmacode</b>} barcode. This symbology is also known as Pharmaceutical BINARY Code
         */
        PHARMACODE: 29,

        /**
         * Specifies that the data should be decoded with {@code <b>DataMatrix</b>} barcode symbology
         */
        DATA_MATRIX: 30,

        /**
         * Specifies that the data should be decoded with {@code <b>GS1DataMatrix</b>} barcode symbology
         */
        GS_1_DATA_MATRIX: 31,

        /**
         * Specifies that the data should be decoded with {@code <b>QR Code</b>} barcode specification
         */
        QR: 32,

        /**
         * Specifies that the data should be decoded with {@code <b>Aztec</b>} barcode specification
         */
        AZTEC: 33,

        /**
         * Specifies that the data should be decoded with {@code <b>Pdf417</b>} barcode symbology
         */
        PDF_417: 34,

        /**
         * Specifies that the data should be decoded with {@code <b>MacroPdf417</b>} barcode specification
         */
        MACRO_PDF_417: 35,

        /**
         * Specifies that the data should be decoded with {@code <b>MicroPdf417</b>} barcode specification
         */
        MICRO_PDF_417: 36,

        /**
         * Specifies that the data should be decoded with {@code <b>CodablockF</b>} barcode specification
         */
        CODABLOCK_F: 65,

        /**
         * Specifies that the data should be decoded with {@code <b>Australia Post</b>} barcode specification
         */
        AUSTRALIA_POST: 37,

        /**
         * Specifies that the data should be decoded with {@code <b>Postnet</b>} barcode specification
         */
        POSTNET: 38,

        /**
         * Specifies that the data should be decoded with {@code <b>Planet</b>} barcode specification
         */
        PLANET: 39,

        /**
         * Specifies that the data should be decoded with USPS {@code <b>OneCode</b>} barcode specification
         */
        ONE_CODE: 40,

        /**
         * Specifies that the data should be decoded with {@code <b>RM4SCC</b>} barcode specification. RM4SCC (Royal Mail 4-state Customer Code) is used for automated mail sort process in UK.
         */
        RM_4_SCC: 41,

        /**
         * Specifies that the data should be decoded with {@code <b>GS1 DATABAR omni-directional</b>} barcode specification
         */
        DATABAR_OMNI_DIRECTIONAL: 42,

        /**
         * Specifies that the data should be decoded with {@code <b>GS1 DATABAR truncated</b>} barcode specification
         */
        DATABAR_TRUNCATED: 43,

        /**
         * Specifies that the data should be decoded with {@code <b>GS1 DATABAR limited</b>} barcode specification
         */
        DATABAR_LIMITED: 44,

        /**
         * Specifies that the data should be decoded with {@code <b>GS1 DATABAR expanded</b>} barcode specification
         */
        DATABAR_EXPANDED: 45,

        /**
         * Specifies that the data should be decoded with {@code <b>GS1 DATABAR stacked omni-directional</b>} barcode specification
         */
        DATABAR_STACKED_OMNI_DIRECTIONAL: 53,

        /**
         * Specifies that the data should be decoded with {@code <b>GS1 DATABAR stacked</b>} barcode specification
         */
        DATABAR_STACKED: 54,

        /**
         * Specifies that the data should be decoded with {@code <b>GS1 DATABAR expanded stacked</b>} barcode specification
         */
        DATABAR_EXPANDED_STACKED: 55,

        /**
         * Specifies that the data should be decoded with {@code <b>Patch code</b>} barcode specification. Barcode symbology is used for automated scanning
         */
        PATCH_CODE: 46,

        /**
         * Specifies that the data should be decoded with {@code <b>ISSN</b>} barcode specification
         */
        ISSN: 47,

        /**
         * Specifies that the data should be decoded with {@code <b>ISMN</b>} barcode specification
         */
        ISMN: 48,

        /**
         * Specifies that the data should be decoded with {@code <b>Supplement(EAN2, EAN5)</b>} barcode specification
         */
        SUPPLEMENT: 49,

        /**
         * Specifies that the data should be decoded with {@code <b>Australian Post Domestic eParcel Barcode</b>} barcode specification
         */
        AUSTRALIAN_POSTE_PARCEL: 50,

        /**
         * Specifies that the data should be decoded with {@code <b>Swiss Post Parcel Barcode</b>} barcode specification
         */
        SWISS_POST_PARCEL: 51,

        /**
         * Specifies that the data should be decoded with {@code <b>SCode16K</b>} barcode specification
         */
        CODE_16_K: 52,

        /**
         * Specifies that the data should be decoded with {@code <b>MicroQR Code</b>} barcode specification
         */
        MICRO_QR: 56,

        /**
         * Specifies that the data should be decoded with {@code <b>CompactPdf417</b>} (Pdf417Truncated) barcode specification
         */
        COMPACT_PDF_417: 57,

        /**
         * Specifies that the data should be decoded with {@code <b>GS1 QR</b>} barcode specification
         */
        GS_1_QR: 58,

        /**
         * Specifies that the data should be decoded with {@code <b>MaxiCode</b>} barcode specification
         */
        MAXI_CODE: 59,

        /**
         * Specifies that the data should be decoded with {@code <b>MICR E-13B</b>} blank specification
         */
        MICR_E_13_B: 60,

        /**
         * Specifies that the data should be decoded with {@code <b>Code32</b>} blank specification
         */
        CODE_32: 61,

        /**
         * Specifies that the data should be decoded with {@code <b>DataLogic 2 of 5</b>} blank specification
         */
        DATA_LOGIC_2_OF_5: 62,

        /**
         * Specifies that the data should be decoded with {@code <b>DotCode</b>} blank specification
         */
        DOT_CODE: 63,

        /**
         * Specifies that the data should be decoded with {@code <b>DotCode</b>} blank specification
         */
        DUTCH_KIX: 64,

        /**
         * Specifies that data will be checked with all available symbologies
         */
        ALL_SUPPORTED_TYPES: 66,

        /**
         * Specifies that data will be checked with all of  1D  barcode symbologies
         */
        TYPES_1D: 67,

        /**
         * Specifies that data will be checked with all of  1.5D POSTAL  barcode symbologies, like  Planet, Postnet, AustraliaPost, OneCode, RM4SCC, DutchKIX
         */
        POSTAL_TYPES: 68,

        /**
         * Specifies that data will be checked with most commonly used symbologies
         */
        MOST_COMMON_TYPES: 69,

        /**
         * Specifies that data will be checked with all of <b>2D</b> barcode symbologies
         */
        TYPES_2D: 70,

        javaClassName: "com.aspose.mw.barcode.recognition.MwDecodeTypeUtils",

        /**
         * Determines if the specified BaseDecodeType contains any 1D barcode symbology
         * @param symbology
         * @return true if BaseDecodeType contains any 1D barcode symbology; otherwise, returns false
         */
        is1D(symbology)
        {
            let javaClass = new java(DecodeType.javaClassName);
            return javaClass.is1DSync(symbology);
        },

        /**
         * Determines if the specified BaseDecodeType contains any Postal barcode symbology
         * @param symbology BaseDecodeType to test
         * @return true if BaseDecodeType contains any Postal barcode symbology; otherwise, returns false
         */
        isPostal(symbology)
        {
            let javaClass = new java(DecodeType.javaClassName);
            return javaClass.isPostalSync(symbology);
        },

        /**
         * Determines if the specified BaseDecodeType contains any 2D barcode symbology
         * @param symbology BaseDecodeType to test.
         * @return true if BaseDecodeType contains any 2D barcode symbology; otherwise, returns false
         */
        is2D(symbology)
        {
            let javaClass = new java(DecodeType.javaClassName);
            return javaClass.is2DSync(symbology);
        },

        containsAny(decodeType, ...decodeTypes)
        {
            let javaClass = new java(DecodeType.javaClassName);
            return javaClass.containsAnySync(...decodeTypes);
        }
    };

/**
 * @enum
 */
Code128SubType =
    {
        /**
         * ASCII characters 00 to 95 (0–9, A–Z and control codes), special characters, and FNC 1–4 ///
         */
        CODE_SET_A: 1,

        /**
         * ASCII characters 32 to 127 (0–9, A–Z, a–z), special characters, and FNC 1–4 ///
         */
        CODE_SET_B: 2,

        /**
         * 00–99 (encodes two digits with a single code point) and FNC1 ///
         */
        CODE_SET_C: 3,
    };

/**
 * Defines the interpreting type(C_TABLE or N_TABLE) of customer information for AustralianPost BarCode.
 * @example
 * let generator = new BarcodeGenerator(EncodeTypes.AUSTRALIA_POST, "5912345678ABCde");
 * generator.getParameters().getBarcode().getAustralianPost().setAustralianPostEncodingTable(CustomerInformationInterpretingType.C_TABLE);
 * image = generator.generateBarCodeImage();
 * let reader = new BarCodeReader(image, DecodeType.AUSTRALIA_POST);
 * reader.setCustomerInformationInterpretingType(CustomerInformationInterpretingType.C_TABLE);
 * reader.readBarCodes().forEach(function(result, i, results)
 * {
 *     console.log("BarCode Type: " + result.getCodeType());
 *     console.log("BarCode CodeText: " + result.getCodeText());
 * });
 *
 *@example
 *  generator = new BarcodeGenerator(EncodeTypes.AUSTRALIA_POST, "59123456781234567");
 *  generator.getParameters().getBarcode().getAustralianPost().setAustralianPostEncodingTable(CustomerInformationInterpretingType.N_TABLE);
 *  image = generator.generateBarCodeImage();
 *  reader = new BarCodeReader(image, DecodeType.AUSTRALIA_POST);
 *  reader.setCustomerInformationInterpretingType(CustomerInformationInterpretingType.N_TABLE);
 * reader.readBarCodes().forEach(function(result, i, results)
 * {
 *     console.log("BarCode Type: " + result.getCodeType());
 *     console.log("BarCode CodeText: " + result.getCodeText());
 * });
 *
 * @example
 * let generator = new BarcodeGenerator(EncodeTypes.AUSTRALIA_POST, "59123456780123012301230123");
 * generator.getParameters().getBarcode().getAustralianPost().setAustralianPostEncodingTable(CustomerInformationInterpretingType.OTHER);
 * image = generator.generateBarCodeImage();
 * let reader = new BarCodeReader(image, DecodeType.AUSTRALIA_POST);
 * reader.CustomerInformationInterpretingType = CustomerInformationInterpretingType.OTHER);
 * reader.readBarCodes().forEach(function(result, i, results)
 * {
 *    console.log("BarCode Type: " + result.getCodeType());
 *    console.log("BarCode CodeText: " + result.getCodeText());
 * });
 *
 * @enum
 */
CustomerInformationInterpretingType =
{

        /**
         * Use C_TABLE to interpret the customer information. Allows A..Z, a..z, 1..9, space and # sing.
         *
         * @code
         * let generator = new BarcodeGenerator(EncodeTypes.AUSTRALIA_POST, "5912345678ABCde");
         * generator.getParameters().getBarcode().getAustralianPost().setAustralianPostEncodingTable(CustomerInformationInterpretingType.C_TABLE);
         * let image = generator.generateBarcodeImage(BarcodeImageFormat.PNG);
         * let reader = new BarCodeReader(image, DecodeType.AUSTRALIA_POST);
         * reader.setCustomerInformationInterpretingType(CustomerInformationInterpretingType.C_TABLE);
         * reader.readBarCodes().forEach(function(result, i, results)
         * {
         *     print("BarCode Type: " + result.getCodeType());
         *     print("BarCode CodeText: " + result.getCodeText());
         * });
         * @endcode
         */
        C_TABLE: 0,

        /**
         * Use N_TABLE to interpret the customer information. Allows digits.
         *
         * @code
         *  let generator = new BarcodeGenerator(EncodeTypes.AUSTRALIA_POST, "59123456781234567");
         *  generator.getParameters().getBarcode().getAustralianPost().setAustralianPostEncodingTable(CustomerInformationInterpretingType.N_TABLE);
         *  let image = generator.generateBarcodeImage(BarcodeImageFormat.PNG);
         *  let reader = new BarCodeReader(image, DecodeType.AUSTRALIA_POST);
         *  reader.setCustomerInformationInterpretingType(CustomerInformationInterpretingType.N_TABLE);
         *  reader.readBarCodes().forEach(function(result, i, results)
         *  {
         *     print("BarCode Type: " + result.getCodeType());
         *     print("BarCode CodeText: " + result.getCodeText());
         *  });
         * @endcode
         */
        N_TABLE: 1,
        /**
         * Do not interpret the customer information. Allows 0, 1, 2 or 3 symbol only.
         *
         * @code
         * let generator = new BarcodeGenerator(EncodeTypes.AUSTRALIA_POST, "59123456780123012301230123");
         * generator.getParameters().getBarcode().getAustralianPost().setAustralianPostEncodingTable(CustomerInformationInterpretingType.OTHER);
         * let image = generator.generateBarcodeImage(BarcodeImageFormat.PNG);
         * let reader = new BarCodeReader(image, DecodeType.AUSTRALIA_POST);
         * reader.setCustomerInformationInterpretingType(CustomerInformationInterpretingType.OTHER));
         * reader.readBarCodes().forEach(function(result, i, results)
         * {
         *    print("BarCode Type: " + result.getCodeType());
         *    print("BarCode CodeText: " + result.getCodeText());
         * });
         * @endcode
         */
        OTHER: 2,
    };

/**
 * Contains recognition confidence level
 *@example
 * //This sample shows how BarCodeConfidence changed, depending on barcode type
 * //Moderate confidence
 * let generator = new BarcodeGenerator(EncodeTypes.CODE_128, "12345");
 * generator.save("test.png");
 * let reader = new BarCodeReader("test.png", null,  [DecodeType.CODE_39_STANDARD, DecodeType.CODE_128]);
 * reader.readBarCodes().forEach(function(result, i, results)
 * {
 *    console.log("BarCode Type: " + result.getCodeTypeName());
 *    console.log("BarCode CodeText: " + result.getCodeText());
 *    console.log("BarCode Confidence: " + result.getConfidence());
 *    console.log("BarCode ReadingQuality: " + result.getReadingQuality());
 * });
 * //Strong confidence
 * let generator = new BarcodeGenerator(EncodeTypes.QR, "12345");
 * generator.save("test.png");
 * let reader = new BarCodeReader("test.png", null,  [DecodeType.CODE_39_STANDARD, DecodeType.QR]);
 * reader.readBarCodes().forEach(function(result, i, results)
 * {
 *     console.log("BarCode Type: " + result.getCodeTypeName());
 *     console.log("BarCode CodeText: " + result.getCodeText());
 *     console.log("BarCode Confidence: " + result.getConfidence());
 *     console.log("BarCode ReadingQuality: " + result.getReadingQuality());
 * });
 *
 * @enum
 */
BarCodeConfidence =
    {
        /**
         * Recognition confidence of barcode where codetext was not recognized correctly or barcode was detected as posible fake
         */
        NONE: 0,

        /**
         * Recognition confidence of barcode (mostly 1D barcodes) with weak checksumm or even without it. Could contains some misrecognitions in codetext
         * or even fake recognitions if  is low
         *
         * @see BarCodeResult.ReadingQuality
         */
        MODERATE: 80,

        /**
         * Recognition confidence which was confirmed with BCH codes like Reed–Solomon. There must not be errors in read codetext or fake recognitions
         */
        STRONG: 100
    };

module.exports = {
    BarCodeReader,
    Quadrangle,
    QRExtendedParameters,
    Pdf417ExtendedParameters,
    OneDExtendedParameters,
    Code128ExtendedParameters,
    BarcodeSvmDetectorSettings,
    DecodeType,
    BarCodeResult,
    BarCodeRegionParameters,
    BarCodeExtendedParameters,
    QualitySettings,
    BarCodeConfidence,
    Code128SubType,
    Code128DataPortion,
    DataBarExtendedParameters,
    AustraliaPostSettings,
    BarcodeSettings,
    CustomerInformationInterpretingType,
    RecognitionAbortedException
};