
    public static Path TESTS_DEVICES_DEFAULT_DIR = Paths.get(".", "home", "script", "tests", "devices");
    public static Path TESTS_TESTS_DEFAULT_DIR = Paths.get(".", "home", "script", "tests", "tests");
    public static Path TESTS_CONFIG_DEFAULT_DIR = Paths.get(".", "home", "script", "tests", "config");
    public static String TESTS_CONFIG_FILENAME = ".config";
    public static String TESTS_HELP_FILENAME = "help.html";
    public static Path TEMPLATES_HELP_FILEPATH   = Paths.get(".", "home", "script", "tests","templates","helpTemplate.html");
    public static Path TEMPLATES_TEST_FILEPATH   = Paths.get(".", "home", "script", "tests","templates","testTemplate.html");
    public static Path TEMPLATES_CONFIG_FILEPATH = Paths.get(".", "home", "script", "tests","templates","configTemplate.html");

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jLabel4 = new javax.swing.JLabel();
        txtTestSuite = new javax.swing.JTextField();
        jLabel5 = new javax.swing.JLabel();
        txtTestName = new javax.swing.JTextField();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTableParams = new javax.swing.JTable();
        jLabel7 = new javax.swing.JLabel();
        cmCancel = new javax.swing.JButton();
        cmOk = new javax.swing.JButton();
        jLabel8 = new javax.swing.JLabel();
        jScrollPane3 = new javax.swing.JScrollPane();
        txtTestDescription = new javax.swing.JTextArea();
        jScrollPane4 = new javax.swing.JScrollPane();
        jEditorPaneHelp = new javax.swing.JEditorPane();

        jLabel4.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        jLabel4.setText("Test Case/Suite");

        txtTestSuite.setEditable(false);
        txtTestSuite.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N

        jLabel5.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        jLabel5.setText("Test Name");

        txtTestName.setEditable(false);
        txtTestName.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N

        jTableParams.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        jTableParams.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Parameter", "Value", "Description"
            }
        ) {
            boolean[] canEdit = new boolean [] {
                false, true, false
            };

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        jTableParams.setDragEnabled(true);
        jTableParams.setRowHeight(20);
        jScrollPane1.setViewportView(jTableParams);
        if (jTableParams.getColumnModel().getColumnCount() > 0) {
            jTableParams.getColumnModel().getColumn(0).setMinWidth(150);
            jTableParams.getColumnModel().getColumn(0).setPreferredWidth(150);
            jTableParams.getColumnModel().getColumn(0).setMaxWidth(150);
            jTableParams.getColumnModel().getColumn(1).setPreferredWidth(80);
            jTableParams.getColumnModel().getColumn(1).setMaxWidth(100);
        }

        jLabel7.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        jLabel7.setText("Test Parameters");

        cmCancel.setText("Close");
        this.cmCancel.setVisible(false);
        this.cmOk.setVisible(false);
        cmCancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmCancelActionPerformed(evt);
            }
        });

        cmOk.setText("Generate");
        this.cmCancel.setVisible(false);
        this.cmOk.setVisible(false);
        cmOk.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmOkActionPerformed(evt);
            }
        });

        jLabel8.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        jLabel8.setText("Test Description");

        jScrollPane3.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N

        txtTestDescription.setEditable(false);
        txtTestDescription.setColumns(20);
        txtTestDescription.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        txtTestDescription.setLineWrap(true);
        txtTestDescription.setRows(5);
        jScrollPane3.setViewportView(txtTestDescription);

        jEditorPaneHelp.setContentType("text/html"); // NOI18N
        jEditorPaneHelp.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        jEditorPaneHelp.setDropMode(javax.swing.DropMode.INSERT);
        jScrollPane4.setViewportView(jEditorPaneHelp);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel5)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel7)
                            .addComponent(jLabel8))
                        .addGap(19, 19, 19)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(txtTestName)
                            .addComponent(jScrollPane3)
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 513, Short.MAX_VALUE)
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                                .addComponent(cmOk, javax.swing.GroupLayout.PREFERRED_SIZE, 96, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(cmCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 98, javax.swing.GroupLayout.PREFERRED_SIZE))))
                    .addComponent(jLabel4)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(118, 118, 118)
                        .addComponent(txtTestSuite)))
                .addGap(18, 18, 18)
                .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 317, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel5)
                            .addComponent(txtTestName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel4)
                            .addComponent(txtTestSuite, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel8)
                            .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel7)
                                .addGap(0, 135, Short.MAX_VALUE))
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(cmCancel)
                            .addComponent(cmOk)))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jScrollPane4)
                        .addContainerGap())))
        );
    }// </editor-fold>                        

    private void fillComponents(HashMap hDetails) {
        //add values to each text box
        //help text
        showHelp(String.valueOf(hDetails.get("testPath")), String.valueOf(hDetails.get("testHelp")));
        //parameters table
        HashMap hParams = (HashMap) hDetails.get("parameters");
        String name="", value="", description="";
        DefaultTableModel model = (DefaultTableModel) jTableParams.getModel();

       for(Object entry : hParams.keySet()){
            Object param = entry;
            if(param instanceof String){
                name = (String) param;
                HashMap attributes = (HashMap) hParams.get(param);
                value = (String) attributes.get("value");
                description = (String) attributes.get("description");
                model.addRow(new Object[]{name, value, description});
            }
            jTableParams.setModel(model);
        }     
    }
    
     //load and show help
    private void showHelp(String sTestPath, String sHelpText){
        this.jEditorPaneHelp.addHyperlinkListener(new HyperlinkListener() {
            @Override
            public void hyperlinkUpdate(HyperlinkEvent hle) {
                if (HyperlinkEvent.EventType.ACTIVATED.equals(hle.getEventType())) {
                    System.out.println(hle.getURL());
                    Desktop desktop = Desktop.getDesktop();
                    try {
                        desktop.browse(hle.getURL().toURI());
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }
        });       
        this.jEditorPaneHelp.setEditable(false);
        //if there is no input, exit
        if(sTestPath == "" && sHelpText == ""){
            return;
        }
        File fTest = new File(sTestPath);
        String sParentPath = fTest.getParent().toString();
        File fHelp = new File(FilenameUtils.separatorsToSystem(sParentPath + "/help.html"));
        
        if(fHelp.isFile()){//if local help file existis:
            try {
                this.jEditorPaneHelp.setPage(fHelp.toURI().toURL());
            } catch (IOException ex) {
                this.jEditorPaneHelp.setText(String.valueOf(ex));
            }
        } else {  //help.html file is present. see if a plain text has been given from .config file    
            if(sHelpText.isEmpty() || sHelpText == "null"){
                this.jEditorPaneHelp.setText("[No help available]");
                //this.jEditorPaneHelp.setVisible(false);
            }else {
                this.jEditorPaneHelp.setText(sHelpText);
            }
        }      
    }

    private void cmCancelActionPerformed(java.awt.event.ActionEvent evt) {                                         
        
    }                                        

    private void cmOkActionPerformed(java.awt.event.ActionEvent evt) {                                     
        // TODO add your handling code here:
    }                                    

    public void generateTestFiles(){
        HashMap hmTestParams = new HashMap();
        generateTestFiles(this.txtTestName.getText(), 
                          this.txtTestDescription.getText(), 
                          this.txtTestSuite.getText(), 
                          hmTestParams);
    }
    
    public void generateTestFiles(String sTestName,
                                  String sTestDescription,
                                  String sTestSuite,
                                  HashMap hmTestParams){
            if (!TESTS_TESTS_DEFAULT_DIR.toFile().isDirectory()) {
                //check that the tests suite dir exists. If not, create it
                Path testSuiteDir = Paths.get(TESTS_TESTS_DEFAULT_DIR.toString(),sTestSuite);
                if( !testSuiteDir.toFile().isDirectory()){
                    boolean success = testSuiteDir.toFile().mkdirs();
                    if (!success) {
                        // Directory creation failed
                        SwingUtils.showMessage(this, "saveSettings()", "Cannot create directory " + testSuiteDir.toString());
                    }else{
                        //new test directory inside tests suite dir
                        Path testDir = Paths.get(testSuiteDir.toString(),sTestName);
                        success = testDir.toFile().mkdirs();
                        if (!success) {
                            // Directory creation failed
                            SwingUtils.showMessage(this, "saveSettings()", "Cannot create directory " + testDir.toString());
                        } else{
                            //generate test files inside test dir
                            generateTestConfig(testDir,
                                            sTestName,
                                            sTestDescription,
                                            sTestSuite,
                                            hmTestParams);
                        }
                    }
                }
            }
    }
    
    public void generateTestScript(String sTestName,
                                  String sTestDescription,
                                  String sTestSuite,
                                  HashMap hmTestParams){
        
    }

    public void generateTestConfig(Path testDir,
                                    String sTestName,
                                    String sTestDescription,
                                    String sTestSuite,
                                    HashMap hmTestParams){
        //generate test config file from template                 
        try {        
            Path path = Paths.get(testDir + FilenameUtils.separatorsToSystem("/"+TESTS_CONFIG_FILENAME));
            Files.copy(TEMPLATES_CONFIG_FILEPATH, path);
            File configFile = path.toFile();
            Properties properties = new Properties();
            properties.setProperty("name", sTestName);
            properties.setProperty("description", sTestDescription);
            OutputStream is = new FileOutputStream(configFile);
            properties.store(is, "Test config");
            is.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(NewTest.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(NewTest.class.getName()).log(Level.SEVERE, null, ex);
        }
        
    }
    
    public void generateTestHelp(Path testDir,
                                String sTestName,
                                String sTestDescription,
                                String sTestSuite,
                                HashMap hmTestParams){
        //generate test config file from template
        Path path = Paths.get(testDir + FilenameUtils.separatorsToSystem("/"+TESTS_HELP_FILENAME));
        try {
            Files.copy(TEMPLATES_HELP_FILEPATH, path);
            File configFile = path.toFile();
        } catch (IOException ex) {
            Logger.getLogger(NewTest.class.getName()).log(Level.SEVERE, null, ex);
        }
    }