package ufrsimplest;

import com.sun.jna.Platform;
import com.sun.jna.ptr.ByteByReference;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.ShortByReference;
import java.util.concurrent.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

/**
 *
 * @author DLogic
 * @version 2.0.0.0
 *
 */
public class UFrSimplest extends javax.swing.JFrame {

    /**
     * Creates new form UFrSimplest
     */
    public UFrSimplest() {
        this.bDLCardType = new ByteByReference();
        initComponents();
    }
    
    //DLOGIC CARD TYPE
    final static byte 
            DL_MIFARE_ULTRALIGHT        = 0x01,
            DL_MIFARE_ULTRALIGHT_EV1_11 = 0x02,
            DL_MIFARE_ULTRALIGHT_EV1_21 = 0x03,
            DL_MIFARE_ULTRALIGHT_C      = 0x04,
            DL_NTAG_203                 = 0x05,
            DL_NTAG_210                 = 0x06,
            DL_NTAG_212                 = 0x07,
            DL_NTAG_213                 = 0x08,
            DL_NTAG_215                 = 0x09,
            DL_NTAG_216                 = 0x0A,
            DL_MIFARE_MINI              = 0x20,
            DL_MIFARE_CLASSIC_1K        = 0x21,
            DL_MIFARE_CLASSIC_4K        = 0x22,
            DL_MIFARE_PLUS_S_2K         = 0x23,
            DL_MIFARE_PLUS_S_4K         = 0x24,
            DL_MIFARE_PLUS_X_2K         = 0x25,
            DL_MIFARE_PLUS_X_4K         = 0x26,
            DL_MIFARE_DESFIRE           = 0x27,
            DL_MIFARE_DESFIRE_EV1_2K    = 0x28,
            DL_MIFARE_DESFIRE_EV1_4K    = 0x29,
            DL_MIFARE_DESFIRE_EV1_8K    = 0x2A;

  
    final static byte MIFARE_AUTHENT1A       = 0x60,
                      MIFARE_AUTHENT1B       = 0x61,
                      KEY_INDEX              = 0,
                      MAX_BLOCK              = 16; 
    // sectors and bytes
    final static byte 
                       MAX_SECTORS_1k        = 16,
                       MAX_SECTORS_4k        = 40,                                   
                       MAX_BYTES_ULTRALIGHT  = 48;
                       
    final static short
                       MAX_BYTES_ULTRALIGHT_C = 144,
                       MAX_BYTES_NTAG_203     = 144,
                       MAX_BYTES_CLASSIC_1K   = 752,
                       MAX_BYTES_CLASSIC_4k   = 3440;
    
    final static short 
                       FORMAT_SIGN            = 0xFF;
    final static int 
                       FUNCT_LIGHT_OK         = 4,
                       FUNCT_SOUND_OK         = 0,//4 Tripple sound
                       FUNCT_LIGHT_ERROR      = 2,
                       FUNCT_SOUND_ERROR      = 0,//2 Long sound
                       DL_OK                  = 0,
                       SLEEP_VALUE            = 500;
    
    boolean boCONN         = false,
            bFunctionStart = false;
    int iRResult = 0,
        iCResult = 0;
    int[] iaReaderType     = new int[1];
    byte[] iaCardUID       = new byte[9];
    
            
    ByteByReference bDLCardType;
    IntByReference  iCardSerial  = new IntByReference();
    ByteByReference bCardUIDSize = new ByteByReference();
    ByteByReference bCardType    = new ByteByReference();
    
    String[] iaErrorCodes = new String[200];
    Declarations.ERRORCODES EC;
    Declarations.ERRORCODES[] ERRCODES = Declarations.ERRORCODES.values();
    ExecutorService exec = Executors.newCachedThreadPool();
     

    public void SetFunct(boolean bValue) {
        bFunctionStart = bValue;
    }

    public boolean GetFunct() {
        return bFunctionStart;
    }
    private boolean bLoopStart;

    public void SetLoop(boolean bValue) {
        bLoopStart = bValue;
    }

    public boolean GetLoop() {
        return bLoopStart;
    }

    private void FillEcArray() {
        for (Declarations.ERRORCODES ECC : EC.values()) {
            iaErrorCodes[ECC.getValue()] = ECC.name();
        }
    }

    private void SetStatusBar(JTextField txtErrorCode, JTextField txtErrorExplain, int iResultValue) {

        txtErrorCode.setText("0x" + Integer.toHexString(iResultValue).toUpperCase());
        txtErrorExplain.setText(iaErrorCodes[iResultValue]);
    }

    //max block in card
    private int MaxBlock(ByteByReference bCardType) {
          int iResult=0;
          switch (bCardType.getValue())
          {
              case DL_MIFARE_CLASSIC_1K : iResult = MAX_SECTORS_1k * 4;
                   break;
              case DL_MIFARE_CLASSIC_4K :
              case DL_MIFARE_PLUS_S_4K: iResult = ((MAX_SECTORS_1k * 2) * 4) + ((MAX_SECTORS_1k - 8) * 16);
                   break;
          }
          return iResult;
    }

    private int MaxBytes(byte bCardType) {
        short usMaxBytes = 0;
          switch(bCardType)
          {
             case DL_NTAG_203           : usMaxBytes = MAX_BYTES_NTAG_203;
                 break;
             case DL_MIFARE_ULTRALIGHT  : usMaxBytes = MAX_BYTES_ULTRALIGHT;
                 break;
             case DL_MIFARE_ULTRALIGHT_C: usMaxBytes = MAX_BYTES_ULTRALIGHT_C;
                 break;
             case DL_MIFARE_CLASSIC_1K  : usMaxBytes = MAX_BYTES_CLASSIC_1K;
                 break;
             case DL_MIFARE_CLASSIC_4K  :
             case DL_MIFARE_PLUS_S_4K   : usMaxBytes = MAX_BYTES_CLASSIC_4k;
                  break;
           }
          return usMaxBytes;
    }

    private void MainLoop() {
        String sBuffer = "";
        byte bUidSize;
        SetLoop(true);
        if (!boCONN) {
            iRResult = Declarations.uFrFunctions.uFrSimplest.ReaderOpen();
            if (iRResult == 0) {
                boCONN = true;
                txtReaderConnected.setText("CONNECTED");
                SetStatusBar(txtReaderCodeError, txtReaderErrorExplain, iRResult);
            } else {
                txtReaderConnected.setText("NOT CONNECTED");
                txtCardType.setText(null);
                txtCardUIDSize.setText(null);
                txtCardUID.setText(null);
                SetStatusBar(txtReaderCodeError, txtReaderErrorExplain, iRResult);
            }
            
        }
        sBuffer = "";
        if (boCONN) {
            iRResult = Declarations.uFrFunctions.uFrSimplest.GetReaderType(iaReaderType);
            if (iRResult == DL_OK) {
                iCResult = Declarations.uFrFunctions.uFrSimplest.GetDlogicCardType(bDLCardType);

                if (iCResult == DL_OK) {
                    btnFormatCard.setEnabled(bDLCardType.getValue()>0x0A);
                    iCResult = Declarations.uFrFunctions.uFrSimplest.GetCardIdEx(bCardType, iaCardUID, bCardUIDSize);                                       
                    if (iCResult==DL_OK){
                         bUidSize = bCardUIDSize.getValue();
                         for (byte bCount = 0; bCount < bUidSize; ++bCount) {
                         sBuffer += Integer.toHexString((((char) iaCardUID[bCount] & 0xFF)));
                         }  
                    }
                    
                    txtCardType.setText("0x" + Integer.toHexString(bDLCardType.getValue()).toUpperCase());
                    txtCardUIDSize.setText("0x" + Integer.toHexString(bCardUIDSize.getValue()).toUpperCase());
                    txtCardUID.setText("0x" + sBuffer.toUpperCase().toUpperCase());                    
                    SetStatusBar(txtCardCodeError, txtCardErrorExplain, iCResult);
                } else {
                    txtCardType.setText(null);
                    txtCardUIDSize.setText(null);
                    txtCardUID.setText(null);
                    
                    btnFormatCard.setEnabled(true);
                    SetStatusBar(txtCardCodeError, txtCardErrorExplain, iCResult);
                }
            } else {
                boCONN = false;
                Declarations.uFrFunctions.uFrSimplest.ReaderClose();
                txtCardType.setText(null);
                txtCardUIDSize.setText(null);
                txtCardUID.setText(null);
                SetStatusBar(txtReaderCodeError, txtReaderErrorExplain, iRResult);
            }            
        }

        SetLoop(false);
    }

    private void WinClose() {
        exec.shutdown();
        System.exit(0);
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        txtCardUID = new javax.swing.JTextField();
        lblLinearRead = new javax.swing.JLabel();
        lblCardSerial = new javax.swing.JLabel();
        txtCardType = new javax.swing.JTextField();
        btnFormatCard = new javax.swing.JButton();
        jScrollPaneLinearRead = new javax.swing.JScrollPane();
        txtLinearRead = new javax.swing.JTextArea();
        jScrollPaneLinearWrite = new javax.swing.JScrollPane();
        txtLinearWrite = new javax.swing.JTextArea();
        lblCardType = new javax.swing.JLabel();
        lblLinearWrite = new javax.swing.JLabel();
        btnLinearRead = new javax.swing.JButton();
        btnLinearWrite = new javax.swing.JButton();
        pnlReaderPanel = new javax.swing.JPanel();
        txtReaderCodeError = new javax.swing.JTextField();
        txtReaderErrorExplain = new javax.swing.JTextField();
        txtReaderConnected = new javax.swing.JTextField();
        pnlCardPanel = new javax.swing.JPanel();
        txtCardCodeError = new javax.swing.JTextField();
        txtCardErrorExplain = new javax.swing.JTextField();
        txtCardStatus = new javax.swing.JTextField();
        pnlFunctionPanel = new javax.swing.JPanel();
        txtFunctionCodeError = new javax.swing.JTextField();
        txtFunctionErrorExplain = new javax.swing.JTextField();
        txtFunctionStatus = new javax.swing.JTextField();
        pbProgress = new javax.swing.JProgressBar();
        lblCardUID = new javax.swing.JLabel();
        txtCardUIDSize = new javax.swing.JTextField();
        mnuMeni = new javax.swing.JMenuBar();
        mnuFile = new javax.swing.JMenu();
        mniExitItem = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("uFr Simplest");
        setFont(new java.awt.Font("Segoe UI", 0, 10)); // NOI18N
        setMinimumSize(new java.awt.Dimension(535, 482));
        setPreferredSize(new java.awt.Dimension(541, 524));
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowActivated(java.awt.event.WindowEvent evt) {
                formWindowActivated(evt);
            }
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });
        getContentPane().setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        txtCardUID.setEditable(false);
        txtCardUID.setBackground(new java.awt.Color(255, 255, 255));
        txtCardUID.setFont(new java.awt.Font("Verdana", 1, 11)); // NOI18N
        txtCardUID.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        getContentPane().add(txtCardUID, new org.netbeans.lib.awtextra.AbsoluteConstraints(110, 40, 150, -1));

        lblLinearRead.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N
        lblLinearRead.setText("Linear Read");
        getContentPane().add(lblLinearRead, new org.netbeans.lib.awtextra.AbsoluteConstraints(280, 100, -1, -1));

        lblCardSerial.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N
        lblCardSerial.setText("Card UID");
        getContentPane().add(lblCardSerial, new org.netbeans.lib.awtextra.AbsoluteConstraints(40, 40, -1, -1));

        txtCardType.setEditable(false);
        txtCardType.setBackground(new java.awt.Color(255, 255, 255));
        txtCardType.setFont(new java.awt.Font("Verdana", 1, 11)); // NOI18N
        txtCardType.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        getContentPane().add(txtCardType, new org.netbeans.lib.awtextra.AbsoluteConstraints(110, 20, 40, -1));

        btnFormatCard.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N
        btnFormatCard.setText("FORMAT CARD");
        btnFormatCard.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
        btnFormatCard.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnFormatCardActionPerformed(evt);
            }
        });
        getContentPane().add(btnFormatCard, new org.netbeans.lib.awtextra.AbsoluteConstraints(280, 20, 230, 40));

        txtLinearRead.setEditable(false);
        txtLinearRead.setBackground(new java.awt.Color(204, 204, 204));
        txtLinearRead.setColumns(20);
        txtLinearRead.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N
        txtLinearRead.setLineWrap(true);
        txtLinearRead.setRows(5);
        txtLinearRead.setOpaque(false);
        jScrollPaneLinearRead.setViewportView(txtLinearRead);

        getContentPane().add(jScrollPaneLinearRead, new org.netbeans.lib.awtextra.AbsoluteConstraints(280, 120, 230, 190));

        txtLinearWrite.setColumns(20);
        txtLinearWrite.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N
        txtLinearWrite.setLineWrap(true);
        txtLinearWrite.setRows(5);
        jScrollPaneLinearWrite.setViewportView(txtLinearWrite);

        getContentPane().add(jScrollPaneLinearWrite, new org.netbeans.lib.awtextra.AbsoluteConstraints(30, 120, 230, 190));

        lblCardType.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N
        lblCardType.setText("Card Type");
        getContentPane().add(lblCardType, new org.netbeans.lib.awtextra.AbsoluteConstraints(40, 20, -1, -1));

        lblLinearWrite.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N
        lblLinearWrite.setText("Linear Write");
        getContentPane().add(lblLinearWrite, new org.netbeans.lib.awtextra.AbsoluteConstraints(30, 100, -1, -1));

        btnLinearRead.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N
        btnLinearRead.setText("LINEAR READ");
        btnLinearRead.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
        btnLinearRead.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnLinearReadActionPerformed(evt);
            }
        });
        getContentPane().add(btnLinearRead, new org.netbeans.lib.awtextra.AbsoluteConstraints(280, 320, 230, 50));

        btnLinearWrite.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N
        btnLinearWrite.setText("LINEAR WRITE");
        btnLinearWrite.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
        btnLinearWrite.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnLinearWriteActionPerformed(evt);
            }
        });
        getContentPane().add(btnLinearWrite, new org.netbeans.lib.awtextra.AbsoluteConstraints(30, 320, 230, 50));

        pnlReaderPanel.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        txtReaderCodeError.setEditable(false);
        txtReaderCodeError.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N
        txtReaderCodeError.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        pnlReaderPanel.add(txtReaderCodeError, new org.netbeans.lib.awtextra.AbsoluteConstraints(120, 0, 60, 20));

        txtReaderErrorExplain.setEditable(false);
        txtReaderErrorExplain.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N
        txtReaderErrorExplain.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        pnlReaderPanel.add(txtReaderErrorExplain, new org.netbeans.lib.awtextra.AbsoluteConstraints(180, 0, 360, 20));

        txtReaderConnected.setEditable(false);
        txtReaderConnected.setBackground(new java.awt.Color(204, 204, 255));
        txtReaderConnected.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N
        txtReaderConnected.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        pnlReaderPanel.add(txtReaderConnected, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, 120, 20));

        getContentPane().add(pnlReaderPanel, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 446, 540, 20));

        pnlCardPanel.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        txtCardCodeError.setEditable(false);
        txtCardCodeError.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N
        txtCardCodeError.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        pnlCardPanel.add(txtCardCodeError, new org.netbeans.lib.awtextra.AbsoluteConstraints(120, 0, 60, 20));

        txtCardErrorExplain.setEditable(false);
        txtCardErrorExplain.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N
        txtCardErrorExplain.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        pnlCardPanel.add(txtCardErrorExplain, new org.netbeans.lib.awtextra.AbsoluteConstraints(180, 0, 360, 20));

        txtCardStatus.setEditable(false);
        txtCardStatus.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N
        txtCardStatus.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        txtCardStatus.setText("Card Status");
        pnlCardPanel.add(txtCardStatus, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, 120, -1));

        getContentPane().add(pnlCardPanel, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 428, 540, 20));

        pnlFunctionPanel.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        txtFunctionCodeError.setEditable(false);
        txtFunctionCodeError.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N
        txtFunctionCodeError.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        pnlFunctionPanel.add(txtFunctionCodeError, new org.netbeans.lib.awtextra.AbsoluteConstraints(120, 0, 60, -1));

        txtFunctionErrorExplain.setEditable(false);
        txtFunctionErrorExplain.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N
        txtFunctionErrorExplain.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        pnlFunctionPanel.add(txtFunctionErrorExplain, new org.netbeans.lib.awtextra.AbsoluteConstraints(180, 0, 360, -1));

        txtFunctionStatus.setEditable(false);
        txtFunctionStatus.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N
        txtFunctionStatus.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        txtFunctionStatus.setText("Function Error");
        pnlFunctionPanel.add(txtFunctionStatus, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, 120, -1));

        getContentPane().add(pnlFunctionPanel, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 410, 540, 20));

        pbProgress.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N
        pbProgress.setForeground(new java.awt.Color(0, 102, 255));
        pbProgress.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        pbProgress.setOpaque(true);
        pbProgress.setStringPainted(true);
        getContentPane().add(pbProgress, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 380, 540, 20));

        lblCardUID.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N
        lblCardUID.setText("UID Size");
        getContentPane().add(lblCardUID, new org.netbeans.lib.awtextra.AbsoluteConstraints(160, 20, -1, -1));

        txtCardUIDSize.setEditable(false);
        txtCardUIDSize.setBackground(new java.awt.Color(255, 255, 255));
        txtCardUIDSize.setFont(new java.awt.Font("Verdana", 1, 11)); // NOI18N
        txtCardUIDSize.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        txtCardUIDSize.setToolTipText("");
        getContentPane().add(txtCardUIDSize, new org.netbeans.lib.awtextra.AbsoluteConstraints(220, 20, 40, -1));

        mnuFile.setText("File");

        mniExitItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Q, java.awt.event.InputEvent.CTRL_MASK));
        mniExitItem.setText("Exit");
        mniExitItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mniExitItemActionPerformed(evt);
            }
        });
        mnuFile.add(mniExitItem);

        mnuMeni.add(mnuFile);

        setJMenuBar(mnuMeni);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void formWindowActivated(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowActivated
        pbProgress.setVisible(false);
        FillEcArray();
        exec.execute(new MainThread());
    }//GEN-LAST:event_formWindowActivated

    private void mniExitItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mniExitItemActionPerformed
        WinClose();

    }//GEN-LAST:event_mniExitItemActionPerformed

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        WinClose();
    }//GEN-LAST:event_formWindowClosing

    private void btnLinearWriteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLinearWriteActionPerformed


        if (GetFunct() || GetLoop()) {
            return;
        }

        try {


            SetFunct(true);
            
            if (txtLinearWrite.getText().trim().length()== 0){
                JOptionPane.showMessageDialog(rootPane,"You must enter any data !","WARNING !",JOptionPane.WARNING_MESSAGE,null);
                txtLinearWrite.requestFocus();
                return;
            }
            int iLinearAddress = 0;
            int iDataLength = txtLinearWrite.getText().length();            
            int iFResult = 0;
            ShortByReference shBytesWritten = new ShortByReference();

            byte[] baWriteData = new byte[iDataLength];
            baWriteData = txtLinearWrite.getText().getBytes();
            iFResult = Declarations.uFrFunctions.uFrSimplest.LinearWrite(baWriteData, iLinearAddress, iDataLength, shBytesWritten, MIFARE_AUTHENT1A, KEY_INDEX);
            if (iFResult == DL_OK) {
                Declarations.uFrFunctions.uFrSimplest.ReaderUISignal(FUNCT_LIGHT_OK, FUNCT_SOUND_OK);
                SetStatusBar(txtFunctionCodeError, txtFunctionErrorExplain, iFResult);
            } else {
                Declarations.uFrFunctions.uFrSimplest.ReaderUISignal(FUNCT_LIGHT_ERROR, FUNCT_SOUND_ERROR);
                SetStatusBar(txtFunctionCodeError, txtFunctionErrorExplain, iFResult);
            }

        } finally {

            SetFunct(false);
        }
    }//GEN-LAST:event_btnLinearWriteActionPerformed

    private void btnLinearReadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLinearReadActionPerformed

        if (GetFunct() || GetLoop()) {
            return;
        }

        try {

            SetFunct(true);

            byte[] baReadData  = new byte[MaxBytes(bDLCardType.getValue())];
            int iLinearAddress = 0;
            int iDataLength    = baReadData.length;
            int iFResult       = 0;
            ShortByReference shBytesRet = new ShortByReference();
            iFResult = Declarations.uFrFunctions.uFrSimplest.LinearRead(baReadData, iLinearAddress, iDataLength, shBytesRet, MIFARE_AUTHENT1A, KEY_INDEX);
            if (iFResult == DL_OK) {
                txtLinearRead.setText(new String(baReadData));
                Declarations.uFrFunctions.uFrSimplest.ReaderUISignal(FUNCT_LIGHT_OK, FUNCT_SOUND_OK);
                SetStatusBar(txtFunctionCodeError, txtFunctionErrorExplain, iFResult);
            } else {
                Declarations.uFrFunctions.uFrSimplest.ReaderUISignal(FUNCT_LIGHT_ERROR, FUNCT_SOUND_ERROR);
                SetStatusBar(txtFunctionCodeError, txtFunctionErrorExplain, iFResult);
            }

        } finally {
            SetFunct(false);

        }
    }//GEN-LAST:event_btnLinearReadActionPerformed

    class FormatCard extends Thread {

        @Override
        public void run() {


            if (GetFunct() || GetLoop()) {
                return;
            }

            try {

                SetFunct(true);


                short shBISCount = 0;
                short shBlockCount = 0;
                byte bSectorCounter = 0;
                byte bBISCounter = 3;
                byte[] baBlockWrite = new byte[MAX_BLOCK];
                int iMaxBlock = MaxBlock(bDLCardType);
                int iFResult = 0;

                for (byte bCounter = 0; bCounter < MAX_BLOCK; bCounter++) {
                    baBlockWrite[bCounter] =(((byte) FORMAT_SIGN));
                }

                pbProgress.setMaximum(iMaxBlock);
                pbProgress.setVisible(true);


                while (shBlockCount < iMaxBlock) {
                    shBISCount = 0;
                    while (shBISCount < bBISCounter) {
                        iFResult = Declarations.uFrFunctions.uFrSimplest.BlockWrite(baBlockWrite, shBlockCount, MIFARE_AUTHENT1A, KEY_INDEX);
                        shBISCount++;
                        shBlockCount++;
                    }
                    if (iFResult != DL_OK) {
                        SetStatusBar(txtFunctionCodeError, txtFunctionErrorExplain, iFResult);
                        break;
                    }
                    shBlockCount++;
                    pbProgress.setValue(shBlockCount);

                    if (bSectorCounter >= 31 && shBlockCount % 16 == 0) {
                        bSectorCounter++;
                        bBISCounter = 15;
                    } else {
                        bSectorCounter++;
                    }
                }

                TimeUnit.MILLISECONDS.sleep(80);
                // SetStatusBar(txtFunctionCodeError, txtFunctionErrorExplain, iFResult);


            } catch (InterruptedException ex) {
                Logger.getLogger(UFrSimplest.class.getName()).log(Level.SEVERE, null, ex);
            } finally {

                SetFunct(false);
                pbProgress.setVisible(false);

            }
        }
    }

    private void btnFormatCardActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFormatCardActionPerformed

        ExecutorService execFormat = Executors.newSingleThreadExecutor();
        execFormat.execute(new FormatCard());
    }//GEN-LAST:event_btnFormatCardActionPerformed

    class MainThread implements Runnable {

        @Override
        public void run() {
            try {
                while (!Thread.interrupted()) {
                    if (!GetFunct()) {
                        MainLoop();
                        Thread.yield();
                    }


                    TimeUnit.MILLISECONDS.sleep(SLEEP_VALUE);
                }
            } catch (InterruptedException ex) {
                Logger.getLogger(UFrSimplest.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {


        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        String sUILook = null;
        if (Platform.getOSType() == 1) {
            sUILook = "Metal";
        } else if (Platform.getOSType() == 2) {
            sUILook = "Windows";
        }
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if (sUILook.equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(UFrSimplest.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(UFrSimplest.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(UFrSimplest.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(UFrSimplest.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                UFrSimplest UFR = new UFrSimplest();
                UFR.setVisible(true);
                UFR.setLocationRelativeTo(null);

            }
        });

    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnFormatCard;
    private javax.swing.JButton btnLinearRead;
    private javax.swing.JButton btnLinearWrite;
    private javax.swing.JScrollPane jScrollPaneLinearRead;
    private javax.swing.JScrollPane jScrollPaneLinearWrite;
    private javax.swing.JLabel lblCardSerial;
    private javax.swing.JLabel lblCardType;
    private javax.swing.JLabel lblCardUID;
    private javax.swing.JLabel lblLinearRead;
    private javax.swing.JLabel lblLinearWrite;
    private javax.swing.JMenuItem mniExitItem;
    private javax.swing.JMenu mnuFile;
    private javax.swing.JMenuBar mnuMeni;
    private javax.swing.JProgressBar pbProgress;
    private javax.swing.JPanel pnlCardPanel;
    private javax.swing.JPanel pnlFunctionPanel;
    private javax.swing.JPanel pnlReaderPanel;
    private javax.swing.JTextField txtCardCodeError;
    private javax.swing.JTextField txtCardErrorExplain;
    private javax.swing.JTextField txtCardStatus;
    private javax.swing.JTextField txtCardType;
    private javax.swing.JTextField txtCardUID;
    private javax.swing.JTextField txtCardUIDSize;
    private javax.swing.JTextField txtFunctionCodeError;
    private javax.swing.JTextField txtFunctionErrorExplain;
    private javax.swing.JTextField txtFunctionStatus;
    private javax.swing.JTextArea txtLinearRead;
    private javax.swing.JTextArea txtLinearWrite;
    private javax.swing.JTextField txtReaderCodeError;
    private javax.swing.JTextField txtReaderConnected;
    private javax.swing.JTextField txtReaderErrorExplain;
    // End of variables declaration//GEN-END:variables
}
