package view;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;

import controller.Controller;

public class Interface extends JFrame implements ActionListener, WindowListener {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L; //JFrame stuff

	public Controller controller;
		
	public JLabel Pseudolabel;
	public JLabel ChangePseudolabel;
	public JTextField ChangePseudotextField;
	
	public JTextArea MessagetextArea;
	public JTextField MessagetextField;
	public JScrollPane scrollpane;
	
	public JButton RemoteUserButton;
	public JComboBox<String> RemoteUserbox;
	public JButton CloseConversationButton;
	
	//Specifies the look and feel to use. Valid values:
	//null (use the default), "Metal", "System", "Motif", "GTK+"
	final static String LOOKANDFEEL = "System";
	
	public Interface(Controller controller) {
		this.controller = controller;
		this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		this.addWindowListener(new java.awt.event.WindowAdapter() {
		    @Override
		    public void windowClosing(java.awt.event.WindowEvent e) {
		        System.out.println("Window closing");
		    }
		});
			
	}
	
	public Component createComponents() {
		
		//Pseudo setup
		JPanel changePseudoPanel = new JPanel(new GridLayout(1, 0));
		ChangePseudolabel = new JLabel("Change nickname : ");
		changePseudoPanel.add(ChangePseudolabel);
		ChangePseudotextField = new JTextField();        
		ChangePseudotextField.setColumns(10);
		ChangePseudotextField.addActionListener(this);
		changePseudoPanel.add(ChangePseudotextField);
		
		Pseudolabel = new JLabel("Nickname : "+controller.getMyUser().getPseudo());
		Pseudolabel.setLabelFor(ChangePseudotextField);
		
		
		
		//Remote user list setup
		RemoteUserButton = new JButton("Start session");          
		RemoteUserButton.addActionListener(this);
		
		
		// Remote user list
		//Converts the Userlist to a Pseudotab for treatment in actionPerformed
		String[] pseudotab = controller.askUpdateActiveUsers();
		RemoteUserbox = new JComboBox<String>(pseudotab);
		RemoteUserbox.setEditable(true);
		RemoteUserbox.addActionListener(this);
		RemoteUserbox.setVisible(false);
		
		// Close session
		CloseConversationButton = new JButton("Close session");
		CloseConversationButton.addActionListener(this);
		CloseConversationButton.setVisible(false);
		
		JPanel userListsPanel = new JPanel(new GridLayout(1, 0));
	
		userListsPanel.add(RemoteUserButton);
		userListsPanel.add(RemoteUserbox);
		userListsPanel.add(CloseConversationButton);

		
	    //Messages setup
		MessagetextField = new JTextField();
		MessagetextField.setColumns(10);
		MessagetextField.addActionListener(this);
		MessagetextArea = new JTextArea("Chat");
		scrollpane = new JScrollPane();
		scrollpane.getViewport().add(MessagetextArea);
		scrollpane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		scrollpane.setPreferredSize(new Dimension(600,60));
		MessagetextField.setVisible(false);
		MessagetextArea.setVisible(false);
		scrollpane.setVisible(false);
		// Create a placeholder on JTextField
		MessagetextField.addFocusListener(new FocusListener() {
		       @Override
		       public void focusGained(FocusEvent e) {
		           if (MessagetextField.getText().equals("Your message")) {
		        	   MessagetextField.setText("");
		        	   MessagetextField.setForeground(Color.BLACK);
		           }
		       }
		       @Override
		       public void focusLost(FocusEvent e) {
		           if (MessagetextField.getText().isEmpty()) {
		        	   MessagetextField.setForeground(Color.GRAY);
		        	   MessagetextField.setText("Your message");
		           }
		       }
		       });

		
		/*
		* An easy way to put space between a top-level container
		* and its contents is to put the contents in a JPanel
		* that has an "empty" border.
		*/
		JPanel header = new JPanel(new GridLayout(0, 1));
		header.add(Pseudolabel);
		header.add(changePseudoPanel);
		header.add(userListsPanel);
		
		JPanel pane = new JPanel(new BorderLayout());
		pane.add(header,BorderLayout.NORTH);
		pane.add(scrollpane,BorderLayout.CENTER);
		pane.add(MessagetextField,BorderLayout.SOUTH);
		pane.setBorder(BorderFactory.createEmptyBorder(
									30, //top
									30, //left
									10, //bottom
									30) //right
		);
			
		return pane;
	}
	
	public void actionPerformed(ActionEvent e) {
		if(e.getSource() == ChangePseudotextField) {                //Changing pseudo
			String Textinput = ChangePseudotextField.getText();
			Pseudolabel.setText("Your current username is: " + Textinput);
			
			try {
				controller.changePseudo();
			} catch (IOException e1) {
				System.out.println("Error in change pseudo\n");
				e1.printStackTrace();
			}
		}else if(e.getSource() == MessagetextField){          //Messages
			String Textinput = MessagetextField.getText();
			MessagetextArea.setText(MessagetextArea.getText() + "\n" + controller.getMyUser().getPseudo() + " : " + Textinput );
			MessagetextField.setText("");
			controller.askToSend(Textinput); // ask to send to controller 
			
		}else if(e.getSource() == RemoteUserButton) {         //Shows remote user list
			RemoteUserbox.setVisible(true);
		}else if(e.getSource() == CloseConversationButton) {
			controller.askCloseSession();
			MessagetextArea.setVisible(false);
			scrollpane.setVisible(false);
			MessagetextField.setVisible(false);
			CloseConversationButton.setVisible(false);
		}else if(e.getSource() == RemoteUserbox){ // Choice in remote user list
			
			//JComboBox cb = (JComboBox)e.getSource();          //Casts obscurs pour récupérer le numéro du user dans la liste
			int selectedUsernb = RemoteUserbox.getSelectedIndex();
					//String.valueOf(((String) cb.getSelectedItem()).charAt(1)));

			// start or switch chat => get history 
			String history = controller.askOpenSession(selectedUsernb);
			// display it
			MessagetextArea.setText(history);
			MessagetextField.setVisible(true);
			scrollpane.setVisible(true);
			MessagetextArea.setVisible(true);
			CloseConversationButton.setVisible(true);
		}
	}
	 
	private static void initLookAndFeel() {
		// Swing allows you to specify which look and feel your program uses-
		// -Java,
		// GTK+, Windows, and so on as shown below.
		String lookAndFeel = null;
			
		if (LOOKANDFEEL != null) {
			if (LOOKANDFEEL.equals("Metal")) {
				lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();
			} else if (LOOKANDFEEL.equals("System")) {
				lookAndFeel = UIManager.getSystemLookAndFeelClassName();
			} else if (LOOKANDFEEL.equals("Motif")) {
				lookAndFeel = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
			} else if (LOOKANDFEEL.equals("GTK+")) { //new in 1.4.2
				lookAndFeel = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
			} else {
				System.err.println("Unexpected value of LOOKANDFEEL specified: " + LOOKANDFEEL);
				lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();
			}	
			try {UIManager.setLookAndFeel(lookAndFeel);
			} catch (ClassNotFoundException e) {
				System.err.println("Couldn't find class for specified look and feel:" + lookAndFeel);
				System.err.println("Did you include the L&F library in the class path?");
				System.err.println("Using the default look and feel.");
			} catch (UnsupportedLookAndFeelException e) {
				System.err.println("Can't use the specified look and feel (" + lookAndFeel+ ") on this platform.");
				System.err.println("Using the default look and feel.");
			} catch (Exception e) {
				System.err.println("Couldn't get specified look and feel (" + lookAndFeel + "), for some reason.");
				System.err.println("Using the default look and feel.");
				e.printStackTrace();
			}
		}
	}
	
	/**
	* Create the GUI and show it. For thread safety,
	* this method should be invoked from the
	* event-dispatching thread.
	*/
	public static Interface createAndShowGUI(Controller controller) {
		//Set the look and feel.
		initLookAndFeel();
		
		//Make sure we have nice window decorations.
		JFrame.setDefaultLookAndFeelDecorated(true);
			
		//Create and set up the window.
		JFrame frame = new JFrame("Clavardage App");
		frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		Interface app = new Interface(controller);
		Component contents = app.createComponents();
		frame.getContentPane().add(contents, BorderLayout.CENTER);
		frame.setPreferredSize(new Dimension(400,300));
		
		//Ends all running background tasks upon closing the window
		frame.addWindowListener(new java.awt.event.WindowAdapter() {
		    @Override
		    public void windowClosing(java.awt.event.WindowEvent windowEvent) {
		        System.out.println("("+controller.getMyUser().getPseudo()+") Window has been closed");
		        controller.askForClose();
		        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		    }
		});	
		
		//Display the window.
		frame.pack();
		frame.setVisible(true);
		
		return app;
	}

	public void windowOpened(WindowEvent e) {} //Had to implement it for WindowListener
    public void windowActivated(WindowEvent e) {}
    public void windowIconified(WindowEvent e) {}
    public void windowDeiconified(WindowEvent e) {}
    public void windowDeactivated(WindowEvent e) {}
    public void windowClosed(WindowEvent e) {}
	public void windowClosing(WindowEvent e) {}

	
	public void notifyNewMessage(String msg) {
		MessagetextArea.setText(MessagetextArea.getText() + "\n" + msg);
		
	}
	
	public void updateActiveUsers() {
		DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>( controller.askUpdateActiveUsers() );
		RemoteUserbox.setModel( model );
	}
		/*
	public static void main(String[] args) throws IOException {
		//Schedule a job for the event-dispatching thread:
		//creating and showing this application’s GUI.
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				createAndShowGUI();
			}
		});
	}*/
}