package bisq.desktop.main.account.content.notifications;

import bisq.common.UserThread;
import bisq.common.util.Utilities;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;

import java.util.List;
import java.util.concurrent.Executor;
import java.util.function.Consumer;



import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamPanel;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import javax.swing.JFrame;

public class QrCodeWindow extends JFrame {

    private Webcam webcam;
    private Executor executor = Utilities.getListeningSingleThreadExecutor("readQR-runner");

    private WebcamPanel panel;
    private Consumer<String> qrCodeResultHandler;

    public QrCodeWindow(Consumer<String> qrCodeResultHandler) {
        this.qrCodeResultHandler = qrCodeResultHandler;

        setLayout(new FlowLayout());
        setTitle("Bisq Notification token"); //TODO

        setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

        addWindowListener(new java.awt.event.WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent windowEvent) {
                webcam.close();
                setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            }
        });

        List<Webcam> webcams = Webcam.getWebcams();
        webcam = webcams.get(0);
        Dimension[] sizes = webcam.getViewSizes();
        webcam.setViewSize(sizes[sizes.length - 1]);

        panel = new WebcamPanel(webcam);
        add(panel);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
        executor.execute(this::doRun);
    }

    private void doRun() {
        // check 10 times a second for the QR code
        boolean run = true;
        while (run) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            Result result = null;
            BufferedImage image;

            if (webcam.isOpen()) {
                if ((image = webcam.getImage()) == null)
                    continue;

                LuminanceSource source = new BufferedImageLuminanceSource(image);
                BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

                try {
                    result = new MultiFormatReader().decode(bitmap);
                } catch (NotFoundException ignore) {
                    // fall thru, it means there is no QR code in image
                }
            }

            if (result != null) {
                String qrCode = result.getText();
                //boolean sendConfirmation = phone.validatePhoneId(qrCode);
                // phone.save();
                dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
                run = false;
                UserThread.execute(() -> {
                    qrCodeResultHandler.accept(qrCode);
                });
               /* Platform.runLater(
                        () -> {
                            // app.updateGUI();
                            // app.sendConfirmation();
                        }
                );*/
            }
        }
    }
}

@@ -263,20 +263,35 @@
 va.util.
-List
+concurrent.Executor
 ;%0Aimport
@@ -308,32 +308,40 @@
 .concurrent.
-Executor
+TimeoutException
 ;%0Aimport jav
@@ -1602,52 +1602,91 @@
     
-List%3CWebcam%3E webcams = Webcam.getWebcams();%0A
+executor.execute(this::doRun);%0A    %7D%0A%0A    private void doRun() %7B%0A        try %7B%0A    
     
@@ -1702,32 +1702,90 @@
 m = 
-w
+W
 ebcam
-s
 .get
-(0);%0A
+Default(1000); // one second timeout - the default is too long%0A 
         
 Dime
@@ -1780,16 +1780,19 @@
         
+   
 Dimensio
@@ -1822,24 +1822,28 @@
 iewSizes();%0A
+    
         webc
@@ -1883,25 +1883,24 @@
  - 1%5D);%0A
-%0A
         
 panel = 
@@ -1891,16 +1891,20 @@
         
+    
 panel = 
@@ -1936,16 +1936,20 @@
         
+    
 add(pane
@@ -1964,16 +1964,20 @@
     
+ 
+   
 pack();%0A
     
@@ -1968,24 +1968,28 @@
     pack();%0A
+    
         setL
@@ -2021,16 +2021,20 @@
         
+ 
+   
 setVisib
@@ -2055,72 +2055,82 @@
     
-executor.execute(this::doRun);%0A
+%7D catch (TimeoutException e) %7B%0A  
     
-%7D%0A%0A
+ 
     
-private void doRun() %7B
+ e.printStackTrace();%0A        %7D%0A
 %0A   
@@ -2469,16 +2469,34 @@
  (webcam
+ != null && webcam
 .isOpen(

Fix threading issue