/*
 * Created on Jan 17, 2005
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package org.eclipse.jst.j2ee.internal;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.jar.Manifest;


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.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jem.workbench.utility.JemProjectUtilities;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferencePage;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jst.common.componentcore.util.ComponentUtilities;
import org.eclipse.jst.j2ee.application.internal.operations.ClassPathSelection;
import org.eclipse.jst.j2ee.application.internal.operations.ClasspathElement;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifest;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifestImpl;
import org.eclipse.jst.j2ee.internal.common.ClasspathModel;
import org.eclipse.jst.j2ee.internal.common.ClasspathModelEvent;
import org.eclipse.jst.j2ee.internal.common.ClasspathModelListener;
import org.eclipse.jst.j2ee.internal.common.operations.UpdateJavaBuildPathOperation;
import org.eclipse.jst.j2ee.internal.listeners.IValidateEditListener;
import org.eclipse.jst.j2ee.internal.listeners.ValidateEditListener;
import org.eclipse.jst.j2ee.internal.project.J2EEComponentUtilities;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.PropertyPage;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants;
import org.eclipse.wst.common.componentcore.resources.IFlexibleProject;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.common.frameworks.internal.ui.WTPUIPlugin;
import org.eclipse.wst.common.frameworks.internal.ui.WorkspaceModifyComposedOperation;

/**
 * @author jialin
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class JARDependencyPropertiesPage extends PropertyPage implements IClasspathTableOwner, Listener, ClasspathModelListener, ICommonManifestUIConstants {

    protected IProject project;
    protected IOException caughtManifestException;
    protected boolean isDirty;
    protected Text classPathText;
    protected Text componentNameText;
    protected ClasspathModel model;
    protected CCombo availableAppsCombo;
    protected ClasspathTableManager tableManager;
    protected IValidateEditListener validateEditListener;
    protected Label manifestLabel;
    protected Label enterpriseApplicationLabel;
    protected Label availableDependentJars;
  

    /**
	 * Constructor for JARDependencyPropertiesPage.
	 */
    public JARDependencyPropertiesPage() {
        super();
    }

    protected void initialize() {
        project = (IProject) getElement().getAdapter(IResource.class);
        model = new ClasspathModel(null);
        model.setProject(project);
        if( model.getComponent() != null ){
	        model.addListener(this);
	        updateModelManifest();
	        initializeValidateEditListener();
        }
    }
    
    public void dispose() {
    	super.dispose();
    	if(model.earArtifactEdit != null) {
    		model.earArtifactEdit.dispose();
    		model.earArtifactEdit = null;
    	}
    }

    private void updateModelManifest() {
        if (JemProjectUtilities.isBinaryProject(project) || model.getAvailableEARComponents().length == 0)
            return;
        IContainer root = null;
        IFile manifestFile = null;
        if (project != null)
            root = project;
        else
            root = JemProjectUtilities.getSourceFolderOrFirst(project, null);

        if (root != null)
            manifestFile = root.getFile(new Path(J2EEConstants.MANIFEST_URI));

        if (manifestFile == null || !manifestFile.exists())
            return;

        InputStream in = null;
        try {
            in = manifestFile.getContents();
            ArchiveManifest mf = new ArchiveManifestImpl(new Manifest(in));
            model.primSetManifest(mf);
        } catch (CoreException e) {
            Logger.getLogger().logError(e);
            model.primSetManifest(new ArchiveManifestImpl());
        } catch (IOException iox) {
            Logger.getLogger().logError(iox);
            model.primSetManifest(new ArchiveManifestImpl());
            caughtManifestException = iox;
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException weTried) {
                	//Ignore
                }
            }
        }
    }

    protected void initializeValidateEditListener() {
        validateEditListener = new ValidateEditListener(null, model);
        validateEditListener.setShell(getShell());
    }

    /**
	 * @see org.eclipse.jface.dialogs.IDialogPage#setVisible(boolean)
	 */
    public void setVisible(boolean visible) {
        super.setVisible(visible);
        if (visible && caughtManifestException != null && !model.isDirty())
            ManifestErrorPrompter.showManifestException(getShell(), ERROR_READING_MANIFEST_DIALOG_MESSAGE_PROP_PAGE, false, caughtManifestException);

    }

    /**
	 * @see PreferencePage#createContents(Composite)
	 */
    protected Control createContents(Composite parent) {
        initialize();

        Composite composite = createBasicComposite(parent);
        GridLayout layout = new GridLayout();
        layout.marginWidth = 0;
        layout.marginWidth = 0;
        composite.setLayout(layout);
        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
        if( model.getComponent() != null ){        
	        if(!isValidComponent())
	        	return composite;
	        createProjectLabelsGroup(composite);
	        createListGroup(composite);
	        createTextGroup(composite);
	        refresh();
    	}
        return composite;
    }
	
	/**
	 * @param comp
	 * @return
	 */
	protected Composite createBasicComposite(Composite comp) {
		Composite composite = new Composite(comp, SWT.NONE);
		GridLayout layout = new GridLayout();
        layout.marginWidth = 0;
        layout.marginWidth = 0;
        composite.setLayout(layout);
        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
		return composite;
	}

	protected boolean isValidComponent() {
		if (model.getComponent().getComponentTypeId().equals(IModuleConstants.JST_EAR_MODULE)) {
			this.setErrorMessage(ManifestUIResourceHandler.getString("EAR_Module_Dep_Error")); //$NON-NLS-1$
			return false;
		} else if ((ComponentUtilities.getComponentsForProject(model.getProject())).length > 1) {
			this.setErrorMessage(ManifestUIResourceHandler.getString("Jar_Dep_One_Module_Error")); //$NON-NLS-1$
			return false;
		} else if (J2EEComponentUtilities.isStandaloneComponent(model.getComponent()) ) {
			this.setErrorMessage(ClasspathModel.NO_EAR_MESSAGE);
			return false;
		}
		return true;
	}

    protected void createProjectLabelsGroup(Composite parent) {

		Composite labelsGroup = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		labelsGroup.setLayout(layout);
		labelsGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		Label label = new Label(labelsGroup, SWT.NONE);
		label.setText(ManifestUIResourceHandler.getString("Project_name__UI_")); //$NON-NLS-1$ = "Project name:"

		componentNameText = new Text(labelsGroup, SWT.BORDER);
		GridData data = new GridData(GridData.FILL_HORIZONTAL);
		componentNameText.setEditable(false);
		componentNameText.setLayoutData(data);
		componentNameText.setText(project.getName());
		
		createEnterpriseAppsControls(labelsGroup);

	}

    private void createEnterpriseAppsControls(Composite labelsGroup) {

		enterpriseApplicationLabel = new Label(labelsGroup, SWT.NONE);
		enterpriseApplicationLabel.setText(ManifestUIResourceHandler.getString("EAR_Project_Name__UI__UI_")); //$NON-NLS-1$ = "EAR project name:"

		availableAppsCombo = new CCombo(labelsGroup, SWT.READ_ONLY | SWT.BORDER);
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		availableAppsCombo.setLayoutData(gd);

		availableAppsCombo.addListener(SWT.Selection, this);

	}
    
    protected void createListGroup(Composite parent) {
        Composite listGroup = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.numColumns = 1;
        layout.marginWidth = 0;
        layout.marginHeight = 0;
        listGroup.setLayout(layout);
        GridData gData = new GridData(GridData.FILL_BOTH);
        gData.horizontalIndent = 5;
        listGroup.setLayoutData(gData);

        availableDependentJars = new Label(listGroup, SWT.NONE);
        gData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL);
        availableDependentJars.setText(ManifestUIResourceHandler.getString("Available_dependent_JARs__UI_")); //$NON-NLS-1$ = "Available dependent JARs:"
        availableDependentJars.setLayoutData(gData);
        createTableComposite(listGroup);
    }

    /*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.etools.j2ee.common.ui.classpath.IClasspathTableOwner#createGroup(org.eclipse.swt.widgets.Composite)
	 */
    public Group createGroup(Composite parent) {
        return new Group(parent, SWT.NULL);
    }

    protected void createTextGroup(Composite parent) {

		Composite textGroup = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 1;
		textGroup.setLayout(layout);
		textGroup.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL));

		createClassPathText(textGroup);

	}

    protected void createClassPathText(Composite textGroup) {
    	
    	manifestLabel = new Label(textGroup, SWT.NONE);
		manifestLabel.setText(ManifestUIResourceHandler.getString("Manifest_Class-Path__UI_")); //$NON-NLS-1$ = "Manifest Class-Path:"
		
        classPathText = new Text(textGroup, SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
        GridData gData = new GridData(GridData.FILL_BOTH);
        gData.widthHint = 400;
        gData.heightHint = 100;
        classPathText.setLayoutData(gData);
        classPathText.setEditable(false);
    }
    
    protected void createTableComposite(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        GridData gData = new GridData(GridData.FILL_BOTH);
        composite.setLayoutData(gData);
        tableManager = new ClasspathTableManager(this, model, validateEditListener);
        tableManager.setReadOnly(isReadOnly());
        tableManager.fillComposite(composite);
    }

    /**
	 * @see IClasspathTableOwner#createAvailableJARsViewer(Composite)
	 */
    public CheckboxTableViewer createAvailableJARsViewer(Composite parent) {
        int flags = SWT.CHECK | SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI;

        Table table = new Table(parent,flags);
        CheckboxTableViewer availableJARsViewer = new CheckboxTableViewer(table);

        // set up table layout
        TableLayout tableLayout = new org.eclipse.jface.viewers.TableLayout();
        tableLayout.addColumnData(new ColumnWeightData(200, true));
        tableLayout.addColumnData(new ColumnWeightData(200, true));
        table.setLayout(tableLayout);
        table.setHeaderVisible(true);
        table.setLinesVisible(true);
        availableJARsViewer.setSorter(null);

        // table columns
        TableColumn fileNameColumn = new TableColumn(table, SWT.NONE, 0);
        fileNameColumn.setText(ManifestUIResourceHandler.getString("JAR/Module_UI_")); //$NON-NLS-1$
        fileNameColumn.setResizable(true);

        TableColumn projectColumn = new TableColumn(table, SWT.NONE, 1);
        projectColumn.setText(ManifestUIResourceHandler.getString("Project_UI_")); //$NON-NLS-1$ = "Project"
        projectColumn.setResizable(true);
        tableLayout.layout(table, true);
        return availableJARsViewer;

    }

    /**
	 * @see IClasspathTableOwner#createButtonColumnComposite(Composite)
	 */
    public Composite createButtonColumnComposite(Composite parent) {
        Composite buttonColumn = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.numColumns = 1;
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        buttonColumn.setLayout(layout);
        GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_BEGINNING);
        buttonColumn.setLayoutData(data);
        return buttonColumn;
    }

    /**
	 * @see IClasspathTableOwner
	 */
    public Button primCreatePushButton(String label, Composite buttonColumn) {
        Button aButton = new Button(buttonColumn, SWT.PUSH);
        aButton.setText(label);
        return aButton;
    }

    /**
	 * @see IClasspathTableOwner
	 */
    public Button primCreateRadioButton(String label, Composite parent) {
        Button aButton = new Button(parent, SWT.RADIO);
        aButton.setText(label);
        return aButton;
    }

    /**
	 * @see Listener#handleEvent(Event)
	 */
    public void handleEvent(Event event) {
        if (event.widget == availableAppsCombo)
            availableAppsSelected(event);
    }
    
	protected void availableAppsSelected(Event event) {
        int index = availableAppsCombo.getSelectionIndex();
        model.selectEAR(index);
    }
    protected void populateApps() {
		IVirtualComponent[] components = model.getAvailableEARComponents();
		String[] values = new String[components.length];
		for (int i = 0; i < components.length; i++) {
			values[i] = components[i].getProject().getName();
		}
		if (availableAppsCombo != null) {
			availableAppsCombo.setItems(values);
			IVirtualComponent selected = model.getSelectedEARComponent();
			if (selected != null) {
				int index = Arrays.asList(components).indexOf(selected);
				availableAppsCombo.select(index);
			} else
				availableAppsCombo.clearSelection();
		}
	}

    protected void refresh() {
		populateApps();
		tableManager.refresh();
		refreshText();
	}
    

    public void refreshText() {
		ClassPathSelection sel = model.getClassPathSelection();
		if( sel != null && classPathText != null )
			classPathText.setText(sel == null ? "" : sel.toString()); //$NON-NLS-1$
	}

    /**
	 * @see ClasspathModelListener#modelChanged(ClasspathModelEvent)
	 */
    public void modelChanged(ClasspathModelEvent evt) {
        if (evt.getEventType() == ClasspathModelEvent.CLASS_PATH_CHANGED) {
            isDirty = true;
            refreshText();
        } else if (evt.getEventType() == ClasspathModelEvent.EAR_PROJECT_CHANGED)
            tableManager.refresh();
    }

    /**
	 * @see PreferencePage#performDefaults()
	 */
    protected void performDefaults() {
        model.resetClassPathSelection();
        refresh();
        isDirty = false;
        model.dispose();
    }
    
    public boolean performCancel() {
    	model.dispose();
    	return super.performCancel();
    }

    /**
	 * @see IPreferencePage#performOk() 
	 */
    public boolean performOk() {
        if (!isDirty)
            return true;
        WorkspaceModifyComposedOperation composed = new WorkspaceModifyComposedOperation(createManifestOperation());
        composed.addRunnable(createBuildPathOperation());
        try {
            new ProgressMonitorDialog(getShell()).run(true, true, composed);
        } catch (InvocationTargetException ex) {
            String title = ManifestUIResourceHandler.getString("An_internal_error_occurred_ERROR_"); //$NON-NLS-1$
            String msg = title;
            if (ex.getTargetException() != null && ex.getTargetException().getMessage() != null)
                msg = ex.getTargetException().getMessage();
            MessageDialog.openError(this.getShell(), title, msg);
            org.eclipse.jem.util.logger.proxy.Logger.getLogger().logError(ex);
            return false;
        } catch (InterruptedException e) {
            // cancelled
            return false;
        } finally {
        	model.dispose();
        }
        isDirty = false;
        return true;
    }
    
//    private boolean runWLPOp(WorkspaceModifyComposedOperation composed) {
//    	try {
//			if (composed != null)
//				new ProgressMonitorDialog(getShell()).run(true, true, composed);
//		} catch (InvocationTargetException ex) {
//			String title = ManifestUIResourceHandler.getString("An_internal_error_occurred_ERROR_"); //$NON-NLS-1$
//			String msg = title;
//			if (ex.getTargetException() != null && ex.getTargetException().getMessage() != null)
//				msg = ex.getTargetException().getMessage();
//			MessageDialog.openError(this.getShell(), title, msg);
//			org.eclipse.jem.util.logger.proxy.Logger.getLogger().logError(ex);
//			return false;
//		} catch (InterruptedException e) {
//			// cancelled
//			return false;
//		}
//		return true;
//    }

	protected WorkspaceModifyComposedOperation createComponentDependencyOperations() {
		WorkspaceModifyComposedOperation composedOp = null;
		List selected = getSelectedClassPathSelectionForWLPs().getClasspathElements();
		List unselected = getUnSelectedClassPathSelectionForWLPs().getClasspathElements();
		
		List targetComponentsHandles = new ArrayList();
		for (int i = 0; i < selected.size(); i++) {
			ClasspathElement element = (ClasspathElement) selected.get(i);
			IProject elementProject = element.getProject();
			if( elementProject != null ){
				IFlexibleProject flexProject = ComponentCore.createFlexibleProject(elementProject);
				IVirtualComponent targetComp = flexProject.getComponents()[0];
				targetComponentsHandles.add(targetComp.getComponentHandle());
			}
		}
		if (!targetComponentsHandles.isEmpty()) {
			composedOp = new WorkspaceModifyComposedOperation();
			composedOp.addRunnable(WTPUIPlugin.getRunnableWithProgress(ComponentUtilities.createWLPReferenceComponentOperation(model.getComponent().getComponentHandle(), targetComponentsHandles)));
		}
		targetComponentsHandles = new ArrayList();
		for (int i = 0; i < unselected.size(); i++) {
			ClasspathElement element = (ClasspathElement) unselected.get(i);
			IProject elementProject = element.getProject();
			if( elementProject != null ){
				IFlexibleProject flexProject = ComponentCore.createFlexibleProject(elementProject);
				if (flexProject.getComponents().length > 0) {
					IVirtualComponent targetComp = flexProject.getComponents()[0];
					targetComponentsHandles.add(targetComp.getComponentHandle());
				}
			}else{
				URI archiveURI = element.getArchiveURI();
				if( archiveURI != null && !archiveURI.equals("") ){ //$NON-NLS-1$
					//the name is toString returned from ComponentHandle [<project name>]:lib/... or 
					//[<project name>]:var/...
					String name = ""; //$NON-NLS-1$
					name = archiveURI.toString().substring(archiveURI.toString().lastIndexOf("]") +2); //$NON-NLS-1$
					if( !name.equals("")){ //$NON-NLS-1$
						IVirtualReference ref = model.getComponent().getReference(name);
						IVirtualComponent referenced = ref.getReferencedComponent();
						targetComponentsHandles.add(referenced.getComponentHandle());
					}	
				}
			}
		}
		if (!targetComponentsHandles.isEmpty()) {
			if(composedOp == null)
				composedOp = new WorkspaceModifyComposedOperation();
			composedOp.addRunnable(WTPUIPlugin.getRunnableWithProgress(ComponentUtilities.removeReferenceComponentOperation(model.getComponent().getComponentHandle(), targetComponentsHandles)));
		}
		return composedOp;
	}
	
	protected WorkspaceModifyComposedOperation createFlexProjectOperations() {
		WorkspaceModifyComposedOperation composedOp = null;
		try {
			Object[] elements = tableManager.availableJARsViewer.getCheckedElements();
			for (int i = 0; i < elements.length; i++) {
				ClasspathElement element = (ClasspathElement) elements[i];
				IProject elementProject = element.getProject();
				if ( elementProject != null && !elementProject.hasNature(IModuleConstants.MODULE_NATURE_ID)) {
					if(composedOp == null)
						composedOp = new WorkspaceModifyComposedOperation();
					composedOp.addRunnable(WTPUIPlugin.getRunnableWithProgress(ComponentUtilities.createFlexJavaProjectForProjectOperation(elementProject)));
				}
			}
		} catch (CoreException ce) {
		}
		return composedOp;
	}
	
	protected IRunnableWithProgress createBuildPathOperation() {
        IJavaProject javaProject = JemProjectUtilities.getJavaProject(project);
        return WTPUIPlugin.getRunnableWithProgress(new UpdateJavaBuildPathOperation(javaProject,getSelectedClassPathSelectionForWLPs()));
    }
	
	protected IRunnableWithProgress createWLPBuildPathOperation() {
        IJavaProject javaProject = JemProjectUtilities.getJavaProject(project);
        return WTPUIPlugin.getRunnableWithProgress(new UpdateJavaBuildPathOperation(javaProject,getSelectedClassPathSelectionForWLPs(),getUnSelectedClassPathSelectionForWLPs()));
    }
	
	protected ClassPathSelection getUnSelectedClassPathSelectionForWLPs() {
		ClassPathSelection selection = new ClassPathSelection();
		Object[] checkedElements = tableManager.availableJARsViewer.getCheckedElements();
		List modelElements = model.getClassPathSelectionForWLPs().getClasspathElements();
		for (int i = 0; i < modelElements.size(); i++) {
			List checkedElementsList = Arrays.asList(checkedElements);
			if (!checkedElementsList.contains(modelElements.get(i))) {
				selection.getClasspathElements().add(modelElements.get(i));
			}
		}
		return selection;
	}
	
    
    private ClassPathSelection getSelectedClassPathSelectionForWLPs() {
    		ClassPathSelection selection = new ClassPathSelection();
    		Object[] checkedElements = tableManager.availableJARsViewer.getCheckedElements();
    		for(int i = 0; i < checkedElements.length; i++) {
    			selection.getClasspathElements().add(checkedElements[i]);
    		}
    		return selection;
	}
    
    protected UpdateManifestOperation createManifestOperation() {
        return new UpdateManifestOperation(project.getName(), model.getClassPathSelection().toString(), true);
    }

    protected boolean isReadOnly() {
        return JemProjectUtilities.isBinaryProject(project);
    }

}