/*******************************************************************************
 *
 * Pentaho Data Integration
 *
 * Copyright (C) 2002-2012 by Pentaho : http://www.pentaho.com
 *
 *******************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ******************************************************************************/

package org.pentaho.di.ui.trans.steps.scriptvalues_mod;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabFolder2Adapter;
import org.eclipse.swt.custom.CTabFolderEvent;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.TreeEditor;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceAdapter;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.mozilla.javascript.CompilerEnvirons;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ContextFactory;
import org.mozilla.javascript.ErrorReporter;
import org.mozilla.javascript.EvaluatorException;
import org.mozilla.javascript.JavaScriptException;
import org.mozilla.javascript.NodeTransformer;
import org.mozilla.javascript.Parser;
import org.mozilla.javascript.Script;
import org.mozilla.javascript.ScriptOrFnNode;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.tools.ToolErrorReporter;
import org.pentaho.di.compatibility.Row;
import org.pentaho.di.compatibility.Value;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.Props;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.plugins.PluginRegistry;
import org.pentaho.di.core.plugins.StepPluginType;
import org.pentaho.di.core.row.RowMeta;
import org.pentaho.di.core.row.RowMetaInterface;
import org.pentaho.di.core.row.ValueMeta;
import org.pentaho.di.core.row.ValueMetaInterface;
import org.pentaho.di.i18n.BaseMessages;
import org.pentaho.di.trans.Trans;
import org.pentaho.di.trans.TransHopMeta;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.step.BaseStepMeta;
import org.pentaho.di.trans.step.StepDialogInterface;
import org.pentaho.di.trans.step.StepMeta;
import org.pentaho.di.trans.steps.rowgenerator.RowGeneratorMeta;
import org.pentaho.di.trans.steps.scriptvalues_mod.ScriptValuesAddedFunctions;
import org.pentaho.di.trans.steps.scriptvalues_mod.ScriptValuesMetaMod;
import org.pentaho.di.trans.steps.scriptvalues_mod.ScriptValuesModDummy;
import org.pentaho.di.trans.steps.scriptvalues_mod.ScriptValuesScript;
import org.pentaho.di.ui.core.dialog.EnterTextDialog;
import org.pentaho.di.ui.core.dialog.ErrorDialog;
import org.pentaho.di.ui.core.dialog.PreviewRowsDialog;
import org.pentaho.di.ui.core.gui.GUIResource;
import org.pentaho.di.ui.core.widget.ColumnInfo;
import org.pentaho.di.ui.core.widget.StyledTextComp;
import org.pentaho.di.ui.core.widget.TableView;
import org.pentaho.di.ui.core.widget.TextVar;
import org.pentaho.di.ui.spoon.Spoon;
import org.pentaho.di.ui.trans.dialog.TransPreviewProgressDialog;
import org.pentaho.di.ui.trans.step.BaseStepDialog;


public class ScriptValuesModDialog extends BaseStepDialog implements StepDialogInterface
{
	private static Class<?> PKG = ScriptValuesMetaMod.class; // for i18n purposes, needed by Translator2!!   $NON-NLS-1$

	private static final String[] YES_NO_COMBO = new String[] { BaseMessages.getString(PKG, "System.Combo.No"), BaseMessages.getString(PKG, "System.Combo.Yes") };
	
	private ModifyListener lsMod;
	private SashForm     wSash;
	private FormData     fdSash;
	
	private Composite    wTop, wBottom;
	private FormData     fdTop, fdBottom;
	
	private Label        wlScript;
	private FormData     fdlScript, fdScript;

	private Label        wSeparator;
	private FormData     fdSeparator;
	
	private Label        wlFields;
	private TableView    wFields;
	private FormData     fdlFields, fdFields;
	
	private Label        wlPosition;
	private FormData     fdlPosition;
	
	private Text		wlHelpLabel;
	
	private Button wVars, wTest;
	private Listener lsVars, lsTest;
	
	// private Button wHelp;
	
	private Label		wlScriptFunctions;
	private FormData	fdlScriptFunctions;
	
	private Tree		wTree;
	private TreeItem	wTreeScriptsItem;
	private TreeItem	wTreeClassesitem;
	private	FormData	fdlTree;
	private Listener	lsTree;
	// private Listener	lsHelp;
	private FormData 	fdHelpLabel;
	
	private Image imageActiveScript=null;
	private Image imageInactiveScript=null;
	private Image imageActiveStartScript=null;
	private Image imageActiveEndScript=null;
	private Image imageInputFields=null;
	private Image imageOutputFields=null;
	private Image imageArrowOrange=null;
	private Image imageArrowGreen=null;
	private Image imageUnderGreen=null;
	private Image imageAddScript=null;
	private Image imageDeleteScript=null;
	private Image imageDuplicateScript=null;
	
	private CTabFolder 	folder;
	private Menu 		cMenu;
	private Menu 		tMenu;
	
	// Suport for Rename Tree
	private TreeItem [] lastItem;
	private TreeEditor editor;
	
	private static final int DELETE_ITEM = 0;
	private static final int ADD_ITEM = 1;
	private static final int RENAME_ITEM = 2;
	private static final int SET_ACTIVE_ITEM = 3;
	
	private static final int ADD_COPY = 2;
	private static final int ADD_BLANK = 1;
	private static final int ADD_DEFAULT = 0;
	
	
	private String strActiveScript;
	private String strActiveStartScript;
	private String strActiveEndScript;
	
	private static String[] jsFunctionList = ScriptValuesAddedFunctions.jsFunctionList;
	
	public final static int SKIP_TRANSFORMATION = 1;
	private final static int ABORT_TRANSFORMATION = -1;
	private final static int ERROR_TRANSFORMATION = -2;
	private final static int CONTINUE_TRANSFORMATION = 0;
	
	
	private ScriptValuesMetaMod input;
	private ScriptValuesHelp scVHelp;
	private ScriptValuesHighlight lineStyler = new ScriptValuesHighlight();
	private Button wCompatible;
	private TextVar wOptimizationLevel;
	
    private TreeItem iteminput;
    
    private TreeItem itemoutput;
    
	private static GUIResource guiresource=GUIResource.getInstance();
	
    private TreeItem itemWaitFieldsIn,itemWaitFieldsOut;
    
    private RowMetaInterface  rowPrevStepFields;;
    
    private RowGeneratorMeta genMeta;
		
	public ScriptValuesModDialog(Shell parent, Object in, TransMeta transMeta, String sname){

		super(parent, (BaseStepMeta)in, transMeta, sname);
		input=(ScriptValuesMetaMod)in;
		genMeta = null;
		try{
			//ImageLoader xl = new ImageLoader();
			imageUnderGreen = guiresource.getImage("ui/images/underGreen.png");
			imageArrowGreen = guiresource.getImage("ui/images/arrowGreen.png");
			imageArrowOrange = guiresource.getImage("ui/images/arrowOrange.png");
			imageInputFields = guiresource.getImage("ui/images/inSmall.png");
			imageOutputFields = guiresource.getImage("ui/images/outSmall.png");
			imageActiveScript = guiresource.getImage("ui/images/faScript.png");
			imageInactiveScript = guiresource.getImage("ui/images/hide-inactive.png");
			imageActiveStartScript = guiresource.getImage("ui/images/SQLbutton.png");
			imageActiveEndScript = guiresource.getImage("ui/images/edfScript.png");
			imageDeleteScript = guiresource.getImage("ui/images/deleteSmall.png");
			imageAddScript = guiresource.getImage("ui/images/addSmall.png");
			imageDuplicateScript = guiresource.getImage("ui/images/copySmall.png");
		}catch(Exception e){
			imageActiveScript = guiresource.getImageEmpty16x16();
			imageInactiveScript = guiresource.getImageEmpty16x16();
			imageActiveStartScript = guiresource.getImageEmpty16x16();
			imageActiveEndScript = guiresource.getImageEmpty16x16();
			imageInputFields = guiresource.getImageEmpty16x16();
			imageOutputFields = guiresource.getImageEmpty16x16();
			imageArrowOrange = guiresource.getImageEmpty16x16();
			imageArrowGreen= guiresource.getImageEmpty16x16();
			imageUnderGreen= guiresource.getImageEmpty16x16();
			imageDeleteScript= guiresource.getImageEmpty16x16();
			imageAddScript= guiresource.getImageEmpty16x16();
			imageDuplicateScript= guiresource.getImageEmpty16x16();
		}
		
        try
        {
            scVHelp = new ScriptValuesHelp("jsFunctionHelp.xml");
        }
        catch (Exception e)
        {
            new ErrorDialog(shell, "Unexpected error", "There was an unexpected error reading the javascript functions help", e);
        }
		
	}

	public String open(){
		
		Shell parent = getParent();
		Display display = parent.getDisplay();
		
		shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MAX | SWT.MIN);
 		props.setLook(shell);
        setShellImage(shell, input);
 		
		lsMod = new ModifyListener() 
		{
			public void modifyText(ModifyEvent e) 
			{
				input.setChanged();
			}
		};
		changed = input.hasChanged();

		FormLayout formLayout = new FormLayout ();
		formLayout.marginWidth  = Const.FORM_MARGIN;
		formLayout.marginHeight = Const.FORM_MARGIN;

		shell.setLayout(formLayout);
		shell.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.Shell.Title")); //$NON-NLS-1$
		
		int middle = props.getMiddlePct();
		int margin = Const.MARGIN;
		
		// Filename line
		wlStepname=new Label(shell, SWT.RIGHT);
		wlStepname.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.Stepname.Label")); //$NON-NLS-1$
		props.setLook(wlStepname);
		fdlStepname=new FormData();
		fdlStepname.left = new FormAttachment(0, 0);
		fdlStepname.right= new FormAttachment(middle, -margin);
		fdlStepname.top  = new FormAttachment(0, margin);
		wlStepname.setLayoutData(fdlStepname);
		wStepname=new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		wStepname.setText(stepname);
 		props.setLook(wStepname);
		wStepname.addModifyListener(lsMod);
		fdStepname=new FormData();
		fdStepname.left = new FormAttachment(middle, 0);
		fdStepname.top  = new FormAttachment(0, margin);
		fdStepname.right= new FormAttachment(100, 0);
		wStepname.setLayoutData(fdStepname);

		wSash = new SashForm(shell, SWT.VERTICAL );
 		
		// Top sash form
		//
		wTop = new Composite(wSash, SWT.NONE);
 		props.setLook(wTop);

		FormLayout topLayout  = new FormLayout ();
		topLayout.marginWidth  = Const.FORM_MARGIN;
		topLayout.marginHeight = Const.FORM_MARGIN;
		wTop.setLayout(topLayout);
		
		// Script line
		wlScriptFunctions=new Label(wTop, SWT.NONE);
		wlScriptFunctions.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.JavascriptFunctions.Label")); //$NON-NLS-1$
		props.setLook(wlScriptFunctions);
		fdlScriptFunctions=new FormData();
		fdlScriptFunctions.left = new FormAttachment(0, 0);
		fdlScriptFunctions.top  = new FormAttachment(0, 0);
		wlScriptFunctions.setLayoutData(fdlScriptFunctions);
				
		// Tree View Test
		wTree = new Tree(wTop, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
		props.setLook(wTree);
	    fdlTree=new FormData();
		fdlTree.left = new FormAttachment(0, 0);
		fdlTree.top  = new FormAttachment(wlScriptFunctions, margin);
		fdlTree.right = new FormAttachment(20, 0);
		fdlTree.bottom = new FormAttachment(100, -margin);
		wTree.setLayoutData(fdlTree);
		
		// Script line
		wlScript=new Label(wTop, SWT.NONE);
		wlScript.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.Javascript.Label")); //$NON-NLS-1$
		props.setLook(wlScript);
		fdlScript=new FormData();
		fdlScript.left = new FormAttachment(wTree, margin);
		fdlScript.top  = new FormAttachment(0, 0);
		wlScript.setLayoutData(fdlScript);
		
		folder = new CTabFolder(wTop, SWT.BORDER | SWT.RESIZE);
		folder.setSimple(false);
		folder.setUnselectedImageVisible(true);
		folder.setUnselectedCloseVisible(true);
		fdScript=new FormData();
		fdScript.left   = new FormAttachment(wTree, margin);
		fdScript.top    = new FormAttachment(wlScript, margin);
		fdScript.right  = new FormAttachment(100, -5);
		fdScript.bottom = new FormAttachment(100, -50);
		folder.setLayoutData(fdScript);
		
		wlPosition=new Label(wTop, SWT.NONE);
		wlPosition.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.Position.Label")); //$NON-NLS-1$
		props.setLook(wlPosition);
		fdlPosition=new FormData();
		fdlPosition.left  = new FormAttachment(wTree, margin);
		fdlPosition.right = new FormAttachment(30, 0);
		fdlPosition.top   = new FormAttachment(folder, margin);
		wlPosition.setLayoutData(fdlPosition);
		
		Label wlCompatible = new Label(wTop, SWT.NONE);
		wlCompatible.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.Compatible.Label")); //$NON-NLS-1$
		props.setLook(wlCompatible);
		FormData fdlCompatible = new FormData();
		fdlCompatible.left  = new FormAttachment(wTree, margin);
		fdlCompatible.right = new FormAttachment(middle, 0);
		fdlCompatible.top   = new FormAttachment(wlPosition, margin);
		wlCompatible.setLayoutData(fdlCompatible);
		wCompatible = new Button(wTop, SWT.CHECK);
		wCompatible.setToolTipText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.Compatible.Tooltip")); 
		props.setLook(wCompatible);
		FormData fdCompatible = new FormData();
		fdCompatible.left  = new FormAttachment(wlCompatible, margin);
		fdCompatible.top   = new FormAttachment(wlPosition, margin);
		wCompatible.setLayoutData(fdCompatible);
		wCompatible.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { setInputOutputFields(); input.setChanged(true);} });
		
      Label wlOptimizationLevel = new Label(wTop, SWT.NONE);
      wlOptimizationLevel.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.OptimizationLevel.Label")); //$NON-NLS-1$
      props.setLook(wlOptimizationLevel);
      FormData fdlOptimizationLevel = new FormData();
      fdlOptimizationLevel.left  = new FormAttachment(wCompatible, margin*2);
      fdlOptimizationLevel.top   = new FormAttachment(wlPosition, margin);
      wlOptimizationLevel.setLayoutData(fdlOptimizationLevel);
      
      wOptimizationLevel = new TextVar(transMeta, wTop, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
      wOptimizationLevel.setToolTipText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.OptimizationLevel.Tooltip")); 
      props.setLook(wOptimizationLevel);
      FormData fdOptimizationLevel = new FormData();
      fdOptimizationLevel.left  = new FormAttachment(wlOptimizationLevel, margin);
      fdOptimizationLevel.top   = new FormAttachment(wlPosition, margin);
      fdOptimizationLevel.right = new FormAttachment(100, margin);
      wOptimizationLevel.setLayoutData(fdOptimizationLevel);
      wOptimizationLevel.addModifyListener(lsMod);
		
		wlHelpLabel = new Text(wTop, SWT.V_SCROLL |   SWT.LEFT);
		wlHelpLabel.setEditable(false);
		wlHelpLabel.setText("Hallo");
		props.setLook(wlHelpLabel);
		fdHelpLabel = new FormData();
		fdHelpLabel.left = new FormAttachment(wlPosition, margin);
		fdHelpLabel.top = new FormAttachment(folder, margin);
		fdHelpLabel.right = new FormAttachment(100, -5);
		fdHelpLabel.bottom = new FormAttachment(100,0);
		wlHelpLabel.setLayoutData(fdHelpLabel);
		wlHelpLabel.setVisible(false);

		fdTop=new FormData();
		fdTop.left  = new FormAttachment(0, 0);
		fdTop.top   = new FormAttachment(0, 0);
		fdTop.right = new FormAttachment(100, 0);
		fdTop.bottom= new FormAttachment(100, 0);
		wTop.setLayoutData(fdTop);
		
		wBottom = new Composite(wSash, SWT.NONE);
 		props.setLook(wBottom);
		
		FormLayout bottomLayout  = new FormLayout ();
		bottomLayout.marginWidth  = Const.FORM_MARGIN;
		bottomLayout.marginHeight = Const.FORM_MARGIN;
		wBottom.setLayout(bottomLayout);
		
		wSeparator = new Label(wBottom, SWT.SEPARATOR | SWT.HORIZONTAL);
		fdSeparator= new FormData();
		fdSeparator.left  = new FormAttachment(0, 0);
		fdSeparator.right = new FormAttachment(100, 0);
		fdSeparator.top   = new FormAttachment(0, -margin+2);
		wSeparator.setLayoutData(fdSeparator);
		
		wlFields=new Label(wBottom, SWT.NONE);
		wlFields.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.Fields.Label")); //$NON-NLS-1$
		props.setLook(wlFields);
		fdlFields=new FormData();
		fdlFields.left = new FormAttachment(0, 0);
		fdlFields.top  = new FormAttachment(wSeparator, 0);
		wlFields.setLayoutData(fdlFields);
		
		final int FieldsRows=input.getFieldname().length;
		
		ColumnInfo[] colinf=new ColumnInfo[]
           {
    		 new ColumnInfo(BaseMessages.getString(PKG, "ScriptValuesDialogMod.ColumnInfo.Filename"),  ColumnInfo.COLUMN_TYPE_TEXT,   false), //$NON-NLS-1$
    		 new ColumnInfo(BaseMessages.getString(PKG, "ScriptValuesDialogMod.ColumnInfo.RenameTo"),  ColumnInfo.COLUMN_TYPE_TEXT,   false ), //$NON-NLS-1$
    		 new ColumnInfo(BaseMessages.getString(PKG, "ScriptValuesDialogMod.ColumnInfo.Type"),       ColumnInfo.COLUMN_TYPE_CCOMBO, ValueMeta.getTypes() ), //$NON-NLS-1$
    		 new ColumnInfo(BaseMessages.getString(PKG, "ScriptValuesDialogMod.ColumnInfo.Length"),     ColumnInfo.COLUMN_TYPE_TEXT,   false), //$NON-NLS-1$
    		 new ColumnInfo(BaseMessages.getString(PKG, "ScriptValuesDialogMod.ColumnInfo.Precision"),  ColumnInfo.COLUMN_TYPE_TEXT,   false), //$NON-NLS-1$
    		 new ColumnInfo(BaseMessages.getString(PKG, "ScriptValuesDialogMod.ColumnInfo.Replace"),  ColumnInfo.COLUMN_TYPE_CCOMBO,   YES_NO_COMBO ), //$NON-NLS-1$
           };
		
		wFields=new TableView(transMeta, wBottom, 
							  SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI, 
							  colinf, 
							  FieldsRows,  
							  lsMod,
							  props
							  );
		
		fdFields=new FormData();
		fdFields.left = new FormAttachment(0, 0);
		fdFields.top  = new FormAttachment(wlFields, margin);
		fdFields.right  = new FormAttachment(100, 0);
		fdFields.bottom = new FormAttachment(100, 0);
		wFields.setLayoutData(fdFields);

		fdBottom=new FormData();
		fdBottom.left  = new FormAttachment(0, 0);
		fdBottom.top   = new FormAttachment(0, 0);
		fdBottom.right = new FormAttachment(100, 0);
		fdBottom.bottom= new FormAttachment(100, 0);
		wBottom.setLayoutData(fdBottom);

		fdSash = new FormData();
		fdSash.left  = new FormAttachment(0, 0);
		fdSash.top   = new FormAttachment(wStepname, 0);
		fdSash.right = new FormAttachment(100, 0);
		fdSash.bottom= new FormAttachment(100, -50);
		wSash.setLayoutData(fdSash);
		
		wSash.setWeights(new int[] {75,25});

		wOK=new Button(shell, SWT.PUSH);
		wOK.setText(BaseMessages.getString(PKG, "System.Button.OK")); //$NON-NLS-1$
		wVars=new Button(shell, SWT.PUSH);
		wVars.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.GetVariables.Button")); //$NON-NLS-1$
		wTest=new Button(shell, SWT.PUSH);
		wTest.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.TestScript.Button")); //$NON-NLS-1$
		wCancel=new Button(shell, SWT.PUSH);
		wCancel.setText(BaseMessages.getString(PKG, "System.Button.Cancel")); //$NON-NLS-1$
		
		setButtonPositions(new Button[] { wOK, wCancel ,  wVars, wTest }, margin, null);


		// Add listeners
		lsCancel   = new Listener() { public void handleEvent(Event e) { cancel();          } };
		//lsGet      = new Listener() { public void handleEvent(Event e) { get();             } };
		lsTest     = new Listener() { public void handleEvent(Event e) { newTest(); } };
		lsVars     = new Listener() { public void handleEvent(Event e) { test(true, true);  } };
		lsOK       = new Listener() { public void handleEvent(Event e) { ok();              } };
		lsTree	   = new Listener() { public void handleEvent(Event e) { treeDblClick(e);       } };
		// lsHelp		= new Listener(){public void handleEvent(Event e){ wlHelpLabel.setVisible(true); }};

		wCancel.addListener(SWT.Selection, lsCancel);
		//wGet.addListener   (SWT.Selection, lsGet   );
		wTest.addListener (SWT.Selection, lsTest  );
		wVars.addListener  (SWT.Selection, lsVars  );
		wOK.addListener    (SWT.Selection, lsOK    );
		wTree.addListener(SWT.MouseDoubleClick, lsTree);
		
		
		
		lsDef=new SelectionAdapter() { public void widgetDefaultSelected(SelectionEvent e) { ok(); } };
		wStepname.addSelectionListener( lsDef );
				
		// Detect X or ALT-F4 or something that kills this window...
		shell.addShellListener(	new ShellAdapter() { public void shellClosed(ShellEvent e) { if (!cancel()) { e.doit=false; } } } );
		
		folder.addCTabFolder2Listener(new CTabFolder2Adapter() {
			public void close(CTabFolderEvent event) {
	        	CTabItem cItem = (CTabItem)event.item;
	        	event.doit=false;
	        	if(cItem!=null && folder.getItemCount()>1){
	        		MessageBox messageBox = new MessageBox(shell, SWT.ICON_QUESTION | SWT.NO | SWT.YES);
	        		messageBox.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.DeleteItem.Label"));
	        		messageBox.setMessage(BaseMessages.getString(PKG, "ScriptValuesDialogMod.ConfirmDeleteItem.Label",cItem.getText()));
		            switch(messageBox.open()){
		            	case SWT.YES:
		            		modifyScriptTree(cItem,DELETE_ITEM);
		            		event.doit=true;
		            		break;
		            }
	        	}
			}
		});

		cMenu = new Menu(shell, SWT.POP_UP);
		buildingFolderMenu();
		tMenu = new Menu(shell, SWT.POP_UP);
		buildingTreeMenu();
		
		// Adding the Default Transform Scripts Item to the Tree
		wTreeScriptsItem = new TreeItem(wTree, SWT.NULL);
		wTreeScriptsItem.setImage(guiresource.getImageBol());
		wTreeScriptsItem.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.TransformScript.Label"));
		
		// Set the shell size, based upon previous time...
		setSize();
		getData();
		
		// Adding the Rest (Functions, InputItems, etc.) to the Tree
		buildSpecialFunctionsTree();
		
		// Input Fields
		iteminput = new TreeItem(wTree, SWT.NULL);
		iteminput.setImage(imageInputFields);
		iteminput.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.InputFields.Label"));
		// Output Fields
		itemoutput = new TreeItem(wTree, SWT.NULL);
		itemoutput.setImage(imageOutputFields);
		itemoutput.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.OutputFields.Label"));
		
		// Display waiting message for input
		itemWaitFieldsIn = new TreeItem(iteminput, SWT.NULL);
		itemWaitFieldsIn.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.GettingFields.Label"));
		itemWaitFieldsIn.setForeground(guiresource.getColorDirectory());
        iteminput.setExpanded(true);
		   
		// Display waiting message for output
        itemWaitFieldsOut = new TreeItem(itemoutput, SWT.NULL);
        itemWaitFieldsOut.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.GettingFields.Label"));
        itemWaitFieldsOut.setForeground(guiresource.getColorDirectory());
        itemoutput.setExpanded(true);
		
		  // 
        // Search the fields in the background
        //
        
        final Runnable runnable = new Runnable()
        {
            public void run()
            {
            	StepMeta stepMeta = transMeta.findStep(stepname);
                if (stepMeta!=null)
                {
                    try
                    {
                    	rowPrevStepFields = transMeta.getPrevStepFields(stepMeta);
                    	if(rowPrevStepFields!=null) {
                    		setInputOutputFields();
                    	}else{
                      	 // Can not get fields...end of wait message
                      	 iteminput.removeAll();
                      	 itemoutput.removeAll();
                       }
                    }
                    catch(KettleException e)
                    {
                    	logError(BaseMessages.getString(PKG, "System.Dialog.GetFieldsFailed.Message"));
                    }
                }
            }
        };
        new Thread(runnable).start();
        

		
		
		//rebuildInputFieldsTree();
		//buildOutputFieldsTree();
		buildAddClassesListTree();
		addRenameTowTreeScriptItems();
		input.setChanged(changed);
		
		// Create the drag source on the tree
	    DragSource ds = new DragSource(wTree, DND.DROP_MOVE);
	    ds.setTransfer(new Transfer[] { TextTransfer.getInstance() });
	    ds.addDragListener(new DragSourceAdapter() {

	    	public void dragStart(DragSourceEvent event) {
	    		TreeItem item = wTree.getSelection()[0];

	    		// Qualifikation where the Drag Request Comes from
	            if(item !=null && item.getParentItem()!=null){
	            	if(item.getParentItem().equals(wTreeScriptsItem)){
	            		event.doit=false;
	            	}else if(!item.getData().equals("Function")){
	                	String strInsert =(String)item.getData();
	                	if(strInsert.equals("jsFunction")) event.doit=true;
	                	else event.doit=false;
	            	}else{
	            		event.doit=false;
	            	}
	            }else{
	            	event.doit=false;
	            }
	    		
			}
	    	
	    	public void dragSetData(DragSourceEvent event) {
	    		// Set the data to be the first selected item's text
	    		event.data = wTree.getSelection()[0].getText();
	    	}
	    });
		
		
		shell.open();
		while (!shell.isDisposed()){
				if (!display.readAndDispatch()) display.sleep();
		}
		return stepname;
	}
	
	private void setActiveCtab(String strName){
		if(strName.length()==0){
			folder.setSelection(0);
		}
		else folder.setSelection(getCTabPosition(strName));
	}
	
	private  void addCtab(String cScriptName, String strScript, int iType){
		CTabItem item = new CTabItem(folder, SWT.CLOSE);
		
		switch(iType){
			case ADD_DEFAULT: item.setText(cScriptName);
				break;
			default:
				item.setText(getNextName(cScriptName));
				break;
		}
		StyledTextComp wScript=new StyledTextComp(transMeta, item.getParent(), SWT.MULTI | SWT.LEFT |  SWT.H_SCROLL | SWT.V_SCROLL, item.getText(), false);
		if((strScript !=null) && strScript.length()>0) wScript.setText(strScript);
		else wScript.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.ScriptHere.Label")+Const.CR+Const.CR); 
		item.setImage(imageInactiveScript);
 		props.setLook(wScript, Props.WIDGET_STYLE_FIXED);
		
		wScript.addKeyListener(new KeyAdapter(){
				public void keyPressed(KeyEvent e) { setPosition(); }
				public void keyReleased(KeyEvent e) { setPosition(); }
			} 
		);
		wScript.addFocusListener(new FocusAdapter(){
				public void focusGained(FocusEvent e) { setPosition(); }
				public void focusLost(FocusEvent e) { setPosition(); }
			}
		);
		wScript.addMouseListener(new MouseAdapter(){
				public void mouseDoubleClick(MouseEvent e) { setPosition(); }
				public void mouseDown(MouseEvent e) { setPosition(); }
				public void mouseUp(MouseEvent e) { setPosition(); }
			}
		);
		
		wScript.addModifyListener(lsMod);
		
		// Text Higlighting
		lineStyler = new ScriptValuesHighlight(ScriptValuesAddedFunctions.jsFunctionList);
		wScript.addLineStyleListener(lineStyler);
 		item.setControl(wScript);
 		
 		// Adding new Item to Tree
 		modifyScriptTree(item, ADD_ITEM );
	}
	
	private void modifyScriptTree(CTabItem ctabitem, int iModType){
		
		switch(iModType){
			case DELETE_ITEM :
				TreeItem dItem = getTreeItemByName(ctabitem.getText());
		        if(dItem!=null){
		        	dItem.dispose();
		        	input.setChanged();
		        }
				break;
			case ADD_ITEM :
				TreeItem item = new TreeItem(wTreeScriptsItem, SWT.NULL);
				item.setImage(imageActiveScript);
				item.setText(ctabitem.getText());
				input.setChanged();
				break;
			
			case RENAME_ITEM :
				input.setChanged();
				break;
			case SET_ACTIVE_ITEM :
	        	input.setChanged();
				break;
		}
	}
	
	private TreeItem getTreeItemByName(String strTabName){
		TreeItem[] tItems = wTreeScriptsItem.getItems();
		for(int i=0;i<tItems.length;i++){
			if(tItems[i].getText().equals(strTabName)) return tItems[i];
		}
		return null;
	}
	
	private int getCTabPosition(String strTabName){
		CTabItem[] cItems = folder.getItems();
		for(int i=0;i<cItems.length;i++){
			if(cItems[i].getText().equals(strTabName)) return i;
		}
		return -1;
	}
	
	private CTabItem getCTabItemByName(String strTabName){
		CTabItem[] cItems = folder.getItems();
		for(int i=0;i<cItems.length;i++){
			if(cItems[i].getText().equals(strTabName)) return cItems[i];
		}
		return null;
	}
	
	
	private void modifyCTabItem(TreeItem tItem, int iModType, String strOption){
		
		switch(iModType){
			case DELETE_ITEM :
				CTabItem dItem = folder.getItem(getCTabPosition(tItem.getText()));
				if(dItem!=null){
					dItem.dispose();
					input.setChanged();
				}
				break;
			
			case RENAME_ITEM : 
				CTabItem rItem = folder.getItem(getCTabPosition(tItem.getText()));
				if(rItem!=null){
					rItem.setText(strOption);
					input.setChanged();
					if(rItem.getImage().equals(imageActiveScript)) strActiveScript = strOption;
					else if(rItem.getImage().equals(imageActiveStartScript)) strActiveStartScript = strOption;
					else if(rItem.getImage().equals(imageActiveEndScript)) strActiveEndScript = strOption;
				}
				break;
			case SET_ACTIVE_ITEM : 
				CTabItem aItem = folder.getItem(getCTabPosition(tItem.getText()));
				if(aItem!=null){
					input.setChanged();
					strActiveScript = tItem.getText();
					for(int i=0;i<folder.getItemCount();i++){
						if(folder.getItem(i).equals(aItem))aItem.setImage(imageActiveScript);
						else folder.getItem(i).setImage(imageInactiveScript);
					}
				}
				break;
		}
		
	}
	
	
	private StyledTextComp getStyledTextComp(){
		CTabItem item = folder.getSelection();
		if(item.getControl().isDisposed()) return null;
		else return (StyledTextComp)item.getControl();
	}

	private StyledTextComp getStyledTextComp(CTabItem item){
		return (StyledTextComp)item.getControl();
	}
	
    /*
	private void setStyledTextComp(String strText){
		CTabItem item = folder.getSelection();
		((StyledTextComp)item.getControl()).setText(strText);
	}

	private void setStyledTextComp(String strText, CTabItem item){
		((StyledTextComp)item.getControl()).setText(strText);
	}
    */
	
	private String getNextName(String strActualName){
		String strRC = "";
		if(strActualName.length()==0){
			strActualName = "Item";
		}
			
		int i=0;
		strRC = strActualName + "_" + i;
		while(getCTabItemByName(strRC)!=null){
			i++;
			strRC = strActualName + "_" + i;
		}
		return strRC; 
	}
	
	public void setPosition(){
		
		StyledTextComp wScript = getStyledTextComp();
		String scr = wScript.getText();
		int linenr = wScript.getLineAtOffset(wScript.getCaretOffset())+1;
		int posnr  = wScript.getCaretOffset();
		
		
		
		// Go back from position to last CR: how many positions?
		int colnr=0;
		while (posnr>0 && scr.charAt(posnr-1)!='\n' && scr.charAt(posnr-1)!='\r')
		{
			posnr--;
			colnr++;
		}
		wlPosition.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.Position.Label2")+linenr+", "+colnr); //$NON-NLS-1$ //$NON-NLS-2$
	}
	
	/**
	 * Copy information from the meta-data input to the dialog fields.
	 */ 
	public void getData()
	{
		wCompatible.setSelection(input.isCompatible());
	   if (!Const.isEmpty(Const.trim(input.getOptimizationLevel()))) {
   		wOptimizationLevel.setText(input.getOptimizationLevel().trim());
	   }
		else {
		   wOptimizationLevel.setText(ScriptValuesMetaMod.OPTIMIZATION_LEVEL_DEFAULT);
		}
		
		for (int i=0;i<input.getFieldname().length;i++)
		{
			if (input.getFieldname()[i]!=null && input.getFieldname()[i].length()>0)
			{	
				TableItem item = wFields.table.getItem(i);
				item.setText(1, input.getFieldname()[i]);
				if (input.getRename()[i]!=null && !input.getFieldname()[i].equals(input.getRename()[i]))
					item.setText(2, input.getRename()[i]);
				item.setText(3, ValueMeta.getTypeDesc(input.getType()[i]));
				if (input.getLength()[i]>=0) item.setText(4, ""+input.getLength()[i]); //$NON-NLS-1$
                if (input.getPrecision()[i]>=0) item.setText(5, ""+input.getPrecision()[i]); //$NON-NLS-1$
                item.setText(6, input.getReplace()[i] ? YES_NO_COMBO[1] : YES_NO_COMBO[0]); //$NON-NLS-1$
			}
		}
	
		ScriptValuesScript[] jsScripts = input.getJSScripts();
		if(jsScripts.length>0){
			for(int i=0;i<jsScripts.length;i++){
				if(jsScripts[i].isTransformScript()) strActiveScript =jsScripts[i].getScriptName();
				else if(jsScripts[i].isStartScript()) strActiveStartScript =jsScripts[i].getScriptName(); 
				else if(jsScripts[i].isEndScript()) strActiveEndScript =jsScripts[i].getScriptName();
				addCtab(jsScripts[i].getScriptName(), jsScripts[i].getScript(), ADD_DEFAULT);
			}
		}else{
			addCtab("", "", ADD_DEFAULT);
		}
		setActiveCtab(strActiveScript);
		refresh();
		
		wFields.setRowNums();
		wFields.optWidth(true);
		wStepname.selectAll();
	}
	
	// Setting default active Script
	private void refresh(){
		//CTabItem item = getCTabItemByName(strActiveScript);
		for(int i=0;i<folder.getItemCount();i++){
			CTabItem item = folder.getItem(i);
			if(item.getText().equals(strActiveScript))item.setImage(imageActiveScript);
			else if(item.getText().equals(strActiveStartScript))item.setImage(imageActiveStartScript);
			else if(item.getText().equals(strActiveEndScript))item.setImage(imageActiveEndScript);
			else item.setImage(imageInactiveScript);
		}
		//modifyScriptTree(null, SET_ACTIVE_ITEM);
	}
	
	private void refreshScripts(){
		CTabItem[] cTabs = folder.getItems();
		for(int i =0;i<cTabs.length;i++){
			if(cTabs[i].getImage().equals(imageActiveStartScript)) strActiveStartScript = cTabs[i].getText();
			else if(cTabs[i].getImage().equals(imageActiveEndScript)) strActiveEndScript = cTabs[i].getText();
		}
	}
	
    private boolean cancel()
    {
    	if (input.hasChanged()) {
    		MessageBox box = new MessageBox(shell, SWT.YES | SWT.NO | SWT.APPLICATION_MODAL);
    		box.setText(BaseMessages.getString(PKG, "ScriptValuesModDialog.WarningDialogChanged.Title"));
    		box.setMessage(BaseMessages.getString(PKG, "ScriptValuesModDialog.WarningDialogChanged.Message", Const.CR));
    		int answer = box.open();
    		
    		if (answer==SWT.NO) {
    			return false;
    		}	
    	}
        stepname = null;
        input.setChanged(changed);
        dispose();
        return true;
    }
	
	private void getInfo(ScriptValuesMetaMod meta) {
		meta.setCompatible( wCompatible.getSelection() );
		meta.setOptimizationLevel(wOptimizationLevel.getText());
		int nrfields = wFields.nrNonEmpty();
		meta.allocate(nrfields);
		for (int i=0;i<nrfields;i++){
			TableItem item = wFields.getNonEmpty(i);
			meta.getFieldname()[i] = item.getText(1);
			meta.getRename()[i] = item.getText(2);
			if (meta.getRename()[i]==null || 
					meta.getRename()[i].length()==0 || 
					meta.getRename()[i].equalsIgnoreCase(meta.getFieldname()[i])
			)
			{
				meta.getRename()[i] = meta.getFieldname()[i];
			}
			meta.getType()  [i] = ValueMeta.getType(item.getText(3));
			String slen = item.getText(4);
			String sprc = item.getText(5);
			meta.getLength()   [i]=Const.toInt(slen, -1);
			meta.getPrecision()[i]=Const.toInt(sprc, -1);
			meta.getReplace()  [i]=YES_NO_COMBO[1].equalsIgnoreCase(item.getText(6));
		}
		
		//input.setActiveJSScript(strActiveScript);
		CTabItem[] cTabs = folder.getItems();
		if(cTabs.length>0){
			ScriptValuesScript[] jsScripts = new ScriptValuesScript[cTabs.length];
			for(int i=0;i<cTabs.length;i++){
				ScriptValuesScript jsScript = new ScriptValuesScript(
						ScriptValuesScript.NORMAL_SCRIPT,
						cTabs[i].getText(),
						getStyledTextComp(cTabs[i]).getText()
					);
				if(cTabs[i].getImage().equals(imageActiveScript)) jsScript.setScriptType(ScriptValuesScript.TRANSFORM_SCRIPT);
				else if(cTabs[i].getImage().equals(imageActiveStartScript)) jsScript.setScriptType(ScriptValuesScript.START_SCRIPT);
				else if(cTabs[i].getImage().equals(imageActiveEndScript)) jsScript.setScriptType(ScriptValuesScript.END_SCRIPT);
				jsScripts[i] = jsScript;
			}
			meta.setJSScripts(jsScripts);
		}
	}
	
	private void ok()
	{
		if (Const.isEmpty(wStepname.getText())) return;

		stepname = wStepname.getText(); // return value
		
		boolean bInputOK = false;
		
		// Check if Active Script has set, otherwise Ask
		if(getCTabItemByName(strActiveScript)==null){
			MessageBox mb = new MessageBox(shell, SWT.OK | SWT.CANCEL | SWT.ICON_ERROR );
			mb.setMessage(BaseMessages.getString(PKG, "ScriptValuesDialogMod.NoActiveScriptSet"));
			mb.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.ERROR.Label")); //$NON-NLS-1$
			switch(mb.open()){
				case SWT.OK:
					strActiveScript = folder.getItem(0).getText();
					refresh();
					bInputOK = true;
				break;
				case SWT.CANCEL: bInputOK = false;
					break;
			}
		}else{
			bInputOK = true;
		}
		
		if (bInputOK && wCompatible.getSelection()) {
		  // If in compatibility mode the "replace" column must not be "Yes"
		  int nrfields = wFields.nrNonEmpty();
		  for (int i=0;i<nrfields;i++){
		    TableItem item = wFields.getNonEmpty(i);
		    if (YES_NO_COMBO[1].equalsIgnoreCase(item.getText(6))) {
		      bInputOK = false;
		    }
		  }
		  if (!bInputOK) {
		    MessageBox mb = new MessageBox(shell, SWT.OK | SWT.CANCEL | SWT.ICON_ERROR );
		    mb.setMessage(BaseMessages.getString(PKG, "ScriptValuesDialogMod.ReplaceNotAllowedInCompatibilityMode")); //$NON-NLS-1$
		    mb.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.ERROR.Label")); //$NON-NLS-1$
		    mb.open();
		  }
		}

		if(bInputOK){
			getInfo(input);
			dispose();
		}
	}
	
	public boolean test()
	{
		return test(false, false);
	}
	
	private boolean newTest() {
		
	    PluginRegistry registry = PluginRegistry.getInstance();
	    String scriptStepName = wStepname.getText();

		try{
			// What fields are coming into the step?
			//
			RowMetaInterface rowMeta = transMeta.getPrevStepFields(stepname).clone();
			if (rowMeta!=null){
				// Create a new RowGenerator step to generate rows for the test data...
				// Only create a new instance the first time to help the user.
				// Otherwise he/she has to key in the same test data all the time
				//
				if (genMeta==null) {
					genMeta = new RowGeneratorMeta();
					genMeta.setRowLimit("10");
					genMeta.allocate(rowMeta.size());
				    for (int i=0;i<rowMeta.size();i++)
				    {
				    	ValueMetaInterface valueMeta = rowMeta.getValueMeta(i);
				    	if (valueMeta.isStorageBinaryString()) {
				    		valueMeta.setStorageType(ValueMetaInterface.STORAGE_TYPE_NORMAL);
				    	}
				    	genMeta.getFieldName()[i] = valueMeta.getName();
				    	genMeta.getFieldType()[i] = valueMeta.getTypeDesc();
				    	genMeta.getFieldLength()[i] = valueMeta.getLength();
				    	genMeta.getFieldPrecision()[i] = valueMeta.getPrecision();
				    	genMeta.getCurrency()[i] = valueMeta.getCurrencySymbol();
				    	genMeta.getDecimal()[i] = valueMeta.getDecimalSymbol();
				    	genMeta.getGroup()[i] = valueMeta.getGroupingSymbol();
			
				    	String string=null;
				    	switch(valueMeta.getType()) {
				    	case ValueMetaInterface.TYPE_DATE :
					    	genMeta.getFieldFormat()[i] = "yyyy/MM/dd HH:mm:ss";
					    	valueMeta.setConversionMask(genMeta.getFieldFormat()[i]);
				    		string = valueMeta.getString(new Date()); 
				    		break;
				    	case ValueMetaInterface.TYPE_STRING : 
				    		string = "test value test value";  //$NON-NLS-1$
				    		break;
				    	case ValueMetaInterface.TYPE_INTEGER :
				    		genMeta.getFieldFormat()[i] = "#";
					    	valueMeta.setConversionMask(genMeta.getFieldFormat()[i]);
				    		string = valueMeta.getString(Long.valueOf(0L)); 
				    		break;
				    	case ValueMetaInterface.TYPE_NUMBER : 
				    		genMeta.getFieldFormat()[i] = "#.#";
					    	valueMeta.setConversionMask(genMeta.getFieldFormat()[i]);
				    		string = valueMeta.getString(Double.valueOf(0.0D)); 
				    		break;
				    	case ValueMetaInterface.TYPE_BIGNUMBER : 
				    		genMeta.getFieldFormat()[i] = "#.#";
					    	valueMeta.setConversionMask(genMeta.getFieldFormat()[i]);
				    		string = valueMeta.getString(BigDecimal.ZERO);
				    		break;
				    	case ValueMetaInterface.TYPE_BOOLEAN : 
				    		string = valueMeta.getString(Boolean.TRUE);
				    		break;
				    	case ValueMetaInterface.TYPE_BINARY : 
				    		string = valueMeta.getString(new byte[] { 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, }); 
				    		break;
				    	default: 
				    		break;
				    	}
				    	
				    	genMeta.getValue()[i] = string;
				    }
				}
			    StepMeta genStep = new StepMeta(registry.getPluginId(StepPluginType.class, genMeta), "## TEST DATA ##", genMeta);
			    genStep.setLocation(50, 50);
			    			    
			    // Now create a JavaScript step with the information in this dialog
			    //
			    ScriptValuesMetaMod scriptMeta = new ScriptValuesMetaMod();
			    getInfo(scriptMeta);
			    StepMeta scriptStep = new StepMeta(registry.getPluginId(StepPluginType.class, scriptMeta), Const.NVL(scriptStepName, "## SCRIPT ##"), scriptMeta);
			    scriptStepName = scriptStep.getName();
			    scriptStep.setLocation(150, 50);
			    
			    // Create a hop between both steps...
			    //
			    TransHopMeta hop = new TransHopMeta(genStep, scriptStep);
			    
			    // Generate a new test transformation...
			    //
          TransMeta transMeta =  new TransMeta();
          transMeta.setName(wStepname.getText()+" - PREVIEW"); // $NON-NLS-1$
			    transMeta.addStep(genStep);
			    transMeta.addStep(scriptStep);
			    transMeta.addTransHop(hop);
			    
			    // OK, now we ask the user to edit this dialog...
			    //
			    if (Spoon.getInstance().editStep(transMeta, genStep)!=null) {
			    	// Now run this transformation and grab the results...
			    	//
			    	TransPreviewProgressDialog progressDialog = new TransPreviewProgressDialog(
			    			shell, 
			    			transMeta, 
			    			new String[] { scriptStepName, }, 
			    			new int[] { Const.toInt(genMeta.getRowLimit(), 10), }
			    		);
			    	progressDialog.open();
			    	
		            Trans trans = progressDialog.getTrans();
		            String loggingText = progressDialog.getLoggingText();

		            if (!progressDialog.isCancelled())
		            {
		                if (trans.getResult()!=null && trans.getResult().getNrErrors()>0)
		                {
		                	EnterTextDialog etd = new EnterTextDialog(shell, BaseMessages.getString(PKG, "System.Dialog.PreviewError.Title"),  
		                			BaseMessages.getString(PKG, "System.Dialog.PreviewError.Message"), loggingText, true );
		                	etd.setReadOnly();
		                	etd.open();
		                }
		            }
		            
                    RowMetaInterface previewRowsMeta = progressDialog.getPreviewRowsMeta(wStepname.getText());
                    List<Object[]> previewRows = progressDialog.getPreviewRows(wStepname.getText());
                    
                    if (previewRowsMeta!=null && previewRows!=null && previewRows.size()>0) {
	                    PreviewRowsDialog prd = new PreviewRowsDialog(shell, 
	                    		transMeta, SWT.NONE, wStepname.getText(), 
	                    		previewRowsMeta, 
	                    		previewRows, 
	                    		loggingText);
	                    prd.open();
                    }
			    }

			    return true;
			} else {
				throw new KettleException(BaseMessages.getString(PKG, "ScriptValuesDialogMod.Exception.CouldNotGetFields")); //$NON-NLS-1$
			}
		}
		catch(Exception e) {
			new ErrorDialog(shell, BaseMessages.getString(PKG, "ScriptValuesDialogMod.TestFailed.DialogTitle"), BaseMessages.getString(PKG, "ScriptValuesDialogMod.TestFailed.DialogMessage"), e); //$NON-NLS-1$ //$NON-NLS-2$
			return false;
		}
		
	}
	
	private boolean test(boolean getvars, boolean popup)
	{
		boolean retval=true;
		StyledTextComp wScript = getStyledTextComp();
		String scr = wScript.getText();
		KettleException testException = null;
		
		Context jscx;
		Scriptable jsscope;
		// Script jsscript;

		// Making Refresh to get Active Script State
		refreshScripts();
		
		jscx = ContextFactory.getGlobal().enterContext();
		jscx.setOptimizationLevel(-1);
		jsscope = jscx.initStandardObjects(null, false);
				
		// Adding the existing Scripts to the Context
		for(int i=0;i<folder.getItemCount();i++){
			StyledTextComp sItem = getStyledTextComp(folder.getItem(i));
			Scriptable jsR = Context.toObject(sItem.getText(), jsscope);
			jsscope.put(folder.getItem(i).getText(), jsscope, jsR); //$NON-NLS-1$
		}
		
		// Adding the Name of the Transformation to the Context
		jsscope.put("_TransformationName_", jsscope, this.stepname);
		
			
		try{
			RowMetaInterface rowMeta = transMeta.getPrevStepFields(stepname);
			if (rowMeta!=null){
				
				ScriptValuesModDummy dummyStep = new ScriptValuesModDummy(rowMeta, transMeta.getStepFields(stepname));
				Scriptable jsvalue = Context.toObject(dummyStep, jsscope);
				jsscope.put("_step_", jsscope, jsvalue); //$NON-NLS-1$

				// Modification for Additional Script parsing
				try{
                    if (input.getAddClasses()!=null)
                    {
    					for(int i=0;i<input.getAddClasses().length;i++){
    						Object jsOut = Context.javaToJS(input.getAddClasses()[i].getAddObject(), jsscope);
    						ScriptableObject.putProperty(jsscope, input.getAddClasses()[i].getJSName(), jsOut);
    					}
                    }
				}catch(Exception e){
					testException = new KettleException(BaseMessages.getString(PKG, "ScriptValuesDialogMod.CouldNotAddToContext",e.toString())); //$NON-NLS-1$
					retval = false;
				}
				
				// Adding some default JavaScriptFunctions to the System
				try {
					Context.javaToJS(ScriptValuesAddedFunctions.class, jsscope);
					((ScriptableObject)jsscope).defineFunctionProperties(jsFunctionList, ScriptValuesAddedFunctions.class, ScriptableObject.DONTENUM);
				} catch (Exception ex) {
					testException = new KettleException(BaseMessages.getString(PKG, "ScriptValuesDialogMod.CouldNotAddDefaultFunctions", ex.toString())); //$NON-NLS-1$
					retval = false;
				};

				// Adding some Constants to the JavaScript
				try {
					jsscope.put("SKIP_TRANSFORMATION", jsscope, Integer.valueOf(SKIP_TRANSFORMATION));
					jsscope.put("ABORT_TRANSFORMATION", jsscope, Integer.valueOf(ABORT_TRANSFORMATION));
					jsscope.put("ERROR_TRANSFORMATION", jsscope, Integer.valueOf(ERROR_TRANSFORMATION));
					jsscope.put("CONTINUE_TRANSFORMATION", jsscope, Integer.valueOf(CONTINUE_TRANSFORMATION));
				} catch (Exception ex) {
					testException = new KettleException(BaseMessages.getString(PKG, "ScriptValuesDialogMod.CouldNotAddTransformationConstants",ex.toString())); //$NON-NLS-1$
					retval = false;
				};
				
				try{
					Object[] row=new Object[rowMeta.size()];
	   			    Scriptable jsRowMeta = Context.toObject(rowMeta, jsscope);
				    jsscope.put("rowMeta", jsscope, jsRowMeta); //$NON-NLS-1$
				    for (int i=0;i<rowMeta.size();i++)
				    {
                        ValueMetaInterface valueMeta = rowMeta.getValueMeta(i);
	  				    Object valueData = null;
                        
					    // Set date and string values to something to simulate real thing
                        //
					    if (valueMeta.isDate()) valueData = new Date();
					    if (valueMeta.isString()) valueData = "test value test value test value test value test value test value test value test value test value test value"; //$NON-NLS-1$ 
                        if (valueMeta.isInteger()) valueData = Long.valueOf(0L);
                        if (valueMeta.isNumber()) valueData = new Double(0.0);
                        if (valueMeta.isBigNumber()) valueData = BigDecimal.ZERO;
                        if (valueMeta.isBoolean()) valueData = Boolean.TRUE;
                        if (valueMeta.isBinary()) valueData = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, };
                        
                        if (valueMeta.isStorageBinaryString()) {
                        	valueMeta.setStorageType(ValueMetaInterface.STORAGE_TYPE_NORMAL);
                        }
                        
                        row[i]=valueData;
                        
                        if (wCompatible.getSelection()) {
                        	Value value = valueMeta.createOriginalValue(valueData);
                        	Scriptable jsarg = Context.toObject(value, jsscope);
    					    jsscope.put(valueMeta.getName(), jsscope, jsarg);
                        }
                        else {
                        	Scriptable jsarg = Context.toObject(valueData, jsscope);
    					    jsscope.put(valueMeta.getName(), jsscope, jsarg);
                        }
				    }
				    
				    // OK, for these input values, we're going to allow the user to edit the default values...
				    // We are displaying a
				    // 2) 
				    
				    
				    // Add support for Value class (new Value())
				    Scriptable jsval = Context.toObject(Value.class, jsscope);
				    jsscope.put("Value", jsscope, jsval); //$NON-NLS-1$

	                // Add the old style row object for compatibility reasons...
	                //
	                if (wCompatible.getSelection()) {
	                	Row v2Row = RowMeta.createOriginalRow(rowMeta, row);
	                	Scriptable jsV2Row = Context.toObject(v2Row, jsscope);
	                    jsscope.put("row", jsscope, jsV2Row); //$NON-NLS-1$
	                }
	                else {
		                Scriptable jsRow = Context.toObject(row, jsscope);
		                jsscope.put("row", jsscope, jsRow); //$NON-NLS-1$
	                }

				}catch(Exception ev){
					testException = new KettleException(BaseMessages.getString(PKG, "ScriptValuesDialogMod.CouldNotAddInputFields", ev.toString())); //$NON-NLS-1$
					retval = false;
				}
				
				try{
					// Checking for StartScript
					if(strActiveStartScript != null && !folder.getSelection().getText().equals(strActiveStartScript) && strActiveStartScript.length()>0){
						String strStartScript = getStyledTextComp(folder.getItem(getCTabPosition(strActiveStartScript))).getText();
						/* Object startScript = */ jscx.evaluateString(jsscope, strStartScript, "trans_Start", 1, null);
					}
				}catch(Exception e){
					testException = new KettleException(BaseMessages.getString(PKG, "ScriptValuesDialogMod.CouldProcessStartScript",e.toString())); //$NON-NLS-1$
					retval = false;					
				};
				
				try {
					
					Script evalScript = jscx.compileString(scr, "script", 1, null);
					evalScript.exec(jscx, jsscope);
					//Object tranScript = jscx.evaluateString(jsscope, scr, "script", 1, null);
						
					if (getvars){
						ScriptOrFnNode tree = parseVariables(jscx, jsscope, scr, "script", 1, null); 
						for (int i=0;i<tree.getParamAndVarCount();i++){
							String varname = tree.getParamOrVarName(i);
							if (!varname.equalsIgnoreCase("row") && !varname.equalsIgnoreCase("trans_Status")){
								int type=ValueMetaInterface.TYPE_STRING;
								int length=-1, precision=-1;
								Object result = jsscope.get(varname, jsscope);
								if (result!=null){
									String classname = result.getClass().getName();	
									if (classname.equalsIgnoreCase("java.lang.Byte")){
										// MAX = 127
										type=ValueMetaInterface.TYPE_INTEGER;
										length=3;
										precision=0;
									}else if (classname.equalsIgnoreCase("java.lang.Integer")){
										// MAX = 2147483647
										type=ValueMetaInterface.TYPE_INTEGER;
										length=9;
										precision=0;
									}else if (classname.equalsIgnoreCase("java.lang.Long")){
										// MAX = 9223372036854775807
										type=ValueMetaInterface.TYPE_INTEGER;
										length=18;
										precision=0;
									}else if (classname.equalsIgnoreCase("java.lang.Double")){
										type=ValueMetaInterface.TYPE_NUMBER;
										length=16;
										precision=2;
										
									}else if (classname.equalsIgnoreCase("org.mozilla.javascript.NativeDate") || classname.equalsIgnoreCase("java.util.Date")){
										type=ValueMetaInterface.TYPE_DATE;
									}else if (classname.equalsIgnoreCase("java.lang.Boolean")){
										type=ValueMetaInterface.TYPE_BOOLEAN;
									}
								}
								TableItem ti = new TableItem(wFields.table, SWT.NONE);
								ti.setText(1, varname);
								ti.setText(2, "");
								ti.setText(3, ValueMeta.getTypeDesc(type));
								ti.setText(4, length>=0 ? ( ""+length) : "" ); //$NON-NLS-1$
								ti.setText(5, precision>=0 ? (""+precision ) : ""); //$NON-NLS-1$
								
								// If the variable name exists in the input, suggest to replace the value
								//
								ti.setText(6, (rowMeta.indexOfValue(varname)>=0) ? YES_NO_COMBO[1] : YES_NO_COMBO[0]);
							}
						}
						wFields.removeEmptyRows();
						wFields.setRowNums();
						wFields.optWidth(true);
					}
					
					// End Script!
				}
				catch(EvaluatorException e){
					String position = "("+e.lineNumber()+":"+e.columnNumber()+")"; // $NON-NLS-1$ $NON-NLS-2$ $NON-NLS-3$   
					String message = BaseMessages.getString(PKG, "ScriptValuesDialogMod.Exception.CouldNotExecuteScript", position); //$NON-NLS-1$
					testException = new KettleException(message, e);
					retval=false;
				}
				catch(JavaScriptException e){
					String position = "("+e.lineNumber()+":"+e.columnNumber()+")"; // $NON-NLS-1$ $NON-NLS-2$ $NON-NLS-3$   
					String message = BaseMessages.getString(PKG, "ScriptValuesDialogMod.Exception.CouldNotExecuteScript", position); //$NON-NLS-1$
					testException = new KettleException(message, e);
					retval=false;
				}
				catch(Exception e){
					testException = new KettleException(BaseMessages.getString(PKG, "ScriptValuesDialogMod.Exception.CouldNotExecuteScript2"), e); //$NON-NLS-1$
					retval=false;
				}
			}else{
				testException = new KettleException(BaseMessages.getString(PKG, "ScriptValuesDialogMod.Exception.CouldNotGetFields")); //$NON-NLS-1$
				retval=false;
			}
	
			if (popup){
				if (retval){
					if (!getvars){
						MessageBox mb = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION );
						mb.setMessage(BaseMessages.getString(PKG, "ScriptValuesDialogMod.ScriptCompilationOK")+Const.CR); //$NON-NLS-1$
						mb.setText("OK"); //$NON-NLS-1$
						mb.open();
					}
				}else{
					new ErrorDialog(shell, BaseMessages.getString(PKG, "ScriptValuesDialogMod.TestFailed.DialogTitle"), BaseMessages.getString(PKG, "ScriptValuesDialogMod.TestFailed.DialogMessage"), testException); //$NON-NLS-1$ //$NON-NLS-2$
				}
			}
		}catch(KettleException ke){
			retval=false;
			new ErrorDialog(shell, BaseMessages.getString(PKG, "ScriptValuesDialogMod.TestFailed.DialogTitle"), BaseMessages.getString(PKG, "ScriptValuesDialogMod.TestFailed.DialogMessage"), ke); //$NON-NLS-1$ //$NON-NLS-2$
		}finally{
			if (jscx!=null) Context.exit();
		}
		return retval;
	}

	private void buildSpecialFunctionsTree(){

		TreeItem item = new TreeItem(wTree, SWT.NULL);
		item.setImage(guiresource.getImageBol());
		item.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.TansformConstant.Label"));
		TreeItem itemT = new TreeItem(item, SWT.NULL);
		itemT.setImage(imageArrowGreen);
		itemT.setText("SKIP_TRANSFORMATION");
		itemT.setData("SKIP_TRANSFORMATION");
		//itemT = new TreeItem(item, SWT.NULL);
		//itemT.setText("ABORT_TRANSFORMATION");
		//itemT.setData("ABORT_TRANSFORMATION");
		itemT = new TreeItem(item, SWT.NULL);
		itemT.setImage(imageArrowGreen);
		itemT.setText("ERROR_TRANSFORMATION");
		itemT.setData("ERROR_TRANSFORMATION");
		itemT = new TreeItem(item, SWT.NULL);
		itemT.setImage(imageArrowGreen);
		itemT.setText("CONTINUE_TRANSFORMATION");
		itemT.setData("CONTINUE_TRANSFORMATION");
		
		
		item = new TreeItem(wTree, SWT.NULL);
		item.setImage(guiresource.getImageBol());
		item.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.TransformFunctions.Label"));
		String strData = "";
		
		// Adding the Grouping Items to the Tree
		TreeItem itemStringFunctionsGroup = new TreeItem(item, SWT.NULL);
		itemStringFunctionsGroup.setImage(imageUnderGreen);
		itemStringFunctionsGroup.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.StringFunctions.Label"));
		itemStringFunctionsGroup.setData("Function");
		TreeItem itemNumericFunctionsGroup = new TreeItem(item, SWT.NULL);
		itemNumericFunctionsGroup.setImage(imageUnderGreen);
		itemNumericFunctionsGroup.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.NumericFunctions.Label"));
		itemNumericFunctionsGroup.setData("Function");
		TreeItem itemDateFunctionsGroup = new TreeItem(item, SWT.NULL);
		itemDateFunctionsGroup.setImage(imageUnderGreen);
		itemDateFunctionsGroup.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.DateFunctions.Label"));
		itemDateFunctionsGroup.setData("Function");
		TreeItem itemLogicFunctionsGroup = new TreeItem(item, SWT.NULL);
		itemLogicFunctionsGroup.setImage(imageUnderGreen);
		itemLogicFunctionsGroup.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.LogicFunctions.Label"));
		itemLogicFunctionsGroup.setData("Function");
		TreeItem itemSpecialFunctionsGroup = new TreeItem(item, SWT.NULL);
		itemSpecialFunctionsGroup.setImage(imageUnderGreen);
		itemSpecialFunctionsGroup.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.SpecialFunctions.Label"));
		itemSpecialFunctionsGroup.setData("Function");
		TreeItem itemFileFunctionsGroup = new TreeItem(item, SWT.NULL);
		itemFileFunctionsGroup.setImage(imageUnderGreen);
		itemFileFunctionsGroup.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.FileFunctions.Label"));
		itemFileFunctionsGroup.setData("Function");
		
		// Loading the Default delivered JScript Functions
		//Method[] methods = ScriptValuesAddedFunctions.class.getMethods();
		//String strClassType = ScriptValuesAddedFunctions.class.toString();
		
		Hashtable<String, String> hatFunctions =scVHelp.getFunctionList(); 
	    
		Vector<String> v = new Vector<String>(hatFunctions.keySet());
	    Collections.sort(v);
	    
	    for (String strFunction : v) {
	       String strFunctionType =(String)hatFunctions.get(strFunction);
	       int iFunctionType = Integer.valueOf(strFunctionType).intValue();

	       TreeItem itemFunction=null;
			switch(iFunctionType){
				case ScriptValuesAddedFunctions.STRING_FUNCTION: itemFunction = new TreeItem(itemStringFunctionsGroup,SWT.NULL); break;
				case ScriptValuesAddedFunctions.NUMERIC_FUNCTION:itemFunction = new TreeItem(itemNumericFunctionsGroup,SWT.NULL); break;
				case ScriptValuesAddedFunctions.DATE_FUNCTION:itemFunction = new TreeItem(itemDateFunctionsGroup,SWT.NULL); break;
				case ScriptValuesAddedFunctions.LOGIC_FUNCTION:itemFunction = new TreeItem(itemLogicFunctionsGroup,SWT.NULL); break;
				case ScriptValuesAddedFunctions.SPECIAL_FUNCTION:itemFunction = new TreeItem(itemSpecialFunctionsGroup,SWT.NULL); break;
				case ScriptValuesAddedFunctions.FILE_FUNCTION:itemFunction = new TreeItem(itemFileFunctionsGroup,SWT.NULL); break;
			}
			if(itemFunction !=null){
				itemFunction.setText(strFunction);
				itemFunction.setImage(imageArrowGreen);
				strData = "jsFunction";
				itemFunction.setData(strData);
			}
	    }		
	}
	
	public boolean TreeItemExist(TreeItem itemToCheck, String strItemName){
		boolean bRC=false;
		if(itemToCheck.getItemCount()>0){
			TreeItem[] items = itemToCheck.getItems();
			for(int i=0;i<items.length;i++){
				if(items[i].getText().equals(strItemName)) return true;
			}
		}
		return bRC;
	}
	
	private void setInputOutputFields(){
		 shell.getDisplay().syncExec(new Runnable()
         {
             public void run()
             {
            	 // fields are got...end of wait message
            	 iteminput.removeAll();
            	 itemoutput.removeAll();
            	 
	             String strItemInToAdd="";
	             String strItemToAddOut="";
            	 
				//try{
				
					//RowMetaInterface r = transMeta.getPrevStepFields(stepname);
					if (rowPrevStepFields!=null){
						//TreeItem item = new TreeItem(wTree, SWT.NULL);
						//item.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.OutputFields.Label"));
						//String strItemToAdd="";

						for (int i=0;i<rowPrevStepFields.size();i++){
								ValueMetaInterface v = rowPrevStepFields.getValueMeta(i);	
								strItemToAddOut=v.getName()+".setValue(var)";
								if (wCompatible.getSelection()) {
									switch(v.getType()){
										case ValueMetaInterface.TYPE_STRING : strItemInToAdd=v.getName()+".getString()"; break; //$NON-NLS-1$
										case ValueMetaInterface.TYPE_NUMBER : strItemInToAdd=v.getName()+".getNumber()"; break; //$NON-NLS-1$
										case ValueMetaInterface.TYPE_INTEGER: strItemInToAdd=v.getName()+".getInteger()"; break; //$NON-NLS-1$
										case ValueMetaInterface.TYPE_DATE   : strItemInToAdd=v.getName()+".getDate()"; break; //$NON-NLS-1$
										case ValueMetaInterface.TYPE_BOOLEAN: 
											strItemInToAdd=v.getName()+".getBoolean()"; 
											strItemToAddOut=v.getName()+".setValue(var)";
											break; //$NON-NLS-1$
										case ValueMetaInterface.TYPE_BIGNUMBER: strItemInToAdd=v.getName()+".getBigNumber()"; break; //$NON-NLS-1$
										case ValueMetaInterface.TYPE_BINARY: strItemInToAdd=v.getName()+".getBytes()"; break; //$NON-NLS-1$
										case ValueMetaInterface.TYPE_SERIALIZABLE: strItemInToAdd=v.getName()+".getSerializable()"; break; //$NON-NLS-1$
										default: 
											strItemInToAdd=v.getName(); 
											strItemToAddOut=v.getName();
										break;
									}
								}
								else {
									strItemInToAdd=v.getName();
								}
								TreeItem itemFields = new TreeItem(iteminput, SWT.NULL);
								itemFields.setImage(imageArrowOrange);
								itemFields.setText(strItemInToAdd);
								itemFields.setData(strItemInToAdd);
								
								/*
								switch(v.getType()){
									case ValueMetaInterface.TYPE_STRING : 
									case ValueMetaInterface.TYPE_NUMBER : 
									case ValueMetaInterface.TYPE_INTEGER: 
									case ValueMetaInterface.TYPE_DATE   : 
									case ValueMetaInterface.TYPE_BOOLEAN: 
										strItemToAdd=v.getName()+".setValue(var)"; break; //$NON-NLS-1$
									default: strItemToAdd=v.getName(); break;
								}*/
								itemFields = new TreeItem(itemoutput, SWT.NULL);
								itemFields.setImage(imageArrowOrange);
								itemFields.setText(strItemToAddOut);
								itemFields.setData(strItemToAddOut);
							}
					}
				/*}catch(KettleException ke){
					new ErrorDialog(shell, BaseMessages.getString(PKG, "ScriptValuesDialogMod.FailedToGetFields.DialogTitle"), BaseMessages.getString(PKG, "ScriptValuesDialogMod.FailedToGetFields.DialogMessage"), ke); //$NON-NLS-1$ //$NON-NLS-2$
				}*/
         }
       }
      );
	}
	
	/*
	private void rebuildInputFieldsTree(){
		try{
			String itemName = BaseMessages.getString(PKG, "ScriptValuesDialogMod.InputFields.Label");
			
			RowMetaInterface r = transMeta.getPrevStepFields(stepname);
			if (r!=null){
				TreeItem item = null;
				for (TreeItem look : wTree.getItems()) {
					if (look.getText().equals(itemName)) {
						// This is the rebuild part!
						for (TreeItem child : look.getItems()) child.dispose(); // clear the children.
						item=look;
						break;
					}
				}
				if (item==null)  item = new TreeItem(wTree, SWT.NULL);
				item.setText(itemName);
				String strItemToAdd="";
				for (int i=0;i<r.size();i++){
						ValueMetaInterface v = r.getValueMeta(i);
						if (wCompatible.getSelection()) {
							switch(v.getType()){
								case ValueMetaInterface.TYPE_STRING : strItemToAdd=v.getName()+".getString()"; break; //$NON-NLS-1$
								case ValueMetaInterface.TYPE_NUMBER : strItemToAdd=v.getName()+".getNumber()"; break; //$NON-NLS-1$
								case ValueMetaInterface.TYPE_INTEGER: strItemToAdd=v.getName()+".getInteger()"; break; //$NON-NLS-1$
								case ValueMetaInterface.TYPE_DATE   : strItemToAdd=v.getName()+".getDate()"; break; //$NON-NLS-1$
								case ValueMetaInterface.TYPE_BOOLEAN: strItemToAdd=v.getName()+".getBoolean()"; break; //$NON-NLS-1$
								case ValueMetaInterface.TYPE_BIGNUMBER: strItemToAdd=v.getName()+".getBigNumber()"; break; //$NON-NLS-1$
								case ValueMetaInterface.TYPE_BINARY: strItemToAdd=v.getName()+".getBytes()"; break; //$NON-NLS-1$
								case ValueMetaInterface.TYPE_SERIALIZABLE: strItemToAdd=v.getName()+".getSerializable()"; break; //$NON-NLS-1$
								default: strItemToAdd=v.getName(); break;
							}
						}
						else {
							strItemToAdd=v.getName();
						}
						TreeItem itemInputFields = new TreeItem(item, SWT.NULL);
						itemInputFields.setText(strItemToAdd);
						itemInputFields.setData(strItemToAdd);
					}
			}
		}catch(KettleException ke){
			new ErrorDialog(shell, BaseMessages.getString(PKG, "ScriptValuesDialogMod.FailedToGetFields.DialogTitle"), BaseMessages.getString(PKG, "ScriptValuesDialogMod.FailedToGetFields.DialogMessage"), ke); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}*/

	// Adds the Current item to the current Position
	private void treeDblClick(Event event){
		StyledTextComp wScript = getStyledTextComp();
		Point point = new Point(event.x, event.y);
        TreeItem item = wTree.getItem(point);
        
        // Qualifikation where the Click comes from
        if(item !=null && item.getParentItem()!=null){
        	if(item.getParentItem().equals(wTreeScriptsItem)){
        		setActiveCtab(item.getText());
        	}else if(!item.getData().equals("Function")){
        		int iStart = wScript.getCaretOffset();
        		int selCount = wScript.getSelectionCount();  // this selection will be replaced by wScript.insert
        		iStart=iStart-selCount; //when a selection is already there we need to subtract the position
        		if (iStart<0) iStart=0; // just safety
            	String strInsert =(String)item.getData();
            	if(strInsert.equals("jsFunction")) strInsert = (String)item.getText();
            	wScript.insert(strInsert);
            	wScript.setSelection(iStart,iStart+strInsert.length());
        	}
        }
        /*
        if (item != null && item.getParentItem()!=null && !item.getData().equals("Function")) {
        	int iStart = wScript.getCaretOffset();
        	String strInsert =(String)item.getData();
        	if(strInsert.equals("jsFunction")) strInsert = (String)item.getText();
        	wScript.insert(strInsert);
        	wScript.setSelection(iStart,iStart+strInsert.length());
        }*/
	}
	
	// Building the Tree for Additional Classes
	private void buildAddClassesListTree(){
		if(wTreeClassesitem!=null){
			wTreeClassesitem.dispose();
		}
        if (input.getAddClasses()!=null)
        {
    		for(int i=0;i<input.getAddClasses().length;i++){
    			//System.out.println(input.getAddClasses().length);
    			
    			try{
    				Method[] methods = input.getAddClasses()[i].getAddClass().getMethods();
    				String strClassType = input.getAddClasses()[i].getAddClass().toString();
    				String strParams;
    				wTreeClassesitem = new TreeItem(wTree, SWT.NULL);
    				wTreeClassesitem.setText(input.getAddClasses()[i].getJSName());
    				for (int j=0; j<methods.length; j++){
    					String strDeclaringClass = methods[j].getDeclaringClass().toString();
    					if(strClassType.equals(strDeclaringClass)){
    						TreeItem item2 = new TreeItem(wTreeClassesitem, SWT.NULL);
    						strParams = buildAddClassFunctionName(methods[j]);
    						item2.setText(methods[j].getName() + "("+ strParams  +")");
    						String strData = input.getAddClasses()[i].getJSName() + "." +methods[j].getName() + "("+strParams+")";
    						item2.setData(strData);
    					}
    				}
    			}
                catch(Exception e){
    			}
    		}
        }
	}
	
	
	private String buildAddClassFunctionName(Method metForParams){
		StringBuffer sbRC = new StringBuffer();
		String strRC = "";
		Class<?>[] clsParamType = metForParams.getParameterTypes();
		String strParam;
		

		for(int x=0;x<clsParamType.length;x++){
			strParam = clsParamType[x].getName();
			if(strParam.toLowerCase().indexOf("javascript")>0){
			}else if(strParam.toLowerCase().indexOf("object")>0){
				sbRC.append("var");
				sbRC.append(", ");
			}else if(strParam.equals("java.lang.String")){
				sbRC.append("String");
				sbRC.append(", ");
			}else{
				sbRC.append(strParam);
				sbRC.append(", ");
			}
			
		}
		strRC = sbRC.toString();
		if(strRC.length()>0) strRC = strRC.substring(0,sbRC.length()-2);
		return strRC;
	}
	
	private void buildingFolderMenu(){
		//styledTextPopupmenu = new Menu(, SWT.POP_UP);
		MenuItem addNewItem = new MenuItem(cMenu, SWT.PUSH);
		addNewItem.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.AddNewTab"));
		addNewItem.setImage(imageAddScript);
		addNewItem.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				addCtab("","", ADD_BLANK);
			}
		});
		
		MenuItem copyItem = new MenuItem(cMenu, SWT.PUSH);
		copyItem.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.AddCopy"));
		copyItem.setImage(imageDuplicateScript);
		copyItem.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				CTabItem item = folder.getSelection();
				StyledTextComp st = (StyledTextComp)item.getControl();
				addCtab(item.getText(),st.getText(), ADD_COPY);
			}
		});
		new MenuItem(cMenu, SWT.SEPARATOR);
		
		MenuItem setActiveScriptItem = new MenuItem(cMenu, SWT.PUSH);
		setActiveScriptItem.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.SetTransformScript"));
		setActiveScriptItem.setImage(imageActiveScript);
		setActiveScriptItem.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				CTabItem item = folder.getSelection();
				for(int i=0;i<folder.getItemCount();i++){
					if(folder.getItem(i).equals(item)){
						if(item.getImage().equals(imageActiveScript)) strActiveScript="";
						else if(item.getImage().equals(imageActiveStartScript)) strActiveStartScript="";
						else if(item.getImage().equals(imageActiveEndScript)) strActiveEndScript="";
						item.setImage(imageActiveScript);
						strActiveScript = item.getText();
					}
					else if(folder.getItem(i).getImage().equals(imageActiveScript)){
						folder.getItem(i).setImage(imageInactiveScript);
					}
				}
				modifyScriptTree(item, SET_ACTIVE_ITEM);
			}
		});
		
		MenuItem setStartScriptItem = new MenuItem(cMenu, SWT.PUSH);
		setStartScriptItem.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.SetStartScript"));
		setStartScriptItem.setImage(imageActiveStartScript);
		setStartScriptItem.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				CTabItem item = folder.getSelection();
				for(int i=0;i<folder.getItemCount();i++){
					if(folder.getItem(i).equals(item)){
						if(item.getImage().equals(imageActiveScript)) strActiveScript="";
						else if(item.getImage().equals(imageActiveStartScript)) strActiveStartScript="";
						else if(item.getImage().equals(imageActiveEndScript)) strActiveEndScript="";
						item.setImage(imageActiveStartScript);
						strActiveStartScript = item.getText();
					}
					else if(folder.getItem(i).getImage().equals(imageActiveStartScript)){
						folder.getItem(i).setImage(imageInactiveScript);
					}
				}
				modifyScriptTree(item, SET_ACTIVE_ITEM);
			}
		});
		
		MenuItem setEndScriptItem = new MenuItem(cMenu, SWT.PUSH);
		setEndScriptItem.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.SetEndScript"));
		setEndScriptItem.setImage(imageActiveEndScript);
		setEndScriptItem.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				CTabItem item = folder.getSelection();
				for(int i=0;i<folder.getItemCount();i++){
					if(folder.getItem(i).equals(item)){
						if(item.getImage().equals(imageActiveScript)) strActiveScript="";
						else if(item.getImage().equals(imageActiveStartScript)) strActiveStartScript="";
						else if(item.getImage().equals(imageActiveEndScript)) strActiveEndScript="";
						item.setImage(imageActiveEndScript);
						strActiveEndScript = item.getText();
					}
					else if(folder.getItem(i).getImage().equals(imageActiveEndScript)){
						folder.getItem(i).setImage(imageInactiveScript);
					}
				}
				modifyScriptTree(item, SET_ACTIVE_ITEM);
			}
		});
		new MenuItem(cMenu, SWT.SEPARATOR);
		MenuItem setRemoveScriptItem = new MenuItem(cMenu, SWT.PUSH);
		setRemoveScriptItem.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.RemoveScriptType"));
		setRemoveScriptItem.setImage(imageInactiveScript);
		setRemoveScriptItem.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				CTabItem item = folder.getSelection();
				input.setChanged(true);
				if(item.getImage().equals(imageActiveScript)) strActiveScript="";
				else if(item.getImage().equals(imageActiveStartScript)) strActiveStartScript="";
				else if(item.getImage().equals(imageActiveEndScript)) strActiveEndScript="";
				item.setImage(imageInactiveScript);
			}
		});
		
		folder.setMenu(cMenu);
	}	

	private void buildingTreeMenu(){
		//styledTextPopupmenu = new Menu(, SWT.POP_UP);
		MenuItem addDeleteItem = new MenuItem(tMenu, SWT.PUSH);
		addDeleteItem.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.Delete.Label"));
		addDeleteItem.setImage(imageDeleteScript);
		addDeleteItem.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				if (wTree.getSelectionCount()<=0) return;
				
				TreeItem tItem = wTree.getSelection()[0];
		        if(tItem!=null){
		        	MessageBox messageBox = new MessageBox(shell, SWT.ICON_QUESTION | SWT.NO | SWT.YES);
		            messageBox.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.DeleteItem.Label"));
		            messageBox.setMessage(BaseMessages.getString(PKG, "ScriptValuesDialogMod.ConfirmDeleteItem.Label",tItem.getText()));
		            switch(messageBox.open()){
		            	case SWT.YES:
				        	modifyCTabItem(tItem,DELETE_ITEM,"");
				        	tItem.dispose();
				        	input.setChanged();
		            		break;
		            }
		        }
			}
		});
		
		MenuItem renItem = new MenuItem(tMenu, SWT.PUSH);
		renItem.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.Rename.Label"));
		renItem.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				renameFunction(wTree.getSelection()[0]);
			}
		});
		
		new MenuItem(tMenu, SWT.SEPARATOR);
		MenuItem helpItem = new MenuItem(tMenu, SWT.PUSH);
		helpItem.setText(BaseMessages.getString(PKG, "ScriptValuesDialogMod.Sample.Label"));
		helpItem.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				String strFunctionName = wTree.getSelection()[0].getText();
				String strFunctionNameWithArgs = strFunctionName;
				strFunctionName = strFunctionName.substring(0,strFunctionName.indexOf('('));
				String strHelpTabName = strFunctionName + "_Sample";
				
				if(getCTabPosition(strHelpTabName)==-1)
				addCtab(strHelpTabName, scVHelp.getSample(strFunctionName,strFunctionNameWithArgs), 0);
				
				if(getCTabPosition(strHelpTabName)!=-1)
				setActiveCtab(strHelpTabName);
			}
		});
		
		
		wTree.addListener(SWT.MouseDown, new Listener(){
			public void handleEvent(Event e) {
				if (wTree.getSelectionCount()<=0) return;
				
				TreeItem tItem = wTree.getSelection()[0];
				if(tItem != null){
					TreeItem pItem = tItem.getParentItem();
					
					if(pItem !=null && pItem.equals(wTreeScriptsItem)){
						if(folder.getItemCount()>1)	tMenu.getItem(0).setEnabled(true);
						else tMenu.getItem(0).setEnabled(false);
						tMenu.getItem(1).setEnabled(true);
						tMenu.getItem(3).setEnabled(false);
					}else if(tItem.equals(wTreeClassesitem)){
						tMenu.getItem(0).setEnabled(false);	
						tMenu.getItem(1).setEnabled(false);
						tMenu.getItem(3).setEnabled(false);
					}else if(tItem.getData() != null && tItem.getData().equals("jsFunction")){
						tMenu.getItem(0).setEnabled(false);	
						tMenu.getItem(1).setEnabled(false);
						tMenu.getItem(3).setEnabled(true);
					}else{
						tMenu.getItem(0).setEnabled(false);	
						tMenu.getItem(1).setEnabled(false);
						tMenu.getItem(3).setEnabled(false);
					}
				}
			}
		});
		wTree.setMenu(tMenu);
	}
	
	private void addRenameTowTreeScriptItems(){
		lastItem = new TreeItem [1];
		editor = new TreeEditor (wTree);
		wTree.addListener (SWT.Selection, new Listener () {
			public void handleEvent (Event event) {
				final TreeItem item = (TreeItem)event.item;
				renameFunction(item);
			}
		});
	}
	
	// This function is for a Windows Like renaming inside the tree
	private void renameFunction(TreeItem tItem){
		final TreeItem item = tItem;
		if(item.getParentItem()!=null && item.getParentItem().equals(wTreeScriptsItem)){
			if (item != null && item == lastItem [0]) {
				boolean isCarbon = SWT.getPlatform ().equals ("carbon");
				final Composite composite = new Composite (wTree, SWT.NONE);
				if (!isCarbon) composite.setBackground(shell.getDisplay().getSystemColor (SWT.COLOR_BLACK));
				final Text text = new Text (composite, SWT.NONE);
				final int inset = isCarbon ? 0 : 1;
				composite.addListener (SWT.Resize, new Listener () {
					public void handleEvent (Event e) {
						Rectangle rect = composite.getClientArea ();
						text.setBounds (rect.x + inset, rect.y + inset, rect.width - inset * 2, rect.height - inset * 2);
					}
				});
				Listener textListener = new Listener () {
					public void handleEvent (final Event e) {
						switch (e.type) {
							case SWT.FocusOut:
								if(text.getText().length()>0){
									// Check if the name Exists
									if(getCTabItemByName(text.getText())==null){
										modifyCTabItem(item,RENAME_ITEM, text.getText());
										item.setText (text.getText ());
									}
								}
								composite.dispose ();
							break;
							case SWT.Verify:
								String newText = text.getText ();
								String leftText = newText.substring (0, e.start);
								String rightText = newText.substring (e.end, newText.length ());
								GC gc = new GC (text);
								Point size = gc.textExtent (leftText + e.text + rightText);
								gc.dispose ();
								size = text.computeSize (size.x, SWT.DEFAULT);
								editor.horizontalAlignment = SWT.LEFT;
								Rectangle itemRect = item.getBounds (), rect = wTree.getClientArea ();
								editor.minimumWidth = Math.max (size.x, itemRect.width) + inset * 2;
								int left = itemRect.x, right = rect.x + rect.width;
								editor.minimumWidth = Math.min (editor.minimumWidth, right - left);
								editor.minimumHeight = size.y + inset * 2;
								editor.layout ();
								break;
							case SWT.Traverse:
								switch (e.detail) {
									case SWT.TRAVERSE_RETURN:
										if(text.getText().length()>0){
											// Check if the name Exists
											if(getCTabItemByName(text.getText())==null){
												modifyCTabItem(item,RENAME_ITEM, text.getText());
												item.setText (text.getText ());
											}
										}
									case SWT.TRAVERSE_ESCAPE:
										composite.dispose ();
										e.doit = false;
								}
								break;
						}
					}
				};
				text.addListener (SWT.FocusOut, textListener);
				text.addListener (SWT.Traverse, textListener);
				text.addListener (SWT.Verify, textListener);
				editor.setEditor (composite, item);
				text.setText (item.getText ());
				text.selectAll ();
				text.setFocus ();
		
			}
		}
		lastItem [0] = item;
	}
	
	// This could be useful for further improvements
	public static ScriptOrFnNode parseVariables(Context cx, Scriptable scope, String source, String sourceName, int lineno, Object securityDomain){
    	// Interpreter compiler = new Interpreter();
    	CompilerEnvirons evn = new CompilerEnvirons();
    	//evn.setLanguageVersion(Context.VERSION_1_5);
    	evn.setOptimizationLevel(-1);
    	evn.setGeneratingSource(true);
    	evn.setGenerateDebugInfo(true);
    	ErrorReporter errorReporter = new ToolErrorReporter(false);
    	Parser p = new Parser(evn, errorReporter);
    	ScriptOrFnNode tree = p.parse(source, "",0); // IOException
        new NodeTransformer().transform(tree);
    	//Script result = (Script)compiler.compile(scope, evn, tree, p.getEncodedSource(),false, null);
    	return tree;
	}
}