package es.dalocar.facturamas.swt.edit;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperExportManager;

import org.apache.log4j.Logger;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;

import es.dalocar.facturamas.reports.FacturaDetailReport;
import es.dalocar.facturamas.reports.Report;
import es.dalocar.facturamas.reports.Reporter;
import es.dalocar.facturamas.swt.SWTUtils;
import es.dalocar.facturamas.swt.components.SaveCancelComposite;
import es.dalocar.facturamas.swt.list.ListaComposite;
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.LineaFactura;
import es.dalocar.software.beans.LineaFacturaId;
import es.dalocar.software.services.AmortizacionService;
import es.dalocar.software.services.FacturaService;
import es.dalocar.software.utils.ResourceUtils;

/**
 * This code was edited or generated using CloudGarden's Jigloo SWT/Swing GUI
 * Builder, which is free for non-commercial use. If Jigloo is being used
 * commercially (ie, by a corporation, company or business for any purpose
 * whatever) then you should purchase a license for each developer using Jigloo.
 * Please visit www.cloudgarden.com for details. Use of Jigloo implies
 * acceptance of these licensing terms. A COMMERCIAL LICENSE HAS NOT BEEN
 * PURCHASED FOR THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED LEGALLY FOR
 * ANY CORPORATE OR COMMERCIAL PURPOSE.
 */
public class EditFacturaComposite extends Composite {

	private static final Logger log = Logger
			.getLogger(EditFacturaComposite.class);

	private Factura factura;
	private ApplicationManager manager;
	private EditDetailFactura editDetailFactura_1;
	private MenuItem menuItemFile;
	private MenuItem pdfItem;
	private MenuItem menuItemPrint;
	private Menu menu1;
	private Menu menuBar;
	private SaveCancelComposite saveCancelComposite1;
	private ListaComposite listaComposite;
	private boolean editMode;
	private String initialState;

	/**
	 * Create the composite.
	 * 
	 * @param parent
	 * @param style
	 */
	public EditFacturaComposite(Composite parent, int style, boolean editMode) {
		super(parent, style);
		GridLayout thisLayout = new GridLayout();
		this.setLayout(thisLayout);
		{
			menuBar = new Menu(getShell(), SWT.BAR);
			getShell().setMenuBar(menuBar);
			{
				menuItemFile = new MenuItem(menuBar, SWT.CASCADE);
				menuItemFile.setText("Archivo");
				{
					menu1 = new Menu(menuItemFile);
					menuItemFile.setMenu(menu1);
					{
						menuItemPrint = new MenuItem(menu1, SWT.PUSH);
						menuItemPrint.setText("Imprimir");
					}
					{
						pdfItem = new MenuItem(menu1, SWT.PUSH);
						pdfItem.setText("Exportar a PDF");
					}
				}
			}
		}

		editDetailFactura_1 = new EditDetailFactura(this, SWT.NONE);
		GridData editDetailFactura_1LayoutData = new GridData();
		editDetailFactura_1.setLayoutData(editDetailFactura_1LayoutData);

		listaComposite = new ListaComposite(this, SWT.NONE);
		GridData listaComposite_LayoutData = new GridData();
		listaComposite_LayoutData.widthHint = 774;
		listaComposite_LayoutData.heightHint = 317;
		listaComposite.setLayoutData(listaComposite_LayoutData);
		{
			GridData saveCancelComposite1LData = new GridData();
			saveCancelComposite1 = new SaveCancelComposite(this, SWT.NONE);
			saveCancelComposite1.setLayoutData(saveCancelComposite1LData);
		}

		manager = ApplicationManager.getManager();
		this.editMode = editMode;

		addComboCliente();
		refresh();

		initialState = SWTUtils.calculateState(this);

		bindSaveCancelButtonsListeners();
		bindLineaButtonsListeners();
		bindModifyListeners();
		bindPrintListeners();
	}

	/**
	 * Metodo que abre deja el nuevo composite en el bucle de espera de eventos
	 */
	public void open() {
		final Display display = Display.getCurrent();
		Shell shell = this.getShell();

		Point size = this.getSize();
		shell.setLayout(new FillLayout());
		shell.layout();
		if (size.x == 0 && size.y == 0) {
			this.pack();
			shell.pack();
		} else {
			Rectangle shellBounds = shell.computeTrim(0, 0, size.x, size.y);
			shell.setSize(shellBounds.width, shellBounds.height);
		}
		SWTUtils.openCentered(shell);
	}

	protected void checkSubclass() {
		// Disable the check that prevents subclassing of SWT components
	}

	/**
	 * Metodo que refresca los datos del formulario a partir de un objeto de
	 * tipo Centro
	 */
	private void refresh() {

		Factura factura = getFacturaContext();

		if (log.isDebugEnabled())
			log.debug(">> Refresh: " + factura.getId().toString());

		this.editDetailFactura_1.getTxtIdfactura().setText(
				factura.getId().getNumero().toString());

		if (this.editMode) {
			this.editDetailFactura_1.getTxtModopago().setText(
					factura.getModopago());
			this.editDetailFactura_1.getDatePickerFecha().setDate(
					factura.getFecha());
			this.editDetailFactura_1.getDatePickerCobro().setDate(
					factura.getFechacobro());
			this.editDetailFactura_1.getButtonCobrada().setSelection(
					factura.getCobrada().booleanValue());
			this.editDetailFactura_1.getTxtIrpf().setText(
					factura.getIrpf().toString());
			SWTUtils.selectCombo(this.editDetailFactura_1.getComboClientes(),
					factura.getCliente());
		} else {
			this.editDetailFactura_1.getDatePickerFecha().setDate(new Date());
			this.editDetailFactura_1.getTxtIrpf().setText(
					ResourceUtils.getString(ResourceUtils.IRPF_FACTURA));
		}

		// this.editDetailFactura_1.getComboClientes().select()
		// this.editDetailFactura_1.gett

		// Rellenar tabla de lineas
		populateTabla();
		customize();
	}

	private void addComboCliente() {
		List listaClientes = manager.getClienteDAO().findAll();

		this.editDetailFactura_1.getComboClientes().removeAll();

		// Añadimos un regimen en blanco al principio
		this.editDetailFactura_1.getComboClientes().add("", 0); //$NON-NLS-1$

		SWTUtils.refreshCombo(this.editDetailFactura_1.getComboClientes(),
				listaClientes, "nombre"); //$NON-NLS-1$
	}

	/**
	 * Rellena la tabla de lineas de factura
	 */
	private void populateTabla() {

		Table tabla = listaComposite.getTabla();

		// Turn off drawing to avoid flicker
		tabla.setRedraw(false);

		// Borramos lineas de la tabla
		tabla.removeAll();
		List lista = new ArrayList();
		lista.addAll(factura.getLineaFacturas());
		int num = 0;
		if (lista != null) {
			// Ordenamos
			// Collections.sort(lista, comparator);
			// Salvamos la lista ordenada en la propia tabla
			tabla.setData(lista);
			Iterator i = lista.iterator();
			while (i.hasNext()) {
				LineaFactura linea = (LineaFactura) i.next();

				TableItem item = new TableItem(tabla, SWT.NONE);
				item.setText(0, linea.getId().getNumerolinea().toString());
				item.setText(1, linea.getDescripcion());

			}// while

			// Actualizamos el numero de elementos
			num = lista.size();
		}
		listaComposite.getNumElementosComposite().getText().setText(
				String.valueOf(num));

		// Turn drawing back on
		tabla.setRedraw(true);
	}

	/**
	 * Metodo que obtiene el centro del contexto
	 * 
	 * @return the Centro
	 */
	private Factura getFacturaContext() {

		Context ctx = manager.getContext();
		factura = (Factura) ctx.getAttribute(Factura.class.getName());
		if (factura == null) {
			factura = new Factura();
			//new Long("0"), null, "", "", "", "", "", new Date()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$

			ctx.setAttribute(Factura.class.getName(), factura);
		}

		return factura;
	}

	/**
	 * Añade los listeners para los botones del composite de lineas
	 */
	private void bindLineaButtonsListeners() {

		final Button btnAdd = listaComposite.getThreeButtonsComposite()
				.getBotonNuevo();

		btnAdd.addSelectionListener(new SelectionAdapter() {

			public void widgetSelected(SelectionEvent evt) {

				if (log.isDebugEnabled()) {
					log.debug("btnAdd.widgetSelected, event=" + evt);
				}

				doAddLinea();

			}

		});

		final Button btnModif = listaComposite.getThreeButtonsComposite()
				.getBtnModificar();
		btnModif.addSelectionListener(new SelectionAdapter() {

			public void widgetSelected(SelectionEvent evt) {

				if (log.isDebugEnabled()) {
					log.debug("buttonModif.widgetSelected, event=" + evt);
				}

				doEditLinea();

			}

		});

		final Button btnDelete = listaComposite.getThreeButtonsComposite()
				.getBtnEliminar();
		btnDelete.addSelectionListener(new SelectionAdapter() {

			public void widgetSelected(SelectionEvent evt) {

				if (log.isDebugEnabled()) {
					log.debug("btnDelete.widgetSelected, event=" + evt);
				}

				doDeleteLinea();

			}

		});

	}

	/**
	 * Añade los listeners a los botones del formulario
	 */
	private void bindSaveCancelButtonsListeners() {

		final Button botonCancelar = this.saveCancelComposite1.getBtnCancelar();
		botonCancelar.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent evt) {

				if (log.isDebugEnabled()) {
					log.debug("buttonModif.widgetSelected, event=" + evt);
				}

				getShell().dispose();

			}

		});

		final Button botonGuardar = this.saveCancelComposite1.getBtnGuardar();
		botonGuardar.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent evt) {

				if (log.isDebugEnabled()) {
					log.debug("butonSave.widgetSelected, event=" + evt);
				}

				if (checkModify()) {
					MessageBox m = new MessageBox(getShell(), SWT.YES | SWT.NO
							| SWT.ICON_QUESTION);
					m.setMessage(Messages
							.getString("EditFacturaComposite.save.changes"));
					int valor = m.open();
					if (valor == SWT.YES) {
						FacturaService service = new FacturaService(
								ApplicationManager.getManager());
						populate();
						service.saveFactura(factura);
						getShell().dispose();
					} else {
						getShell().dispose();
					}
				} else {
					getShell().dispose();
				}
			}

		});

	}

	/**
	 * 
	 */
	private void bindPrintListeners() {
		menuItemPrint.setAccelerator(SWT.CONTROL + 'P');
		menuItemPrint.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent evt) {
				doPrint();
			}
		});
		pdfItem.setAccelerator(SWT.CONTROL + 'E');
		pdfItem.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent evt) {
				doExportPDF();
			}
		});

	}

	private void populate() {

		int selectedCliente = this.editDetailFactura_1.getComboClientes()
				.getSelectionIndex();
		List listaClientes = (List) this.editDetailFactura_1.getComboClientes()
				.getData();

		factura.setCliente((Cliente) listaClientes.get(selectedCliente));
		factura.setCobrada(Boolean.valueOf(this.editDetailFactura_1
				.getButtonCobrada().getSelection()));
		factura.setFecha(this.editDetailFactura_1.getDatePickerFecha()
				.getDate());
		factura.setFechacobro(this.editDetailFactura_1.getDatePickerCobro()
				.getDate());
		factura
				.setModopago(this.editDetailFactura_1.getTxtModopago()
						.getText());
		factura.setIrpf(Double.valueOf(this.editDetailFactura_1.getTxtIrpf()
				.getText()));
		Iterator it = factura.getLineaFacturas().iterator();
		double importeTotal = 0.0;
		double netoLinea = 0.0;
		double ivaLinea = 0.0;
		while (it.hasNext()) {
			LineaFactura linea = (LineaFactura) it.next();
			netoLinea = linea.getCantidad().doubleValue()
					* linea.getPrecio().doubleValue();
			ivaLinea = netoLinea * linea.getIva().doubleValue() / 100;
			importeTotal += netoLinea + ivaLinea;
		}
		factura.setImportefactura(Double.valueOf(importeTotal));

	}

	/**
	 * Acciones a realizar al añadir una nueva linea
	 */
	public void doAddLinea() {

		Table tabla = listaComposite.getTabla();

		Context ctx = ApplicationManager.getManager().getContext();

		LineaFactura linea = new LineaFactura();
		LineaFacturaId id = new LineaFacturaId();
		id.setAnyofactura(getFacturaContext().getId().getAnyo());
		id.setNumerofactura(getFacturaContext().getId().getNumero());
		id.setNumerolinea(new Integer(factura.getLineaFacturas().size() + 1));
		linea.setId(id);

		ctx.setAttribute(LineaFactura.class.getName(), linea);

		Shell shell = new Shell(listaComposite.getShell(),
				SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM);
		shell
				.setText(Messages
						.getString("EditLineaFacturaComposite.add.title"));

		EditLineaFacturaComposite composite = new EditLineaFacturaComposite(
				shell, SWT.TITLE, false);
		composite.open();

		linea = (LineaFactura) ctx.getAttribute(LineaFactura.class.getName());

		if (linea != null)
			factura.getLineaFacturas().add(linea);

		refresh();
		checkModify();

	}

	/**
	 * Acciones a realizar al pulsar sobre el botón editar línea
	 */
	public void doEditLinea() {
		Table tabla = listaComposite.getTabla();
		if (tabla.getSelection().length == 0) {
			MessageBox m = new MessageBox(listaComposite.getShell(),
					SWT.ICON_WARNING);
			m.setMessage(Messages.getString("ListaLineas.select.info"));
			m.open();
		} else {
			Context ctx = ApplicationManager.getManager().getContext();

			List lista = (List) tabla.getData();
			if (lista != null) {

				LineaFactura linea = (LineaFactura) lista.get(tabla
						.getSelectionIndex());
				ctx.setAttribute(LineaFactura.class.getName(), linea);

				Shell shell = new Shell(listaComposite.getShell(),
						SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM);
				shell.setText(Messages
						.getString("EditLineaFacturaComposite.edit.title"));

				EditLineaFacturaComposite composite = new EditLineaFacturaComposite(
						shell, SWT.NONE, true);
				composite.open();

				refresh();
				checkModify();
			}
		}

	}

	/**
	 * Acciones a realizar al pulsar sobre el botón editar línea
	 */
	public void doDeleteLinea() {

		if (log.isDebugEnabled()) {
			log.debug("doDeleteLinea");
		}

		Table tabla = listaComposite.getTabla();
		if (tabla.getSelection().length == 0) {
			MessageBox m = new MessageBox(listaComposite.getShell(),
					SWT.ICON_WARNING);
			m.setMessage(Messages.getString("ListaLineas.select.info"));
			m.open();
		} else {
			MessageBox m = new MessageBox(listaComposite.getShell(),
					SWT.ICON_QUESTION | SWT.YES | SWT.NO);
			m.setMessage(Messages.getString("ListaLineas.delete.info"));

			if (m.open() == SWT.YES) {

				List lista = (List) tabla.getData();
				int[] seleccion = tabla.getSelectionIndices();

				for (int i = 0; i < tabla.getSelectionCount(); i++) {
					factura.getLineaFacturas().remove(lista.get(seleccion[i]));
					tabla.remove(seleccion[i]);
					lista.remove(seleccion[i]);

				}
				Context ctx = ApplicationManager.getManager().getContext();
				ctx.setAttribute(Factura.class.getName(), factura);
				refresh();
			}
		}
	}

	private void doPrint() {
		// Rellenamos el bean
		populate();

		if (log.isDebugEnabled())
			log.debug("Factura con " + factura.getLineaFacturas().size()
					+ " lineas." + factura.toString());
		// Abrimos el informe
		Collection beans = new ArrayList();
		beans.add(factura);

		// Rellenamos los parámetros
		Map map = new java.util.HashMap();

		// Creamos el Report
		Report report = new FacturaDetailReport(map, beans);

		// Visualizamos
		Reporter.view(report);

	}
	
	private void doExportPDF() {
		// Rellenamos el bean
		populate();

		if (log.isDebugEnabled())
			log.debug("Factura con " + factura.getLineaFacturas().size()
					+ " lineas." + factura.toString());
		// Abrimos el informe
		Collection beans = new ArrayList();
		beans.add(factura);

		// Rellenamos los parámetros
		Map map = new java.util.HashMap();

		// Creamos el Report
		Report report = new FacturaDetailReport(map, beans);

		
//		Shell shell = new Shell(listaComposite.getShell(), SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM);
//		
		Shell shell = new Shell(this.getDisplay().getActiveShell(),
				SWT.APPLICATION_MODAL | SWT.SHELL_TRIM);

		
		FileDialog fileDialog = new FileDialog(shell, SWT.CLOSE);
		fileDialog.setFileName(this.getEditDetailFactura().getTxtIdfactura().getText() + ".pdf" );
		String destFileName = fileDialog.open();
		
		
		// Visualizamos
		try {
			JasperExportManager.exportReportToPdfFile(report.getJasperPrint(), destFileName);
		} catch (JRException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	

	}

	/**
	 * Añade los listeners de modificación a los campos del formulario
	 */
	private void bindModifyListeners() {

		ModifyListener listener = new ModifyListener() {
			public void modifyText(ModifyEvent evt) {
				if (log.isDebugEnabled())
					log.debug("modifyText, event=" + evt);
				checkModify();
			}
		};

		this.editDetailFactura_1.getTxtModopago().addModifyListener(listener);
		this.editDetailFactura_1.getComboClientes().addModifyListener(listener);
		this.editDetailFactura_1.getDatePickerFecha().addModifyListener(
				listener);
		this.editDetailFactura_1.getDatePickerCobro().addModifyListener(
				listener);
		this.editDetailFactura_1.getButtonCobrada().addSelectionListener(
				new SelectionListener() {

					public void widgetSelected(SelectionEvent arg0) {
						checkModify();
					}

					public void widgetDefaultSelected(SelectionEvent arg0) {
						checkModify();

					}
				});

	}

	/**
	 * Comprobar el estado del formulario
	 * 
	 * @return Devuelve true si se ha producido alguna modificación en el
	 *         formulario, false en caso contrario
	 * 
	 */
	private boolean checkModify() {
		String currentState = SWTUtils.calculateState(this);

		if (log.isDebugEnabled()) {
			log.debug("initialState: " + initialState);
			log.debug("currentState: " + currentState);
		}

		boolean modified = !initialState.equals(currentState);
		this.saveCancelComposite1.getBtnGuardar().setEnabled(modified);
		return modified;
	}

	public EditDetailFactura getEditDetailFactura() {
		return editDetailFactura_1;
	}

	public ListaComposite getListaComposite() {
		return listaComposite;
	}

	public SaveCancelComposite getSaveCancelComposite1() {
		return saveCancelComposite1;
	}

	/**
	 * Personalizacion
	 * 
	 */
	private void customize() {

		// Establecer los controles que sean requeridos
		editDetailFactura_1.getTxtIdfactura().setData(
				SWTUtils.CONTROL_REQUIRED, Boolean.TRUE);
		editDetailFactura_1.getDatePickerFecha().setData(
				SWTUtils.CONTROL_REQUIRED, Boolean.TRUE);
		editDetailFactura_1.getComboClientes().setData(
				SWTUtils.CONTROL_REQUIRED, Boolean.TRUE);

		// Establecer los textos
		listaComposite.getThreeButtonsComposite().getBotonNuevo().setText(
				"&Añadir");// Messages.getString("EditFacturaComposite.buttons.add"));
		listaComposite.getThreeButtonsComposite().getBtnModificar().setText(
				Messages.getString("EditFacturaComposite.buttons.edit"));
		listaComposite.getThreeButtonsComposite().getBtnEliminar().setText(
				Messages.getString("EditFacturaComposite.buttons.delete"));
		SWTUtils.customize(this);
	}

}
