/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOUSE. See the GNU
 * General Public License for more details.
 *
 * You should have recieved a copy of the GNU General Public License
 * along with this program; if not write to the Free Software
 * Foundation, inc., 59 Temple Place, Suite 330, Boston MA 02111-1307
 * USA
 */

package gui;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import run.*;
import uka.karmi.rmi.RemoteException;

import java.util.*;
import j3d.*;
import javax.swing.table.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import jp.lang.DistributedRuntime;
import jp.sync.Barrier;
import jp.sync.BarrierFactory;
/**
 * Insert the type's description here.
 *
 * @author: Yuriy Mikhaylovskiy
 */

public class Processor extends JPanel {
  public static final String ver = "Processor (2005.03.17)";
  public Hashtable db_node = new Hashtable();
  public Hashtable db_node_constraints = new Hashtable();
  public Hashtable db_constraints = new Hashtable();
  public Hashtable db_node_loads = new Hashtable();
  public Hashtable db_loads = new Hashtable();
  public Hashtable db_element = new Hashtable();
  public Hashtable db_element_loads = new Hashtable();
  public String path = "";
  JDialog dialog;
  ImageIcon img_open = new ImageIcon(Processor.class.getResource("open.gif"));
  ImageIcon img_import = new ImageIcon(Processor.class.getResource("import.gif"));
  ImageIcon img_save = new ImageIcon(Processor.class.getResource("save.gif"));
  ImageIcon img_run = new ImageIcon(Processor.class.getResource("run.gif"));
  ImageIcon img_stop = new ImageIcon(Processor.class.getResource("stop.gif"));
  ImageIcon img_find = new ImageIcon(Processor.class.getResource("find.gif"));
  ImageIcon img_solid = new ImageIcon(Processor.class.getResource("solid.gif"));
  //ImageIcon img_zooma = new ImageIcon(Processor.class.getResource("zooma.gif"));
  ImageIcon img_zoomin = new ImageIcon(Processor.class.getResource("zoomin.gif"));
  ImageIcon img_zoomout = new ImageIcon(Processor.class.getResource("zoomout.gif"));
  ImageIcon img_view_top = new ImageIcon(Processor.class.getResource("view_top.gif"));
  ImageIcon img_view_bottom = new ImageIcon(Processor.class.getResource("view_bottom.gif"));
  ImageIcon img_view_left = new ImageIcon(Processor.class.getResource("view_left.gif"));
  ImageIcon img_view_right = new ImageIcon(Processor.class.getResource("view_right.gif"));
  ImageIcon img_view_front = new ImageIcon(Processor.class.getResource("view_front.gif"));
  ImageIcon img_view_back = new ImageIcon(Processor.class.getResource("view_back.gif"));
  ImageIcon img_view_sw = new ImageIcon(Processor.class.getResource("view_sw.gif"));
  ImageIcon img_view_se = new ImageIcon(Processor.class.getResource("view_se.gif"));
  ImageIcon img_view_ne = new ImageIcon(Processor.class.getResource("view_ne.gif"));
  ImageIcon img_view_nw = new ImageIcon(Processor.class.getResource("view_nw.gif"));
  ImageIcon img_config = new ImageIcon(Processor.class.getResource("config.gif"));
  Thread tsolve;
  boolean isSolve = false;
  JCheckBox cb_node = new JCheckBox("Nodes label",true);
  JCheckBox cb_element = new JCheckBox("Elements label",true);
  JCheckBox cb_constraints = new JCheckBox("Constraints",true);
  JCheckBox cb_loads = new JCheckBox("Loads",true);
  JCheckBox cb_trackers = new JCheckBox("Trackers",true);
  JCheckBox cb_materials = new JCheckBox("Materials",true);
  Object[][] table_materials = new Object[0][4];
  String[] table_hdr_materials = {"Show","Color","Material"};
  private TableModel tableModel = new AbstractTableModel() {
    public int getColumnCount() { return 3; }
    public int getRowCount() { return table_materials.length; }
    public Object getValueAt(int row, int col){ return table_materials[row][col]+"";}
    public String getColumnName(int col) {return table_hdr_materials[col];}
    public boolean isCellEditable(int row, int col) {return false;}
  };
  BorderLayout borderLayout1 = new BorderLayout();
  JSplitPane jSplitPane1 = new JSplitPane();
  JTextArea result = new JTextArea();
  JScrollPane jScrollPane1 = new JScrollPane();
  JPanel jPanel3 = new JPanel();
  BorderLayout borderLayout3 = new BorderLayout();
  JSplitPane jSplitPane2 = new JSplitPane();
  JPanel jPanel4 = new JPanel();
  JPanel jPanel5 = new JPanel();
  JScrollPane jScrollPane2 = new JScrollPane();
  JTextArea problem = new JTextArea();
  BorderLayout borderLayout4 = new BorderLayout();
  BorderLayout borderLayout5 = new BorderLayout();
  JToolBar jToolBar1 = new JToolBar();
//  JButton b_zooma = new JButton();
  JButton b_zoomin = new JButton();
  JButton b_zoomout = new JButton();
  Canvas3D J3D = new Canvas3D(null);
  JButton b_viewbottom = new JButton();
  JButton b_viewright = new JButton();
  JButton b_viewfront = new JButton();
  JButton b_viewleft = new JButton();
  JButton b_viewtop = new JButton();
  JButton b_viewback = new JButton();
  JButton b_viewsw = new JButton();
  JButton b_viewse = new JButton();
  JButton b_viewne = new JButton();
  JButton b_viewnw = new JButton();
  JToolBar jToolBar2 = new JToolBar();
  JButton b_open = new JButton();
  JButton b_model = new JButton();
  JButton b_start = new JButton();
  JButton b_config = new JButton();
  JButton b_save = new JButton();
  JButton b_find = new JButton();
  JButton b_import = new JButton();
  JSlider js = new JSlider(JSlider.HORIZONTAL,1,8,1);

  public Processor() {
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }
  private void jbInit() throws Exception {
    J3D.RENDERMODE=J3D.RENDERMODE_HIDE;
    this.setLayout(borderLayout1);
    jSplitPane1.setOrientation(JSplitPane.VERTICAL_SPLIT);
    jSplitPane1.setLastDividerLocation(0);
    jSplitPane1.setOneTouchExpandable(true);
    result.setEditable(false);
    jPanel3.setLayout(borderLayout3);
    jPanel4.setLayout(borderLayout4);
    jPanel5.setLayout(borderLayout5);
    jToolBar1.setFloatable(false);
//    b_zooma.setIcon(img_zooma);
//    b_zooma.addActionListener(new java.awt.event.ActionListener() {
//      public void actionPerformed(ActionEvent e) {
//        b_zooma_actionPerformed(e);
//      }
//    });
    b_zoomin.setToolTipText("Zoom in");
    b_zoomin.setIcon(img_zoomin);
    b_zoomin.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_zoomin_actionPerformed(e);
      }
    });
    b_zoomout.setToolTipText("Zoom out");
    b_zoomout.setIcon(img_zoomout);
    b_zoomout.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_zoomout_actionPerformed(e);
      }
    });
    b_viewtop.setToolTipText("Top View");
    b_viewtop.setIcon(img_view_top);
    b_viewtop.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_viewtop_actionPerformed(e);
      }
    });
    b_viewbottom.setToolTipText("Bottom View");
    b_viewbottom.setIcon(img_view_bottom);
    b_viewbottom.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_viewbottom_actionPerformed(e);
      }
    });
    b_viewleft.setToolTipText("Left View");
    b_viewleft.setIcon(img_view_left);
    b_viewleft.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_viewleft_actionPerformed(e);
      }
    });
    b_viewright.setToolTipText("Right View");
    b_viewright.setIcon(img_view_right);
    b_viewright.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_viewright_actionPerformed(e);
      }
    });
    b_viewfront.setToolTipText("Front View");
    b_viewfront.setIcon(img_view_front);
    b_viewfront.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_viewfront_actionPerformed(e);
      }
    });
    b_viewback.setToolTipText("Back View");
    b_viewback.setIcon(img_view_back);
    b_viewback.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_viewback_actionPerformed(e);
      }
    });
    b_viewsw.setToolTipText("SW Isometric View");
    b_viewsw.setIcon(img_view_sw);
    b_viewsw.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_viewsw_actionPerformed(e);
      }
    });
    b_viewse.setToolTipText("SE Isometric View");
    b_viewse.setIcon(img_view_se);
    b_viewse.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_viewse_actionPerformed(e);
      }
    });
    b_viewne.setToolTipText("NE Isometric View");
    b_viewne.setIcon(img_view_ne);
    b_viewne.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_viewne_actionPerformed(e);
      }
    });
    b_viewnw.setToolTipText("NW Isometric View");
    b_viewnw.setIcon(img_view_nw);
    b_viewnw.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_viewnw_actionPerformed(e);
      }
    });
    jSplitPane2.setOneTouchExpandable(true);
    b_open.setToolTipText("Open model *.in");
    b_open.setIcon(img_open);
    b_open.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_open_actionPerformed(e);
      }
    });
    b_start.setToolTipText("Start / Stop");
    b_start.setIcon(img_run);
    b_start.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_start_actionPerformed(e);
      }
    });
    b_model.setToolTipText("Reload view");
    b_model.setIcon(img_solid);
    b_model.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_model_actionPerformed(e);
      }
    });
    jToolBar2.setFloatable(false);
    b_config.setToolTipText("Configure");
    b_config.setIcon(img_config);
    b_config.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_config_actionPerformed(e);
      }
    });
    b_save.setToolTipText("Save");
    b_save.setIcon(img_save);
    b_save.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_save_actionPerformed(e);
      }
    });
    b_find.setIcon(img_find);
    b_find.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_find_actionPerformed(e);
      }
    });
    b_import.setToolTipText("Import model (NASTRAN, GMSH)");
    b_import.setIcon(img_import);
    b_import.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_import_actionPerformed(e);
      }
    });
    js.setMajorTickSpacing(1);
    js.setMinorTickSpacing(1);
    js.setPaintTicks(true);
    js.setPaintLabels(true);
    js.setSnapToTicks(true);
    js.addChangeListener(new ChangeListener() {
      public void stateChanged(ChangeEvent arg0) {
        js_stateChanged(arg0);
      }
    });
    this.add(jSplitPane1, BorderLayout.CENTER);
    jSplitPane1.add(jScrollPane1, JSplitPane.LEFT);
    jSplitPane1.add(jPanel3, JSplitPane.RIGHT);
    jPanel3.add(jSplitPane2, BorderLayout.CENTER);
    jSplitPane2.add(jPanel4, JSplitPane.LEFT);
    jPanel4.add(jScrollPane2, BorderLayout.CENTER);
    jPanel4.add(jToolBar2, BorderLayout.NORTH);
    jToolBar2.add(b_open, null);
    jToolBar2.add(b_import, null);
    jToolBar2.add(b_save, null);
    jToolBar2.addSeparator();
    jToolBar2.add(b_start, null);
    jToolBar2.addSeparator();
    jToolBar2.add(b_find, null);
    jToolBar2.add(b_model, null);
    jToolBar2.addSeparator();
    jToolBar2.add(js);
    jScrollPane2.getViewport().add(problem);
    jSplitPane2.add(jPanel5, JSplitPane.RIGHT);
    jPanel5.add(jToolBar1, BorderLayout.NORTH);
//    jToolBar1.add(b_zooma, null);
    jToolBar1.add(b_zoomin, null);
    jToolBar1.add(b_zoomout, null);
    jToolBar1.addSeparator();
    jToolBar1.add(b_viewtop, null);
    jToolBar1.add(b_viewbottom, null);
    jToolBar1.add(b_viewleft, null);
    jToolBar1.add(b_viewright, null);
    jToolBar1.add(b_viewfront, null);
    jToolBar1.add(b_viewback, null);
    jToolBar1.add(b_viewsw, null);
    jToolBar1.add(b_viewse, null);
    jToolBar1.add(b_viewne, null);
    jToolBar1.add(b_viewnw, null);
    jToolBar1.addSeparator();
    jToolBar1.add(b_config, null);
    jPanel5.add(J3D, BorderLayout.CENTER);
    jScrollPane1.getViewport().add(result);
    jSplitPane1.setDividerLocation(100);
    jSplitPane2.setDividerLocation(400);
  }

  void b_open_actionPerformed(ActionEvent e) {
    try {
      FileDialog fd = new FileDialog(getFrame(this),"Open model",FileDialog.LOAD);
      fd.setDirectory(".");
      fd.setFile("*.in");
      fd.show();
      path=fd.getDirectory()+fd.getFile();
      if(fd.getFile()!=null){
        RandomAccessFile in = new RandomAccessFile(path, "r");
        problem.setText("");
        String st;
        while((st=in.readLine())!=null) problem.append(st+"\n");
        in.close();
        result.setText("Selected problem - "+path);
        show_model();
      }
    } catch(Exception e1) {error(e1);}
  }
  void b_import_actionPerformed(ActionEvent e) {
    try {
      FileDialog fd = new FileDialog(getFrame(this),"Import model",FileDialog.LOAD);
      fd.setDirectory(".");
      fd.show();
      if(fd.getFile()!=null){
        path=fd.getDirectory()+(fd.getFile().substring(0,fd.getFile().lastIndexOf(".")))+".in";
        Translator translatorinstance = new Translator();
        translatorinstance.initialize(fd.getDirectory()+fd.getFile(), path);
        translatorinstance.post();
        RandomAccessFile in = new RandomAccessFile(path, "r");
        problem.setText("");
        String st;
        while((st=in.readLine())!=null) problem.append(st+"\n");
        in.close();
        result.setText("Selected problem - "+path);
        show_model();
      }
    } catch(Exception e1) {error(e1);}
  }

  public void error(Object st){
    JOptionPane.showMessageDialog(this,"Error: "+st,"Error!",JOptionPane.ERROR_MESSAGE);
    if(st instanceof Exception) ((Exception)st).printStackTrace(); else System.out.println("Error: "+st);
  }
  public static Frame getFrame(Component component){
    for(; component != null && !(component instanceof Frame); component = component.getParent());
    return (Frame)component;
  }

  void b_start_actionPerformed(ActionEvent e) {
    try{
      if(isSolve){
        tsolve.interrupt();
        tsolve=null;
        isSolve=false;
        b_start.setIcon(img_run);
        b_open.setEnabled(true);
        b_import.setEnabled(true);
        js.setEnabled(true);
        result.append("\n*** Interrupted Solver ***");
        result.setCaretPosition(result.getText().length());
      }else{
        File f = new File(path);
        f.delete();
        RandomAccessFile o = new RandomAccessFile(path, "rw");
        o.writeBytes(problem.getText());
        o.close();
        System.setOut(new PrintStream(System.out){
          public void println(String x){
            super.println(x);
            result.append(x+"\n");
            result.setCaretPosition(result.getText().length());
          }
        });
        System.setErr(new PrintStream(System.err){
          public void println(Object x){
            super.println(x);
            result.append(x+"\n");
            isSolve=false;
            b_start.setIcon(img_run);
            b_open.setEnabled(true);
            b_import.setEnabled(true);
            js.setEnabled(true);
            result.append("\n*** Interrupted Solver ***");
            result.setCaretPosition(result.getText().length());
          }
        });
        tsolve = new Thread(){
          public void run() {
            result.setText("");
            int nr_CPU = DistributedRuntime.getMachineCnt();
			if (nr_CPU > 0){
			    Thread[] workers;
			    final ModelCluster[] nodes;
			    // Run a cluster version since clusters are present
				try {
					System.out.println("********************************");
					System.out.println("*** Cluster has been invoked ***");
					System.out.println("********************************\n\n");
					System.out.println("Running on " + nr_CPU + " clients\n\n");

			        nodes = new ModelCluster[nr_CPU];

			        System.out.println("*** Creating cluster processes ***");

			        for (int n = 0; n < nr_CPU; n++) {
			            /**
			             * @at n
			             */
			            nodes[n] = new ModelCluster(nr_CPU,n);
			        }

			        final Barrier barrier = BarrierFactory.createBarrier(nodes.length);
			        final String filename = path;
			        
			        // Create threads
			        workers = new Thread[nr_CPU];

			        for (int n = 0; n < workers.length; n++) {
			            final ModelCluster node = nodes[n];
			            workers[n] = new Thread(
			                    new Runnable() {
			                        public void run() {
			                            try {
			                            	node.initialize(path, nodes);
			                            	node.assembleMassMatrix();
			                            	node.setInitialConditions();
			                            	barrier.sync();
			                            	node.passReferences();
			                            	barrier.sync();
			                            	node.determineDistribution();
			                            	node.referenceNodes();
			                            	barrier.sync();
			                            	node.optimize();
			                            	node.solve(barrier);
			                            } catch (Exception e) {
			                                System.out.println("Hej");
			                                e.printStackTrace();
			                                return;
			                            } 
			                        }
			                    }
			                );
			        }

			        System.out.println("*** Starting the solution ***");
			        System.out.println("See terminal window for printout");

			        // start worker threads
			        for (int n = 0; n < workers.length; n++) {
			            workers[n].start();
			        }

					long stime = System.currentTimeMillis();

					// wait for worker threads to terminate
			        for (int n = 0; n < workers.length; n++) {
			            try {
							workers[n].join();
						} catch (InterruptedException e) {
						    
						    System.out.println("Shutting down clients");

  						    for (int m = 0; m < workers.length; m++)
  						        nodes[m].setTerminate(true);
						    
						}
			        }
			        
					System.out.println("Solving took "
							+ (System.currentTimeMillis() - stime) + " ms");
					
				} catch (Error e) {
					e.printStackTrace();
					return;
				}  
			}
				else {
					// A standard smp version is run -> make nr_CPU positive
					nr_CPU = js.getValue();
					try {
					    
					    System.out.println("*******************************");
					    System.out.println("*** Solver has been invoked ***");
					    System.out.println("*******************************\n\n");
					    System.out.println("Running on " + nr_CPU + " clients\n\n");
					    
					    // Create an instance of the solver (no preprocess)
					    ModelSmp siminstance = new ModelSmp(nr_CPU);
					    
					    System.out.println("Processing file: " + path);
					    System.out.println("*** Initializing ***");
					    siminstance.initialize(path);
					    
					    // Assemble the mass matrix
					    System.out.println("*** Assembling the Mass Matrix ***");
					    siminstance.assembleMassMatrix();
					    
					    // Set up the prerequisites
					    System.out.println("*** Setting Initial Conditions ***");
					    siminstance.setInitialConditions();
					    
					    // Solve the problem 
					    long stime = System.currentTimeMillis();
					    System.out.println("*** Initiating Solver ***");
					    
					    try {
                            siminstance.solve();
                        } catch (InterruptedException e1) {
                            // Just terminate
                        }
                        
					    System.out.println("Solving took "
					            + (System.currentTimeMillis() - stime) + " ms");
					    
					    // Post the results and clean up
					    siminstance.post();
					    
					} catch (Error e) {
					    System.out.println(e);
					    return;
					} catch (RemoteException e) {
					    e.printStackTrace();
					}
				}
			
			isSolve=false;
            b_start.setIcon(img_run);
            b_open.setEnabled(true);
            b_import.setEnabled(true);
            js.setEnabled(true);
            result.append("*** End ***");
            result.setCaretPosition(result.getText().length());
          }
          
        };
        tsolve.setPriority(tsolve.MIN_PRIORITY);
        tsolve.start();
        isSolve=true;
        b_start.setIcon(img_stop);
        b_open.setEnabled(false);
        b_import.setEnabled(false);
        js.setEnabled(false);
      }
    } catch(IOException e1) {
       error(e1); 
        e1.printStackTrace();
        result.append("\n\n"+e1);
    } 
  }

  public void show_model() {
    J3D.remove_all();
    db_node.clear();
    db_element.clear();
    db_constraints.clear();
    db_node_constraints.clear();
    db_loads.clear();
    db_node_loads.clear();
    db_element_loads.clear();
    StringTokenizer stt = new StringTokenizer(problem.getText().replaceAll("\t"," "),"\n");
    String st;
    while (stt.hasMoreTokens()) {
      st = stt.nextToken().trim().toUpperCase();
      if(st.equals("NODES")){
        try{
          while (stt.hasMoreTokens()) {
            st = stt.nextToken().trim().toUpperCase();
            if(st.startsWith("#") || st.length()==0)continue;
            StringTokenizer stt1 = new StringTokenizer(st," =XYZ\t");
            String key = stt1.nextToken();
            db_node.put(key,new _Point(Float.parseFloat(stt1.nextToken()),Float.parseFloat(stt1.nextToken()),Float.parseFloat(stt1.nextToken())));
            if(st.indexOf("CONSTRAINT =")!=-1){
              String st1 = st.substring(st.indexOf("CONSTRAINT")+10);
              stt1 = new StringTokenizer(st1," \t");
              stt1.nextToken();
              db_node_constraints.put(key,stt1.nextToken());
            }
            if(st.indexOf("LOAD =")!=-1){
              String st1 = st.substring(st.indexOf("LOAD")+4);
              stt1 = new StringTokenizer(st1," \t");
              stt1.nextToken();
              db_node_loads.put(key,stt1.nextToken());
            }
          }
        }catch(Exception e1){}
      }
    }
    stt = new StringTokenizer(problem.getText(),"\n");
    while (stt.hasMoreTokens()) {
      st = stt.nextToken().trim().toUpperCase();
      if(st.startsWith("ELEMENTS")){
        try{
          while (stt.hasMoreTokens()) {
            st = stt.nextToken().trim().toUpperCase();
            if(st.startsWith("#") || st.length()==0 || st.startsWith("ELEMENTS"))continue;
            StringTokenizer stt1 = new StringTokenizer(st,"[]");
            String key = stt1.nextToken();
            key = new StringTokenizer(key," \t").nextToken();
            String st_nd = stt1.nextToken();
            String st_load = stt1.nextToken();
            StringTokenizer stt2 = new StringTokenizer(st_nd,", \t");
            int[] arr = new int[stt2.countTokens()];
            int i=0;
            while (stt2.hasMoreTokens()){
              arr[i]=Integer.parseInt(stt2.nextToken());
              i++;
            }
            db_element.put(key,arr);
            if(st_load.toUpperCase().indexOf("LOAD")!=-1){
              st_load=st_load.substring(st_load.toUpperCase().indexOf("LOAD"));
              StringTokenizer stt3 = new StringTokenizer(st_load,"= \t");
              stt3.nextToken();
              db_element_loads.put(key,stt3.nextToken());
              //System.out.println(st_load);
            }
          }
        }catch(Exception e1){}
      }
    }
//System.out.println(db_element.size());
    stt = new StringTokenizer(problem.getText(),"\n");
    while (stt.hasMoreTokens()) {
      st = stt.nextToken().trim().toUpperCase();
      if(st.toUpperCase().indexOf("BOUNDARY_CONDITION")!=-1 || st.toUpperCase().indexOf("RIGID_BODY")!=-1){
        try{
          while (stt.hasMoreTokens()) {
            st = stt.nextToken().trim().toUpperCase();
            if(st.startsWith("#") || st.length()==0)continue;
            if(st.startsWith("NODES") || st.startsWith("ELEMENTS") || st.startsWith("CONTROLS") || st.startsWith("TRACKERS") || st.startsWith("MATERIALS")  || st.startsWith("LOADS"))break;
            StringTokenizer stt1 = new StringTokenizer(st," \t");
            String key = stt1.nextToken();
            //db_constraints.put(key,st);
            db_constraints.put(key,key);
          }
        }catch(Exception e1){}
      }
    }
    stt = new StringTokenizer(problem.getText(),"\n");
    while (stt.hasMoreTokens()) {
      st = stt.nextToken().trim().toUpperCase();
      if(st.toUpperCase().indexOf("LOADS")!=-1){
        try{
          while (stt.hasMoreTokens()) {
            st = stt.nextToken().trim().toUpperCase();
            if(st.startsWith("#") || st.length()==0)continue;
            if(st.startsWith("NODES") || st.startsWith("ELEMENTS") || st.startsWith("CONTROLS") || st.startsWith("TRACKERS") || st.startsWith("MATERIALS")  || st.indexOf("BOUNDARY_CONDITION")!=-1 || st.indexOf("RIGID_BODY")!=-1)break;
            StringTokenizer stt1 = new StringTokenizer(st," \t");
            String key = stt1.nextToken();
            //db_loads.put(key,st);
            db_loads.put(key,key);
          }
        }catch(Exception e1){}
      }
    }

    for(Enumeration en = db_node.keys(); en.hasMoreElements();) {
      String key = en.nextElement()+"";
      _Point p = (_Point)db_node.get(key);
      if(cb_node.isSelected())J3D.add3D(new _OrientedText(key,p.x,p.y,p.z));
      J3D.add3D(p);
    }

    if(cb_constraints.isSelected()) for(Enumeration en = db_node_constraints.keys(); en.hasMoreElements() ;) {
      String key = en.nextElement()+"";
      String text = db_constraints.get((db_node_constraints.get(key)+"").toUpperCase())+"";
      _Point p = (_Point)db_node.get(key);
      J3D.add3D(new _OrientedText(text,p.x,p.y,p.z,Color.blue));
    }
    if(cb_loads.isSelected()){
      for(Enumeration en = db_node_loads.keys(); en.hasMoreElements() ;) {
        String key = en.nextElement()+"";
        String text = db_loads.get((db_node_loads.get(key)+"").toUpperCase())+"";
        _Point p = (_Point)db_node.get(key);
        J3D.add3D(new _OrientedText(text,p.x,p.y,p.z,Color.red));
      }
      for(Enumeration en = db_element_loads.keys(); en.hasMoreElements() ;) {
        String key = ""+en.nextElement();
        int[] arr = (int[])db_element.get(key);
        String val = db_element_loads.get(key)+"";
        if(arr.length==3){
          _Point p1 = (_Point)db_node.get(arr[0]+"");
          _Point p2 = (_Point)db_node.get(arr[1]+"");
          _Point p3 = (_Point)db_node.get(arr[2]+"");
          J3D.add3D(new _Triangle(p1,p2,p3));
          if(cb_element.isSelected())J3D.add3D(new _OrientedText(val,(p1.x+p2.x+p3.x)/3,(p1.y+p2.y+p3.y)/3,(p1.z+p2.z+p3.z)/3,Color.red));
        }else if(arr.length==4){
          _Point p1 = (_Point)db_node.get(arr[0]+"");
          _Point p2 = (_Point)db_node.get(arr[1]+"");
          _Point p3 = (_Point)db_node.get(arr[2]+"");
          _Point p4 = (_Point)db_node.get(arr[3]+"");
          J3D.add3D(new _Quad(p1,p2,p3,p4));
          if(cb_element.isSelected())J3D.add3D(new _OrientedText(val,(p1.x+p2.x+p3.x+p4.x)/4,(p1.y+p2.y+p3.y+p4.y)/4,(p1.z+p2.z+p3.z+p4.z)/4,Color.red));
        }
      }
      //////////////////
    }

    for(Enumeration en = db_element.keys(); en.hasMoreElements() ;) {
      String key = ""+en.nextElement();
      int[] arr = (int[])db_element.get(key);
      if(arr.length==2){
        _Point p1 = (_Point)db_node.get(arr[0]+"");
        _Point p2 = (_Point)db_node.get(arr[1]+"");
        J3D.add3D(new _Line(p1,p2));
        if(cb_element.isSelected())J3D.add3D(new _OrientedText(key,(p1.x+p2.x)/2,(p1.y+p2.y)/2,(p1.z+p2.z)/2,Color.green));
      }else if(arr.length==3){
        _Point p1 = (_Point)db_node.get(arr[0]+"");
        _Point p2 = (_Point)db_node.get(arr[1]+"");
        _Point p3 = (_Point)db_node.get(arr[2]+"");
        J3D.add3D(new _Triangle(p1,p2,p3));
        if(cb_element.isSelected())J3D.add3D(new _OrientedText(key,(p1.x+p2.x+p3.x)/3,(p1.y+p2.y+p3.y)/3,(p1.z+p2.z+p3.z)/3,Color.green));
      }else if(arr.length==4){
        _Point p1 = (_Point)db_node.get(arr[0]+"");
        _Point p2 = (_Point)db_node.get(arr[1]+"");
        _Point p3 = (_Point)db_node.get(arr[2]+"");
        _Point p4 = (_Point)db_node.get(arr[3]+"");
        J3D.add3D(new _Quad(p1,p2,p3,p4));
        if(cb_element.isSelected())J3D.add3D(new _OrientedText(key,(p1.x+p2.x+p3.x+p4.x)/4,(p1.y+p2.y+p3.y+p4.y)/4,(p1.z+p2.z+p3.z+p4.z)/4,Color.green));
      }else if(arr.length==8){
        _Point p1 = (_Point)db_node.get(arr[0]+"");
        _Point p2 = (_Point)db_node.get(arr[1]+"");
        _Point p3 = (_Point)db_node.get(arr[2]+"");
        _Point p4 = (_Point)db_node.get(arr[3]+"");
        _Point p5 = (_Point)db_node.get(arr[4]+"");
        _Point p6 = (_Point)db_node.get(arr[5]+"");
        _Point p7 = (_Point)db_node.get(arr[6]+"");
        _Point p8 = (_Point)db_node.get(arr[7]+"");
        J3D.add3D(new _Quad(p1,p2,p3,p4));
        J3D.add3D(new _Quad(p5,p6,p7,p8));
        J3D.add3D(new _Quad(p1,p2,p6,p5));
        J3D.add3D(new _Quad(p2,p3,p7,p6));
        J3D.add3D(new _Quad(p3,p4,p8,p7));
        J3D.add3D(new _Quad(p1,p4,p8,p5));
        if(cb_element.isSelected())J3D.add3D(new _OrientedText(key,(p1.x+p2.x+p3.x+p4.x+p5.x+p6.x+p7.x+p8.x)/8,(p1.y+p2.y+p3.y+p4.y+p5.y+p6.y+p7.y+p8.y)/8,(p1.z+p2.z+p3.z+p4.z+p5.z+p6.z+p7.z+p8.z)/8,Color.green));
      }
    }
  }

  void b_zooma_actionPerformed(ActionEvent e) {
    J3D.view_all();
  }

  void b_zoomin_actionPerformed(ActionEvent e) {
    J3D.view_scale(1.2f);
  }

  void b_zoomout_actionPerformed(ActionEvent e) {
    J3D.view_scale(0.8f);
  }

  void b_viewtop_actionPerformed(ActionEvent e) {
    J3D.view_top();
  }

  void b_viewbottom_actionPerformed(ActionEvent e) {
    J3D.view_bottom();
  }

  void b_viewleft_actionPerformed(ActionEvent e) {
    J3D.view_left();
  }

  void b_viewright_actionPerformed(ActionEvent e) {
    J3D.view_right();
  }

  void b_viewfront_actionPerformed(ActionEvent e) {
    J3D.view_front();
  }

  void b_viewback_actionPerformed(ActionEvent e) {
    J3D.view_back();
  }

  void b_viewsw_actionPerformed(ActionEvent e) {
    J3D.view_sw();
  }

  void b_viewse_actionPerformed(ActionEvent e) {
    J3D.view_se();
  }

  void b_viewne_actionPerformed(ActionEvent e) {
    J3D.view_ne();
  }

  void b_viewnw_actionPerformed(ActionEvent e) {
    J3D.view_nw();
  }

  void b_model_actionPerformed(ActionEvent e) {
    show_model();
  }

  void b_config_actionPerformed(ActionEvent e) {
    JPanel p = new JPanel(new VerticalFlowLayout());
    p.add(cb_node);
    p.add(cb_element);
    p.add(cb_constraints);
    p.add(cb_loads);
    p.add(cb_trackers);
    p.add(cb_materials);
    JOptionPane.showMessageDialog(this,p,"Show",JOptionPane.PLAIN_MESSAGE,null);
    show_model();
  }

  void b_save_actionPerformed(ActionEvent e) {
    try {
      FileDialog fd = new FileDialog(getFrame(this),"Save model as",FileDialog.SAVE);
      fd.setDirectory(".");
      fd.setFile("*.in");
      fd.show();
      String st = fd.getDirectory()+fd.getFile();
      if(fd.getFile()!=null){
        if(!st.endsWith(".in"))st+=".in";
        File f = new File(st);
        f.delete();
        RandomAccessFile o = new RandomAccessFile(st, "rw");
        o.writeBytes(problem.getText());
        o.close();
        result.append("\nSaved problem as - "+st+"\n");
        path=st;
      }
    } catch(Exception e1) {error(e1);}
  }

  void b_find_actionPerformed(ActionEvent e) {
    if(dialog==null)dialog = new JDialog(getFrame(this));
    dialog.setTitle("Find/Replace");
    dialog.getContentPane().removeAll();
    dialog.getContentPane().add(new Processor_Find(problem));
    dialog.pack();
    dialog.setVisible(true);
  }

  void js_stateChanged(ChangeEvent arg) {
    result.setText("Number of CPU:s set to:" + js.getValue());
  }
  public void exit(){
    System.out.println("Processor finalize.");
  }

}