/*******************************************************************************
 * Copyright (c) 2005 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.ui.internal.ide;

import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProduct;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IPageListener;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveRegistry;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPartConstants;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PerspectiveAdapter;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.application.ActionBarAdvisor;
import org.eclipse.ui.application.IActionBarConfigurer;
import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
import org.eclipse.ui.application.WorkbenchWindowAdvisor;
import org.eclipse.ui.internal.ide.dialogs.WelcomeEditorInput;
import org.eclipse.ui.part.EditorInputTransfer;
import org.eclipse.ui.part.MarkerTransfer;
import org.eclipse.ui.part.ResourceTransfer;
import org.eclipse.update.configurator.ConfiguratorUtils;
import org.eclipse.update.configurator.IPlatformConfiguration;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;

/**
 * Window-level advisor for the IDE.
 */
public class IDEWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {

    private static final String WELCOME_EDITOR_ID = "org.eclipse.ui.internal.ide.dialogs.WelcomeEditor"; //$NON-NLS-1$

    private IDEWorkbenchAdvisor wbAdvisor;
    private boolean editorsAndIntrosOpened = false;
    private IEditorPart lastActiveEditor = null;
    private IPerspectiveDescriptor lastPerspective = null;

    private IWorkbenchPage lastActivePage;
    private String lastEditorTitle = ""; //$NON-NLS-1$
    
    private IPropertyListener editorPropertyListener = new IPropertyListener() {
        public void propertyChanged(Object source, int propId) {
            if (propId == IWorkbenchPartConstants.PROP_TITLE) {
                if (lastActiveEditor != null) {
                    String newTitle = lastActiveEditor.getTitle();
                    if (!lastEditorTitle.equals(newTitle)) {
                        recomputeTitle();
                    }
                }
            }
        }
    };

    private IAdaptable lastInput;

    /**
     * Crates a new IDE workbench window advisor.
     *  
     * @param wbAdvisor the workbench advisor
     * @param configurer the window configurer
     */
    public IDEWorkbenchWindowAdvisor(IDEWorkbenchAdvisor wbAdvisor, IWorkbenchWindowConfigurer configurer) {
        super(configurer);
        this.wbAdvisor = wbAdvisor;
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.application.WorkbenchWindowAdvisor#createActionBarAdvisor(org.eclipse.ui.application.IActionBarConfigurer)
     */
    public ActionBarAdvisor createActionBarAdvisor(IActionBarConfigurer configurer) {
        return new WorkbenchActionBuilder(configurer);
    }
    
    /**
     * Returns the workbench.
     * 
     * @return the workbench
     */
    private IWorkbench getWorkbench() {
        return getWindowConfigurer().getWorkbenchConfigurer().getWorkbench();
    }
    
    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.application.WorkbenchAdvisor#preWindowShellClose
     */
    public boolean preWindowShellClose() {
        if (getWorkbench().getWorkbenchWindowCount() > 1) {
            return true;
        }
        // the user has asked to close the last window, while will cause the
        // workbench to close in due course - prompt the user for confirmation
        IPreferenceStore store = IDEWorkbenchPlugin.getDefault()
                .getPreferenceStore();
        boolean promptOnExit = store
                .getBoolean(IDEInternalPreferences.EXIT_PROMPT_ON_CLOSE_LAST_WINDOW);

        if (promptOnExit) {
            String message;

            String productName = null;
            IProduct product = Platform.getProduct();
            if (product != null) {
                productName = product.getName();
            }
            if (productName == null) {
                message = IDEWorkbenchMessages.PromptOnExitDialog_message0;
            } else {
                message = NLS.bind(IDEWorkbenchMessages.PromptOnExitDialog_message1, productName);
            }

            MessageDialogWithToggle dlg = MessageDialogWithToggle
                    .openOkCancelConfirm(getWindowConfigurer().getWindow()
                            .getShell(), IDEWorkbenchMessages.PromptOnExitDialog_shellTitle,
                            message, IDEWorkbenchMessages.PromptOnExitDialog_choice,
                            false, null, null);
            if (dlg.getReturnCode() != IDialogConstants.OK_ID) {
                return false;
            }
            if (dlg.getToggleState()) {
                store
                        .setValue(
                                IDEInternalPreferences.EXIT_PROMPT_ON_CLOSE_LAST_WINDOW,
                                false);
                IDEWorkbenchPlugin.getDefault().savePluginPreferences();
            }
        }

        return true;
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.application.WorkbenchAdvisor#preWindowOpen
     */
    public void preWindowOpen() {
        IWorkbenchWindowConfigurer configurer = getWindowConfigurer();

        // show the shortcut bar and progress indicator, which are hidden by default
        configurer.setShowPerspectiveBar(true);
        configurer.setShowFastViewBars(true);
        configurer.setShowProgressIndicator(true);

        // add the drag and drop support for the editor area
        configurer.addEditorAreaTransfer(EditorInputTransfer
                .getInstance());
        configurer.addEditorAreaTransfer(ResourceTransfer.getInstance());
        configurer.addEditorAreaTransfer(MarkerTransfer.getInstance());
        configurer
                .configureEditorAreaDropListener(new EditorAreaDropAdapter(
                        configurer.getWindow()));

        hookTitleUpdateListeners(configurer);
    }

    /**
     * Hooks the listeners needed on the window
     * @param configurer
     */
    private void hookTitleUpdateListeners(IWorkbenchWindowConfigurer configurer) {
        // hook up the listeners to update the window title
        configurer.getWindow().addPageListener(new IPageListener() {
            public void pageActivated(IWorkbenchPage page) {
                updateTitle();
            }

            public void pageClosed(IWorkbenchPage page) {
                updateTitle();
            }

            public void pageOpened(IWorkbenchPage page) {
                // do nothing
            }
        });
        configurer.getWindow().addPerspectiveListener(
                new PerspectiveAdapter() {
                    public void perspectiveActivated(IWorkbenchPage page,
                            IPerspectiveDescriptor perspective) {
                        updateTitle();
                    }
					public void perspectiveSavedAs(IWorkbenchPage page,IPerspectiveDescriptor oldPerspective,IPerspectiveDescriptor newPerspective){
						updateTitle();
					}
                    public void perspectiveDeactivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
                        updateTitle();
                    }
                });
        configurer.getWindow().getPartService().addPartListener(
                new IPartListener2() {
                    public void partActivated(IWorkbenchPartReference ref) {
                        if (ref instanceof IEditorReference) {
                            updateTitle();
                        }
                    }

                    public void partBroughtToTop(IWorkbenchPartReference ref) {
                        if (ref instanceof IEditorReference) {
                            updateTitle();
                        }
                    }

                    public void partClosed(IWorkbenchPartReference ref) {
						updateTitle();
                    }

                    public void partDeactivated(IWorkbenchPartReference ref) {
                        // do nothing
                    }

                    public void partOpened(IWorkbenchPartReference ref) {
                        // do nothing
                    }

                    public void partHidden(IWorkbenchPartReference ref) {
                        // do nothing
                    }

                    public void partVisible(IWorkbenchPartReference ref) {
                        // do nothing
                    }

                    public void partInputChanged(IWorkbenchPartReference ref) {
                        // do nothing
                    }
                });
    } 

    private String computeTitle() {
        IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
        IWorkbenchPage currentPage = configurer.getWindow().getActivePage();
        IEditorPart activeEditor = null;
        if (currentPage != null) {
            activeEditor = currentPage.getActiveEditor();
        }
        
        String title = null;
        IProduct product = Platform.getProduct();
        if (product != null) {
            title = product.getName();
        }
        if (title == null) {
            title = ""; //$NON-NLS-1$
        }

        if (currentPage != null) {
            if (activeEditor != null) {
                lastEditorTitle = activeEditor.getTitle();
                title = NLS.bind(IDEWorkbenchMessages.WorkbenchWindow_shellTitle, lastEditorTitle, title);
            }
            IPerspectiveDescriptor persp = currentPage.getPerspective();
            String label = ""; //$NON-NLS-1$
            if (persp != null)
                label = persp.getLabel();
            IAdaptable input = currentPage.getInput();
            if (input != null && !input.equals(wbAdvisor.getDefaultPageInput())) {
                label = currentPage.getLabel();
            }
            if (label != null && !label.equals("")) { //$NON-NLS-1$ 
                title = NLS.bind(IDEWorkbenchMessages.WorkbenchWindow_shellTitle, label, title);
            }
        }

        String workspaceLocation = wbAdvisor.getWorkspaceLocation();
        if (workspaceLocation != null) {
            title = NLS.bind(IDEWorkbenchMessages.WorkbenchWindow_shellTitle, title, workspaceLocation);
        }
        
        return title;        
    }
    
    private void recomputeTitle() {
        IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
        String oldTitle = configurer.getTitle();
        String newTitle = computeTitle();
        if (!newTitle.equals(oldTitle)) {
            configurer.setTitle(newTitle);
        }
    }
        
    /**
     * Updates the window title. Format will be:
     * [pageInput -] [currentPerspective -] [editorInput -] [workspaceLocation -] productName
     */
    private void updateTitle() {
        IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
        IWorkbenchWindow window = configurer.getWindow();
        IEditorPart activeEditor = null;
        IWorkbenchPage currentPage = window.getActivePage();
        IPerspectiveDescriptor persp = null;
        IAdaptable input = null;
        
        if (currentPage != null) {
            activeEditor = currentPage.getActiveEditor();
            persp = currentPage.getPerspective();
            input = currentPage.getInput();
        }
        
        // Nothing to do if the editor hasn't changed
        if (activeEditor == lastActiveEditor && currentPage == lastActivePage 
                && persp == lastPerspective && input == lastInput) {
            return;
        }
        
        if (lastActiveEditor != null) {
            lastActiveEditor.removePropertyListener(editorPropertyListener );
        }
        
        lastActiveEditor = activeEditor;
        lastActivePage = currentPage;
        lastPerspective = persp;
        lastInput = input;
        
        if (activeEditor != null) {
            activeEditor.addPropertyListener(editorPropertyListener);
        }

        recomputeTitle();
    }

    
    /* (non-Javadoc)
     * @see org.eclipse.ui.application.WorkbenchAdvisor#postWindowRestore
     */
    public void postWindowRestore()
            throws WorkbenchException {
        IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
        IWorkbenchWindow window = configurer.getWindow();
        
        int index = getWorkbench().getWorkbenchWindowCount() - 1;

        AboutInfo[] welcomePerspectiveInfos = wbAdvisor.getWelcomePerspectiveInfos(); 
        if (index >= 0 && welcomePerspectiveInfos != null
                && index < welcomePerspectiveInfos.length) {
            // find a page that exist in the window
            IWorkbenchPage page = window.getActivePage();
            if (page == null) {
                IWorkbenchPage[] pages = window.getPages();
                if (pages != null && pages.length > 0)
                    page = pages[0];
            }

            // if the window does not contain a page, create one
            String perspectiveId = welcomePerspectiveInfos[index].getWelcomePerspectiveId();
            if (page == null) {
                IAdaptable root = wbAdvisor.getDefaultPageInput();
                page = window.openPage(perspectiveId,
                        root);
            } else {
                IPerspectiveRegistry reg = getWorkbench()
                        .getPerspectiveRegistry();
                IPerspectiveDescriptor desc = reg
                        .findPerspectiveWithId(perspectiveId);
                if (desc != null) {
                    page.setPerspective(desc);
                }
            }

            // set the active page and open the welcome editor
            window.setActivePage(page);
            page.openEditor(new WelcomeEditorInput(
                    welcomePerspectiveInfos[index]),
                    WELCOME_EDITOR_ID, true);
        }
    }

    /**
     * Tries to open the intro, if one exists and otherwise will open the legacy 
     * Welcome pages.
     * 
     * @see org.eclipse.ui.application.WorkbenchWindowAdvisor#openIntro()
     */
    public void openIntro() {
        if (editorsAndIntrosOpened )
            return;

        editorsAndIntrosOpened = true;

        // don't try to open the welcome editors if there is an intro
        if (wbAdvisor.hasIntro())
            super.openIntro();
        else {
            openWelcomeEditors(getWindowConfigurer().getWindow());
            // save any preferences changes caused by the above actions
            IDEWorkbenchPlugin.getDefault().savePluginPreferences();
        }
    }

    /*
     * Open the welcome editor for the primary feature and
     * for any newly installed features.
     */
    private void openWelcomeEditors(IWorkbenchWindow window) {
        if (IDEWorkbenchPlugin.getDefault().getPreferenceStore().getBoolean(
                IDEInternalPreferences.WELCOME_DIALOG)) {
            // show the welcome page for the product the first time the workbench opens
            IProduct product = Platform.getProduct();
            if (product == null)
                return;

            AboutInfo productInfo = new AboutInfo(product);
            URL url = productInfo.getWelcomePageURL();
            if (url == null)
                return;

            IDEWorkbenchPlugin.getDefault().getPreferenceStore().setValue(
                    IDEInternalPreferences.WELCOME_DIALOG, false);
            openWelcomeEditor(window, new WelcomeEditorInput(productInfo), null);
        } else {
            // Show the welcome page for any newly installed features
            List welcomeFeatures = new ArrayList();
            for (Iterator it = wbAdvisor.getNewlyAddedBundleGroups().entrySet()
                    .iterator(); it.hasNext();) {
                Map.Entry entry = (Map.Entry) it.next();
                String versionedId = (String) entry.getKey();
                String featureId = versionedId.substring(0, versionedId
                        .indexOf(':'));
                AboutInfo info = (AboutInfo) entry.getValue();

                if (info != null && info.getWelcomePageURL() != null) {
                    welcomeFeatures.add(info);
                    // activate the feature plug-in so it can run some install code
                    IPlatformConfiguration platformConfiguration = ConfiguratorUtils
                            .getCurrentPlatformConfiguration();
                    IPlatformConfiguration.IFeatureEntry feature = platformConfiguration
                            .findConfiguredFeatureEntry(featureId);
                    if (feature != null) {
                        String pi = feature.getFeaturePluginIdentifier();
                        if (pi != null) {
                            //Start the bundle if there is one
                            Bundle bundle = Platform.getBundle(pi);
                            if(bundle != null)
                                try{
                                    bundle.start();
                                }
                                catch(BundleException exception){
                                    IDEWorkbenchPlugin.log("Failed to load feature", exception);//$NON-NLS-1$
                                }
                        }
                    }
                }
            }

            int wCount = getWorkbench().getWorkbenchWindowCount();
            for (int i = 0; i < welcomeFeatures.size(); i++) {
                AboutInfo newInfo = (AboutInfo) welcomeFeatures.get(i);
                String id = newInfo.getWelcomePerspectiveId();
                // Other editors were already opened in postWindowRestore(..)
                if (id == null || i >= wCount) {
                    openWelcomeEditor(window, new WelcomeEditorInput(newInfo),
                            id);
                }
            }
        }
    }

    /**
     * Open a welcome editor for the given input
     */
    private void openWelcomeEditor(IWorkbenchWindow window,
            WelcomeEditorInput input, String perspectiveId) {
        if (getWorkbench().getWorkbenchWindowCount() == 0) {
            // Something is wrong, there should be at least
            // one workbench window open by now.
            return;
        }

        IWorkbenchWindow win = window;
        if (perspectiveId != null) {
            try {
                win = getWorkbench().openWorkbenchWindow(perspectiveId,
                        wbAdvisor.getDefaultPageInput());
                if (win == null) {
                    win = window;
                }
            } catch (WorkbenchException e) {
                IDEWorkbenchPlugin
                        .log(
                                "Error opening window with welcome perspective.", e.getStatus()); //$NON-NLS-1$
                return;
            }
        }

        if (win == null) {
            win = getWorkbench().getWorkbenchWindows()[0];
        }

        IWorkbenchPage page = win.getActivePage();
        String id = perspectiveId;
        if (id == null) {
            id = getWorkbench().getPerspectiveRegistry()
                    .getDefaultPerspective();
        }

        if (page == null) {
            try {
                page = win.openPage(id, wbAdvisor.getDefaultPageInput());
            } catch (WorkbenchException e) {
                ErrorDialog.openError(win.getShell(), IDEWorkbenchMessages.Problems_Opening_Page,
                        e.getMessage(), e.getStatus());
            }
        }
        if (page == null)
            return;

        if (page.getPerspective() == null) {
            try {
                page = getWorkbench().showPerspective(id, win);
            } catch (WorkbenchException e) {
                ErrorDialog
                        .openError(
                                win.getShell(),
                                IDEWorkbenchMessages.Workbench_openEditorErrorDialogTitle,
                                IDEWorkbenchMessages.Workbench_openEditorErrorDialogMessage,
                                e.getStatus());
                return;
            }
        }

        page.setEditorAreaVisible(true);

        // see if we already have an editor
        IEditorPart editor = page.findEditor(input);
        if (editor != null) {
            page.activate(editor);
            return;
        }

        try {
            page.openEditor(input, WELCOME_EDITOR_ID);
        } catch (PartInitException e) {
            ErrorDialog
                    .openError(
                            win.getShell(),
                            IDEWorkbenchMessages.Workbench_openEditorErrorDialogTitle,
                            IDEWorkbenchMessages.Workbench_openEditorErrorDialogMessage,
                            e.getStatus());
        }
        return;
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.application.WorkbenchAdvisor#createEmptyWindowContents(org.eclipse.ui.application.IWorkbenchWindowConfigurer, org.eclipse.swt.widgets.Composite)
     */
    public Control createEmptyWindowContents(Composite parent) {
        final IWorkbenchWindow window = getWindowConfigurer().getWindow();
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setLayout(new GridLayout(2, false));
        Display display = composite.getDisplay();
        Color bgCol = display.getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND);
        composite.setBackground(bgCol);
        Label label = new Label(composite, SWT.WRAP);
        label.setForeground(display.getSystemColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND));
        label.setBackground(bgCol);
        label.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
        String msg = IDEWorkbenchMessages.IDEWorkbenchAdvisor_noPerspective;
        label.setText(msg);
        ToolBarManager toolBarManager = new ToolBarManager();
        // TODO: should obtain the open perspective action from ActionFactory
        IAction openPerspectiveAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG.create(window);
        toolBarManager.add(openPerspectiveAction);
        ToolBar toolBar = toolBarManager.createControl(composite);
        toolBar.setBackground(bgCol);
        return composite;
    }

}
