/*
 *  iReport  --  Visual designer for generating JasperReports Documents
 *  Copyright (C) 2002  Giulio Toffoli gt@businesslogic.it
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Giulio Toffoli
 *  Via T.Aspetti, 233
 *  35100 Padova ITALY
 *  gt@businesslogic.it
 */
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.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 "ClasspathForm"
 * non viene creato nel metodo main().
 */
public class ClasspathForm extends Form
{
	MainForm mf=null;
	boolean modified_jvm=false;
	boolean modified_sjvm=false;
	boolean modified_jdk=false;
	public ClasspathForm(MainForm mf)
	{
		super();
		this.mf = mf;
		// Necessario per il supporto della finestra di progettazione form di Visual J++
		initForm();		

		String sb="";
		StringBuffer sbx = new StringBuffer(1024*32);
		GetEnvironmentVariable("classpath",sbx,1024*32);
		
		java.util.StringTokenizer st = new java.util.StringTokenizer(sbx+"",";",false);
		while (st.hasMoreTokens())
		{
			listBox2.addItem(st.nextToken());
		}
		
		com.ms.wfc.app.RegistryKey  ks =  com.ms.wfc.app.Registry.LOCAL_MACHINE;
		ks = ks.getSubKey("Software\\Microsoft\\Java VM");
		String[] vals = ks.getValueNames();
		sb = (String)ks.getValue("Classpath");
	
		st = new java.util.StringTokenizer(sb+"",";",false);
		while (st.hasMoreTokens())
		{
			listBox1.addItem(st.nextToken());
		}
		
		String java_home = (String)mf.connProperties.get("JAVA_HOME");
		
		if (java_home == null)
		{
			java_home = searchJavaHome();	
		}
		
		editJavaHome.setText( java_home );
		
		// TODO: aggiungere il codice del costruttore dopo la chiamata di initForm.
	}
	
	/** @dll.import("KERNEL32") */
	public static native int GetEnvironmentVariable(String name, 
                              StringBuffer value, int ccbValue);
	/** @dll.import("KERNEL32") */
	public static native int SetEnvironmentVariable(String name, 
                              String value);

	/**
	 * ClasspathForm esegue l'overriding di dispose e quindi può svuotare
	 * l'elenco dei componenti.
	 */
	public void dispose()
	{
		super.dispose();
		components.dispose();
	}

	private void button3_click(Object source, Event e)
	{
		this.dispose();
	}

	private void button1_click(Object source, Event e)
	{
		OpenFileDialog ofd = new OpenFileDialog();
		ofd.setFilter("Java archive (JAR)|*.jar|Zip|*.zip");
		
		if (ofd.showDialog() == DialogResult.OK)
		{
			this.listBox1.addItem( ofd.getFileName());
			modified_jvm = true;
		}
	}
	
	public void updateClasspath()
	{
		String val ="";
		for (int i=0; i<listBox1.getItemCount(); ++i)
		{
			if (i>0) val += ";";
			val += listBox1.getItem(i);
		}
		//SetEnvironmentVariable("CLASSPATH",val);
		//HKEY_LOCAL_MACHINE\Software\Microsoft\Java VM\Classpath
		com.ms.wfc.app.RegistryKey ks =  com.ms.wfc.app.Registry.LOCAL_MACHINE;
		ks = ks.getSubKey("SOFTWARE",false);
		ks = ks.getSubKey("Microsoft",false);
		ks = ks.getSubKey("Java VM",false);
		if (ks != null)
		{
			ks.setValue("Classpath",val);
		}
		MessageBox.show("You must restart iReport for the changes to take effect.","",MessageBox.ICONWARNING); 
	}
	
	public void saveClasspath()
	{
		String val ="";
		for (int i=0; i<listBox2.getItemCount(); ++i)
		{
			if (i>0) val += ";";
			val += listBox2.getItem(i);
		}
		SetEnvironmentVariable("classpath",val);
		
		// Save classpath to properties....
		mf.connProperties.put("CLASSPATH",val);
		mf.connProperties.put("JAVA_HOME", editJavaHome.getText() );
		saveConnections();	
		
	}
	
	public void saveConnections()
	{
		try {
			FileOutputStream fos = new FileOutputStream(mf.propfile_name);
			mf.connProperties.save( fos, "#Connection properties");
			fos.close();
		} catch (Exception ex)
		{
			MessageBox.show("Errore: "+ex.getMessage(),"",MessageBox.ICONERROR);
		}	
	}

	private void button2_click(Object source, Event e)
	{
		com.businesslogic.ireport.ui.directorydialog.FileExplorer fe = new com.businesslogic.ireport.ui.directorydialog.FileExplorer(this.mf.programDir);
		if (fe.showDialog() == DialogResult.OK)
		{
			this.listBox1.addItem( fe.getDirectory() );
			modified_jvm = true;
		}
	}


	private void button4_click(Object source, Event e)
	{
		OpenFileDialog ofd = new OpenFileDialog();
		ofd.setFilter("Java archive (JAR)|*.jar|Zip|*.zip");
		
		if (ofd.showDialog() == DialogResult.OK)
		{
			this.listBox2.addItem( ofd.getFileName());
			modified_sjvm = true;
		}
	}

	private void button5_click(Object source, Event e)
	{
		com.businesslogic.ireport.ui.directorydialog.FileExplorer fe = new com.businesslogic.ireport.ui.directorydialog.FileExplorer(this.mf.programDir);
		if (fe.showDialog() == DialogResult.OK)
		{
			this.listBox2.addItem( fe.getDirectory() );
			modified_sjvm = true;
		}
	}

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

	private void button6_click(Object source, Event e)
	{
		
		if (listBox2.getSelectedIndex()> -1)
		{
			listBox2.removeItem( listBox2.getSelectedItem());
			saveClasspath();
			modified_sjvm = true;
		}	
	
	}

	private void button7_click(Object source, Event e)
	{
		if (listBox1.getSelectedIndex()> -1)
		{
			listBox1.removeItem( listBox1.getSelectedItem());
			modified_jvm = true;
		}
	}

	private void button8_click(Object source, Event e)
	{
		com.businesslogic.ireport.ui.directorydialog.FileExplorer fe = new com.businesslogic.ireport.ui.directorydialog.FileExplorer(this.mf.programDir);
		if (fe.showDialog() == DialogResult.OK)
		{
			this.editJavaHome.setText(fe.getDirectory());
			modified_jdk = true;
		}
	}
	
	public String searchJavaHome()
	{
		com.ms.wfc.app.RegistryKey ks =  com.ms.wfc.app.Registry.LOCAL_MACHINE;
		ks = ks.getSubKey("SOFTWARE");
		String java_home="";
		com.ms.wfc.app.RegistryKey k = ks;
		boolean nojava = false;
		if (k==null) return "";
		else
		{
			//2) Ricerca Standard Edition...
			//if (nojava)
			//Prendiamo la versione più recente...
			String tmp_version="";
			String ex_java_version="";
			{  
				k = ks;
				k = k.getSubKey("JavaSoft");
				if (k ==null) nojava = true;
				else
				{
					// Prendiamo l'indirizzo di Java Development kit
					k = k.getSubKey("Java Development Kit");
					if (k==null) nojava = true;
					else {
						String[] versioni = k.getSubKeyNames();
						for (int i=0; i< versioni.length; ++i)
						{
							if (tmp_version.compareTo(versioni[i]) < 0)
							{
								tmp_version = versioni[i];
							}
						}
						if (tmp_version.compareTo("1.3")<0) nojava=true;
						else if (tmp_version.length() > 0)
						{
							ex_java_version =tmp_version;
							k = k.getSubKey(tmp_version);
							java_home = (String)k.getValue("JavaHome","");
							//java_version = "Java Development Kit v."+tmp_version;
							nojava=false;
						}
						else
							nojava=true;
					} 
				}
			}	
			
			//3) Ricerca del runtime...
			//if (nojava)
			{
				k = ks;
				k = k.getSubKey("JavaSoft");
				if (k ==null);
				else
				{
					// Prendiamo l'indirizzo di Java Runtime Environment
					k = k.getSubKey("Java Runtime Environment");
					if (k==null);
					else {
						
						String[] versioni = k.getSubKeyNames();
						for (int i=0; i< versioni.length; ++i)
						{
							if (tmp_version.compareTo(versioni[i]) < 0)
							{
								tmp_version = versioni[i];
							}
						}	 
						if (tmp_version.compareTo("1.3")<0 || tmp_version.compareTo(ex_java_version)<=0);
						else if (tmp_version.length() > 0)
						{
							ex_java_version =tmp_version;
							k = k.getSubKey(tmp_version);
							java_home = (String)k.getValue("JavaHome","");
							//java_version = "Java Runtime Environment v."+tmp_version;
							//java_dll = (String)k.getValue("RuntimeLib","");
							nojava=false;
						}
					}
				}
			}
			if (nojava) return "";
			else return java_home;
				
		}
	}

	private void button10_click(Object source, Event e)
	{
		button9_click(source, e);
		this.dispose();
	}

	private void button9_click(Object source, Event e)
	{
		if (modified_jdk || modified_sjvm)
			saveClasspath();
		if (modified_jvm)
			updateClasspath();
	}

	private void editJavaHome_textChanged(Object source, Event e)
	{
		modified_jdk = true;
	}

	/**
	 * 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();
	ListBox listBox1 = new ListBox();
	Label label1 = new Label();
	Button button1 = new Button();
	Button button2 = new Button();
	Button button3 = new Button();
	ListBox listBox2 = new ListBox();
	Button button4 = new Button();
	Button button5 = new Button();
	GroupBox groupBox1 = new GroupBox();
	Button button6 = new Button();
	Button button7 = new Button();
	Label label2 = new Label();
	Edit editJavaHome = new Edit();
	Button button8 = new Button();
	Label label3 = new Label();
	Button button9 = new Button();
	Button button10 = new Button();

	private void initForm()
	{
		this.setText("Classpath");
		this.setAutoScaleBaseSize(new Point(5, 13));
		this.setBorderStyle(FormBorderStyle.FIXED_TOOLWINDOW);
		this.setClientSize(new Point(627, 334));

		listBox1.setLocation(new Point(4, 20));
		listBox1.setSize(new Point(512, 43));
		listBox1.setTabIndex(0);
		listBox1.setText("listBox1");
		listBox1.setUseTabStops(true);

		label1.setLocation(new Point(4, 4));
		label1.setSize(new Point(124, 16));
		label1.setTabIndex(14);
		label1.setTabStop(false);
		label1.setText("Classpath MS JVM");

		button1.setLocation(new Point(524, 20));
		button1.setSize(new Point(96, 24));
		button1.setTabIndex(3);
		button1.setText("Add JAR file");
		button1.addOnClick(new EventHandler(this.button1_click));

		button2.setLocation(new Point(524, 48));
		button2.setSize(new Point(96, 24));
		button2.setTabIndex(4);
		button2.setText("Add directory");
		button2.addOnClick(new EventHandler(this.button2_click));

		button3.setLocation(new Point(524, 304));
		button3.setSize(new Point(96, 24));
		button3.setTabIndex(13);
		button3.setText("Cancel");
		button3.addOnClick(new EventHandler(this.button3_click));

		listBox2.setLocation(new Point(4, 84));
		listBox2.setSize(new Point(512, 147));
		listBox2.setTabIndex(1);
		listBox2.setText("listBox1");
		listBox2.setColumnWidth(200);
		listBox2.setUseTabStops(true);
		listBox2.addOnSelectedIndexChanged(new EventHandler(this.listBox2_selectedIndexChanged));

		button4.setLocation(new Point(524, 140));
		button4.setSize(new Point(96, 24));
		button4.setTabIndex(6);
		button4.setText("Add JAR file");
		button4.addOnClick(new EventHandler(this.button4_click));

		button5.setLocation(new Point(524, 168));
		button5.setSize(new Point(96, 24));
		button5.setTabIndex(7);
		button5.setText("Add directory");
		button5.addOnClick(new EventHandler(this.button5_click));

		groupBox1.setLocation(new Point(8, 292));
		groupBox1.setSize(new Point(612, 4));
		groupBox1.setTabIndex(15);
		groupBox1.setTabStop(false);
		groupBox1.setText("");

		button6.setLocation(new Point(524, 196));
		button6.setSize(new Point(96, 24));
		button6.setTabIndex(8);
		button6.setText("Remove");
		button6.addOnClick(new EventHandler(this.button6_click));

		button7.setLocation(new Point(524, 76));
		button7.setSize(new Point(96, 24));
		button7.setTabIndex(5);
		button7.setText("Remove");
		button7.addOnClick(new EventHandler(this.button7_click));

		label2.setLocation(new Point(4, 68));
		label2.setSize(new Point(124, 16));
		label2.setTabIndex(12);
		label2.setTabStop(false);
		label2.setText("Classpath (env variable)");

		editJavaHome.setLocation(new Point(4, 260));
		editJavaHome.setSize(new Point(512, 20));
		editJavaHome.setTabIndex(2);
		editJavaHome.setText("");
		editJavaHome.addOnTextChanged(new EventHandler(this.editJavaHome_textChanged));

		button8.setLocation(new Point(524, 256));
		button8.setSize(new Point(92, 24));
		button8.setTabIndex(9);
		button8.setText("Search...");
		button8.addOnClick(new EventHandler(this.button8_click));

		label3.setLocation(new Point(4, 244));
		label3.setSize(new Point(128, 16));
		label3.setTabIndex(16);
		label3.setTabStop(false);
		label3.setText("Java home");

		button9.setLocation(new Point(428, 304));
		button9.setSize(new Point(88, 24));
		button9.setTabIndex(11);
		button9.setText("Apply");
		button9.addOnClick(new EventHandler(this.button9_click));

		button10.setLocation(new Point(332, 304));
		button10.setSize(new Point(88, 24));
		button10.setTabIndex(10);
		button10.setText("Save");
		button10.addOnClick(new EventHandler(this.button10_click));

		this.setNewControls(new Control[] {
							button10, 
							button9, 
							label3, 
							button8, 
							editJavaHome, 
							label2, 
							button7, 
							button6, 
							groupBox1, 
							button5, 
							button4, 
							listBox2, 
							button3, 
							button2, 
							button1, 
							label1, 
							listBox1});
	}

	/**
	 * 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 ClasspathForm(null));
	}
}
