package es.dalocar.facturamas.swt.edit;

import java.util.List;

import org.apache.commons.validator.GenericValidator;
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.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import es.dalocar.appskeleton.swt.ACButtonsComposite;
import es.dalocar.appskeleton.swt.SWTUtils;
import es.dalocar.software.ApplicationManager;
import es.dalocar.software.beans.Cliente;
import es.dalocar.software.delegates.ClienteDelegate;

/**
 * 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.
 */
/**
 * Composite para editar un Cliente
 */
public class ClienteEditComposite extends org.eclipse.swt.widgets.Composite {

	// $hide>>$
	private static Logger log = Logger.getLogger(ClienteEditComposite.class);
	private static boolean DEBUG = log.isDebugEnabled();
	// private static boolean INFO = log.isInfoEnabled();
	// $hide<<$

	private Label lblIdentificador;
	private Text txtIdentificador;
	private Label lblCif;
	private Text txtCif;
	private Label lblNombre;
	private Text txtNombre;
	private Label lblDireccion;
	private Text txtDireccion;
	private Label lblPoblacion;
	private Text txtPoblacion;
	private Label lblProvincia;
	private Text txtProvincia;
	private Label lblCp;
	private Text txtCp;
	private Label lblTelefono;
	private Text txtTelefono;
	private Label lblFax;
	private Text txtFax;
	private Label lblActivo;
	private Button botonActivo;

	private Group group1;
	private ACButtonsComposite buttons;

	// $hide>>$
	private ApplicationManager manager;
	private ClienteDelegate delegate;
	// $hide<<$

	private boolean esAlta;
	private String initialState;

	/**
	 * Auto-generated main method to display this
	 * org.eclipse.swt.widgets.Composite inside a new Shell.
	 */
	public static void main(String[] args) {
		showGUI();
	}

	/**
	 * Auto-generated method to display this org.eclipse.swt.widgets.Composite
	 * inside a new Shell.
	 */
	public static void showGUI() {
		Display display = Display.getDefault();
		Shell shell = new Shell(display);
		ClienteEditComposite inst = new ClienteEditComposite(shell, SWT.NULL);
		Point size = inst.getSize();
		shell.setLayout(new FillLayout());
		shell.setText("Cliente");
		shell.layout();
		if (size.x == 0 && size.y == 0) {
			inst.pack();
			shell.pack();
		} else {
			Rectangle shellBounds = shell.computeTrim(0, 0, size.x, size.y);
			shell.setSize(shellBounds.width, shellBounds.height);
		}
		SWTUtils.openCentered(inst, shell);
	}

	/**
	 * Constructor que inicializa la GUI
	 * 
	 * @param parent
	 * @param style
	 */
	public ClienteEditComposite(org.eclipse.swt.widgets.Composite parent, int style) {
		this(parent,style,true);
	}
	/**
	 * Constructor que inicializa la GUI
	 * 
	 * @param parent
	 * @param style
	 * @param esAlta Indica si estamos editando o añadiendo
	 */
	public ClienteEditComposite(org.eclipse.swt.widgets.Composite parent, int style, boolean esAlta) {

		super(parent, style);
		this.esAlta = esAlta;

		initGUI();

		this.txtIdentificador.setEnabled(esAlta);
		
		// Desactivamos el boton aceptar
		this.buttons.getButtonAceptar().setEnabled(false);
		initialState = SWTUtils.calculateState(this);
		manager = ApplicationManager.getManager();

		delegate = (ClienteDelegate) manager.getClienteDelegate();

		refresh();
		// $hide<<$
		customize();

		addListeners();
	}

	/**
	 * Init GUI
	 * 
	 */
	private void initGUI() {
		{
			// Register as a resource user - SWTResourceManager will
			// handle the obtaining and disposing of resources
			// SWTResourceManager.registerResourceUser(getShell());
		}

		try {
			FormLayout thisLayout = new FormLayout();
			this.setLayout(thisLayout);
			this.setSize(740, 376);

			// START >> group1
			group1 = new Group(this, SWT.NONE);
			FormData group1LData = new FormData();
			group1LData.width = 714;
			group1LData.height = 308;
			group1LData.left = new FormAttachment(0, 1000, 10);
			group1LData.top = new FormAttachment(0, 1000, 0);
			group1LData.right = new FormAttachment(1000, 1000, -10);
			group1.setLayoutData(group1LData);
			group1.setText("Cliente");

			{
				lblIdentificador = new Label(group1, SWT.NONE);
				lblIdentificador.setText("Identificador");
				lblIdentificador.setBounds(10, 21, 120, 21);
			}
			{
				txtIdentificador = new Text(group1, SWT.BORDER);
				txtIdentificador.setBounds(145, 21, 329, 21);
				txtIdentificador.setTextLimit(35);
				// SWTUtils.computeWidth(txtIdentificador);
			}
			{
				lblCif = new Label(group1, SWT.NONE);
				lblCif.setText("Cif");
				lblCif.setBounds(10, 49, 120, 21);
			}
			{
				txtCif = new Text(group1, SWT.BORDER);
				txtCif.setBounds(145, 49, 329, 21);
				txtCif.setTextLimit(35);
				// SWTUtils.computeWidth(txtCif);
			}
			{
				lblNombre = new Label(group1, SWT.NONE);
				lblNombre.setText("Nombre");
				lblNombre.setBounds(10, 77, 120, 21);
			}
			{
				txtNombre = new Text(group1, SWT.BORDER);
				txtNombre.setBounds(145, 77, 329, 21);
				txtNombre.setTextLimit(35);
				// SWTUtils.computeWidth(txtNombre);
			}
			{
				lblDireccion = new Label(group1, SWT.NONE);
				lblDireccion.setText("Direccion");
				lblDireccion.setBounds(10, 105, 120, 21);
			}
			{
				txtDireccion = new Text(group1, SWT.BORDER);
				txtDireccion.setBounds(145, 105, 329, 21);
				txtDireccion.setTextLimit(35);
				// SWTUtils.computeWidth(txtDireccion);
			}
			{
				lblPoblacion = new Label(group1, SWT.NONE);
				lblPoblacion.setText("Poblacion");
				lblPoblacion.setBounds(10, 133, 120, 21);
			}
			{
				txtPoblacion = new Text(group1, SWT.BORDER);
				txtPoblacion.setBounds(145, 133, 329, 21);
				txtPoblacion.setTextLimit(35);
				// SWTUtils.computeWidth(txtPoblacion);
			}
			{
				lblProvincia = new Label(group1, SWT.NONE);
				lblProvincia.setText("Provincia");
				lblProvincia.setBounds(10, 161, 120, 21);
			}
			{
				txtProvincia = new Text(group1, SWT.BORDER);
				txtProvincia.setBounds(145, 161, 329, 21);
				txtProvincia.setTextLimit(35);
				// SWTUtils.computeWidth(txtProvincia);
			}
			{
				lblCp = new Label(group1, SWT.NONE);
				lblCp.setText("Cp");
				lblCp.setBounds(10, 189, 120, 21);
			}
			{
				txtCp = new Text(group1, SWT.BORDER);
				txtCp.setBounds(145, 189, 329, 21);
				txtCp.setTextLimit(35);
				// SWTUtils.computeWidth(txtCp);
			}
			{
				lblTelefono = new Label(group1, SWT.NONE);
				lblTelefono.setText("Telefono");
				lblTelefono.setBounds(10, 217, 120, 21);
			}
			{
				txtTelefono = new Text(group1, SWT.BORDER);
				txtTelefono.setBounds(145, 217, 329, 21);
				txtTelefono.setTextLimit(35);
				// SWTUtils.computeWidth(txtTelefono);
			}
			{
				lblFax = new Label(group1, SWT.NONE);
				lblFax.setText("Fax");
				lblFax.setBounds(10, 245, 120, 21);
			}
			{
				txtFax = new Text(group1, SWT.BORDER);
				txtFax.setBounds(145, 245, 329, 21);
				txtFax.setTextLimit(35);
				// SWTUtils.computeWidth(txtFax);
			}
			{
				lblActivo = new Label(group1, SWT.NONE);
				lblActivo.setText("Activo");
				lblActivo.setBounds(10, 273, 120, 21);
			}
			{
				botonActivo = new Button(group1, SWT.CHECK | SWT.LEFT);
				botonActivo.setBounds(147, 273, 329, 21);
			}
			group1.setTabList(new org.eclipse.swt.widgets.Control[] {
					txtIdentificador, txtCif, txtNombre, txtDireccion,
					txtPoblacion, txtProvincia, txtCp, txtTelefono, txtFax,
					botonActivo });

			// START >> buttons
			{
				FormData buttonsLData = new FormData();
				buttonsLData.width = 166;
				buttonsLData.height = 33;

				buttonsLData.right = new FormAttachment(100, -10);
				buttonsLData.top = new FormAttachment(100, -33);
				buttons = new ACButtonsComposite(this, SWT.NONE);
				buttons.setLayoutData(buttonsLData);
			}
			this.setTabList(new org.eclipse.swt.widgets.Control[] { group1,
					buttons });
			buttons.getButtonAceptar().setEnabled(false);
			// END << buttons
			this.layout();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Method to display this org.eclipse.swt.widgets.Composite inside a new
	 * Shell.
	 */
	public void open() {
		Shell shell = getShell();
		Display display = getDisplay();
		Composite inst = this;
		Point size = this.getSize();
		shell.setLayout(new FillLayout());
		shell.layout();
		if (size.x == 0 && size.y == 0) {
			inst.pack();
			shell.pack();
		} else {
			Rectangle shellBounds = shell.computeTrim(0, 0, size.x, size.y);
			shell.setSize(shellBounds.width, shellBounds.height);
		}
		SWTUtils.openCentered(inst, shell);
	}

	/**
	 * Metodo que añade a todos los campos de texto un listener para escuchar
	 * los cambios
	 */
	private void addListeners() {

		// Listeners para los campos de texto
		txtIdentificador.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent evt) {
				if (DEBUG) {
					log.debug("Identificador.modifyText, event=" + evt);
				}
				checkModify();
			}
		});
		txtIdentificador.addVerifyListener(new VerifyListener() {
			public void verifyText(VerifyEvent evt) {
				if (DEBUG) {
					log.debug("Identificador.verifyText, event=" + evt); // NON-NLS-1
				}
				evt.doit = SWTUtils.filterInteger(evt.text);
			}
		});
		txtCif.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent evt) {
				if (DEBUG) {
					log.debug("Cif.modifyText, event=" + evt);
				}
				checkModify();
			}
		});
		txtCif.addVerifyListener(new VerifyListener() {
			public void verifyText(VerifyEvent evt) {
				if (DEBUG) {
					log.debug("Cif.verifyText, event=" + evt); // NON-NLS-1
				}
				// TODO: Substituir la linea anterior por la siguiente en el
				// caso de que se trate de un entero.
				// Comprobar que el dato pulsado sea un entero
				// evt.doit = SWTUtils.filterAlphaNumeric(evt.text);
			}
		});
		txtNombre.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent evt) {
				if (DEBUG) {
					log.debug("Nombre.modifyText, event=" + evt);
				}
				checkModify();
			}
		});
		txtNombre.addVerifyListener(new VerifyListener() {
			public void verifyText(VerifyEvent evt) {
				if (DEBUG) {
					log.debug("Nombre.verifyText, event=" + evt); // NON-NLS-1
				}
				// TODO: Substituir la linea anterior por la siguiente en el
				// caso de que se trate de un entero.
				// Comprobar que el dato pulsado sea un entero
				// evt.doit = SWTUtils.filterAlphaNumeric(evt.text);
			}
		});
		txtDireccion.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent evt) {
				if (DEBUG) {
					log.debug("Direccion.modifyText, event=" + evt);
				}
				checkModify();
			}
		});
		txtDireccion.addVerifyListener(new VerifyListener() {
			public void verifyText(VerifyEvent evt) {
				if (DEBUG) {
					log.debug("Direccion.verifyText, event=" + evt); // NON-NLS-1
				}
				// TODO: Substituir la linea anterior por la siguiente en el
				// caso de que se trate de un entero.
				// Comprobar que el dato pulsado sea un entero
				// evt.doit = SWTUtils.filterAlphaNumeric(evt.text);
			}
		});
		txtPoblacion.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent evt) {
				if (DEBUG) {
					log.debug("Poblacion.modifyText, event=" + evt);
				}
				checkModify();
			}
		});
		txtPoblacion.addVerifyListener(new VerifyListener() {
			public void verifyText(VerifyEvent evt) {
				if (DEBUG) {
					log.debug("Poblacion.verifyText, event=" + evt); // NON-NLS-1
				}
				// TODO: Substituir la linea anterior por la siguiente en el
				// caso de que se trate de un entero.
				// Comprobar que el dato pulsado sea un entero
				// evt.doit = SWTUtils.filterAlphaNumeric(evt.text);
			}
		});
		txtProvincia.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent evt) {
				if (DEBUG) {
					log.debug("Provincia.modifyText, event=" + evt);
				}
				checkModify();
			}
		});
		txtProvincia.addVerifyListener(new VerifyListener() {
			public void verifyText(VerifyEvent evt) {
				if (DEBUG) {
					log.debug("Provincia.verifyText, event=" + evt); // NON-NLS-1
				}
				// TODO: Substituir la linea anterior por la siguiente en el
				// caso de que se trate de un entero.
				// Comprobar que el dato pulsado sea un entero
				// evt.doit = SWTUtils.filterAlphaNumeric(evt.text);
			}
		});
		txtCp.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent evt) {
				if (DEBUG) {
					log.debug("Cp.modifyText, event=" + evt);
				}
				checkModify();
			}
		});
		txtCp.addVerifyListener(new VerifyListener() {
			public void verifyText(VerifyEvent evt) {
				if (DEBUG) {
					log.debug("Cp.verifyText, event=" + evt); // NON-NLS-1
				}
				// TODO: Substituir la linea anterior por la siguiente en el
				// caso de que se trate de un entero.
				// Comprobar que el dato pulsado sea un entero
				// evt.doit = SWTUtils.filterAlphaNumeric(evt.text);
			}
		});
		txtTelefono.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent evt) {
				if (DEBUG) {
					log.debug("Telefono.modifyText, event=" + evt);
				}
				checkModify();
			}
		});
		txtTelefono.addVerifyListener(new VerifyListener() {
			public void verifyText(VerifyEvent evt) {
				if (DEBUG) {
					log.debug("Telefono.verifyText, event=" + evt); // NON-NLS-1
				}
				// TODO: Substituir la linea anterior por la siguiente en el
				// caso de que se trate de un entero.
				// Comprobar que el dato pulsado sea un entero
				// evt.doit = SWTUtils.filterAlphaNumeric(evt.text);
			}
		});
		txtFax.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent evt) {
				if (DEBUG) {
					log.debug("Fax.modifyText, event=" + evt);
				}
				checkModify();
			}
		});
		txtFax.addVerifyListener(new VerifyListener() {
			public void verifyText(VerifyEvent evt) {
				if (DEBUG) {
					log.debug("Fax.verifyText, event=" + evt); // NON-NLS-1
				}
				// TODO: Substituir la linea anterior por la siguiente en el
				// caso de que se trate de un entero.
				// Comprobar que el dato pulsado sea un entero
				// evt.doit = SWTUtils.filterAlphaNumeric(evt.text);
			}
		});
		botonActivo.addSelectionListener(new SelectionListener() {

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

			}

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

			}
		});
		// Listeners para los botones
		buttons.getButtonAceptar().addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent evt) {
				populate();
				if (validate()) {
					save();
					getShell().dispose();
				}
			}
		});

		buttons.getButtonCancelar().addSelectionListener(
				new SelectionAdapter() {
					public void widgetSelected(SelectionEvent evt) {
						if (checkModify()) {
							MessageBox msgBox = new MessageBox(getShell(),
									SWT.YES | SWT.NO | SWT.ICON_WARNING);
							msgBox.setText("Confirmación");
							msgBox.setMessage("¿Desea descartar los cambios?");
							int ret = msgBox.open();
							if (ret == SWT.YES) {
								getShell().dispose();
							}
						} else {
							getShell().dispose();
						}

					}
				});
	}

	/**
	 * 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);
		boolean modified = !initialState.equals(currentState)
				&& comprobarObligatorios();
		buttons.getButtonAceptar().setEnabled(modified);
		return modified;
	}

	/**
	 * Valida que los campos obligatorios del formulario han sido informados
	 * 
	 * @return Devuelve true si están informados, false en caso contrario
	 */
	private boolean comprobarObligatorios() {
		if ((GenericValidator.isBlankOrNull(txtIdentificador.getText()))
				|| (GenericValidator.isBlankOrNull(txtNombre.getText()))) {
			return false;
		} else {
			return true;
		}
	}

	/**
	 * Customizar el panel en la creación
	 * 
	 */
	private void customize() {
		// Establecer los controles que sean requeridos
		txtIdentificador.setData(SWTUtils.CONTROL_REQUIRED, Boolean.TRUE);
		txtNombre.setData(SWTUtils.CONTROL_REQUIRED, Boolean.TRUE);
		SWTUtils.customize(this);
	}

	/**
	 * Devuelve el conjunto de botones ACButtonsComposite
	 * 
	 * @return the buttons
	 */
	public ACButtonsComposite getButtons() {
		return buttons;
	}

	/**
	 * Devuelve el grupo de elementos
	 * 
	 * @return the group1
	 */
	public Group getGroup1() {
		return group1;
	}

	/**
	 * Obtener el objeto del contexto
	 * 
	 * @return Object El objeto almacenado en el contexto
	 */
	private Object getFromContext() {
		return manager.getContext().getAttribute(Cliente.class.getName());
	}

	/**
	 * Metodo que obtiene un objeto de tipo bean a partir de los datos del
	 * formulario
	 */
	private void populate() {
		Cliente bean = (Cliente) getFromContext();

		if (esAlta) {
			// TODO: Descomentar la siguiente línea o cambiar el texto
			// propuesto:
			// bean.setId(this.textCodigo.getText().trim().toUpperCase());
		}

		bean.setIdentificador(java.lang.Integer.valueOf(this.txtIdentificador
				.getText().trim()));
		bean.setCif(this.txtCif.getText().trim());
		bean.setNombre(this.txtNombre.getText().trim());
		bean.setDireccion(this.txtDireccion.getText().trim());
		bean.setPoblacion(this.txtPoblacion.getText().trim());
		bean.setProvincia(this.txtProvincia.getText().trim());
		bean.setCp(this.txtCp.getText().trim());
		bean.setTelefono(this.txtTelefono.getText().trim());
		bean.setFax(this.txtFax.getText().trim());
		bean.setActivo(new Boolean(this.botonActivo.getSelection()));
	}

	/**
	 * Metodo que refresca los datos del formulario a partir de un objeto de
	 * tipo Cliente
	 */
	private void refresh() {
		if (!esAlta) {
			Cliente bean = (Cliente) getFromContext();
			// TODO: Descomentar la siguiente línea o cambiar el texto
			// propuesto:
			txtIdentificador.setText(String.valueOf(bean.getIdentificador()));
			txtCif.setText(bean.getCif());
			txtNombre.setText(bean.getNombre());
			txtDireccion.setText(bean.getDireccion());
			txtPoblacion.setText(bean.getPoblacion());
			txtProvincia.setText(bean.getProvincia());
			txtCp.setText(bean.getCp());
			txtTelefono.setText(bean.getTelefono());
			txtFax.setText(bean.getFax());
			botonActivo.setSelection(bean.getActivo().booleanValue());
		} else {
			// Si es alta se debe de calcular el número de cliente
			// automáticamente
			txtIdentificador.setText(delegate.getNextId().toString());
		}

	}

	/**
	 * Metodo que salva un bean en BBDD
	 */
	private void save() {
		Cliente bean = (Cliente) getFromContext();
		if (esAlta) {
			log.info("Estamos haciendo una alta ");
			delegate.create(bean);
		} else {
			log.info("Estamos haciendo una modificación");
			delegate.update(bean);
		}
	}

	/**
	 * Metodo que valida los campos del formulario. Devuelve true si todo esta
	 * OK, en caso contrario devuelve false
	 * 
	 * @return True si la validación es correcta, false en caso contrario
	 */
	private boolean validate() {

		List result = null;

		// Validaciones del formulario
		Cliente bean = (Cliente) getFromContext();
		result = manager.validate(bean);

		// Mostrar mensaje si procede
		if (!result.isEmpty()) {
			SWTUtils.showValidatonErrors(getShell(), manager
					.constructValidationString(result));
		} else {
			// Validaciones de lógica
			if ((esAlta) && delegate.exists(bean)) {
				result.add("ClienteEditComposite.exists");
				SWTUtils.showValidatonErrors(getShell(), manager
						.constructValidationString(result));
			}
		}
		return result.isEmpty();
	}
}