/*
 * 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 j3d.*;
import java.awt.event.*;

import javax.swing.event.*;
import javax.swing.tree.*;
import java.util.*;
import javax.swing.table.*;
import java.io.*;
/**
 * Insert the type's description here.
 *
 * @author: Yuriy Mikhaylovskiy
 */

public class PreProcessor extends JPanel {
  public static final String ver = "Pre Processor (2005.03.17)";
  private String path;
  private String CONTROLS_RUN_FROM = "0.0";
  private String CONTROLS_RUN_TO = "1.0";
  private String CONTROLS_RUN_STEP = "";
  private String CONTROLS_PRINT_STEP = "0.01";
  private String CONTROLS_PRINT_TRACKER_STEP = "";
  private String[] graphicsmode = {"WIREFRAME","SURFACE","SOLID"};
  public Hashtable MatDB = new Hashtable();
  public Hashtable ConstDB = new Hashtable();
  public Hashtable LoadDB = new Hashtable();
  private int id_color = 0;
  private String[] MatHdr = {"Name","Color","Type","Description"};
  private String[] LoadHdr = {"Name","Color","Description"};
  private TableModel MatModel = new AbstractTableModel() {
    public int getColumnCount() { return 4; }
    public int getRowCount() { return MatDB.size(); }
    public Object getValueAt(int row, int col){
        int i=0;
        for(Enumeration en = MatDB.keys(); en.hasMoreElements();){
          String key = en.nextElement()+"";
          Material mat = (Material)MatDB.get(key);
          if(i==row){
            if(col==0)return key;
            else if(col==1) return "";
            else if(col==2) return mat.type;
            else if(col==3) return mat.description;
            else return "";
          }
          i++;
        }
        return "";
    }
    public String getColumnName(int col) {return MatHdr[col];}
    public boolean isCellEditable(int row, int col) { if(col==3 || col==1)return true; else return false;}
    public void setValueAt(Object aValue, int row, int col) {
      Material mat = (Material)MatDB.get(getValueAt(row,0));
      if(col==1)mat.color=(Color)aValue;
      if(col==3)mat.description=aValue+"";
    }
    public Class getColumnClass(int c) {return getValueAt(0, c).getClass();}
  };
  private TableModel ConstModel = new AbstractTableModel() {
    public int getColumnCount() { return 4; }
    public int getRowCount() { return ConstDB.size(); }
    public Object getValueAt(int row, int col){
        int i=0;
        for(Enumeration en = ConstDB.keys(); en.hasMoreElements();){
          String key = en.nextElement()+"";
          Constraints con = (Constraints)ConstDB.get(key);
          if(i==row){
            if(col==0)return key;
            else if(col==1) return "";
            else if(col==2) return con.type;
            else if(col==3) return con.description;
            else return "";
          }
          i++;
        }
        return "";
    }
    public String getColumnName(int col) {return MatHdr[col];}
    public boolean isCellEditable(int row, int col) { if(col==3 || col==1)return true; else return false;}
    public void setValueAt(Object aValue, int row, int col) {
      Constraints con = (Constraints)ConstDB.get(getValueAt(row,0));
      if(col==1)con.color=(Color)aValue;
      if(col==3)con.description=aValue+"";
    }
    public Class getColumnClass(int c) {return getValueAt(0, c).getClass();}
  };
  private TableModel LoadModel = new AbstractTableModel() {
    public int getColumnCount() { return 3; }
    public int getRowCount() { return LoadDB.size(); }
    public Object getValueAt(int row, int col){
        int i=0;
        for(Enumeration en = LoadDB.keys(); en.hasMoreElements();){
          String key = en.nextElement()+"";
          Loads ld = (Loads)LoadDB.get(key);
          if(i==row){
            if(col==0)return key;
            else if(col==1) return "";
            else if(col==2) return ld.description;
            else return "";
          }
          i++;
        }
        return "";
    }
    public String getColumnName(int col) {return LoadHdr[col];}
    public boolean isCellEditable(int row, int col) { if(col==2 || col==1)return true; else return false;}
    public void setValueAt(Object aValue, int row, int col) {
      Loads ld = (Loads)LoadDB.get(getValueAt(row,0));
      if(col==1)ld.color=(Color)aValue;
      if(col==2)ld.description=aValue+"";
    }
    public Class getColumnClass(int c) {return getValueAt(0, c).getClass();}
  };

  private JTable MatTable = new JTable(MatModel){
    public TableCellRenderer getCellRenderer(int row, int column) {
      if(column == 1) {
        DefaultTableCellRenderer render = new DefaultTableCellRenderer();
        render.setBackground(((Material)MatDB.get(getValueAt(row,0))).color);
        render.setForeground(((Material)MatDB.get(getValueAt(row,0))).color);
        return render;
        }else  return super.getCellRenderer(row, column);
    }
    public TableCellEditor getCellEditor(int row, int column) {
      if(column == 1) {
        Color cl = JColorChooser.showDialog(this,"Pick a Color",((Material)MatDB.get(getValueAt(row,0))).color);
        if(cl!=null)((Material)MatDB.get(getValueAt(row,0))).color=cl;
      }
      return super.getCellEditor(row, column);
    }
  };
  private JTable ConstTable = new JTable(ConstModel){
    public TableCellRenderer getCellRenderer(int row, int column) {
      if(column == 1) {
        DefaultTableCellRenderer render = new DefaultTableCellRenderer();
        render.setBackground(((Constraints)ConstDB.get(getValueAt(row,0))).color);
        render.setForeground(((Constraints)ConstDB.get(getValueAt(row,0))).color);
        return render;
        }else  return super.getCellRenderer(row, column);
    }
    public TableCellEditor getCellEditor(int row, int column) {
      if(column == 1) {
        Color cl = JColorChooser.showDialog(this,"Pick a Color",((Constraints)ConstDB.get(getValueAt(row,0))).color);
        if(cl!=null)((Constraints)ConstDB.get(getValueAt(row,0))).color=cl;
      }
      return super.getCellEditor(row, column);
    }
  };
  private JTable LoadTable = new JTable(LoadModel){
    public TableCellRenderer getCellRenderer(int row, int column) {
      if(column == 1) {
        DefaultTableCellRenderer render = new DefaultTableCellRenderer();
        render.setBackground(((Loads)LoadDB.get(getValueAt(row,0))).color);
        render.setForeground(((Loads)LoadDB.get(getValueAt(row,0))).color);
        return render;
        }else  return super.getCellRenderer(row, column);
    }
    public TableCellEditor getCellEditor(int row, int column) {
      if(column == 1) {
        Color cl = JColorChooser.showDialog(this,"Pick a Color",((Loads)LoadDB.get(getValueAt(row,0))).color);
        if(cl!=null)((Loads)LoadDB.get(getValueAt(row,0))).color=cl;
      }
      return super.getCellEditor(row, column);
    }
  };

  ImageIcon img_new = new ImageIcon(PreProcessor.class.getResource("new.gif"));
  ImageIcon img_open = new ImageIcon(PreProcessor.class.getResource("open.gif"));
  ImageIcon img_save = new ImageIcon(PreProcessor.class.getResource("save.gif"));
  ImageIcon img_saveall = new ImageIcon(PreProcessor.class.getResource("saveall.gif"));
  ImageIcon img_list = new ImageIcon(PreProcessor.class.getResource("list.gif"));
  ImageIcon img_add = new ImageIcon(PreProcessor.class.getResource("add.gif"));

  ImageIcon img_zoomin = new ImageIcon(PreProcessor.class.getResource("zoomin.gif"));
  ImageIcon img_zoomout = new ImageIcon(PreProcessor.class.getResource("zoomout.gif"));
  ImageIcon img_zoomall = new ImageIcon(PreProcessor.class.getResource("zooma.gif"));
  ImageIcon img_center = new ImageIcon(PreProcessor.class.getResource("center.png"));
  ImageIcon img_show = new ImageIcon(PreProcessor.class.getResource("show.png"));
  ImageIcon img_hide = new ImageIcon(PreProcessor.class.getResource("hide.png"));
  ImageIcon img_view_top = new ImageIcon(PreProcessor.class.getResource("view_top.gif"));
  ImageIcon img_view_bottom = new ImageIcon(PreProcessor.class.getResource("view_bottom.gif"));
  ImageIcon img_view_left = new ImageIcon(PreProcessor.class.getResource("view_left.gif"));
  ImageIcon img_view_right = new ImageIcon(PreProcessor.class.getResource("view_right.gif"));
  ImageIcon img_view_front = new ImageIcon(PreProcessor.class.getResource("view_front.gif"));
  ImageIcon img_view_back = new ImageIcon(PreProcessor.class.getResource("view_back.gif"));
  ImageIcon img_view_sw = new ImageIcon(PreProcessor.class.getResource("view_sw.gif"));
  ImageIcon img_view_se = new ImageIcon(PreProcessor.class.getResource("view_se.gif"));
  ImageIcon img_view_ne = new ImageIcon(PreProcessor.class.getResource("view_ne.gif"));
  ImageIcon img_view_nw = new ImageIcon(PreProcessor.class.getResource("view_nw.gif"));
  ImageIcon img_config = new ImageIcon(PreProcessor.class.getResource("config.gif"));
  ImageIcon img_build = new ImageIcon(PreProcessor.class.getResource("build.png"));

  ImageIcon img_point = new ImageIcon(PreProcessor.class.getResource("node.gif"));
  ImageIcon img_arc = new ImageIcon(PreProcessor.class.getResource("arc.gif"));
  ImageIcon img_nurbcurve = new ImageIcon(PreProcessor.class.getResource("nurbcurve.gif"));

  ImageIcon img_surf_dir = new ImageIcon(PreProcessor.class.getResource("surf_dir.gif"));
  ImageIcon img_surf_rev = new ImageIcon(PreProcessor.class.getResource("surf_rev.gif"));
  ImageIcon img_surf_rule = new ImageIcon(PreProcessor.class.getResource("surf_rule.gif"));
  ImageIcon img_surf_nurb = new ImageIcon(PreProcessor.class.getResource("surf_nurb.gif"));

  ImageIcon img_node = new ImageIcon(PreProcessor.class.getResource("node.gif"));
  ImageIcon img_beam = new ImageIcon(PreProcessor.class.getResource("beam.gif"));
  ImageIcon img_spring = new ImageIcon(PreProcessor.class.getResource("spring.gif"));
  ImageIcon img_triangle = new ImageIcon(PreProcessor.class.getResource("triangle.gif"));
  ImageIcon img_quad = new ImageIcon(PreProcessor.class.getResource("quad.gif"));
  ImageIcon img_solid_iso_6 = new ImageIcon(PreProcessor.class.getResource("solid_iso_6.gif"));
  ImageIcon img_mesh = new ImageIcon(PreProcessor.class.getResource("mesh.gif"));
  ImageIcon img_material = new ImageIcon(PreProcessor.class.getResource("material.gif"));

  ImageIcon img_erase = new ImageIcon(PreProcessor.class.getResource("erase.gif"));
  ImageIcon img_move = new ImageIcon(PreProcessor.class.getResource("move.gif"));
  ImageIcon img_rotate = new ImageIcon(PreProcessor.class.getResource("rotate.gif"));
  ImageIcon img_scale = new ImageIcon(PreProcessor.class.getResource("scale.gif"));
  ImageIcon img_transform = new ImageIcon(PreProcessor.class.getResource("transform.gif"));
  ImageIcon img_properties = new ImageIcon(PreProcessor.class.getResource("properties.gif"));
  ImageIcon img_duplicate = new ImageIcon(PreProcessor.class.getResource("duplicate.png"));

  ImageIcon img_constraints = new ImageIcon(PreProcessor.class.getResource("constraints.gif"));
  ImageIcon img_loads = new ImageIcon(PreProcessor.class.getResource("loads.gif"));

  ImageIcon img_grid = new ImageIcon(PreProcessor.class.getResource("grid.gif"));

  BorderLayout borderLayout1 = new BorderLayout();
  JSplitPane jSplitPane1 = new JSplitPane();
  JPanel PanelInspector = new JPanel();
  private Canvas3D J3D = new Canvas3D(this);
  JToolBar jToolBar1 = new JToolBar();
  JButton b_new = new JButton();
  JButton b_open = new JButton();
  JButton b_save = new JButton();
  JButton b_saveall = new JButton();
  JPanel jPanel1 = new JPanel();
  GridLayout gridLayout1 = new GridLayout();
  JLabel coordinates = new JLabel();
  JToolBar jToolBar2 = new JToolBar();
  JToolBar jToolBar3 = new JToolBar();
  BorderLayout borderLayout2 = new BorderLayout();
  ButtonGroup CommandGroup = new ButtonGroup();
  JPanel jPanel5 = new JPanel();
  JButton b_zoomin = new JButton();
  JButton b_zoomout = new JButton();
  JButton b_zoomall = new JButton();
  JButton b_center = new JButton();
  JButton b_showhide = new JButton();
  JButton b_viewtop = new JButton();
  JButton b_viewleft = new JButton();
  JButton b_viewsw = new JButton();
  JButton b_viewne = new JButton();
  JButton b_viewse = new JButton();
  JButton b_viewbottom = new JButton();
  JButton b_viewright = new JButton();
  JButton b_viewnw = new JButton();
  JButton b_viewfront = new JButton();
  JButton b_viewback = new JButton();
  JButton b_savemodel = new JButton();
  JButton b_build = new JButton();
  
  BorderLayout borderLayout4 = new BorderLayout();
  JTabbedPane jTabbedPane2 = new JTabbedPane();
  JToolBar jToolBar6 = new JToolBar();
  JToolBar jToolBar5 = new JToolBar();
  JButton b_point = new JButton();
  JButton b_erase = new JButton();
  JButton b_duplicate = new JButton();
  JButton b_move = new JButton();
  JButton b_rotate = new JButton();
  JComboBox cb_graphicsmode = new JComboBox(graphicsmode);
  JButton b_del = new JButton();
  JButton b_add = new JButton();
  JToolBar jToolBar4 = new JToolBar();
  JScrollPane jScrollPane1 = new JScrollPane();
  JTree Tree = new JTree();
  JButton b_scale = new JButton();
  JButton b_node = new JButton();
  JButton b_element2 = new JButton();
  JButton b_element3 = new JButton();
  JButton b_element4 = new JButton();
  private JButton b_config = new JButton();
  private JPanel p_cmd = new JPanel();
  private JButton b_element8 = new JButton();
  private JButton b_surf_dir = new JButton();
  private JButton b_surf_rev = new JButton();
  private JButton b_surf_rule = new JButton();
  private JButton b_nurbcurve = new JButton();
  private JButton b_arc = new JButton();
  private JButton b_material = new JButton();
  private JButton b_constraints = new JButton();
  private JButton b_loads = new JButton();
  JCheckBox cb_node_0 = new JCheckBox("Nodes",true);
  JCheckBox cb_node = new JCheckBox("Nodes label",false);
  JCheckBox cb_element = new JCheckBox("Elements label",false);
  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);
  private JButton b_setmaterial = new JButton();
  private JButton c_setconstraints = new JButton();
  private JButton b_setloads = new JButton();
  private JButton b_transform = new JButton();
  private JButton b_surf_nurb = new JButton();
  private JButton b_mesh = new JButton();
  private JButton b_grid = new JButton();
  private JButton b_properties = new JButton();
  private JButton b_element3s = new JButton();

  public _Object edit_panel;
  private boolean block = false;
  private boolean show = true;
  
  public PreProcessor() {
    try { jbInit(); } catch(Exception e) { e.printStackTrace();  }
  }
  public void exit(){
    save_loads();
    save_materials();
    save_constraints();
    System.out.println("PreProcessor finalize.");
  }
  private void jbInit() throws Exception {
    load_materials();
    load_constraints();
    load_loads();
    MatTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    MatTable.getColumnModel().getColumn(3).setPreferredWidth(500);
    ConstTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    ConstTable.getColumnModel().getColumn(3).setPreferredWidth(500);
    LoadTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    LoadTable.getColumnModel().getColumn(2).setPreferredWidth(500);
    this.setLayout(borderLayout1);
    jSplitPane1.setMinimumSize(new Dimension(0, 0));
    jSplitPane1.setPreferredSize(new Dimension(0, 0));
    jSplitPane1.setLastDividerLocation(220);
    jSplitPane1.setOneTouchExpandable(true);
    PanelInspector.setMinimumSize(new Dimension(0, 0));
    PanelInspector.setPreferredSize(new Dimension(0, 0));
    PanelInspector.setLayout(borderLayout2);
    b_new.setToolTipText("New");
    b_new.setIcon(img_new);
    b_new.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        J3D.remove_all();
        p_cmd.removeAll();
        p_cmd.validate();
        PanelInspector.validate();
      }
    });
    b_open.setToolTipText("Open");
    b_open.setIcon(img_open);
    b_open.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_open_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_saveall.setToolTipText("Save all");
    b_saveall.setIcon(img_saveall);
    b_saveall.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_save_actionPerformed(e);
        b_savemodel_actionPerformed(e);
      }
    });
    b_build.setToolTipText("Rebuild model");
    b_build.setIcon(img_build);
    b_build.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        J3D.rebuild();
      }
    });
    jPanel1.setLayout(gridLayout1);
    gridLayout1.setColumns(3);
    jToolBar1.setFloatable(false);
    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_zoomall.setToolTipText("Zoom all");
    b_zoomall.setIcon(img_zoomall);
    b_zoomall.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_zoomall_actionPerformed(e);
      }
    });
    b_center.setToolTipText("Set the selected object to center of rotation");
    b_center.setIcon(img_center);
    b_center.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        J3D.setCenterOfRotation();
      }
    });
    b_showhide.setToolTipText("Set the selected object to center of rotation");
    b_showhide.setIcon(img_hide);
    b_showhide.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        show = J3D.showhide();
        
        if (show) b_showhide.setIcon(img_hide);
            else b_showhide.setIcon(img_show);
        
      }
    });
    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_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);
      }
    });
    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_savemodel.setToolTipText("Save model *.in");
    b_savemodel.setIcon(img_list);
    b_savemodel.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_savemodel_actionPerformed(e);
      }
    });
    jPanel5.setLayout(borderLayout4);
    coordinates.setText(" ");
    jToolBar6.setFloatable(false);
    jToolBar5.setFloatable(false);
    b_point.setToolTipText("Point");
    b_point.setActionCommand("Point");
    b_point.setIcon(img_point);
    b_point.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        command(e);
      }
    });
    b_erase.setToolTipText("Erase");
    b_erase.setActionCommand("Erase");
    b_erase.setIcon(img_erase);
    b_erase.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        resetselect();
        J3D.remove();
      }
    });
    b_move.setToolTipText("Move");
    b_move.setActionCommand("Move");
    b_move.setIcon(img_move);
    b_move.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        command(e);
      }
    });
    b_rotate.setToolTipText("Rotate");
    b_rotate.setActionCommand("Rotate");
    b_rotate.setIcon(img_rotate);
    b_rotate.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        command(e);
      }
    });
    cb_graphicsmode.setPreferredSize(new Dimension(25, 21));
    cb_graphicsmode.setToolTipText("Graphics mode");
    cb_graphicsmode.setSelectedIndex(1);
    J3D.GRAPHICSMODE=J3D.GRAPHICSMODE_SURFACE;
    cb_graphicsmode.addItemListener(new java.awt.event.ItemListener() {
      public void itemStateChanged(ItemEvent e) {
        cb_graphicsmode_itemStateChanged(e);
      }
    });
    b_del.setToolTipText("Erase");
    b_del.setActionCommand("Erase");
    b_del.setIcon(img_erase);
    b_del.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        resetselect();
        J3D.remove();
      }
    });
    b_add.setToolTipText("Import from file");
    b_add.setActionCommand("Add");
    b_add.setIcon(img_add);
    b_add.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_add_actionPerformed(e);
      }
    });
    jToolBar4.setFloatable(false);
    Tree.setModel(J3D.tree3d);
    Tree.setRootVisible(false);
    Tree.setShowsRootHandles(true);
    Tree.addMouseListener(new MouseAdapter(){
      public void mouseClicked(MouseEvent e){
        showEditPanel(e);
      }
    });

    Tree.addTreeSelectionListener(new TreeSelectionListener() {
        public void valueChanged(TreeSelectionEvent e) {
            if (!block)
                treeSelectionChanged();
        }
    });
    
    b_scale.setToolTipText("Scale");
    b_scale.setActionCommand("Scale");
    b_scale.setIcon(img_scale);
    b_scale.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        command(e);
      }
    });
    b_node.setToolTipText("Node");
    b_node.setActionCommand("Node");
    b_node.setIcon(img_node);
    b_node.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        command(e);
      }
    });
    b_element2.setToolTipText("Elements with 2 nodes");
    b_element2.setActionCommand("Element2");
    b_element2.setIcon(img_beam);
    b_element2.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        command(e);
      }
    });
    b_element3.setToolTipText("Elements with 3 nodes");
    b_element3.setActionCommand("Element3");
    b_element3.setIcon(img_triangle);
    b_element3.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        command(e);
      }
    });
    b_element4.setToolTipText("Elements with 4 nodes");
    b_element4.setActionCommand("Element4");
    b_element4.setIcon(img_quad);
    b_element4.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        command(e);
      }
    });
    b_config.setToolTipText("Properties");
    b_config.setIcon(img_config);
    b_config.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_config_actionPerformed(e);
      }
    });
    b_element8.setToolTipText("Elements with 8 nodes");
    b_element8.setActionCommand("Element8");
    b_element8.setIcon(img_solid_iso_6);
    b_element8.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        command(e);
      }
    });
    b_surf_dir.setToolTipText("Tabulated surface from a path curve and a direction");
    b_surf_dir.setActionCommand("SurfDir");
    b_surf_dir.setIcon(img_surf_dir);
    b_surf_dir.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(ActionEvent e) {
          command(e);
        }
      });
    b_surf_rev.setToolTipText("Revolved surface about a selected axis");
    b_surf_rev.setActionCommand("SurfRev");
    b_surf_rev.setIcon(img_surf_rev);
    b_surf_rev.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        command(e);
      }
    });
    b_surf_rule.setToolTipText("Ruled surface between curves");
    b_surf_rule.setActionCommand("SurfRul");
    b_surf_rule.setIcon(img_surf_rule);
    b_surf_rule.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
       command(e);
      }
    });
    b_arc.setToolTipText("Arc");
    b_arc.setActionCommand("Arc");
    b_arc.setIcon(img_arc);
    b_arc.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        command(e);
      }
    });
    b_nurbcurve.setToolTipText("Spline");
    b_nurbcurve.setActionCommand("Spline");
    b_nurbcurve.setIcon(img_nurbcurve);
    b_nurbcurve.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        command(e);
      }
    });
    b_material.setToolTipText("Materials");
    b_material.setActionCommand("Material");
    b_material.setIcon(img_material);
    b_material.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_material_actionPerformed(e);
      }
    });
    b_constraints.setToolTipText("Constraints");
    b_constraints.setActionCommand("Constraints");
    b_constraints.setIcon(img_constraints);
    b_constraints.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_constraints_actionPerformed(e);
      }
    });
    b_loads.setToolTipText("Loads");
    b_loads.setActionCommand("Loads");
    b_loads.setIcon(img_loads);
    b_loads.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        b_loads_actionPerformed(e);
      }
    });
    b_setmaterial.setToolTipText("Material for ...");
    b_setmaterial.setActionCommand("SetMaterial");
    b_setmaterial.setIcon(img_material);
    b_setmaterial.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        command(e);
      }
    });
    c_setconstraints.setToolTipText("Constraints for ...");
    c_setconstraints.setActionCommand("SetConstraints");
    c_setconstraints.setIcon(img_constraints);
    c_setconstraints.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        command(e);
      }
    });
    b_setloads.setToolTipText("Loads for ...");
    b_setloads.setActionCommand("SetLoads");
    b_setloads.setIcon(img_loads);
    b_setloads.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        command(e);
      }
    });
    b_transform.setToolTipText("Transform 4X4");
    b_transform.setActionCommand("Transform");
    b_transform.setIcon(img_transform);
    b_transform.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        command(e);
      }
    });
    b_surf_nurb.setIcon(img_surf_nurb);
    b_surf_nurb.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        command(e);
      }
    });
    b_surf_nurb.setToolTipText("Nurb Surface");
    b_surf_nurb.setActionCommand("SurfNurb");
    b_mesh.setToolTipText("Mesh");
    b_mesh.setActionCommand("Mesh");
    b_mesh.setIcon(img_mesh);
    b_mesh.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        command(e);
      }
    });
    b_grid.setToolTipText("Grid");
    b_grid.setActionCommand("Grid");
    b_grid.setIcon(img_grid);
    b_grid.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        command(e);
      }
    });
    b_properties.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        command(e);
      }
    });
    b_properties.setIcon(img_properties);
    b_properties.setActionCommand("Properties");
    b_properties.setToolTipText("Properties");
    b_duplicate.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(ActionEvent e) {
            J3D.duplicate();
          }
        });
    b_duplicate.setIcon(img_duplicate);
    b_duplicate.setActionCommand("Duplicate");
    b_duplicate.setToolTipText("Duplicate");
    b_element3s.setToolTipText("Element Spring");
    b_element3s.setActionCommand("Element3s");
    b_element3s.setIcon(img_spring);
    this.add(jSplitPane1, BorderLayout.CENTER);
    jSplitPane1.add(PanelInspector, JSplitPane.TOP);
    PanelInspector.add(jToolBar4, BorderLayout.NORTH);
    jToolBar4.add(cb_graphicsmode);
    PanelInspector.add(jScrollPane1, BorderLayout.CENTER);
    PanelInspector.add(p_cmd,  BorderLayout.SOUTH);
    jScrollPane1.getViewport().add(Tree);
    jPanel5.add(J3D, BorderLayout.CENTER);
    jPanel5.add(jTabbedPane2, BorderLayout.NORTH);

    jTabbedPane2.add(jToolBar5, "Draw");
    jToolBar5.add(b_point, null);
    jToolBar5.add(b_nurbcurve, null);
    jToolBar5.add(b_arc, null);
    jToolBar5.addSeparator();
    jToolBar5.add(b_surf_dir, null);
    jToolBar5.add(b_surf_rev, null);
    jToolBar5.add(b_surf_rule, null);
    jToolBar5.add(b_surf_nurb, null);
    jToolBar5.addSeparator();
    jToolBar5.add(b_node, null);
    jToolBar5.add(b_element2, null);
    jToolBar5.add(b_element3s, null);
    jToolBar5.add(b_element3, null);
    jToolBar5.add(b_element4, null);
    jToolBar5.add(b_element8, null);

    jTabbedPane2.add(jToolBar6, "Modify");
    jToolBar6.add(b_duplicate,null);
    jToolBar6.add(b_erase, null);
    jToolBar6.add(b_move, null);
    jToolBar6.add(b_rotate, null);
    jToolBar6.add(b_scale, null);
    jToolBar6.add(b_transform, null);
    jToolBar6.addSeparator();
    jToolBar6.add(b_setmaterial, null);
    jToolBar6.add(c_setconstraints, null);
    jToolBar6.add(b_setloads, null);
    jToolBar6.add(b_mesh, null);
    jToolBar6.addSeparator();
    jToolBar6.add(b_grid, null);
    jSplitPane1.add(jPanel5, JSplitPane.BOTTOM);

    this.add(jToolBar1, BorderLayout.NORTH);
    jToolBar1.add(b_new, null);
    jToolBar1.add(b_open, null);
    jToolBar1.add(b_add, null);
    jToolBar1.add(b_save, null);
    jToolBar1.add(b_saveall, null);
    jToolBar1.add(b_savemodel, null);
    jToolBar1.addSeparator();
    jToolBar1.add(b_build, null);
    jToolBar1.addSeparator();
    jToolBar1.add(b_showhide, null);
    jToolBar1.add(b_zoomin, null);
    jToolBar1.add(b_zoomout, null);
    jToolBar1.add(b_zoomall, null);
    jToolBar1.add(b_center,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.addSeparator();
    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);
    jToolBar1.addSeparator();
    jToolBar1.add(b_material, null);
    jToolBar1.add(b_constraints, null);
    jToolBar1.add(b_loads, null);

    this.add(jPanel1, BorderLayout.SOUTH);
    jPanel1.add(coordinates, null);
    jPanel1.add(jToolBar3, null);
    jPanel1.add(jToolBar2, null);
    jSplitPane1.setDividerLocation(220);
    //J3D.coodinates=coordinates;
  }


  public static Frame getFrame(Component component){
    for(; component != null && !(component instanceof Frame); component = component.getParent());
    return (Frame)component;
  }

  void b_add_actionPerformed(ActionEvent e) {
    try {
      FileDialog fd = new FileDialog(getFrame(this),"Open result",FileDialog.LOAD);
      fd.setDirectory(".");
      fd.setFile("*.stl"+File.pathSeparator+"*.in");
      fd.show();
      String file=fd.getDirectory()+fd.getFile();
      if(fd.getFile()!=null){
        if(file.endsWith(".stl"))J3D.open_stl(file);
        if(file.endsWith(".in")){
          J3D.add3D(new _In(file,MatDB,ConstDB,LoadDB));
          J3D.view_reset();
          //save_materials();
          //save_constraints();
          //save_loads();
        }
      }
    } 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);
  }

  void cb_graphicsmode_itemStateChanged(ItemEvent e) {
    J3D.GRAPHICSMODE=(byte)cb_graphicsmode.getSelectedIndex();
    if(cb_graphicsmode.getSelectedIndex()==0)cb_materials.setSelected(false); else cb_materials.setSelected(true);
    J3D.repaint();
  }

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

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

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

  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_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 command(ActionEvent e) {
    p_cmd.removeAll();
    int w = p_cmd.getWidth();
    String st_cmd = ""+e.getActionCommand();
    if(st_cmd.equalsIgnoreCase("POINT")) {
        _Point t = new _Point(true);
        p_cmd.add(t.getEditPanel(J3D,this),BorderLayout.CENTER);
        t.requestFocus();
    }
    else if(st_cmd.equalsIgnoreCase("NODE")) {
        edit_panel = new _Node(true);
        p_cmd.add(edit_panel.getEditPanel(J3D,this),BorderLayout.CENTER);
        edit_panel.requestFocus();
    }
    else if(st_cmd.equalsIgnoreCase("ELEMENT8")) {
        edit_panel = new _Element8(true);
        p_cmd.add(edit_panel.getEditPanel(J3D,this),BorderLayout.CENTER);
        edit_panel.requestFocus();
    }

    else if(st_cmd.equalsIgnoreCase("ELEMENT4")) {
        edit_panel = new _Element4(true);
        p_cmd.add(edit_panel.getEditPanel(J3D,this),BorderLayout.CENTER);
        edit_panel.requestFocus();
    }
    
    else if(st_cmd.equalsIgnoreCase("ELEMENT3")) {
        edit_panel = new _Element3(true);
        p_cmd.add(edit_panel.getEditPanel(J3D,this),BorderLayout.CENTER);
        edit_panel.requestFocus();
    }
    else if(st_cmd.equalsIgnoreCase("ELEMENT2")) {
        edit_panel = new _Element2(true);
        p_cmd.add(edit_panel.getEditPanel(J3D,this),BorderLayout.CENTER);
        edit_panel.requestFocus();
    }
    else if(st_cmd.equalsIgnoreCase("MESH"))p_cmd.add(new PreProcessor_Mesh(J3D),BorderLayout.CENTER);
    else if(st_cmd.equalsIgnoreCase("MOVE"))p_cmd.add(new PreProcessor_Move(J3D,this),BorderLayout.CENTER);
    else if(st_cmd.equalsIgnoreCase("ROTATE"))p_cmd.add(new PreProcessor_Rotate(J3D,this),BorderLayout.CENTER);
    else if(st_cmd.equalsIgnoreCase("SCALE"))p_cmd.add(new PreProcessor_Scale(J3D,this),BorderLayout.CENTER);
    else if(st_cmd.equalsIgnoreCase("TRANSFORM"))p_cmd.add(new PreProcessor_Transform(J3D),BorderLayout.CENTER);
    else if(st_cmd.equalsIgnoreCase("ARC")) {
        edit_panel = new _Arc(true);
        p_cmd.add(edit_panel.getEditPanel(J3D,this),BorderLayout.CENTER);
        edit_panel.requestFocus();
    }
    else if(st_cmd.equalsIgnoreCase("SPLINE")) {
        edit_panel = new _Spline(true);
        p_cmd.add(edit_panel.getEditPanel(J3D,this),BorderLayout.CENTER);
        edit_panel.requestFocus();
    }
    else if(st_cmd.equalsIgnoreCase("SURFDIR")) {
        edit_panel = new _SurfDir(true);
        p_cmd.add(edit_panel.getEditPanel(J3D,this),BorderLayout.CENTER);
        edit_panel.requestFocus();
    }
    else if(st_cmd.equalsIgnoreCase("SURFREV")) {
        edit_panel = new _SurfRev(true);
        p_cmd.add(edit_panel.getEditPanel(J3D,this),BorderLayout.CENTER);
        edit_panel.requestFocus();
    }
    else if(st_cmd.equalsIgnoreCase("SURFRUL")){
        edit_panel = new _SurfRul(true);
        p_cmd.add(edit_panel.getEditPanel(J3D,this),BorderLayout.CENTER);
        edit_panel.requestFocus();
    }
    else if(st_cmd.equalsIgnoreCase("SURFNURB")){
        edit_panel = new _BilinearSurface(true);
        p_cmd.add(edit_panel.getEditPanel(J3D,this),BorderLayout.CENTER);
        edit_panel.requestFocus();
    }
    else if(st_cmd.equalsIgnoreCase("PROPERTIES"))showEditPanel();
    else if(st_cmd.equalsIgnoreCase("SETCONSTRAINTS"))p_cmd.add(new PreProcessor_SetConstraints(J3D,this),BorderLayout.CENTER);
    else if(st_cmd.equalsIgnoreCase("SETLOADS"))p_cmd.add(new PreProcessor_SetLoads(J3D,this),BorderLayout.CENTER);
    else if(st_cmd.equalsIgnoreCase("SETMATERIAL"))p_cmd.add(new PreProcessor_SetMaterial(J3D,this),BorderLayout.CENTER);
    else if(st_cmd.equalsIgnoreCase("GRID"))p_cmd.add(new PreProcessor_Grid(J3D),BorderLayout.CENTER);
    p_cmd.validate();
    PanelInspector.validate();
  }


  void b_save_actionPerformed(ActionEvent e) {
    try {
      FileDialog fd = new FileDialog(getFrame(this),"Save model as",FileDialog.SAVE);
      fd.setDirectory(".");
      fd.setFile("*.impact");
      fd.show();
      String st = fd.getDirectory()+fd.getFile();
      if(fd.getFile()!=null){
        if(!st.endsWith(".impact"))st+=".impact";
        File f = new File(st);
        f.delete();
        try {
          FileOutputStream ostream = new FileOutputStream(st);
          ObjectOutputStream p = new ObjectOutputStream(ostream);
          p.writeObject(MatDB);
          p.writeObject(ConstDB);
          p.writeObject(LoadDB);
          p.writeObject(J3D.VMatrix3D);
          _Object[] arr_obj = J3D.getAllObjects3D();
          for(int i=0; i<arr_obj.length; i++){
            p.writeObject(arr_obj[i]);
          }
          p.flush();
          ostream.flush();
          ostream.close();
        }catch(Exception ie) { error(ie); }
        path=st;
      }
    } catch(Exception e1) {error(e1);}
  }

  void b_open_actionPerformed(ActionEvent e) {
    try {
      FileDialog fd = new FileDialog(getFrame(this),"Open Impact model",FileDialog.LOAD);
      fd.setDirectory(".");
      fd.setFile("*.impact");
      fd.show();
      path=fd.getDirectory()+fd.getFile();
      if(fd.getFile()!=null){
        FileInputStream istream = new FileInputStream(path);
        ObjectInputStream p = new ObjectInputStream(istream);
        MatDB = (Hashtable)p.readObject();
        ConstDB = (Hashtable)p.readObject();
        LoadDB = (Hashtable)p.readObject();
        J3D.remove_all();
        J3D.VMatrix3D=(Matrix3D)p.readObject();
        Object obj;
        try { while((obj = p.readObject())!=null) J3D.add3D(obj); }catch(EOFException eof){}
        J3D.view_repaint();
        p.close();
        istream.close();
        //save_constraints();
        //save_loads();
        //save_materials();
      }
    } catch(Exception e1) {error(e1);}
  }

  public Color getColorLine(int cl){
      int i = (int)(cl-Math.round(cl/10)*10);
      if(i==0)return Color.black;
      else if(i==1)return Color.gray;
      else if(i==2)return Color.cyan;
      else if(i==3)return Color.blue;
      else if(i==4)return Color.green;
      else if(i==5)return Color.magenta;
      else if(i==6)return Color.orange;
      else if(i==7)return Color.pink;
      else if(i==8)return Color.red;
      else return Color.yellow;
  }

  void b_material_actionPerformed(ActionEvent e) {
    JPanel p = new JPanel(new BorderLayout());
    JPanel p1 = new JPanel();
    JButton m_new = new JButton("New");
    m_new.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        JPanel p2 = new JPanel(new VerticalFlowLayout());
        JPanel p3 = new JPanel(new BorderLayout());
        JPanel p4 = new JPanel(new BorderLayout());
        JPanel p5 = new JPanel(new BorderLayout());
        JPanel p6 = new JPanel(new BorderLayout());
        String[] st = {"Elastic","Elastoplastic","Spring"};
        JComboBox cb_type = new JComboBox(st);
        JTextField tf_name = new JTextField("mat"+id_color);
        JTextField tf_disc = new JTextField();
        JButton b_col = new JButton();
        b_col.addActionListener(new java.awt.event.ActionListener() {
          public void actionPerformed(ActionEvent e) {
            Color cl = JColorChooser.showDialog(getFrame(PanelInspector),"Pick a Color",getColorLine(id_color));
            if(cl!=null)((JButton)e.getSource()).setBackground(cl);
          }
        });
        b_col.setBackground(getColorLine(id_color));
        p2.add(p3);
        p3.add(new JLabel("Type of material"), BorderLayout.WEST);
        p3.add(cb_type, BorderLayout.CENTER);
        p2.add(p4);
        p4.add(new JLabel("Name"),  BorderLayout.WEST);
        p4.add(tf_name,  BorderLayout.CENTER);
        p2.add(p5, null);
        p5.add(new JLabel("Description"), BorderLayout.WEST);
        p5.add(tf_disc, BorderLayout.CENTER);
        p2.add(p6);
        p6.add(new JLabel("Color"), BorderLayout.WEST);
        p6.add(b_col, BorderLayout.CENTER);
        int result = JOptionPane.showOptionDialog(getFrame(PanelInspector),p2,"New Material",JOptionPane.YES_NO_OPTION,JOptionPane.PLAIN_MESSAGE,null,null,null);
        if(result!=0) return;
        id_color++;
        Material mat = new Material();
        mat.name=tf_name.getText();
        mat.type=cb_type.getSelectedItem()+"";
        mat.color=b_col.getBackground();
        mat.description=tf_disc.getText();
        MatDB.put(tf_name.getText(),mat);
        MatTable.revalidate();
      }
    });
    JButton m_del = new JButton("Delete");
    m_del.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        int[] sel = MatTable.getSelectedRows();
        String[] sel_st = new String[sel.length];
        for(int i=0; i<sel.length; i++){
          sel_st[i]=MatTable.getValueAt(sel[i],0)+"";
        }
        for(int i=0; i<sel.length; i++){
          MatDB.remove(sel_st[i]);
        }
        MatTable.revalidate();
      }
    });
    JScrollPane spl = new JScrollPane();
    p.add(spl, BorderLayout.CENTER);
    p.add(p1, BorderLayout.NORTH);
    p1.add(m_new);
    p1.add(m_del);
    spl.getViewport().add(MatTable);
    JOptionPane.showMessageDialog(getFrame(PanelInspector), p, "Material", JOptionPane.PLAIN_MESSAGE);
    //if(result!=0) load_materials(); else save_materials();
  }
  
  public void load_materials(){
    try{
      MatDB.clear();
      RandomAccessFile fin = new RandomAccessFile("Material.properties","r");
      String st;
      while((st=fin.readLine())!=null){
        Material mat = new Material();
        mat.type = st;
        mat.name = fin.readLine();
        mat.description = fin.readLine();
        StringTokenizer stt = new StringTokenizer(fin.readLine());
        mat.color = new Color(Integer.parseInt(stt.nextToken()),Integer.parseInt(stt.nextToken()),Integer.parseInt(stt.nextToken()));
        MatDB.put(mat.name,mat);
      }
      fin.close();
    }catch(Exception ex){error(ex);}
  }
  
  public void load_constraints(){
    try{
      ConstDB.clear();
      RandomAccessFile fin = new RandomAccessFile("Constraints.properties","r");
      String st;
      while((st=fin.readLine())!=null){
        Constraints con = new Constraints();
        con.type = st;
        con.name = fin.readLine();
        con.description = fin.readLine();
        StringTokenizer stt = new StringTokenizer(fin.readLine());
        con.color = new Color(Integer.parseInt(stt.nextToken()),Integer.parseInt(stt.nextToken()),Integer.parseInt(stt.nextToken()));
        ConstDB.put(con.name,con);
      }
      fin.close();
    }catch(Exception ex){error(ex);}
  }
  
  public void load_loads(){
    try{
      LoadDB.clear();
      RandomAccessFile fin = new RandomAccessFile("Loads.properties","r");
      String st;
      while((st=fin.readLine())!=null){
        Loads ld = new Loads();
        ld.name = st;
        ld.description = fin.readLine();
        StringTokenizer stt = new StringTokenizer(fin.readLine());
        ld.color = new Color(Integer.parseInt(stt.nextToken()),Integer.parseInt(stt.nextToken()),Integer.parseInt(stt.nextToken()));
        LoadDB.put(ld.name,ld);
      }
      fin.close();
    }catch(Exception ex){error(ex);}
  }

  public void save_materials(){
    try{
      File f = new File("Material.properties");
      f.delete();
      RandomAccessFile fout = new RandomAccessFile(f,"rw");
      for(Enumeration en = MatDB.keys(); en.hasMoreElements();){
        String key = en.nextElement()+"";
        Material mat = (Material)MatDB.get(key);
        fout.writeBytes(mat.type+"\n");
        fout.writeBytes(mat.name+"\n");
        fout.writeBytes(mat.description+"\n");
        fout.writeBytes(mat.color.getRed()+" "+mat.color.getGreen()+" "+mat.color.getBlue()+"\n");
      }
      fout.close();
      J3D.tree_reset();
      J3D.view_reset();
    }catch(Exception ex){error(ex);}
  }
  
  public void save_constraints(){
    try{
      File f = new File("Constraints.properties");
      f.delete();
      RandomAccessFile fout = new RandomAccessFile(f,"rw");
      for(Enumeration en = ConstDB.keys(); en.hasMoreElements();){
        String key = en.nextElement()+"";
        Constraints con = (Constraints)ConstDB.get(key);
        fout.writeBytes(con.type+"\n");
        fout.writeBytes(con.name+"\n");
        fout.writeBytes(con.description+"\n");
        fout.writeBytes(con.color.getRed()+" "+con.color.getGreen()+" "+con.color.getBlue()+"\n");
      }
      fout.close();
      J3D.tree_reset();
      J3D.view_reset();
    }catch(Exception ex){error(ex);}
  }
  
  public void save_loads(){
    try{
      File f = new File("Loads.properties");
      f.delete();
      RandomAccessFile fout = new RandomAccessFile(f,"rw");
      for(Enumeration en = LoadDB.keys(); en.hasMoreElements();){
        String key = en.nextElement()+"";
        Loads ld = (Loads)LoadDB.get(key);
        fout.writeBytes(ld.name+"\n");
        fout.writeBytes(ld.description+"\n");
        fout.writeBytes(ld.color.getRed()+" "+ld.color.getGreen()+" "+ld.color.getBlue()+"\n");
      }
      fout.close();
      J3D.tree_reset();
      J3D.view_reset();
    }catch(Exception ex){error(ex);}
  }


  void b_config_actionPerformed(ActionEvent e) {
    JTabbedPane p = new JTabbedPane();
    JPanel p1 = new JPanel(new VerticalFlowLayout());
    JPanel p2 = new JPanel(new VerticalFlowLayout());
    JPanel p3 = new JPanel(new FlowLayout(FlowLayout.LEFT));
    JPanel p4 = new JPanel(new FlowLayout(FlowLayout.LEFT));
    JPanel p5 = new JPanel(new FlowLayout(FlowLayout.LEFT));
    p1.add(cb_node_0);
    p1.add(cb_node);
    p1.add(cb_element);
    p1.add(cb_constraints);
    p1.add(cb_loads);
    p1.add(cb_trackers);
    p1.add(cb_materials);
    p2.add(p3);
    p2.add(p4);
    p2.add(p5);
    p.add("Controls",p2);
    p.add("Show",p1);
    JTextField tf_CONTROLS_RUN_FROM = new JTextField(CONTROLS_RUN_FROM,5);
    JTextField tf_CONTROLS_RUN_TO = new JTextField(CONTROLS_RUN_TO,5);
    JTextField tf_CONTROLS_RUN_STEP = new JTextField(CONTROLS_RUN_STEP,5);
    JTextField tf_CONTROLS_PRINT_STEP = new JTextField(CONTROLS_PRINT_STEP,5);
    JTextField tf_CONTROLS_PRINT_TRACKER_STEP = new JTextField(CONTROLS_PRINT_TRACKER_STEP,5);
    p3.add(new JLabel("Run from"));
    p3.add(tf_CONTROLS_RUN_FROM);
    p3.add(new JLabel("to"));
    p3.add(tf_CONTROLS_RUN_TO);
    p3.add(new JLabel("step"));
    p3.add(tf_CONTROLS_RUN_STEP);
    p4.add(new JLabel("Print every"));
    p4.add(tf_CONTROLS_PRINT_STEP);
    p4.add(new JLabel("step"));
    p5.add(new JLabel("Print tracker every"));
    p5.add(tf_CONTROLS_PRINT_TRACKER_STEP);
    p5.add(new JLabel("step"));
    JOptionPane.showMessageDialog(this,p,"Properties",JOptionPane.PLAIN_MESSAGE,null);
    if(cb_node_0.isSelected())J3D.POINTSIZE=4; else J3D.POINTSIZE=0;
    J3D.SHOW_ID_NODE=cb_node.isSelected();
    J3D.SHOW_ID_ELEMENT=cb_element.isSelected();
    J3D.SHOW_ID_CONSTRAINTS=cb_constraints.isSelected();
    J3D.SHOW_ID_LOADS=cb_loads.isSelected();
    J3D.SHOW_ID_TRACKERS=cb_trackers.isSelected();
    if(!cb_materials.isSelected()){
      cb_graphicsmode.setSelectedIndex(0);
    }else cb_graphicsmode.setSelectedIndex(1);
    CONTROLS_RUN_FROM=tf_CONTROLS_RUN_FROM.getText();
    CONTROLS_RUN_TO=tf_CONTROLS_RUN_TO.getText();
    CONTROLS_RUN_STEP=tf_CONTROLS_RUN_STEP.getText();
    CONTROLS_PRINT_STEP=tf_CONTROLS_PRINT_STEP.getText();
    CONTROLS_PRINT_TRACKER_STEP=tf_CONTROLS_PRINT_TRACKER_STEP.getText();
    J3D.view_reset();
    J3D.tree_reset();
  }

  void b_constraints_actionPerformed(ActionEvent e) {
    JPanel p = new JPanel(new BorderLayout());
    JPanel p1 = new JPanel();
    JButton m_new = new JButton("New");
    m_new.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        JPanel p2 = new JPanel(new VerticalFlowLayout());
        JPanel p3 = new JPanel(new BorderLayout());
        JPanel p4 = new JPanel(new BorderLayout());
        JPanel p5 = new JPanel(new BorderLayout());
        JPanel p6 = new JPanel(new BorderLayout());
        String[] st = {"Boundary_Condition","Rigid_Body"};
        JComboBox cb_type = new JComboBox(st);
        JTextField tf_name = new JTextField("Fixed"+id_color);
        JTextField tf_disc = new JTextField();
        JButton b_col = new JButton();
        b_col.addActionListener(new java.awt.event.ActionListener() {
          public void actionPerformed(ActionEvent e) {
            Color cl = JColorChooser.showDialog(getFrame(PanelInspector),"Pick a Color",getColorLine(id_color));
            if(cl!=null)((JButton)e.getSource()).setBackground(cl);
          }
        });
        b_col.setBackground(getColorLine(id_color));
        p2.add(p3);
        p3.add(new JLabel("Type of constraint"), BorderLayout.WEST);
        p3.add(cb_type, BorderLayout.CENTER);
        p2.add(p4);
        p4.add(new JLabel("Name"),  BorderLayout.WEST);
        p4.add(tf_name,  BorderLayout.CENTER);
        p2.add(p5, null);
        p5.add(new JLabel("Description"), BorderLayout.WEST);
        p5.add(tf_disc, BorderLayout.CENTER);
        p2.add(p6);
        p6.add(new JLabel("Color"), BorderLayout.WEST);
        p6.add(b_col, BorderLayout.CENTER);
        int result = JOptionPane.showOptionDialog(getFrame(PanelInspector),p2,"New Constraints",JOptionPane.YES_NO_OPTION,JOptionPane.PLAIN_MESSAGE,null,null,null);
        if(result!=0) return;
        id_color++;
        Constraints con = new Constraints();
        con.name=tf_name.getText();
        con.type=cb_type.getSelectedItem()+"";
        con.color=b_col.getBackground();
        con.description=tf_disc.getText();
        ConstDB.put(tf_name.getText(),con);
        ConstTable.revalidate();
      }
    });
    JButton m_del = new JButton("Delete");
    m_del.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        int[] sel = ConstTable.getSelectedRows();
        String[] sel_st = new String[sel.length];
        for(int i=0; i<sel.length; i++){
          sel_st[i]=ConstTable.getValueAt(sel[i],0)+"";
        }
        for(int i=0; i<sel.length; i++){
          ConstDB.remove(sel_st[i]);
        }
        ConstTable.revalidate();
      }
    });
    JScrollPane spl = new JScrollPane();
    p.add(spl, BorderLayout.CENTER);
    p.add(p1, BorderLayout.NORTH);
    p1.add(m_new);
    p1.add(m_del);
    spl.getViewport().add(ConstTable);
    JOptionPane.showMessageDialog(getFrame(PanelInspector), p, "Constraints",JOptionPane.PLAIN_MESSAGE);
    //if(result!=0) load_constraints(); else save_constraints();
  }

  void b_loads_actionPerformed(ActionEvent e) {
    JPanel p = new JPanel(new BorderLayout());
    JPanel p1 = new JPanel();
    JButton m_new = new JButton("New");
    m_new.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        JPanel p2 = new JPanel(new VerticalFlowLayout());
        JPanel p3 = new JPanel(new BorderLayout());
        JPanel p4 = new JPanel(new BorderLayout());
        JPanel p5 = new JPanel(new BorderLayout());
        JPanel p6 = new JPanel(new BorderLayout());
        //String[] st = {"Boundary_Condition","Rigid_Body"};
        //JComboBox cb_type = new JComboBox(st);
        JTextField tf_name = new JTextField("Force"+id_color);
        JTextField tf_disc = new JTextField();
        JButton b_col = new JButton();
        b_col.addActionListener(new java.awt.event.ActionListener() {
          public void actionPerformed(ActionEvent e) {
            Color cl = JColorChooser.showDialog(getFrame(PanelInspector),"Pick a Color",getColorLine(id_color));
            if(cl!=null)((JButton)e.getSource()).setBackground(cl);
          }
        });
        b_col.setBackground(getColorLine(id_color));
        p2.add(p3);
        //p3.add(new JLabel("Type of constraint"), BorderLayout.WEST);
        //p3.add(cb_type, BorderLayout.CENTER);
        p2.add(p4);
        p4.add(new JLabel("Name"),  BorderLayout.WEST);
        p4.add(tf_name,  BorderLayout.CENTER);
        p2.add(p5, null);
        p5.add(new JLabel("Description"), BorderLayout.WEST);
        p5.add(tf_disc, BorderLayout.CENTER);
        p2.add(p6);
        p6.add(new JLabel("Color"), BorderLayout.WEST);
        p6.add(b_col, BorderLayout.CENTER);
        int result = JOptionPane.showOptionDialog(getFrame(PanelInspector),p2,"New Loads",JOptionPane.YES_NO_OPTION,JOptionPane.PLAIN_MESSAGE,null,null,null);
        if(result!=0) return;
        id_color++;
        Loads ld = new Loads();
        ld.name=tf_name.getText();
        ld.color=b_col.getBackground();
        ld.description=tf_disc.getText();
        LoadDB.put(tf_name.getText(),ld);
        LoadTable.revalidate();
      }
    });
    JButton m_del = new JButton("Delete");
    m_del.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        int[] sel = LoadTable.getSelectedRows();
        String[] sel_st = new String[sel.length];
        for(int i=0; i<sel.length; i++){
          sel_st[i]=LoadTable.getValueAt(sel[i],0)+"";
        }
        for(int i=0; i<sel.length; i++){
          LoadDB.remove(sel_st[i]);
        }
        LoadTable.revalidate();
      }
    });
    JScrollPane spl = new JScrollPane();
    p.add(spl, BorderLayout.CENTER);
    p.add(p1, BorderLayout.NORTH);
    p1.add(m_new);
    p1.add(m_del);
    spl.getViewport().add(LoadTable);
    JOptionPane.showMessageDialog(getFrame(PanelInspector), p, "Loads", JOptionPane.PLAIN_MESSAGE);
    //if(result!=0) load_loads(); else save_loads();
  }
  
  public void showEditPanel(MouseEvent e) {
    if(e.getClickCount()==2){
      TreePath tp = Tree.getSelectionPath();
      if(tp==null)return;
      Object[] obj = tp.getPath();
      for(int j=0; j<obj.length; j++){
        Object uobj = ((DefaultMutableTreeNode)obj[j]).getUserObject();
        if(uobj instanceof _Object){
          p_cmd.removeAll();
          edit_panel = (_Object)uobj;
          p_cmd.add(edit_panel.getEditPanel(J3D,this),BorderLayout.CENTER);
          p_cmd.validate();
          PanelInspector.validate();
        }
      }
    }
  }
  
  public void showEditPanel() {
    TreePath tp = Tree.getSelectionPath();
    if(tp==null)return;
    Object[] obj = tp.getPath();
    for(int j=0; j<obj.length; j++){
      Object uobj = ((DefaultMutableTreeNode)obj[j]).getUserObject();
      if(uobj instanceof _Object){
        p_cmd.removeAll();
        p_cmd.add(((_Object)uobj).getEditPanel(J3D,this),BorderLayout.CENTER);
        p_cmd.validate();
        PanelInspector.validate();
      }
    }
  }

  public void resetselect() {
    TreePath[] tp = Tree.getSelectionPaths();
    if(tp==null)return;
    J3D.remove_select();
    for(int i=0; i<tp.length; i++){
      DefaultMutableTreeNode tn = (DefaultMutableTreeNode)tp[i].getLastPathComponent();
      Object obj = tn.getUserObject();
      if(obj instanceof _Object)  ((_Object)obj).Select(tp[i]+"");
    }
  }

  void b_savemodel_actionPerformed(ActionEvent e) {
    float merge_distance = -1;
    float dist;
    int current_master_type;
    boolean merge = false;
    boolean merged = false;
    _Node a,b;
    String file_in;
    FileDialog fd = new FileDialog(getFrame(this),"Save model *.in",FileDialog.SAVE);
    fd.setDirectory(".");
    fd.setFile("*.in");
    fd.show();
    file_in = fd.getDirectory()+fd.getFile();
    if(fd.getFile()!=null){
      if(!file_in.endsWith(".in"))file_in+=".in";
    }else return;
    Frame frame = getFrame(this);
    String frame_title = frame.getTitle();
    String st_model="# Created Impact "+ver+"\n# "+new Date()+"\n\nCONTROLS\nrun from "+CONTROLS_RUN_FROM+" to "+CONTROLS_RUN_TO+(CONTROLS_RUN_STEP.trim().length()!=0?" step "+CONTROLS_RUN_STEP:"")+"\nprint every "+CONTROLS_PRINT_STEP+" step\n"+(CONTROLS_PRINT_TRACKER_STEP.trim().length()!=0?"Print TRACKER every "+CONTROLS_PRINT_TRACKER_STEP+" step":"")+"\n\n",
    st_nodes="NODES\n",
    st_elements="",
    st_elements_Rod_2="ELEMENTS OF TYPE Rod_2\n",
    st_elements_Beam_2="ELEMENTS OF TYPE Beam_2\n",
    st_elements_Beam_Spring_2="ELEMENTS OF TYPE Beam_Spring_2\n",
    st_elements_Contact_Line="ELEMENTS OF TYPE Contact_Line\n",
    st_elements_Contact_Triangle="ELEMENTS OF TYPE Contact_Triangle\n",
    st_elements_Shell_C0_3="ELEMENTS OF TYPE Shell_C0_3\n",
    st_elements_Shell_BT_4="ELEMENTS OF TYPE Shell_BT_4\n",
    st_elements_Solid_Iso_6="ELEMENTS OF TYPE Solid_Iso_6\n";
    

    // Merge nodes
    _Node[] narr = J3D.getAllNodes3D();
    String s = JOptionPane.showInputDialog("Enter node merge distance\nor select Cancel to prevent merging",new Float(Canvas3D.NODE_MERGE_TOLERANCE));

    merge_distance = new Float(s).floatValue();
    
    if (merge_distance >= 0) merge = true;

    if (merge) {
        
        merge_distance = merge_distance * merge_distance;
        
        for (int i = 0; i < narr.length; i++) {
            merged = false;
            a = (_Node) narr[i];
            a.setMerged_reference(a);
            current_master_type = a.getMaster_type();
            for (int j = 0; j < narr.length; j++)
                if (i != j) {
                    b = (_Node) narr[j];
                    dist = (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y) + (a.z - b.z)*(a.z - b.z);
                    if (dist <= merge_distance) {
                        if (b.getMaster_type() < current_master_type) {
                            a.setMerged_reference(b);
                            current_master_type = b.getMaster_type();
                            merged = true;
                        }
                        else if (b.getMaster_type() == current_master_type && j < i && !merged) {
                            a.setMerged_reference(b);
                            merged = true;
                        }
                    }
                }
        }
    }
    
    // Create printout of nodes
    _Object[] arr = J3D.getAllObjects3D();
    for(int i=0; i<arr.length; i++){
        _Node[] arr_nodes = arr[i].get_Nodes();
        frame.setTitle(" Prepare Object - "+arr[i]+"   Nodes - "+(arr_nodes!=null?arr_nodes.length:0));
        if(arr_nodes!=null) 
            for(int j=0; j<arr_nodes.length; j++){
                // Replace node with reference if merged is wanted
                if(merge) arr_nodes[j] = arr_nodes[j].getMerged_reference();
            //frame.setTitle(" Object - "+i+"   Node - "+j);
            String st = "<"+arr_nodes[j].get_Id()+"> \tX = "+arr_nodes[j].x+" \tY = "+arr_nodes[j].y+" \tZ = "+arr_nodes[j].z;
            if(arr_nodes[j].constraint!=null) st+=" \tConstraint = "+arr_nodes[j].constraint.name;
            if(arr_nodes[j].load!=null) st+=" \tLoad = "+arr_nodes[j].load.name;
            if(arr_nodes[j].M!=null) st+=" \tM = "+arr_nodes[j].M;
            if(arr_nodes[j].Ixx!=null) st+=" \tIxx = "+arr_nodes[j].Ixx;
            if(arr_nodes[j].Iyy!=null) st+=" \tIyy = "+arr_nodes[j].Iyy;
            if(arr_nodes[j].Izz!=null) st+=" \tIzz = "+arr_nodes[j].Izz;
            if(arr_nodes[j].Ixy!=null) st+=" \tIxy = "+arr_nodes[j].Ixy;
            if(arr_nodes[j].Iyz!=null) st+=" \tIyz = "+arr_nodes[j].Iyz;
            if(arr_nodes[j].Ixz!=null) st+=" \tIxz = "+arr_nodes[j].Ixz;
            st+="\n";
            if(st_nodes.indexOf("<"+arr_nodes[j].get_Id()+">")==-1)st_nodes+=st;
        }
    }
    
    
    // Create printout of elements
    for(int i=0; i<arr.length; i++){
      _Object[] arr_elements = arr[i].get_Elements();
      frame.setTitle(" Prepare Object - "+arr[i]+"   Elements - "+(arr_elements!=null?arr_elements.length:0));
      if(arr_elements!=null)for(int j=0; j<arr_elements.length; j++){
        //frame.setTitle(" Object - "+i+"   Element - "+j);
        String st = "@"+arr_elements[j].get_Id()+"@";
        ////--------------------------------------
        if(arr_elements[j] instanceof _Element2 && ((_Element2)arr_elements[j]).msh_type==Canvas3D.MESH_Beam_2){
          _Element2 el = (_Element2)arr_elements[j];
          if (merge) st+=" \tnodes = [<"+el.node1.getMerged_reference().get_Id()+">,<"+el.node2.getMerged_reference().get_Id()+">] \tD = "+el.diameter+"\tMaterial = "+el.material.name+"\n";
          else st+=" \tnodes = [<"+el.node1.get_Id()+">,<"+el.node2.get_Id()+">] \tD = "+el.diameter+"\tMaterial = "+el.material.name+"\n";
          st_elements_Beam_2+=st;
        }else if(arr_elements[j] instanceof _Element2 && ((_Element2)arr_elements[j]).msh_type==Canvas3D.MESH_Contact_Line){
          _Element2 el = (_Element2)arr_elements[j];
          if (merge) st+=" \tnodes = [<"+el.node1.getMerged_reference().get_Id()+">,<"+el.node2.getMerged_reference().get_Id()+">] \tD = "+el.diameter;
          else st+=" \tnodes = [<"+el.node1.get_Id()+">,<"+el.node2.get_Id()+">] \tD = "+el.diameter;
          if(el.factor!=null) st+=" \tFactor = "+el.factor;
          if(el.friction!=null) st+=" \tFriction = "+el.friction;
          if(el.contact.compareToIgnoreCase("OFF")==0) st+=" \tContact = OFF";
          st_elements_Contact_Line+=st+"\n";
        }else if(arr_elements[j] instanceof _Element2 && ((_Element2)arr_elements[j]).msh_type==Canvas3D.MESH_Rod_2){
          _Element2 el = (_Element2)arr_elements[j];
          if (merge) st+=" \tnodes = [<"+el.node1.getMerged_reference().get_Id()+">,<"+el.node2.getMerged_reference().get_Id()+">] \tD = "+el.diameter+"\tMaterial = "+el.material.name;
          else st+=" \tnodes = [<"+el.node1.get_Id()+">,<"+el.node2.get_Id()+">] \tD = "+el.diameter+"\tMaterial = "+el.material.name;
          if(el.factor!=null) st+=" \tFactor = "+el.factor;
          if(el.friction!=null) st+=" \tFriction = "+el.friction;
          if(el.contact!=null && el.contact.compareToIgnoreCase("OFF")==0) st+=" \tContact = OFF";
          st_elements_Rod_2+=st+"\n";
        }else if(arr_elements[j] instanceof _Element3 && ((_Element3)arr_elements[j]).msh_type==Canvas3D.MESH_Contact_Triangle){
          _Element3 el = (_Element3)arr_elements[j];
          if(merge) st+=" \tnodes = [<"+el.node1.getMerged_reference().get_Id()+">,<"+el.node2.getMerged_reference().get_Id()+">,<"+el.node3.getMerged_reference().get_Id()+">] \tT = "+el.thickness;
          else st+=" \tnodes = [<"+el.node1.get_Id()+">,<"+el.node2.get_Id()+">,<"+el.node3.get_Id()+">] \tT = "+el.thickness;
          if(el.factor!=null) st+=" \tFactor = "+el.factor;
          if(el.friction!=null) st+=" \tFriction = "+el.friction;
          st_elements_Contact_Triangle+=st+"\n";
        }else if(arr_elements[j] instanceof _Element3 && ((_Element3)arr_elements[j]).msh_type==Canvas3D.MESH_Shell_C0_3){
          _Element3 el = (_Element3)arr_elements[j];
          if(merge) st+=" \tnodes = [<"+el.node1.getMerged_reference().get_Id()+">,<"+el.node2.getMerged_reference().get_Id()+">,<"+el.node3.getMerged_reference().get_Id()+">] \tT = "+el.thickness+" \tMaterial = "+el.material.name;
          else st+=" \tnodes = [<"+el.node1.get_Id()+">,<"+el.node2.get_Id()+">,<"+el.node3.get_Id()+">] \tT = "+el.thickness+" \tMaterial = "+el.material.name;
          if(el.NIP!=null) st+=" \tNIP = "+el.NIP;
          if(el.PIP!=null) st+=" \tPIP = "+el.PIP;
          if(el.load!=null) st+=" \tLoad = "+el.load.name;
          if(el.factor!=null) st+=" \tFactor = "+el.factor;
          if(el.contact!=null && el.contact.length()!=0) st+=" \tContact = "+el.contact;
          if(el.friction!=null) st+=" \tFriction = "+el.friction;
          if(el.thinning!=null && el.thinning.compareToIgnoreCase("OFF")==0) st+=" \tThinning = OFF";
          st_elements_Shell_C0_3+=st+"\n";
        }else if(arr_elements[j] instanceof _Element4){
          _Element4 el = (_Element4)arr_elements[j];
          if(merge) st+=" \tnodes = [<"+el.node1.getMerged_reference().get_Id()+">,<"+el.node2.getMerged_reference().get_Id()+">,<"+el.node3.getMerged_reference().get_Id()+">,<"+el.node4.getMerged_reference().get_Id()+">] \tT = "+el.thickness+" \tMaterial = "+el.material.name;
          else st+=" \tnodes = [<"+el.node1.get_Id()+">,<"+el.node2.get_Id()+">,<"+el.node3.get_Id()+">,<"+el.node4.get_Id()+">] \tT = "+el.thickness+" \tMaterial = "+el.material.name;
          if(el.NIP!=null) st+=" \tNIP = "+el.NIP;
          if(el.PIP!=null) st+=" \tPIP = "+el.PIP;
          if(el.load!=null) st+=" \tLoad = "+el.load.name;
          if(el.factor!=null) st+=" \tFactor = "+el.factor;
          if(el.contact!=null && el.contact.length()!=0) st+=" \tContact = "+el.contact;
          if(el.friction!=null) st+=" \tFriction = "+el.friction;
          if(el.thinning!=null && el.thinning.compareToIgnoreCase("OFF")==0) st+=" \tThinning = OFF";
          if(el.shear_factor!=null) st+=" \tSHEAR_FACTOR = "+el.shear_factor;
          if(el.hourglass!=null && el.hourglass.compareToIgnoreCase("OFF")==0) st+=" \tHOURGLASS = OFF";
          if(el.MHC!=null) st+=" \tMHC = "+el.MHC;
          if(el.OOPHC!=null) st+=" \tOOPHC = "+el.OOPHC;
          if(el.RHC!=null) st+=" \tRHC = "+el.RHC;
          st_elements_Shell_BT_4+=st+"\n";
        }else if(arr_elements[j] instanceof _Element8){
          _Element8 el = (_Element8)arr_elements[j];
          if(merge) st+=" \tnodes = [<"+el.node1.getMerged_reference().get_Id()+">,<"+el.node2.getMerged_reference().get_Id()+">,<"+el.node3.getMerged_reference().get_Id()+">,<"+el.node4.getMerged_reference().get_Id()+">,<"+el.node5.getMerged_reference().get_Id()+">,<"+el.node6.getMerged_reference().get_Id()+">,<"+el.node7.getMerged_reference().get_Id()+">,<"+el.node8.getMerged_reference().get_Id()+">] \tNIP = 8 \tMaterial = "+el.material.name+"\n";
          else st+=" \tnodes = [<"+el.node1.get_Id()+">,<"+el.node2.get_Id()+">,<"+el.node3.get_Id()+">,<"+el.node4.get_Id()+">,<"+el.node5.get_Id()+">,<"+el.node6.get_Id()+">,<"+el.node7.get_Id()+">,<"+el.node8.get_Id()+">] \tNIP = 8 \tMaterial = "+el.material.name+"\n";
          st_elements_Solid_Iso_6+=st;
        }
      }
    }
    st_elements=(st_elements_Rod_2.length()>35?st_elements_Rod_2+"\n\n":"")
               +(st_elements_Beam_2.length()>35?st_elements_Beam_2+"\n\n":"")
               +(st_elements_Beam_Spring_2.length()>35?st_elements_Beam_Spring_2+"\n\n":"")
               +(st_elements_Contact_Line.length()>35?st_elements_Contact_Line+"\n\n":"")
               +(st_elements_Contact_Triangle.length()>35?st_elements_Contact_Triangle+"\n\n":"")
               +(st_elements_Shell_C0_3.length()>35?st_elements_Shell_C0_3+"\n\n":"")
               +(st_elements_Shell_BT_4.length()>35?st_elements_Shell_BT_4+"\n\n":"")
               +(st_elements_Solid_Iso_6.length()>35?st_elements_Solid_Iso_6:"");
    int k=1;
    for(int i=0; i<arr.length; i++){
      _Object[] arr_elements = arr[i].get_Elements();
      frame.setTitle(" Prepare Object - "+arr[i]+"   Elements - "+(arr_elements!=null?arr_elements.length:0));
      if(arr_elements!=null) for(int j=0; j<arr_elements.length; j++){
        //frame.setTitle(" Object - "+i+"   Element - "+j);
        String st = "@"+arr_elements[j].get_Id()+"@";
        st_elements = st_elements.replaceAll(st,(k++)+"");
      }
    }
    for(Enumeration en = MatDB.keys(); en.hasMoreElements();){
      String key = en.nextElement()+"";
      //frame.setTitle(" Material - "+key);
      Material mat = (Material)MatDB.get(key);
      String st = "MATERIALS OF TYPE "+mat.type+"\n"+mat.name+" "+mat.description+"\n\n";
      if(st_elements.indexOf("Material = "+mat.name)!=-1)st_model+=st;
    }
    for(Enumeration en = ConstDB.keys(); en.hasMoreElements();){
      String key = en.nextElement()+"";
      //frame.setTitle(" Constraints - "+key);
      Constraints con = (Constraints)ConstDB.get(key);
      String st = "CONSTRAINTS OF TYPE "+con.type+"\n"+con.name+" "+con.description+"\n\n";
      if(st_nodes.indexOf("Constraint = "+con.name)!=-1)st_model+=st;
    }
    for(Enumeration en = LoadDB.keys(); en.hasMoreElements();){
      String key = en.nextElement()+"";
      //frame.setTitle(" Loads - "+key);
      Loads ld = (Loads)LoadDB.get(key);
      String st = "LOADS "+"\n"+ld.name+" "+ld.description+"\n\n";
      if(st_nodes.indexOf("Load = "+ld.name)!=-1 || st_elements.indexOf("Load = "+ld.name)!=-1)st_model+=st;
    }
    st_model+=st_nodes+"\n\n"+st_elements;
    k=1;
    for(int i=0; i<arr.length; i++){
      _Node[] arr_nodes = arr[i].get_Nodes();
      frame.setTitle(" Prepare Object - "+arr[i]+"   Nodes - "+(arr_nodes!=null?arr_nodes.length:0));
      if(arr_nodes!=null) for(int j=0; j<arr_nodes.length; j++){
        //frame.setTitle(" Object - "+i+"   Node - "+j);
        String st = "<"+arr_nodes[j].get_Id()+">";
        st_model = st_model.replaceAll(st,(k++)+"");
      }
    }
    frame.setTitle(" Write model to "+file_in);
    try{
      File f = new File(file_in);
      f.delete();
      RandomAccessFile fout = new RandomAccessFile(f,"rw");
      fout.writeBytes(st_model);
      fout.close();
    }catch(Exception ex){error(ex);}
    frame.setTitle("");
  }

  /**
   * This method goes through the Canvas 3D view and checks with _Objects that
   * are selected. If an object is found, all occurances of this object in the
   * tree is selected.
   * 
   * A block variable is set during this update to avoid triggering of the 
   * SelectionChanged event for each change.
   *
   */
  
  public void rescanTree() {
      Object obj;
      TreePath tp = Tree.getPathForRow(0);
      Vector tps = new Vector();
      TreePath[] ftps;
      
      if (tp == null) return;
      
      DefaultMutableTreeNode tn = (DefaultMutableTreeNode)tp.getPathComponent(0);
      Enumeration en = tn.depthFirstEnumeration();
      
      block = true;
      
      while (en.hasMoreElements()) {
          tn = (DefaultMutableTreeNode)en.nextElement();
          obj = tn.getUserObject();
          if(obj instanceof _Object)
              if (((_Object)obj).isSelected()) {
                  tps.add(new TreePath(tn.getPath()));
              }
      }

      ftps = new TreePath[tps.size()];
      
      for (int i=0; i < ftps.length; i++) {
          ftps[i] = (TreePath)tps.elementAt(i);
          Tree.expandPath(ftps[i]);
      }
      
      Tree.addSelectionPaths(ftps);
      
      block = false;
      
      Tree.repaint();
  }

  /**
   * 
   * This method goes through the tree and checks which nodes that have
   * been selected. If a node is selected, the corresponding _Object is
   * set as selected in the canvas3D view.
   * Finally, the view is redrawn.
   * 
   * @param e TreeSelectionEvent
   */
  
  public void treeSelectionChanged() {
          J3D.remove_select();
          TreePath[] tp = Tree.getSelectionPaths();
          if(tp==null)return;
          for(int i=0; i<tp.length; i++){
              DefaultMutableTreeNode tn = (DefaultMutableTreeNode)tp[i].getLastPathComponent();
              Object obj = tn.getUserObject();
              int count = 0;
              if(obj instanceof _Object){ ((_Object)obj).Select(tp[i]+""); count++; }
              /* 
               int lev = tn.getLevel();
               while((tn=tn.getNextNode())!=null && lev<tn.getLevel()){
               obj = tn.getUserObject();
               if(obj instanceof _Object){ ((_Object)obj).Select(tp[i]+""); count++; }
               }
               */
              if(count==0){
                  obj = ((DefaultMutableTreeNode)tp[i].getParentPath().getLastPathComponent()).getUserObject();
                  if(obj instanceof _Object) ((_Object)obj).Select(tp[i]+"");
              }
          }
          J3D.view_reset();
  }
  
 public void clearTree() {
     Tree.clearSelection();
 }
 
 public void message(String m) {
     Frame f = getFrame(this);
     f.setTitle(m);
 }
 
 public void requestAction() {
     if (edit_panel != null)
         edit_panel.requestAction();

 }
 
}