/*******************************************************************************
 * Copyright (c) 2000, 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.dialogs;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * A parser for the the welcome page
 */
public class WelcomeParser extends DefaultHandler {
    private static final String TAG_WELCOME_PAGE = "welcomePage"; //$NON-NLS-1$	

    private static final String TAG_INTRO = "intro"; //$NON-NLS-1$	

    private static final String TAG_ITEM = "item"; //$NON-NLS-1$	

    private static final String TAG_BOLD = "b"; //$NON-NLS-1$	

    private static final String TAG_ACTION = "action"; //$NON-NLS-1$	

    private static final String TAG_PARAGRAPH = "p"; //$NON-NLS-1$	

    private static final String TAG_TOPIC = "topic"; //$NON-NLS-1$	

    private static final String ATT_TITLE = "title"; //$NON-NLS-1$	

    private static final String ATT_FORMAT = "format"; //$NON-NLS-1$	

    private static final String ATT_PLUGIN_ID = "pluginId"; //$NON-NLS-1$	

    private static final String ATT_CLASS = "class"; //$NON-NLS-1$	

    private static final String ATT_ID = "id"; //$NON-NLS-1$

    private static final String ATT_HREF = "href"; //$NON-NLS-1$

    private static final String FORMAT_WRAP = "wrap"; //$NON-NLS-1$

    private static final char DELIMITER = '\n'; // sax parser replaces crlf with lf

    private SAXParser parser;

    private String title;

    private WelcomeItem introItem;

    private ArrayList items = new ArrayList();

    private String format;

    private class WelcomeContentHandler implements ContentHandler {
        protected ContentHandler parent;

        public void setParent(ContentHandler p) {
            parent = p;
        }

        public void characters(char[] ch, int start, int length)
                throws SAXException {
        }

        public void endDocument() throws SAXException {
        }

        public void endElement(String namespaceURI, String localName,
                String qName) throws SAXException {
        }

        public void endPrefixMapping(String prefix) throws SAXException {
        }

        public void ignorableWhitespace(char[] ch, int start, int length)
                throws SAXException {
        }

        public void processingInstruction(String target, String data)
                throws SAXException {
        }

        public void setDocumentLocator(Locator locator) {
        }

        public void skippedEntity(String name) throws SAXException {
        }

        public void startDocument() throws SAXException {
        }

        public void startElement(String namespaceURI, String localName,
                String qName, Attributes atts) throws SAXException {
        }

        public void startPrefixMapping(String prefix, String uri)
                throws SAXException {
        }
    }

    private class WelcomePageHandler extends WelcomeContentHandler {
        public WelcomePageHandler(String newTitle) {
            title = newTitle;
        }

        public void startElement(String namespaceURI, String localName,
                String qName, Attributes atts) throws SAXException {
            if (localName.equals(TAG_INTRO)) {
                ItemHandler h = new IntroItemHandler();
                h.setParent(WelcomePageHandler.this);
                parser.getXMLReader().setContentHandler(h);
            } else if (localName.equals(TAG_ITEM)) {
                ItemHandler h = new ItemHandler();
                h.setParent(WelcomePageHandler.this);
                parser.getXMLReader().setContentHandler(h);
            }
        }
    }

    private class ItemHandler extends WelcomeContentHandler {
        private ArrayList boldRanges = new ArrayList();

        protected ArrayList wrapRanges = new ArrayList();

        private ArrayList actionRanges = new ArrayList();

        private ArrayList pluginIds = new ArrayList();

        private ArrayList classes = new ArrayList();

        private ArrayList helpRanges = new ArrayList();

        private ArrayList helpIds = new ArrayList();

        private ArrayList helpHrefs = new ArrayList();

        private StringBuffer text = new StringBuffer();

        protected int offset = 0;

        protected int textStart;

        protected int wrapStart;

        private class BoldHandler extends WelcomeContentHandler {
            public void characters(char[] ch, int start, int length)
                    throws SAXException {
                ItemHandler.this.characters(ch, start, length);
            }

            public void endElement(String namespaceURI, String localName,
                    String qName) throws SAXException {
                if (localName.equals(TAG_BOLD)) {
                    boldRanges.add(new int[] { textStart, offset - textStart });
                    parser.getXMLReader().setContentHandler(parent);
                }
            }
        }

        private class ActionHandler extends WelcomeContentHandler {
            public ActionHandler(String pluginId, String className) {
                pluginIds.add(pluginId);
                classes.add(className);
            }

            public void characters(char[] ch, int start, int length)
                    throws SAXException {
                ItemHandler.this.characters(ch, start, length);
            }

            public void endElement(String namespaceURI, String localName,
                    String qName) throws SAXException {
                if (localName.equals(TAG_ACTION)) {
                    actionRanges
                            .add(new int[] { textStart, offset - textStart });
                    parser.getXMLReader().setContentHandler(parent);
                }
            }
        }

        private class TopicHandler extends WelcomeContentHandler {
            public TopicHandler(String helpId, String href) {
                helpIds.add(helpId);
                helpHrefs.add(href);
            }

            public void characters(char[] ch, int start, int length)
                    throws SAXException {
                ItemHandler.this.characters(ch, start, length);
            }

            public void endElement(String namespaceURI, String localName,
                    String qName) throws SAXException {
                if (localName.equals(TAG_TOPIC)) {
                    helpRanges.add(new int[] { textStart, offset - textStart });
                    parser.getXMLReader().setContentHandler(parent);
                }
            }
        }

        protected WelcomeItem constructWelcomeItem() {
            if (isFormatWrapped()) {
                // replace all line delimiters with a space
                for (int i = 0; i < wrapRanges.size(); i++) {
                    int[] range = (int[]) wrapRanges.get(i);
                    int start = range[0];
                    int length = range[1];
                    for (int j = start; j < start + length; j++) {
                        char ch = text.charAt(j);
                        if (ch == DELIMITER) {
                            text.replace(j, j + 1, " "); //$NON-NLS-1$
                        }
                    }
                }
            }
            return new WelcomeItem(
                    text.toString(),
                    (int[][]) boldRanges.toArray(new int[boldRanges.size()][2]),
                    (int[][]) actionRanges
                            .toArray(new int[actionRanges.size()][2]),
                    (String[]) pluginIds.toArray(new String[pluginIds.size()]),
                    (String[]) classes.toArray(new String[classes.size()]),
                    (int[][]) helpRanges.toArray(new int[helpRanges.size()][2]),
                    (String[]) helpIds.toArray(new String[helpIds.size()]),
                    (String[]) helpHrefs.toArray(new String[helpHrefs.size()]));
        }

        public void characters(char[] ch, int start, int length)
                throws SAXException {
            for (int i = 0; i < length; i++) {
                text.append(ch[start + i]);
            }
            offset += length;
        }

        public void startElement(String namespaceURI, String localName,
                String qName, Attributes atts) throws SAXException {
            textStart = offset;
            if (localName.equals(TAG_BOLD)) {
                BoldHandler h = new BoldHandler();
                h.setParent(ItemHandler.this);
                parser.getXMLReader().setContentHandler(h);
            } else if (localName.equals(TAG_ACTION)) {
                ActionHandler h = new ActionHandler(atts
                        .getValue(ATT_PLUGIN_ID), atts.getValue(ATT_CLASS));
                h.setParent(ItemHandler.this);
                parser.getXMLReader().setContentHandler(h);
            } else if (localName.equals(TAG_PARAGRAPH)) {
                wrapStart = textStart;
            } else if (localName.equals(TAG_TOPIC)) {
                TopicHandler h = new TopicHandler(atts.getValue(ATT_ID), atts
                        .getValue(ATT_HREF));
                h.setParent(ItemHandler.this);
                parser.getXMLReader().setContentHandler(h);
            }
        }

        public void endElement(String namespaceURI, String localName,
                String qName) throws SAXException {
            if (localName.equals(TAG_ITEM)) {
                items.add(constructWelcomeItem());
                parser.getXMLReader().setContentHandler(parent);
            } else if (localName.equals(TAG_PARAGRAPH)) {
                wrapRanges.add(new int[] { wrapStart, offset - wrapStart });
            }
        }
    }

    private class IntroItemHandler extends ItemHandler {
        public void endElement(String namespaceURI, String localName,
                String qName) throws SAXException {
            if (localName.equals(TAG_INTRO)) {
                introItem = constructWelcomeItem();
                parser.getXMLReader().setContentHandler(parent);
            } else if (localName.equals(TAG_PARAGRAPH)) {
                wrapRanges.add(new int[] { wrapStart, offset - wrapStart });
            }
        }
    }

    /**
     * Creates a new welcome parser.
     */
    public WelcomeParser() throws ParserConfigurationException, SAXException,
            FactoryConfigurationError {
        super();
        SAXParserFactory factory = SAXParserFactory.newInstance();
        factory.setFeature("http://xml.org/sax/features/namespaces", true); //$NON-NLS-1$
        parser = factory.newSAXParser();

        parser.getXMLReader().setContentHandler(this);
        parser.getXMLReader().setDTDHandler(this);
        parser.getXMLReader().setEntityResolver(this);
        parser.getXMLReader().setErrorHandler(this);
    }

    /**
     * Returns the intro item.
     */
    public WelcomeItem getIntroItem() {
        return introItem;
    }

    /**
     * Returns the items.
     */
    public WelcomeItem[] getItems() {
        return (WelcomeItem[]) items.toArray(new WelcomeItem[items.size()]);
    }

    /**
     * Returns the title
     */
    public String getTitle() {
        return title;
    }

    /**
     * Returns whether or not the welcome editor input should be wrapped.
     */
    public boolean isFormatWrapped() {
        return FORMAT_WRAP.equals(format);
    }

    /**
     * Parse the contents of the input stream
     */
    public void parse(InputStream is) {
        try {
            parser.parse(new InputSource(is), this);
        } catch (SAXException e) {
            IStatus status = new Status(IStatus.ERROR,
                    IDEWorkbenchPlugin.IDE_WORKBENCH, 1, IDEWorkbenchMessages.WelcomeParser_parseException, e);
            IDEWorkbenchPlugin.log(IDEWorkbenchMessages.WelcomeParser_parseError, status);
        } catch (IOException e) {
            IStatus status = new Status(IStatus.ERROR,
                    IDEWorkbenchPlugin.IDE_WORKBENCH, 1, IDEWorkbenchMessages.WelcomeParser_parseException, e);
            IDEWorkbenchPlugin.log(IDEWorkbenchMessages.WelcomeParser_parseError, status);
        }
    }

    /**
     * Handles the start element
     */
    public void startElement(String namespaceURI, String localName,
            String qName, Attributes atts) throws SAXException {
        if (localName.equals(TAG_WELCOME_PAGE)) {
            WelcomeContentHandler h = new WelcomePageHandler(atts
                    .getValue(ATT_TITLE));
            format = atts.getValue(ATT_FORMAT);
            h.setParent(this);
            parser.getXMLReader().setContentHandler(h);
        }
    }
}
