package artistmetrics;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class LoginForm
{
	final String CONFIG_FILE = ".artistmetrics"; 
	
	Combo comboServer;
	ServerFinder serverFinder = null;
	String username = "";
	String password = "";
	String server = "";
	boolean remember = false;
	boolean success = false;
	
	
	public LoginForm() throws MalformedURLException
	{
		//Create the shell and display.
		Display display = Display.getDefault();
		final Shell shell = new Shell(display);
		shell.setText("ARTIST Metrics - Login");
		GridLayout layout = new GridLayout();
		layout.numColumns = 4;
		layout.marginTop = 0;
		layout.marginLeft = 0;
		layout.horizontalSpacing = 10;
		layout.verticalSpacing = 10;
		layout.marginWidth = 0;
		shell.setLayout(layout);
		shell.setSize(400, 300);
		Rectangle b = display.getBounds();
		shell.setLocation((b.width - 400)/2, (b.height - 300)/2);
		
		final ImageDescriptor id = ImageDescriptor.createFromURL(new URL(Activator.getDefault().getDescriptor().getInstallURL(), "images/logo.jpg"));
		final Image fullImage = id.createImage();

		GridData gridData = new GridData();
		gridData.grabExcessHorizontalSpace = true;
		gridData.grabExcessVerticalSpace = true;
		gridData.horizontalSpan = 4;
		gridData.minimumWidth = 500;
		gridData.minimumHeight = 100;

		Canvas canvas = new Canvas(shell,SWT.NO_REDRAW_RESIZE);
		canvas.setLayoutData(gridData);
	    canvas.addPaintListener(new PaintListener() {
	        public void paintControl(PaintEvent e) {
	            e.gc.drawImage(fullImage,0,0);
	        }
	    }); 
		
	    GridData labelData = new GridData();
	    labelData.grabExcessHorizontalSpace = true;
	    labelData.horizontalAlignment = SWT.LEFT;
	    labelData.minimumWidth = 30;
	    labelData.verticalAlignment = SWT.BOTTOM;
	    
	    GridData spacingLabelData = new GridData();
	    spacingLabelData.minimumHeight = 50;
	    spacingLabelData.horizontalAlignment = SWT.FILL;
	    spacingLabelData.grabExcessHorizontalSpace = true;
	    
	    GridData controlData = new GridData();
	    controlData.grabExcessHorizontalSpace = true;
	    controlData.horizontalAlignment = SWT.LEFT;
	    controlData.minimumWidth = 300;
	    controlData.minimumHeight = 30;
	    controlData.verticalAlignment = SWT.BOTTOM;
	    
	    Label tmplabel = new Label(shell, SWT.SINGLE);
		tmplabel.setLayoutData(labelData);
	    
		Label un_label = new Label(shell, SWT.SINGLE);
		un_label.setText("Username:");
		final Text txt_username = new Text(shell, SWT.SINGLE | SWT.BORDER);
		txt_username.setLayoutData(controlData);
		
		tmplabel = new Label(shell, SWT.SINGLE);
		tmplabel.setLayoutData(labelData);
		tmplabel = new Label(shell, SWT.SINGLE);
		tmplabel.setLayoutData(labelData);
		
		Label pa_label = new Label(shell, SWT.SINGLE);
		pa_label.setText("Password:");
		final Text txt_password = new Text(shell, SWT.PASSWORD | SWT.BORDER | SWT.SINGLE);
		txt_password.setLayoutData(controlData);
		
		tmplabel = new Label(shell, SWT.SINGLE);
		tmplabel.setLayoutData(labelData);
		tmplabel = new Label(shell, SWT.SINGLE);
		tmplabel.setLayoutData(labelData);
		
		Label server_label = new Label(shell, SWT.SINGLE);
		server_label.setText("Server:");
		comboServer = new Combo(shell,SWT.DROP_DOWN);
		comboServer.setLayoutData(controlData);
		
		tmplabel = new Label(shell, SWT.SINGLE);
		tmplabel.setLayoutData(labelData);
		
		GridData checkData = new GridData();
	    checkData.grabExcessHorizontalSpace = true;
	    checkData.horizontalAlignment = SWT.CENTER;
	    checkData.horizontalSpan = 4;
	    
		Button btn_remember = new Button(shell, SWT.CHECK);
		btn_remember.setText("Remember Password");
		btn_remember.setLayoutData(checkData);
		btn_remember.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent arg0) {
			}

			
			public void widgetSelected(SelectionEvent arg0) {
				remember = !remember;
			}
		});
		

	    labelData.minimumWidth = 30;
		tmplabel = new Label(shell, SWT.SINGLE);
		tmplabel.setLayoutData(labelData);
		
		
		GridData bottomButtonData = new GridData();
	    bottomButtonData.grabExcessHorizontalSpace = true;
	    bottomButtonData.horizontalAlignment = SWT.RIGHT;
	    bottomButtonData.horizontalIndent = 5;
	    bottomButtonData.widthHint = 80;
		
		Button ok = new Button(shell, SWT.DEFAULT);
		ok.setText("OK");
		ok.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent arg0) {}
			public void widgetSelected(SelectionEvent arg0) {
				if(serverFinder != null)
					serverFinder.stop();
				
				success = true;
				username = txt_username.getText();
				password = txt_password.getText();
				server = comboServer.getText();
				
				if(getRemember())
				{
					writeConfig();
				}
				else
				{
					deleteConfig();
				}
				
				shell.close();
			}
		});
		ok.setLayoutData(bottomButtonData);
		
		Button cancel = new Button(shell, SWT.CANCEL);
		cancel.setText("Cancel");
		cancel.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent arg0) {}
			public void widgetSelected(SelectionEvent arg0) {
				if(serverFinder != null)
					serverFinder.stop();
				shell.close();
			}
		});
		cancel.setLayoutData(bottomButtonData);

	    labelData = new GridData();
	    labelData.horizontalAlignment = SWT.RIGHT;
	    labelData.minimumWidth = 30;
	    labelData.verticalAlignment = SWT.BOTTOM;
		tmplabel = new Label(shell, SWT.SINGLE);
		tmplabel.setLayoutData(labelData);
		
		shell.pack();
		shell.open();
		
		//Start the server finder...
		serverFinder = new ServerFinder(this);
		serverFinder.start();
		
		//Try to read the configuration in from a config file...
		readConfig();
		txt_username.setText(username);
		txt_password.setText(password);
		comboServer.setText(server);
		
		if(!txt_username.getText().equals("") || !txt_password.getText().equals("") || !comboServer.getText().equals(""))
		{
			remember = true;
			btn_remember.setSelection(true);
		}
		
		//Event handling loop.
		while(!shell.isDisposed())
		{
			if(!display.readAndDispatch()) 
		      display.sleep();
		}
	}
	
	private void writeConfig()
	{
		FileOutputStream fos;

	    try
	    {
	    	File file= new File(CONFIG_FILE);
	    	if(file.exists())
	    		file.delete();
	    	
	    	fos = new FileOutputStream(file);
	    	
	    	fos.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".getBytes());
	    	fos.write("<configuration>".getBytes());
	    	fos.write(("<username>" + username + "</username>").getBytes());
	    	fos.write(("<password>" + password + "</password>").getBytes());
	    	fos.write(("<URL>" + server + "</URL>").getBytes());
	    	fos.write("</configuration>".getBytes());

	    }
	    catch (IOException e)
	    {
	    	e.printStackTrace();
	    }
	}
	
	private void deleteConfig()
	{
		File f = new File(CONFIG_FILE);
	    f.delete();	
	}
	
	public boolean getRemember()
	{
		return remember;
	}
	
	private void readConfig()
	{
		File file = new File(CONFIG_FILE);;
		DocumentBuilderFactory docBuilderFactory;
		DocumentBuilder docBuilder;
		
		try
		{
			//Check that the file exists...
			if(!file.exists())
				return;
			
			
			docBuilderFactory = DocumentBuilderFactory.newInstance();
			docBuilder = docBuilderFactory.newDocumentBuilder();
	    
			//Create an instance of the XML document in memory.
			Document doc = docBuilder.parse (file);
	        doc.getDocumentElement ().normalize ();
	        NodeList nl = doc.getDocumentElement().getChildNodes();
	        
	        //Iterate through the children to find what we're looking for.
	        for(int i = 0; i < nl.getLength(); i++)
	        {
	        	Node n = nl.item(i);
	            	
	        	if(n.getNodeName() == "username")
	        		username = n.getTextContent();
	        	else if(n.getNodeName() == "password")
	        		password = n.getTextContent();
	        	else if(n.getNodeName() == "URL")
	        		server = n.getTextContent();	
	        }
	            
		} catch (Exception e)
		{
			e.printStackTrace();
		}
	}
	
	public boolean getSuccess()
	{
		return success;
	}
	
	public String getUsername()
	{
		return username;
	}
	
	public String getPassword()
	{
		return password;
	}
	
	public String getServer()
	{
		return server;
	}
	
	public void addServer(final String svr)
	{
		Display display = Display.getDefault();

		display.asyncExec(new Runnable() {
			public void run() {
				comboServer.add(svr);
			}
		});
	}
}
