/*******************************************************************************
 * Copyright (c) 2004, 2005 John-Mason P. Shackelford and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     John-Mason P. Shackelford - initial API and implementation
 *     IBM Corporation - Bug 73411, 84342
 *******************************************************************************/
package org.eclipse.ant.internal.ui.editor.formatter;

import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class XmlTagFormatter {

    protected static class AttributePair {

        private String fAttribute;
        private String fValue;
        private char fQuote;

        public AttributePair(String attribute, String value, char attributeQuote) {
            fAttribute = attribute;
            fValue = value;
            fQuote= attributeQuote;
        }

        public String getAttribute() {
            return fAttribute;
        }

        public String getValue() {
            return fValue;
        }
        
        public char getQuote() {
            return fQuote;
        }
    }

    protected static class ParseException extends Exception {
    	
		private static final long serialVersionUID = 1L;

		public ParseException(String message) {
            super(message);
        }
    }

    protected static class Tag {

        private List fAttributes = new ArrayList();

        private boolean fClosed;

        private String fElementName;

        public void addAttribute(String attribute, String value, char quote) {
            fAttributes.add(new AttributePair(attribute, value, quote));
        }

        public int attributeCount() {
            return fAttributes.size();
        }

        public AttributePair getAttributePair(int i) {
            return (AttributePair) fAttributes.get(i);
        }

        public String getElementName() {
            return this.fElementName;
        }

        public boolean isClosed() {
            return fClosed;
        }

        public int minimumLength() {
            int length = 2; // for the < >
            if (this.isClosed()) length++; // if we need to add an />
            length += this.getElementName().length();
            if (this.attributeCount() > 0 || this.isClosed()) length++;
            for (int i = 0; i < this.attributeCount(); i++) {
                AttributePair attributePair = this.getAttributePair(i);
                length += attributePair.getAttribute().length();
                length += attributePair.getValue().length();
                length += 4; // equals sign, quote characters & trailing space
            }
            if (this.attributeCount() > 0 && !this.isClosed()) length--;
            return length;
        }

        public void setAttributes(List attributePair) {
            fAttributes.clear();
            fAttributes.addAll(attributePair);
        }

        public void setClosed(boolean closed) {
            fClosed = closed;
        }

        public void setElementName(String elementName) {
            fElementName = elementName;
        }

        public String toString() {
            StringBuffer sb = new StringBuffer(500);
            sb.append('<');
            sb.append(this.getElementName());
            if (this.attributeCount() > 0 || this.isClosed()) sb.append(' ');

            for (int i = 0; i < this.attributeCount(); i++) {
                AttributePair attributePair = this.getAttributePair(i);
                sb.append(attributePair.getAttribute());
                sb.append('=');
                sb.append(attributePair.getQuote());
                sb.append(attributePair.getValue());
                sb.append(attributePair.getQuote());
                if (this.isClosed() || i != this.attributeCount() - 1)
                        sb.append(' ');
            }
            if (this.isClosed()) sb.append('/');
            sb.append('>');
            return sb.toString();
        }
    }

    protected static class TagFormatter {

        private int countChar(char searchChar, String inTargetString) {
            StringCharacterIterator iter = new StringCharacterIterator(
                    inTargetString);
            int i = 0;
            if (iter.first() == searchChar) i++;
            while (iter.getIndex() < iter.getEndIndex()) {
                if (iter.next() == searchChar) {
                    i++;
                }
            }
            return i;
        }

        public String format(Tag tag, FormattingPreferences prefs, String indent, String lineDelimiter) {
            if (prefs.wrapLongTags()
                    && lineRequiresWrap(indent + tag.toString(), prefs
                            .getMaximumLineWidth(), prefs.getTabWidth())) {
                return wrapTag(tag, prefs, indent, lineDelimiter);
            }
            return tag.toString();
        }

        protected boolean lineRequiresWrap(String line, int lineWidth, int tabWidth) {
            return tabExpandedLineWidth(line, tabWidth) > lineWidth;
        }

        /**
         * @param line
         *            the line in which spaces are to be expanded
         * @param tabWidth
         *            number of spaces to substitute for a tab
         * @return length of the line with tabs expanded to spaces
         */
        protected int tabExpandedLineWidth(String line, int tabWidth) {
            int tabCount = countChar('\t', line);
            return (line.length() - tabCount) + (tabCount * tabWidth);
        }

        protected String wrapTag(Tag tag, FormattingPreferences prefs, String indent, String lineDelimiter) {
            StringBuffer sb = new StringBuffer(1024);
            sb.append('<');
            sb.append(tag.getElementName());
            sb.append(' ');

            if (tag.attributeCount() > 0) {
                AttributePair pair= tag.getAttributePair(0);
                sb.append(pair.getAttribute());
                sb.append('=');
                sb.append(pair.getQuote());
                sb.append(tag.getAttributePair(0).getValue());
                sb.append(pair.getQuote());
            }

            if (tag.attributeCount() > 1) {
                char[] extraIndent = new char[tag.getElementName().length() + 2];
                Arrays.fill(extraIndent, ' ');
                for (int i = 1; i < tag.attributeCount(); i++) {
                    AttributePair pair= tag.getAttributePair(i);
                    sb.append(lineDelimiter);
                    sb.append(indent);
                    sb.append(extraIndent);
                    sb.append(pair.getAttribute());
                    sb.append('=');
                    sb.append(pair.getQuote());
                    sb.append(pair.getValue());
                    sb.append(pair.getQuote());
                }
            }

            if (prefs.alignElementCloseChar()) {
                sb.append(lineDelimiter);
                sb.append(indent);
            } else if (tag.isClosed()) {
                sb.append(' ');
            }

            if (tag.isClosed()) sb.append('/');
            sb.append('>');
            return sb.toString();
        }
    }

    // if object creation is an issue, use static methods or a flyweight
    // pattern
    protected static class TagParser {

        private String fElementName;

        private String fParseText;

        protected List getAttibutes(String elementText)
                throws ParseException {

            class Mode {
                private int mode;
                public void setAttributeNameSearching() {mode = 0;}
                public void setAttributeNameFound() {mode = 1;}
                public void setAttributeValueSearching() {mode = 2;}
                public void setAttributeValueFound() {mode = 3;}
                public void setFinished() {mode = 4;}
                public boolean isAttributeNameSearching() {return mode == 0;}
                public boolean isAttributeNameFound() {return mode == 1;}
                public boolean isAttributeValueSearching() {return mode == 2;}
                public boolean isAttributeValueFound() {return mode == 3;}
                public boolean isFinished() {return mode == 4;}
            }

            List attributePairs = new ArrayList();

            CharacterIterator iter = new StringCharacterIterator(elementText
                    .substring(getElementName(elementText).length() + 2));

            // state for finding attributes
            Mode mode = new Mode();
            mode.setAttributeNameSearching();
            char attributeQuote = '"';
            StringBuffer currentAttributeName = null;
            StringBuffer currentAttributeValue = null;

            char c = iter.first();
            while (iter.getIndex() < iter.getEndIndex()) {
                
                switch (c) {                
                
                case '"':
                case '\'':

                    if (mode.isAttributeValueSearching()) {

                        // start of an attribute value
                        attributeQuote = c;
                        mode.setAttributeValueFound();
                        currentAttributeValue = new StringBuffer(1024);

                    } else if (mode.isAttributeValueFound()
                            && attributeQuote == c) {

                        // we've completed a pair!
                        AttributePair pair = new AttributePair(
                                currentAttributeName.toString(),
                                currentAttributeValue.toString(), attributeQuote);

                        attributePairs.add(pair);

                        // start looking for another attribute
                        mode.setAttributeNameSearching();

                    } else if (mode.isAttributeValueFound()
                            && attributeQuote != c) {

                        // this quote character is part of the attribute value
                        currentAttributeValue.append(c);

                    } else {
                        // this is no place for a quote!
                        throw new ParseException("Unexpected '" + c //$NON-NLS-1$
                                + "' when parsing:\n\t" + elementText); //$NON-NLS-1$
                    }
                    break;

                case '=':
                    
                    if (mode.isAttributeValueFound()) {

                        // this character is part of the attribute value
                        currentAttributeValue.append(c);

                    } else if (mode.isAttributeNameFound()) {

                        // end of the name, now start looking for the value
                        mode.setAttributeValueSearching();
                        
                    } else {
                        // this is no place for an equals sign!
                        throw new ParseException("Unexpected '" + c //$NON-NLS-1$
                                + "' when parsing:\n\t" + elementText); //$NON-NLS-1$
                    }
                    break;

                case '/':
                case '>':
                    if (mode.isAttributeValueFound()) {
                        // attribute values are CDATA, add it all
                        currentAttributeValue.append(c);
                    } else if (mode.isAttributeNameSearching()) {
                        mode.setFinished();
					} else if (mode.isFinished()){
						// consume the remaining characters
                    } else {
                        // we aren't ready to be done!
                        throw new ParseException("Unexpected '" + c //$NON-NLS-1$
                                + "' when parsing:\n\t" + elementText); //$NON-NLS-1$
                    }
                    break;

                default:

                    if (mode.isAttributeValueFound()) {
                        // attribute values are CDATA, add it all
                        currentAttributeValue.append(c);

					} else if (mode.isFinished()) {
						if (!Character.isWhitespace(c)) {
								throw new ParseException("Unexpected '" + c //$NON-NLS-1$
										+ "' when parsing:\n\t" + elementText); //$NON-NLS-1$
						}
                    } else {
                        if (!Character.isWhitespace(c)) {
                            if (mode.isAttributeNameSearching()) {
                                // we found the start of an attribute name
                                mode.setAttributeNameFound();
                                currentAttributeName = new StringBuffer(255);
                                currentAttributeName.append(c);
                            } else if (mode.isAttributeNameFound()) {
                                currentAttributeName.append(c);                            
                            }
                        }
                    }
                    break;
                }
                
                c = iter.next();
            }
			if (!mode.isFinished()) {
				throw new ParseException("Element did not complete normally."); //$NON-NLS-1$
			}
            return attributePairs;
        }

        /**
         * @param tagText
         *            text of an XML tag
         * @return extracted XML element name
         */
        protected String getElementName(String tagText) throws ParseException {
            if (!tagText.equals(this.fParseText) || this.fElementName == null) {
                int endOfTag = tagEnd(tagText);
                if ((tagText.length() > 2) && (endOfTag > 1)) {
                    this.fParseText = tagText;
                    this.fElementName = tagText.substring(1, endOfTag);
                } else {
                    throw new ParseException("No element name for the tag:\n\t" //$NON-NLS-1$
                            + tagText);
                }
            }
            return fElementName;
        }

        protected boolean isClosed(String tagText) {
            return tagText.charAt(tagText.lastIndexOf('>') - 1) == '/';
        }

        /**
         * @param tagText
         * @return a fully populated tag
         */
        public Tag parse(String tagText) throws ParseException {
            Tag tag = new Tag();
            tag.setElementName(getElementName(tagText));
            tag.setAttributes(getAttibutes(tagText));
            tag.setClosed(isClosed(tagText));
            return tag;
        }

        private int tagEnd(String text) {
            // This is admittedly a little loose, but we don't want the
            // formatter to be too strict...
            // http://www.w3.org/TR/2000/REC-xml-20001006#NT-Name
            for (int i = 1; i < text.length(); i++) {
                char c = text.charAt(i);
                if (!Character.isLetterOrDigit(c) && c != ':' && c != '.'
                        && c != '-' && c != '_') { return i; }
            }
            return -1;
        }
    }

    public static String format(String tagText, FormattingPreferences prefs, String indent, String lineDelimiter) {

        Tag tag;
        if (tagText.startsWith("</") || tagText.startsWith("<%") //$NON-NLS-1$ //$NON-NLS-2$
                || tagText.startsWith("<?") || tagText.startsWith("<[")) { //$NON-NLS-1$ //$NON-NLS-2$
            return tagText;
        } 
    	try {
            tag = new TagParser().parse(tagText);
        } catch (ParseException e) {
            // if we can't parse the tag, give up and leave the text as is.
            return tagText;
        }
        return new TagFormatter().format(tag, prefs, indent, lineDelimiter);
    }
}