/**
 * 
 */
package es.dalocar.facturamas.swt.handlers;

import java.text.Collator;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import org.apache.commons.beanutils.BeanComparator;
import org.apache.log4j.Logger;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Widget;

import es.dalocar.facturamas.swt.SWTUtils;
import es.dalocar.facturamas.swt.edit.EditFacturaComposite;
import es.dalocar.facturamas.swt.list.FacturaListaComposite;
import es.dalocar.software.ApplicationManager;
import es.dalocar.software.Context;
import es.dalocar.software.Messages;
import es.dalocar.software.beans.Cliente;
import es.dalocar.software.beans.Factura;
import es.dalocar.software.beans.FacturaId;
import es.dalocar.software.beans.FacturaSearch;
import es.dalocar.software.services.FacturaService;

/**
 * Handler para la lista de Facturas
 * 
 * @author dlopez
 * 
 */
public class ListaFacturasHandler extends AbstractHandler {

	private static Logger log = Logger.getLogger(ListaFacturasHandler.class.getName());
	private static boolean DEBUG = log.isDebugEnabled();
	private static boolean INFO = log.isInfoEnabled();

	private FacturaListaComposite listaComposite;
	private ApplicationManager manager;
	//private FacturaDAO facturaDAO;
	private FacturaService facturaService;
	private List listaFacturas;
	
	
	/**
	 * Constructor por defecto que instancia el comparador para centros
	 */
	public ListaFacturasHandler() {
		manager = ApplicationManager.getManager();
		facturaService = new FacturaService(manager);	
	}

	/**
	 * @see es.valencia.proyeduca.handlers.Handler#run(org.eclipse.swt.widgets.Widget)
	 * @wbp.parser.entryPoint
	 */
	public void run(Widget parent) {

		Shell shell = new Shell(parent.getDisplay().getActiveShell(),SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM);
		shell.setText(Messages.getString("ListaFacturas.title")); //$NON-NLS-1$
		
		listaComposite = new FacturaListaComposite(shell, SWT.DIALOG_TRIM);		
		listaComposite.toDisplay(new Point(0, 0));
		
		listaFacturas =facturaService.search(getFacturaSearchContext());
		refresh();
		populateClienteSearchCombo();
		bindSearchListener();
		bindEditListener();
		bindAddListener();
		bindDeleteListener();
		//Para poner los textos que queramos
		customize();
		listaComposite.open();
	}
	

	private void populateClienteSearchCombo() {
		
			List listaClientes = manager.getClienteDAO().findAll();		
				
			this.listaComposite.getFacturaSearchComposite1().getCmbCliente().removeAll();
			this.listaComposite.getFacturaSearchComposite1().getCmbCliente().add("",0);	
			
			SWTUtils.refreshCombo(this.listaComposite.getFacturaSearchComposite1().getCmbCliente(), listaClientes, new String[]{ "nombre","direccion"}); //$NON-NLS-1$
			
			//this.listaComposite.getFacturaSearchComposite1().getCmbCliente().add("",0);			
			this.listaComposite.getFacturaSearchComposite1().getTxtAnyo().setText(getFacturaSearchContext().getAnyo());
			this.listaComposite.getFacturaSearchComposite1().getTxtNumFactura().setText(getFacturaSearchContext().getNumero());
			//this.listaComposite.getFacturaSearchComposite1().getTxtAnyo().setText(getFacturaSearchContext().getAnyo());			
	}
	
	/**
	 * Binds the Edit listener
	 *
	 */
	private void bindSearchListener() {
		
		final Button btnSearch = listaComposite.getFacturaSearchComposite1().getBtnBuscar();
		btnSearch.addSelectionListener(new SelectionAdapter() {

			public void widgetSelected(SelectionEvent evt) {
				
				if(DEBUG){								
					log.debug("btnSearch.widgetSelected, event="
							+ evt);								
				}
								
				doSearch();
								
			}
			
		});
	}
	
	/**
	 * Binds the Delete listener
	 *
	 */
	private void bindDeleteListener() {
		
		final Button btnDelete = listaComposite.getListaComposite1().getThreeButtonsComposite().getBtnEliminar();
		btnDelete.addSelectionListener(new SelectionAdapter() {

			public void widgetSelected(SelectionEvent evt) {
				
				if(DEBUG){								
					log.debug("btnSearch.widgetSelected, event="
							+ evt);								
				}
								
				doDelete();
								
			}
			
		});
	}
	

	/**
	 * Binds the Edit listener
	 *
	 */
	private void bindEditListener() {
		
		final Button btnModif = listaComposite.getListaComposite1().getThreeButtonsComposite().getBtnModificar();
		btnModif.addSelectionListener(new SelectionAdapter() {

			public void widgetSelected(SelectionEvent evt) {
				
				if(DEBUG){								
					log.debug("buttonModif.widgetSelected, event="
							+ evt);								
				}
								
				doCopy();
								
			}
			
		});
		
		listaComposite.getListaComposite1().getTabla().addMouseListener(new MouseListener() {
			
			public void mouseUp(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}
			
			public void mouseDown(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}
			
			public void mouseDoubleClick(MouseEvent arg0) {
				
				if(DEBUG){								
					log.debug("buttonModif.widgetSelected, event=" + arg0);								
				}
								
				doEdit();
			}
		});
	}
	
	/**
	 * Binds the Edit listener
	 *
	 */
	private void bindAddListener() {
		final Button btnAdd = listaComposite.getListaComposite1().getThreeButtonsComposite().getBotonNuevo();
		btnAdd.addSelectionListener(new SelectionAdapter() {

			public void widgetSelected(SelectionEvent evt) {
				
				if(DEBUG){								
					log.debug("btnAdd.widgetSelected, event="
							+ evt);								
				}
								
				doAdd();
								
			}
			
		});
	}
	
	
	/**
	 * Rellenamos la tabla SWT con los valores de la lista
	 * @param lista Lista de programas que queremos mostrar
	 */
	private void refresh() {
		int num=0;		
		
		Table tabla=listaComposite.getListaComposite1().getTabla();
		
		
		//Turn off drawing to avoid flicker
		tabla.setRedraw(false);
		
		//Borramos lineas de la tabla
		tabla.removeAll();
		 DateFormat formatter = new SimpleDateFormat("dd/MM/yy");
	   
		if(listaFacturas!=null){
			//Ordenamos
			//Collections.sort(lista, comparator);
			//Salvamos la lista ordenada en la propia tabla
			tabla.setData(listaFacturas);
			Iterator i=listaFacturas.iterator();
			while(i.hasNext()){
				Factura p=(Factura)i.next();
									
				TableItem item = new TableItem(tabla, SWT.NONE);
				item.setText(0, p.getId().getNumero().toString());
				item.setText(1, p.getCliente().getNombre());
				item.setText(2, formatter.format(p.getFecha()));
			}//while
			
			//Actualizamos el numero de elementos
			num=listaFacturas.size();
		}		
		listaComposite.getListaComposite1().getNumElementosComposite().getText().setText(String.valueOf(num));
		
//		Turn drawing back on
	    tabla.setRedraw(true);
	}
	
	
	/**
	 * Evento a realizar al pulsar sobre el botón buscar
	 */
	private void doSearch() {
		
		FacturaSearch facturaSearch = getFacturaSearchContext();

		facturaSearch.setAnyo(listaComposite.getFacturaSearchComposite1().getTxtAnyo().getText());
		facturaSearch.setNumero(listaComposite.getFacturaSearchComposite1().getTxtNumFactura().getText());
		
		int selectedCliente= listaComposite.getFacturaSearchComposite1().getCmbCliente().getSelectionIndex();
		if(selectedCliente >= 0)
		 {
			List listaClientes = (List)listaComposite.getFacturaSearchComposite1().getCmbCliente().getData();		
		 	facturaSearch.setNumCliente(((Cliente)listaClientes.get(selectedCliente)).getIdentificador().toString());
		 } else {
			 facturaSearch.setNumCliente("");
		 }
	
		listaFacturas = facturaService.search(facturaSearch);
		refresh();
		
	}
	
	
	private void doAdd() {
		
		//Cargamos en el contexto la factura obtenida
		Context ctx=ApplicationManager.getManager().getContext();		


		Calendar calendar = Calendar.getInstance();		
		int any = calendar.get(Calendar.YEAR);
		Integer siguienteNum = facturaService.getNextIdFactura(any);
		
		if(log.isDebugEnabled())
			log.debug("Siguiente id para año" + any + " ," + siguienteNum );
		
		Factura factura = new Factura();
		factura.setId(new FacturaId(siguienteNum,new Integer(any)));
		
		ctx.setAttribute(Factura.class.getName(), factura);
		
		Shell shell = new Shell(listaComposite.getShell(), SWT.APPLICATION_MODAL|SWT.DIALOG_TRIM);
		shell.setText(Messages.getString("ListaFacturasHandler.add.title"));			
		EditFacturaComposite composite=new EditFacturaComposite(shell,SWT.NONE, false);
		composite.open();
			
		
		listaFacturas = facturaService.search(getFacturaSearchContext());
		refresh();
	}
	
	private void doDelete() {
		if(log.isDebugEnabled()){								
			log.debug("doDeleteFactura");								
		}
		
		Table tabla = listaComposite.getListaComposite1().getTabla();
		if(tabla.getSelection().length==0){
			MessageBox m = new MessageBox(listaComposite.getShell(),SWT.ICON_WARNING);
			m.setMessage(Messages.getString("ListaFacturasHandler.select.info"));
			m.open();
		}
		else{						
			MessageBox m = new MessageBox(listaComposite.getShell(),SWT.ICON_QUESTION | SWT.YES | SWT.NO);
			m.setMessage(Messages.getString("ListaFacturasHandler.delete.info"));
									
			if(m.open()==SWT.YES){
				
				List lista=(List)tabla.getData();
				int[] seleccion=tabla.getSelectionIndices();
				List listaBorrar = new ArrayList();
				for(int i=0;i<tabla.getSelectionCount();i++){						
					tabla.remove(seleccion[i]);
					listaBorrar.add(listaFacturas.get(seleccion[i]));
					listaFacturas.remove(seleccion[i]);					
				}				
				
				facturaService.deleteListaFacturas(listaBorrar);
				refresh();
			}														
		}
	}
	/**
	 * Realiza la edicion de un registro 
	 *
	 */
	private void doEdit() {
		
		Table tabla=listaComposite.getListaComposite1().getTabla();				
		if(tabla.getSelection().length==0){
			MessageBox m = new MessageBox(listaComposite.getShell(),SWT.ICON_WARNING);
			m.setMessage(Messages.getString("ListaFacturasHandler.select.info"));
			m.open();
		}
		else{				
			//Cargamos en el contexto la factura obtenida
			Context ctx=ApplicationManager.getManager().getContext();
			
			
			List lista=(List)tabla.getData();
			if(lista!=null){
				Factura f=(Factura)lista.get(tabla.getSelectionIndex());
				
				if(DEBUG){
					log.debug("Factura elegida: " + f.toString());					
				}
				
				
				Factura factura=facturaService.getFacturaById(f.getId());
				//ClienteDAO clienteDAO = manager.getClienteDAO();
		
				if(DEBUG){
					log.debug("Factura recuperada: " + f.toString());					
				}
			
				
				ctx.setAttribute(Factura.class.getName(), factura);
				
				Shell shell = new Shell(listaComposite.getShell(), SWT.APPLICATION_MODAL|SWT.DIALOG_TRIM);
				shell.setText(Messages.getString("ListaCentrosHandler.edit.title"));
				
				EditFacturaComposite composite=new EditFacturaComposite(shell,SWT.NONE, true);
				composite.open();
				
				//FIXME Populamos la tabla
				doSearch();

			}
																	
		}
		
	}
	
	/**
	 * Realiza la edicion de un registro 
	 *
	 */
	private void doCopy() {
		
		Table tabla=listaComposite.getListaComposite1().getTabla();				
		if(tabla.getSelection().length==0){
			MessageBox m = new MessageBox(listaComposite.getShell(),SWT.ICON_WARNING);
			m.setMessage(Messages.getString("ListaFacturasHandler.select.info"));
			m.open();
		}
		else{				
			//Cargamos en el contexto la factura obtenida
			Context ctx=ApplicationManager.getManager().getContext();
			
			
			List lista=(List)tabla.getData();
			if(lista!=null){
				Factura f=(Factura)lista.get(tabla.getSelectionIndex());
				
				if(DEBUG){
					log.debug("Factura elegida: " + f.toString());					
				}
				
				//Copiamos la factura			
				facturaService.copyFacturaById(f.getId());
				listaFacturas =facturaService.search(getFacturaSearchContext());
				refresh();
			}
																	
		}
		
	}
	
	/**
	 * Devuelve el objeto de busquedas de factura en contexto
	 * @return
	 */
	public FacturaSearch getFacturaSearchContext() {
		Context ctx=ApplicationManager.getManager().getContext();	
		FacturaSearch facturaSearch = (FacturaSearch)ctx.getAttribute(FacturaSearch.class.getName());
		
		if(facturaSearch ==null) {
			facturaSearch = new FacturaSearch();
			Calendar cal = Calendar.getInstance();
			facturaSearch.setAnyo(String.valueOf(cal.get(Calendar.YEAR)));
			ctx.setAttribute(FacturaSearch.class.getName(),facturaSearch);
		}
		return facturaSearch;
	}
	
	/**
	 * Pone los textos a los campos
	 */
	private void customize() {
		//botonera derecha
		this.listaComposite.getListaComposite1().getThreeButtonsComposite().getBtnEliminar().setText(Messages.getString("ListaFacturasHandler.button.delete.text"));
		this.listaComposite.getListaComposite1().getThreeButtonsComposite().getBotonNuevo().setText(Messages.getString("ListaFacturasHandler.button.add.text"));
		this.listaComposite.getListaComposite1().getThreeButtonsComposite().getBtnModificar().setText(Messages.getString("ListaFacturasHandler.button.edit.text"));
		
		//listado
		this.listaComposite.getListaComposite1().getTabla().getColumns()[0].setText(Messages.getString("ListaFacturasHandler.table.col1.title"));
		this.listaComposite.getListaComposite1().getTabla().getColumns()[1].setText(Messages.getString("ListaFacturasHandler.table.col2.title"));
		this.listaComposite.getListaComposite1().getTabla().getColumns()[2].setText(Messages.getString("ListaFacturasHandler.table.col3.title"));
		
		 Listener sortListener = new Listener() {
		      
			 public void handleEvent(Event e) {
		    	
		    	Table table = listaComposite.getListaComposite1().getTabla();
		        TableItem[] items = table.getItems();
		        Collator collator = Collator.getInstance(Locale.getDefault());
		        TableColumn column = (TableColumn) e.widget;
		        int index = 0;
		        TableColumn[] columns = table.getColumns(); 
		        for(int i=0; i < columns.length;i++) {
		        	if(columns[i].equals(column)) {
		        		index=i;
		        		break;
		        	}
		        }
		        	
		        listaFacturas= (List)table.getData();
		        switch(index) {
		       		case 0:
		       			Collections.sort(listaFacturas,new BeanComparator("id.numero"));
		        		break;
		        	case 1: 
		        		Collections.sort(listaFacturas,new BeanComparator("cliente.nombre"));
		        		break;
		        	case 2: 
		        		Collections.sort(listaFacturas,new BeanComparator("fecha"));
		        		break;		        		
		        }
		        
		        if(table.getSortDirection() == SWT.UP) {
		        	Collections.reverse(listaFacturas);
		        	table.setSortDirection(SWT.DOWN);
		        } else {
		        	table.setSortDirection(SWT.UP);
		        }
		        refresh();
		        table.setSortColumn(column);
		      }
		    };
		   
		    this.listaComposite.getListaComposite1().getTabla().getColumns()[0].addListener(SWT.Selection, sortListener);
		    this.listaComposite.getListaComposite1().getTabla().getColumns()[1].addListener(SWT.Selection, sortListener);
		    this.listaComposite.getListaComposite1().getTabla().getColumns()[2].addListener(SWT.Selection, sortListener);		    
		   

	}
}
