/*

   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 java.awt.geom.AffineTransform;

import org.apache.batik.parser.ParseException;
import org.apache.batik.parser.TransformListHandler;
import org.apache.batik.parser.TransformListParser;

import org.w3c.dom.DOMException;
import org.w3c.dom.svg.SVGException;
import org.w3c.dom.svg.SVGMatrix;
import org.w3c.dom.svg.SVGTransform;
import org.w3c.dom.svg.SVGTransformList;

/**
 * This class is the implementation of
 * <code>SVGTransformList</code>.
 *
 * @author <a href="mailto:nicolas.socheleau@bitflash.com">Nicolas Socheleau</a>
 * @version $Id$
 */
public abstract class AbstractSVGTransformList
    extends AbstractSVGList
    implements SVGTransformList {

    /**
     * Separator for a point list.
     */
    public static final String SVG_TRANSFORMATION_LIST_SEPARATOR
        = "";

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

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

    /**
     * <b>DOM</b>: Implements {@link SVGTransformList#initialize(SVGTransform)}.
     */
    public SVGTransform initialize(SVGTransform newItem)
            throws DOMException, SVGException {
        return (SVGTransform) initializeImpl(newItem);
    }

    /**
     * <b>DOM</b>: Implements {@link SVGTransformList#getItem(int)}.
     */
    public SVGTransform getItem(int index) throws DOMException {
        return (SVGTransform) getItemImpl(index);
    }

    /**
     * <b>DOM</b>: Implements {@link
     * SVGTransformList#insertItemBefore(SVGTransform,int)}.
     */
    public SVGTransform insertItemBefore(SVGTransform newItem, int index)
            throws DOMException, SVGException {
        return (SVGTransform) insertItemBeforeImpl(newItem, index);
    }

    /**
     * <b>DOM</b>: Implements {@link
     * SVGTransformList#replaceItem(SVGTransform,int)}.
     */
    public SVGTransform replaceItem(SVGTransform newItem, int index)
            throws DOMException, SVGException {
        return (SVGTransform) replaceItemImpl(newItem, index);
    }

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

    /**
     * <b>DOM</b>: Implements {@link SVGTransformList#appendItem(SVGTransform)}.
     */
    public SVGTransform appendItem(SVGTransform newItem)
            throws DOMException, SVGException {
        return (SVGTransform) appendItemImpl(newItem);
    }

    /**
     * <b>DOM</b>: Implements {@link
     * SVGTransformList#createSVGTransformFromMatrix(SVGMatrix)}.
     */
    public SVGTransform createSVGTransformFromMatrix(SVGMatrix matrix) {
        SVGOMTransform transform = new SVGOMTransform();
        transform.setMatrix(matrix);
        return transform;
    }

    /**
     * <b>DOM</b>: Implements {@link SVGTransformList#consolidate()}.
     */
    public SVGTransform consolidate() {
        revalidate();

        int size = itemList.size();
        if (size == 0) {
            return null;
        } else if (size == 1) {
            return getItem(0);
        }

        SVGTransformItem t = (SVGTransformItem) getItemImpl(0);
        AffineTransform at = (AffineTransform) t.affineTransform.clone();

        for (int i = 1; i < size; i++) {
            t = (SVGTransformItem) getItemImpl(i);
            at.concatenate(t.affineTransform);
        }
        SVGOMMatrix matrix = new SVGOMMatrix(at);
        return initialize(createSVGTransformFromMatrix(matrix));
    }

    /**
     * Returns an {@link AffineTransform} that represents the same transform
     * as that specified by this transform list.
     */
    public AffineTransform getAffineTransform() {
        AffineTransform at = new AffineTransform();
        for (int i = 0; i < getNumberOfItems(); i++) {
            SVGTransformItem item = (SVGTransformItem) getItem(i);
            at.concatenate(item.affineTransform);
        }
        return at;
    }

    /**
     * Creates a new {@link SVGItem} object from the given {@link SVGTransform}.
     */
    protected SVGItem createSVGItem(Object newItem) {
        return new SVGTransformItem((SVGTransform) newItem);
    }

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

        TransformListParser transformListParser = new TransformListParser();
        TransformListBuilder builder = new TransformListBuilder(handler);
        transformListParser.setTransformListHandler(builder);
        transformListParser.parse(value);
    }

    /**
     * Asserts that the given item is an {@link SVGTransformList}.
     */
    protected void checkItemType(Object newItem) {
        if (!(newItem instanceof SVGTransform)) {
            createSVGException(SVGException.SVG_WRONG_TYPE_ERR,
                               "expected.transform", null);
        }
    }

    /**
     * An {@link SVGTransform} in the list.
     */
    public class SVGTransformItem
            extends AbstractSVGTransform
            implements SVGItem {

        /**
         * Whether the transform value specifies only an x value, no y value.
         */
        protected boolean xOnly;

        /**
         * Whether the rotation transform value specifies only an angle.
         */
        protected boolean angleOnly;

        /**
         * List the item belongs to.
         */
        protected AbstractSVGList parent;

        /**
         * String representation of the item.
         *
         * This is a cached representation of the
         * item while it is not changed.
         */
        protected String itemStringValue;

        /**
         * Creates a new, uninitialized SVGTransformItem.
         */
        public SVGTransformItem() {
        }

        /**
         * Creates a new SVGTransformItem from the given {@link SVGTransform}.
         */
        public SVGTransformItem(SVGTransform transform) {
            assign(transform);
        }

        /**
         * Notifies the parent list that this item has changed.  This also
         * discards the cached representation of the item.
         */
        protected void resetAttribute() {
            if (parent != null) {
                itemStringValue = null;
                parent.itemChanged();
            }
        }

        /**
         * Assigns a parent list to this item.
         * @param list The list the item belongs.
         */
        public void setParent(AbstractSVGList list) {
            parent = list;
        }

        /**
         * Returns the parent list of this item.
         */
        public AbstractSVGList getParent() {
            return parent;
        }

        /**
         * Returns the cached representation of the item if valid, otherwise
         * recomputes the String representation of the item.
         */
        public String getValueAsString() {
            if (itemStringValue == null) {
                itemStringValue = getStringValue();
            }
            return itemStringValue;
        }

        /**
         * Copies the values from the given {@link SVGTransform} into this
         * {@link SVGTransformItem}.
         */
        public void assign(SVGTransform transform) {
            type = transform.getType();
            SVGMatrix matrix = transform.getMatrix();
            switch (type) {
                case SVGTransform.SVG_TRANSFORM_TRANSLATE:
                    setTranslate(matrix.getE(), matrix.getF());
                    break;
                case SVGTransform.SVG_TRANSFORM_SCALE:
                    setScale(matrix.getA(), matrix.getD());
                    break;
                case SVGTransform.SVG_TRANSFORM_ROTATE:
                    if (matrix.getE() == 0.0f) {
                        rotate(transform.getAngle());
                    } else {
                        angleOnly = false;
                        if (matrix.getA() == 1.0f) {
                            setRotate(transform.getAngle(),
                                      matrix.getE(), matrix.getF());
                        } else if (transform instanceof AbstractSVGTransform) {
                            AbstractSVGTransform internal =
                                (AbstractSVGTransform) transform;
                            setRotate(internal.getAngle(),
                                      internal.getX(), internal.getY());
                        } else {
                            // XXX Should extract the angle, x and y from the
                            //     matrix.
                        }
                    }
                    break;
                case SVGTransform.SVG_TRANSFORM_SKEWX:
                    setSkewX(transform.getAngle());
                    break;
                case SVGTransform.SVG_TRANSFORM_SKEWY:
                    setSkewY(transform.getAngle());
                    break;
                case SVGTransform.SVG_TRANSFORM_MATRIX:
                    setMatrix(matrix);
                    break;
            }
        }

        /**
         * Sets the transform to be an x translation.
         */
        protected void translate(float x) {
            xOnly = true;
            setTranslate(x, 0.0f);
        }

        /**
         * Sets the transform to be rotation.
         */
        protected void rotate(float angle) {
            angleOnly = true;
            setRotate(angle, 0.0f, 0.0f);
        }

        /**
         * Sets the transform to be an x scale.
         */
        protected void scale(float x) {
            xOnly = true;
            setScale(x, x);
        }

        /**
         * Sets the transform to be a matrix transform.
         */
        protected void matrix(float a, float b, float c,
                              float d, float e, float f) {
            setMatrix(new SVGOMMatrix(new AffineTransform(a, b, c, d, e, f)));
        }

        /**
         * <b>DOM</b>: Implements {@link SVGTransform#setMatrix(SVGMatrix)}.
         */
        public void setMatrix(SVGMatrix matrix) {
            super.setMatrix(matrix);
            resetAttribute();
        }

        /**
         * <b>DOM</b>: Implements {@link SVGTransform#setTranslate(float,float)}.
         */
        public void setTranslate(float tx, float ty) {
            super.setTranslate(tx, ty);
            resetAttribute();
        }

        /**
         * <b>DOM</b>: Implements {@link SVGTransform#setScale(float,float)}.
         */
        public void setScale(float sx, float sy) {
            super.setScale(sx, sy);
            resetAttribute();
        }

        /**
         * <b>DOM</b>: Implements {@link
         * SVGTransform#setRotate(float,float,float)}.
         */
        public void setRotate(float angle, float cx, float cy) {
            super.setRotate(angle, cx, cy);
            resetAttribute();
        }

        /**
         * <b>DOM</b>: Implements {@link SVGTransform#setSkewX(float)}.
         */
        public void setSkewX(float angle) {
            super.setSkewX(angle);
            resetAttribute();
        }

        /**
         * <b>DOM</b>: Implements {@link SVGTransform#setSkewY(float)}.
         */
        public void setSkewY(float angle) {
            super.setSkewY(angle);
            resetAttribute();
        }

        /**
         * Creates the {@link SVGMatrix} used to store the transform.
         */
        protected SVGMatrix createMatrix() {
            return new AbstractSVGMatrix() {
                protected AffineTransform getAffineTransform() {
                    return SVGTransformItem.this.affineTransform;
                }
                public void setA(float a) throws DOMException {
                    SVGTransformItem.this.type = SVGTransform.SVG_TRANSFORM_MATRIX;
                    super.setA(a);
                    SVGTransformItem.this.resetAttribute();
                }
                public void setB(float b) throws DOMException {
                    SVGTransformItem.this.type = SVGTransform.SVG_TRANSFORM_MATRIX;
                    super.setB(b);
                    SVGTransformItem.this.resetAttribute();
                }
                public void setC(float c) throws DOMException {
                    SVGTransformItem.this.type = SVGTransform.SVG_TRANSFORM_MATRIX;
                    super.setC(c);
                    SVGTransformItem.this.resetAttribute();
                }
                public void setD(float d) throws DOMException {
                    SVGTransformItem.this.type = SVGTransform.SVG_TRANSFORM_MATRIX;
                    super.setD(d);
                    SVGTransformItem.this.resetAttribute();
                }
                public void setE(float e) throws DOMException {
                    SVGTransformItem.this.type = SVGTransform.SVG_TRANSFORM_MATRIX;
                    super.setE(e);
                    SVGTransformItem.this.resetAttribute();
                }
                public void setF(float f) throws DOMException {
                    SVGTransformItem.this.type = SVGTransform.SVG_TRANSFORM_MATRIX;
                    super.setF(f);
                    SVGTransformItem.this.resetAttribute();
                }
            };
        }

        /**
         * Returns the string representation of this transform.
         */
        protected String getStringValue(){
            StringBuffer buf = new StringBuffer();
            switch(type) {
                case SVGTransform.SVG_TRANSFORM_TRANSLATE:
                    buf.append("translate(");
                    buf.append((float) affineTransform.getTranslateX());
                    if (!xOnly) {
                        buf.append(' ');
                        buf.append((float) affineTransform.getTranslateY());
                    }
                    buf.append(')');
                    break;
                case SVGTransform.SVG_TRANSFORM_ROTATE:
                    buf.append("rotate(");
                    buf.append(angle);
                    if (!angleOnly) {
                        buf.append(' ');
                        buf.append(x);
                        buf.append(' ');
                        buf.append(y);
                    }
                    buf.append(')');
                    break;
                case SVGTransform.SVG_TRANSFORM_SCALE:
                    buf.append("scale(");
                    buf.append((float) affineTransform.getScaleX());
                    if (!xOnly) {
                        buf.append(' ');
                        buf.append((float) affineTransform.getScaleY());
                    }
                    buf.append(')');
                    break;
                case SVGTransform.SVG_TRANSFORM_SKEWX:
                    buf.append("skewX(");
                    buf.append(angle);
                    buf.append(')');
                    break;
                case SVGTransform.SVG_TRANSFORM_SKEWY:
                    buf.append("skewY(");
                    buf.append(angle);
                    buf.append(')');
                    break;
                case SVGTransform.SVG_TRANSFORM_MATRIX:
                    buf.append("matrix(");
                    double[] matrix = new double[6];
                    affineTransform.getMatrix(matrix);
                    for(int i = 0; i < 6; i++) {
                        if (i != 0) {
                            buf.append(' ');
                        }
                        buf.append((float) matrix[i]);
                    }
                    buf.append(')');
                    break;
            }
            return buf.toString();
        }
    }

    /**
     * Helper class to interface the {@link TransformListParser} and the
     * {@link ListHandler}.
     */
    protected class TransformListBuilder implements TransformListHandler {

        /**
         * The {@link ListHandler} to pass newly created
         * {@link SVGTransformItem} objects to.
         */
        protected ListHandler listHandler;

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

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

        /**
         * Implements {@link
         * TransformListHandler#matrix(float,float,float,float,float,float)}.
         */
        public void matrix(float a, float b, float c, float d, float e, float f)
                throws ParseException {
            SVGTransformItem item  = new SVGTransformItem();
            item.matrix(a, b, c, d, e, f);
            listHandler.item(item);
        }

        /**
         * Implements {@link TransformListHandler#rotate(float)}.
         */
        public void rotate(float theta) throws ParseException {
            SVGTransformItem item = new SVGTransformItem();
            item.rotate(theta);
            listHandler.item(item);
        }

        /**
         * Implements {@link TransformListHandler#rotate(float,float,float)}.
         */
        public void rotate(float theta, float cx, float cy)
                throws ParseException {
            SVGTransformItem item = new SVGTransformItem();
            item.setRotate(theta, cx, cy);
            listHandler.item(item);
        }

        /**
         * Implements {@link TransformListHandler#translate(float)}.
         */
        public void translate(float tx) throws ParseException {
            SVGTransformItem item = new SVGTransformItem();
            item.translate(tx);
            listHandler.item(item);
        }

        /**
         * Implements {@link TransformListHandler#translate(float,float)}.
         */
        public void translate(float tx, float ty) throws ParseException {
            SVGTransformItem item = new SVGTransformItem();
            item.setTranslate(tx, ty);
            listHandler.item(item);
        }

        /**
         * Implements {@link TransformListHandler#scale(float)}.
         */
        public void scale(float sx) throws ParseException {
            SVGTransformItem item  = new SVGTransformItem();
            item.scale(sx);
            listHandler.item(item);
        }

        /**
         * Implements {@link TransformListHandler#scale(float,float)}.
         */
        public void scale(float sx, float sy) throws ParseException {
            SVGTransformItem item = new SVGTransformItem();
            item.setScale(sx, sy);
            listHandler.item(item);
        }

        /**
         * Implements {@link TransformListHandler#skewX(float)}.
         */
        public void skewX(float skx) throws ParseException {
            SVGTransformItem item = new SVGTransformItem();
            item.setSkewX(skx);
            listHandler.item(item);
        }

        /**
         * Implements {@link TransformListHandler#skewY(float)}.
         */
        public void skewY(float sky) throws ParseException {
            SVGTransformItem item  = new SVGTransformItem();
            item.setSkewY(sky);
            listHandler.item(item);
        }

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