void fetchPassword() {
    Config config = Config.instance();
    config.updateConfig(
        this.emailField.getText(),
        this.passField.getText(),
        "",
        this.rememberPasswordCheckbox.getState());

    if (config.getEmail().isEmpty() || config.getPassword().isEmpty()) {
      JOptionPane.showMessageDialog(
          mainPanel, "Empty email or SSO password", "Bad SSO Account", JOptionPane.ERROR_MESSAGE);
      return;
    }

    taskThread = new TwoTaskThread(TwoTaskThread.GEN_PASSWORD | TwoTaskThread.GEN_QRCODE);

    setBusy();
    taskThread.start();
    timer.start();
  }
  public void run() {
    try {
      if (isGenPassword()) {
        Config config = Config.instance();
        String email = config.getEmail();
        String password = config.getPassword();

        String wifiPassword = PasswordGenerator.getPassword(email, password, false);
        config.setWifiPassword(wifiPassword);

        System.out.println("Gen password");
      }

      if (isGenQRCode()) {
        BufferedImage qrImage =
            QRCodeGenerator.generateQRImage(Config.instance().getWifiPassword());
        Config.instance().setQRImage(qrImage);
        System.out.println("Gen qr with :" + Config.instance().getWifiPassword());
      }

    } catch (Exception e) {
      error = e.toString();
    }
  }
  /** Create GUI elements */
  private void loadGUI() {
    setTitle("Wifi QRCode Generator");

    mainPanel = new JPanel();
    BoxLayout vBoxLayout = new BoxLayout(mainPanel, BoxLayout.Y_AXIS);
    mainPanel.setLayout(vBoxLayout);

    int LABEL_WIDTH = 100;
    int LABEL_HEIGHT = 30;

    int EDIT_WIDTH = 200;
    int EDIT_HEIGHT = 30;

    // guide label
    {
      // This layout simply makes label looks left-alignmented
      JPanel barPanel = new JPanel();
      BoxLayout barHLayout = new BoxLayout(barPanel, BoxLayout.X_AXIS);
      barPanel.setLayout(barHLayout);

      JLabel ssoGuideLabel = new JLabel("Enter your SSO and click button below to login");
      ssoGuideLabel.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 15));
      barPanel.add(ssoGuideLabel);
      mainPanel.add(barPanel);
    }

    Font gFont = new Font(Font.SANS_SERIF, Font.PLAIN, 13);

    Config config = Config.instance();

    // email password remember password
    {
      JPanel userPanel = new JPanel();
      BoxLayout hBoxLayout = new BoxLayout(userPanel, BoxLayout.X_AXIS);
      userPanel.setLayout(hBoxLayout);
      JLabel emailLabel = new JLabel("Email:");
      Dimension labelDimension = new Dimension(LABEL_WIDTH, LABEL_HEIGHT);
      emailLabel.setMinimumSize(labelDimension);
      emailLabel.setPreferredSize(labelDimension);
      emailLabel.setMaximumSize(labelDimension);
      userPanel.add(emailLabel);
      userPanel.add(Box.createRigidArea(new Dimension(5, 0)));
      emailField = new TextField();
      emailField.setMinimumSize(new Dimension(EDIT_WIDTH, EDIT_HEIGHT));
      emailField.setMaximumSize(new Dimension(EDIT_WIDTH + 300, EDIT_HEIGHT));
      emailField.setFont(gFont);
      emailField.setText(config.getEmail());

      userPanel.add(emailField);

      mainPanel.add(userPanel);

      JPanel passwordPanel = new JPanel();
      BoxLayout hBoxLayout2 = new BoxLayout(passwordPanel, BoxLayout.X_AXIS);
      passwordPanel.setLayout(hBoxLayout2);
      JLabel passwordLabel = new JLabel("SSO Password:"******"Remember password", false);
      rememberPasswordCheckbox.setState(config.getRememberPassword());

      mainPanel.add(rememberPasswordCheckbox);
      mainPanel.add(Box.createHorizontalGlue());
    }

    JPanel centerPanel = new JPanel();
    BorderLayout bLayout = new BorderLayout();
    centerPanel.setLayout(bLayout);

    buttonGetPassword = new JButton(idleButtonText);
    Font font = new Font(Font.SERIF, Font.BOLD, 18);
    buttonGetPassword.setFont(font);
    buttonGetPassword.setMinimumSize(new Dimension(300, 50));
    buttonGetPassword.setPreferredSize(new Dimension(300, 50));
    buttonGetPassword.setMaximumSize(new Dimension(300, 50));

    centerPanel.add(buttonGetPassword, BorderLayout.CENTER);

    hintLabel = new JLabel("Enter your SSO and click button to start");
    hintLabel.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 15));

    centerPanel.add(hintLabel, BorderLayout.SOUTH);
    mainPanel.add(centerPanel);

    wifiPasswordField = new TextField("Wifi password has not been generated");
    mainPanel.add(wifiPasswordField);

    JPanel qrCenterPanel = new JPanel();
    BorderLayout bLayout2 = new BorderLayout();
    qrCenterPanel.setLayout(bLayout2);
    qrCodeLabel = new JLabel("");
    qrCodeLabel.setMinimumSize(new Dimension(400, 400));
    qrCodeLabel.setPreferredSize(new Dimension(400, 400));
    qrCodeLabel.setMaximumSize(new Dimension(400, 400));
    qrCodeLabel.setHorizontalAlignment(JLabel.CENTER);
    qrCodeLabel.setVerticalAlignment(JLabel.CENTER);
    qrCodeLabel.setIcon(idleIcon);

    qrCenterPanel.add(qrCodeLabel, BorderLayout.CENTER);
    mainPanel.add(qrCenterPanel);

    // client download section
    {
      Font clientFont = new Font(Font.SANS_SERIF, Font.BOLD, 15);
      Dimension clientDimension = new Dimension(200, 30);
      JPanel clientPanel = new JPanel();
      BorderLayout cp_bLayout = new BorderLayout();
      clientPanel.setLayout(cp_bLayout);
      HyberLinkLabel androidLabel =
          new HyberLinkLabel(
              " [ Android Client ] ",
              "https://github.com/tangyanhan/ClrGstAutoLogin-/blob/master/ClrGstAutoConnect/bin/ClrGstAutoConnect.apk");
      androidLabel.setMinimumSize(clientDimension);
      androidLabel.setFont(clientFont);
      clientPanel.add(androidLabel, BorderLayout.WEST);

      HyberLinkLabel iosLabel = new HyberLinkLabel(" [ iOS Client ] ", "");
      iosLabel.setMinimumSize(clientDimension);
      iosLabel.setFont(clientFont);
      clientPanel.add(iosLabel, BorderLayout.EAST);

      mainPanel.add(clientPanel);
    }

    add(mainPanel);

    this.pack();
    this.setVisible(true);
    this.setLocation(300, 100);
    this.setSize(500, 730);

    buttonGetPassword.addActionListener(
        new ActionListener() {

          @Override
          public void actionPerformed(ActionEvent arg0) {

            long elapsed = Calendar.getInstance().getTimeInMillis() - lastClickTime;

            // If we got the successfull password 5 minutes ago
            if (((elapsed / 1000) / 60) < 5) {
              hintLabel.setText("Take a rest! You have got the QR code already!");
              return;
            }

            fetchPassword();

            if (!Config.instance().getWifiPassword().isEmpty())
              lastClickTime = Calendar.getInstance().getTimeInMillis();
          }
        });
  }
  public MainWindow() {
    Config config = Config.instance();

    {
      URL url = MainWindow.class.getResource("/idle.png");
      if (url != null) {
        idleIcon = new ImageIcon(url);
      }

      url = MainWindow.class.getResource("/wait_cursor.gif");
      if (url != null) {
        waitIcon = new ImageIcon(url);
      }
    }

    loadGUI();

    timer =
        new Timer(
            100,
            new ActionListener() {
              public void actionPerformed(ActionEvent arg0) {
                if (!taskThread.isAlive()) {
                  // task finished without errors
                  if (!taskThread.error.isEmpty()) {
                    if (taskThread.isGenPassword() && Config.instance().wifiPassword.isEmpty()) {
                      passField.setText("");
                      JOptionPane.showMessageDialog(
                          mainPanel,
                          "Invalid SSO info, please try again:" + taskThread.error,
                          "Login Failed",
                          JOptionPane.ERROR_MESSAGE);
                    } else if (taskThread.isGenQRCode()) {
                      JOptionPane.showMessageDialog(
                          mainPanel,
                          "Failed to generate QR Image, please try again: " + taskThread.error,
                          "QRCode Generation Failed",
                          JOptionPane.ERROR_MESSAGE);
                    }
                  }
                  timer.stop();
                  taskThread = null;

                  displayWifiPassword();

                  buttonGetPassword.setText(idleButtonText);
                  buttonGetPassword.setEnabled(true);
                }
              }
            });

    if (!config.getWifiPassword().isEmpty()) {
      taskThread = new TwoTaskThread(TwoTaskThread.GEN_QRCODE);

      qrCodeLabel.setIcon(waitIcon);

      setBusy();
      taskThread.start();
      timer.start();
    } else if (!(config.getEmail().isEmpty() || config.getPassword().isEmpty())) {
      fetchPassword();
    } else {
      qrCodeLabel.setIcon(idleIcon);
    }
  }