/*******************************************************************************
 * Copyright (c) 2000, 2016 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.help.ui.internal.search;

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

import org.eclipse.help.internal.HelpPlugin;
import org.eclipse.help.internal.base.BaseHelpSystem;
import org.eclipse.help.internal.criteria.CriterionResource;
import org.eclipse.help.internal.workingset.AdaptableHelpResource;
import org.eclipse.help.internal.workingset.WorkingSet;
import org.eclipse.help.ui.IEngineDescriptor;
import org.eclipse.help.ui.RootScopePage;
import org.eclipse.help.ui.internal.Messages;
import org.eclipse.help.ui.internal.search.HelpCriteriaContentProvider.CriterionName;
import org.eclipse.help.ui.internal.search.HelpCriteriaContentProvider.CriterionValue;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.ITreeViewerListener;
import org.eclipse.jface.viewers.TreeExpansionEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;

/**
 * Local Help participant in the federated search.
 */
public class LocalHelpPage extends RootScopePage {
	private Button searchAll;

	private Button searchSelected;

	private CheckboxTreeViewer contentTree;

	private ITreeContentProvider contentTreeContentProvider;

	private ILabelProvider contentTreeLabelProvider;

	private CheckboxTreeViewer criteriaTree;

	private ITreeContentProvider criteriaTreeContentProvider;

	private ILabelProvider criteriaTreeLabelProvider;

	//private boolean firstCheck;

	private WorkingSet workingSet;

	@Override
	public void init(IEngineDescriptor ed, String scopeSetName) {
		super.init(ed, scopeSetName);
		if (scopeSetName != null)
			workingSet = BaseHelpSystem.getWorkingSetManager().getWorkingSet(
					scopeSetName);
	}

	/**
	 * Default constructor.
	 */
	public LocalHelpPage() {
		//firstCheck = true;
	}

	@Override
	protected int createScopeContents(Composite parent) {
		Font font = parent.getFont();
		initializeDialogUnits(parent);

		searchAll = new Button(parent, SWT.RADIO);
		searchAll.setText(Messages.selectAll);
		GridData gd = new GridData();
		gd.horizontalSpan = 2;
		searchAll.setLayoutData(gd);
		searchAll.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				contentTree.getTree().setEnabled(false);
				if (criteriaTree != null) {
				    criteriaTree.getTree().setEnabled(false);
				}
			}
		});

		searchSelected = new Button(parent, SWT.RADIO);
		searchSelected.setText(Messages.selectWorkingSet);
		gd = new GridData();
		gd.horizontalSpan = 2;
		searchSelected.setLayoutData(gd);
		searchSelected.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				contentTree.getTree().setEnabled(true);
				if (criteriaTree != null) {
				    criteriaTree.getTree().setEnabled(true);

				}
			}
		});

		if (workingSet == null)
			searchAll.setSelection(true);
		else
			searchSelected.setSelection(true);

		Label contentLabel = new Label(parent, SWT.WRAP);
		contentLabel.setFont(font);
		contentLabel.setText(Messages.WorkingSetContent);
		gd = new GridData(GridData.GRAB_HORIZONTAL
				| GridData.HORIZONTAL_ALIGN_FILL
				| GridData.VERTICAL_ALIGN_CENTER);
		gd.horizontalSpan = 2;
		contentLabel.setLayoutData(gd);

		createContentTree(parent, font);

		if (HelpPlugin.getCriteriaManager().isCriteriaEnabled()) {
			Label criteriaLabel = new Label(parent, SWT.WRAP);
			criteriaLabel.setFont(font);
			criteriaLabel.setText(Messages.WorkingSetCriteria);
			gd = new GridData(GridData.GRAB_HORIZONTAL
					| GridData.HORIZONTAL_ALIGN_FILL
					| GridData.VERTICAL_ALIGN_CENTER);
			gd.horizontalSpan = 2;
			criteriaLabel.setLayoutData(gd);
		    createCriteriaTree(parent, font);
		}

		initializeCheckedState();
		applyDialogFont(parent);

		// Set help for the page
		// WorkbenchHelp.setHelp(tree, "help_workingset_page");
		return 1;
	}

	protected void createContentTree(Composite parent, Font font) {
		GridData gd;
		contentTree = new CheckboxTreeViewer(parent, SWT.BORDER | SWT.H_SCROLL
				| SWT.V_SCROLL);
		gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_VERTICAL);
		gd.heightHint = getTreeHeightHint();
		gd.horizontalSpan = 2;
		contentTree.getControl().setLayoutData(gd);
		contentTree.getControl().setFont(font);

		contentTreeContentProvider = new HelpWorkingSetTreeContentProvider();
		contentTree.setContentProvider(contentTreeContentProvider);

		contentTreeLabelProvider = new HelpWorkingSetElementLabelProvider();
		contentTree.setLabelProvider(contentTreeLabelProvider);

		contentTree.setUseHashlookup(true);

		contentTree.setInput(BaseHelpSystem.getWorkingSetManager().getRoot());

		contentTree.addCheckStateListener(
				event -> handleCheckStateChange(event, contentTree, contentTreeContentProvider));

		contentTree.addTreeListener(new ITreeViewerListener() {

			@Override
			public void treeCollapsed(TreeExpansionEvent event) {
			}

			@Override
			public void treeExpanded(TreeExpansionEvent event) {
				final Object element = event.getElement();
				if (contentTree.getGrayed(element) == false)
					BusyIndicator.showWhile(getShell().getDisplay(),
							() -> setSubtreeChecked(element, contentTree.getChecked(element), false,
									contentTree, contentTreeContentProvider));
			}
		});
		contentTree.getTree().setEnabled(workingSet != null);
	}

	protected int getTreeHeightHint() {
		if (HelpPlugin.getCriteriaManager().isCriteriaEnabled()) {
			return convertHeightInCharsToPixels(8);
		}
		return convertHeightInCharsToPixels(15);
	}


	protected void createCriteriaTree(Composite parent, Font font) {
		GridData gd;
		criteriaTree = new CheckboxTreeViewer(parent, SWT.BORDER | SWT.H_SCROLL
				| SWT.V_SCROLL);
		gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_VERTICAL);
		gd.heightHint = getTreeHeightHint();
		gd.horizontalSpan = 2;
		criteriaTree.getControl().setLayoutData(gd);
		criteriaTree.getControl().setFont(font);

		criteriaTreeContentProvider = new HelpCriteriaContentProvider();
		criteriaTree.setContentProvider(criteriaTreeContentProvider);

		criteriaTreeLabelProvider = new HelpCriteriaLabelProvider();
		criteriaTree.setLabelProvider(criteriaTreeLabelProvider);

		criteriaTree.setUseHashlookup(true);

		criteriaTree.setInput(BaseHelpSystem.getWorkingSetManager().getCriterionIds());

		criteriaTree.addCheckStateListener(
				event -> handleCheckStateChange(event, criteriaTree, criteriaTreeContentProvider));

		criteriaTree.addTreeListener(new ITreeViewerListener() {

			@Override
			public void treeCollapsed(TreeExpansionEvent event) {
			}

			@Override
			public void treeExpanded(TreeExpansionEvent event) {
				final Object element = event.getElement();
				if (criteriaTree.getGrayed(element) == false)
					BusyIndicator.showWhile(getShell().getDisplay(),
							() -> setSubtreeChecked(element, criteriaTree.getChecked(element), false,
									criteriaTree, criteriaTreeContentProvider));
			}
		});
		criteriaTree.getTree().setEnabled(workingSet != null);
	}


	private void initializeCheckedState() {
		if (workingSet == null)
			return;

		BusyIndicator.showWhile(getShell().getDisplay(), () -> {
			initializeContentTree();
			if (HelpPlugin.getCriteriaManager().isCriteriaEnabled()) {
				initializeCriteriaTree();
			}
		});
	}

	boolean isExpandable(Object element, ITreeContentProvider contentProvider) {
		return contentProvider.hasChildren(element);
	}

	void updateParentState(Object child, boolean baseChildState,
			               CheckboxTreeViewer tree, ITreeContentProvider contentProvider) {
		if (child == null)
			return;

		Object parent = contentProvider.getParent(child);
		if (parent == null)
			return;

		boolean allSameState = true;
		Object[] children = null;
		children = contentProvider.getChildren(parent);

		for (int i = children.length - 1; i >= 0; i--) {
			if (tree.getChecked(children[i]) != baseChildState
					|| tree.getGrayed(children[i])) {
				allSameState = false;
				break;
			}
		}

		tree.setGrayed(parent, !allSameState);
		tree.setChecked(parent, !allSameState || baseChildState);

		updateParentState(parent, baseChildState, tree, contentProvider);
	}

	void setSubtreeChecked(Object parent, boolean state,
			boolean checkExpandedState,
            CheckboxTreeViewer tree, ITreeContentProvider contentProvider) {

		Object[] children = contentProvider.getChildren(parent);
		for (int i = children.length - 1; i >= 0; i--) {
			Object element = children[i];
			if (state) {
				tree.setChecked(element, true);
				tree.setGrayed(element, false);
			} else
				tree.setGrayChecked(element, false);
			if (isExpandable(element, contentProvider))
				setSubtreeChecked(element, state, checkExpandedState, tree, contentProvider);
		}
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private void findCheckedElements(java.util.List checkedResources, Object parent,
            CheckboxTreeViewer tree, ITreeContentProvider contentProvider) {
		Object[] children = contentProvider.getChildren(parent);
		for (int i = 0; i < children.length; i++) {
			if (tree.getGrayed(children[i]))
				findCheckedElements(checkedResources, children[i], tree, contentProvider);
			else if (tree.getChecked(children[i]))
				checkedResources.add(children[i]);
		}
	}

	private CriterionResource[] findCheckedCriteria(Object parent,
            CheckboxTreeViewer tree, ITreeContentProvider contentProvider) {
		Object[] children = contentProvider.getChildren(parent);
		List<CriterionResource> resources = new ArrayList<>();
		for (int i = 0; i < children.length; i++) {
			// First level children are names
			CriterionName name = (CriterionName) children[i];
			CriterionResource resource = new CriterionResource(name.getId());
			Object[] grandChildren = contentProvider.getChildren(name);
			for (int j = 0; j < grandChildren.length; j++) {
				if (tree.getChecked(grandChildren[j])) {
				    CriterionValue value = (CriterionValue) grandChildren[j];
				    resource.addCriterionValue(value.getId());
				}
			}
			if (resource.getCriterionValues().size() > 0) {
				resources.add(resource);
			}
		}
		return resources.toArray(new CriterionResource[resources.size()]);
	}

	void handleCheckStateChange(final CheckStateChangedEvent event,
            final CheckboxTreeViewer tree, final ITreeContentProvider contentProvider) {
		BusyIndicator.showWhile(getShell().getDisplay(), () -> {
			Object element = event.getElement();
			boolean state = event.getChecked();
			tree.setGrayed(element, false);
			if (isExpandable(element, contentProvider))
				setSubtreeChecked(element, state, state, tree, contentProvider);
			// only check subtree if state is set to true

			updateParentState(element, state, tree, contentProvider);
			// validateInput();
		});
	}

	public WorkingSet getWorkingSet() {
		ArrayList<AdaptableHelpResource> elements = new ArrayList<>(10);
		CriterionResource[] criteria;
		if (!HelpPlugin.getCriteriaManager().isCriteriaEnabled()) {
			criteria = new CriterionResource[0];
		} else {
			criteria = findCheckedCriteria(
				criteriaTree.getInput(),
				criteriaTree,
				criteriaTreeContentProvider);
		}
		findCheckedElements(elements, contentTree.getInput(), contentTree, contentTreeContentProvider);
		if (workingSet == null) {
			workingSet = new WorkingSet(
					getScopeSetName(),
					elements.toArray(new AdaptableHelpResource[elements.size()]), criteria);
		} else {
			workingSet.setName(getScopeSetName());
			workingSet.setElements(elements.toArray(new AdaptableHelpResource[elements.size()]));
			workingSet.setCriteria(criteria);
		}
		return workingSet;
	}

	@Override
	public boolean performOk() {
		if (searchSelected.getSelection())
			BaseHelpSystem.getWorkingSetManager()
					.addWorkingSet(getWorkingSet());
		else
			BaseHelpSystem.getWorkingSetManager().removeWorkingSet(
					getWorkingSet());

		getPreferenceStore().setValue(
				getKey(LocalSearchScopeFactory.P_WORKING_SET),
				getScopeSetName());
		getPreferenceStore().setValue(
				getKey(LocalSearchScopeFactory.P_CAPABILITY_FILTERING),
				false);
		return super.performOk();
	}

	private String getKey(String key) {
		return getEngineDescriptor().getId() + "." + key; //$NON-NLS-1$
	}

	protected void initializeContentTree() {
		Object[] elements = workingSet.getElements();
		contentTree.setCheckedElements(elements);
		for (int i = 0; i < elements.length; i++) {
			Object element = elements[i];
			if (isExpandable(element, contentTreeContentProvider))
				setSubtreeChecked(element, true, true, contentTree, contentTreeContentProvider);
			updateParentState(element, true, contentTree, contentTreeContentProvider);
		}
	}

	protected void initializeCriteriaTree() {
		CriterionResource[] criteria = workingSet.getCriteria();
		criteriaTree.setCheckedElements(criteria);
		for (int i = 0; i < criteria.length; i++) {
			CriterionResource element = criteria[i];
			CriterionName name = new CriterionName(element.getCriterionName(), null);
			List<String> values = element.getCriterionValues();
			for (Iterator<String> iter = values.iterator(); iter.hasNext();) {
				String valueString = iter.next();
				CriterionValue value = new CriterionValue(valueString, name);
			    criteriaTree.setChecked(value, true);
				updateParentState(value, true, criteriaTree, criteriaTreeContentProvider);
			}
		}
	}

	@Override
	protected void performDefaults() {
		searchAll.setSelection(true);
		searchSelected.setSelection(false);
		contentTree.setCheckedElements(new Object[0]);
		if (criteriaTree != null) {
		    criteriaTree.setCheckedElements(new Object[0]);
		}
		super.performDefaults();
	}

	@Override
	protected Label createDescriptionLabel(Composite parent) {
		if ( getContainer() == null ) {
			return null;
		}
		return super.createDescriptionLabel(parent);
	}
}
