/*******************************************************************************
 * Copyright (c) 2004, 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.intro.impl.presentations;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Map;
import java.util.Properties;

import org.eclipse.core.runtime.IRegistryChangeEvent;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.ProgressEvent;
import org.eclipse.swt.browser.ProgressListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.internal.intro.impl.IIntroConstants;
import org.eclipse.ui.internal.intro.impl.IntroPlugin;
import org.eclipse.ui.internal.intro.impl.Messages;
import org.eclipse.ui.internal.intro.impl.html.HTMLElement;
import org.eclipse.ui.internal.intro.impl.html.IIntroHTMLConstants;
import org.eclipse.ui.internal.intro.impl.html.IntroHTMLGenerator;
import org.eclipse.ui.internal.intro.impl.model.AbstractIntroPage;
import org.eclipse.ui.internal.intro.impl.model.AbstractIntroPartImplementation;
import org.eclipse.ui.internal.intro.impl.model.History;
import org.eclipse.ui.internal.intro.impl.model.IntroContentProvider;
import org.eclipse.ui.internal.intro.impl.model.IntroHomePage;
import org.eclipse.ui.internal.intro.impl.model.IntroModelRoot;
import org.eclipse.ui.internal.intro.impl.model.loader.ContentProviderManager;
import org.eclipse.ui.internal.intro.impl.model.loader.IntroContentParser;
import org.eclipse.ui.internal.intro.impl.model.util.ModelUtil;
import org.eclipse.ui.internal.intro.impl.util.Log;
import org.eclipse.ui.internal.intro.impl.util.Util;
import org.eclipse.ui.intro.config.IIntroContentProvider;
import org.eclipse.ui.intro.config.IIntroContentProviderSite;
import org.eclipse.ui.intro.config.IIntroXHTMLContentProvider;
import org.eclipse.ui.intro.config.IntroConfigurer;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class BrowserIntroPartImplementation extends
        AbstractIntroPartImplementation implements IPropertyListener,
        IIntroContentProviderSite {
 

    // the browser widget that will display the intro content 
    protected Browser browser = null;

    // the HTML generator used to generate dynamic content
    private IntroHTMLGenerator htmlGenerator = null;

    protected BrowserIntroPartLocationListener urlListener = new BrowserIntroPartLocationListener(
        this);


    protected void updateNavigationActionsState() {
        if (getModel().isDynamic()) {
            forwardAction.setEnabled(history.canNavigateForward());
            backAction.setEnabled(history.canNavigateBackward());
            return;
        }

        // in static html intro, use browser history.
        forwardAction.setEnabled(browser.isForwardEnabled());
        backAction.setEnabled(browser.isBackEnabled());
    }


    /**
     * create the browser and set it's contents
     */
    public void createPartControl(Composite parent) {
        long start = 0;
        if (Log.logPerformance)
            start = System.currentTimeMillis();

        browser = new Browser(parent, SWT.NONE);

        // add a location listener on the browser so we can intercept
        // LocationEvents. Responsible for intercepting URLs and updating UI
        // with history.
        browser.addLocationListener(urlListener);

        // add a location listener that will clear a flag at the end of any
        // navigation to a page. This is used in conjunction with the location
        // listener to filter out redundant navigations due to frames.
        browser.addProgressListener(new ProgressListener() {

            public void changed(ProgressEvent event) {
                // no-op
            }

            public void completed(ProgressEvent event) {
                urlListener.flagEndOfNavigation();
                urlListener.flagEndOfFrameNavigation();
                urlListener.flagRemovedTempUrl();
                if (!getModel().isDynamic())
                    updateNavigationActionsState();
            }
        });

        // Enable IE pop-up menu only in debug mode.
        browser.addListener(SWT.MenuDetect, new Listener() {

            public void handleEvent(Event event) {
                if (IntroPlugin.getDefault().isDebugging())
                    event.doit = true;
                else
                    event.doit = false;
            }
        });

        // if we are logging performance, log actual UI creation time for
        // browser.
        if (Log.logPerformance)
            Util.logPerformanceTime("creating a new Browser() took:", start); //$NON-NLS-1$

        addToolBarActions();

        if (!getModel().hasValidConfig()) {
            browser.setText(Messages.Browser_invalidConfig);
            return;
        }
        
         // root page is what decides if the model is dynamic or not.
        if (getModel().isDynamic())
            handleDynamicIntro();
        else
            handleStaticIntro();
    }



    private void handleDynamicIntro() {
        IntroHomePage homePage = getModel().getHomePage();
        // check cache state, and populate url page if needed.
        String cachedPage = getCachedCurrentPage();
        if (cachedPage != null) {
            // we have a cached state. handle appropriately
            if (History.isURL(cachedPage)) {
                // set the URL the browser should display
                boolean success = browser.setUrl(cachedPage);
                if (!success) {
                    Log.error("Unable to set the following ULR in browser: " //$NON-NLS-1$
                            + cachedPage, null);
                    return;
                }
                history.updateHistory(cachedPage);
            } else {
                // Generate HTML for the cached page, and set it on the browser.
                getModel().setCurrentPageId(cachedPage, false);
                // generateDynamicContentForPage(getModel().getCurrentPage());
                history.updateHistory(getModel().getCurrentPage());
            }

        } else {
            // No cached page. Generate HTML for the home page, and set it
            // on the browser.
            // generateDynamicContentForPage(homePage);
            history.updateHistory(homePage);
        }
        // INTRO: all setText calls above are commented out because calling
        // setText twice causes problems. revisit when swt bug is fixed.

        // Add this presentation as a listener to model
        // only in dynamic case, for now.
        getModel().addPropertyListener(this);
    }


    /**
     * Generate dynamic HTML for the provided page, and set it in the browser
     * widget. A cache is used for performance and for having a correct dynamic
     * content life cycle. This method also updates the navigation history.
     * 
     * @param page
     *            the page to generate HTML for
     */
    private boolean generateDynamicContentForPage(AbstractIntroPage page) {
        String content = null;

        if (page.isXHTMLPage())
            content = generateXHTMLPage(page, this);
        else {
            HTMLElement html = getHTMLGenerator().generateHTMLforPage(page,
                this);
            if (html != null) {
            	IntroModelRoot root = getModel();
            	if (root!=null) {
            		Map props = root.getTheme()!=null?root.getTheme().getProperties():null;
            		if (props!=null) {
            			String value = (String)props.get("standardSupport"); //$NON-NLS-1$
            			String doctype=null;
            			if ("strict".equalsIgnoreCase(value)) //$NON-NLS-1$
            				doctype = generateDoctype(true);
            			else if ("loose".equalsIgnoreCase(value)) //$NON-NLS-1$
            				doctype = generateDoctype(false);
            			if (doctype!=null)
            				content = doctype+html.toString();
            		}
            	}
            	if (content==null)
            		content = html.toString();
            }
        }


        if (content == null) {
            // there was an error generating the html. log an error
            Log.error("Error generating HTML content for page", null); //$NON-NLS-1$
            return false;
        }

        // set the browser's HTML.
        boolean success = false;
        if (browser != null) {
            long start = 0;
            if (Log.logPerformance)
                start = System.currentTimeMillis();
            success = browser.setText(content);
            if (Log.logPerformance)
                Util
                    .logPerformanceTime("setText() on the browser took:", start); //$NON-NLS-1$

            if (!success)
                Log.error("Unable to set HTML on the browser", null); //$NON-NLS-1$
        }


        // print the HTML if we are in debug mode and have tracing turned on
        if (IntroPlugin.getDefault().isDebugging()) {
            String printHtml = Platform
                .getDebugOption("org.eclipse.ui.intro/trace/printHTML"); //$NON-NLS-1$
            if (printHtml != null && printHtml.equalsIgnoreCase("true")) { //$NON-NLS-1$
                System.out.println(content);
            }
        }
        return success;
    }

    /**
     * Generate an XHTML page as a string.
     * <ul>
     * <li> Create any dynamic content providers, if there are any. We do this
     * by replacing each content provider with a div with the same id. The div
     * is the parent of the dynamic content.</li>
     * <li>Use xslt to flatten the DOM for the page, and create a string.</li>
     * <li>Re-inject the contentProviders into the DOM to recreate the original
     * state of the DOM. DOM could not have been cloned since cloning a DOM
     * removes the docType.</li>
     * </ul>
     * Note: Resolving dynamic content is done at the UI level, consistant with
     * SWT presentation.
     */
    public String generateXHTMLPage(AbstractIntroPage page,
            IIntroContentProviderSite site) {
        // get/cache all content provider elements in DOM.
        Document dom = page.getResolvedDocument();
        NodeList nodes = dom.getElementsByTagNameNS("*", //$NON-NLS-1$
            IntroContentProvider.TAG_CONTENT_PROVIDER);
        // get the array version of the nodelist to work around DOM api design.
        Node[] contentProviderElements = ModelUtil.getArray(nodes);

        // this modifies the DOM.
        resolveDynamicContent(page, site);
        String content = IntroContentParser.convertToString(dom);

        // this restores the DOM to its original state.
        reinjectDynamicContent(dom, contentProviderElements);
        return content;
    }
    
    private String generateDoctype(boolean strict) {
    	StringWriter swriter = new StringWriter();
    	PrintWriter writer = new PrintWriter(swriter);
    	if (strict) {
    		writer.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\""); //$NON-NLS-1$
    		writer.println("\t\t\t\"http://www.w3.org/TR/html4/strict.dtd\">"); //$NON-NLS-1$
    	}
    	else {
    		writer.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\""); //$NON-NLS-1$
    		writer.println("\t\t\t\"http://www.w3.org/TR/html4/loose.dtd\">"); //$NON-NLS-1$    		
    	}
    	writer.close();
    	return swriter.toString();
    }

    /**
     * Resolve the dynamic content in the page. Resolving dynamic content will
     * alter the original page DOM. Dynamic content tags are removed once
     * resolved to have clean xhtml.
     */
    private Document resolveDynamicContent(AbstractIntroPage page,
            IIntroContentProviderSite site) {
        Document dom = page.getResolvedDocument();

        // get all content provider elements in DOM.
        NodeList contentProviders = dom.getElementsByTagNameNS("*", //$NON-NLS-1$
            IntroContentProvider.TAG_CONTENT_PROVIDER);

        // get the array version of the nodelist to work around DOM api design.
        Node[] nodes = ModelUtil.getArray(contentProviders);
        for (int i = 0; i < nodes.length; i++) {
            Element contentProviderElement = (Element) nodes[i];
            IntroContentProvider provider = new IntroContentProvider(
                contentProviderElement, page.getBundle());
            provider.setParent(page);
            // If we've already loaded the content provider for this element,
            // retrieve it, otherwise load the class.
            IIntroXHTMLContentProvider providerClass = (IIntroXHTMLContentProvider) ContentProviderManager
                .getInst().getContentProvider(provider);
            if (providerClass == null)
                // content provider never created before, create it.
                providerClass = (IIntroXHTMLContentProvider) ContentProviderManager
                    .getInst().createContentProvider(provider, site);

            if (providerClass != null) {
                // create a div with the same id as the contentProvider, pass it
                // as the parent to create the specialized content, and then
                // replace the contentProvider element with this div.
                Properties att = new Properties();
                att.setProperty(IIntroHTMLConstants.ATTRIBUTE_ID, provider
                    .getId());
                Element contentDiv = ModelUtil.createElement(dom,
                    ModelUtil.TAG_DIV, att);
                providerClass.createContent(provider.getId(), contentDiv);

                contentProviderElement.getParentNode().replaceChild(contentDiv,
                    contentProviderElement);
            } else {
                // we couldn't load the content provider, so add any alternate
                // text content if there is any.
                // INTRO: do it. 3.0 intro content style uses text element as
                // alt text. We can load XHTML content here.
            }
        }
        return dom;
    }


    private void reinjectDynamicContent(Document dom,
            Node[] contentProviderElements) {
        for (int i = 0; i < contentProviderElements.length; i++) {
            // for each cached contentProvider, find replacement div in DOM and
            // re-subsitute.
            Element contentProviderElement = (Element) contentProviderElements[i];
            Element contentProviderDiv = ModelUtil.getElementById(dom,
                contentProviderElement
                    .getAttribute(IIntroHTMLConstants.ATTRIBUTE_ID),
                ModelUtil.TAG_DIV);
            contentProviderDiv.getParentNode().replaceChild(
                contentProviderElement, contentProviderDiv);
        }
    }



    /**
     * Return the cached IntroHTMLGenerator
     * 
     * @return
     */
    private IntroHTMLGenerator getHTMLGenerator() {
        if (htmlGenerator == null)
            htmlGenerator = new IntroHTMLGenerator();

        return htmlGenerator;
    }

    protected void addToolBarActions() {
        // Handle menus:
        IActionBars actionBars = getIntroPart().getIntroSite().getActionBars();
        IToolBarManager toolBarManager = actionBars.getToolBarManager();
        actionBars.setGlobalActionHandler(ActionFactory.FORWARD.getId(),
            forwardAction);
        actionBars.setGlobalActionHandler(ActionFactory.BACK.getId(),
            backAction);
        toolBarManager.add(new Separator(IntroConfigurer.TB_ADDITIONS));
        toolBarManager.add(homeAction);
        toolBarManager.add(backAction);
        toolBarManager.add(forwardAction);
        toolBarManager.update(true);
        actionBars.updateActionBars();
        updateNavigationActionsState();
    }

    public void dynamicStandbyStateChanged(boolean standby,
            boolean isStandbyPartNeeded) {

        if (isStandbyPartNeeded)
            // we have a standby part, nothing more to do in presentation.
            return;

        if (history.currentLocationIsUrl())
            // last page disaplyed was a url. It is already set in the browser
            // and stored in history. Nothing more to do.
            return;



        // presentation is shown here. toggle standby page. No need to update
        // history here.
        IntroHomePage homePage = getModel().getHomePage();
        IntroHomePage standbyPage = getModel().getStandbyPage();
        if (standbyPage == null)
            standbyPage = homePage;

        if (standby) {
            generateDynamicContentForPage(standbyPage);
        } else {
            // REVISIT: If cached page is the standby page and we are not
            // initially in standby mode, it means standby was forced on
            // intro view on close. react.
            if (getModel().getCurrentPage().equals(standbyPage.getId()))
                getModel().setCurrentPageId(getModel().getHomePage().getId());
            generateDynamicContentForPage(getModel().getCurrentPage());
        }
    }



    /**
     * Handle model property changes. Property listeners are only added in the
     * dynamic case.
     * 
     * @see org.eclipse.ui.IPropertyListener#propertyChanged(java.lang.Object,
     *      int)
     */
    public void propertyChanged(Object source, int propId) {
        if (propId == IntroModelRoot.CURRENT_PAGE_PROPERTY_ID) {
            String pageId = getModel().getCurrentPageId();
            if (pageId == null || pageId.equals("")) //$NON-NLS-1$
                // page ID was not set properly. exit.
                return;
            // update the presentation's content based on the model changes
            updateContent();
        }
    }

    public void setFocus() {
        browser.setFocus();
    }

    public void dispose() {
        browser.dispose();
    }

    /**
     * Regenerate the dynamic content for the current page
     */
    protected void updateContent() {
        generateDynamicContentForPage(getModel().getCurrentPage());
    }

    /**
     * 
     * @see org.eclipse.ui.internal.intro.impl.model.AbstractIntroPartImplementation#reflow()
     */
    public void reflow(IIntroContentProvider provider, boolean incremental) {
        updateContent();
    }

    /**
     * Override parent behavior to handle the case when we have a static page.
     * This can happen in both the static intro case, or in the dynamic when the
     * last visited page is the dynamic browser is an http: page, and not an
     * intro page.
     */
    protected void saveCurrentPage(IMemento memento) {
        if (memento == null)
            return;
        // Handle the case where we are on a static page.
        // browser.getURL() returns the empty string if there is no current URL
        // and returns "about:blank" if we are on a dynamic page
        if (browser != null && browser.getUrl() != null
                && browser.getUrl().length() > 0
                && !(browser.getUrl().equals("about:blank")) //$NON-NLS-1$
                && !(browser.getUrl().equals("file:///"))) { //$NON-NLS-1$

            String currentURL = browser.getUrl();
            if (currentURL != null) {
                memento.putString(IIntroConstants.MEMENTO_CURRENT_PAGE_ATT,
                    currentURL);
            }
        } else {
            super.saveCurrentPage(memento);
        }
    }


    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.internal.intro.impl.model.AbstractIntroPartImplementation#navigateBackward()
     */
    public boolean navigateBackward() {
        boolean success = false;
        if (getModel().isDynamic()) {
            // dynamic case. Uses navigation history.
            if (history.canNavigateBackward()) {
                history.navigateHistoryBackward();
                // guard against unnecessary History updates.
                urlListener.flagStartOfNavigation();
                if (history.currentLocationIsUrl()) {
                    success = browser.setUrl(history.getCurrentLocationAsUrl());
                } else {
                    // we need to regen HTML. We can not use setting current
                    // page to trigger regen for one case: navigating back from
                    // a url will not trigger regen since current page would be
                    // the same.
                    AbstractIntroPage page = history.getCurrentLocationAsPage();
                    success = generateDynamicContentForPage(page);
                    getModel().setCurrentPageId(page.getId(), false);
                }
            } else
                success = false;
            // update history only in dynamic case.
            updateNavigationActionsState();
        } else
            // static HTML case. use browser real Back.
            success = browser.back();

        return success;
    }


    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.internal.intro.impl.model.AbstractIntroPartImplementation#navigateForward()
     */
    public boolean navigateForward() {
        boolean success = false;
        if (getModel().isDynamic()) {
            // dynamic case. Uses navigation history.
            if (history.canNavigateForward()) {
                history.navigateHistoryForward();
                // guard against unnecessary History updates.
                urlListener.flagStartOfNavigation();
                if (history.currentLocationIsUrl()) {
                    success = browser.setUrl(history.getCurrentLocationAsUrl());
                } else {
                    AbstractIntroPage page = history.getCurrentLocationAsPage();
                    success = generateDynamicContentForPage(page);
                    getModel().setCurrentPageId(page.getId(), false);
                }
            } else
                success = false;
            // update history only in dynamic case.
            updateNavigationActionsState();
        } else
            // static HTML case. use browser real Forward.
            success = browser.forward();

        return success;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.internal.intro.impl.model.AbstractIntroPartImplementation#navigateHome()
     */
    public boolean navigateHome() {
        // Home is URL of root page in static case, and root page in
        // dynamic.
        IntroHomePage rootPage = getModel().getHomePage();
        boolean success = false;
        if (getModel().isDynamic()) {
            // special case for when workbench is started with a cached URL. We
            // set the url in the browser, but current page is Home Page, and so
            // setting the root page will not fire an event. So, force a
            // generation
            // of root page.
            if (history.currentLocationIsUrl())
                generateDynamicContentForPage(rootPage);

            success = getModel().setCurrentPageId(rootPage.getId());
            updateHistory(rootPage);

        } else {
            String location = rootPage.getUrl();
            success = browser.setUrl(location);
            updateHistory(location);
        }

        return success;
    }



    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.internal.intro.impl.model.AbstractIntroPartImplementation#handleRegistryChanged(org.eclipse.core.runtime.IRegistryChangeEvent)
     */
    protected void handleRegistryChanged(IRegistryChangeEvent event) {
        if (getModel().isDynamic()) {
            // null generator first.
            htmlGenerator = null;
            // Add this presentation as a listener to model only in dynamic
            // case.
            getModel().addPropertyListener(this);
            getModel().firePropertyChange(
                IntroModelRoot.CURRENT_PAGE_PROPERTY_ID);
        }
    }


    protected void doStandbyStateChanged(boolean standby,
            boolean isStandbyPartNeeded) {
        // if we have a standby part, regardless if standby state, disable
        // actions. Same behavior for static html.
        if (isStandbyPartNeeded | standby) {
            homeAction.setEnabled(false);
            forwardAction.setEnabled(false);
            backAction.setEnabled(false);
        } else {
            homeAction.setEnabled(true);
            updateNavigationActionsState();
        }

        if (getModel().isDynamic())
            dynamicStandbyStateChanged(standby, isStandbyPartNeeded);
        else
            staticStandbyStateChanged(standby);
    }



    // ***************** Static Intro *****************
    private void handleStaticIntro() {
        // We have a static case. Set the url on the browser to be the url
        // defined in the root page. But first check memento if we can
        // restore last visited page.
        String url = getCachedCurrentPage();
        if (!History.isURL(url))
            // no cached state, or invalid state.
            url = getModel().getHomePage().getUrl();

        if (url == null) {
            // We have no content to display. log an error
            Log.error("Url is null; no content to display in browser", null); //$NON-NLS-1$
            return;
        }
        // set the URL the browser should display
        boolean success = browser.setUrl(url);
        if (!success) {
            Log.error("Unable to set the following ULR in browser: " + url, //$NON-NLS-1$
                null);
            return;
        }
    }

    public void staticStandbyStateChanged(boolean standby) {
        IntroHomePage homePage = getModel().getHomePage();
        IntroHomePage standbyPage = getModel().getStandbyPage();
        if (standbyPage == null)
            standbyPage = homePage;

        if (standby)
            browser.setUrl(standbyPage.getUrl());
        else
            browser.setUrl(homePage.getUrl());
    }


    public Browser getBrowser() {
        return browser;
    }




}