//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 IBM Corporation and others.
// 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:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library.ui.dialogs;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.epf.library.edit.command.UserInput;
import org.eclipse.epf.library.edit.validation.IValidator;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
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.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

/**
 * This dialog acts as a input dialog during command execution based on user
 * input and inputType dialog behaviour changes.
 * 
 * @author Shashidhar Kannoori
 * @author Shilpa Toraskar
 * @since 1.2
 * 
 */
public class UserInputsDialog extends Dialog {

	IStructuredContentProvider contentProvider;

	ILabelProvider labelProvider;

	private String title;

	private String globalErrorTxt = "";
	
	private String message;

	private List userInputs;

	private boolean result = false;

	Label messageArea;

	Label errorArea;

	HashMap<Object,Object> oldInfoForCancel;
	
	private Color redColor;
	
	public UserInputsDialog(Shell parentShell, List userInputs, String title,
			String message) {
		super(parentShell);
		this.title = title;
		this.message = message;
		this.userInputs = userInputs;
		oldInfoForCancel = new HashMap<Object,Object>();
	}

	/**
	 * 
	 * @param title
	 */
	public void setTitle(String title) {
		this.title = title;
	}

	/**
	 * 
	 * @param msg
	 */
	public void setMessage(String message) {
		this.message = message;
	}

	/**
	 * Create a Tree Viewer.
	 * 
	 */
	protected void createTreeViewer(Composite parent, UserInput userInput) {
		TreeViewer viewer;
		if (!userInput.isMultiple()) {
			viewer = new TreeViewer(parent, SWT.SINGLE | SWT.H_SCROLL
					| SWT.V_SCROLL | SWT.BORDER);
		} else {
			viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL
					| SWT.V_SCROLL | SWT.BORDER);
		}

		GridData spec = new GridData(GridData.FILL_BOTH);
		{
			spec.widthHint = 200;
			spec.heightHint = 200;
			spec.horizontalSpan = 3;
			viewer.getControl().setLayoutData(spec);
		}
		viewer.addSelectionChangedListener(new ISelectionChangedListener() {

			public void selectionChanged(SelectionChangedEvent event) {
				
			}

		});

		if (viewer != null) {
			viewer.setLabelProvider(labelProvider);
			if (contentProvider != null) {
				viewer.setContentProvider(contentProvider);
			} else {
				viewer.setContentProvider(new ArrayContentProvider());
			}
			viewer.setUseHashlookup(true);

			viewer.setInput(userInput.getChoices());
			viewer.getControl().setFont(parent.getFont());
			// TODO: treeViewer Sorter and Expand/Collapse
		}
	}

	/**
	 * Creates a TableViewer
	 * 
	 */
	protected void createTableViewer(Composite parent, UserInput userInput) {
		TableViewer viewer = new TableViewer(parent);
		viewer.addSelectionChangedListener(new ISelectionChangedListener() {

			public void selectionChanged(SelectionChangedEvent event) {
				
			}
		});
	}

	/**
	 * Creates a Text control
	 * 
	 * @param parent
	 * @param userInput
	 */
	protected void createText(Composite parent, UserInput userInput) {
		final UserInput localinput = userInput;
		final IValidator validator = userInput.getValidator();
		final Text text = new Text(parent, SWT.SINGLE | SWT.BORDER);
		text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		text.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				getButton(OK).setEnabled(true);
				errorArea.setText("");
			}
		});

		text.addFocusListener(new FocusAdapter() {
			public void focusLost(FocusEvent e) {
				String errorTxt = "";
				if (validator != null) {
					errorTxt = validator.isValid(text.getText());
					if (errorTxt != null && errorTxt.length() > 0) {
						errorArea.setText(errorTxt);
						getButton(OK).setEnabled(false);					
					} else {
						errorArea.setText("");
					}
					globalErrorTxt = errorTxt;
				}
				if (errorTxt == null || errorTxt.length() <= 0) {
					localinput.setInput(text.getText());
				}
			}
		});
		if (userInput.getInput() != null) {
			text.setText((String) userInput.getInput());
		}
	}

	/**
	 * Method to setInput, subclass can override it.
	 * 
	 */
	protected void setInput(UserInput input, Object obj) {
		input.setInput(obj);
	}

	/**
	 * Creates a Comboviewer.
	 * 
	 * @param composite
	 * @param userInput
	 */
	protected void createComboViewer(Composite composite, UserInput userInput) {
		final UserInput localInput = userInput;
		final IValidator validator = userInput.getValidator();
		final ComboViewer viewer = new ComboViewer(composite);
		viewer.getCombo().setLayoutData(
				new GridData(SWT.FILL, SWT.FILL, true, true));
		viewer.setContentProvider(new ArrayContentProvider());
		if (userInput.getLabelProvider() != null) {
			viewer.setLabelProvider(userInput.getLabelProvider());
		}
		List choices = userInput.getChoices();
		viewer.setInput(choices);
		if (choices != null && choices.size() > 0) {
			viewer.setSelection(new StructuredSelection(choices.get(0)));
			localInput.setInput(choices.get(0));
		}
		viewer.getCombo().addFocusListener(new FocusAdapter() {
			public void focusLost(FocusEvent e) {
				String errorTxt = "";
				IStructuredSelection selected = (IStructuredSelection) viewer
						.getSelection();
				IStatus status = validator.isValid(selected.getFirstElement());
				if (status.getSeverity() == IStatus.ERROR) {
					errorTxt = status.getMessage();
				}
				if (errorTxt != null && errorTxt.length() > 0) {
					errorArea.setText(errorTxt);
					getButton(OK).setEnabled(false);
				} if (globalErrorTxt != null && globalErrorTxt.length() > 0) {
					errorArea.setText(globalErrorTxt);
					getButton(OK).setEnabled(false);
				}
				else
					errorArea.setText("");
			}
		});
		viewer.addSelectionChangedListener(new ISelectionChangedListener() {

			public void selectionChanged(SelectionChangedEvent event) {
				getButton(OK).setEnabled(true);
				errorArea.setText("");

				IStructuredSelection selection = (IStructuredSelection) event
						.getSelection();
				Object obj = selection.getFirstElement();
				String errorTxt = "";
				if (validator != null) {
					IStatus status = validator.isValid(obj);
					if (status.getCode() == IStatus.ERROR) {
						errorTxt = status.getMessage();
					}
					if (errorTxt != null && errorTxt.length() > 0) {
						errorArea.setText(errorTxt);
					}
					else if (globalErrorTxt != null && globalErrorTxt.length() > 0) {
						errorArea.setText(globalErrorTxt);
						getButton(OK).setEnabled(false);
					}
					else
						errorArea.setText("");
				}
				if (errorTxt == null || errorTxt.length() <= 0) {
					localInput.setInput(obj);
				}
			}
		});	
	}

	/**
	 * Create a Label and Text for message area.
	 * 
	 * @param composite
	 * @return
	 */
	protected Label createMessageArea(Composite composite) {
		messageArea = new Label(composite, SWT.WRAP);
		if (message != null) {
			messageArea.setText(message);
		}
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		gd.horizontalSpan = 2;
		gd.heightHint = 25;
		gd.minimumWidth = 400;
		messageArea.setLayoutData(gd);
		applyDialogFont(messageArea);
		Label separator = new Label(composite, SWT.HORIZONTAL | SWT.SEPARATOR);
		GridData gd1 = new GridData(GridData.FILL_HORIZONTAL);
		gd1.horizontalSpan = 2;
		separator.setLayoutData(gd1);
		return messageArea;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
	 */
	protected Control createDialogArea(Composite parent) {
		Composite composite = (Composite) super.createDialogArea(parent);
		composite.setFont(parent.getFont());

		GridLayout layout = (GridLayout) composite.getLayout();
		layout.marginWidth = 10;
		layout.marginHeight = 10;
		layout.numColumns = 2;

		createMessageArea(composite);

		// Create controls based on UserInputs
		if (userInputs != null && userInputs.size() > 0) {
			for (Iterator iterator = userInputs.iterator(); iterator.hasNext();) {
				Object object = iterator.next();
				if (object instanceof UserInput) {
					UserInput userInput = (UserInput) object;

					// Store the userInput in the hashmap for cancel action.
					oldInfoForCancel.put(userInput, userInput.getInput());

					Label label = new Label(composite, SWT.NONE);
					label.setText(userInput.getLabel());
					GridData gridData = new GridData(GridData.BEGINNING);
					label.setLayoutData(gridData);

					if (userInput.getType() == UserInput.TEXT) {
						createText(composite, userInput);
					} else if (userInput.getType() == UserInput.SELECTION) {
						createComboViewer(composite, userInput);
					}
					// createEmptyLabel(composite, 2);
				}
			}
		}
		createErrorArea(composite);
		return composite;
	}

	/**
	 * Creates a Error Area.
	 * 
	 * @param composite
	 */
	private void createErrorArea(Composite composite) {
		// create blank label
		new Label(composite, SWT.WRAP);

		errorArea = new Label(composite, SWT.WRAP);
		redColor = new Color(null, new RGB(255, 0, 0));
		if(redColor != null){
			errorArea.setForeground(redColor);
		}
		// if(errorTxt != null && errorTxt.length() >0){
		// errorArea.setText(errorTxt);
		// }
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		gd.horizontalSpan = 2;
		gd.heightHint = 25;
		errorArea.setLayoutData(gd);
		applyDialogFont(errorArea);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
	 */
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		if (this.title != null) {
			newShell.setText(this.title);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.dialogs.Dialog#okPressed()
	 */
	protected void okPressed() {
		result = true;		
		super.okPressed();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.dialogs.Dialog#cancelPressed()
	 */
	protected void cancelPressed() {
		if (userInputs != null && userInputs.size() > 0) {
			for (Iterator iterator = userInputs.iterator(); iterator.hasNext();) {
				Object object = iterator.next();
				if (object instanceof UserInput) {
					UserInput userInput = (UserInput) object;
					userInput.setInput(oldInfoForCancel.get(userInput));
				}
			}
		}
		super.cancelPressed();
	}

	/**
	 * Returns the results.
	 * 
	 * @return
	 */
	public boolean getResult() {
		return result;
	}

	@Override
	public boolean close() {
		if(redColor != null){
			redColor.dispose();
		}
		return super.close();
	}
	/**
	 * Create a empty label.
	 * 
	 * @param composite
	 * @param span
	 */
	// private void createEmptyLabel(Composite composite, int span){
	// Label emptyLabel = new Label(composite, SWT.NONE);
	// emptyLabel.setBackground(Colors.INHERITED_ELEMENT_LABEL);
	// GridData emptyData = new GridData(GridData.FILL_HORIZONTAL);
	// emptyLabel.setText("");
	// emptyData = new GridData(GridData.FILL_HORIZONTAL);
	// emptyData.horizontalSpan =span;
	// emptyData.heightHint = 3;
	// emptyLabel.setLayoutData(emptyData);
	// }
	/**
	 * validates the input with given Validator in UserInput.
	 */
	// private boolean validate() {
	// for (Iterator iter = userInputs.iterator(); iter.hasNext();) {
	// UserInput element = (UserInput) iter.next();
	// IValidator validator = element.getValidator();
	// if (validator != null) {
	// if (element.getType() == UserInput.TEXT) {
	// errorTxt += validator
	// .isValid(element.getInput().toString());
	// } else {
	// errorTxt += validator.isValid(element.getInput());
	// }
	// }
	// }
	// errorTxt = "System out testing";
	// if (errorTxt != null && errorTxt.length() > 0) {
	// errorArea.setText(errorTxt);
	// errorArea.setForeground(ColorConstants.red);
	// return false;
	// }
	// return true;
	// }
}
