const generation = require("./Generation");
const joint = require('./Joint');

const java = require('java');


/**
 * Interface for complex codetext used with ComplexBarcodeGenerator.
 */
class IComplexCodetext extends joint.BaseJavaClass
{
    constructor(javaClass)
    {
        super(javaClass);
        this.init();
    }

    /**
     * Construct codetext for complex barcode
     * @return Constructed codetext
     */
    getConstructedCodetext()
    {
        throw new BarcodeException('You have to implement the method getConstructedCodetext!');
    }

    /**
     * Initializes instance with constructed codetext.
     * @param constructedCodetext Constructed codetext.
     */
    initFromString(constructedCodetext)
    {
        throw new BarcodeException('You have to implement the method initFromString!');
    }

    /**
     * Gets barcode type.
     * @return Barcode type.
     */
    getBarcodeType()
    {
        throw new BarcodeException('You have to implement the method getBarcodeType!');
    }
}

/**
 *  ComplexBarcodeGenerator for backend complex barcode (e.g. SwissQR) images generation.
 *
 *  This sample shows how to create and save a SwissQR image.
 *    let swissQRCodetext = new SwissQRCodetext(null);
 *    swissQRCodetext.getBill().setAccount("Account");
 *    swissQRCodetext.getBill().setBillInformation("BillInformation");
 *    swissQRCodetext.getBill().setBillInformation("BillInformation");
 *    swissQRCodetext.getBill().setAmount(1024);
 *    swissQRCodetext.getBill().getCreditor().setName("Creditor.Name");
 *    swissQRCodetext.getBill().getCreditor().setAddressLine1("Creditor.AddressLine1");
 *    swissQRCodetext.getBill().getCreditor().setAddressLine2("Creditor.AddressLine2");
 *    swissQRCodetext.getBill().getCreditor().setCountryCode("Nl");
 *    swissQRCodetext.getBill().setUnstructuredMessage("UnstructuredMessage");
 *    swissQRCodetext.getBill().setReference("Reference");
 *    swissQRCodetext.getBill().setAlternativeSchemes([new AlternativeScheme("AlternativeSchemeInstruction1"),new AlternativeScheme("AlternativeSchemeInstruction2")]);
 *    swissQRCodetext.getBill().setDebtor(new Address(null));
 *    swissQRCodetext.getBill().getDebtor().setName("Debtor.Name");
 *    swissQRCodetext.getBill().getDebtor().setAddressLine1("Debtor.AddressLine1");
 *    swissQRCodetext.getBill().getDebtor().setAddressLine2("Debtor.AddressLine2");
 *    swissQRCodetext.getBill().getDebtor().setCountryCode("Lux");
 *    let cg = new ComplexBarcodeGenerator(swissQRCodetext);
 *    let res = cg.generateBarCodeImage();
 */
class ComplexBarcodeGenerator extends joint.BaseJavaClass {
    static javaClassName = "com.aspose.mw.barcode.complexbarcode.MwComplexBarcodeGenerator";
    parameters;

    init() {
        this.parameters = new generation.BaseGenerationParameters(this.getJavaClass().getParametersSync());
    }

    /**
     * Generation parameters.
     */
    getParameters() {
        return this.parameters;
    }

    /**
     * Creates an instance of ComplexBarcodeGenerator.
     * @param complexCodetext Complex codetext
     */
    constructor(complexCodetext)
    {
        let java_class_link = java.import(ComplexBarcodeGenerator.javaClassName);
        super(new java_class_link(complexCodetext.getJavaClass()));
        this.init();
    }

    /**
     * Generates complex barcode image under current settings.
     * @return  Base64 presentation of image.
     */
    generateBarCodeImage(format) {
        let base64Image = this.getJavaClass().generateBarCodeImageSync(format);
        return base64Image;
    }

    /**
     * <p>
     * Generates and saves complex barcode image under current settings.
     * </p>
     * @param filePath Path to save to.
     * @param format BarCodeImageFormat(PNG, BMP, JPEG, GIF)
     */
    save(filePath, format) {
        let image64 = this.generateBarcodeImage(format);
        let buff = Buffer.from(image64, 'base64');
        fs.writeFileSync(filePath, buff);
    }
}

/**
 * Address of creditor or debtor.
 *
 * You can either set street, house number, postal code and town (type structured address)
 * or address line 1 and 2 (type combined address elements). The type is automatically set
 * once any of these fields is set. Before setting the fields, the address type is undetermined.
 * If fields of both types are set, the address type becomes conflicting.
 * Name and country code must always be set unless all fields are empty.
 */
class Address extends joint.BaseJavaClass {
    static javaClassName = "com.aspose.mw.barcode.complexbarcode.MwAddress";

    constructor(arg) {
        super(Address.initAddress(arg));
        this.init();
    }

    static initAddress(arg) {
        if (arg == null) {
            let javaAddress = java.import(Address.javaClassName);
            return new javaAddress();
        }
        return arg;
    }

    /**
     * Gets the address type.
     *
     * The address type is automatically set by either setting street / house number
     * or address line 1 and 2. Before setting the fields, the address type is Undetermined.
     * If fields of both types are set, the address type becomes Conflicting.
     *
     * Value: The address type.
     */
    getType() {
        return this.getJavaClass().getTypeSync();
    }

    /**
     * Gets the name, either the first and last name of a natural person or the
     * company name of a legal person.
     * Value: The name.
     */
    getName() {
        return this.getJavaClass().getNameSync();
    }

    /**
     * Sets the name, either the first and last name of a natural person or the
     * company name of a legal person.
     * Value: The name.
     */
    setName(value) {
        this.getJavaClass().setNameSync(value);
    }

    /**
     * Gets the address line 1.
     *
     * Address line 1 contains street name, house number or P.O. box.
     *
     * Setting this field sets the address type to AddressType.COMBINED_ELEMENTS unless it's already
     * AddressType.STRUCTURED, in which case it becomes AddressType.CONFLICTING.
     *
     * This field is only used for combined elements addresses and is optional.
     *
     * Value: The address line 1.
     */
    getAddressLine1() {
        return this.getJavaClass().getAddressLine1Sync();
    }

    /**
     * Sets the address line 1.
     *
     * Address line 1 contains street name, house number or P.O. box.
     *
     * Setting this field sets the address type to AddressType.COMBINED_ELEMENTS unless it's already
     * AddressType.STRUCTURED, in which case it becomes AddressType.CONFLICTING.
     *
     * This field is only used for combined elements addresses and is optional.
     *
     * Value: The address line 1.
     */
    setAddressLine1(value) {
        this.getJavaClass().setAddressLine1Sync(value);
    }

    /**
     * Gets the address line 2.
     * Address line 2 contains postal code and town.
     * Setting this field sets the address type to AddressType.COMBINED_ELEMENTS unless it's already
     * AddressType.STRUCTURED, in which case it becomes AddressType.CONFLICTING.
     * This field is only used for combined elements addresses. For this type, it's mandatory.
     * Value: The address line 2.
     */
    getAddressLine2() {
        return this.getJavaClass().getAddressLine2Sync();
    }

    /**
     * Sets the address line 2.
     * Address line 2 contains postal code and town.
     * Setting this field sets the address type to AddressType.COMBINED_ELEMENTS unless it's already
     * AddressType.STRUCTURED, in which case it becomes AddressType.CONFLICTING.
     * This field is only used for combined elements addresses. For this type, it's mandatory.
     * Value: The address line 2.
     */
    setAddressLine2(value) {
        this.getJavaClass().setAddressLine2Sync(value);
    }

    /**
     * Gets the street.
     * The street must be speicfied without house number.
     * Setting this field sets the address type to AddressType.STRUCTURED unless it's already
     * AddressType.COMBINED_ELEMENTS, in which case it becomes AddressType.CONFLICTING.
     * This field is only used for structured addresses and is optional.
     * Value: The street.
     */
    getStreet() {
        return this.getJavaClass().getStreetSync();
    }

    /**
     * Sets the street.
     *
     * The street must be speicfied without house number.
     *
     * Setting this field sets the address type to AddressType.STRUCTURED unless it's already
     * AddressType.COMBINED_ELEMENTS, in which case it becomes AddressType.CONFLICTING.
     *
     * This field is only used for structured addresses and is optional.
     *
     * Value: The street.
     */
    setStreet(value) {
        this.getJavaClass().setStreetSync(value);
    }

    /**
     * Gets the house number.
     *
     * Setting this field sets the address type to AddressType.STRUCTURED unless it's already
     * AddressType.COMBINED_ELEMENTS, in which case it becomes AddressType.CONFLICTING.
     *
     * This field is only used for structured addresses and is optional.
     *
     * Value: The house number.
     */
    getHouseNo() {
        return this.getJavaClass().getHouseNoSync();
    }

    /**
     * Sets the house number.
     *
     * Setting this field sets the address type to AddressType.STRUCTURED unless it's already
     * AddressType.COMBINED_ELEMENTS, in which case it becomes AddressType.CONFLICTING.
     *
     * This field is only used for structured addresses and is optional.
     *
     * Value: The house number.
     */
    setHouseNo(value) {
        this.getJavaClass().setHouseNoSync(value);
    }

    /**
     * Gets the postal code.
     *
     * Setting this field sets the address type to AddressType.STRUCTURED unless it's already
     * AddressType.COMBINED_ELEMENTS, in which case it becomes AddressType.CONFLICTING.
     *
     * This field is only used for structured addresses. For this type, it's mandatory.
     *
     * Value: The postal code.
     */
    getPostalCode() {
        return this.getJavaClass().getPostalCodeSync();
    }

    /**
     * Sets the postal code.
     *
     * Setting this field sets the address type to AddressType.STRUCTURED unless it's already
     * AddressType.COMBINED_ELEMENTS, in which case it becomes AddressType.CONFLICTING.
     *
     * This field is only used for structured addresses. For this type, it's mandatory.
     *
     * Value: The postal code.
     */
    setPostalCode(value) {
        this.getJavaClass().setPostalCodeSync(value);
    }

    /**
     * Gets the town or city.
     *
     * Setting this field sets the address type to AddressType.STRUCTURED unless it's already
     * AddressType.COMBINED_ELEMENTS, in which case it becomes AddressType.CONFLICTING.
     *
     * This field is only used for structured addresses. For this type, it's mandatory.
     *
     * Value: The town or city.
     */
    getTown() {
        return this.getJavaClass().getTownSync();
    }

    /**
     * Sets the town or city.
     *
     * Setting this field sets the address type to AddressType.STRUCTURED unless it's already
     * AddressType.COMBINED_ELEMENTS, in which case it becomes AddressType.CONFLICTING.
     *
     * This field is only used for structured addresses. For this type, it's mandatory.
     *
     * Value: The town or city.
     */
    setTown(value) {
        this.getJavaClass().setTownSync(value);
    }

    /**
     * Gets the two-letter ISO country code.
     *
     * The country code is mandatory unless the entire address contains null or emtpy values.
     *
     * Value: The ISO country code.
     */
    getCountryCode() {
        return this.getJavaClass().getCountryCodeSync();
    }

    /**
     * Sets the two-letter ISO country code.
     *
     * The country code is mandatory unless the entire address contains null or emtpy values.
     *
     * Value: The ISO country code.
     */
    setCountryCode(value) {
        this.getJavaClass().setCountryCodeSync(value);
    }

    /**
     * Clears all fields and sets the type to AddressType.UNDETERMINED.
     */
    clear() {
        this.setName(null);
        this.setAddressLine1(null);
        this.setaddressLine2(null);
        this.setStreet(null);
        this.setHouseNo(null);
        this.setPostalCode(null);
        this.setTown(null);
        this.setCountryCode(null);
    }

    /**
     * Determines whether the specified object is equal to the current object.
     * @return true if the specified object is equal to the current object; otherwise, false.
     * @param obj The object to compare with the current object.
     */
    equals(obj) {
        return this.getJavaClass().equalsSync(obj.getJavaClass());
    }

    /**
     * Gets the hash code for this instance.
     * @return A hash code for the current object.
     */
    hashCode() {
        return this.getJavaClass().hashCodeSync();
    }

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

/**
 * Address type
 */
AddressType =
    {
        /**
         * Undetermined
         */
        UNDETERMINED: "0",
        /**
         * Structured address
         */
        STRUCTURED: "1",
        /**
         * Combined address elements
         */
        COMBINED_ELEMENTS: "2",
        /**
         * Conflicting
         */
        CONFLICTING: "3"
    };

/**
 * Alternative payment scheme instructions
 */
class AlternativeScheme extends joint.BaseJavaClass {
    static get javaClassName() {
        return "com.aspose.mw.barcode.complexbarcode.MwAlternativeScheme";
    }

    constructor(instruction)
    {
        let javaAlternativeScheme = java.import(AlternativeScheme.javaClassName);
        super(new javaAlternativeScheme(instruction));
    }

    static construct(javaClass)
    {
        let jsClass = new AlternativeScheme("");
        jsClass.setJavaClass(javaClass);
        return jsClass;
    }

    /**
     * Gets the payment instruction for a given bill.
     *
     * The instruction consists of a two letter abbreviation for the scheme, a separator characters
     * and a sequence of parameters(separated by the character at index 2).
     *
     * Value: The payment instruction.
     */
    getInstruction() {
        return this.getJavaClass().getInstructionSync();
    }

    /**
     * Gets the payment instruction for a given bill.
     * The instruction consists of a two letter abbreviation for the scheme, a separator characters
     * and a sequence of parameters(separated by the character at index 2).
     * Value: The payment instruction.
     */
    setInstruction(value) {
        this.getJavaClass().setInstructionSync(value);
    }

    /**
     * Determines whether the specified object is equal to the current object.
     * @return true if the specified object is equal to the current object; otherwise, false.
     * @param obj The object to compare with the current object.
     */
    equals(obj) {
        return this.getJavaClass().equalsSync(obj.getJavaClass());
    }

    /**
     * Gets the hash code for this instance.
     * @return  hash code for the current object.
     */
    hashCode() {
        return this.getJavaClass().hashCodeSync();
    }

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

/**
 *  ComplexCodetextReader decodes codetext to specified complex barcode type.
 *
 *  This sample shows how to recognize and decode SwissQR image.
 *
 *  let cr = new BarCodeReader("SwissQRCodetext.png", DecodeType.QR);
 *  cr.read();
 *  let result = ComplexCodetextReader.tryDecodeSwissQR(cr.getCodeText(false));
 */
class ComplexCodetextReader {
    static javaClassName = "com.aspose.mw.barcode.complexbarcode.MwComplexCodetextReader";

    /**
     * Decodes SwissQR codetext.
     *
     * @param encodedCodetext encoded codetext
     * @return decoded SwissQRCodetext or null.
     */
    static tryDecodeSwissQR(encodedCodetext) {
        let javaJsComplexCodetextReader = java.import(ComplexCodetextReader.javaClassName);
        return SwissQRCodetext.construct(javaJsComplexCodetextReader.tryDecodeSwissQRSync(encodedCodetext));
    }

    /**
     * Decodes Royal Mail Mailmark 2D codetext.
     * @param encodedCodetext encoded codetext
     * @return decoded Royal Mail Mailmark 2D or null.
     */
    static tryDecodeMailmark2D(encodedCodetext)
    {
        let javaJsComplexCodetextReader = java.import(ComplexCodetextReader.javaClassName);
        return Mailmark2DCodetext.construct(javaJsComplexCodetextReader.tryDecodeMailmark2DSync(encodedCodetext));
    }
}

/**
 * SwissQR bill standard version
 */
QrBillStandardVersion =
    {
        /**
         *
         * Version 2.0
         *
         */
        V2_0: "0"
    };

/**
 * SwissQR bill data
 */
class SwissQRBill extends joint.BaseJavaClass {
    creditor;
    debtor;

    init() {
        this.creditor = new Address(this.getJavaClass().getCreditorSync());
        this.debtor = new Address(this.getJavaClass().getDebtorSync());
    }

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

    static convertAlternativeSchemes(javaAlternativeSchemes) {
        let alternativeSchemes = [];
        for (let i = 0; i < javaAlternativeSchemes.sizeSync(); i++) {
            alternativeSchemes[i] = AlternativeScheme.construct(javaAlternativeSchemes.getSync(i));
        }
        return alternativeSchemes;
    }

    /**
     * Gets the version of the SwissQR bill standard.
     * Value: The SwissQR bill standard version.
     */
    getVersion() {
        return this.getJavaClass().getVersionSync();
    }

    /**
     * Sets the version of the SwissQR bill standard.
     * Value: The SwissQR bill standard version.
     */
    setVersion(value) {
        this.getJavaClass().setVersionSync(value);
    }

    /**
     * Gets the payment amount.
     *
     * Valid values are between 0.01 and 999,999,999.99.
     *
     * Value: The payment amount.
     */
    getAmount() {
        return this.getJavaClass().getAmountSync();
    }

    /**
     * Sets the payment amount.
     *
     * Valid values are between 0.01 and 999,999,999.99.
     *
     * Value: The payment amount.
     */
    setAmount(value) {
        this.getJavaClass().setAmountSync(value);
    }

    /**
     * Gets the payment currency.
     *
     * Valid values are "CHF" and "EUR".
     *
     * Value: The payment currency.
     */
    getCurrency() {
        return this.getJavaClass().getCurrencySync();
    }

    /**
     * Sets the payment currency.
     *
     * Valid values are "CHF" and "EUR".
     *
     * Value: The payment currency.
     */
    setCurrency(value) {
        this.getJavaClass().setCurrencySync(value);
    }

    /**
     * Gets the creditor's account number.
     *
     * Account numbers must be valid IBANs of a bank of Switzerland or
     * Liechtenstein. Spaces are allowed in the account number.
     *
     * Value: The creditor account number.
     */
    getAccount() {
        return this.getJavaClass().getAccountSync();
    }

    /**
     * Sets the creditor's account number.
     *
     * Account numbers must be valid IBANs of a bank of Switzerland or
     * Liechtenstein. Spaces are allowed in the account number.
     *
     * Value: The creditor account number.
     */
    setAccount(value) {
        this.getJavaClass().setAccountSync(value);
    }

    /**
     * Gets the creditor address.
     * Value: The creditor address.
     */
    getCreditor() {
        return this.creditor;
    }

    /**
     * Sets the creditor address.
     * Value: The creditor address.
     */
    setCreditor(value) {
        this.creditor = value;
        this.getJavaClass().setCreditorSync(value.getJavaClass());
    }

    /**
     * Gets the creditor payment reference.
     *
     * The reference is mandatory for SwissQR IBANs, i.e.IBANs in the range
     * CHxx30000xxxxxx through CHxx31999xxxxx.
     *
     * If specified, the reference must be either a valid SwissQR reference
     * (corresponding to ISR reference form) or a valid creditor reference
     * according to ISO 11649 ("RFxxxx"). Both may contain spaces for formatting.
     *
     * Value: The creditor payment reference.
     */
    getReference() {
        return this.getJavaClass().getReferenceSync();
    }

    /**
     * Sets the creditor payment reference.
     *
     * The reference is mandatory for SwissQR IBANs, i.e.IBANs in the range
     * CHxx30000xxxxxx through CHxx31999xxxxx.
     *
     * If specified, the reference must be either a valid SwissQR reference
     * (corresponding to ISR reference form) or a valid creditor reference
     * according to ISO 11649 ("RFxxxx"). Both may contain spaces for formatting.
     *
     * Value: The creditor payment reference.
     */
    setReference(value) {
        this.getJavaClass().setReferenceSync(value);
    }

    /**
     * Creates and sets a ISO11649 creditor reference from a raw string by prefixing
     * the String with "RF" and the modulo 97 checksum.
     *
     * Whitespace is removed from the reference
     *
     * @exception ArgumentException rawReference contains invalid characters.
     * @param rawReference The raw reference.
     */
    createAndSetCreditorReference(rawReference) {
        this.getJavaClass().createAndSetCreditorReferenceSync(rawReference);
    }

    /**
     * Gets the debtor address.
     *
     * The debtor is optional. If it is omitted, both setting this field to
     * null or setting an address with all null or empty values is ok.
     *
     * Value: The debtor address.
     */
    getDebtor() {
        return this.debtor;
    }

    /**
     * Sets the debtor address.
     *
     * The debtor is optional. If it is omitted, both setting this field to
     * null or setting an address with all null or empty values is ok.
     *
     * Value: The debtor address.
     */
    setDebtor(value) {
        this.debtor = value;
        this.getJavaClass().setDebtorSync(value.getJavaClass());
    }

    /**
     * Gets the additional unstructured message.
     * Value: The unstructured message.
     */
    getUnstructuredMessage() {
        return this.getJavaClass().getUnstructuredMessageSync();
    }

    /**
     * Sets the additional unstructured message.
     * Value: The unstructured message.
     */
    setUnstructuredMessage(value) {
        this.getJavaClass().setUnstructuredMessageSync(value);
    }

    /**
     * Gets the additional structured bill information.
     * Value: The structured bill information.
     */
    getBillInformation() {
        return this.getJavaClass().getBillInformationSync();
    }

    /**
     * Sets the additional structured bill information.
     * Value: The structured bill information.
     */
    setBillInformation(value) {
        this.getJavaClass().setBillInformationSync(value);
    }

    /**
     * Gets ors sets the alternative payment schemes.
     *
     * A maximum of two schemes with parameters are allowed.
     *
     * Value: The alternative payment schemes.
     */
    getAlternativeSchemes() {
        return SwissQRBill.convertAlternativeSchemes(this.getJavaClass().getAlternativeSchemesSync());
    }

    /**
     * Gets or sets the alternative payment schemes.
     *
     * A maximum of two schemes with parameters are allowed.
     *
     * Value: The alternative payment schemes.
     */
    setAlternativeSchemes(value) {
        let ArrayList = java.import('java.util.ArrayList');
        let javaArray = new ArrayList();
        for(let i = 0; i < value.length; i++)
        {
            javaArray.addSync(value[i].getJavaClass());
        }
        this.getJavaClass().setAlternativeSchemesSync(javaArray);
    }

    /**
     * Determines whether the specified object is equal to the current object.
     * @return true if the specified object is equal to the current object; otherwise, false.
     * @param obj The object to compare with the current object.
     */
    equals(obj) {
        return this.getJavaClass().equalsSync(obj.getJavaClass());
    }

    /**
     * Gets the hash code for this instance.
     * @return A hash code for the current object.
     */
    hashCode() {
        return this.getJavaClass().hashCodeSync();
    }
}

/**
 * Class for encoding and decoding the text embedded in the SwissQR code.
 */
class SwissQRCodetext extends IComplexCodetext {
    static javaClassName = "com.aspose.mw.barcode.complexbarcode.MwSwissQRCodetext";
    bill;

    init() {
        this.bill = new SwissQRBill(this.getJavaClass().getBillSync());
    }

    /**
     * SwissQR bill data
     */
    getBill() {
        return this.bill;
    }

    /**
     * Creates an instance of SwissQRCodetext.
     *
     * @param bill SwissQR bill data
     * @throws BarcodeException
     */
    constructor(bill) {
        let java_class_link = java.import(SwissQRCodetext.javaClassName);
        let javaBill = null;
        if (bill == null)
        {
            javaBill = new java_class_link();
        }
        else
        {
            javaBill = new java_class_link(bill.getJavaClass());
        }
        super(javaBill);
        this.init();
    }

    static construct(javaClass)
    {
        let phpClass = new SwissQRCodetext(null);
        phpClass.setJavaClass(javaClass);
        return phpClass;
    }

    /**
     * Construct codetext from SwissQR bill data
     *
     * @return Constructed codetext
     */
    getConstructedCodetext() {
        return this.getJavaClass().getConstructedCodetextSync();
    }

    /**
     * Initializes Bill with constructed codetext.
     *
     * @param constructedCodetext Constructed codetext.
     */
    initFromString(constructedCodetext) {
        this.getJavaClass().initFromStringSync(constructedCodetext);
        this.init();
    }

    /**
     * Gets barcode type.
     *
     * @return Barcode type.
     */
    getBarcodeType() {
        return this.getJavaClass().getBarcodeTypeSync();
    }
}

class Mailmark2DCodetext extends IComplexCodetext
{

    static javaClassName = "com.aspose.mw.barcode.complexbarcode.MwMailmark2DCodetext";

    static construct(javaClass)
    {
        let jsClass = new Mailmark2DCodetext();
        jsClass.setJavaClass(javaClass);
        return jsClass;
    }

    /**
     * Identifies the UPU Country ID.Max length: 4 characters.
     * @return Country ID
     */
    getUPUCountryID()
    {
        return this.getJavaClass().getUPUCountryIDSync();
    }

    /**
     * Identifies the UPU Country ID.Max length: 4 characters.
     * @param value Country ID
     */
     setUPUCountryID(value) 
    {
        this.getJavaClass().setUPUCountryIDSync(value);
    }

    /**
     * Identifies the Royal Mail Mailmark barcode payload for each product type.
     * Valid Values:
     *
     * '0' - Domestic Sorted &amp; Unsorted
     * 'A' - Online Postage
     * 'B' - Franking
     * 'C' - Consolidation
     *
     * @return Information type ID
     */
    getInformationTypeID()
    {
        return this.getJavaClass().getInformationTypeIDSync();
    }
    
    /**
     * Identifies the Royal Mail Mailmark barcode payload for each product type.
     * Valid Values:
     *
     * '0' - Domestic Sorted &amp; Unsorted
     * 'A' - Online Postage
     * 'B' - Franking
     * 'C' - Consolidation
     *
     * @param value Information type ID
     */
     setInformationTypeID(value)
    {
        this.getJavaClass().setInformationTypeIDSync(value);
    }
    
    
    /**
     * Identifies the  barcode version as relevant to each Information Type ID.
     * Valid Values:
     *
     * Currently '1'.
     * '0' &amp; '2' to '9' and 'A' to 'Z' spare reserved for potential future use.
     *
     * @return Version ID
     */
    getVersionID()
    {
        return this.getJavaClass().getVersionIDSync();
    }
    
    /**
     * Identifies the  barcode version as relevant to each Information Type ID.
     * Valid Values:
     *
     * Currently '1'.
     * '0' &amp; '2' to '9' and 'A' to 'Z' spare reserved for potential future use.
     *
     * @param value Version ID
     */
     setVersionID(value)
    {
        this.getJavaClass().setVersionIDSync(value);
    }
    
    /**
     * Identifies the class of the item.
     *
     * Valid Values:
     * '1' - 1C (Retail)
     * '2' - 2C (Retail)
     * '3' - Economy (Retail)
     * '5' - Deffered (Retail)
     * '8' - Premium (Network Access)
     * '9' - Standard (Network Access)
     *
     * @return class of the item
     */
    getclass()
    {
        return this.getJavaClass().getclassSync();
    }
    
    /**
     * Identifies the class of the item.
     *
     * Valid Values:
     * '1' - 1C (Retail)
     * '2' - 2C (Retail)
     * '3' - Economy (Retail)
     * '5' - Deffered (Retail)
     * '8' - Premium (Network Access)
     * '9' - Standard (Network Access)
     *
     * @param value  class of the item
     */
     setclass(value)
    {
        this.getJavaClass().setclassSync(value);
    }
    
    /**
     * Identifies the unique group of customers involved in the mailing.
     * Max value: 9999999.
     *
     * @return Supply chain ID
     */
    getSupplyChainID()
    {
        return this.getJavaClass().getSupplyChainIDSync();
    }
    
    /**
     * Identifies the unique group of customers involved in the mailing.
     * Max value: 9999999.
     *
     * @param value  Supply chain ID
     */
     setSupplyChainID(value)
    {
        this.getJavaClass().setSupplyChainIDSync(value);
    }
    
    /**
     * Identifies the unique item within the Supply Chain ID.
     * Every Mailmark barcode is required to carry an ID
     * so it can be uniquely identified for at least 90 days.
     * Max value: 99999999.
     *
     * @return item within the Supply Chain ID
     */
    getItemID()
    {
        return this.getJavaClass().getItemIDSync();
    }
    
    /**
     * Identifies the unique item within the Supply Chain ID.
     * Every Mailmark barcode is required to carry an ID
     * so it can be uniquely identified for at least 90 days.
     * Max value: 99999999.
     *
     * @param value item within the Supply Chain ID
     */
     setItemID(value)
    {
        this.getJavaClass().setItemIDSync(value);
    }
    
    /**
     * Contains the Postcode of the Delivery Address with DPS
     * If inland the Postcode/DP contains the following number of characters.
     * Area (1 or 2 characters) District(1 or 2 characters)
     * Sector(1 character) Unit(2 characters) DPS (2 characters).
     * The Postcode and DPS must comply with a valid PAF® format.
     *
     * @return the Postcode of the Delivery Address with DPS
     */
    getDestinationPostCodeAndDPS()
    {
        return this.getJavaClass().getDestinationPostCodeAndDPSSync();
    }
    
    /**
     * Contains the Postcode of the Delivery Address with DPS
     * If inland the Postcode/DP contains the following number of characters.
     * Area (1 or 2 characters) District(1 or 2 characters)
     * Sector(1 character) Unit(2 characters) DPS (2 characters).
     * The Postcode and DPS must comply with a valid PAF® format.
     *
     * @param value  the Postcode of the Delivery Address with DPS
     */
     setDestinationPostCodeAndDPS(value)
    {
        this.getJavaClass().setDestinationPostCodeAndDPSSync(value);
    }
    
    /**
     * Flag which indicates what level of Return to Sender service is being requested.
     *
     * @return RTS Flag
     */
    getRTSFlag()
    {
        return this.getJavaClass().getRTSFlagSync();
    }
    
    /**
     * Flag which indicates what level of Return to Sender service is being requested.
     *
     * @return RTS Flag
     */
     setRTSFlag(value)
    {
        this.getJavaClass().setRTSFlagSync(value);
    }
    
    /**
     * Contains the Return to Sender Post Code but no DPS.
     * The PC(without DPS) must comply with a PAF® format.
     *
     * @return Return to Sender Post Code but no DPS
     */
    getReturnToSenderPostCode()
    {
        return this.getJavaClass().getReturnToSenderPostCodeSync();
    }
    
    /**
     * Contains the Return to Sender Post Code but no DPS.
     * The PC(without DPS) must comply with a PAF® format.
     *
     * @param value  Return to Sender Post Code but no DPS
     */
     setReturnToSenderPostCode(value)
    {
        this.getJavaClass().setReturnToSenderPostCodeSync(value);
    }
    
    /**
     * Optional space for use by customer.
     *
     * Max length by Type:
     * Type 7: 6 characters
     * Type 9: 45 characters
     * Type 29: 25 characters
     *
     * @return Customer content
     */
    getCustomerContent()
    {
        return this.getJavaClass().getCustomerContentSync();
    }
    
    /**
     * Optional space for use by customer.
     *
     * Max length by Type:
     * Type 7: 6 characters
     * Type 9: 45 characters
     * Type 29: 25 characters
     *
     * @param value  Customer content
     */
     setCustomerContent(value)
    {
        this.getJavaClass().setCustomerContentSync(value);
    }
    
    /**
     * Encode mode of Datamatrix barcode.
     * Default value: DataMatrixEncodeMode.C40.
     *
     * @return Encode mode of Datamatrix barcode.
     */
    getCustomerContentEncodeMode()
    {
        return this.getJavaClass().getCustomerContentEncodeModeSync();
    }
    
    /**
     * Encode mode of Datamatrix barcode.
     * Default value: DataMatrixEncodeMode.C40.
     *
     * @param value  Encode mode of Datamatrix barcode.
     */
    setCustomerContentEncodeMode(value)
    {
        this.getJavaClass().setCustomerContentEncodeModeSync(value);
    }
    
    /**
     * 2D Mailmark Type defines size of Data Matrix barcode.
     *
     * @return Size of Data Matrix barcode
     */
    getDataMatrixType()
    {
        return this.getJavaClass().getDataMatrixTypeSync();
    }
    
    /**
     * 2D Mailmark Type defines size of Data Matrix barcode.
     *
     * @param value  Size of Data Matrix barcode
     */
    setDataMatrixType(value)
    {
        this.getJavaClass().setDataMatrixTypeSync(value);
    }
    
    /**
     * Create default instance of Mailmark2DCodetext class.
     */
    constructor()
    {
        let java_class_link = java.import(Mailmark2DCodetext.javaClassName);
        super(new java_class_link());
        this.init();
    }
    
    init()
    {}
    
    /**
     * Construct codetext from Mailmark data.
     * @return Constructed codetext
     */
    getConstructedCodetext()
    {
    
        return this.getJavaClass().getConstructedCodetextSync();
    }
    
    /**
     * Initializes Mailmark data from constructed codetext.
     * @param constructedCodetext Constructed codetext.
     */
     initFromString(constructedCodetext)
    {
        this.getJavaClass().initFromStringSync(constructedCodetext);
    }
    
    /**
     * Gets barcode type.
     * @return Barcode type.
     */
    getBarcodeType()  {
        return EncodeTypes.DATA_MATRIX;
    }
}

/**
 * 2D Mailmark Type defines size of Data Matrix barcode
 * @enum
 */
Mailmark2DType =
{
    /**
     * Auto determine
     */
    AUTO: 0,

    /**
     * 24 x 24 modules
     */
    TYPE_7: 1,

    /**
     * 32 x 32 modules
     */
    TYPE_9: 2,

    /**
     * 16 x 48 modules
     */
    TYPE_29: 3
}

module.exports = {
    SwissQRCodetext,
    ComplexBarcodeGenerator,
    ComplexCodetextReader,
    AlternativeScheme,
    Address,
    AddressType,
    SwissQRBill,
    Mailmark2DCodetext,
    Mailmark2DType
};