/** Observer method to update the insuranceCompanyTable */
  public void updateTable() {

    tableData.update(
        model.getInsuranceCompanies(), model.getSortingStrategy()); // Populate the table

    // Check if InsuranceCompany map is empty
    if (model.getInsuranceCompanies().size() > 0) {
      selectRow();
      int selectedCompanyId =
          Integer.valueOf(
              (String)
                  insuranceCompaniesTable.getValueAt(insuranceCompaniesTable.getSelectedRow(), 0));
      controller.selectInsuranceCompany(selectedCompanyId);
      recordEdited = -1; // Reset the recordEdited field
    } else {
      // If all records are deleted, clear the edit panel
      companyIdTextField.setText("");
      companyNameTextField.setText("");
      urlTextField.setText("");
      generalDescriptionTextField.setText("");
      insuranceTypesTextField.setText("");
      telephoneTextField.setText("");
      percentageTextField.setText("");
    }
  }
 /**
  * Searches for InsuranceCompanies. Calls the controller and updates the tableData to the
  * searchMap.
  */
 private void searchInsuranceCompany() {
   String query = searchTextField.getText();
   controller.searchInsuranceCompanies(query);
   tableData.update(
       model.getSearchMap(), model.getSortingStrategy()); // Updates tableData and sortingStrategy
   // Enable automatic selection while searching
   if (tableData.getRowCount() > 0) {
     selectRow();
     int selectedCompanyId =
         Integer.valueOf(
             (String)
                 insuranceCompaniesTable.getValueAt(insuranceCompaniesTable.getSelectedRow(), 0));
     controller.selectInsuranceCompany(selectedCompanyId);
   }
 }
  /** Observer method to update the editPanel and it's contents */
  public void updateEditPanel() {

    InsuranceCompany insuranceCompany = model.getCurrentInsuranceCompany();

    if (insuranceCompany != null) { // If no currentInsuranceCompany is set (if the db is empty)
      // Update all text fields
      String id =
          (String) insuranceCompaniesTable.getValueAt(insuranceCompaniesTable.getSelectedRow(), 0);
      companyIdTextField.setText(id);
      companyNameTextField.setText(insuranceCompany.getCompanyName());
      urlTextField.setText(insuranceCompany.getUrl());
      urlTextField.setCaretPosition(0);
      generalDescriptionTextField.setText(insuranceCompany.getGeneralDescription());
      generalDescriptionTextField.setCaretPosition(0);
      insuranceTypesTextField.setText(insuranceCompany.getInsuranceTypes());
      insuranceTypesTextField.setCaretPosition(0);
      telephoneTextField.setText(insuranceCompany.getTelephone());
      percentageTextField.setText(Float.toString(insuranceCompany.getPercentage()));
    }
  }
  /** Makes sure that the right row is selected on adding a new record, or on editing a record. */
  private void selectRow() {

    int tableRows = tableData.getRowCount();
    int tabelCols = tableData.getColumnCount();
    int rowToSelect = 0;

    if (recordEdited != -1) {
      rowToSelect = recordEdited; // Select the edited record
    } else {
      for (int i = 0; i < tableRows; i++) {
        String companyName = (String) tableData.getValueAt(i, 1);
        if (companyName.equals("-")) {
          rowToSelect = i; // Select the new record
        }
      }
    }

    insuranceCompaniesTable.setRowSelectionInterval(rowToSelect, rowToSelect);
  }
  /** Initial method to populate the insuranceCompaniesTable */
  public void loadTable() {

    Map<Integer, InsuranceCompany> data = model.getInsuranceCompanies();
    tableData = new InsuranceCompanyTableModel(data);
    insuranceCompaniesTable.setModel(tableData);
    insuranceCompaniesTable.getColumnModel().getColumn(0).setMaxWidth(50);
    insuranceCompaniesTable
        .getSelectionModel()
        .setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    // Check if db is empty and proceed with selecting only if the table is populated
    if (insuranceCompaniesTable.getRowCount() > 0) {
      // Set selected company according to selected row on load
      selectRow();
      int selectedCompanyId =
          Integer.valueOf(
              (String)
                  insuranceCompaniesTable.getValueAt(insuranceCompaniesTable.getSelectedRow(), 0));
    }
  }
  /** Creates the view's listeners */
  public void createListeners() {

    // If the table selection changes, set the currentInsuranceCompany accordingly (Listens to
    // keyboard and mouse)
    insuranceCompaniesTable
        .getSelectionModel()
        .addListSelectionListener(
            new ListSelectionListener() {
              public void valueChanged(ListSelectionEvent e) {
                if ((e.getValueIsAdjusting() == false)
                    && (insuranceCompaniesTable.getSelectedRow() != -1)) {
                  int selectedCompanyId =
                      Integer.valueOf(
                          (String)
                              insuranceCompaniesTable.getValueAt(
                                  insuranceCompaniesTable.getSelectedRow(), 0));
                  controller.selectInsuranceCompany(selectedCompanyId);
                }
              }
            });

    // Add a new InsuranceCompany
    addInsuranceCompanyButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            controller.addInsuranceCompany();
          }
        });

    // Save an InsuranceCompany
    saveInsuranceCompanyButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            // Check if a row is selected
            if (insuranceCompaniesTable.getSelectedRow() != -1) {
              int selectedCompanyId =
                  Integer.parseInt(
                      (String)
                          insuranceCompaniesTable.getValueAt(
                              insuranceCompaniesTable.getSelectedRow(), 0));
              String[] newData = {
                companyNameTextField.getText(),
                telephoneTextField.getText(),
                urlTextField.getText(),
                insuranceTypesTextField.getText(),
                percentageTextField.getText(),
                generalDescriptionTextField.getText()
              };

              // Input validation
              boolean checkInput = true;
              for (String input : newData) {
                if ((input.equals("")) || (input.equals(":"))) {
                  checkInput = false;
                }
              }
              // Use regex pattern to check double values
              if (!percentageTextField.getText().matches("(-|\\+)?[0-9]+(\\.[0-9]+)?")) {
                checkInput = false;
              }

              if (checkInput) {
                recordEdited = insuranceCompaniesTable.getSelectedRow();
                controller.updateInsuranceCompany(selectedCompanyId, newData);
              } else {
                showErrorMsg(
                    "Error Saving Insurance Company",
                    "Please enter proper values:\n(Fields cannot be blank or contain \":\")");
              }

            } else {
              showErrorMsg("Error Saving Insurance Company", "Please select a valid table row.");
            }
          }
        });

    // Delete an InsuranceCompany
    deleteInsuranceCompanyButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            // Check if a row is selected
            if (insuranceCompaniesTable.getSelectedRow() != -1) {
              int i =
                  JOptionPane.showConfirmDialog(
                      null,
                      "<html>Are you sure you want to delete following Insurance Company:<br><br><b>ID: "
                          + (String)
                              insuranceCompaniesTable.getValueAt(
                                  insuranceCompaniesTable.getSelectedRow(), 0)
                          + " - "
                          + (String)
                              insuranceCompaniesTable.getValueAt(
                                  insuranceCompaniesTable.getSelectedRow(), 1)
                          + "</b></html>",
                      "Delete Insurance Company",
                      JOptionPane.YES_NO_OPTION);

              if (i == JOptionPane.YES_OPTION) {
                int selectedCompanyId =
                    Integer.parseInt(
                        (String)
                            insuranceCompaniesTable.getValueAt(
                                insuranceCompaniesTable.getSelectedRow(), 0));
                controller.deleteInsuranceCompany(selectedCompanyId);
                searchTextField.setText("");
              }
            } else {
              showErrorMsg("Error Deleting Insurance Company", "Please select a valid table row.");
            }
          }
        });

    // Enable dynamic searching, by just typing into the searchTextField
    searchTextField
        .getDocument()
        .addDocumentListener(
            new DocumentListener() {
              public void changedUpdate(DocumentEvent e) {}

              public void removeUpdate(DocumentEvent e) {
                searchInsuranceCompany();
              }

              public void insertUpdate(DocumentEvent e) {
                searchInsuranceCompany();
              }
            });

    // Clear the searchTextField
    clearSearchButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            searchTextField.setText("");
          }
        });

    // Enable sorting
    sortComboBox.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            String sortStrategy = (String) sortComboBox.getSelectedItem();

            if (sortStrategy.equals("ID")) {
              model.setSortingStrategy(null);
            } else if (sortStrategy.equals("Company Name")) {
              model.setSortingStrategy(new InsuranceCompanyNameComparator());
            } else {
              model.setSortingStrategy(new InsuranceCompanyPercentageComparator());
            }

            updateTable();
          }
        });
  }