/*
 * Created on Aug 7, 2003
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package AppletInterface;

import amber.type.server.*;
import amber.server.panel.*;
import amber.server.component.*;
import amber.server.application.ApplicationInterface;
import amber.awt.event.*;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import DataClasses.*;
import Validators.*;
import XmlCommunication.*;
import DatabaseCommunication.*;
import nz.co.k.tms.ldap.*;

/**
  * This class handles the requirements for the specific manipulation of panels within
  * specific applications. In a lot of ways this class functions very similarly to the
  * ApplicationInterface class.
  * This is the overall intelligence for this particular panel.
  *
  * @author Insert your name here
  * @version 1.0.0
  * @see amber.server.panel.BaseFrame
*/
/**
 * @author student
 *
 * This class represents the entry point of the stock trading application.
 * 
 */
public class LoginFrame
	extends BaseFrame
	implements ComponentWindowListener, ActionListener {

	private ServletConnection servletconn = new ServletConnection();
	private XmlGenerator xmlgenerator = new XmlGenerator();
	private XmlUnmarshal xmlunmarshal = new XmlUnmarshal();
			
		
	private final int FRAMEWIDTH = 800;
	private final int FRAMEHEIGHT = 400;

	private FloatButtonHandler btnMain =
		new FloatButtonHandler(getParentApplication());
	private ImageHandler imgBanner = new ImageHandler(getParentApplication());
	private FloatButtonHandler btnUpdate =
		new FloatButtonHandler(getParentApplication());
	private FloatButtonHandler btnLogin =
		new FloatButtonHandler(getParentApplication());
	private LabelHandler lblInfo = new LabelHandler(getParentApplication());
	private LabelHandler lblUserName = new LabelHandler(getParentApplication());
	private LabelHandler lblPassword = new LabelHandler(getParentApplication());
	private TextFieldHandler txtUserName =
		new TextFieldHandler(getParentApplication());
	private TextFieldHandler txtPassword =
		new TextFieldHandler(getParentApplication());
	private FloatButtonHandler btnRegister =
		new FloatButtonHandler(getParentApplication());

	private Font level1 = new Font("Arial", Font.BOLD, 14);
	private Font level2 = new Font("Arial", Font.ITALIC, 14);

	private UserManager umanager = new UserManager();

	/**
	 * This is the constructor for LoginFrame.java
	 */
	public LoginFrame() {
		super();
		defineComponents();
	}

	/**
	  * The initialising constructor.
	  * @param appHandler The handle to the main ApplicationInterface which
	  * handles the functions of the overall application.
	*/
	public LoginFrame(ApplicationInterface appHandler) {
		super(appHandler);
		defineComponents();
	}

	/**
	  * The initialising constructor.
	  * @param id The int containing the id of the corresponding remote component
	  * residing on the browser.
	  * @param appHandler The handle to the main ApplicationInterface which
	  * handles the functions of the overall application.
	*/
	public LoginFrame(int id, ApplicationInterface appHandler) {
		super(id, appHandler);
		defineComponents();
	}

	/**
		* This function would normally never need to be called, but is required
		* to be defined as it is called internally.
		* Its specific purpose is to set the controls to a known state once
		* they are created.
	*/
	public void fillControls() {
	}

	/**
	  * This function determines if the panel can be closed.
	  * The derived panels must determine if this panel can close. If this is
	  * not possible the function should return false.
	  * @return boolean false if it is not possible to close this panel.
	*/
	public boolean canClose() {
		return true;
	}

	/**
	  * This function is called to save any required information in the panel.
	  * This function is called externally when another panel wishes to take
	  * over the base panel or when closing the panel.
	  * This function need not actually do something.
	*/
	public void saveData() {
	}

	/**
	  * This function is called to define the components which are a part of this
	  * panel.
	  * This function is called by the constructor to set up the normal static
	  * components and their locations.
	  * This method is required.
	*/
	protected void defineComponents() {
		try {
			setProperties();
			addComponents();
			addListeners();
		} catch (Exception ex) {
			System.out.println(ex.toString());
		}
	}
	/**
	 * This method is being used for setting the properties of various
	 * components.
	 * @return void
	 */
	private void setProperties() {
		try {
			this.setTitle("Stock Trading Login Screen");
			this.setBackground(Color.WHITE);

			imgBanner.setImage("Banner1.gif");

			btnMain.setBackground(Color.LIGHT_GRAY);
			btnUpdate.setBackground(Color.LIGHT_GRAY);
			btnLogin.setBackground(Color.LIGHT_GRAY);
			btnRegister.setBackground(Color.LIGHT_GRAY);

			lblUserName.setFont(level2);
			lblPassword.setFont(level2);

			btnMain.setLabel("MAIN");
			btnUpdate.setLabel("UPDATE");
			btnLogin.setLabel("LOGIN");
			lblInfo.setText(
				"Use this screen to Login or if you have not used this platform before, click register.");
			lblUserName.setText("User Name :");
			lblPassword.setText("Password :");
			txtUserName.setText("");
			txtPassword.setText("");
			btnRegister.setLabel("REGISTER");

			txtUserName.requestFocus();
			txtPassword.setEchoChar('*');

			btnMain.setEnabled(false);
			btnUpdate.setEnabled(false);

		} catch (Exception ex) {
			System.err.println(ex.toString());
		}
	}

	/**
	 * This method is being used for adding the components to the frame.
	 * @return void
	 */
	private void addComponents() {
		try {
			add(btnMain, new XYConstraints(164, 100, 154, 20));
			add(imgBanner, new XYConstraints(0, 0, 800, 100));
			add(btnUpdate, new XYConstraints(323, 100, 154, 20));
			add(btnLogin, new XYConstraints(482, 100, 154, 20));
			add(lblInfo, new XYConstraints(50, 300, 450, 20));
			add(lblUserName, new XYConstraints(164, 200, 100, 20));
			add(lblPassword, new XYConstraints(164, 225, 100, 20));
			add(txtUserName, new XYConstraints(300, 200, 100, 20));
			add(txtPassword, new XYConstraints(300, 225, 100, 20));
			add(btnRegister, new XYConstraints(540, 300, 154, 20));
		} catch (Exception ex) {
			System.err.println(ex.toString());
		}
	}

	/**
	 * Method: addListeners
	 * This method is being used for adding the listeners to the frame.
	 * @return void
	 */
	private void addListeners() {
		try {
			addActionListener(this);
			addWindowListener(this);
			txtUserName.addActionListener(this);
			txtPassword.addActionListener(this);
			btnLogin.addActionListener(this);
			btnRegister.addActionListener(this);
		} catch (Exception ex) {
			System.err.println(ex.toString());
		}
	}

	/* (non-Javadoc)
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent e) {
		try {
			if (e.getSource() == btnLogin
				|| e.getSource() == txtPassword
				|| e.getSource() == txtPassword) {
				// check the user has entered a name
				String userName = txtUserName.getText();
				String password = txtPassword.getText();

				//Validation of login fields..++++++++++++++++++++++++++++++++++++++++
				if (userName.trim().length() == 0) // no name, display error
					throw new ValidationException("You must enter a login name.");
				if (password.trim().length() == 0)
					// no password, display error
					throw new ValidationException("You must enter your password.");

				//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
				//Authentication using LDAP..+++++++++++++++++++++++++++++++++++++++++
				User_Data userdata = new User_Data();
				userdata.setUserName(userName);
				userdata.setPassword(password);

				boolean loginValid = false;
				LoginValidator lv = new LoginValidator();
				loginValid = lv.validate(userdata);

				if (!loginValid) {
					throw new ValidationException("Unable to find entry. Either your user name or password is incorrect.");
				}

				//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
				//Authentication using local DB..+++++++++++++++++++++++++++++++++++++
				loginValid = umanager.readUser(userdata);

				if (!loginValid) {
					throw new ValidationException("The user name is not found in the Stock Trading Database.");
				}

				//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
				//Fetch Details from Local Database+++++++++++++++++++++++++++++++++++

				//fetch user details.
				umanager.readUser(userdata);

				//fetch stocks interested.
				umanager.readStocksInterested(userdata);

				//fetch stocks owned.
				boolean read = umanager.readStocksOwned(userdata);

				System.out.println("read stocks owned? " + read);

				//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
				//Fetch Details from TMS++++++++++++++++++++++++++++++++++++++++++++++

				UserDetail ud =
					LdapHelper.authentiacteUser(
						userdata.getUserName(),
						userdata.getPassword());

				//get ncb id from TMS..
				String ncbid =
					xmlunmarshal.readNcbServiceResponse(ud.getXmlPacket());
				int id = Integer.parseInt(ncbid);

				//fetch user details.
				userdata.setNcbId(id);

				String xmlstr = xmlgenerator.enquiryNcbXml(userdata, null);
				System.out.println("ENQUIRY NCB XML: "+xmlstr);
				
				String out = servletconn.sendXml(xmlstr);
				System.out.println("RESPONSE: "+out);

				String message = xmlunmarshal.readResponse(out);
				xmlunmarshal.getUser(userdata);

				//fetch address details.
				UserAddress_Data addressdata = new UserAddress_Data();

				String xmlstr2 =
					xmlgenerator.enquiryNcbAddressXml(userdata, null);
				System.out.println("ENQUIRY NCB ADDRESS XML: "+xmlstr2);
				
				String out2 = servletconn.sendXml(xmlstr2);
				System.out.println("ENQUIRY NCB ADDRESS XML RESPONSE: "+out2);
				
				String message2 = xmlunmarshal.readResponse(out2);
				xmlunmarshal.getAddress(addressdata);

				//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
				//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

				displayDebug("Login DEBUG", userdata, addressdata);

				//set the master copy in the application.
				getStockTradingApplication().setUser(userdata);
				getStockTradingApplication().setAddress(addressdata);

				// through to the next frame
				MainFrame mainFrame = new MainFrame(getParentApplication());
				add(
					mainFrame,
					new XYConstraints(
						5,
						5,
						mainFrame.FRAMEWIDTH,
						mainFrame.FRAMEWIDTH));

				mainFrame.setVisible(true);
				mainFrame.show();

				// trash this screen
				setVisible(false);
				// do I remove it?
			} else if (e.getSource() == btnRegister) {
				RegisterFrame registerFrame =
					new RegisterFrame(getParentApplication(), this);
				add(
					registerFrame,
					new XYConstraints(
						10,
						10,
						registerFrame.FRAMEWIDTH,
						registerFrame.FRAMEHEIGHT));
				registerFrame.setVisible(true);
				setVisible(false);
			}

		} catch (Exception ex) {
			ex.printStackTrace();
			displayMessageBox("Error", ex.getMessage());
		}

	}
	
	/**
	 * This method is being used for debugging purposes.
	 * @param s The string used to identify the location from where this method is being called.
	 * @param user The user whose information is to be displayed.
	 * @param address The user address information to be displayed. 
	 * @return void
	 */
	private void displayDebug(
		String s,
		User_Data user,
		UserAddress_Data address) {
		System.out.println("++++++++++++" + s + "++++++++++++++++");
		System.out.println("user fname : " + user.getFirstName());
		System.out.println("user lname : " + user.getLastName());
		System.out.println("user organisation : " + user.getOrganisation());
		System.out.println("user type : " + user.getType());
		System.out.println("user username : " + user.getUserName());
		System.out.println("user password : " + user.getPassword());
		System.out.println("++++++++++++++++++++++++++++++++++");
		System.out.println("address street : " + address.getStreet());
		System.out.println("address suburb : " + address.getSuburb());
		System.out.println("address city : " + address.getCity());
		System.out.println("address country : " + address.getCountry());
		System.out.println("+++++++++++++++END++++++++++++++++");
	}
	
	/**
	 * This method is being used for getting the parent application.
	 * @return StockTradingApplication The parent application.
	 */
	protected StockTradingApplication getStockTradingApplication() {
		return (StockTradingApplication) getParentApplication();
	}
	
	/* (non-Javadoc)
	 * @see amber.awt.event.ComponentWindowListener#windowOpened(amber.awt.event.ComponentWindowEvent)
	 */
	public void windowOpened(ComponentWindowEvent arg0) {
	}
	
	/* (non-Javadoc)
	 * @see amber.awt.event.ComponentWindowListener#windowClosing(amber.awt.event.ComponentWindowEvent)
	 */
	public void windowClosing(ComponentWindowEvent arg0) {
		setVisible(false);
	}
	
	/* (non-Javadoc)
	 * @see amber.awt.event.ComponentWindowListener#windowClosed(amber.awt.event.ComponentWindowEvent)
	 */
	public void windowClosed(ComponentWindowEvent arg0) {
	}
	
	/* (non-Javadoc)
	 * @see amber.awt.event.ComponentWindowListener#windowIconified(amber.awt.event.ComponentWindowEvent)
	 */
	public void windowIconified(ComponentWindowEvent arg0) {
	}
	
	/* (non-Javadoc)
	 * @see amber.awt.event.ComponentWindowListener#windowDeiconified(amber.awt.event.ComponentWindowEvent)
	 */
	public void windowDeiconified(ComponentWindowEvent arg0) {
	}
	
	/* (non-Javadoc)
	 * @see amber.awt.event.ComponentWindowListener#windowActivated(amber.awt.event.ComponentWindowEvent)
	 */
	public void windowActivated(ComponentWindowEvent arg0) {
	}
	
	/* (non-Javadoc)
	 * @see amber.awt.event.ComponentWindowListener#windowDeactivated(amber.awt.event.ComponentWindowEvent)
	 */
	public void windowDeactivated(ComponentWindowEvent arg0) {
	}
}
