Subversion Repositories wimsdev

Rev

Rev 7295 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2.     Sketch Elements: Chemistry molecular diagram drawing tool.
  3.    
  4.     (c) 2005 Dr. Alex M. Clark
  5.    
  6.     Released as GNUware, under the Gnu Public License (GPL)
  7.    
  8.     See www.gnu.org for details.
  9.  
  10.    
  11.     11/2013 rewrite based on SketchEl 1.21: (08/Nov/2008) to include export of SVG.
  12.    
  13.     More recent verions than 1.21 do not improve the Applet or SVG export.
  14.    
  15.     jm.evers
  16. */  
  17. package WIMSchem;
  18.  
  19. import java.io.*;
  20. import java.awt.*;
  21. import java.awt.event.*;
  22. import java.util.*;
  23. import javax.swing.*;
  24. import java.net.*;
  25. import java.applet.AppletContext;
  26. import java.text.*;
  27.  
  28. public class MainApplet extends JApplet implements ComponentListener
  29. {
  30.     MainPanel mainPanel=null;
  31.     long id;
  32.     String zoom_js;
  33.     public static String g_id = "g_SVG_1000000";/* used for SVG zoom in/out */
  34.     public static String svg_id = "SVG_1000000";/* used for SVG zoom in/out */
  35.     /* jm.evers addition to configure applet */
  36.     static String[] TOOLS={"TOOL_CURSOR","TOOL_ROTATOR","TOOL_ERASOR","TOOL_DIALOG","TOOL_EDIT",
  37.     "TOOL_SETATOM","TOOL_SINGLE","TOOL_DOUBLE","TOOL_TRIPLE","TOOL_ZERO",
  38.     "TOOL_INCLINED","TOOL_DECLINED","TOOL_UNKNOWN","TOOL_CHARGE","TOOL_UNDO",
  39.     "TOOL_REDO","TOOL_TEMPLATE","TOOL_CUT","TOOL_COPY","TOOL_PASTE",
  40.     "TOOL_UNSELECT","TOOL_SELECT"};
  41.     static String[] MENUS={"MENU_BLOCK","MENU_SELECT","MENU_TRANSFORM","MENU_ZOOM","MENU_SHOW","MENU_HYDROGEN","MENU_STEREO","MENU_HELP"};
  42.     static int TOOL_COUNT = TOOLS.length;
  43.     static int MENU_COUNT = MENUS.length;
  44.     public static String[] templateURL;
  45.     public static AppletContext applet_context;
  46.     public static String[] myAtoms;
  47.     public static int rotation;
  48.     public static boolean viewC;
  49.     public static boolean viewH;
  50.     public static boolean[] TOOL_SELECTION;
  51.     public static boolean[] MENU_SELECTION;
  52.     public static boolean USER_SELECTION;
  53.     public static int GLOBAL_ALPHA = 140;
  54.     public static Color ATOM_SELECT_COLOR;
  55.     public static Color BOND_SELECT_COLOR;
  56.     public static int[] ExternalAtomSelection;
  57.     public static Color SelectedAtomColorArray[];
  58.     public static int[] ExternalBondSelection;
  59.     public static Color SelectedBondColorArray[];
  60.     public static boolean ATOM_BUTTONS = true;
  61.     public static String language;
  62.     public void init(){
  63.         ATOM_BUTTONS = getBool("atom_button_row",false); /* if set an extra row of buttons will be shown  */
  64.         USER_SELECTION = getBool("user_selection",false);
  65.         if( USER_SELECTION ){
  66.             GLOBAL_ALPHA = getInt("color_alpha",140);
  67.             /* some people forget the importance of alpha...this should be removed */
  68.             if( GLOBAL_ALPHA > 250 ){GLOBAL_ALPHA = 140;}
  69.             ATOM_SELECT_COLOR = getColor("default_atom_select_color",GLOBAL_ALPHA,255,0,0);/* RGB */
  70.             BOND_SELECT_COLOR = getColor("default_bond_select_color",GLOBAL_ALPHA,0,0,255);/* RGB */
  71.         }
  72.         zoom_js = "";
  73.         language = getLanguage();
  74.         TOOL_SELECTION = getTools();
  75.         MENU_SELECTION = getMenus();
  76.         ExternalAtomSelection = SetAtomSelection();
  77.         ExternalBondSelection = SetBondSelection();
  78.         rotation = getInt("rotation",0);
  79.         myAtoms = GetMyAtoms(); /* read parm atoms to tailomade atomselection*/
  80.         templateURL = getTemplateURL();/* read params template1...template_n and use these insteadof default ones */
  81.         viewC =  getBool("show_carbon",true);
  82.         viewH = getBool("show_hydrogen",true);
  83.         System.out.println("viewC = "+viewC+"\nviewH = "+viewH);
  84.         getContentPane().setLayout(new BorderLayout());
  85.         mainPanel=new MainPanel(null,MainPanel.MODE_APPLET,null);
  86.         getContentPane().add(mainPanel,BorderLayout.CENTER);
  87.         addComponentListener(this);
  88.         getFile();/* read param file and load it if param showfile is set */
  89.         repaint(1000);
  90.     }
  91.     public String getAppletInfo()
  92.     {
  93.         return "WIMSchem: Applet version of chemistry\nmolecular diagram drawing tool.";
  94.     }
  95.  
  96.     /*
  97.         replace the current molecule with the content of the string, which can be any of the formats which WIMSchem
  98.         is able to read out from a file; returns true if successful
  99.     */
  100.     public boolean SetMoleculeNative(String Source) {
  101.         try{
  102.             Molecule mol=MoleculeStream.readNative(new BufferedReader(new StringReader(Source.toString())));
  103.             mainPanel.setMolecule(mol);
  104.             mainPanel.repaint();
  105.             return true;
  106.         } catch (IOException e) { System.out.println("problems parsing:\n"+Source.toString()+"\n"+e);}
  107.         return false;
  108.     }
  109.     public boolean SetMoleculeMDLMol(String Source){
  110.         try{
  111.             Molecule mol = MoleculeStream.readMDLMOL(new BufferedReader(new StringReader(Source.toString())));
  112.             mainPanel.setMolecule(mol);
  113.             mainPanel.repaint();
  114.             return true;
  115.         } catch (IOException e) { System.out.println("problems parsing:\n"+Source.toString()+"\n"+e);}
  116.         return false;
  117.     }
  118.     public boolean SetMolecule(String Source, boolean is_molfile)
  119.     {
  120.         try
  121.         {
  122.             Molecule mol;
  123.             if(is_molfile){
  124.              mol = MoleculeStream.readMDLMOL(new BufferedReader(new StringReader(Source.toString())));
  125.             }
  126.             else
  127.             {
  128.              mol = MoleculeStream.readUnknown(new BufferedReader(new StringReader(Source.toString())));
  129.             }
  130.             mainPanel.setMolecule(mol);
  131.             mainPanel.repaint();
  132.             return true;
  133.         }
  134.         catch (IOException e){ System.out.println("error in applet : setMolecule( String Source ) :\ncan not parse : "+Source.toString());}
  135.         return false;
  136.     }
  137.    
  138.     /*
  139.         appends the indicated molecular source to the current molecule,
  140.         in the same way as the paste feature; otherwise works
  141.         the same as SetMolecule
  142.     */
  143.     public boolean AppendMolecule(String Source, boolean is_molfile)
  144.     {
  145.         try
  146.         {
  147.             Molecule mol;
  148.             if(is_molfile){
  149.              mol = MoleculeStream.readMDLMOL(new BufferedReader(new StringReader(Source.toString())));
  150.             }
  151.             else
  152.             {
  153.              mol = MoleculeStream.readUnknown(new BufferedReader(new StringReader(Source.toString())));
  154.             }
  155.             mainPanel.addMolecule(mol);
  156.             mainPanel.repaint();
  157.             return true;
  158.         }
  159.         catch (IOException e) { System.out.println("error in applet : appendMolelcule( String Source ) : "+e.toString());}
  160.        
  161.         return false;
  162.     }
  163.    
  164.     /*
  165.         return the string representation of the molecule, in WIMSchem native format
  166.     */
  167.     public String GetMoleculeNative()
  168.     {
  169.         try
  170.         {
  171.             StringWriter sw=new StringWriter();
  172.             BufferedWriter bw=new BufferedWriter(sw);
  173.             MoleculeStream.writeNative(bw,mainPanel.molData());
  174.             return sw.toString();
  175.         }
  176.         catch (IOException e) {}
  177.        
  178.         return null;
  179.     }
  180.    
  181.     /*
  182.         return the string representation of the molecule, in MDL MOL-file format
  183.     */
  184.     public String GetMoleculeMDLMol()
  185.     {
  186.         try
  187.         {
  188.             StringWriter sw = new StringWriter();
  189.             BufferedWriter bw = new BufferedWriter(sw);
  190.             MoleculeStream.writeMDLMOL(bw,mainPanel.molData());
  191.             return sw.toString();
  192.         }
  193.         catch (IOException e) {}
  194.        
  195.         return "error getting MDLMol file from applet";
  196.     }
  197.  
  198.     public void componentHidden(ComponentEvent e) {}
  199.     public void componentMoved(ComponentEvent e) {}
  200.     public void componentResized(ComponentEvent e)
  201.     {
  202.     }
  203.     public void componentShown(ComponentEvent e)
  204.     {
  205.         mainPanel.scaleToFit();
  206.         mainPanel.repaint();
  207.     }
  208.     /*
  209.         jm.evers additions to configuring applet
  210.     */
  211.     public String getSelected(){
  212.         int num=0;
  213.         String reply="";
  214.         Molecule mol = (mainPanel.editor).molData();
  215.         for (int n=1;n<mol.numAtoms();n++){
  216.             if( (mainPanel.editor).selected[n-1] ){ reply = reply+mol.atomElement(n-1)+"\n";}
  217.         }
  218.         return reply;
  219.     }
  220.    
  221.     public String getSVG(String type){ /* 1 or URL : URL is correct answer from server  */
  222.         SVGMolecule svgmol;
  223.         if( type.equals("1") ){ /* get the student reply*/
  224.             try{
  225.                 svgmol = new SVGMolecule((mainPanel.editor).molData());
  226.             }catch(Exception e){return e.toString();}
  227.         }
  228.         else
  229.         {
  230.             try{
  231.                 type = getString("file2");
  232.                 if( type == null ){return "no answer molecule MDLMol to SVG";}
  233.                 String correct_answer = loadAny(type);
  234.                 Molecule answer_mol = MoleculeStream.readMDLMOL(new BufferedReader(new StringReader(correct_answer.toString())));
  235.                 svgmol = new SVGMolecule(answer_mol);
  236.             }catch(Exception e){return e.toString();}
  237.         }    
  238.         double zoom_factor = getDouble("zoomfactor",1.00);
  239.         if( zoom_factor != 1.00 ){ /* simple static in/out zoom, no pan */
  240.             id = System.currentTimeMillis();
  241.             g_id = ("g_SVG_"+id).toString();
  242.             svg_id = ("SVG_"+id).toString();
  243.             zoom_js="<script type=\"text/javascript\">"+
  244.             "var flip = 0;"+
  245.             "function SVG_zoom(svg,g,w0,h0){"+
  246.              "var svg = document.getElementById(svg);"+
  247.              "var g = document.getElementById(g);"+
  248.              "var f = "+zoom_factor+";"+
  249.              "if( flip == 1 ){"+
  250.               "flip = 0;"+
  251.               "var w1 = parseInt(w0*f);"+
  252.               "var h1 = parseInt(h0*f);"+
  253.               "svg.setAttributeNS(null, 'viewBox', '0 0 '+w1+' '+h1);"+
  254.               "svg.setAttributeNS(null, 'width',w1);"+
  255.               "svg.setAttributeNS(null, 'height',h1);"+
  256.               "g.setAttributeNS(null,'transform','matrix('+f+' 0 0 '+f+' 0 0)');"+
  257.              "}else{"+
  258.               "flip = 1;"+
  259.               "svg.setAttributeNS(null, 'viewBox', '0 0 '+w0+' '+h0);"+
  260.               "svg.setAttributeNS(null, 'width',w0);"+
  261.               "svg.setAttributeNS(null, 'height',h0);"+
  262.               "g.setAttributeNS(null,'transform','matrix(1 0 0 1 0 0)');"+
  263.               "};};</script>";
  264.         }
  265.         svgmol.draw();
  266.         String reply = "";
  267.         reply = (svgmol + zoom_js).toString();
  268.         return reply.replaceAll("(\\n|\\r|\\  )", " ");
  269.     }
  270.    
  271.     public boolean[] getTools(){ /* jm.evers: configuring toolbar through appletparams  */
  272.      String param;
  273.      boolean[] TOOL_SELECTION = new boolean[TOOL_COUNT];
  274.      for(int p = 0;p < TOOL_COUNT ; p++){ /* adjust if more buttons are added MainPanel */
  275.       param = getParameter(TOOLS[p]);
  276.       TOOL_SELECTION[p] = false;
  277.       if( param != null ){if(param.equalsIgnoreCase("yes") || param.equals("1")){ TOOL_SELECTION[p] = true;} }
  278.      }
  279.       return TOOL_SELECTION;
  280.     }
  281.  
  282.     public boolean[] getMenus(){ /* jm.evers: configuring menubar through appletparams  */
  283.      String param;
  284.      boolean[] MENU_SELECTION = new boolean[MENU_COUNT];
  285.      for(int p = 0;p < MENU_COUNT ; p++){ /* adjust if more buttons are added MainPanel */
  286.       param = getParameter(MENUS[p]);
  287.       MENU_SELECTION[p] = false;
  288.       if( param != null && param.length() > 0){if(param.equalsIgnoreCase("yes") || param.equals("1")){ MENU_SELECTION[p] = true;} }
  289.      }
  290.       return MENU_SELECTION;
  291.     }
  292.    
  293.     public String[] getTemplateURL(){
  294.         // jm.evers : retreive an unknown amount of templates via params called template1,template2...
  295.         // these templates will be called by Template.java
  296.         String param = getParameter("template1");
  297.         if( param != null && param.length()>0 ){
  298.             int p=0;
  299.             while( param!=null && param.length()!=0 ){
  300.                 p++; /* unknown amount...let's count */
  301.                 param = getParameter("template"+p);
  302.             }
  303.             String[] templateURL = new String[p-1];
  304.             for(int s = 1;s < p; s++){ /* fill the array with url's */
  305.                 param = getParameter("template"+s);
  306.                 System.out.println("loading template url : "+param);
  307.                 templateURL[s - 1] = param;
  308.             }
  309.             return templateURL;
  310.         }
  311.         else
  312.         {
  313.             return null;
  314.         }
  315.     }
  316.    
  317.     public boolean getFile(){
  318.     /*
  319.         jm.evers : try to load a file as string from the URL given in the params
  320.     */
  321.         String showfile = getParameter("showfile");
  322.         if(showfile != null && showfile.length()>0){
  323.             if(showfile.equalsIgnoreCase("yes") ||  showfile.equals("1") ){
  324.                 String filename = getParameter("file");
  325.                 if (filename != null && filename.length() > 0){
  326.                 /*
  327.                     jm.evers: is param showfile is set, draw to canvas...
  328.                 */
  329.                     String demomol = loadAny(filename);
  330.                     if( demomol.indexOf("V2000") < 1 ){
  331.                         SetMolecule(demomol,false);
  332.                     }
  333.                     else
  334.                     {
  335.                         SetMolecule(demomol,true);
  336.                     }
  337.                     return true;
  338.                 }
  339.             }
  340.         }
  341.         else
  342.         {
  343.             System.out.println("not using external file loading");
  344.         }
  345.         return false;
  346.     }
  347.  
  348.     public String getString( String p ){
  349.         String param = getParameter(p);
  350.         if( param != null  && param.length()>0){
  351.             return  param.toString();
  352.         }
  353.         return null;
  354.     }
  355.     public Boolean getBool(String p , boolean d ){
  356.     /* jm.evers 27/12/2008 */
  357.         String param = getParameter(p);
  358.         if( param != null && param.length()>0 ){
  359.             param = param.toLowerCase();
  360.             if(param.equals("1") || param.equalsIgnoreCase("yes") || param.equalsIgnoreCase("true") ){
  361.                 return true;
  362.             }
  363.             if(param.equals("0") || param.equalsIgnoreCase("no") ||  param.equalsIgnoreCase("false")){
  364.                 return false;
  365.             }
  366.         }
  367.         return d;
  368.     }
  369.  
  370.     /*
  371.         routine to read an 'int' from some applet param 'p'
  372.     */
  373.     public int getInt(String p, int d){/* jm.evers 27/12/2008 */
  374.         String param = getParameter(p);
  375.         if( param != null  && param.length()>0){
  376.             return Integer.parseInt( param );
  377.         }
  378.         return d;
  379.         /*
  380.             we don't want to trip over a wrong param...use default
  381.         */
  382.     }
  383.     /*
  384.         routine to read a 'double' from some applet param 'p'
  385.     */
  386.     public double getDouble(String p, double d){/* jm.evers 27/12/2008 */
  387.         String param = getParameter(p);
  388.         if( param != null  && param.length()>0){
  389.             return Double.parseDouble( param );
  390.         }
  391.         return d;
  392.         /*
  393.             we don't want to trip over a wrong param...
  394.         */
  395.     }
  396.     /*
  397.         routine to read a color from some applet param 'p'
  398.     */
  399.     public Color getColor(String p, int alpha, int r0,int g0,int b0 ){
  400.         String param = getParameter(p);
  401.         if( param != null && param.length()>0){
  402.             String k;int R1=0,G1=0,B1=0,rgb=0;
  403.             StringTokenizer q = new StringTokenizer(param, ",");
  404.             int c = q.countTokens();
  405.             if( c != 3){System.out.println("use R,G,B for colours ; use param color_alpha for transparency"); return new Color(0,0,255,255);}
  406.             for( int a = 0; a < 3 ; a++){
  407.                 k = q.nextToken();
  408.                 rgb = Integer.parseInt(k, 10);
  409.                 if( rgb < 0 ){ rgb = 0; }
  410.                 if( rgb > 255 ){ rgb = 255; }
  411.                 if(a == 0){ R1 = rgb;}
  412.                 else
  413.                 if(a == 1){G1 = rgb;}
  414.                 else B1 = rgb;
  415.             }
  416.             return new Color(R1,G1,B1,alpha);
  417.         }
  418.         else
  419.         {
  420.             return new Color(r0,g0,b0,alpha);
  421.         }
  422.     }
  423.    
  424.     /*
  425.         jm.evers: reading atoms from params
  426.     */
  427.     public String[] GetMyAtoms(){
  428.         String param = getParameter("atoms");
  429.         if( param != null && param.length()>0){
  430.             return String2Array( param );
  431.         }
  432.         else
  433.         {
  434.             return null;
  435.         }
  436.     }
  437.     public String getLanguage(){
  438.     /*
  439.         jm.evers: reading language. default english
  440.     */
  441.      String param = getParameter("language");
  442.      if(param != null && param.length() == 2){return  param.toLowerCase();}
  443.      return "en";
  444.     }
  445.    
  446. /* called via javascript */
  447.     public String ReadAtomSelection(){
  448.      boolean[] S = EditorPane.atomselection;
  449.      String selection="";
  450.      for (int p = 1;p < S.length; p++){ /* starts with 1 */
  451.       if(S[p]){ /* is selected */
  452.        if(selection != ""){ selection = selection +","+p; } else { selection=""+p; }
  453.       }
  454.      }
  455.      return selection;
  456.     }
  457.     public String ReadBondSelection(){
  458.      boolean[] S = EditorPane.bondselection;
  459.       String selection="";
  460.       for (int p=0;p<S.length;p++){
  461.        if(S[p]){ /* is selected */
  462.         if(selection == ""){ selection = ""+p; } else { selection = selection+","+p; }
  463.        }
  464.       }
  465.       return selection;
  466.     }
  467.                
  468.  
  469. /* jm.evers : routines to load a file direct or via network */
  470.  
  471.     public String loadAny(String filename){
  472.      String demomol = "";
  473.      try{
  474.         return (load(filename)).toString();
  475.      }catch(Exception e){System.out.println("HMMMM");}
  476.      return demomol;
  477.     }
  478.     public static byte [] loadURL(URL url) throws IOException {
  479.         int bufSize = 1024 * 2;
  480.         byte [] buf = new byte[bufSize];
  481.         ByteArrayOutputStream bout = new ByteArrayOutputStream();
  482.         BufferedInputStream   in   = new BufferedInputStream(url.openStream());
  483.         int n;
  484.         while ((n = in.read(buf)) > 0) {
  485.             bout.write(buf, 0, n);
  486.         }
  487.         try
  488.         { in.close(); } catch (Exception ignored) { }
  489.         return bout.toByteArray();
  490.     }
  491.  
  492.     public static String loadFile(String fname) throws IOException {
  493.      try{
  494.         byte[] bytes = loadURL(new URL("file:" + fname));
  495.         return new String(bytes);
  496.      }catch(Exception e ){System.out.println("loadFile error :"+e.toString());}
  497.      return null;
  498.     }
  499.    
  500.     public static String load(String fileOrURL) throws IOException {
  501.         try {
  502.             URL url = new URL(fileOrURL);
  503.             return new String(loadURL(url));
  504.         } catch (Exception e) {
  505.         return loadFile(fileOrURL);
  506.         }
  507.     }
  508.    public String[] String2Array(String t){
  509.         /*
  510.             jm.evers: parsing params into array...fieldseparators are "," ":" ";" " "
  511.         */
  512.         StringTokenizer q;
  513.         if(t.indexOf(",")!=-1){
  514.             q = new StringTokenizer(t, ",");
  515.         }
  516.         else
  517.         {
  518.             if(t.indexOf(":")!=-1){
  519.                 q = new StringTokenizer(t, ":");
  520.             }
  521.             else
  522.             {
  523.                 if(t.indexOf(";")!=-1){
  524.                     q = new StringTokenizer(t, ";");
  525.                 }
  526.                 else
  527.                 {
  528.                     if(t.indexOf(" ")>2){
  529.                         q = new StringTokenizer(t, " ");
  530.                     }
  531.                     else
  532.                     {
  533.                         return null;
  534.                     }
  535.                 }
  536.             }
  537.         }
  538.         int max = q.countTokens();if( max > 50 ){ max = 50;}
  539.         String[] tmp = new String[max];String s="";
  540.         for( int p = 0 ; p<max ; p++){
  541.             s=q.nextToken();
  542.             if(s.length()==1 || s.length()==2){
  543.                 System.out.println("atom = "+s);
  544.                 tmp[p]=s;
  545.             }
  546.         }
  547.         return tmp;
  548.     }
  549.     public void send_to_wims(int type){
  550.     /*
  551.         DO NOT USE THIS FOR SENDING SVG/XML !!!
  552.         THIS WILL GIVE TROUBLE WIH TOO LARGE STRINGS:
  553.         [quote] The requested URL's length exceeds the capacity limit for this server.
  554.         BETTER USE:
  555.         <form  action="$wims_ref_name?form-data$session" method="post" enctype="multipart/form-data" >
  556.     */
  557.         applet_context = this.getAppletContext();
  558.         String wims_ref_name = getString("wims_ref_name");
  559.         String session = getString("session");
  560.         String module = getString("module");
  561.         String replyargs = getString("replyarguments"); /* reply2=*/
  562.         if( wims_ref_name == null ){
  563.             System.out.println("param wims_ref_name is not set POST will not work !!");
  564.         }
  565.         else
  566.         {
  567.             String student_MDL_molecule = GetMoleculeMDLMol();
  568.             String student_svg_molecule = getSVG("1");
  569.             String correct_svg_molecule = getSVG("2");
  570.             String reply = "";
  571.             switch(type){
  572.                 case 0: reply = student_MDL_molecule;break;
  573.                 case 1: reply = student_svg_molecule+"\n"+student_MDL_molecule;break;
  574.                 case 2: reply = correct_svg_molecule+"\n"+student_svg_molecule+"\n"+student_MDL_molecule;break;
  575.                 default: reply = "send_to_wims(type) \ntype=1: MDLmol student drawing\ntype=2: student SVG \\n MDLmol student drawing\ntype=3: answer SVG \\n student SVG \\n MDLmol student drawing ";
  576.             }
  577.             try{reply = URLEncoder.encode(reply,"UTF-8"); }catch(Exception e){reply = e.toString();}
  578.             String back_url_string = wims_ref_name+"?session="+session+"&module="+module+"&cmd=reply&"+replyargs;
  579.             back_url_string = back_url_string.replaceAll(" ",""); /* no space in url */
  580.             URL backurl;
  581.             try {backurl=new URL(back_url_string+reply);
  582.                 applet_context.showDocument(backurl,"_self");
  583.             } catch (MalformedURLException e){backurl=null;System.out.println("could not send  to wims "+back_url_string);}
  584.         }
  585.     }
  586.    
  587.     /*  
  588.         set bonds and atoms via applet param
  589.     */
  590.     public int[] SetAtomSelection(){
  591.         String param = getParameter("select_atoms");
  592.         if(param != null && param.length()>0){
  593.             String k;int rgb=0;int R1=255;int G1=0;int B1=0;//red
  594.             param=param.replaceAll(";",",");param=param.replaceAll(":",",");
  595.             StringTokenizer i = new StringTokenizer(param, ",");
  596.             int max=i.countTokens();
  597.             ExternalAtomSelection = new int[max];
  598.             SelectedAtomColorArray = new Color[max];
  599.             String ColorParam;
  600.             for(int p=0;p<max;p++){
  601.                 ExternalAtomSelection[p] = Integer.parseInt(i.nextToken());
  602.                 // now try to find the color belonging to this selected atom
  603.                 ColorParam=getParameter("select_atom_color"+ExternalAtomSelection[p]);
  604.                 if(ColorParam != null && ColorParam.length()>0){
  605.                     ColorParam=ColorParam.replaceAll(":",",");ColorParam=ColorParam.replace(";",",");
  606.                     StringTokenizer q = new StringTokenizer(ColorParam, ",");
  607.                     for( int a=0; a<3 ; a++){
  608.                         k=q.nextToken();
  609.                         rgb=Integer.parseInt(k, 10);
  610.                         if(rgb<0){rgb=0;}if(rgb>255){rgb=255;}
  611.                         if(a == 0){R1 = rgb;}
  612.                         else
  613.                         {
  614.                             if(a == 1){G1 = rgb;}
  615.                             else{B1 = rgb;}
  616.                         }
  617.                     }
  618.                     SelectedAtomColorArray[p] = new  Color(R1,G1,B1,GLOBAL_ALPHA);
  619.                 }
  620.                 else
  621.                 {
  622.                     SelectedAtomColorArray[p] = ATOM_SELECT_COLOR;
  623.                 }
  624.             }
  625.         }else{ ExternalAtomSelection = null;}
  626.         return ExternalAtomSelection;
  627.     }
  628.  
  629.     /*  
  630.         set bonds and atoms via applet param
  631.     */
  632.     public int[] SetBondSelection(){
  633.         String param = getParameter("select_bonds");
  634.         if(param != null && param.length()>0){
  635.             String k;int rgb=0;int R1=255;int G1=0;int B1=0;String ColorParam;
  636.             param=param.replaceAll(";",",");param=param.replaceAll(":",",");
  637.             StringTokenizer i = new StringTokenizer(param, ",");
  638.             int max=i.countTokens();
  639.             ExternalBondSelection = new int[max];
  640.             SelectedBondColorArray = new Color[max];
  641.             for(int p=0;p<max;p++){
  642.                 ExternalBondSelection[p] = Integer.parseInt(i.nextToken());
  643.                 // now try to find the color belonging to this selected bond
  644.                 ColorParam=getParameter("select_bond_color"+ExternalBondSelection[p]);
  645.                 if(ColorParam != null && ColorParam.length()>0){
  646.                     ColorParam=ColorParam.replaceAll(":",",");ColorParam=ColorParam.replace(";",",");
  647.                     StringTokenizer q = new StringTokenizer(ColorParam, ",");
  648.                     for( int a=0; a<3 ; a++){
  649.                         k=q.nextToken();
  650.                         rgb=Integer.parseInt(k, 10);
  651.                         if(rgb<0){rgb=0;}if(rgb>255){rgb=255;}
  652.                         if(a == 0){R1 = rgb;}
  653.                         else
  654.                         {
  655.                             if(a == 1){G1 = rgb;}
  656.                             else{B1 = rgb;}
  657.                         }
  658.                     }
  659.                     SelectedBondColorArray[p] = new  Color(R1,G1,B1,GLOBAL_ALPHA);
  660.                 }
  661.                 else
  662.                 {
  663.                     SelectedBondColorArray[p] = BOND_SELECT_COLOR;
  664.                 }
  665.             }
  666.         }else{ ExternalBondSelection = null;}
  667.         return ExternalBondSelection;
  668.     }
  669.  
  670.     /*
  671.         return molecule data from current molecule in panel
  672.         returns 5 lines with  
  673.         line 1 : molweight      : eg 1 decimal, eg 123.4
  674.         line 2 : plain formula  : eg C5H4O2
  675.         line 3 : html formula   : eg C<sub>5</sub>H<sub>4</sub>O<sub>2</sub>
  676.         line 4 : plain formula  : eg C5H4O2 (this was in the old wimschem a faulty smiles interpretation...)
  677.         line 5 : latex formula  : eg C_{5}H_{4}O_{2}
  678.     */
  679.     public String ReadApplet(){
  680.         try{
  681.             StringWriter sw = new StringWriter();
  682.             BufferedWriter bw = new BufferedWriter(sw);
  683.             MoleculeStream.writeNative(bw,mainPanel.molData());
  684.             String nativemol = sw.toString();
  685.             nativemol = nativemol.replaceAll(" ","");
  686.             return moleculeData(nativemol);
  687.         }catch(Exception e){return e.toString();}
  688.     }
  689.    
  690.     public String moleculeData(String S){
  691.         int N=Molecule.ELEMENTS.length;
  692.         double[] WEIGHTS={0.0,1.00794,4.002602,6.941,9.01218,10.811,12.011,14.00674,15.9994,18.998403,20.1797,
  693.         22.989768,24.305,26.981539,28.0855,30.973762,32.066,35.4527,39.948,39.0983,40.078,
  694.         44.95591,47.88,50.9415,51.9961,54.93805,55.847,58.9332,58.6934,63.546,65.39,
  695.         69.723,72.61,74.92159,78.96,79.904,83.8,85.4678,87.62,88.90585,91.224,
  696.         92.90638,95.94,97.9072,101.07,102.9055,106.42,107.8682,112.411,114.818,118.71,
  697.         121.760,127.6,126.90447,131.29,132.90543,137.327,138.9055,140.115,140.90765,144.24,
  698.         144.9127,150.36,151.965,157.25,158.92534,162.50,164.93032,167.26,168.93421,173.04,
  699.         174.967,178.49,180.9479,183.84,186.207,190.23,192.22,195.08,196.96654,200.59,
  700.         204.3833,207.2,208.98037,208.9824,209.9871,222.0176,223.0197,226.0254,227.0278,232.0381,
  701.         231.03588,238.0289,237.048,244.0642,243.0614,247.0703,247.0703,251.0796,252.083,257.0951,
  702.         258.1,259.1009,262.11};
  703.        
  704.         String[] s=S.split("\n");String[] atom;int s1=s[0].indexOf('(');int s2=s[0].indexOf(',');int s3=s[0].indexOf(')');
  705.         int n_s=Integer.parseInt(s[0].substring(s1+1,s2).trim());int b_s=Integer.parseInt(s[0].substring(s2+1,s3).trim());
  706.         String[] E_s=new String[n_s];int[] H_s=new int[n_s];int[] C_s=new int[n_s];int[] R_s=new int[n_s];
  707.         int[] this_A=new int[N];int[] this_C=new int[N];int[] this_R=new int[N];int[] this_H=new int[N];
  708.         String plainformula="";String htmlformula="";String latexformula="";
  709.         String R_plain="";String R_html="";String R_latex="";
  710.         String C_plain="";String C_html="";String C_latex="";
  711.         String sign;
  712.         double weight_s=0.0D;int r=0;
  713.        
  714.         /* loop only through the atom part of the file-string */
  715.         for( int p=0; p<n_s ;p++){
  716.             atom=s[p+1].split("[\\=\\,\\;]"); /* first line is mimetype */
  717.             E_s[p]=atom[0];r=0;
  718.             for(int n=0;n<N;n++){
  719.                 if(atom[0].equals(Molecule.ELEMENTS[n])){
  720.                     weight_s=(double)(weight_s + WEIGHTS[n]);
  721.                     this_A[n]++;r=n;n=N;
  722.                 }
  723.             }
  724.             C_s[p]=Integer.parseInt(atom[3]);
  725.             this_C[r]=C_s[p];
  726.             R_s[p]=Integer.parseInt(atom[4]);
  727.             this_R[p]=R_s[p];
  728.             if( atom[5].indexOf("i")!=-1){
  729.                 atom[5]=atom[5].replaceAll("i","");H_s[p]=Integer.parseInt(atom[5]);this_H[r]=H_s[p];this_A[1]=this_A[1]+H_s[p];//hydrogen
  730.             }
  731.             else
  732.             {
  733.                 atom[5]=atom[5].replaceAll("e","");H_s[p]=Integer.parseInt(atom[5]);this_H[r]=H_s[p];this_A[1]=this_A[1]+H_s[p];//hydrogen
  734.             }      
  735.             weight_s=(double)(weight_s + H_s[p]);
  736.         }
  737.  
  738.         if(this_A[6]!=0){
  739.             if(this_R[6] != 0){R_plain="\u2022";R_latex="^{^{\\cdot}}";R_html="<sup>&cdot;</sup>";}
  740.             if(this_C[6] != 0){
  741.                 if(this_C[6]>0){sign="+";}else{sign="-";this_C[6]=(int) (Math.abs(this_C[6]));}
  742.                 C_plain=this_C[6]+sign;C_latex="^{"+this_C[6]+sign+"}";C_html="<sup><small>"+this_C[6]+sign+"</small></sup>";
  743.             }
  744.             if(this_A[6] == 1 ){/* C1 is not done:  CH4 */
  745.                 plainformula="C"+C_plain+R_plain+" ";
  746.                 htmlformula="<span style=\"fontsize:110%\" ><tt>C"+C_html+R_html+"</tt></span>";
  747.                 latexformula="\\Bf{C"+C_latex+R_latex+"}";
  748.             }
  749.             else
  750.             {//C2H5OH
  751.                 plainformula="C"+C_plain+R_plain+this_A[6];
  752.                 htmlformula="<span style=\"fontsize:110%\" ><tt>C"+C_html+R_html+"</tt></span><sub><small>"+this_A[6]+"</small></sub>";
  753.                 latexformula="\\Bf{C"+C_latex+R_latex+"}_{"+this_A[6]+"}";
  754.             }
  755.         }
  756.         // the rest
  757.         for(int p = 0; p<N; p++){
  758.             if( p == 6 ){ p = 7;} /* we already covered carbon */
  759.             if( this_A[p] != 0 ){
  760.                 R_plain="";R_html="";R_latex="";C_plain="";C_html="";C_latex="";sign="";
  761.                 if( this_R[p] != 0 ){ R_plain=this_R[p]+"\u2022";R_latex="^{^{"+this_R[p]+"\\cdot}}";R_html="<sup><sup>"+this_R[p]+"&cdot;</sup></sup>";}
  762.                 if( this_C[p] != 0 ){ if( this_C[p]>0 ){ sign="+"; } else { sign="-"; this_C[p]=-1*this_C[p];}C_plain=this_C[p]+sign;C_latex="^{"+this_C[p]+sign+"}";C_html="<sup><small>"+this_C[p]+sign+"</small></sup>";}
  763.                 if( this_A[p] == 1 ){
  764.                     plainformula=plainformula+" "+Molecule.ELEMENTS[p]+""+C_plain+""+R_plain;
  765.                     htmlformula=htmlformula+" <span style=\"fontsize:110%\" ><tt>"+Molecule.ELEMENTS[p]+C_html+R_html+"</tt></span>";
  766.                     latexformula=latexformula+"\\,\\Bf{"+Molecule.ELEMENTS[p]+C_latex+R_latex+"}";
  767.                 }
  768.                 else
  769.                 {
  770.                     plainformula=plainformula+" "+Molecule.ELEMENTS[p]+""+C_plain+""+R_plain+""+this_A[p];
  771.                     htmlformula=htmlformula+" <span style=\"fontsize:110%\" ><tt>"+Molecule.ELEMENTS[p]+C_html+R_html+"</tt></span><sub><small>"+this_A[p]+"</small></sub>";
  772.                     latexformula=latexformula+"\\,\\Bf{"+Molecule.ELEMENTS[p]+C_latex+R_latex+"}_{"+this_A[p]+"}";
  773.                 }
  774.             }
  775.         }
  776.         DecimalFormat df = new DecimalFormat("#.#",new DecimalFormatSymbols(Locale.US));
  777.         /*
  778.             the second 'plainformula' was (the no good) previous smiles-formula ;
  779.             added just to satisfy my checkfiles ...
  780.         */
  781.         return df.format(weight_s)+"\n"+plainformula+"\n"+htmlformula+"\n"+plainformula+"\n"+latexformula;
  782.     }
  783. }
  784.