import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;

import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.ListCellRenderer;

/**
 * Window to set parameters of a job for creation or updating
 * 
 * @author 413
 *
 */
public class WindowJob extends JFrame implements ActionListener
{
	private static final long serialVersionUID = 1L;
	private WindowManageJobs manager; // link to the manage Window
	private Job job; // link to the job if updating
	private Boolean creation; // true if the job is being created and false if it is updating
	private JComboBox<File> pdfListe; // comboBox displaying available PDF list
	private JComboBox<File> stampType; // comboBox displaying stamp type list
	private JComboBox<File> stamps; // comboBox displaying stamps available in the stamp type selected
	private JTextField field1; // TextField for the number of the start page
	private JTextField field2; // TextField for the number of the last page
	private JTextField field3; // TextField for the parameter 1
	private JTextField field4; // TextField for the parameter 2
	private JTextField field5; // TextField for the parameter 3
	private JTextField field6; // TextField for the parameter 4
	private JTextField field7; // TextField for the parameter 5

	/*
	 * a filter to get only PDF files
	 */
	private FilenameFilter filterPDF = new FilenameFilter()
	{
		public boolean accept(File arg0, String arg1)
		{
			return arg1.endsWith(".pdf");
		}
	};

	/*
	 * a filter to get only folders
	 */
	private FileFilter filterRep = new FileFilter()
	{

		public boolean accept(File pathname)
		{
			return pathname.isDirectory();
		}
	};

	/**
	 * updating constructor
	 * 
	 * @param manager
	 * @param job
	 */
	public WindowJob(WindowManageJobs manager, Job job)
	{
		super();
		this.manager = manager;
		this.job = job;
		this.creation = false;
		createInterface();
	}

	/**
	 * creating constructor
	 * 
	 * @param manager
	 */
	public WindowJob(WindowManageJobs manager)
	{
		super();
		this.manager = manager;
		this.creation = true;
		createInterface();
	}

	/**
	 * display the windows with every elements and layout
	 */
	void createInterface()
	{
		//Interface components
		JLabel text0 = new JLabel("Pdf:");
		JLabel text1 = new JLabel("Stamp Type:");
		JLabel text2 = new JLabel("Stamp:");
		JLabel text3 = new JLabel("First page number:");
		JLabel text4 = new JLabel("Last page number:");
		JLabel text5 = new JLabel("Parameter 1:");
		JLabel text6 = new JLabel("Parameter 2:");
		JLabel text7 = new JLabel("Parameter 3:");
		JLabel text8 = new JLabel("Parameter 4:");
		JLabel text9 = new JLabel("Parameter 5:");
		JButton validate = new JButton("Validate");
		JButton cancel = new JButton("Cancel");
		JButton open1 = new JButton("Open Source");
		JButton open2 = new JButton("Open Stamp");
		field1 = new JTextField();
		field2 = new JTextField();
		field3 = new JTextField();
		field4 = new JTextField();
		field5 = new JTextField();
		field6 = new JTextField();
		field7 = new JTextField();
		//===================================COMBOBOX============================================================
		// I PDF source
		File repertoire = ServiceConfig.source;
		File[] children = repertoire.listFiles(filterPDF);
		pdfListe = new JComboBox<File>(children);
		DefaultListModel<Job> l = manager.getL();
		
		//deleting all sources used by another job
		for(int i = 0; i<l.size();i++)
		{
			for(int j =0; j< pdfListe.getItemCount();j++)
			{
				if(pdfListe.getItemAt(j).equals(l.get(i).getPDFSource()))
				{
					if(creation||!l.get(i).getPDFSource().equals(job.getPDFSource()))
					{
						//deleting files already used
						pdfListe.removeItemAt(j);
					}
					else
					{
						//selecting the updating job
						pdfListe.setSelectedIndex(j);
					}
				}
			}
		}
		// II Stamp Type
		repertoire = ServiceConfig.stamp;
		children = repertoire.listFiles(filterRep);
		stampType = new JComboBox<File>(children);
		
		if(!creation)
		{
			//loading type stamp on update
			for(int j =0; j< stampType.getItemCount();j++)
			{
				if(stampType.getItemAt(j).equals(job.getPDFStampType()))
				{
					stampType.setSelectedIndex(j);
				}
			}
		}
		
		//III The stamp
		if(stampType.getSelectedIndex()!=-1)
		{
			children = ((File)stampType.getSelectedItem()).listFiles(filterPDF);
			stamps = new JComboBox<File>(children);
			
			if(!creation)
			{
				//loading stamp file if updating
				for(int j =0; j< stamps.getItemCount();j++)
				{
					if(stamps.getItemAt(j).equals(job.getPDFStamp()))
					{
						stamps.setSelectedIndex(j);
					}
				}
			}
		}
		else
		{
			//case where there are no stamp type folder
			stamps = new JComboBox<File>();
		}

		pdfListe.setRenderer(new ListCellRenderer<File>()
		{
			protected DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();
			public Component getListCellRendererComponent(JList<? extends File> list, File value, int index, boolean isSelected, boolean cellHasFocus)
			{
				//String[] finalstring = {value.getName()};
				JLabel renderer = (JLabel) defaultRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
				if(value != null)
				{
					if(!creation)
					{
						if (value.getName().equals(job.getPDFSource().getName()))
						{
							if(isSelected)
							{
								renderer.setBackground(new Color(100,100,255));
							}
							else
							{
								renderer.setBackground(new Color(150,150,255));
							}
						}
					}
					renderer.setText(value.getName());
				}
		        return renderer;
			}

		});
		stampType.setRenderer(new ListCellRenderer<File>()
		{
			protected DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();
			public Component getListCellRendererComponent(JList<? extends File> list, File value, int index, boolean isSelected, boolean cellHasFocus)
			{
				//String[] finalstring = {value.getName()};
				JLabel renderer = (JLabel) defaultRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
				if(value != null)
				{
					if(!creation)
					{
						if (value.getName().equals(job.getPDFStampType().getName()))
						{
							if(isSelected)
							{
								renderer.setBackground(new Color(100,100,255));
							}
							else
							{
								renderer.setBackground(new Color(150,150,255));
							}
						}	
					}
					renderer.setText(value.getName());
				}
		        return renderer;
			}

		});
		stamps.setRenderer(new ListCellRenderer<File>()
		{
			protected DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();
			public Component getListCellRendererComponent(JList<? extends File> list, File value, int index, boolean isSelected, boolean cellHasFocus)
			{
				//String[] finalstring = {value.getName()};
				JLabel renderer = (JLabel) defaultRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
				if(value != null)
				{
					if(!creation)
					{
						if(isSelected)
						{
							renderer.setBackground(new Color(100,100,255));
						}
						else
						{
							renderer.setBackground(new Color(150,150,255));
						}
					}
					renderer.setText(value.getName());
				}
		        return renderer;
			}

		});
		//=============================Loading parameters=====================================================================
		if(!creation)
		{
			//loading other parameters if updating
			field1.setText(job.getStartPage()+"");
			
			//the last page could be null
			if(job.getLastPage()!=null)
			{
				field2.setText(job.getLastPage()+"");
			}
			field3.setText(job.getParameter1());
			field4.setText(job.getParameter2());
			field5.setText(job.getParameter3());
			field6.setText(job.getParameter4());
			field7.setText(job.getParameter5());
			
			//comboBox are already updated 
			
		}
		else
		{
			//if creating, the first page is at 1 by default
			field1.setText("1");
		}
		
		//====================================LAYOUT===================================================================
				GroupLayout layout = new GroupLayout(getContentPane());
				getContentPane().setLayout(layout);
				layout.setAutoCreateGaps(true);
				layout.setAutoCreateContainerGaps(true);
				layout.setHorizontalGroup
				(
					layout.createSequentialGroup()
				    .addGroup
				    (
				    	layout.createParallelGroup(GroupLayout.Alignment.LEADING)
				    	.addComponent(text0)
				    	.addComponent(text1)
				    	.addComponent(text2)
				    	.addComponent(text3)
				    	.addComponent(text4)
				    	.addComponent(text5)
				    	.addComponent(text6)
				    	.addComponent(text7)
				    	.addComponent(text8)
				    	.addComponent(text9)
				    	.addComponent(validate)
			    	)
				    .addGroup
				    (
				    	layout.createParallelGroup(GroupLayout.Alignment.LEADING)
				    	.addComponent(pdfListe)
				    	.addComponent(stampType)
				    	.addComponent(stamps)
				    	.addComponent(field1)
				    	.addComponent(field2)
				    	.addComponent(field3)
				    	.addComponent(field4)
				    	.addComponent(field5)
				    	.addComponent(field6)
				    	.addComponent(field7)
				    	.addComponent(cancel)
				    )
				    .addGroup
				    (
				    	layout.createParallelGroup(GroupLayout.Alignment.LEADING)
				    	.addComponent(open1)
				    	.addComponent(open2)
				    )
				);
				layout.setVerticalGroup
				(
					layout.createSequentialGroup()
				    .addGroup
				    (
				    	layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
		                .addComponent(text0)
		                .addComponent(pdfListe)
		                .addComponent(open1)
			        )
				    .addGroup
				    (
				    	layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
		                .addComponent(text1)
		                .addComponent(stampType)
			        )
				    .addGroup
				    (
				    	layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
		                .addComponent(text2)
		                .addComponent(stamps)
		                .addComponent(open2)
			        )
				    .addGroup
				    (
				    	layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
		                .addComponent(text3)
		                .addComponent(field1)
			        )
				    .addGroup
				    (
				    	layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
		                .addComponent(text4)
		                .addComponent(field2)
			        )
				    .addGroup
				    (
				    	layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
		                .addComponent(text5)
		                .addComponent(field3)
			        )
				    .addGroup
				    (
				    	layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
		                .addComponent(text6)
		                .addComponent(field4)
			        )
				    .addGroup
				    (
				    	layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
		                .addComponent(text7)
		                .addComponent(field5)
			        )
				    .addGroup
				    (
				    	layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
		                .addComponent(text8)
		                .addComponent(field6)
			        )
				    .addGroup
				    (
				    	layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
		                .addComponent(text9)
		                .addComponent(field7)
			        )
				    .addGroup
				    (
				    	layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
		                .addComponent(validate)
		                .addComponent(cancel)
			        )
				);
				
				//Window settings
		        setTitle("Add a new Job");
		        pack();
		        setSize(600, 375);
		        setLocationRelativeTo(null);
		        setVisible(true);
		        
				//adding listeners
		        validate.addActionListener(this);
		        cancel.addActionListener(this);
		    	stampType.addActionListener(this);
		        open1.addActionListener(this);
		    	open2.addActionListener(this);
	}

	/**
	 * catch events
	 */
	public void actionPerformed(ActionEvent e)
	{
		switch (e.getActionCommand())
		{
		case "comboBoxChanged":
			stamps.removeAllItems();
			File[] l = (((File) stampType.getSelectedItem()).listFiles(filterPDF));
			for (int i = 0; i < l.length; ++i)
			{
				stamps.addItem(l[i]);
			}
			break;

		case "Validate":
			if (creation)
			{
				job = new Job();
			}
			if (field1.getText().isEmpty())
			{
				JOptionPane.showMessageDialog(null, "You have to set the fist and last page", "Impossible operation", JOptionPane.WARNING_MESSAGE);
			}
			else
			{
				if (stampType.getSelectedIndex() == -1 || stamps.getSelectedIndex() == -1 || pdfListe.getSelectedIndex() == -1)
				{
					JOptionPane.showMessageDialog(null, "You have to select all files to use", "Impossible operation", JOptionPane.WARNING_MESSAGE);
				}
				else
				{
					try
					{
						job.setPDFSource((File) pdfListe.getSelectedItem());
						job.setPDFStampType(((File) stampType.getSelectedItem()));
						job.setPDFStamp((File) stamps.getSelectedItem());
						job.setStartPage(Integer.parseInt(field1.getText()));
						if (!field2.getText().isEmpty())
						{
							job.setLastPage(Integer.parseInt(field2.getText()));
						}
						job.setParameter1(field3.getText());
						job.setParameter2(field4.getText());
						job.setParameter3(field5.getText());
						job.setParameter4(field6.getText());
						job.setParameter5(field7.getText());
						job.save();
						if (creation)
						{
							manager.add(job);
						}
						this.dispose();
					}
					catch (NumberFormatException er)
					{
						JOptionPane.showMessageDialog(null, "Page numbers are integers.", "Impossible operation", JOptionPane.WARNING_MESSAGE);
					}
				}
			}
			break;

		case "Open Source":
			try
			{
				MacroMethods.openPdf(pdfListe.getItemAt(pdfListe.getSelectedIndex()));
			}
			catch (Exception e1)
			{
				e1.printStackTrace();
			}
			break;

		case "Open Stamp":
			try
			{
				MacroMethods.openPdf(stamps.getItemAt(stamps.getSelectedIndex()));
			}
			catch (Exception e1)
			{
				e1.printStackTrace();
			}
			break;

		case "Cancel":
			this.dispose();
			break;

		default:
			JOptionPane.showMessageDialog(null, "Unkonwn event happended :/");
		}

	}

}
