Subversion Repositories wimsdev

Rev

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

  1. /*
  2.     WIMSchem: modified version of SketchEl.
  3.     Elements: Chemistry molecular diagram drawing tool.
  4.    
  5.     (c) 2005 Dr. Alex M. Clark
  6.    
  7.     Released as GNUware, under the Gnu Public License (GPL)
  8.    
  9.     See www.gnu.org for details.
  10. */
  11.  
  12. package WIMSchem;
  13.  
  14. import java.io.*;
  15. import java.awt.*;
  16. import java.awt.event.*;
  17. import java.util.*;
  18. import javax.swing.*;
  19. import java.net.*;
  20.  
  21. public class MainApplet extends JApplet implements ComponentListener{
  22.    
  23.     // amateur solutions...
  24.     MainPanel mainPanel=null;
  25.     MainPanel Language=null;
  26.     MainPanel Translation=null;
  27.     static String[] tools={"TOOL_CURSOR","TOOL_ROTATOR","TOOL_ERASOR","TOOL_DIALOG","TOOL_EDIT","TOOL_SETATOM",
  28.     "TOOL_SINGLE","TOOL_DOUBLE","TOOL_TRIPLE","TOOL_ZERO","TOOL_INCLINED","TOOL_DECLINED","TOOL_UNKNOWN",
  29.     "TOOL_CHARGE","TOOL_UNDO","TOOL_REDO","TOOL_TEMPLATE","TOOL_CUT","TOOL_COPY","TOOL_PASTE","TOOL_UNSELECT","TOOL_SELECT"};
  30.     static String[] menus={"MENU_BLOCK","MENU_SELECT","MENU_TRANSFORM","MENU_ZOOM","MENU_SHOW","MENU_HYDROGEN","MENU_STEREO","MENU_HELP"};
  31.     public boolean[] selected_tools;
  32.     public boolean[] selected_menus;
  33.     public static Properties translation=new Properties();
  34.     public String Correct_answer="";
  35.     public String feedback="";
  36.     public boolean continu=true;
  37.     public String replytext="";
  38.     public String Student_answer="";
  39.     public String language;
  40.     public int typeset=0;
  41.     public String plain_formula_ca="";
  42.     public String html_formula_ca="";
  43.     public String latex_formula_ca="";
  44.     public String plain_formula_sa="";
  45.     public String html_formula_sa="";
  46.     public String latex_formula_sa="";
  47.     static int N=Molecule.ELEMENTS.length;
  48.     public int[] charge_ca;// charge of the atom
  49.     public int[] radical_ca;// radicals?
  50.     public int[] charge_sa;// charge of the atom
  51.     public int[] radical_sa;// radicals?
  52.     public String[] elements_ca;
  53.     public String[] elements_sa;
  54.     public int[] hydro_ca;
  55.     public int[] hydro_sa;
  56.     double weight_ca=0;
  57.     double weight_sa=0;
  58.     String html_smiles_ca="";
  59.     String html_smiles_sa="";
  60.     public int num_sa=0;
  61.     public int num_ca=0;
  62.     public int bond_sa=0;
  63.     public int bond_ca=0;
  64.     public String[] my_atoms;
  65.     public boolean ViewH;
  66.     public boolean ViewC;
  67.     public static String[] templateURL;
  68.     public static int[] ExternalAtomSelection;
  69.     public static Color SelectedAtomColorArray[];
  70.     public static int[] ExternalBondSelection;
  71.     public static Color SelectedBondColorArray[];
  72.     public static double rotation;
  73.     public static boolean once=true;
  74.     public static Color DefaultAtomSelectionColor;
  75.     public static Color DefaultBondSelectionColor;
  76.     public int alpha = 100;
  77.     public static boolean user_selection;
  78.  
  79.     public void init(){
  80.         getUserSelection();
  81.         if(user_selection){
  82.             getAlpha();
  83.             GetDefaultAtomSelectionColor();
  84.             GetDefaultBondSelectionColor();
  85.         }
  86.         ExternalAtomSelection = SetAtomSelection();
  87.         ExternalBondSelection = SetBondSelection();
  88.         getRotation();
  89.         templateURL=GetTemplateURL();
  90.         ViewH=ViewHydrogen();
  91.         ViewC=ViewCarbon();
  92.         selected_tools=getTools();
  93.         selected_menus=getMenus();
  94.         my_atoms=GetMyAtoms();
  95.         language=getLanguage();
  96.         translation=loadProperties(language);
  97.         getContentPane().setLayout(new BorderLayout());
  98.         mainPanel=new MainPanel(null,false,true,null,language,translation,selected_tools,selected_menus,my_atoms,ViewH,ViewC);
  99.         getContentPane().add(mainPanel,BorderLayout.CENTER);
  100.         Molecule mol=ParseParams();
  101.         if (mol!=null){mainPanel.SetMolecule(mol);}    
  102.         addComponentListener(this);
  103.         GetFile();
  104.         repaint(1000);
  105.     }
  106.    
  107.  
  108.     public void getUserSelection(){
  109.         String Param=getParameter("user_selection");
  110.         if(Param != null && Param.length()>0){
  111.             if(Param.equalsIgnoreCase("yes") || Param.equals("1")){
  112.                 user_selection = true;
  113.             }
  114.             else
  115.             {
  116.                 user_selection = false;
  117.             }
  118.         }
  119.     }
  120.  
  121.     public void getAlpha(){
  122.         String AlphaParam=getParameter("color_alpha");
  123.         if(AlphaParam != null && AlphaParam.length()>0){
  124.             alpha = Integer.parseInt(AlphaParam);
  125.         }
  126.     }
  127.    
  128.     public void GetDefaultAtomSelectionColor(){
  129.         String DefaultParam = getParameter("default_atom_select_color");
  130.         if(DefaultParam != null && DefaultParam.length()>0){
  131.             String k;int R1=0,G1=0,B1=0,rgb=0;
  132.             StringTokenizer q = new StringTokenizer(DefaultParam, ",");
  133.             for( int a=0; a<3 ; a++){
  134.                 k=q.nextToken();
  135.                 rgb=Integer.parseInt(k, 10);
  136.                 if(rgb<0){rgb=0;}if(rgb>255){rgb=255;}
  137.                 if(a == 0){R1 = rgb;}
  138.                 else
  139.                 if(a == 1){G1 = rgb;}
  140.                 else B1 = rgb;
  141.             }
  142.             DefaultAtomSelectionColor = new Color(R1,G1,B1,alpha);         
  143.         }
  144.         else
  145.         {
  146.             DefaultAtomSelectionColor = new Color(0,0,255,100);
  147.         }
  148.     }
  149.  
  150.     public void GetDefaultBondSelectionColor(){
  151.         String DefaultParam = getParameter("default_bond_select_color");
  152.         if(DefaultParam != null && DefaultParam.length()>0){
  153.             String k;int R1=0,G1=0,B1=0,rgb=0;
  154.             StringTokenizer q = new StringTokenizer(DefaultParam, ",");
  155.             for( int a=0; a<3 ; a++){
  156.                 k=q.nextToken();
  157.                 rgb=Integer.parseInt(k, 10);
  158.                 if(rgb<0){rgb=0;}if(rgb>255){rgb=255;}
  159.                 if(a == 0){R1 = rgb;}
  160.                 else
  161.                 if(a == 1){G1 = rgb;}
  162.                 else B1 = rgb;
  163.             }
  164.             DefaultBondSelectionColor = new Color(R1,G1,B1,alpha);         
  165.         }
  166.         else
  167.         {
  168.             DefaultBondSelectionColor = new Color(255,0,0);
  169.         }
  170.     }
  171.  
  172.     public int[] SetAtomSelection(){
  173.         String param = getParameter("select_atoms");
  174.         if(param != null && param.length()>0){
  175.             String k;int rgb=0;int R1=255;int G1=0;int B1=0;//red
  176.             param=param.replaceAll(";",",");param=param.replaceAll(":",",");
  177.             StringTokenizer i = new StringTokenizer(param, ",");
  178.             int max=i.countTokens();
  179.             ExternalAtomSelection = new int[max];
  180.             SelectedAtomColorArray = new Color[max];
  181.             String ColorParam;
  182.             for(int p=0;p<max;p++){
  183.                 ExternalAtomSelection[p] = Integer.parseInt(i.nextToken());
  184.                 // now try to find the color belonging to this selected atom
  185.                 ColorParam=getParameter("select_atom_color"+ExternalAtomSelection[p]);
  186.                 if(ColorParam != null && ColorParam.length()>0){
  187.                     ColorParam=ColorParam.replaceAll(":",",");ColorParam=ColorParam.replace(";",",");
  188.                     StringTokenizer q = new StringTokenizer(ColorParam, ",");
  189.                     for( int a=0; a<3 ; a++){
  190.                         k=q.nextToken();
  191.                         rgb=Integer.parseInt(k, 10);
  192.                         if(rgb<0){rgb=0;}if(rgb>255){rgb=255;}
  193.                         if(a == 0){R1 = rgb;}
  194.                         else
  195.                         {
  196.                             if(a == 1){G1 = rgb;}
  197.                             else{B1 = rgb;}
  198.                         }
  199.                     }
  200.                     SelectedAtomColorArray[p] = new  Color(R1,G1,B1,alpha);
  201.                 }
  202.                 else
  203.                 {
  204.                     SelectedAtomColorArray[p] = DefaultAtomSelectionColor;
  205.                 }
  206.             }
  207.         }else{ ExternalAtomSelection = null;}
  208.         return ExternalAtomSelection;
  209.     }
  210.  
  211.     public int[] SetBondSelection(){
  212.         String param = getParameter("select_bonds");
  213.         if(param != null && param.length()>0){
  214.             String k;int rgb=0;int R1=255;int G1=0;int B1=0;String ColorParam;
  215.             param=param.replaceAll(";",",");param=param.replaceAll(":",",");
  216.             StringTokenizer i = new StringTokenizer(param, ",");
  217.             int max=i.countTokens();
  218.             ExternalBondSelection = new int[max];
  219.             SelectedBondColorArray = new Color[max];
  220.             for(int p=0;p<max;p++){
  221.                 ExternalBondSelection[p] = Integer.parseInt(i.nextToken());
  222.                 // now try to find the color belonging to this selected bond
  223.                 ColorParam=getParameter("select_bond_color"+ExternalBondSelection[p]);
  224.                 if(ColorParam != null && ColorParam.length()>0){
  225.                     ColorParam=ColorParam.replaceAll(":",",");ColorParam=ColorParam.replace(";",",");
  226.                     StringTokenizer q = new StringTokenizer(ColorParam, ",");
  227.                     for( int a=0; a<3 ; a++){
  228.                         k=q.nextToken();
  229.                         rgb=Integer.parseInt(k, 10);
  230.                         if(rgb<0){rgb=0;}if(rgb>255){rgb=255;}
  231.                         if(a == 0){R1 = rgb;}
  232.                         else
  233.                         {
  234.                             if(a == 1){G1 = rgb;}
  235.                             else{B1 = rgb;}
  236.                         }
  237.                     }
  238.                     SelectedBondColorArray[p] = new  Color(R1,G1,B1);
  239.                 }
  240.                 else
  241.                 {
  242.                     SelectedBondColorArray[p] = DefaultBondSelectionColor;
  243.                 }
  244.             }
  245.         }else{ ExternalBondSelection = null;}
  246.         return ExternalBondSelection;
  247.     }
  248.    
  249.     public void getRotation(){
  250.         String rot = getParameter("rotation");
  251.         if(rot != null && rot.length()>0){
  252.             rotation = Double.parseDouble(rot);
  253.         }else{rotation = 0.0D;}
  254.     }
  255.  
  256.     public static byte [] loadURL(URL url) throws IOException {
  257.     // jm.evers :handy functions !!! not mine :(
  258.         int bufSize = 1024 * 2;
  259.         byte [] buf = new byte[bufSize];
  260.         ByteArrayOutputStream bout = new ByteArrayOutputStream();
  261.         BufferedInputStream   in   = new BufferedInputStream(url.openStream());
  262.         int n;
  263.         while ((n = in.read(buf)) > 0) {
  264.             bout.write(buf, 0, n);
  265.         }
  266.         try
  267.         { in.close(); } catch (Exception ignored) { }
  268.         return bout.toByteArray();
  269.     }
  270.  
  271.     public static String loadFile(String fname) throws IOException {
  272.     // jm.evers :handy functions !!! not mine :(
  273.         byte[] bytes = loadURL(new URL("file:" + fname));
  274.         return new String(bytes);
  275.     }
  276.    
  277.     public static String load(String fileOrURL) throws IOException {
  278.     // jm.evers :handy functions !!! not mine :(
  279.         try {
  280.             URL url = new URL(fileOrURL);
  281.             return new String(loadURL(url));
  282.         } catch (Exception e) {
  283.         return loadFile(fileOrURL);
  284.         }
  285.     }
  286.    
  287.     public String[] GetTemplateURL(){
  288.         // jm.evers : retreive an unknown amount of templates via params called template1,template2...
  289.         // these templates will be called by Template.java
  290.         String parm=getParameter("template1");
  291.         if( parm != null && parm.length()!=0 ){
  292.             int p=0;
  293.             while( parm!=null && parm.length()!=0 ){
  294.                 p++;
  295.                 parm=getParameter("template"+p);
  296.             }
  297.             String[] templateURL=new String[p-1];
  298.             for(int s=1;s<p;s++){
  299.                 parm=getParameter("template"+s);
  300.                 templateURL[s-1]=parm;
  301.             }
  302.             return templateURL;
  303.         }
  304.         else
  305.         {
  306.             return null;
  307.         }
  308.     }
  309.    
  310.     public void GetFile(){
  311.     //jm.evers : try to load a file as string from the URL given in the params
  312.         String filename=getParameter("file");
  313.         if (filename!=null){
  314.             try
  315.             {
  316.                 // jm.evers: is param showfile is set, draw to canvas...
  317.                 String showfile=getParameter("showfile");
  318.                 if(showfile.equalsIgnoreCase("yes") ||  showfile.equals("1")){
  319.                     String DemoMol=(load(filename)).toString();
  320.                     if(DemoMol.indexOf("WIMSchem!")!=-1 && DemoMol.indexOf("!FIN")!=-1){
  321.                         AppendMoleculeNative(DemoMol);
  322.                     }
  323.                     else
  324.                     {
  325.                         if( DemoMol.indexOf("molfile")!=-1){
  326.                             AppendMoleculeMDLMol(DemoMol);
  327.                         }
  328.                         else
  329.                         {
  330.                             System.out.println("Unknown filetype or corrupt file "+filename+"\n"+DemoMol);
  331.                         }
  332.                     }
  333.                 }
  334.                 else
  335.                 {
  336.                     Correct_answer=(load(filename)).toString();
  337.                     GetQuestion(Correct_answer);
  338.                 }
  339.             }
  340.             catch (Exception e){System.out.println("Could not load "+filename);continu=false;}
  341.         }
  342.         else
  343.         {
  344.             System.out.println("param \"file\" is empty\nWill not use fileloading");
  345.         }
  346.     }  
  347.  
  348.     public String getLanguage(){
  349.         // jm.evers: reading language. default english
  350.         String param = getParameter("language");
  351.         if(param != null){param = param.toLowerCase();}else{param = "en";}
  352.         return param;
  353.     }
  354.  
  355.     public Boolean ViewHydrogen(){
  356.         // jm.evers: reading hydrogen param. 27/12/2008
  357.         String param = getParameter("show_hydrogen");
  358.         boolean h=true;
  359.         if(param != null){param = param.toLowerCase();
  360.             if(param.equals("0") || param.equals("no")){
  361.                 h=false;
  362.             }
  363.         }
  364.         return h;
  365.     }
  366.  
  367.     public Boolean ViewCarbon(){
  368.         // jm.evers: reading elements param. 27/12/2008
  369.         String param = getParameter("show_carbon");
  370.         boolean c=true;
  371.         if(param != null){param = param.toLowerCase();
  372.             if(param.equals("0") || param.equals("no")){
  373.                 c=false;
  374.             }
  375.         }
  376.         return c;
  377.     }
  378.  
  379.     public String[] GetMyAtoms(){
  380.         // jm.evers: reading atoms from params
  381.         String param = getParameter("atoms");
  382.         if(param != null){
  383.             //System.out.println("found Atoms: "+param);
  384.             my_atoms=AtomString2AtomArray(param);
  385.             return my_atoms;
  386.         }
  387.         else{
  388.             return null;
  389.         }
  390.     }
  391.    
  392.     public String ReadAtomSelection(){
  393.         boolean[] S = EditorPane.atomselection;
  394.         String selection="";
  395.         for (int p=1;p<S.length;p++){ // starts with 1
  396.             if(S[p]){ // is selected
  397.                 if(selection != ""){
  398.                     selection=selection +","+p;
  399.                 }
  400.                 else{
  401.                     selection=""+p;
  402.                 }
  403.             }
  404.         }
  405.         return selection;
  406.     }
  407.  
  408.     public String ReadBondSelection(){
  409.         boolean[] S = EditorPane.bondselection;
  410.         String selection="";
  411.         for (int p=0;p<S.length;p++){
  412.             if(S[p]){ // is selected
  413.                 if(selection == ""){
  414.                     selection = ""+p;
  415.                 }
  416.                 else{
  417.                     selection=selection+","+p;
  418.                 }
  419.             }
  420.         }
  421.         return selection;
  422.     }
  423.    
  424.     public String[] AtomString2AtomArray(String t){
  425.         //jm.evers: parsing params into array...fieldseparators are "," ":" ";" " "
  426.         StringTokenizer q;
  427.         if(t.indexOf(",")!=-1){
  428.             q = new StringTokenizer(t, ",");
  429.         }
  430.         else
  431.         {
  432.             if(t.indexOf(":")!=-1){
  433.                 q = new StringTokenizer(t, ":");       
  434.             }
  435.             else
  436.             {
  437.                 if(t.indexOf(";")!=-1){
  438.                     q = new StringTokenizer(t, ";");   
  439.                 }
  440.                 else
  441.                 {
  442.                     if(t.indexOf(" ")>2){
  443.                         q = new StringTokenizer(t, " ");       
  444.                     }
  445.                     else
  446.                     {
  447.                         return null;
  448.                     }
  449.                 }
  450.             }
  451.         }
  452.         int max=q.countTokens();if( max > 50 ){ max = 50;}
  453.         String[] tmp=new String[max];String s="";
  454.         for( int p = 0 ; p<max ; p++){
  455.             s=q.nextToken();
  456.             //System.out.println("found atom "+s);
  457.             if(s.length()==1 || s.length()==2){
  458.                 tmp[p]=s;
  459.                 //System.out.println("added");
  460.             }
  461.         }
  462.         return tmp;
  463.     }    
  464.    
  465.     public boolean[] getMenus(){
  466.         // jm.evers: configuring menus through appletparams
  467.         String param;
  468.         selected_menus=new boolean[8];
  469.         for(int p=0;p<8;p++){
  470.             param=getParameter(menus[p]);
  471.             if(param!=null){
  472.                 if(param.equalsIgnoreCase("yes") || param.equals("1")){
  473.                     selected_menus[p]=true;
  474.                 }
  475.                 else
  476.                 {
  477.                     selected_menus[p]=false;
  478.                 }
  479.             }
  480.             else
  481.             {
  482.                 selected_menus[p]=true;
  483.             }
  484.         }
  485.         return selected_menus;
  486.    
  487.     }
  488.    
  489.     public boolean[] getTools(){
  490.         // jm.evers: configuring toolbar through appletparams
  491.         String param;
  492.         selected_tools=new boolean[22];//adjust if more buttons are added MainPanel en here
  493.         for(int p=0;p<22;p++){//adjust if more buttons are added MainPanel en here
  494.             param=getParameter(tools[p]);
  495.             if(param!=null){
  496.                 if(param.equalsIgnoreCase("yes") || param.equals("1")){
  497.                     selected_tools[p]=true;
  498.                 }
  499.                 else
  500.                 {
  501.                     selected_tools[p]=false;
  502.                 }
  503.             }
  504.             else
  505.             {
  506.                 selected_tools[p]=false;
  507.             }
  508.         }
  509.         return selected_tools;
  510.     }
  511.    
  512.     public Properties loadProperties (String lang){
  513.         translation=new Properties();
  514.         // jm.evers : trying global properties file with translations
  515.         try{
  516.             InputStream in = getClass().getResourceAsStream("/lang/WIMSchemProperties_"+lang+".properties");
  517.             translation.load(in);in.close();
  518.             return translation;
  519.         }
  520.         catch (Exception e){ System.out.println("error reading /lang/WIMSchemProperties_"+lang+".properties\n"+e);}        
  521.             return null;                                                                                                              
  522.     }  
  523.  
  524.  
  525.     public String getAppletInfo(){
  526.         return  translation.getProperty("WIMSchem_Applet_Description");
  527.     }
  528.  
  529.     // if the source webpage wishes to supply a molecule at startup time, there is a slightly cumbersome way to accomplish this:
  530.     // the <params> tag may be used; "nlines" should have the total number of lines of text, and each "line{#}" (e.g. "line1", "line50",
  531.     // etc.) should contain the content; the string that emerges should be either WIMSchem native format, or MDL MOL
  532.    
  533.     private Molecule ParseParams(){
  534.         try
  535.         {
  536.             String str=getParameter("nlines");
  537.             if (str==null) return null;
  538.             int nlines=Integer.valueOf(str).intValue();
  539.             if (nlines<3 || nlines>10000) return null; // insanity
  540.  
  541.             StringBuffer buff=new StringBuffer();
  542.             for (int n=1;n<=nlines;n++)
  543.             {
  544.                 str=getParameter("line"+n);
  545.                 if (str==null) return null;
  546.                 for (int i=0;i<str.length();i++)
  547.                 {
  548.                     if (str.charAt(i)=='_') str=str.substring(0,i)+" "+str.substring(i+1); else break;
  549.                 }
  550.                 buff.append(str+"\n");
  551.             }
  552.            
  553.             Molecule mol=MoleculeStream.ReadNative(new BufferedReader(new StringReader(buff.toString())));
  554.             if (mol.NumAtoms()>0) return mol;
  555.             return null;
  556.         }
  557.         catch (Exception e)
  558.         {
  559.             JOptionPane.showMessageDialog(null,translation.getProperty("Unable_to_parse_parameter_molecule")+e.getMessage(),"zog",JOptionPane.ERROR_MESSAGE);
  560.         }
  561.  
  562.         return null;
  563.     }
  564.    
  565.     // methods intended to interact with Javascript
  566.     // replace the current molecule with the content of the string, which can be any of the formats which WIMSchem
  567.     // is able to read out from a file; returns true if successful
  568.     public boolean SetMoleculeNative(String Source) {
  569.         try
  570.         {
  571.             Molecule mol=MoleculeStream.ReadNative(new BufferedReader(new StringReader(Source.toString())));
  572.             //Molecule mol=MoleculeStream.ReadUnknown(new BufferedReader(new StringReader(Source)));
  573.             mainPanel.SetMolecule(mol);
  574.             mainPanel.repaint();
  575.             return true;
  576.         }
  577.         catch (IOException e) { System.out.println("error"+e);}
  578.         return false;
  579.     }
  580.  
  581.     public boolean SetMoleculeMDLMol(String Source) {
  582.         try
  583.         {
  584.             Molecule mol=MoleculeStream.ReadMDLMOL(new BufferedReader(new StringReader(Source.toString())));
  585.             //Molecule mol=MoleculeStream.ReadUnknown(new BufferedReader(new StringReader(Source)));
  586.             mainPanel.SetMolecule(mol);
  587.             mainPanel.repaint();
  588.             return true;
  589.         }
  590.         catch (IOException e) { System.out.println("error"+e);}
  591.         return false;
  592.     }
  593.    
  594.     // appends the indicated molecular source to the current molecule, in the same way as the paste feature; otherwise works
  595.     // the same as SetMolecule
  596.     public boolean AppendMoleculeNative(String Source){
  597.         try
  598.         {
  599.             Molecule mol=MoleculeStream.ReadNative(new BufferedReader(new StringReader(Source.toString())));
  600.             mainPanel.AddMolecule(mol);
  601.             mainPanel.repaint();
  602.             return true;
  603.         }
  604.         catch (IOException e) {System.out.println("error"+e);}
  605.        
  606.         return false;
  607.     }
  608.  
  609.     public boolean AppendMoleculeMDLMol(String Source){
  610.         try
  611.         {
  612.             Molecule mol=MoleculeStream.ReadMDLMOL(new BufferedReader(new StringReader(Source.toString())));   
  613.             mainPanel.AddMolecule(mol);
  614.             mainPanel.repaint();
  615.             return true;
  616.         }
  617.         catch (IOException e) {System.out.println("error"+e);}
  618.        
  619.         return false;
  620.     }
  621.    
  622.     // return the string representation of the molecule, in WIMSchem native format
  623.     public String GetMoleculeNative(){
  624.         try
  625.         {
  626.             StringWriter sw=new StringWriter();
  627.             BufferedWriter bw=new BufferedWriter(sw);
  628.             MoleculeStream.WriteNative(bw,mainPanel.MolData());
  629.             return sw.toString();
  630.         }
  631.         catch (IOException e) {System.out.println("error"+e);}
  632.        
  633.         return null;
  634.     }
  635.    
  636.     // return the string representation of the molecule, in MDL MOL-file format
  637.     public String GetMoleculeMDLMol(){
  638.         try
  639.         {
  640.             StringWriter sw=new StringWriter();
  641.             BufferedWriter bw=new BufferedWriter(sw);
  642.             MoleculeStream.WriteMDLMOL(bw,mainPanel.MolData());
  643.             return sw.toString();
  644.         }
  645.         catch (IOException e) {System.out.println("error"+e);}
  646.        
  647.         return null;
  648.     }
  649.  
  650.     public void GetQuestion(String i){
  651.         //jm.evers:
  652.         // called by javascript to "upload" the chemical from a javascript variable. [a wims "record" in my modules]
  653.         // and the same javascript function could call "CompareNative()" to compare this molecule with the drawing  
  654.         // OR
  655.         // if <param name="file" value="http://whatever_wims_server/filename"> is set
  656.         feedback="";
  657.         if(i.indexOf("WIMSchem!")!=-1 && i.indexOf("!FIN")!=-1){
  658.             //Correct_answer=i.replaceAll(" ","");continu=true;
  659.             //System.out.println("found Native WIMSchem file :"+Correct_answer);
  660.             System.out.println("Native fileformat detected");
  661.                 Molecule elmol=new Molecule();
  662.                 try
  663.                 {
  664.                     elmol=MoleculeStream.ReadNative(new BufferedReader(new StringReader(i.toString())));
  665.                     System.out.println("Native stringfile converted to molecule");
  666.                 }
  667.                 catch (IOException e) {System.out.println("error"+e);continu=false;}
  668.                 // then convert molecule to Native string...
  669.                 try
  670.                 {
  671.                     Correct_answer=MoleculeStream.Molecule2String(elmol);
  672.                     continu=true;
  673.                 }
  674.                 catch (IOException e) {System.out.println("error"+e+"trouble with converting native molecule to string:"+i );continu=false;}
  675.         }
  676.         else
  677.         {
  678.             if( i.indexOf("molfile")!=-1){
  679.                 System.out.println("molfile detected");
  680.                 // first convert MDMOL to molecule
  681.                 Molecule mdmol=new Molecule();
  682.                 try
  683.                 {
  684.                     mdmol=MoleculeStream.ReadMDLMOL(new BufferedReader(new StringReader(i.toString())));
  685.                     System.out.println("MDMOL file converted to molecule");
  686.                 }
  687.                 catch (IOException e) {System.out.println("error"+e);continu=false;}
  688.                 // then convert molecule to Native string...
  689.                 try
  690.                 {
  691.                     Correct_answer=MoleculeStream.Molecule2String(mdmol);
  692.                     continu=true;
  693.                 }
  694.                 catch (IOException e) {System.out.println("error"+e+"trouble with converting molecule to string:"+i );continu=false;}
  695.             }
  696.             else
  697.             {
  698.                 if(Correct_answer.length() == 0){
  699.                     feedback=translation.getProperty("empy_string_question");continu=false;
  700.                 }
  701.                 else
  702.                 {
  703.                     feedback=translation.getProperty("invalid_question");continu=false;
  704.                 }
  705.             }
  706.         }
  707.     }
  708.    
  709.     public String ReadApplet(){
  710.         //jm.evers:
  711.         // return info of the shown molecule... e.g. using the applet as image viewer
  712.         // accet
  713.         try
  714.         {
  715.             StringWriter sw=new StringWriter();BufferedWriter bw=new BufferedWriter(sw);MoleculeStream.WriteNative(bw,mainPanel.MolData());
  716.             Correct_answer=sw.toString();Correct_answer=Correct_answer.replaceAll(" ","");
  717.             if(Correct_answer.indexOf("WIMSchem!")!=-1 || Correct_answer.indexOf("!FIN")!=-1){
  718.                 if(Correct_answer.length() < 22){// !WIMSchem(0,0) \n !FIN
  719.                     feedback=translation.getProperty("empty_answer");continu=false;
  720.                 }
  721.             }
  722.             else
  723.             {
  724.                 continu=false;feedback=translation.getProperty("no_sketchfile_answer");
  725.             }
  726.         }
  727.         catch (IOException e) {System.out.println("error"+e);continu=false;feedback=translation.getProperty("no_sketchfile_answer");}
  728.         AnalyseMolecule(Correct_answer,false);
  729.         html_smiles_ca=MoleculeStream.GetSmiles(mainPanel.MolData());
  730.         return  weight_ca+"\n"+plain_formula_ca+"\n"+html_formula_ca+"\n"+html_smiles_ca+"\n"+latex_formula_ca;
  731.     }
  732.    
  733.     public String CompareNative(){
  734.         // jm.evers:
  735.         // only usefull if called [javascript] together with GetQuestion(). See example in javascript !
  736.         System.out.println("entering function CompareNative()");
  737.         try
  738.         {
  739.             StringWriter sw=new StringWriter();BufferedWriter bw=new BufferedWriter(sw);
  740.             MoleculeStream.WriteNative(bw,mainPanel.MolData());
  741.             Student_answer=sw.toString();Student_answer=Student_answer.replaceAll(" ","");
  742.             System.out.println("Student answer is:"+Student_answer);
  743.            
  744.             if(Student_answer.indexOf("WIMSchem!")!=-1 || Student_answer.indexOf("!FIN")!=-1){
  745.                 if(Student_answer.length() < 22){// !WIMSchem(0,0) \n !FIN
  746.                     feedback=translation.getProperty("empty_answer");;
  747.                     continu=false;
  748.                 }
  749.             }
  750.             else
  751.             {
  752.                 continu=false;
  753.                 feedback=translation.getProperty("no_sketchfile_answer");
  754.             }
  755.         }
  756.         catch (IOException e) {System.out.println("error"+e);continu=false;feedback=translation.getProperty("no_sketchfile_answer");}
  757.  
  758.         if(continu){
  759.             feedback="";num_sa=0;num_ca=0;bond_sa=0;bond_ca=0;weight_sa=0.0;weight_ca=0.0;
  760.             AnalyseMolecule(Student_answer,true);
  761.             AnalyseMolecule(Correct_answer,false);
  762.             double score=getScore();
  763.             // a smiles representation -at least it could look like smiles ...
  764.             html_smiles_sa=MoleculeStream.GetSmiles(mainPanel.MolData());
  765.             try {
  766.                 html_smiles_ca=MoleculeStream.GetSmiles(MoleculeStream.ReadNative(new BufferedReader(new StringReader(Correct_answer))));
  767.             }
  768.             catch(IOException e) { System.out.println("error"+e);}
  769.             return score+"\n"+weight_sa+"\n"+weight_ca+"\n"+plain_formula_sa+"\n"+plain_formula_ca+"\n"+html_formula_sa+"\n"+html_formula_ca+"\n"+html_smiles_sa+"\n"+html_smiles_ca+"\n"+latex_formula_sa+"\n"+latex_formula_ca+"\n"+feedback+"\n@"+Student_answer+"\n@"+Correct_answer;
  770.         }
  771.         else
  772.         {
  773.             return "error\n"+feedback;
  774.         }
  775.     }
  776.    
  777.     public void AnalyseMolecule(String S , boolean whatisit){
  778.         // jm.evers
  779.         // whatisit=false : correct answer e.g. from javascript by wims.
  780.         // whatisit=true  : student drawing
  781.         // reading data , preparing representation formulas
  782.         if(whatisit){System.out.println("analysing student reply");}else{System.out.println("analysing correct answer");}
  783.         String[] s=S.split("\n");String[] atom;int s1=s[0].indexOf('(');int s2=s[0].indexOf(',');int s3=s[0].indexOf(')');
  784.         int n_s=Integer.parseInt(s[0].substring(s1+1,s2).trim());int b_s=Integer.parseInt(s[0].substring(s2+1,s3).trim());
  785.         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];
  786.         int[] this_A=new int[N];int[] this_C=new int[N];int[] this_R=new int[N];int[] this_H=new int[N];
  787.         String plainformula="";String htmlformula="";String latexformula="";
  788.         String R_plain="";String R_html="";String R_latex="";
  789.         String C_plain="";String C_html="";String C_latex="";
  790.         String sign;
  791.         double weight_s=0.0D;int r=0;
  792.        
  793.         // loop only through the atom part of the file-string
  794.         for( int p=0; p<n_s ;p++){
  795.             atom=s[p+1].split("[\\=\\,\\;]"); //first line is mimetype
  796.             E_s[p]=atom[0];r=0;
  797.             for(int n=0;n<N;n++){
  798.                 if(atom[0].equals(Molecule.ELEMENTS[n])){
  799.                     weight_s=(double)(weight_s + Molecule.WEIGHTS[n]);
  800.                     this_A[n]++;r=n;n=N;
  801.                 }
  802.             }
  803.             C_s[p]=Integer.parseInt(atom[3]);
  804.             this_C[r]=C_s[p];
  805.             R_s[p]=Integer.parseInt(atom[4]);
  806.             this_R[p]=R_s[p];
  807.             if( atom[5].indexOf("i")!=-1){
  808.                 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
  809.             }
  810.             else
  811.             {
  812.                 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
  813.             }      
  814.             weight_s=(double)(weight_s + H_s[p]);
  815.         }
  816.  
  817.         if(this_A[6]!=0){
  818.             if(this_R[6] != 0){R_plain="\u2022";R_latex="^{^{\\cdot}}";R_html="<sup>&cdot;</sup>";}
  819.             if(this_C[6] != 0){
  820.                 if(this_C[6]>0){sign="+";}else{sign="-";this_C[6]=(int) (Math.abs(this_C[6]));}
  821.                 C_plain=this_C[6]+sign;C_latex="^{"+this_C[6]+sign+"}";C_html="<sup><small>"+this_C[6]+sign+"</small></sup>";
  822.             }
  823.             if(this_A[6] == 1 ){// C1 is not done:  CH4
  824.                 plainformula="C"+C_plain+R_plain+" ";
  825.                 htmlformula="<font size=+1><tt>C"+C_html+R_html+"</tt></font>";
  826.                 latexformula="\\Bf{C"+C_latex+R_latex+"}";
  827.             }
  828.             else
  829.             {//C2H5OH
  830.                 plainformula="C"+C_plain+R_plain+this_A[6];
  831.                 htmlformula="<font size=+1><tt>C"+C_html+R_html+"</tt></font><sub><small>"+this_A[6]+"</small></sub>";
  832.                 latexformula="\\Bf{C"+C_latex+R_latex+"}_{"+this_A[6]+"}";
  833.             }
  834.         }
  835.         // the rest
  836.         for(int p = 0; p<N; p++){
  837.             if( p == 6 ){ p = 7;} // we already covered carbon
  838.             if( this_A[p] != 0 ){
  839.                 R_plain="";R_html="";R_latex="";C_plain="";C_html="";C_latex="";sign="";
  840.                 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>";}
  841.                 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>";}
  842.                 if( this_A[p] == 1 ){
  843.                     plainformula=plainformula+" "+Molecule.ELEMENTS[p]+""+C_plain+""+R_plain;
  844.                     htmlformula=htmlformula+" <font size=+1><tt>"+Molecule.ELEMENTS[p]+C_html+R_html+"</tt></font>";
  845.                     latexformula=latexformula+"\\,\\Bf{"+Molecule.ELEMENTS[p]+C_latex+R_latex+"}";
  846.                 }
  847.                 else
  848.                 {
  849.                     plainformula=plainformula+" "+Molecule.ELEMENTS[p]+""+C_plain+""+R_plain+""+this_A[p];
  850.                     htmlformula=htmlformula+" <font size=+1><tt>"+Molecule.ELEMENTS[p]+C_html+R_html+"</tt></font><sub><small>"+this_A[p]+"</small></sub>";
  851.                     latexformula=latexformula+"\\,\\Bf{"+Molecule.ELEMENTS[p]+C_latex+R_latex+"}_{"+this_A[p]+"}";
  852.                 }
  853.             }
  854.         }
  855.        
  856.         if(whatisit){// these are used for getting a score
  857.             elements_sa=E_s;hydro_sa=H_s;charge_sa=C_s;radical_sa=R_s;weight_sa=weight_s;
  858.             plain_formula_sa=plainformula;html_formula_sa=htmlformula;latex_formula_sa=latexformula;num_sa=n_s;bond_sa=b_s;
  859.         }
  860.         else
  861.         {
  862.             elements_ca=E_s;hydro_ca=H_s;charge_ca=C_s;radical_ca=R_s;weight_ca=weight_s;
  863.             plain_formula_ca=plainformula;html_formula_ca=htmlformula;latex_formula_ca=latexformula;num_ca=n_s;bond_ca=b_s;
  864.         }
  865.     }// end AnalyseMolecule()
  866.  
  867.     public double getScore(){
  868.         System.out.println("entering function getScore()");
  869.         // jm.evers:
  870.         // comparing the molecules studentanswer [sa] and correct answer [ca]
  871.         // giving somekind of score: ofcourse any "score < 10" is technically plain wrong !!
  872.         // feedback is not yet operational...because it gives disturbing messages :(
  873.         int hit=0;String tmp_remark="";
  874.         boolean[] done=new boolean[num_sa];
  875.         double finalscore=0.0D;
  876.         for(int p=0;p<num_sa;p++){
  877.             done[p]=true;
  878.         }
  879.         if( num_ca == num_sa  && bond_ca == bond_sa ){
  880.             for( int c=0; c < num_ca ; c++){
  881.                 for( int s=0; s < num_sa ;s++){
  882.                     if(done[s]){
  883.                         if( elements_ca[c].equals(elements_sa[s]) && charge_ca[c] == charge_sa[s] && radical_ca[c] == radical_sa[s] && hydro_ca[c] == hydro_sa[s]){
  884.                             done[s]=false;
  885.                             hit++;s=num_sa;break;
  886.                         }
  887.                         else
  888.                         {
  889.                             if( elements_ca[c].equals(elements_sa[s]) ){
  890.                                 if( charge_ca[c] != charge_sa[s] ){ tmp_remark="wrong_charge "+elements_ca[c]+"="+charge_ca[c]+",";}
  891.                                 if( radical_ca[c] != radical_sa[s] ){ tmp_remark="wrong_radical "+elements_ca[c]+"="+radical_ca[c]+",";}
  892.                                 if( hydro_ca[c] != hydro_sa[s] ){ tmp_remark="wrong_amount_hydrogen "+elements_ca[c]+"="+hydro_ca[c]+","; }
  893.                             }
  894.                         }
  895.                     }
  896.                 }
  897.             }
  898.         }      
  899.         feedback=feedback+tmp_remark;
  900.         if(num_ca > num_sa){
  901.             finalscore=(double)(10*hit/num_ca);
  902.         }
  903.         else
  904.         {
  905.             finalscore=(double)(10*hit/num_sa);
  906.         }
  907.         System.out.println("finalscore="+finalscore);
  908.         return finalscore;
  909.     }
  910.  
  911.     public void componentHidden(ComponentEvent e){}
  912.     public void componentMoved(ComponentEvent e){}
  913.     public void componentResized(ComponentEvent e){}
  914.     public void componentShown(ComponentEvent e){
  915.     mainPanel.ScaleToFit();
  916.     mainPanel.repaint();
  917.     }
  918.  
  919. }
  920.  
  921.  
  922.