/*******************************************************************************
 * Copyright (c) 2004, 2005 Sybase, Inc. 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: Sybase,
 * Inc. - initial API and implementation
 ******************************************************************************/

package org.eclipse.jst.jsf.facesconfig.ui.wizard;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.jst.jsf.common.ui.internal.guiutils.SWTUtils;
import org.eclipse.jst.jsf.facesconfig.ui.EditorPlugin;
import org.eclipse.jst.jsf.facesconfig.ui.IFacesConfigConstants;
import org.eclipse.jst.jsf.facesconfig.ui.util.JavaClassUtils;
import org.eclipse.jst.jsf.facesconfig.ui.util.ManagedBeanUtil;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
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.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

/**
 * ManangedBeanProperty wizard page used to show properties of the previous
 * selected java class, suade services. and set the default values for each
 * property.
 * 
 * @author Xiao-guang Zhang, sfshi
 */
public class ManagedBeanPropertyPage extends WizardPage implements ISummaryDataSource {
	/** Default height of description Text Control */
	private static final int DESCRIPTION_TEXT_HEIGHT = 60;

	private static final int DEFAULT_WIDTHHINT = 10;

	/** The Text control for managed bean instance name */
	private Text managedBeanNameText;

	/** The Combo control for Project Selection */
	private Combo scopeCombo;

	/** The Text control for managed bean's description */
	private Text managedBeanDescriptionText;

	private String helpID = null;

	private IProject currentProject;

	private String defaultScope;

	/**
	 * @param defaultScope
	 *            the default scope, if be null, then use "session".
	 * @param project
	 */
	public ManagedBeanPropertyPage(String defaultScope, IProject project) {
		super("ManagedBeanPropertyWizardPage"); //$NON-NLS-1$);

		this.defaultScope = defaultScope;
		currentProject = project;
		setTitle(WizardMessages.ManagedBeanPropertyWizardPage_Title);
		setDescription(WizardMessages.ManagedBeanPropertyWizardPage_Description);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see WizardPage#createControl(Composite)
	 */
	public void createControl(Composite parent) {
		initializeDialogUnits(parent);

		Composite container = new Composite(parent, SWT.NONE);
		GridLayout gl = new GridLayout();
		gl.numColumns = 1;
		container.setLayout(gl);
		GridData gridData = new GridData(GridData.FILL_BOTH);
		container.setLayoutData(gridData);

		createGeneralSection(container);

		setControl(container);

		setPageComplete(false);

		if (helpID != null) {
			EditorPlugin.getDefault().getWorkbench().getHelpSystem().setHelp(
					getControl(), helpID);
		}
	}

	/**
	 * create managed bean 's configuration group
	 * 
	 * @param container
	 */
	private void createGeneralSection(Composite container) {
		Group generalSection = new Group(container, SWT.NONE);

		// ManagedBeanPropertyWizardPage.General = General
		generalSection
				.setText(WizardMessages.ManagedBeanPropertyWizardPage_General);

		GridLayout gl = new GridLayout();
		// gl.marginHeight = 20;
		gl.numColumns = 2;
		generalSection.setLayout(gl);
		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
		generalSection.setLayoutData(gridData);

		SWTUtils
				.createLabel(
						generalSection,
						WizardMessages.ManagedBeanPropertyWizardPage_ManagedBeanName,
						1);

		managedBeanNameText = SWTUtils.createTextBox(generalSection, 1);
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		gd.horizontalSpan = 1;
		gd.widthHint = DEFAULT_WIDTHHINT;
		managedBeanNameText.setLayoutData(gd);

		managedBeanNameText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				// dialogChanged();
				if (isValidManagedBeanName(true)) {
					setPageComplete(true);
				} else {
					setPageComplete(false);
				}
			}
		});

		SWTUtils
				.createLabel(
						generalSection,
						WizardMessages.ManagedBeanPropertyWizardPage_ManagedBeanScope,
						1); //$NON-NLS-1$

		String[] items = {
				IFacesConfigConstants.MANAGED_BEAN_SCOPE_APPLICATION,
				IFacesConfigConstants.MANAGED_BEAN_SCOPE_SESSION,
				IFacesConfigConstants.MANAGED_BEAN_SCOPE_REQUEST,
				IFacesConfigConstants.MANAGED_BEAN_SCOPE_NONE };

		scopeCombo = SWTUtils.createCombo(generalSection, items, 1);
		gd = new GridData(GridData.FILL_HORIZONTAL);
		gd.horizontalSpan = 1;
		gd.widthHint = DEFAULT_WIDTHHINT;
		scopeCombo.setLayoutData(gd);

		Label labelDesp = SWTUtils
				.createLabel(
						generalSection,
						WizardMessages.ManagedBeanPropertyWizardPage_ManagedBeanDescription,
						1); //$NON-NLS-1$

		gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
		labelDesp.setLayoutData(gd);

		managedBeanDescriptionText = SWTUtils.createTextBoxScrollable(
				generalSection, 1, -1, DESCRIPTION_TEXT_HEIGHT);

	}

	/**
	 * Validates the managed bean Name entry
	 * 
	 * @param reportError -
	 *            true, to report errors.
	 * @return boolean - the valid state of the data entered
	 */
	private boolean isValidManagedBeanName(boolean reportError) {
		if (managedBeanNameText.getText().length() == 0) {
			if (reportError) {
				setErrorMessage(WizardMessages.ManagedBeanPropertyWizardPage_Warning_MissingManagedBeanName); //$NON-NLS-1$
			}
			return false;
		} else if (JavaClassUtils.hasIllegalCharacters(managedBeanNameText
				.getText())) {
			if (reportError) {
				setErrorMessage(WizardMessages.ManagedBeanPropertyWizardPage_Warning_InvalidManagedBeanName); //$NON-NLS-1$
			}
			return false;
		} else {
			if (ManagedBeanUtil.isBeanDuplicate(currentProject,
					managedBeanNameText.getText())) {
				if (reportError) {
					setErrorMessage(WizardMessages.ManagedBeanPropertyWizardPage_Warning_DuplicateManagedBeanName);
				}
				return false;
			}

		}

		setErrorMessage(null);
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.wizard.IWizardPage#setPreviousPage(org.eclipse.jface.wizard.IWizardPage)
	 */
	public void setPreviousPage(IWizardPage page) {
		super.setPreviousPage(page);
		initialize();
	}

	private void initialize() {
		if (defaultScope != null && defaultScope.length() > 0)
			scopeCombo.setText(defaultScope);
		else
			scopeCombo.setText("session");

		if (((NewManagedBeanWizard) getWizard()).getSuggestedBeanName() != null) {
			this.managedBeanNameText
					.setText(((NewManagedBeanWizard) getWizard())
							.getSuggestedBeanName());
		} else {
			String beanName;
			if (this.getPreviousPage() instanceof ManagedBeanClassSelectionPage) {
				beanName = ((ManagedBeanClassSelectionPage) this.getPreviousPage())
						.getClassName();
			} else {
				beanName = ((NewJavaClassPage) this.getPreviousPage())
						.getTypeName();
			}
			beanName = beanName.substring(beanName.lastIndexOf(".") + 1);
			if (beanName != null && beanName.length() > 0) {
				beanName = (beanName.substring(0, 1)).toLowerCase()
						+ (beanName.substring(1));

				beanName = ManagedBeanUtil.getDefaultManagedBeanName(
						currentProject, beanName);

			} else
				beanName = "";
			managedBeanNameText.setText(beanName);
		}
	}

	/**
	 * Returns key-value summary data.
	 * 
	 * @return List - Summary data.
	 */
	public List getSummaryData() {
		List data = new ArrayList();

		data
				.add(new String[] {
						WizardMessages.NewJavaManagedBeanWizard_Summary_ManagedBeanName,
						getManagedBeanName() }); //$NON-NLS-1$
		data
				.add(new String[] {
						WizardMessages.NewJavaManagedBeanWizard_Summary_ManagedBeanScope,
						getManagedBeanScope() });
		data.add(new String[] {
				WizardMessages.NewJavaManagedBeanWizard_Summary_ClassName,
				getManagedBeanClass() });

		data
				.add(new String[] {
						WizardMessages.NewJavaManagedBeanWizard_Summary_Description,
						getManagedBeanDescription() });
		return data;
	}

	/**
	 * @return the name of the managed bean
	 */
	public String getManagedBeanName() {
		return this.managedBeanNameText.getText().trim();
	}

	/**
	 * @return the managed bean class name
	 */
	public String getManagedBeanClass() {
		if (this.getPreviousPage() instanceof ManagedBeanClassSelectionPage) {
			return ((ManagedBeanClassSelectionPage) this.getPreviousPage()).getClassName();
		} else if (this.getPreviousPage() instanceof NewJavaClassPage) {
			NewJavaClassPage newJavaClassPage = (NewJavaClassPage) this.getPreviousPage();
			StringBuffer buffer = new StringBuffer();
			if (newJavaClassPage.getPackageText() != null
					&& newJavaClassPage.getPackageText().length() > 0) {
				buffer.append(newJavaClassPage.getPackageText());
				buffer.append("."); //$NON-NLS-1$
			}
			buffer.append(newJavaClassPage.getTypeName());
			return buffer.toString();
		}

		return "";//$NON-NLS-1$
	}

	/**
	 * @return the managed bean scope
	 */
	public String getManagedBeanScope() {
		return this.scopeCombo.getText().trim();
	}

	/**
	 * @return the managed bean description
	 */
	public String getManagedBeanDescription() {
		return this.managedBeanDescriptionText.getText().trim();
	}
}