/**
 * SettingsPanel.java
 * @date Jan 19, 2011
 * @author ricky barrette
 * @author Twenty Codes, LLC
 */
package com.TwentyCodes.java.OrderProcessor.UI;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;

import org.jasypt.util.text.BasicTextEncryptor;

import com.TwentyCodes.java.OrderProcessor.DB.OrderDB;

/**
 * this panel will be used to display and handle application settings
 * @author ricky barrette
 */
public class SettingsPanel extends JPanel implements ActionListener {

	private static final long serialVersionUID = 2568209868143577096L;
	public static final String IS_USING_REMOTE_SERVER = "use_remote_server";
	public static final String SERVER_LOCATION = "server_location";
	public static final String SERVER_PORT_NUMBER = "server_port_number";
	public static final String SERVER_USERNAME = "server_user_name";
	public static final String SERVER_PASSWORD = "server_parrword";
	public static final String SAVE_PASSWORD = "save_password";
	public static final String DATABASE_NAME = "database_name";
	private JTextField mServerLocation;
	private JTextField mPortNumber;
	private JTextField mUserName;
	private JPasswordField mUserPassword;
	private boolean isUsingRemoteServer;
	private JButton mSaveButton;
	private JCheckBox mUseRemoteDatabase;
	private Properties mProps;
	private JTextField mDatabaseName;
	private JCheckBox mSavePassword;

	/**
	 * Creates a new SettingsPanel
	 * @author ricky barrette
	 */
	public SettingsPanel() {
		
		JLabel lblMysqlServerLocation = new JLabel("MYsql server location:");
		
		//mql database location
		mServerLocation = new JTextField();
		mServerLocation.setColumns(10);
		
		//use remote database checkbox
		mUseRemoteDatabase = new JCheckBox("Use Remote Database?");
		mUseRemoteDatabase.addActionListener(this);
		
		JLabel lblMysqlServerPort = new JLabel("MYsql server port:");
		
		//server port number
		mPortNumber = new JTextField();
		mPortNumber.setEnabled(false);
		mPortNumber.setColumns(10);
		
		JLabel lblMysql = new JLabel("MYsql server user name:");
		JLabel lblMysqlServerPassword = new JLabel("MYsql server password:");
		//username
		mUserName = new JTextField();
		mUserName.setColumns(10);
		
		//user password
		mUserPassword = new JPasswordField();
		mUserPassword.setColumns(10);
		
		//disable everything
		mServerLocation.setEnabled(false);
		mUserName.setEnabled(false);
		mUserPassword.setEnabled(false);
		
		//save button
		mSaveButton = new JButton("Save", new ImageIcon(getClass().getResource("/floppy_disc.png")));
		mSaveButton.addActionListener(this);
		
		mSavePassword = new JCheckBox("Save Password?");
		mSavePassword.addActionListener(this);
		
		JLabel lblDatabaseName = new JLabel("Database Name:");
		
		mDatabaseName = new JTextField();
		mDatabaseName.setEnabled(false);
		
		mDatabaseName.setColumns(10);
		
		//group layout bullshit
		GroupLayout groupLayout = new GroupLayout(this);
		groupLayout.setHorizontalGroup(
			groupLayout.createParallelGroup(Alignment.LEADING)
				.addGroup(groupLayout.createSequentialGroup()
					.addContainerGap()
					.addComponent(mUseRemoteDatabase)
					.addContainerGap(1087, Short.MAX_VALUE))
				.addGroup(groupLayout.createSequentialGroup()
					.addContainerGap()
					.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
						.addGroup(groupLayout.createSequentialGroup()
							.addComponent(mSavePassword)
							.addContainerGap())
						.addGroup(groupLayout.createSequentialGroup()
							.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
								.addComponent(lblMysqlServerLocation)
								.addComponent(lblMysqlServerPort)
								.addComponent(lblDatabaseName)
								.addComponent(lblMysql))
							.addPreferredGap(ComponentPlacement.RELATED)
							.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
								.addComponent(mPortNumber, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 1079, Short.MAX_VALUE)
								.addComponent(mServerLocation, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 1079, Short.MAX_VALUE)
								.addComponent(mDatabaseName, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 1079, Short.MAX_VALUE)
								.addComponent(mUserName, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 1079, Short.MAX_VALUE))
							.addContainerGap())))
				.addGroup(groupLayout.createSequentialGroup()
					.addContainerGap()
					.addComponent(lblMysqlServerPassword)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
						.addComponent(mUserPassword, GroupLayout.DEFAULT_SIZE, 313, Short.MAX_VALUE)
						.addComponent(mSaveButton, GroupLayout.DEFAULT_SIZE, 949, Short.MAX_VALUE))
					.addContainerGap())
		);
		groupLayout.setVerticalGroup(
			groupLayout.createParallelGroup(Alignment.LEADING)
				.addGroup(groupLayout.createSequentialGroup()
					.addContainerGap()
					.addComponent(mUseRemoteDatabase)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
						.addComponent(lblMysqlServerLocation)
						.addComponent(mServerLocation, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
					.addPreferredGap(ComponentPlacement.RELATED)
					.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
						.addComponent(lblMysqlServerPort)
						.addComponent(mPortNumber, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
					.addPreferredGap(ComponentPlacement.RELATED)
					.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
						.addComponent(lblDatabaseName)
						.addComponent(mDatabaseName, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
					.addPreferredGap(ComponentPlacement.RELATED)
					.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
						.addComponent(mUserName, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
						.addComponent(lblMysql))
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(mSavePassword)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
						.addComponent(lblMysqlServerPassword)
						.addComponent(mUserPassword, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(mSaveButton)
					.addContainerGap(264, Short.MAX_VALUE))
		);
		setLayout(groupLayout);

		// create and load default properties
		mProps = new Properties();
		
		try {
			FileInputStream in = new FileInputStream(".settings.propertys");
			mProps.load(in);
			in.close();
			isUsingRemoteServer = Boolean.parseBoolean(mProps.getProperty(IS_USING_REMOTE_SERVER, "false"));
			
			if(isUsingRemoteServer){
				mServerLocation.setEnabled(true);
				mPortNumber.setEnabled(true);
				mUserName.setEnabled(true);
				mUserPassword.setEnabled( Boolean.parseBoolean(mProps.getProperty(SAVE_PASSWORD, "false")));
				mUseRemoteDatabase.setSelected(true);
				mDatabaseName.setEnabled(true);
				mSavePassword.setEnabled(true);
			}
			
			mDatabaseName.setText(mProps.getProperty(DATABASE_NAME, "Orders"));
			mServerLocation.setText(mProps.getProperty(SERVER_LOCATION));
			mPortNumber.setText(mProps.getProperty(SERVER_PORT_NUMBER, "3306"));
			mUserName.setText(mProps.getProperty(SERVER_USERNAME));
			mSavePassword.setSelected(Boolean.parseBoolean(mProps.getProperty(SAVE_PASSWORD, "false")));
		
		} catch (IOException e) {
			e.printStackTrace();
			mDatabaseName.setText("Orders");
			mPortNumber.setText("3306");
		}
	}

	/**
	 * called when the save button is clicked, or the use remote database check box is clicked
	 * (non-Javadoc)
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 * @author ricky barrette
	 */
	@Override
	public void actionPerformed(ActionEvent e) {
		
		//save button
		if(e.getSource() == mSaveButton){
			BasicTextEncryptor passwordEncryptor = new BasicTextEncryptor();
			passwordEncryptor.setPassword(OrderDB.PASSWORD);
			mProps.put(SERVER_LOCATION, mServerLocation.getText());
			mProps.put(SERVER_PORT_NUMBER, mPortNumber.getText());
			mProps.put(SERVER_USERNAME, mUserName.getText());
			mProps.put(DATABASE_NAME, mDatabaseName.getText());
			
			if(mSavePassword.isSelected())
				mProps.put(SERVER_PASSWORD, new String(passwordEncryptor.encrypt(new String(mUserPassword.getPassword()))));
			
			writeProperties(mProps);
			
		}
		
		//use remote database checkbox
		if(e.getSource() == mUseRemoteDatabase){
			mProps.put(IS_USING_REMOTE_SERVER, Boolean.toString(mUseRemoteDatabase.isSelected()));
			writeProperties(mProps);
			
			if(mUseRemoteDatabase.isSelected()){
				mServerLocation.setEnabled(true);
				mPortNumber.setEnabled(true);
				mUserName.setEnabled(true);
				mUserPassword.setEnabled(true);
				mDatabaseName.setEnabled(true);
				mSavePassword.setEnabled(true);
			} else {
				mServerLocation.setEnabled(false);
				mPortNumber.setEnabled(false);
				mUserName.setEnabled(false);
				mUserPassword.setEnabled(false);
				mDatabaseName.setEnabled(false);
				mSavePassword.setEnabled(false);
			}
		} 
		
		if(e.getSource() == mSavePassword){
			mProps.setProperty(SAVE_PASSWORD, Boolean.toString(mSavePassword.isSelected()));
			writeProperties(mProps);
			if(mSavePassword.isSelected()){
				mUserPassword.setEnabled(true);
				return;
			} else {
				mUserPassword.setEnabled(false);
				return;
			}
		}
		
		MainWindow.loadDatabase();
		
	}
	
	/**
	 * writes the Properties to a persitent file
	 * @param p
	 * @author ricky barrette
	 */
	private void writeProperties(Properties p){
		try {
			 FileOutputStream out = new FileOutputStream(".settings.propertys");
			 p.store(out, "---Order Processor Settings---");
			out.close();
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}
}