/*******************************************************************************
 * 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();
	}

	protected 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;
	}

	public String getManagedBeanName() {
		return this.managedBeanNameText.getText().trim();
	}

	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$
	}

	public String getManagedBeanScope() {
		return this.scopeCombo.getText().trim();
	}

	public String getManagedBeanDescription() {
		return this.managedBeanDescriptionText.getText().trim();
	}
}