/*******************************************************************************
 * Copyright (c) 2009 Wind River Systems 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:
 *     Wind River Systems - initial API and implementation
 *******************************************************************************/
package org.eclipe.debug.tests.viewer.model;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import junit.framework.Assert;
import junit.framework.TestCase;

import org.eclipe.debug.tests.viewer.model.TestModel.TestElement;
import org.eclipse.debug.internal.ui.viewers.model.ITreeModelContentProviderTarget;
import org.eclipse.debug.internal.ui.viewers.model.ITreeModelViewer;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;

/**
 * Tests to verify that the viewer property updates when created
 * with the SWT.POPUP style.   
 * 
 * @since 3.6
 */
abstract public class PopupTests extends TestCase implements ITestModelUpdatesListenerConstants {
    Display fDisplay;
    Shell fShell;
    ITreeModelViewer fViewer;
    TestModelUpdatesListener fListener;
    
    public PopupTests(String name) {
        super(name);
    }

    /**
     * @throws java.lang.Exception
     */
    protected void setUp() throws Exception {
        fDisplay = PlatformUI.getWorkbench().getDisplay();
        fShell = new Shell(fDisplay/*, SWT.ON_TOP | SWT.SHELL_TRIM*/);
        fShell.setMaximized(true);
        fShell.setLayout(new FillLayout());

        fViewer = createViewer(fDisplay, fShell, SWT.POP_UP);
        
        fListener = new TestModelUpdatesListener(fViewer, false, false);

        fShell.open ();
    }

    protected ITreeModelContentProviderTarget getCTargetViewer() {
        return (ITreeModelContentProviderTarget)fViewer;
    }
    

    abstract protected ITreeModelViewer createViewer(Display display, Shell shell, int style);
    
    /**
     * @throws java.lang.Exception
     */
    protected void tearDown() throws Exception {
        fListener.dispose();
        fViewer.getPresentationContext().dispose();
        
        // Close the shell and exit.
        fShell.close();
        while (!fShell.isDisposed()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
    }

    /**
     * This test verifies that content updates are still being performed. 
     */
    public void testRefreshStruct() {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
        
        TestModel model = TestModel.simpleSingleLevel();
        fViewer.setAutoExpandLevel(-1);

        // Create the listener
        fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, true, false); 

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
        while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        model.validateData(fViewer, TreePath.EMPTY);
        
        // Update the model
        TestElement element = model.getRootElement().getChildren()[0];
        TreePath elementPath = new TreePath(new Object[] { element });
        TestElement[] newChildren = new TestElement[] {
            new TestElement(model, "1.1 - new", new TestElement[0]),
            new TestElement(model, "1.2 - new", new TestElement[0]),
            new TestElement(model, "1.3 - new", new TestElement[0]),
        };
        ModelDelta delta = model.setElementChildren(elementPath, newChildren);
        
        fListener.reset(elementPath, element, -1, true, false); 
        model.postDelta(delta);
        while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        model.validateData(fViewer, TreePath.EMPTY);
    }

    /**
     * This test verifies that expand and select updates are being ignored.
     */
    public void testExpandAndSelect() {
        TestModel model = TestModel.simpleMultiLevel();
        
        // Create the listener
        fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, true, false);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
        while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        model.validateData(fViewer, TreePath.EMPTY, true);

        // Create the delta
        fListener.reset();
        // TODO Investigate: there seem to be unnecessary updates being issued 
        // by the viewer.  These include the updates that are commented out:  
        // For now disable checking for extra updates.
        fListener.setFailOnRedundantUpdates(false);
        TestElement element = model.getRootElement();
        TreePath path_root = TreePath.EMPTY;
        ModelDelta delta= new ModelDelta(model.getRootElement(), -1, IModelDelta.EXPAND, element.getChildren().length);
        ModelDelta deltaRoot = delta;
        element = element.getChildren()[2];
        TreePath path_root_3 = path_root.createChildPath(element);
        delta.addNode(element, 2, IModelDelta.SELECT | IModelDelta.EXPAND, element.fChildren.length);

        // Validate the expansion state BEFORE posting the delta.
        
        ITreeModelContentProviderTarget contentProviderViewer = (ITreeModelContentProviderTarget)fViewer; 
        Assert.assertFalse(contentProviderViewer.getExpandedState(path_root_3));
        
        model.postDelta(deltaRoot);
        while (true) {
            if (fListener.isFinished(MODEL_CHANGED_COMPLETE)) {
                if (fListener.isFinished(CONTENT_UPDATES_STARTED)) {
                    if (fListener.isFinished(CONTENT_UPDATES_COMPLETE)) {
                        break;
                    }
                } else {
                    break;
                }
            }
            if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        }
        model.validateData(fViewer, TreePath.EMPTY, true);

        // Validate the expansion state AFTER posting the delta.
        Assert.assertFalse(contentProviderViewer.getExpandedState(path_root_3));
        
        // Verify selection
        ISelection selection = fViewer.getSelection();
        if (selection instanceof ITreeSelection) {
            List selectionPathsList = Arrays.asList( ((ITreeSelection)selection).getPaths() );
            Assert.assertFalse(selectionPathsList.contains(path_root_3));
        } else {
            Assert.fail("Not a tree selection");
        }
    }
    

    
    public void testPreserveExpandedOnSubTreeContent() {
        //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer);
        TestModel model = TestModel.simpleMultiLevel();

        // Expand all
        fViewer.setAutoExpandLevel(-1);
        
        // Create the listener, 
        fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, true, false); 

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
        while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
        model.validateData(fViewer, TreePath.EMPTY, true);

        // Turn off auto-expansion
        fViewer.setAutoExpandLevel(0);
        
        // Set a selection in view
        TreeSelection originalSelection = new TreeSelection(model.findElement("3.3.1"));
        fViewer.setSelection(originalSelection);

        // Update the model
        model.addElementChild(model.findElement("3"), 0, new TestElement(model, "3.0 - new", new TestElement[0]));
        
        // Create the delta for element "3" with content update.
        TreePath elementPath = model.findElement("3");
        ModelDelta rootDelta = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
        ModelDelta elementDelta = model.getElementDelta(rootDelta, elementPath, true);
        elementDelta.setFlags(IModelDelta.CONTENT);

        // Note: Re-expanding nodes causes redundant updates.
        fListener.reset(false, false);
        fListener.addUpdates(getCTargetViewer(), elementPath, model.getElement(elementPath), -1, ALL_UPDATES_COMPLETE);
        
        // Post the sub-tree update
        model.postDelta(rootDelta);
        while (!fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE)) 
            if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();

        // Validate data
        model.validateData(fViewer, TreePath.EMPTY, true);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("3")) == true);
        // On windows, getExpandedState() may return true for an element with no children:
        // Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("3.0 - new")) == false);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("3.1")) == true);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("3.2")) == true);
        Assert.assertTrue(getCTargetViewer().getExpandedState(model.findElement("3.3")) == true);
        Assert.assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) );
    }

    private boolean areTreeSelectionsEqual(ITreeSelection sel1, ITreeSelection sel2) {
        Set sel1Set = new HashSet();
        sel1Set.addAll( Arrays.asList(sel1.getPaths()) );
        
        Set sel2Set = new HashSet();
        sel2Set.addAll( Arrays.asList(sel2.getPaths()) );
        
        return sel1Set.equals(sel2Set);
    }
    

}
