/*******************************************************************************
 * Copyright (c) 2008 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 API and implementation
 *******************************************************************************/
package org.eclipse.wst.html.ui.internal.preferences.ui;

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

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IPreferencesService;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.forms.events.ExpansionAdapter;
import org.eclipse.ui.forms.events.ExpansionEvent;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.wst.html.ui.internal.HTMLUIMessages;
import org.eclipse.wst.sse.core.internal.validate.ValidationMessage;
import org.eclipse.wst.sse.ui.internal.preferences.ui.ScrolledPageContent;
import org.eclipse.wst.validation.ValidationFramework;
import org.osgi.service.prefs.BackingStoreException;

/**
 * Based on org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock
 */
abstract class AbstractValidationSettingsPage extends PropertyPreferencePage {

	private List fCombos;
	private List fExpandables;
	
	private SelectionListener fSelectionListener;
	
	private IPreferencesService fPreferencesService = null;
	
	private static final String SETTINGS_EXPANDED = "expanded"; //$NON-NLS-1$
	
	private ValidationFramework fValidation;
	
	private class ComboData {
		private String fKey;
		private int[] fSeverities;
		private int fIndex;
		
		public ComboData(String key, int[] severities, int index) {
			fKey = key;
			fSeverities = severities;
			fIndex = index;
		}
		
		public String getKey() {
			return fKey;
		}
		
		public void setIndex(int index) {
			fIndex = index;
		}
		
		public int getIndex() {
			return fIndex;
		}
		
		/**
		 * Sets the severity index based on <code>severity</code>.
		 * If the severity doesn't exist, the index is set to -1.
		 * 
		 * @param severity the severity level
		 */
		public void setSeverity(int severity) {
			for(int i = 0; fSeverities != null && i < fSeverities.length; i++) {
				if(fSeverities[i] == severity) {
					fIndex = i;
					return;
				}
			}
			
			fIndex = -1;
		}
		
		public int getSeverity() {
			return (fIndex >= 0 && fSeverities != null && fIndex < fSeverities.length) ? fSeverities[fIndex] : -1;
		}
		
	}
	
	public AbstractValidationSettingsPage() {
		super();
		fCombos = new ArrayList();
		fExpandables = new ArrayList();
		fPreferencesService = Platform.getPreferencesService();
		fValidation = ValidationFramework.getDefault();
	}
	
	/**
	 * Creates a Combo widget in the composite <code>parent</code>. The data
	 * in the Combo is associated with <code>key</code>. The Combo data is
	 * generated based on the integer <code>values</code> where the index
	 * of <code>values</code> corresponds to the index of <code>valueLabels</code>
	 * 
	 * @param parent the composite to create the combo box in
	 * @param label the label to give the combo box
	 * @param key the unique key to identify the combo box
	 * @param values the values represented by the combo options
	 * @param valueLabels the calues displayed in the combo box
	 * @param indent how far to indent the combo box label
	 * 
	 * @return the generated combo box
	 */
	protected Combo addComboBox(Composite parent, String label, String key, int[] values, String[] valueLabels, int indent) {
		GridData gd= new GridData(GridData.FILL, GridData.CENTER, true, false, 2, 1);
		gd.horizontalIndent= indent;
				
		Label labelControl= new Label(parent, SWT.LEFT);
		labelControl.setFont(JFaceResources.getDialogFont());
		labelControl.setText(label);
		labelControl.setLayoutData(gd);
				
		Combo comboBox= newComboControl(parent, key, values, valueLabels);
		comboBox.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));

		return comboBox;
	}
	
	/**
	 * Creates a combo box and associates the combo data with the
	 * combo box.
	 * 
	 * @param composite the composite to create the combo box in
	 * @param key the unique key to identify the combo box
	 * @param values the values represented by the combo options
	 * @param valueLabels the values displayed in the combo box
	 * 
	 * @return the generated combo box
	 */
	protected Combo newComboControl(Composite composite, String key, int[] values, String[] valueLabels) {
		ComboData data = new ComboData(key, values, -1);
		
		Combo comboBox= new Combo(composite, SWT.READ_ONLY);
		comboBox.setItems(valueLabels);
		comboBox.setData(data);
		comboBox.addSelectionListener(getSelectionListener());
		comboBox.setFont(JFaceResources.getDialogFont());
			
		makeScrollableCompositeAware(comboBox);
		
		int severity = -1;
		if(key != null)
			severity = fPreferencesService.getInt(getPreferenceNodeQualifier(), key, ValidationMessage.WARNING, createPreferenceScopes());

		if(severity == ValidationMessage.ERROR || severity == ValidationMessage.WARNING || severity == ValidationMessage.IGNORE)
			data.setSeverity(severity);
		
		if(data.getIndex() >= 0)
			comboBox.select(data.getIndex());
		
		fCombos.add(comboBox);
		return comboBox;
	}
	
	protected SelectionListener getSelectionListener() {
		if (fSelectionListener == null) {
			fSelectionListener= new SelectionListener() {
				public void widgetDefaultSelected(SelectionEvent e) {}
	
				public void widgetSelected(SelectionEvent e) {
					controlChanged(e.widget);
				}
			};
		}
		return fSelectionListener;
	}
	
	protected void controlChanged(Widget widget) {
		ComboData data= (ComboData) widget.getData();
		if (widget instanceof Combo) {
			data.setIndex(((Combo)widget).getSelectionIndex());
		} else {
			return;
		}
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.wst.sse.ui.internal.preferences.ui.AbstractSettingsPage#storeValues()
	 */
	protected void storeValues() {
		if(fCombos == null || fCombos.size() == 0)
			return;
		
		Iterator it = fCombos.iterator();
		
		IScopeContext[] contexts = createPreferenceScopes();

		while(it.hasNext()) {
			ComboData data = (ComboData) ((Combo)it.next()).getData();
			if(data.getKey() != null) {
				contexts[0].getNode(getPreferenceNodeQualifier()).putInt(data.getKey(), data.getSeverity());
			}
		}
		
		for(int i = 0; i < contexts.length; i++) {
			try {
				contexts[i].getNode(getPreferenceNodeQualifier()).flush();
			}
			catch (BackingStoreException e) {
				
			}
		}
	}
	
	protected ExpandableComposite getParentExpandableComposite(Control control) {
		Control parent= control.getParent();
		while (!(parent instanceof ExpandableComposite) && parent != null) {
			parent= parent.getParent();
		}
		if (parent instanceof ExpandableComposite) {
			return (ExpandableComposite) parent;
		}
		return null;
	}
	
	protected ExpandableComposite createStyleSection(Composite parent, String label, int nColumns) {
		ExpandableComposite excomposite= new ExpandableComposite(parent, SWT.NONE, ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT);
		excomposite.setText(label);
		excomposite.setExpanded(false);
		excomposite.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT));
		excomposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false, nColumns, 1));
		excomposite.addExpansionListener(new ExpansionAdapter() {
			public void expansionStateChanged(ExpansionEvent e) {
				expandedStateChanged((ExpandableComposite) e.getSource());
			}
		});
		fExpandables.add(excomposite);
		makeScrollableCompositeAware(excomposite);
		return excomposite;
	}
	
	protected final void expandedStateChanged(ExpandableComposite expandable) {
		ScrolledPageContent parentScrolledComposite= getParentScrolledComposite(expandable);
		if (parentScrolledComposite != null) {
			parentScrolledComposite.reflow(true);
		}
	}
	
	private void makeScrollableCompositeAware(Control control) {
		ScrolledPageContent parentScrolledComposite= getParentScrolledComposite(control);
		if (parentScrolledComposite != null) {
			parentScrolledComposite.adaptChild(control);
		}
	}
	
	protected ScrolledPageContent getParentScrolledComposite(Control control) {
		Control parent= control.getParent();
		while (!(parent instanceof ScrolledPageContent) && parent != null) {
			parent= parent.getParent();
		}
		if (parent instanceof ScrolledPageContent) {
			return (ScrolledPageContent) parent;
		}
		return null;
	}
	
	protected void storeSectionExpansionStates(IDialogSettings section) {
		for(int i = 0; i < fExpandables.size(); i++) {
			ExpandableComposite comp = (ExpandableComposite) fExpandables.get(i);
			section.put(SETTINGS_EXPANDED + String.valueOf(i), comp.isExpanded());
		}
	}
	
	protected void restoreSectionExpansionStates(IDialogSettings settings) {
		for (int i= 0; i < fExpandables.size(); i++) {
			ExpandableComposite excomposite= (ExpandableComposite) fExpandables.get(i);
			if (settings == null) {
				excomposite.setExpanded(i == 0); // only expand the first node by default
			} else {
				excomposite.setExpanded(settings.getBoolean(SETTINGS_EXPANDED + String.valueOf(i)));
			}
		}
	}
	
	protected void resetSeverities() {
		IEclipsePreferences defaultContext = new DefaultScope().getNode(getPreferenceNodeQualifier());
		for(int i = 0; i < fCombos.size(); i++) {
			ComboData data = (ComboData)((Combo)fCombos.get(i)).getData();
			int severity = defaultContext.getInt(data.getKey(), ValidationMessage.WARNING);
			data.setSeverity(severity);
			((Combo)fCombos.get(i)).select(data.getIndex());
		}
	}
	
	protected abstract boolean shouldRevalidateOnSettingsChange();
	
	public boolean performOk() {
		if(super.performOk() && shouldRevalidateOnSettingsChange()) {
			MessageBox mb = new MessageBox(this.getShell(), SWT.APPLICATION_MODAL | SWT.YES | SWT.NO | SWT.CANCEL | SWT.ICON_INFORMATION | SWT.RIGHT);
			mb.setText(HTMLUIMessages.Validation_Title);
			/* Choose which message to use based on if its project or workspace settings */
			String msg = (getProject() == null) ? HTMLUIMessages.Validation_Workspace : HTMLUIMessages.Validation_Project;
			mb.setMessage(msg);
			switch(mb.open()) {
				case SWT.CANCEL:
					return false;
				case SWT.YES:
					ValidateJob job = new ValidateJob(HTMLUIMessages.Validation_jobName);
					job.schedule();
				case SWT.NO:
				default:
					return true;
			}
		}
		return false;
	}
	
	/**
	 * Performs validation after validation preferences have been modified.
	 */
	private class ValidateJob extends Job {
		
		public ValidateJob(String name) {
			super(name);
		}

		protected IStatus run(IProgressMonitor monitor) {
			IStatus status = Status.OK_STATUS;
			try {
				IProject[] projects = null;
				/* Changed preferences for a single project, only validate it */
				if(getProject() != null)
					projects = new IProject[] {getProject()};
				/* Workspace-wide preferences changed */
				else {
					/* Get all of the projects in the workspace */
					projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
					IEclipsePreferences prefs = null;
					List projectList = new ArrayList();
					
					/* Filter out projects that use project-specific settings or have been closed */
					for(int i = 0; i < projects.length; i++) {
						prefs = new ProjectScope(projects[i]).getNode(getPreferenceNodeQualifier());
						if(projects[i].isAccessible() && !prefs.getBoolean(getProjectSettingsKey(), false))
							projectList.add(projects[i]);
					}
					projects = (IProject[]) projectList.toArray(new IProject[projectList.size()]);
				}
				fValidation.validate(projects, true, false, monitor);
			}
			catch (CoreException ce) {
				status = Status.CANCEL_STATUS;
			}
			
			return status;
		}
		
	}
	
}
