package com.businesslogic.ireport.ui;

import com.businesslogic.ireport.*;
import com.ms.wfc.app.*;
import com.ms.wfc.core.*;
import com.ms.wfc.ui.*;
import com.ms.wfc.html.*;

import java.util.*;
import java.io.*;

/**
 * Questa classe può accettare un numero variabile di parametri sulla riga
 * di comando. L'esecuzione del programma inizia con il metodo main(). Il costruttore
 * della classe non viene richiamato fino a quando un oggetto di tipo "ExpressionGeneratorForm"
 * non viene creato nel metodo main().
 */
public class ExpressionGeneratorForm extends Form
{
	int pos=0;
	Report report;
	String selected_list="";
	String expression="";
	// an hashtable that containes the expression. 
	Hashtable userExpression = new Hashtable();

	private String getExpression( String name, String caption, String expression )
	{
	  Hashtable expressions = (Hashtable)userExpression.get(name);
	  return (String)expressions.get(caption);
	}
	
	private boolean addExpression( String name, String caption, String expression )
	{
	  boolean result = false;
	  Hashtable expressions = (Hashtable)userExpression.get(name);
		  
	  if ( expressions == null )
	  {
		  expressions = new Hashtable();
		  userExpression.put(name,expressions);
		  listView1.addItem(new ListItem(name,1));
		  result = true;
	  }
	  expressions.put(caption, expression);
	  return result;
	}
	
	public ExpressionGeneratorForm(Report report, String initial_expression)
	{
		super();
		StringBuffer str = new StringBuffer(1024);
		MainForm.GetModuleFileName( MainForm.GetModuleHandle(null),str,1024);
		
		String programDir = com.ms.wfc.io.File.getDirectory(""+str);
		
		Properties expressions = new Properties();
		try {
			String expressionsFileName = com.ms.wfc.io.File.combine(programDir,"expressions.properties");
			FileInputStream fio = new FileInputStream(expressionsFileName);
			expressions.load(fio);
			fio.close();
		} catch (FileNotFoundException ex)
		{
		} catch (Exception ex)
		{
		}
			
		// Necessario per il supporto della finestra di progettazione form di Visual J++
		initForm();		
		this.report = report;
		listView1.addItem(new ListItem("Fields",1));
		listView1.addItem(new ListItem("Parameters",1));
		listView1.addItem(new ListItem("Variables",1));
		listView1.addItem(new ListItem("Constructs",1));
		listView1.addItem(new ListItem("Format number",1));
		// listView1.addItem(new ListItem("Format date",1));
		
		// load from the properties the user expression
		
		Enumeration e = expressions.keys();
		while ( e.hasMoreElements() )
		{
			String key = e.nextElement().toString();
			if ( key.startsWith("expression.") )
			{
				// get the name
				String name = key.substring(key.indexOf(".")+1);
				String caption = name.substring(name.indexOf(".")+1);
				name = name.substring(0, name.indexOf("."));
				addExpression( name, caption, expressions.getProperty( key ));
			}		
		}
			   
			
		richEdit1.setText(initial_expression);	
	}
	public ExpressionGeneratorForm(Report report)
	{
		this(report,"");
	}
	
	private void saveUserExpression( )
	{
		Properties expressions = new Properties();
		
		try {
			FileOutputStream foo = new FileOutputStream("expression.properties");
			expressions.save(foo, "User properties");
			foo.close();
		} catch (FileNotFoundException ex)
		{
		} catch (Exception ex)
		{
		}	
	}
	
	public void setExpression(String expression)
	{
		richEdit1.setRTF(this.report.formatExpression(expression) );
	}
	
	public String getExpression()
	{
		return expression;
	}
	
	/**
	 * ExpressionGeneratorForm esegue l'overriding di dispose e quindi può svuotare
	 * l'elenco dei componenti.
	 */
	public void dispose()
	{
		super.dispose();
		components.dispose();
	}



	private void richEdit1_keyPress(Object source, KeyPressEvent e)
	{

	}
	
	private void button1_click(Object source, Event e)
	{
		this.setDialogResult(DialogResult.CANCEL);
		this.dispose();
	}

	private void richEdit1_textChanged(Object source, Event e)
	{
		if ( ((MainForm)this.report.reportForm.getMDIParent()).ireportProperties.getProperty("SYNTAX_HIGHLIGHTING")!=null &&
			 ((MainForm)this.report.reportForm.getMDIParent()).ireportProperties.getProperty("SYNTAX_HIGHLIGHTING").equalsIgnoreCase("false"))
		{
			return;
		}
		int pos = richEdit1.getSelectionStart();
		richEdit1.setRTF(report.formatExpression( richEdit1.getText()));
		richEdit1.setSelectionStart(pos);
	}

	private void listView1_doubleClick(Object source, Event e)
	{
		if (listView1.getSelectedItems().length > 0)
		{
			if ((listView1.getSelectedItems()[0].getText() ).equalsIgnoreCase("Fields"))
			{
					selected_list ="F";
					this.listBox1.removeAll();
					Enumeration enum = report.fields.elements();
					while (enum.hasMoreElements())
					{
						String s=""+enum.nextElement();
						listBox1.addItem(s );
					}
			} 
			else if ((listView1.getSelectedItems()[0].getText() ).equalsIgnoreCase("Parameters"))
			{
					selected_list ="P";
					this.listBox1.removeAll();
					Enumeration enum = report.parameters.elements();
					while (enum.hasMoreElements())
					{
						String s=((JRParameter)enum.nextElement()).name;
						listBox1.addItem(s );
					}
			}
			else if ((listView1.getSelectedItems()[0].getText() ).equalsIgnoreCase("Variables"))
			{
					selected_list ="V";
					this.listBox1.removeAll();
					Enumeration enum = report.variables.elements();
					while (enum.hasMoreElements())
					{
						String s=((JRVariable)enum.nextElement()).name;
						listBox1.addItem(s );
					}
			}
			else if ((listView1.getSelectedItems()[0].getText() ).equalsIgnoreCase("Constructs"))
			{
					selected_list ="C";
					this.listBox1.removeAll();
					listBox1.addItem("((EXP == EXP) ? EXP : EXP)");
					listBox1.addItem("((EXP.equals(\"EXP\")) ? \"EXP\" : \"EXP\")");
			}
			else if ((listView1.getSelectedItems()[0].getText() ).equalsIgnoreCase("Format number"))
			{
					selected_list ="N";
					this.listBox1.removeAll();
					listBox1.addItem(new JRParameter("1.234","(new DecimalFormat(\"0\",new DecimalFormatSymbols(Locale.ITALIAN))).format(EXP.intValue())"));
					listBox1.addItem(new JRParameter("1,234","(new DecimalFormat(\"0\",new DecimalFormatSymbols(Locale.US))).format(EXP.intValue())"));
					listBox1.addItem(new JRParameter("1.234,56","(new DecimalFormat(\"0.00\",new DecimalFormatSymbols(Locale.ITALIAN))).format(EXP.intValue())"));
					listBox1.addItem(new JRParameter("1.234,56-","(new DecimalFormat(\"0.00-\",new DecimalFormatSymbols(Locale.ITALIAN))).format(EXP.intValue())"));
					listBox1.addItem(new JRParameter("1,234.56","(new DecimalFormat(\"0.00\",new DecimalFormatSymbols(Locale.US))).format(EXP.intValue())"));
					listBox1.addItem(new JRParameter("12%","( NumberFormat.getPercentInstance().format(EXP.intValue()))"));
			} else
			{
					selected_list ="U";
					this.listBox1.removeAll();
					Hashtable elements = (Hashtable)userExpression.get(listView1.getSelectedItems()[0].getText());
					Enumeration enum = elements.keys();
					while ( enum.hasMoreElements() )
					{
						String element = (String)enum.nextElement();
  					    listBox1.addItem(new JRParameter(element,(String)elements.get(element)));
					}
			}
			
					
		//	(new DecimalFormat("0.00",new DecimalFormatSymbols(Locale.ITALIAN))).format(
		//	$P{NUMERO}.intValue()
		//)
		}
	}

	private void listBox1_doubleClick(Object source, Event e)
	{
		if (listBox1.getSelectedItems().length > 0)
		{
			if ( selected_list.equals("F"))
			{
				this.richEdit1.setSelectedText("$F{"+ (String)listBox1.getSelectedItem() +"}");
				this.richEdit1.focus();
			}
			else if ( selected_list.equals("P"))
			{
				this.richEdit1.setSelectedText("$P{"+ (String)listBox1.getSelectedItem() +"}");
				this.richEdit1.focus();
			}
			else if ( selected_list.equals("V"))
			{
				this.richEdit1.setSelectedText("$V{"+ (String)listBox1.getSelectedItem() +"}");
				this.richEdit1.focus();
			}
			else if ( selected_list.equals("C"))
			{
				this.richEdit1.setSelectedText((String)listBox1.getSelectedItem());
				this.richEdit1.focus();
			}
			else if ( selected_list.equals("N")) 
			{
				this.richEdit1.setSelectedText(((JRParameter)listBox1.getSelectedItem()).classType);
				this.richEdit1.focus();
			}
			else if ( selected_list.equals("U")) 
			{
				this.richEdit1.setSelectedText(((JRParameter)listBox1.getSelectedItem()).classType);
				this.richEdit1.focus();
			}

		}
	}

	private void richEdit1_keyDown(Object source, KeyEvent e)
	{
         if (e.getKeyCode()==Key.RETURN )
		 {
			 if (this.richEdit1.getSelectionStart() == 
				 this.richEdit1.getText().length())
			 {
				this.richEdit1.setSelectionStart( this.richEdit1.getText().length());
			 }
		 }
	}


	private void button2_click(Object source, Event e)
	{
		this.expression = richEdit1.getText();
		this.setDialogResult(DialogResult.OK);
		this.dispose();
	}

	private void btnAdd_click(Object source, Event e)
	{
		MessageBox.show("Not implemented yet, modify the file 'expressions.properties' !" );
			
	}

	private void listView1_click(Object source, Event e)
	{
		
	}

	/**
	 * NOTA: il seguente codice è richiesto dalla finestra di progettazione form 
	 * di Visual J++. È possibile modificarlo con l'Editor di form.  Non modificarlo
	 * con l'Editor del codice.
	 */
	Container components = new Container();
	Panel panel1 = new Panel();
	RichEdit richEdit1 = new RichEdit();
	Panel panel2 = new Panel();
	Splitter splitter1 = new Splitter();
	ListBox listBox1 = new ListBox();
	ImageList imageList1 = new ImageList();
	Splitter splitter2 = new Splitter();
	Button button1 = new Button();
	ListView listView1 = new ListView();
	ColumnHeader columnHeader1 = new ColumnHeader();
	Button btnAdd = new Button();
	Button button3 = new Button();

	private void initForm()
	{
		// REMARQUE : cette feuille stocke des informations sur les ressources
		// dans un fichier externe. Ne modifiez le paramètre de chaîne d'aucun
		// appel de fonction resources.getObject(). Par exemple,
		// ne modifiez pas "foo1_location" dans la ligne de code
		// suivante, même si le nom de l'objet Foo change : 
		//	 foo1.setLocation((Point)resources.getObject("foo1_location"));

		IResourceManager resources = new ResourceManager(this, "ExpressionGeneratorForm");
		this.setText("JasperReportExpression Editor");
		this.setAutoScaleBaseSize(new Point(5, 13));
		this.setClientSize(new Point(422, 294));
		this.setIcon((Icon)resources.getObject("this_icon"));
		this.setMinimizeBox(false);
		this.setShowInTaskbar(false);

		panel1.setDock(ControlDock.BOTTOM);
		panel1.setLocation(new Point(0, 118));
		panel1.setSize(new Point(422, 176));
		panel1.setTabIndex(0);
		panel1.setText("panel1");

		richEdit1.setDock(ControlDock.FILL);
		richEdit1.setFont(new Font("Courier New", 8.0f, FontSize.POINTS, FontWeight.NORMAL, false, false, false, CharacterSet.DEFAULT, 0));
		richEdit1.setForeColor(Color.BLUE);
		richEdit1.setSize(new Point(422, 115));
		richEdit1.setTabIndex(1);
		richEdit1.setText("");
		richEdit1.setAcceptsTab(true);
		richEdit1.setHideSelection(false);
		richEdit1.setScrollBars(RichEditScrollBars.BOTH);
		richEdit1.setWordWrap(false);
		richEdit1.addOnKeyDown(new KeyEventHandler(this.richEdit1_keyDown));
		richEdit1.addOnKeyPress(new KeyPressEventHandler(this.richEdit1_keyPress));
		richEdit1.addOnTextChanged(new EventHandler(this.richEdit1_textChanged));

		panel2.setDock(ControlDock.BOTTOM);
		panel2.setLocation(new Point(0, 144));
		panel2.setSize(new Point(422, 32));
		panel2.setTabIndex(3);
		panel2.setText("panel2");

		splitter1.setDock(ControlDock.LEFT);
		splitter1.setLocation(new Point(208, 0));
		splitter1.setSize(new Point(3, 144));
		splitter1.setTabIndex(1);
		splitter1.setTabStop(false);

		listBox1.setDock(ControlDock.FILL);
		listBox1.setLocation(new Point(211, 0));
		listBox1.setSize(new Point(211, 144));
		listBox1.setTabIndex(2);
		listBox1.setText("listBox1");
		listBox1.setIntegralHeight(false);
		listBox1.setUseTabStops(true);
		listBox1.addOnDoubleClick(new EventHandler(this.listBox1_doubleClick));

		imageList1.setImageStream((ImageListStreamer)resources.getObject("imageList1_imageStream"));
		/* @designTimeOnly imageList1.setLocation(new Point(88, 56)); */

		splitter2.setCursor(Cursor.HSPLIT);
		splitter2.setDock(ControlDock.BOTTOM);
		splitter2.setLocation(new Point(0, 115));
		splitter2.setSize(new Point(422, 3));
		splitter2.setTabIndex(2);
		splitter2.setTabStop(false);

		button1.setAnchor(ControlAnchor.BOTTOMRIGHT);
		button1.setLocation(new Point(324, 4));
		button1.setSize(new Point(92, 24));
		button1.setTabIndex(2);
		button1.setText("Cancel");
		button1.addOnClick(new EventHandler(this.button1_click));

		columnHeader1.setText("columnHeader1");
		columnHeader1.setWidth(116);

		listView1.setDock(ControlDock.LEFT);
		listView1.setSize(new Point(208, 144));
		listView1.setTabIndex(0);
		listView1.setText("listView1");
		listView1.setFullRowSelect(true);
		listView1.setHeaderStyle(ColumnHeaderStyle.NONE);
		listView1.setHideSelection(false);
		listView1.setLargeImageList(imageList1);
		listView1.setSmallImageList(imageList1);
		listView1.setView(ViewEnum.REPORT);
		listView1.setColumns(new ColumnHeader[] {
							 columnHeader1});
		listView1.addOnClick(new EventHandler(this.listView1_click));
		listView1.addOnDoubleClick(new EventHandler(this.listView1_doubleClick));

		btnAdd.setAnchor(ControlAnchor.BOTTOMRIGHT);
		btnAdd.setLocation(new Point(228, 4));
		btnAdd.setSize(new Point(92, 24));
		btnAdd.setTabIndex(1);
		btnAdd.setText("Add");
		btnAdd.addOnClick(new EventHandler(this.btnAdd_click));

		button3.setAnchor(ControlAnchor.BOTTOMRIGHT);
		button3.setLocation(new Point(128, 4));
		button3.setSize(new Point(92, 24));
		button3.setTabIndex(0);
		button3.setText("OK");
		button3.addOnClick(new EventHandler(this.button2_click));

		this.setNewControls(new Control[] {
							splitter2, 
							richEdit1, 
							panel1});
		panel1.setNewControls(new Control[] {
							  splitter1, 
							  listView1, 
							  listBox1, 
							  panel2});
		panel2.setNewControls(new Control[] {
							  button3, 
							  btnAdd, 
							  button1});
	}

	/**
	 * Punto di ingresso principale per l'applicazione. 
	 *
	 * @param args Matrice di parametri passata all'applicazione
	 * tramite la riga di comando.
	 */
	public static void main(String args[])
	{
		Application.run(new ExpressionGeneratorForm(null));
	}
}
