/*
 * Created on 2005-01-01
 *
 * Part of the Symbian development plug-in for Eclipse
 * Copyright (C) Mikołaj Zalewski, 2005
 */
package pl.zalewski.mikolaj.symbdev.ui.mmpedit;

import java.util.LinkedList;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.forms.widgets.FormText;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.TableWrapData;
import org.eclipse.ui.forms.widgets.TableWrapLayout;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;

import pl.zalewski.mikolaj.symbdev.SymbdevPlugin;
import pl.zalewski.mikolaj.symbdev.SymbianSDKEntry;
import pl.zalewski.mikolaj.symbdev.core.mmpmodel.IMMPModel;
import pl.zalewski.mikolaj.symbdev.core.mmpmodel.MMPSourceFileReference;

/**
 * @author mikolaj
 */
public class SourceSection extends MMPSectionPart {

    static final String HELP_TEXT=
        "<form><p>Apart from selecting files you can also select " +
        "whole directories. The plug-in will take care to add all " +
        "the *.cpp files in such a directory to the MMP file.</p>" +
        "<p>Files added automatically by the plugin will be marked " +
        "with a grey tick. If you click on such tick it will be removed " +
        "- the file will be removed from the MMP file and it will " +
        "be added to a \"don't add\" list of files that should not " +
        "be added automatically</p></form>"; 
    
    public SourceSection(Composite parent, FormToolkit toolkit, IMMPModel model,
            IProject project, SymbianSDKEntry sdk, IPath currPath) {
        super(parent, toolkit, "Sources", "Selects the sources to build the target", 2);
        ((TableWrapLayout)fContainer.getLayout()).makeColumnsEqualWidth=true;
		fProject=project;
        fModel=model;
        fSDK=sdk;
        fCurrentDir=currPath;
		fTreeViewer = new CheckboxTreeViewer(toolkit.createTree(fContainer,
				SWT.CHECK));
		fTreeViewer.setContentProvider(new WorkbenchContentProvider());
		fTreeViewer.setLabelProvider(new WorkbenchLabelProvider());
		fTreeViewer.setAutoExpandLevel(0);
		fTreeViewer.setInput(project);
		
		TableWrapData td=new TableWrapData(TableWrapData.FILL_GRAB);
		fTreeViewer.getTree().setLayoutData(td);
		fTreeViewer.addCheckStateListener(new ICheckStateListener() {
            public void checkStateChanged(CheckStateChangedEvent event) {
                checkedStateChanged(event.getElement(), event.getChecked(),
                        fTreeViewer.getGrayed(event.getElement()));
            }		    
		});
		
		fHelpText=toolkit.createFormText(fContainer, true);
		td=new TableWrapData(TableWrapData.FILL_GRAB);
		fHelpText.setText(HELP_TEXT, true, false);
		fHelpText.setLayoutData(td);
		
		checkItems();
		
		fSourcesListener=new Listener() {
            public void handleEvent(org.eclipse.swt.widgets.Event e) {
                checkItems();
            }			
        };
        fModel.addChangeListener(IMMPModel.CHANGE_SOURCE, fSourcesListener);
        fSourcesDirListener=new Listener() {
            public void handleEvent(org.eclipse.swt.widgets.Event e) {
                checkItems();
            }			
        };
        fModel.addChangeListener(IMMPModel.CHANGE_SOURCE_DIR, fSourcesDirListener);
		
        contentCreated();
    }
    
    protected void checkedStateChanged(Object element, boolean checked, boolean grayed) {
        try {
	        if (element instanceof IFile) {
	            IPath path=((IFile)element).getLocation();
	            if (checked)
	                fModel.addSourceFile(path);
	            	else fModel.removeSourceFile(path, new Path(fSDK.epocRoot));
	        } else if (element instanceof IContainer) {
	            IPath path=((IContainer)element).getLocation();
	            if (checked) fModel.addSourceDir(path);
	            	else if (grayed) fModel.addSourceDir(path);
	            	    else fModel.removeSourceDir(path);
	        } else checkItems();
        }
        catch (CoreException e) {
            SymbdevPlugin.showError(e, "Error adding file", getSection().getShell());
            checkItems();
        }
    }
    
    protected void checkItems()
    {
        if (fTreeViewer.getControl().isDisposed())
            return;
        MMPSourceFileReference[] sources=fModel.getSourceFiles();
        LinkedList checked=new LinkedList();
        LinkedList grayed=new LinkedList();
        for (int i=0; i<sources.length; i++) {
            IResource ret=sources[i].getWorkspaceFile(fCurrentDir);
            if (ret!=null) {
                checked.add(ret);
                if (sources[i].fType==MMPSourceFileReference.ITEM_SOURCE_AUTO)
                    grayed.add(ret);
            }
        }
        IPath[] paths=null;
        IPath[] autopaths=null;
        try {
            paths=fModel.getSourceDirs();
            autopaths=fModel.getAllSourceAutoDirs();
        }
        catch (CoreException e) {
            SymbdevPlugin.showError(e, "Error retrieving source directories list - " +
            		"sources directories won't be shown", getSection().getShell());
        }
        if (paths!=null && autopaths!=null) {
            for (int i=0; i<paths.length; i++) {
	            IResource ret=ResourcesPlugin.getWorkspace().getRoot().getContainerForLocation(paths[i]);
	            if (ret!=null)
	                checked.add(ret);
            }
            for (int i=0; i<autopaths.length; i++) {
	            IResource ret=ResourcesPlugin.getWorkspace().getRoot().getContainerForLocation(autopaths[i]);
	            if (ret!=null) {
	                checked.add(ret);
	                grayed.add(ret);
	            }
            }            
        }
        fTreeViewer.setCheckedElements(checked.toArray());
        fTreeViewer.setGrayedElements(grayed.toArray());
    }
    
    public void dispose() {
        fModel.removeChangeListener(IMMPModel.CHANGE_SOURCE, fSourcesListener);
        fModel.removeChangeListener(IMMPModel.CHANGE_SOURCE_DIR, fSourcesDirListener);
        super.dispose();
    }


    CheckboxTreeViewer fTreeViewer;
    IMMPModel fModel;
    IPath fCurrentDir;
    IProject fProject;
    Listener fSourcesListener;
    Listener fSourcesDirListener;
    FormText fHelpText;
    SymbianSDKEntry fSDK;
}
