package de.cooperateproject.ui.nature;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.cooperateproject.ui.nature.tasks.BackgroundTasksAdapter;

/**
 * IResourceChangeListener which provides custom logic for cooperate projects.
 * 
 * @author faller, seifermann, persch
 *
 */
public class ProjectOpenedListener implements IResourceChangeListener {

    private static final Logger LOGGER = LoggerFactory.getLogger(ProjectOpenedListener.class);

    @Override
    public void resourceChanged(IResourceChangeEvent event) {
        if (handleNullOrClosing(event)) {
            return;
        }
        try {
            event.getDelta().accept(new CooperateResourceDeltaVisitor());
        } catch (CoreException e) {
            LOGGER.error("Exception during rebuild after opening or closing of a project", e);
        }
    }

    private static boolean handleNullOrClosing(IResourceChangeEvent event) {
        if (event == null) {
            return true;
        } else if (event.getDelta() == null) {
            if (event.getType() == IResourceChangeEvent.PRE_CLOSE) {
                BackgroundTasksAdapter.getManager().deregisterProject((IProject) event.getResource());
            }
            return true;
        }
        return false;
    }

    private static boolean isRelevantForClean(IResourceDelta delta) {
        if ((delta.getResource().getType() & IResource.PROJECT) != 0 && (delta.getFlags() & IResourceDelta.OPEN) != 0) {
            return true;
        }

        return false;
    }

    private static boolean isRelevantForDelete(IResourceDelta delta) {
        if ((delta.getResource().getType() & IResource.PROJECT) == 0) {
            return false;
        }

        if (delta.getKind() == IResourceDelta.REMOVED) {
            return true;
        }

        return false;
    }

    private static class CooperateResourceDeltaVisitor implements IResourceDeltaVisitor {
        @Override
        public boolean visit(final IResourceDelta delta) throws CoreException {
            if (isRelevantForClean(delta)) {
                IProject project = (IProject) delta.getResource();
                Job rebuild = new Job("rebuild") {
                    @Override
                    protected IStatus run(IProgressMonitor monitor) {
                        try {
                            project.build(IncrementalProjectBuilder.FULL_BUILD, monitor);
                        } catch (CoreException e) {
                            LOGGER.error("Exception during rebuild after opening of a project", e);
                            return Status.CANCEL_STATUS;
                        }
                        return Status.OK_STATUS;
                    }
                };
                rebuild.schedule();
            }
            if (isRelevantForDelete(delta)) {
                BackgroundTasksAdapter.getManager().deregisterProject((IProject) delta.getResource());
            }
            return true;
        }
    }
}

@@ -875,16 +875,23 @@
 , persch
+, henss
 %0A *%0A */%0A
@@ -2070,35 +2070,132 @@
             
-return true
+IProject project = delta.getResource().getAdapter(IProject.class);%0A            return project.isAccessible()
 ;%0A        %7D%0A
@@ -2266,20 +2266,24 @@
 antForDe
-le
+regis
 te
+r
 (IResour
@@ -2398,32 +2398,107 @@
 false;%0A        %7D
+%0A        IProject project = delta.getResource().getAdapter(IProject.class);
 %0A%0A        if (de
@@ -2536,16 +2536,43 @@
 .REMOVED
+ %7C%7C !project.isAccessible()
 ) %7B%0A    
@@ -2903,19 +2903,8 @@
 ct =
- (IProject)
  del
@@ -2919,16 +2919,43 @@
 source()
+.getAdapter(IProject.class)
 ;%0A      
@@ -3586,32 +3586,33 @@
 ;%0A            %7D%0A
+%0A
             if (
@@ -3630,12 +3630,16 @@
 orDe
-le
+regis
 te
+r
 (del

use isAccessible