/* ===============================================================================
 *
 * Part of the InfoGlue Content Management Platform (www.infoglue.org)
 *
 * ===============================================================================
 *
 *  Copyright (C)
 * 
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License version 2, as published by the
 * Free Software Foundation. See the file LICENSE.html for more information.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY, including 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 org.infoglue.cmsinstaller;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

/**
 * This is the database dialog.
 */

public class DatabaseDialog extends JPanel implements ActionListener
{
	private InfoGlueInstaller infoglueInstaller = null;
	
	private final static String introductionHeader  = "Database setup";
	private final static String introductionMessage = "For the system to work you will have to state which database you wish to use. All fields have a help texts if you click on the question mark next to it.";
	
	//private final static String createDatabaseLabel = "Do you want us to create a new InfoGlue instance in the given database? If yes, supply the information needed below so we can access the database as a priviliged user.";
	private final static String createDatabaseLabel = "The installer can automatically create a database and set up some basic data to make the basic functionality and examples work. If you would like the installer to do these tasks you mark the options you want below and then supply the installer with an administrative db-account. The account must have rights to create databases and tables on the server stated above.";
	private final static String createInitialDataLabel = "The installer can automatically create a database and set up some basic data to make the basic functionality and examples work. If you would like the installer to do these tasks you mark the options you want below and then supply the installer with an administrative db-account. The account must have rights to create databases and tables on the server stated above.";
	private final static String upgradeDatabaseEncodingLabelText = "Upgrade to utf-8?";
	
	private final static String databaseLabel           = "Database type"; 
	private final static String databaseNameLabel       = "Database name"; 
	private final static String databaseSuffixLabel     = "Database suffix"; 
	private final static String databaseDriverNameLabel = "Database driver name"; 
	private final static String databaseServerLabel     = "Database server"; 
	private final static String databasePortLabel     	= "Database port"; 
	private final static String databaseInstanceLabel   = "Database instance"; 
	private final static String databaseUserLabel       = "DBA name"; 
	private final static String databasePasswordLabel   = "DBA password"; 
	private final static String infoGluePasswordLabel   = "InfoGlue password"; 
	//private final static String upgradeDatabaseEncodingLabelText   = "Convert database"; 
	
	private final static Color fieldBackground = new Color(230, 230, 245);
	
	private JComboBox databaseCombo   			= null;
	private JTextField dbName         			= null;
	private JTextField dbSuffix       			= null;
	//private JComboBox dbDriverName    = null;
	private JTextField dbServer       			= null;
	private JTextField dbPort       			= null;
	private JTextField dbInstance      			= null;
	private JCheckBox createDatabase  			= null;
	private JCheckBox createInitialData			= null;
	private JCheckBox createExamples			= null;
	private JCheckBox upgradeDatabaseEncoding 	= null;
	private JTextField dbUser         			= null;
	private JPasswordField dbPassword 			= null;
	private JTextField infoGlueUserName 		= null;
	private JPasswordField infoGluePassword 	= null;
	
	private JTextArea errorMessage    = null;

	private int xPosLabels = 0;
	private int xPosLabelsWidth = 170;
	private int xPosValues = 180;
	private int xPosValuesWidth = 190;



	public DatabaseDialog(InfoGlueInstaller infoGlueInstaller)
	{
		this.infoglueInstaller = infoGlueInstaller;
		
		this.setSize(300, 430);
		this.setLayout(null);
		this.setBackground(Color.white);
		JLabel introductionLabel = new JLabel(introductionHeader);
		introductionLabel.setBounds(xPosLabels, 0, 400, 30);
		introductionLabel.setFont(new java.awt.Font("Dialog", java.awt.Font.BOLD, 16));
		
		JTextArea textArea = new JTextArea(introductionMessage); 
		textArea.setEditable(false);
		textArea.setBounds(xPosLabels, 30, 400, 40);
		textArea.setWrapStyleWord(true);
		textArea.setLineWrap(true);
		
		//here comes all input fields
		JLabel dbLabel = new JLabel(databaseLabel);
		dbLabel.setBounds(xPosLabels, 70, 130, 20);
		dbLabel.setToolTipText("<html>The database brand you wish to install InfoGlue on.</html>");
		databaseCombo = new JComboBox();
		this.databaseCombo.addActionListener(this);
		databaseCombo.addItem("MySQL");
		databaseCombo.addItem("SQL Server");
		databaseCombo.addItem("Oracle");
		databaseCombo.addItem("DB2");
		databaseCombo.setNextFocusableComponent(this.dbSuffix);
		databaseCombo.setBounds(xPosValues, 70, xPosValuesWidth, 20);
		HelpButton helpDBCombo = new HelpButton(dbLabel);
		helpDBCombo.setBounds(xPosValues + xPosValuesWidth + 2, 70, 20, 20);
		
		JLabel dbNameLabel = new JLabel(databaseNameLabel);
		dbNameLabel.setBounds(xPosLabels, 90, 130, 20);
		dbNameLabel.setToolTipText("<html>The name of the infoglue database. Only change this if you have a current installation you wish to use.</html>");
		//this.dbName = new JTextField("infoglue");
		this.dbName = new JTextField("infoglue");
		this.dbName.setBounds(xPosValues, 90, xPosValuesWidth, 20);
		this.dbName.setBackground(fieldBackground);
		HelpButton helpDBName = new HelpButton(dbNameLabel);
		helpDBName.setBounds(xPosValues + xPosValuesWidth + 2, 90, 20, 20);

		JLabel dbSuffixLabel = new JLabel(databaseSuffixLabel);
		dbSuffixLabel.setBounds(xPosLabels, 110, 130, 20);
		dbSuffixLabel.setToolTipText("<html>This field gives you an option to add a suffix to the database name<br>so you can have more than one InfoGlue installation in the same database.<br>Used primarily in hosting services.</html>");
		this.dbSuffix = new JTextField("");
		this.dbSuffix.setBounds(xPosValues, 110, xPosValuesWidth, 20);
		this.dbSuffix.setBackground(fieldBackground);
		this.dbSuffix.setNextFocusableComponent(this.dbServer);
		HelpButton helpDBSuffix = new HelpButton(dbSuffixLabel);
		helpDBSuffix.setBounds(xPosValues + xPosValuesWidth + 2, 110, 20, 20);

		JLabel dbServerLabel = new JLabel(databaseServerLabel);
		dbServerLabel.setBounds(xPosLabels, 130, 130, 20);
		dbServerLabel.setToolTipText("<html>The hostname of the database server on which the database is located.<br>Can be an IP or a hostname.</html>");
		this.dbServer = new JTextField("localhost");
		//this.dbServer = new JTextField("dev2.sprawlsolutions.se");
		this.dbServer.setBounds(xPosValues, 130, xPosValuesWidth, 20);
		this.dbServer.setBackground(fieldBackground);
		this.dbServer.setNextFocusableComponent(this.infoGluePassword);
		HelpButton helpDBServer = new HelpButton(dbServerLabel);
		helpDBServer.setBounds(xPosValues + xPosValuesWidth + 2, 130, 20, 20);

		JLabel dbPortLabel = new JLabel(databasePortLabel);
		dbPortLabel.setBounds(xPosLabels, 150, 130, 20);
		dbPortLabel.setToolTipText("<html>The database portnumber.</html>");
		this.dbPort = new JTextField("3306");
		this.dbPort.setBounds(xPosValues, 150, xPosValuesWidth, 20);
		this.dbPort.setBackground(fieldBackground);
		this.dbPort.setNextFocusableComponent(this.infoGluePassword);
		HelpButton helpDBPort = new HelpButton(dbPortLabel);
		helpDBPort.setBounds(xPosValues + xPosValuesWidth + 2, 150, 20, 20);
		
		JLabel dbInstanceLabel = new JLabel(databaseInstanceLabel);
		dbInstanceLabel.setBounds(xPosLabels, 170, 130, 20);
		dbInstanceLabel.setToolTipText("<html>The database instance - only applies to SQL SERVER.</html>");
		this.dbInstance = new JTextField("");
		this.dbInstance.setBounds(xPosValues, 170, xPosValuesWidth, 20);
		this.dbInstance.setBackground(fieldBackground);
		this.dbInstance.setNextFocusableComponent(this.infoGluePassword);
		this.dbInstance.setEnabled(false);
		HelpButton helpDBInstance = new HelpButton(dbInstanceLabel);
		helpDBInstance.setBounds(xPosValues + xPosValuesWidth + 2, 170, 20, 20);

		JLabel infoglueDBUserNameLabel = new JLabel("InfoGlue username");
		infoglueDBUserNameLabel.setBounds(xPosLabels, 190, 130, 20);
		infoglueDBUserNameLabel.setToolTipText("<html>The username InfoGlue is to use for connecting to the database.<br>If you want to upgrade an existing installation you need to supply the username used there.<br>The username is not related to what users use to log into the CMS with.</html>");
		//this.infoGlueUserName = new JTextField("infoglue");
		this.infoGlueUserName = new JTextField("INFOGLUE_CMS");
		this.infoGlueUserName.setBounds(xPosValues, 190, xPosValuesWidth, 20);
		this.infoGlueUserName.setBackground(fieldBackground);
		this.infoGlueUserName.setNextFocusableComponent(this.infoGluePassword);
		HelpButton helpInfoGlueUserName = new HelpButton(infoglueDBUserNameLabel);
		helpInfoGlueUserName.setBounds(xPosValues + xPosValuesWidth + 2, 190, 20, 20);

		JLabel infoglueDBPasswordLabel = new JLabel(infoGluePasswordLabel);
		infoglueDBPasswordLabel.setBounds(xPosLabels, 210, 130, 20);
		infoglueDBPasswordLabel.setToolTipText("<html>The password InfoGlue is to use for connecting to the database.<br>This password is not related to what users use to log into the CMS with.</html>");
		//this.infoGluePassword = new JPasswordField();
		this.infoGluePassword = new JPasswordField("INFOGLUEPASS");
		this.infoGluePassword.setBounds(xPosValues, 210, xPosValuesWidth, 20);
		this.infoGluePassword.setBackground(fieldBackground);
		this.infoGluePassword.setNextFocusableComponent(this.createDatabase);
		//this.infogluePassword.setEnabled(false);
		HelpButton helpInfoGluePassword = new HelpButton(infoglueDBPasswordLabel);
		helpInfoGluePassword.setBounds(xPosValues + xPosValuesWidth + 2, 210, 20, 20);

		JTextArea createDBIntroTextArea = new JTextArea(createDatabaseLabel);
		createDBIntroTextArea.setEditable(false);
		createDBIntroTextArea.setBounds(xPosLabels, 235, 200 + xPosValuesWidth, 100);
		createDBIntroTextArea.setWrapStyleWord(true);
		createDBIntroTextArea.setLineWrap(true);
		
		JLabel dbCreateDatabaseLabel = new JLabel("Create database");
		dbCreateDatabaseLabel.setBounds(xPosLabels, 340, 130, 20);
		dbCreateDatabaseLabel.setToolTipText("<html>Do you wish to install a new InfoGlue database?<br>If you allready have a infoglue installation and <br>wish to keep the data you probably don't want to.</html>");
		this.createDatabase = new JCheckBox("Yes");
		createDatabase.setBackground(Color.white);
		this.createDatabase.setBounds(xPosValues, 340, xPosValuesWidth, 20);
		this.createDatabase.addActionListener(this);
		this.createDatabase.setNextFocusableComponent(this.createInitialData);
		HelpButton helpDBCreate = new HelpButton(dbCreateDatabaseLabel);
		helpDBCreate.setBounds(xPosValues + xPosValuesWidth + 2, 340, 20, 20);

		JLabel dbCreateTablesLabel = new JLabel("Create tables and initial data");
		dbCreateTablesLabel.setBounds(xPosLabels, 360, xPosLabelsWidth, 20);
		dbCreateTablesLabel.setToolTipText("<html>Do you wish to setup the infoglue tables and initial data?<br>If you allready have a infoglue installation and <br>wish to keep the data you probably don't want to.</html>");
		this.createInitialData = new JCheckBox("Yes");
		this.createInitialData.setBackground(Color.white);
		this.createInitialData.setBounds(xPosValues, 360, xPosValuesWidth, 20);
		this.createInitialData.addActionListener(this);
		this.createInitialData.setNextFocusableComponent(this.createExamples);
		HelpButton helpDBCreateInitialData = new HelpButton(dbCreateTablesLabel);
		helpDBCreateInitialData.setBounds(xPosValues + xPosValuesWidth + 2, 360, 20, 20);

		JLabel dbCreateExamplesLabel = new JLabel("Create example sites");
		dbCreateExamplesLabel.setBounds(xPosLabels, 380, xPosLabelsWidth, 20);
		dbCreateExamplesLabel.setToolTipText("<html>Do you wish to install the example sites.</html>");
		this.createExamples = new JCheckBox("Yes");
		this.createExamples.setBackground(Color.white);
		this.createExamples.setBounds(xPosValues, 380, xPosValuesWidth, 20);
		this.createExamples.addActionListener(this);
		this.createExamples.setNextFocusableComponent(this.dbUser);
		HelpButton helpDBCreateExamples = new HelpButton(dbCreateExamplesLabel);
		helpDBCreateExamples.setBounds(xPosValues + xPosValuesWidth + 2, 380, 20, 20);

		JLabel upgradeDatabaseEncodingLabel = new JLabel(upgradeDatabaseEncodingLabelText);
		upgradeDatabaseEncodingLabel.setBounds(xPosLabels, 400, 130, 20);
		upgradeDatabaseEncodingLabel.setToolTipText("<html>When users in 1.0, 1.1 and 1.2 of InfoGlue stored non-ascii-characters it was most likely encoded as ISO-8859-1.<br>This is not a very good approach and this version operates with full Unicode(utf-8).<br>Because of this we need to upgrade your database content if you have non-ascii (special international characters).<br>If you do not convert the data the special charaters will look broken in the tools and on the site until you correct them manually in the tools.</html>");
		this.upgradeDatabaseEncoding = new JCheckBox("Yes");
		this.upgradeDatabaseEncoding.setBounds(xPosValues, 400, xPosValuesWidth, 20);
		this.upgradeDatabaseEncoding.setBackground(Color.white);
		this.upgradeDatabaseEncoding.setNextFocusableComponent(this.createDatabase);
		this.upgradeDatabaseEncoding.addActionListener(new AlertActionListener(this, "As this operation can seriously affect your data you must backup your database before continuing.", "Backup database", JOptionPane.WARNING_MESSAGE));
		HelpButton helpUpgradeDatabaseEncoding = new HelpButton(upgradeDatabaseEncodingLabel);
		helpUpgradeDatabaseEncoding.setBounds(xPosValues + xPosValuesWidth + 2, 400, 20, 20);

		JLabel dbUserLabel = new JLabel(databaseUserLabel);
		dbUserLabel.setBounds(xPosLabels, 420, 130, 20);
		dbUserLabel.setToolTipText("<html>The root username to the database.<br>InfoGlue needs it to be able to create the database.</html>");
		//this.dbUser = new JTextField("root");
		this.dbUser = new JTextField("root");
		this.dbUser.setBounds(xPosValues, 420, xPosValuesWidth, 20);
		this.dbUser.setEnabled(false);
		this.dbUser.setBackground(fieldBackground);
		this.dbUser.setNextFocusableComponent(this.dbPassword);
		HelpButton helpDBUser = new HelpButton(dbUserLabel);
		helpDBUser.setBounds(xPosValues + xPosValuesWidth + 2, 420, 20, 20);
		
		JLabel dbPasswordLabel = new JLabel(databasePasswordLabel);
		dbPasswordLabel.setBounds(xPosLabels, 440, 130, 20);
		dbPasswordLabel.setToolTipText("<html>The root password to the database.<br>InfoGlue needs it to be able to create the database.</html>");
		//this.dbPassword = new JPasswordField();
		this.dbPassword = new JPasswordField("");
		this.dbPassword.setBounds(xPosValues, 440, xPosValuesWidth, 20);
		this.dbPassword.setEnabled(false);
		this.dbPassword.setBackground(fieldBackground);
		HelpButton helpDBPassword = new HelpButton(dbPasswordLabel);
		helpDBPassword.setBounds(xPosValues + xPosValuesWidth + 2, 440, 20, 20);

		/*
		JTextArea upgradeDatabaseEncodingIntro = new JTextArea(upgradeDatabaseEncodingIntroductionText); 
		upgradeDatabaseEncodingIntro.setEditable(false);
		upgradeDatabaseEncodingIntro.setBounds(xPosLabels, 330, 200 + xPosValuesWidth, 50);
		upgradeDatabaseEncodingIntro.setWrapStyleWord(true);
		upgradeDatabaseEncodingIntro.setLineWrap(true);
		*/
		
		//JOptionPane.showMessageDialog(this, "You must backup your database before continuing.", "Backup database", JOptionPane.WARNING_MESSAGE);

		this.errorMessage = new JTextArea("");
		this.errorMessage.setForeground(Color.red);
		this.errorMessage.setEditable(false);
		this.errorMessage.setBounds(xPosLabels, 460, 450, 60);
		this.errorMessage.setWrapStyleWord(true);
		this.errorMessage.setLineWrap(true);
		
		this.add(introductionLabel);
		this.add(textArea);
		this.add(dbLabel);
		this.add(databaseCombo);
		this.add(helpDBCombo);
		this.add(dbNameLabel);
		this.add(dbName);
		this.add(helpDBName);
		this.add(dbSuffixLabel);
		this.add(dbSuffix);
		this.add(helpDBSuffix);
		this.add(createDBIntroTextArea);
		
		//this.add(dbDriverNameLabel);
		//this.add(dbDriverName);
		this.add(dbServerLabel);
		this.add(dbServer);
		this.add(helpDBServer);
		this.add(dbPortLabel);
		this.add(dbPort);
		this.add(helpDBPort);
		this.add(dbInstanceLabel);
		this.add(dbInstance);
		this.add(helpDBInstance);
		
		this.add(dbCreateDatabaseLabel);
		this.add(createDatabase);
		this.add(helpDBCreate);
		this.add(dbCreateTablesLabel);
		this.add(createInitialData);
		this.add(dbCreateExamplesLabel);
		this.add(createExamples);
		this.add(helpDBCreateInitialData);
		this.add(helpDBCreateExamples);

		this.add(dbUserLabel);
		this.add(dbUser);
		this.add(helpDBUser);

		this.add(dbPasswordLabel);
		this.add(dbPassword);
		this.add(helpDBPassword);

		this.add(infoglueDBUserNameLabel);
		this.add(infoGlueUserName);
		this.add(helpInfoGlueUserName);

		this.add(infoglueDBPasswordLabel);
		this.add(infoGluePassword);
		this.add(helpInfoGluePassword);
		
		
		//this.add(upgradeDatabaseEncodingIntro);
		this.add(upgradeDatabaseEncodingLabel);
		this.add(upgradeDatabaseEncoding);
		this.add(helpUpgradeDatabaseEncoding);
		
		
		this.add(errorMessage);
		
		infoglueInstaller.setBackButtonCommand("ShowIntroductionDialog");
		infoGlueInstaller.setNextButtonCommand("ShowServerDialog");
	}	
	
	
	public void actionPerformed(ActionEvent e)
	{
		if(e.getSource().equals(this.databaseCombo))
        {
        	if(this.dbPort != null)
        	{
        		if(this.getDatabaseTypeName().equalsIgnoreCase("MySQL"))
        		{
        			this.dbPort.setText("3306");
        		}
        		else if(this.getDatabaseTypeName().equalsIgnoreCase("SQL Server"))
        		{
        			this.dbPort.setText("1433");
        			this.dbInstance.setEnabled(true);
        		}
        		else if(this.getDatabaseTypeName().equalsIgnoreCase("Oracle"))
        		{
        			this.dbPort.setText("1521");
        		}
        		else if(this.getDatabaseTypeName().equalsIgnoreCase("DB2"))
        		{
        			this.dbPort.setText("50000");
        		}
        		else 
        		{
        			this.dbPort.setText("not_valid");
        		}
        	}
        }
		else if(this.createDatabase != null && (this.createDatabase.isSelected() || this.createInitialData.isSelected() || this.createExamples.isSelected()))
		{      
			this.dbUser.setEnabled(true);
			this.dbPassword.setEnabled(true);
			//this.infogluePassword.setEnabled(true);
			this.upgradeDatabaseEncoding.setEnabled(false);
		}
		else if(this.createDatabase != null && (!this.createDatabase.isSelected() && !this.createInitialData.isSelected() && !this.createExamples.isSelected()))
		{
			this.dbUser.setEnabled(false);
			this.dbPassword.setEnabled(false);
			////this.infogluePassword.setEnabled(false);
			this.upgradeDatabaseEncoding.setEnabled(true);
		}
	}
	
	public void setErrorMessage(String errorMessage)
	{
		this.errorMessage.setText("An error made the installation stop: \n" + errorMessage);
	}
	
	public String getDatabaseTypeName()
	{
		return this.databaseCombo.getSelectedItem().toString();
	}
	
	public String getDatabaseName()
	{
		return this.dbName.getText();
	}
	
	public String getDatabaseDriverName()
	{
		if(getDatabaseTypeName().equalsIgnoreCase("MySQL"))
			return "com.mysql.jdbc.Driver";
		else if(getDatabaseTypeName().equalsIgnoreCase("SQL Server"))
			return "net.sourceforge.jtds.jdbc.Driver";
			//return "com.microsoft.jdbc.sqlserver.SQLServerDriver";
		else if(getDatabaseTypeName().equalsIgnoreCase("Oracle"))
			return "oracle.jdbc.driver.OracleDriver";
		else if(getDatabaseTypeName().equalsIgnoreCase("DB2"))
			return "com.ibm.db2.jcc.DB2Driver";
		else
			return "";
	}

	public String getDatabaseDialectName()
	{
		if(getDatabaseTypeName().equalsIgnoreCase("MySQL"))
			return "net.sf.hibernate.dialect.MySQLDialect";
		else if(getDatabaseTypeName().equalsIgnoreCase("SQL Server"))
			return "net.sf.hibernate.dialect.SQLServerDialect";
			//return "com.microsoft.jdbc.sqlserver.SQLServerDriver";
		else if(getDatabaseTypeName().equalsIgnoreCase("Oracle"))
			return "net.sf.hibernate.dialect.OracleDialect";
		else if(getDatabaseTypeName().equalsIgnoreCase("DB2"))
			return "net.sf.hibernate.dialect.DB2Dialect";
		else
			return "";
	}

	public String getDatabaseServer()
	{
		return this.dbServer.getText();
	}

	public String getDatabasePort()
	{
		return this.dbPort.getText();
	}

	public String getDatabaseInstance()
	{
		return this.dbInstance.getText();
	}

	public String getDatabaseUser()
	{
		return this.dbUser.getText();
	}
	
	public String getDatabasePassword()
	{
		return this.dbPassword.getText();
	}

	public String getInfoGluePassword()
	{
		return this.infoGluePassword.getText();
	}

	public boolean getCreateDatabase()
	{
		return createDatabase.isSelected();
	}
	
	public boolean getCreateInitialData()
	{
		return createInitialData.isSelected();
	}

	public boolean getCreateExamples()
	{
		return createExamples.isSelected();
	}
	
	public String getDbSuffix()
	{
		return dbSuffix.getText();
	}

	public boolean getUpgradeDatabaseEncoding()
	{
		return upgradeDatabaseEncoding.isSelected();
	}

	public String getInfoGlueUserName()
	{
		return this.infoGlueUserName.getText();
	}
	
	public void paint(Graphics g) 
	{
	    Graphics2D g2 = (Graphics2D)g;
		g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

		super.paint(g);
	}

}