/*
 *
 * Copyright (C)  30-août-2003 Jean-Yves Beaujean 
 * 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.,  59
 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */


package jxtray;


import java.util.Enumeration;
import java.util.Properties;


import java.io.File;
import java.io.InputStream;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.IOException;


import jxtray.xmlconf.PropertiesContentHandler;
import jxtray.xmlconf.PropertiesWriter;

import java.awt.Font;
import javax.swing.UIManager;

import jxtray.connection.JxtConnectionManager;
import jxtray.connection.DriverCache;

import jxtray.gui.SplashScreen;

import jxtray.util.UIUtilities;

import org.xml.sax.ContentHandler;
import org.xml.sax.XMLReader;
import org.xml.sax.InputSource;
import org.xml.sax.helpers.XMLReaderFactory;

/**
 * 
 * @author Jean-Yves Beaujean
 * Main class. It contains the 'main' method.
 * 
 */
public class Jxtray
{
   
   /** User properities loaded from properties.xml */
   private static Properties props;
   /** Properties object that contains all traductions */
   private static Properties lang;
	
	/** Home directory = System.getProperty("user.home") */
	public static String HOME =System.getProperty("user.home")+File.separator+"."+JxtrayConstants.APPNAME+File.separator;
	/** App directory = System.getProperty("user.dir") */
	//public static String APPHOME =System.getProperty("user.dir")+File.separator;
	
	/** Application font */
	private static Font font;
   
    /** Directory where config files are located  */
    private static String pathConfFile;
    /** Connection Manager */
    private static JxtConnectionManager connectionManager;
    /** Driver Manager */
    private static DriverCache driverCache;
    /** SQLHistory Manager */
    private static SQLHistoryCache sqlhistoryCache;
    private static SplashScreen splash = null;
    /** Application main frame */
    private static JxtFrame mainFrame;
   
   /** Main constructor  */
   public Jxtray()
   {
   		

		/* Load drivers database */
		driverCache = DriverCache.getInstance();
		/* Load history file */
		sqlhistoryCache = SQLHistoryCache.getInstance();
		try
		{
			splash.setText(lang.getProperty("splash.drivers"));
			driverCache.loadDrivers();
			sqlhistoryCache.load();
			splash.setValue(65);
		}
		catch ( Exception e )
		{
			System.err.println("Jxtray-constructor : loading drivers : " + e );
			Messages.error("Jxtray-constructor : loading drivers : " + e+ ". Exit." );
			System.exit(0);
		}
		splash.setText(lang.getProperty("splash.connections"));
		connectionManager = JxtConnectionManager.getInstance();
		splash.setValue(80);
   }

  /** Main Method.
   *  1. Check User directory<br>
   *  2. Load XML files<br>
   *  3. Load Drivers<br>
   *  4. Create frame and load connections<br> 
   */
  public static void main(String[] args) 
  {
  		splash = new SplashScreen(null);
  		UIUtilities.center(splash);
  		splash.setVisible(true);
  		
		splash.setText("Checking USER directory...");
		try
		{
			checkUserDirectory();
			
		}
		catch ( Exception e )
		{
			System.err.println("Jxtray.main() : Error : "+ e );
			System.exit(0);
		}  		
		splash.setValue(25);
	    splash.setText("Load XML files...");
      
		try
		{
			props = new Properties();
			lang = new Properties();
			
			XMLReader reader = XMLReaderFactory.createXMLReader(JxtrayConstants.XMLPARSER);
	  		
			ContentHandler propsHandler = new  PropertiesContentHandler(props);
			reader.setContentHandler(propsHandler);
			InputSource inputSource = new InputSource("file:///"+HOME+"conf"+File.separator+"properties.xml");
			reader.parse(inputSource);
			
			propsHandler = new  PropertiesContentHandler(lang);
			reader.setContentHandler(propsHandler);
			inputSource = new InputSource(reader.getClass().getResourceAsStream("/share/lang/"+props.getProperty("lang").toLowerCase()+".xml"));
			reader.parse(inputSource);  
			
			font = new Font(props.getProperty("font.name"),0,Integer.parseInt(props.getProperty("font.size")));
			try
			{
				if (  props.getProperty("log.file.error").trim().length() > 0 && props.getProperty("log.file.error") != null )
						System.setErr(new PrintStream(new FileOutputStream(HOME+"log/"+props.getProperty("log.file.error") ),true ));
			}
			catch ( Exception e )
			{
				System.err.println("Jxtray.main() : Output Error redirection : " + e);
			}
			try
			{
				if (  props.getProperty("log.file.output").trim().length() > 0 && props.getProperty("log.file.output") != null )
							System.setOut(new PrintStream(new FileOutputStream(HOME+"log/"+props.getProperty("log.file.output") ),true ));
			}
			catch ( Exception e )
			{
				System.err.println("Jxtray.main() : Output redirection : " + e);
			}
			splash.setValue(45);
			splash.setText(lang.getProperty("splash.lookandfeel"));
			UIManager.setLookAndFeel(props.getProperty("lookandfeel"));
			splash.setValue(50);
		}
		
		
		catch ( Exception e )
		{
			Messages.error("Jxtray.main() : FATAL ERROR : Unable to load properties. Exit. ( exception = "+ e +")" );
			System.err.println("Jxtray.main() : FATAL ERROR : Unable to load properties. Exit. ( exception = "+ e +")" );
			System.exit(0);
		}
		
		Jxtray jxtray= new Jxtray();		
		splash.setText(lang.getProperty("splash.mainframe"));
		jxtray.launchFrame();
		
  }
  
  /** Modify a user property */
  public static void setProperty   ( String key, String val)  {  props.setProperty(key,val);  }
  
  /**
   *  Return a user property value
   * @param key
   * @return String
   */
  public static String getProperty(String key)    { return props.getProperty(key);   }
  public static String getLang(String key)    { return lang.getProperty(key);   }


  public static void setProperties   ( Properties p)  {  props = p;  }
  public static Properties getProperties   ()  {  return props;  }

  
  /**
   * Print all user properties.
   */
  public static void printProperties()
  {
		Enumeration names = props.propertyNames();
		while ( names.hasMoreElements() )
		{
			String key = (String) names.nextElement();
			System.out.println(key+" \t\t " + props.getProperty(key));
		}
  }  
  
  private void launchFrame()
  {
		splash.setValue(90);
		mainFrame = new JxtFrame();
		splash.setValue(95);
		UIUtilities.center(mainFrame);
		splash.setValue(100);
		splash.setVisible(false);
		splash.stop();
		mainFrame.setVisible(true); 
  }
  
  /** Return the JxtFrame */
  public static JxtFrame getMainFrame() { return mainFrame; }
  

	/** Call an external command on the locate system */
	public static void exec ( String command )
	{
		  try
		  {
				Runtime run = Runtime.getRuntime();
				run.exec(command);
		  }
		  catch ( IOException e )
		  {
				 System.err.println("Jxtray.exec() :  " + e );
		  }
	}

	/**
	 * Print all user properties.
	 */

	public static void printSystemProperties()
	{
		  Properties ptmp = System.getProperties();
		  Enumeration names = ptmp.propertyNames();

		  while ( names.hasMoreElements() )
		  {
			  String key = (String) names.nextElement();
			  System.out.println(key+" \t\t " + ptmp.getProperty(key));
		  }
	}
	
	/** Save the user properties */
	public static void saveProperties()
	{
		PropertiesWriter.write(HOME+"conf"+File.separator+"properties.xml",props);
	}
	

  
/**
 * Return the Connection Manager
 * @return JxtConnectionManager
 */
	public static JxtConnectionManager getConnectionManager() {
	return connectionManager;
}

/**
 * 
 * @return DriverCache
 */
public static DriverCache getDriverCache() {
	return driverCache;
}

/**
 * 
 * @return SQLHistoryCache
 */
public static SQLHistoryCache getSQLHistoryCache() {
	return sqlhistoryCache;
}


/**
 * 
 * @return Font
 */
	public static Font getFont() {return font;}
	/**
	 * 
	 * @param f
	 */
	public static void setFont(Font f){	font = f;}
	
	
	/** Create the user directory. 
	 * 1. Create the following directory<br>
	 * HOME/.jxtray<br>
	 * HOME/.jxtray/log<br>
	 * HOME/.jxtray/conf<br>
	 * @throws Exception<br>
	 * 2. Copy the default XML files in this directory
	 */
	private static void checkUserDirectory() throws Exception 
	{
		File creation = new File(HOME);
		File test = new File(HOME);
		creation.mkdir();
		
		creation = new File(HOME+"conf");
		if ( !creation.exists())
			creation.mkdir();
		creation = new File(HOME+"log");
		if ( !creation.exists())
			creation.mkdir();
		
		InputStream in;
		FileOutputStream out;
		
		String[] fileName = {"connections.xml","dbdrivers.xml","properties.xml","sqlhistory.xml"};
		
		for ( int i=0; i < fileName.length;i++)
		{
			test = new File(HOME+"conf"+File.separator+fileName[i]);
			if ( !test.exists() )
			{
				// TODO : tester à fond ce code.
				in = test.getClass().getResourceAsStream("/share/default/"+fileName[i]);
				out = new FileOutputStream(HOME+"conf"+File.separator+fileName[i]);
				int bRead = -1;
				while ( (bRead = in.read()) != -1)
					out.write(bRead);
				out.close();
			}
		}
		
	}
	
	/** Upgrade or Add new properties if user properties file is older than this version.
	 *  It's possible that this function does nothing, but it always calls at start.   
	 */
	public void updateConfigFile()
	{
	}
	
	/** 
	 * Return the main icon program
	 * @return ImagIcon
	 */
	/*public static ImageIcon getIcon()
	{
		return new ImageIcon(APPHOME+"images"+File.separator+"icons"+File.separator+"jxtray.gif");
	}*/

} 
