content: /*
   * Universal Password Manager
   * Copyright (C) 2005-2013 Adrian Smith
   *
   * This file is part of Universal Password Manager.
   *   
   * Universal Password Manager is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * Universal Password Manager is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with Universal Password Manager; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   */
  package com._17od.upm.gui;
  
  import java.awt.Component;
  import java.awt.Container;
  import java.awt.FlowLayout;
  import java.awt.GridBagConstraints;
  import java.awt.GridBagLayout;
  import java.awt.Insets;
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.util.ArrayList;
  import java.util.Arrays;
  
  import javax.swing.BorderFactory;
  import javax.swing.Box;
  import javax.swing.BoxLayout;
  import javax.swing.JButton;
  import javax.swing.JComboBox;
  import javax.swing.JFrame;
  import javax.swing.JLabel;
  import javax.swing.JOptionPane;
  import javax.swing.JPanel;
  import javax.swing.JTextField;
  import javax.swing.border.Border;
  import javax.swing.border.EtchedBorder;
  
  import com._17od.upm.database.PasswordDatabase;
  import com._17od.upm.transport.Transport;
  import com._17od.upm.transport.TransportException;
  import com._17od.upm.util.Translator;
  
  
  public class DatabasePropertiesDialog extends EscapeDialog {
  
      private static final long serialVersionUID = 1L;
      
      private boolean databaseNeedsSaving = false;
      
      public DatabasePropertiesDialog(final JFrame frame, ArrayList accountNames, final PasswordDatabase database) {
          super(frame, Translator.translate("databaseProperties"), true);
          
          Container container = getContentPane();
  
          // Create a pane with an empty border for spacing
          Border emptyBorder = BorderFactory.createEmptyBorder(2, 5, 5, 5);
          JPanel emptyBorderPanel = new JPanel();
          emptyBorderPanel.setLayout(new BoxLayout(emptyBorderPanel, BoxLayout.Y_AXIS));
          emptyBorderPanel.setBorder(emptyBorder);
          container.add(emptyBorderPanel);
  
          // Create a pane with an title etched border
          Border etchedBorder = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);
          Border etchedTitleBorder = BorderFactory.createTitledBorder(etchedBorder, ' ' + Translator.translate("remoteLocation") + ' ');
          JPanel mainPanel = new JPanel(new GridBagLayout());
          mainPanel.setBorder(etchedTitleBorder);
          emptyBorderPanel.add(mainPanel);
  
          GridBagConstraints c = new GridBagConstraints();
  
          // The Remote URL Label row
          JLabel urlLabel = new JLabel(Translator.translate("url"));
          c.gridx = 0;
          c.gridy = 0;
          c.anchor = GridBagConstraints.LINE_START;
          c.insets = new Insets(0, 3, 0, 0);
          c.weightx = 1;
          c.weighty = 0;
          c.gridwidth = 1;
          c.fill = GridBagConstraints.NONE;
          mainPanel.add(urlLabel, c);
  
          // The Remote URL input field row
          final JTextField urlTextField = new JTextField(database.getDbOptions().getRemoteLocation(), 20);
          c.gridx = 0;
          c.gridy = 1;
          c.anchor = GridBagConstraints.LINE_START;
          c.insets = new Insets(0, 3, 3, 3);
          c.weightx = 1;
          c.weighty = 0;
          c.gridwidth = 1;
          c.fill = GridBagConstraints.NONE;
          mainPanel.add(urlTextField, c);
  
          // The Authentication Credentials label row
          JLabel authLabel = new JLabel(Translator.translate("authenticationCredentials"));
          c.gridx = 0;
          c.gridy = 2;
          c.anchor = GridBagConstraints.LINE_START;
          c.insets = new Insets(3, 3, 0, 0);
          c.weightx = 1;
          c.weighty = 0;
          c.gridwidth = 1;
          c.fill = GridBagConstraints.NONE;
          mainPanel.add(authLabel, c);
  
          // The Authentication Credentials input field row
          String[] sAccountNames = new String[accountNames.size() + 1];
          sAccountNames[0] = "";
          System.arraycopy(accountNames.toArray(), 0, sAccountNames, 1, accountNames.size());
          Arrays.sort(sAccountNames);
          final JComboBox auth = new JComboBox(sAccountNames);
          auth.setSelectedItem(database.getDbOptions().getAuthDBEntry());
          c.gridx = 0;
          c.gridy = 3;
          c.anchor = GridBagConstraints.LINE_START;
          c.insets = new Insets(0, 3, 3, 3);
          c.weightx = 1;
          c.weighty = 0;
          c.gridwidth = 1;
          c.fill = GridBagConstraints.HORIZONTAL;
          mainPanel.add(auth, c);
  
          // Some spacing
          Component verticalSpace = Box.createVerticalGlue();
          c.gridx = 0;
          c.gridy = 4;
          c.weighty = 1;
          mainPanel.add(verticalSpace, c);
          
          // The buttons row
          JPanel buttonPanel = new JPanel(new FlowLayout());
          emptyBorderPanel.add(buttonPanel);
          JButton okButton = new JButton(Translator.translate("ok"));
          okButton.addActionListener(new ActionListener() {
              public void actionPerformed(ActionEvent e) {
                  saveDatabaseOptions(frame, urlTextField.getText().trim(), (String) auth.getSelectedItem(), database);
              }
          });
          buttonPanel.add(okButton);
          
          JButton cancelButton = new JButton(Translator.translate("cancel"));
          cancelButton.addActionListener(new ActionListener() {
              public void actionPerformed(ActionEvent e) {
                  databaseNeedsSaving = false;
                  setVisible(false);
                  dispose();
              }
          });
          buttonPanel.add(cancelButton);
          
      }
      
      
      private URL validateURL(String urlString) {
          URL url = null;
          try {
              url = new URL(urlString);
          } catch (MalformedURLException e) {
              // If we got here the the URL is invalid
          }
          return url;
      }
      
      
      private void saveDatabaseOptions(JFrame parentFrame, String remoteLocation, String authEntry, PasswordDatabase database) {
  
          boolean canCloseWindow = false;
  
          // If either the url or authentication entry to use have changed then update 
          // the flag to indicate that the database needs to be saved
          if (!database.getDbOptions().getRemoteLocation().equals(remoteLocation) ||
                  !database.getDbOptions().getAuthDBEntry().equals(authEntry)) {
              databaseNeedsSaving = true;
          } else {
              // If the db doesn't need to be saved then we can close this window
              canCloseWindow = true;
          }
  
          // If the url/remoteLocation is not empty then we need to validate the URL and upload the database
          if (!remoteLocation.equals("")) {
  
              // Check the validity of the URL given by the user
              URL url = validateURL(remoteLocation);
              if (url != null) {
  
                  // Only allow supported protocols
                  if (Transport.isASupportedProtocol(url.getProtocol())) {
  
                      // If the remote location has changed then upload the database
                      if (!database.getDbOptions().getRemoteLocation().equals(remoteLocation)) {
                          try {
                              Transport transport = Transport.getTransportForURL(url);
                              if (!authEntry.equals("")) {
                                  String userId = database.getAccount(authEntry).getUserId();
                                  String password = database.getAccount(authEntry).getPassword();
                                  transport.put(remoteLocation, database.getDatabaseFile(), userId, password);
                              } else {
                                  transport.put(remoteLocation, database.getDatabaseFile());
                              }
                              canCloseWindow = true;
                          } catch (TransportException e ){
                              JOptionPane.showMessageDialog(parentFrame, e.getMessage(), Translator.translate("transportError"), JOptionPane.ERROR_MESSAGE);                            
                          }
                      } else {
                          canCloseWindow = true;
                      }
  
                  } else {
                      JOptionPane.showMessageDialog(parentFrame, Translator.translate("unsupportedProtocol"), Translator.translate("invalidProtocol"), JOptionPane.ERROR_MESSAGE);
                  }
  
              } else {
                  // If we got here the the URL is invalid
                  JOptionPane.showMessageDialog(parentFrame, Translator.translate("givenURLIsInvalid"), Translator.translate("invalidURL"), JOptionPane.ERROR_MESSAGE);
              }
              
          } else {
              // If we were given a blank URL then the user doesn't want to maintain a remote location so we can safetly exit
              canCloseWindow = true;
          }
  
          
          // Attempt to save the database and then close the window
          if (canCloseWindow) {
              try {
                  if (databaseNeedsSaving) {
                      database.getDbOptions().setAuthDBEntry(authEntry);
                      database.getDbOptions().setRemoteLocation(remoteLocation);
                  }
                  setVisible(false);
                  dispose();
              } catch (Exception e) {
                  JOptionPane.showMessageDialog(parentFrame, e.getMessage(), Translator.translate("problemSavingDB"), JOptionPane.ERROR_MESSAGE);
              }
          }
          
      }
  
  
      public boolean getDatabaseNeedsSaving() {
          return databaseNeedsSaving;
      }
  
  }