/*
 * Copyright (c) 2006-2008 Maskat Project.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Maskat Project - initial API and implementation
 */
package org.maskat.ui.views.properties.tabbed.masterdetails;

import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.forms.widgets.TableWrapData;
import org.eclipse.ui.forms.widgets.TableWrapLayout;

import org.maskat.core.event.Source;
import org.maskat.ui.Messages;
import org.maskat.ui.views.properties.tabbed.beanwrapper.Validation;

public class ValidationDetailsPage extends AbstractMaskatDetailsPage {

	private static final String SECTION_TEXT = Messages
			.getString("validationDetails.sectionText"); //$NON-NLS-1$

	private static final String SECTION_DESCRIPTION = Messages
			.getString("validationDetails.description"); //$NON-NLS-1$

	private String[] validationComboValues = { "disabled", "byte", "short",
			"int", "long", "float", "string", "date", "time", "url", "required" };

	private Combo validationCombo;

	private Source sourceBean;

	private Text minLengthText;

	private Text maxLengthText;

	private Text regExpText;

	private Text errorMessageText;

	protected int originialStateMaxLength = -1;

	protected int originialStateMinLength = -1;

	public ValidationDetailsPage(TreeViewer masterBlockTreeViewer) {
		this.masterBlockTreeViewer = masterBlockTreeViewer;
	}
	
	public void createContents(Composite parent) {
		TableWrapLayout layout = new TableWrapLayout();
		layout.topMargin = 0;
		layout.leftMargin = 5;
		layout.rightMargin = 5;
		layout.bottomMargin = 5;
		parent.setLayout(layout);

		FormToolkit toolkit = managedForm.getToolkit();

		Section validationSection = toolkit.createSection(parent,
				ExpandableComposite.TITLE_BAR | Section.DESCRIPTION);
		validationSection.setText(SECTION_TEXT);
		validationSection.setDescription(SECTION_DESCRIPTION);
		TableWrapData tableWrapData = new TableWrapData(TableWrapData.FILL,
				TableWrapData.TOP);
		tableWrapData.grabHorizontal = true;
		validationSection.setLayoutData(tableWrapData);

		Composite validationComposite = toolkit
				.createComposite(validationSection);
		validationComposite.setLayout(new GridLayout(3, false));

		toolkit.createLabel(validationComposite, Messages
				.getString("validationDetails.selectTypeLabel")); //$NON-NLS-1$
		toolkit.createLabel(validationComposite, ":");
		validationCombo = new Combo(validationComposite, SWT.DROP_DOWN
				| SWT.READ_ONLY);
		validationCombo.setVisibleItemCount(15);
		for (int i = 0; i < validationComboValues.length; i++) {
			validationCombo.add(validationComboValues[i]);
		}

		toolkit.createLabel(validationComposite, Messages
				.getString("validationDetails.minLengthLabel")); //$NON-NLS-1$
		toolkit.createLabel(validationComposite, ":");
		minLengthText = toolkit.createText(validationComposite, "", SWT.SINGLE
				| SWT.BORDER);
		minLengthText.setForeground(null);
		minLengthText.setLayoutData(new GridData(SWT.FILL, 0, true, false));

		toolkit.createLabel(validationComposite, Messages
				.getString("validationDetails.maxLengthLabel")); //$NON-NLS-1$
		toolkit.createLabel(validationComposite, ":");
		maxLengthText = toolkit.createText(validationComposite, "", SWT.SINGLE
				| SWT.BORDER);
		maxLengthText.setForeground(null);
		maxLengthText.setLayoutData(new GridData(SWT.FILL, 0, true, false));

		toolkit.createLabel(validationComposite, Messages
				.getString("validationDetails.ReqularExpressionLabel")); //$NON-NLS-1$
		toolkit.createLabel(validationComposite, ":");
		regExpText = toolkit.createText(validationComposite, "", SWT.SINGLE
				| SWT.BORDER);
		regExpText.setForeground(null);
		regExpText.setLayoutData(new GridData(SWT.FILL, 0, true, false));

		toolkit.createLabel(validationComposite, Messages
				.getString("validationDetails.ErrMsgLabel")); //$NON-NLS-1$
		toolkit.createLabel(validationComposite, ":");
		errorMessageText = toolkit.createText(validationComposite, "",
				SWT.SINGLE | SWT.BORDER);
		errorMessageText.setForeground(null);
		errorMessageText.setLayoutData(new GridData(SWT.FILL, 0, true, false));

		validationCombo.addSelectionListener(new SelectionAdapter() {

			public void widgetSelected(SelectionEvent e) {
				updateNewSelection(validationCombo.getSelectionIndex());
				super.widgetSelected(e);
			}
		});

		validationCombo.addFocusListener(new FocusAdapter() {

			private String newStateValidationType;

			private String originalStateValitationType;

			public void focusGained(FocusEvent e) {
				originalStateValitationType = validationCombo.getText();
			}

			public void focusLost(FocusEvent e) {
				newStateValidationType = validationCombo.getText();
				if (!(newStateValidationType
						.equals(originalStateValitationType))) {
					if (!(newStateValidationType.equals("disabled"))) {
						EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
								Validation.class, sourceBean, "type",
								newStateValidationType);

						if (newStateValidationType.equals("byte")
								|| newStateValidationType.equals("short")
								|| newStateValidationType.equals("int")
								|| newStateValidationType.equals("long")
								|| newStateValidationType.equals("float")
								|| newStateValidationType.equals("url")) {
							EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
									Validation.class, sourceBean, "regexp",
									null);
						} else if (newStateValidationType.equals("date")
								|| newStateValidationType.equals("time")) {
							EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
									Validation.class, sourceBean, "min", "-1");
							EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
									Validation.class, sourceBean, "max", "-1");
							EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
									Validation.class, sourceBean, "regexp",
									null);
						} else if (newStateValidationType.equals("required")) {
							EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
									Validation.class, sourceBean, "min", "-1");
							EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
									Validation.class, sourceBean, "max", "-1");
							EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
									Validation.class, sourceBean, "regexp",
									null);
							EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
									Validation.class, sourceBean, "desc", null);
						}
					} else {
						EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
								Validation.class, sourceBean, "type", null);
						EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
								Validation.class, sourceBean, "min", "-1");
						EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
								Validation.class, sourceBean, "max", "-1");
						EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
								Validation.class, sourceBean, "regexp", null);
						EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
								Validation.class, sourceBean, "desc", null);
					}
				}
			}
		});

		minLengthText.addKeyListener(new KeyAdapter() {

			public void keyReleased(KeyEvent e) {
				if (sourceBean.getMin() != getTextValueAsIntValue(
						minLengthText, originialStateMinLength)) {
					EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
							Validation.class, sourceBean, "min", new Integer(
									getTextValueAsIntValue(minLengthText,
											originialStateMinLength))
									.toString());
				}
			}
		});

		minLengthText.addListener(SWT.Verify, new VerifyIntegerListener());
		minLengthText.addFocusListener(new FocusAdapter() {

			public void focusGained(FocusEvent e) {
				originialStateMinLength = sourceBean.getMin();
			}

			public void focusLost(FocusEvent e) {

				if (!minLengthText.getText().equals("")) {
					if (sourceBean.getMin() != getTextValueAsIntValue(
							minLengthText, originialStateMinLength)) {
						EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
								Validation.class, sourceBean, "min",
								minLengthText.getText());
					}
					minLengthText
							.setText(new Integer(getTextValueAsIntValue(
									minLengthText, originialStateMinLength))
									.toString());
				} else if (sourceBean.getMin() != -1) {
					EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
							Validation.class, sourceBean, "min", "-1");
				}
			}
		});
		
		maxLengthText.addKeyListener(new KeyAdapter() {

			public void keyReleased(KeyEvent e) {
				if (sourceBean.getMax() != getTextValueAsIntValue(
						maxLengthText, originialStateMaxLength)) {
					EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
							Validation.class, sourceBean, "max", new Integer(
									getTextValueAsIntValue(maxLengthText,
											originialStateMaxLength))
									.toString());
				}
			}
		});

		maxLengthText.addListener(SWT.Verify, new VerifyIntegerListener());
		maxLengthText.addFocusListener(new FocusAdapter() {

			public void focusGained(FocusEvent e) {
				originialStateMaxLength = sourceBean.getMax();
			}

			public void focusLost(FocusEvent e) {

				if (!maxLengthText.getText().equals("")) {
					if (sourceBean.getMax() != getTextValueAsIntValue(
							maxLengthText, originialStateMaxLength)) {
						EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
								Validation.class, sourceBean, "max",
								maxLengthText.getText());
					}
					maxLengthText
							.setText(new Integer(getTextValueAsIntValue(
									maxLengthText, originialStateMaxLength))
									.toString());
				} else if (sourceBean.getMax() != -1) {
					EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
							Validation.class, sourceBean, "max", "-1");
				}
			}
		});

		regExpText.addKeyListener(new KeyAdapter() {
			public void keyReleased(KeyEvent e) {
				EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
						Validation.class, sourceBean, "regexp", regExpText
								.getText());
			}
		});
		regExpText.addFocusListener(new FocusAdapter() {
			public void focusLost(FocusEvent e) {
				if (sourceBean.getRegexp() == null
						|| !sourceBean.getRegexp().equals(regExpText.getText())) {
					EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
							Validation.class, sourceBean, "regexp", regExpText
									.getText());
				}
			}
		});

		errorMessageText.addKeyListener(new KeyAdapter() {
			public void keyReleased(KeyEvent e) {
				EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
						Validation.class, sourceBean, "desc",
						errorMessageText.getText());
			}
		});
		errorMessageText.addFocusListener(new FocusAdapter() {

			public void focusLost(FocusEvent e) {
				if (sourceBean.getDesc() == null
						|| !sourceBean.getDesc().equals(
								errorMessageText.getText())) {
					EventPropertiesMasterDetailsBlock.setEventProperty(masterBlockTreeViewer,
							Validation.class, sourceBean, "desc",
							errorMessageText.getText());
				}
			}
		});
		/*
		 * 
		 * errorMessageText
		 */

		validationSection.setClient(validationComposite);
	}

	public int getTextValueAsString(Text textField) {
		int returnValue = -1;
		if (textField == minLengthText) {
			returnValue = originialStateMinLength;
		} else {
			returnValue = originialStateMaxLength;
		}

		try {
			returnValue = new Integer(textField.getText()).intValue();
		} catch (NumberFormatException e) {

		}

		return returnValue;
	}

	// private void updateSourceBean(int selectionIndex) {
	/*
	 * String validationType = validationCombo.getText();
	 * 
	 * if (!(validationType.equals("disabled"))) {
	 * sourceBean.setType(validationType); } else { sourceBean.setType(null); }
	 */
	// updateNewSelection();
	// }
	private void updateNewSelection(int selectionIndex) {
		String validationType = validationComboValues[selectionIndex];
		int minLength = sourceBean.getMin();
		int maxLength = sourceBean.getMax();
		String regExp = sourceBean.getRegexp();
		String errorMsg = sourceBean.getDesc();

		minLengthText.setText("");
		maxLengthText.setText("");
		errorMessageText.setText("");
		regExpText.setText("");

		minLengthText.setEnabled(false);
		maxLengthText.setEnabled(false);
		errorMessageText.setEnabled(false);
		regExpText.setEnabled(false);

		if (validationType != null && !validationType.equals("")) {
			for (int i = 0; i < validationComboValues.length; i++) {
				if (validationComboValues[i].equals(validationType)) {
					validationCombo.select(i);
				}
			}

			if (!(validationType.equals("required"))
					&& !(validationType.equals("disabled"))) {
				errorMessageText.setEnabled(true);
				if (errorMsg != null) {
					errorMessageText.setText(errorMsg);
				}

				if (validationType.equals("byte")
						|| validationType.equals("short")
						|| validationType.equals("int")
						|| validationType.equals("long")
						|| validationType.equals("float")
						|| validationType.equals("string")
						|| validationType.equals("url")) {
					minLengthText.setEnabled(true);
					maxLengthText.setEnabled(true);
					errorMessageText.setEnabled(true);

					// TODO update and use source std values!
					if (minLength != Source.MIN_DEFAULT) {
						minLengthText.setText(((new Integer(minLength))
								.toString()));
					}
					if (maxLength != Source.MAX_DEFAULT) {
						maxLengthText.setText(((new Integer(maxLength))
								.toString()));
					}
					if (errorMsg != null) {
						errorMessageText.setText(errorMsg);
					}
				}
				if (validationType.equals("string")) {
					regExpText.setEnabled(true);
					if (regExp != null) {
						regExpText.setText(regExp);
					}
				}
			}
		} else {
			validationCombo.select(0);
			validationCombo.setFocus();
		}

		setDirtyFlag(false);

	}

	protected void update() {
		String validationType = sourceBean.getType();
		int minLength = sourceBean.getMin();
		int maxLength = sourceBean.getMax();
		String regExp = sourceBean.getRegexp();
		String errorMsg = sourceBean.getDesc();

		minLengthText.setEnabled(false);
		maxLengthText.setEnabled(false);
		errorMessageText.setEnabled(false);
		regExpText.setEnabled(false);

		if (validationType != null && !validationType.equals("")) {
			for (int i = 0; i < validationComboValues.length; i++) {
				if (validationComboValues[i].equals(validationType)) {
					validationCombo.select(i);
				}
			}

			if (!(validationType.equals("required"))) {
				errorMessageText.setEnabled(true);
				if (errorMsg != null) {
					errorMessageText.setText(errorMsg);
				}

				if (validationType.equals("byte")
						|| validationType.equals("short")
						|| validationType.equals("int")
						|| validationType.equals("long")
						|| validationType.equals("float")
						|| validationType.equals("string")
						|| validationType.equals("url")) {
					minLengthText.setEnabled(true);
					maxLengthText.setEnabled(true);
					errorMessageText.setEnabled(true);

					if (minLength != Source.MIN_DEFAULT) {
						minLengthText.setText(((new Integer(minLength))
								.toString()));
					}
					if (maxLength != Source.MAX_DEFAULT) {
						maxLengthText.setText(((new Integer(maxLength))
								.toString()));
					}
					if (errorMsg != null) {
						errorMessageText.setText(errorMsg);
					}
				}
				if (validationType.equals("string")) {
					regExpText.setEnabled(true);
					if (regExp != null) {
						regExpText.setText(regExp);
					}
				}
			}
		} else {
			validationCombo.select(0);
			validationCombo.setFocus();
		}

		setDirtyFlag(false);
	}

	public void setSource(Source source) {
		this.sourceBean = source;
	}

	protected void initializeInterface() {
		minLengthText.setText("");
		maxLengthText.setText("");
		errorMessageText.setText("");
		regExpText.setText("");
		update();
		setStaleFlag(false);
	}
}
