// set the model's bonds using Jmol display.
 public void setModelBonds() {
   int currModel = 0, prevModel = 0;
   Atom atom1, atom2;
   Bond bond;
   String index1, index2;
   ArrayList<Bond> ownbonds = new ArrayList<Bond>();
   org.jmol.modelset.Bond[] bonds = viewer.ms.bo;
   for (int i = 0; i < bonds.length; i++) {
     prevModel = currModel;
     currModel = bonds[i].getAtom1().getModelNumber();
     Model model = modelList.get(currModel - 1);
     if (currModel != prevModel && i != 0) {
       modelList.get(prevModel - 1).setBonds(ownbonds);
       ownbonds.clear();
     }
     index1 = model.getModelName() + bonds[i].getAtom1().atomSite;
     index2 = model.getModelName() + bonds[i].getAtom2().atomSite;
     atom1 = model.getAtomHash().get(index1);
     atom2 = model.getAtomHash().get(index2);
     if (atom1 == null || atom2 == null) continue;
     bond = new Bond(atom1, atom2);
     ownbonds.add(bond);
     atom1.setBond(bond);
     atom2.setBond(bond);
     if (i == bonds.length - 1) {
       modelList.get(currModel - 1).setBonds(ownbonds);
     }
   }
 }
 public void updateViewerCoord() {
   for (Atom atm : modelList.get(viewer.getDisplayModelIndex()).getAtomHash().values()) {
     viewer.ms.setAtomCoord(
         (atm.getAtomSeqNum() - 1),
         atm.getCoordinates()[0],
         atm.getCoordinates()[1],
         atm.getCoordinates()[2]);
   }
   jmolPanel.getViewer().refresh(3, "minimization step ");
 }
 public void atomMoved() {
   for (Atom atm : modelList.get(viewer.getDisplayModelIndex()).getAtomHash().values()) {
     for (int i = 0; i < viewer.ms.at.length; i++) {
       if (atm.getAtomSeqNum() == (i + 1)) {
         double[] coords = {viewer.ms.at[i].x, viewer.ms.at[i].y, viewer.ms.at[i].z};
         atm.setCoordinates(coords);
       }
     }
   }
 }
  public void notifyUpdated(AbstractParticle[] particles) {
    List<Atom> atomsUpdated = new ArrayList<Atom>();

    // When the two particles are part of common model
    if (modelList.size() != 0) {
      for (int i = 0; i < particles.length; i++) {
        if (particles[i] instanceof Atom) { // if particle is Atom type
          // get the updated atom from model
          atomsUpdated.add(
              modelList
                  .get(0)
                  .getAtomHash()
                  .get(modelList.get(0).getModelName() + ((Atom) particles[i]).getChainSeqNum()));
        }
      }
      // update atoms in jmol display
      for (int i = 0; i < atomsUpdated.size(); i++) {
        Atom atom = atomsUpdated.get(i);
        float xOffset =
            (float) atom.getPosition().x - viewer.getAtomPoint3f(atom.getChainSeqNum() - 1).x;
        float yOffset =
            (float) atom.getPosition().y - viewer.getAtomPoint3f(atom.getChainSeqNum() - 1).y;
        float zOffset =
            (float) atom.getPosition().z - viewer.getAtomPoint3f(atom.getChainSeqNum() - 1).z;
        viewer.evalString("select atomno=" + atom.getChainSeqNum());
        viewer.evalString("translateSelected {" + xOffset + " " + yOffset + " " + zOffset + "}");
      }
    }
  }
  // paste copied/cut atoms, not applicable when copied atoms are paste to same model.
  public void pasteSavedAtoms(int modelIndex) {
    if (savedAtoms == null)
      JOptionPane.showMessageDialog(
          jmolPanel,
          "You have not copied or cut any atoms to paste!",
          "Warning",
          JOptionPane.WARNING_MESSAGE);
    else {
      boolean error = false;
      for (int i = 0; i < savedAtoms.size(); i++) {
        for (Atom atm : modelList.get(modelIndex).getAtomHash().values()) {
          if (savedAtoms.get(i).getCoordinates()[0] == atm.getCoordinates()[0]
              && savedAtoms.get(i).getCoordinates()[1] == atm.getCoordinates()[1]
              && savedAtoms.get(i).getCoordinates()[2] == atm.getCoordinates()[2]) {
            error = true;
            break;
          }
        }
        if (error) {
          JOptionPane.showMessageDialog(
              jmolPanel,
              "You are trying to paste atoms in location occupied!",
              "Warning",
              JOptionPane.WARNING_MESSAGE);
          break;
        } else {
          addAtom(modelIndex, savedAtoms.get(i));
        }
      }
      String pdb = DataManager.modelToPDB(modelList);
      System.out.println(pdb);

      viewer.openStringInline(pdb);
      viewer.setCurrentModelIndex(modelIndex);
    }
    toolPanel.setModelText(modelList);
  }
  public void displayParticles(ArrayList<AbstractParticle> list) {

    String pdb = "MODEL       1\n";
    for (int i = 0; i < list.size(); i++) {
      // String index = String.format("%4d", list.get(i).getGUID());
      String index = String.format("%4d", i);
      if (list.get(i) instanceof Atom) {
        double scale = Math.pow(10, 10 + list.get(i).getPosition().metric);
        Vector3D position = list.get(i).getPosition();
        double x = capCoord(position.x * scale);
        double y = capCoord(position.y * scale);
        double z = capCoord(position.z * scale);
        String coords = String.format("%8.3f%8.3f%8.3f", x, y, z);
        String elementSymbol =
            String.format("%-4s", ((Atom) list.get(i)).getElementSymbol().toUpperCase());

        pdb +=
            "HETATM " + index + " " + elementSymbol + "         1    " + coords + "  1.00  0.00\n";

      } else if (list.get(i) instanceof Molecule) {
        Molecule m = (Molecule) list.get(i);
        if (World.simulationLvlAtomic == true) {
          for (Atom a : m.getChains().get(0).atomSeq) {
            double scale = Math.pow(10, 10 + list.get(i).getPosition().metric);
            Vector3D position = a.getPosition();
            double x = capCoord(position.x * scale);
            double y = capCoord(position.y * scale);
            double z = capCoord(position.z * scale);
            String coords = String.format("%8.3f%8.3f%8.3f", x, y, z);
            String elementSymbol = String.format("%-4s", a.getElementSymbol().toUpperCase());

            pdb +=
                "HETATM "
                    + index
                    + " "
                    + elementSymbol
                    + "         1    "
                    + coords
                    + "  1.00  0.00\n";
          }

          /*
          pdb += "HETATM    1 NA   TST A   1       5.000   5.000   5.000  1.00  0.00\n"+
          	   "HETATM    2 CL   TST A   1       6.400   6.400   6.400  1.00  0.00\n"+
          	   "CONECT    1      2\n" +
          	   "CONECT    2      1\n";
          	   */
        } else {
          double scale = Math.pow(10, 10 + list.get(i).getPosition().metric);
          Vector3D position = list.get(i).getPosition();
          double x = capCoord(position.x * scale);
          double y = capCoord(position.y * scale);
          double z = capCoord(position.z * scale);
          String coords = String.format("%8.3f%8.3f%8.3f", x, y, z);
          pdb += "HETATM    1 CS   TST A   1    " + coords + "  1.00  0.00\n";
        }
      }
    }
    pdb += "ENDMDL";

    if (World.displayUI) viewer.openStringInline(pdb);

    try {
      BufferedWriter writer = new BufferedWriter(new FileWriter("output.pdb"));
      writer.write(pdb);
      writer.close();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      World.simulationStatus = "restart";
    }

    if (World.displayUI) {
      createUserModel(DataManager.readFile("output.pdb"));
    }
  }