/*

   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

 */
package org.apache.batik.dom.svg;

import org.apache.batik.parser.NumberListHandler;
import org.apache.batik.parser.NumberListParser;
import org.apache.batik.parser.ParseException;

import org.w3c.dom.DOMException;
import org.w3c.dom.Element;
import org.w3c.dom.svg.SVGException;
import org.w3c.dom.svg.SVGNumber;
import org.w3c.dom.svg.SVGNumberList;

/**
 * This class is the implementation of {@link SVGNumberList}.
 *
 * @author <a href="mailto:tonny@kiyut.com">Tonny Kohar</a>
 * @version $Id$
 */
public abstract class AbstractSVGNumberList
        extends AbstractSVGList
        implements SVGNumberList {

    /**
     * Separator for a length list.
     */
    public static final String SVG_NUMBER_LIST_SEPARATOR
        = " ";

    /**
     * Return the separator between values in the list.
     */
    protected String getItemSeparator() {
        return SVG_NUMBER_LIST_SEPARATOR;
    }

    /**
     * Create an SVGException when the {@link #checkItemType(Object)} fails.
     */
    protected abstract SVGException createSVGException(short type,
                                                       String key,
                                                       Object[] args);

    /**
     * Returns the element associated with this SVGNumberList.
     */
    protected abstract Element getElement();

    /**
     * Creates a new SVGNumberList.
     */
    protected AbstractSVGNumberList() {
    }

    /**
     * <b>DOM</b>: Implements {@link SVGNumberList#initialize(SVGNumber)}.
     */
    public SVGNumber initialize(SVGNumber newItem)
        throws DOMException, SVGException {

        return (SVGNumber)initializeImpl(newItem);
    }

    /**
     * <b>DOM</b>: Implements {@link SVGNumberList#getItem(int)}.
     */
    public SVGNumber getItem(int index) throws DOMException {

        return (SVGNumber)getItemImpl(index);
    }

    /**
     * <b>DOM</b>: Implements {@link
     * SVGNumberList#insertItemBefore(SVGNumber,int)}.
     */
    public SVGNumber insertItemBefore(SVGNumber newItem, int index)
        throws DOMException, SVGException {

        return (SVGNumber)insertItemBeforeImpl(newItem,index);
    }

    /**
     * <b>DOM</b>: Implements {@link SVGNumberList#replaceItem(SVGNumber,int)}.
     */
    public SVGNumber replaceItem(SVGNumber newItem, int index)
        throws DOMException, SVGException {

        return (SVGNumber)replaceItemImpl(newItem,index);
    }

    /**
     * <b>DOM</b>: Implements {@link SVGNumberList#removeItem(int)}.
     */
    public SVGNumber removeItem(int index) throws DOMException {
        return (SVGNumber)removeItemImpl(index);
    }

    /**
     * <b>DOM</b>: Implements {@link SVGNumberList#appendItem(SVGNumber)}.
     */
    public SVGNumber appendItem(SVGNumber newItem)
        throws DOMException, SVGException {

        return (SVGNumber)appendItemImpl(newItem);
    }

    /**
     * Creates a new {@link SVGNumberItem} from the given {@link SVGNumber}.
     */
    protected SVGItem createSVGItem(Object newItem) {
        SVGNumber l = (SVGNumber)newItem;
        return new SVGNumberItem(l.getValue());
    }

    /**
     * Parse the attribute associated with this SVGNumberList.
     * @param value attribute value
     * @param handler list handler
     */
    protected void doParse(String value, ListHandler handler)
        throws ParseException{

        NumberListParser NumberListParser = new NumberListParser();
        NumberListBuilder builder = new NumberListBuilder(handler);

        NumberListParser.setNumberListHandler(builder);
        NumberListParser.parse(value);
    }

    /**
     * Asserts that the given item object is an {@link SVGNumber}.
     */
    protected void checkItemType(Object newItem) throws SVGException {
        if (!(newItem instanceof SVGNumber)) {
            // XXX Fix error code.
            createSVGException(SVGException.SVG_WRONG_TYPE_ERR,
                               "expected SVGNumber",
                               null);
        }
    }

    /**
     * Representation of the item SVGNumber.
     */
    protected class SVGNumberItem extends AbstractSVGNumber implements SVGItem {

        /**
         * The {@link SVGNumberList} this item belongs to.
         */
        protected AbstractSVGList parentList;

        /**
         * Creates a new SVGNumberItem.
         */
        public SVGNumberItem(float value) {
            this.value = value;
        }

        /**
         * Returns a String representation of the number.
         */
        public String getValueAsString() {
            return Float.toString(value);
        }

        /**
         * Associates this item to the given {@link SVGNumberList}.
         */
        public void setParent(AbstractSVGList list) {
            parentList = list;
        }

        /**
         * Returns the list the item belongs to.
         */
        public AbstractSVGList getParent() {
            return parentList;
        }

        /**
         * Notifies the parent {@link SVGNumberList} that this item's value
         * has changed.
         */
        protected void reset() {
            if (parentList != null) {
                parentList.itemChanged();
            }
        }
    }

    /**
     * Helper class to interface the {@link NumberListParser} and the
     * {@link NumberListHandler}.
     */
    protected class NumberListBuilder implements NumberListHandler {

        /**
         * The ListHandler to notify of parsed numbers.
         */
        protected ListHandler listHandler;

        /**
         * The number just parsed.
         */
        protected float currentValue;

        /**
         * Creates a new NumberListBuilder.
         */
        public NumberListBuilder(ListHandler listHandler) {
            this.listHandler = listHandler;
        }

        /**
         * Implements {@link NumberListHandler#startNumberList()}.
         */
        public void startNumberList() throws ParseException{
            listHandler.startList();
        }

        /**
         * Implements {@link NumberListHandler#startNumber()}.
         */
        public void startNumber() throws ParseException {
            currentValue = 0.0f;
        }

        /**
         * Implements {@link NumberListHandler#numberValue(float)}.
         */
        public void numberValue(float v) throws ParseException {
            currentValue = v;
        }

        /**
         * Implements {@link NumberListHandler#endNumber()}.
         */
        public void endNumber() throws ParseException {
            listHandler.item(new SVGNumberItem(currentValue));
        }

        /**
         * Implements {@link NumberListHandler#endNumberList()}.
         */
        public void endNumberList() throws ParseException {
            listHandler.endList();
        }
    }
}
