/*

   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.bridge;

import java.util.ArrayList;
import java.util.List;

import org.apache.batik.anim.AbstractAnimation;
import org.apache.batik.anim.AnimationEngine;
import org.apache.batik.dom.anim.AnimationTarget;
import org.apache.batik.anim.SimpleAnimation;
import org.apache.batik.anim.values.AnimatableValue;
import org.apache.batik.util.SMILConstants;

/**
 * Bridge class for the 'animate' animation element.
 *
 * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
 * @version $Id$
 */
public class SVGAnimateElementBridge extends SVGAnimationElementBridge {

    /**
     * Returns 'animate'.
     */
    public String getLocalName() {
        return SVG_ANIMATE_TAG;
    }

    /**
     * Returns a new instance of this bridge.
     */
    public Bridge getInstance() {
        return new SVGAnimateElementBridge();
    }

    /**
     * Creates the animation object for the animation element.
     */
    protected AbstractAnimation createAnimation(AnimationTarget target) {
        AnimatableValue from = parseAnimatableValue(SVG_FROM_ATTRIBUTE);
        AnimatableValue to = parseAnimatableValue(SVG_TO_ATTRIBUTE);
        AnimatableValue by = parseAnimatableValue(SVG_BY_ATTRIBUTE);
        return new SimpleAnimation(timedElement,
                                   this,
                                   parseCalcMode(),
                                   parseKeyTimes(),
                                   parseKeySplines(),
                                   parseAdditive(),
                                   parseAccumulate(),
                                   parseValues(),
                                   from,
                                   to,
                                   by);
    }

    /**
     * Returns the parsed 'calcMode' attribute from the animation element.
     */
    protected int parseCalcMode() {
        // If the attribute being animated has only non-additive values, take
        // the animation as having calcMode="discrete".
        if (animationType == AnimationEngine.ANIM_TYPE_CSS
                && !targetElement.isPropertyAdditive(attributeLocalName)
            || animationType == AnimationEngine.ANIM_TYPE_XML
                && !targetElement.isAttributeAdditive(attributeNamespaceURI,
                                                      attributeLocalName)) {
            return SimpleAnimation.CALC_MODE_DISCRETE;
        }

        String calcModeString = element.getAttributeNS(null,
                                                       SVG_CALC_MODE_ATTRIBUTE);
        if (calcModeString.length() == 0) {
            return getDefaultCalcMode();
        } else if (calcModeString.equals(SMILConstants.SMIL_LINEAR_VALUE)) {
            return SimpleAnimation.CALC_MODE_LINEAR;
        } else if (calcModeString.equals(SMILConstants.SMIL_DISCRETE_VALUE)) {
            return SimpleAnimation.CALC_MODE_DISCRETE;
        } else if (calcModeString.equals(SMILConstants.SMIL_PACED_VALUE)) {
            return SimpleAnimation.CALC_MODE_PACED;
        } else if (calcModeString.equals(SMILConstants.SMIL_SPLINE_VALUE)) {
            return SimpleAnimation.CALC_MODE_SPLINE;
        }
        throw new BridgeException
            (ctx, element, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
             new Object[] { SVG_CALC_MODE_ATTRIBUTE, calcModeString });
    }

    /**
     * Returns the parsed 'additive' attribute from the animation element.
     */
    protected boolean parseAdditive() {
        String additiveString = element.getAttributeNS(null,
                                                       SVG_ADDITIVE_ATTRIBUTE);
        if (additiveString.length() == 0
                || additiveString.equals(SMILConstants.SMIL_REPLACE_VALUE)) {
            return false;
        } else if (additiveString.equals(SMILConstants.SMIL_SUM_VALUE)) {
            return true;
        }
        throw new BridgeException
            (ctx, element, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
             new Object[] { SVG_ADDITIVE_ATTRIBUTE, additiveString });
    }

    /**
     * Returns the parsed 'accumulate' attribute from the animation element.
     */
    protected boolean parseAccumulate() {
        String accumulateString =
            element.getAttributeNS(null, SVG_ACCUMULATE_ATTRIBUTE);
        if (accumulateString.length() == 0 ||
                accumulateString.equals(SMILConstants.SMIL_NONE_VALUE)) {
            return false;
        } else if (accumulateString.equals(SMILConstants.SMIL_SUM_VALUE)) {
            return true;
        }
        throw new BridgeException
            (ctx, element, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
             new Object[] { SVG_ACCUMULATE_ATTRIBUTE, accumulateString });
    }

    /**
     * Returns the parsed 'values' attribute from the animation element.
     */
    protected AnimatableValue[] parseValues() {
        boolean isCSS = animationType == AnimationEngine.ANIM_TYPE_CSS;
        String valuesString = element.getAttributeNS(null,
                                                     SVG_VALUES_ATTRIBUTE);
        int len = valuesString.length();
        if (len == 0) {
            return null;
        }
        ArrayList values = new ArrayList(7);
        int i = 0, start = 0, end;
        char c;
outer:  while (i < len) {
            while (valuesString.charAt(i) == ' ') {
                i++;
                if (i == len) {
                    break outer;
                }
            }
            start = i++;
            if (i != len) {
                c = valuesString.charAt(i);
                while (c != ';') {
                    i++;
                    if (i == len) {
                        break;
                    }
                    c = valuesString.charAt(i);
                }
            }
            end = i++;
            AnimatableValue val = eng.parseAnimatableValue
                (element, animationTarget, attributeNamespaceURI,
                 attributeLocalName, isCSS, valuesString.substring(start, end));
            if (!checkValueType(val)) {
                throw new BridgeException
                    (ctx, element, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
                     new Object[] { SVG_VALUES_ATTRIBUTE, valuesString });
            }
            values.add(val);
        }
        AnimatableValue[] ret = new AnimatableValue[values.size()];
        return (AnimatableValue[]) values.toArray(ret);
    }

    /**
     * Returns the parsed 'keyTimes' attribute from the animation element.
     */
    protected float[] parseKeyTimes() {
        String keyTimesString =
            element.getAttributeNS(null, SVG_KEY_TIMES_ATTRIBUTE);
        int len = keyTimesString.length();
        if (len == 0) {
            return null;
        }
        ArrayList keyTimes = new ArrayList(7);
        int i = 0, start = 0, end;
        char c;
outer:  while (i < len) {
            while (keyTimesString.charAt(i) == ' ') {
                i++;
                if (i == len) {
                    break outer;
                }
            }
            start = i++;
            if (i != len) {
                c = keyTimesString.charAt(i);
                while (c != ' ' && c != ';') {
                    i++;
                    if (i == len) {
                        break;
                    }
                    c = keyTimesString.charAt(i);
                }
            }
            end = i++;
            try {
                float keyTime =
                    Float.parseFloat(keyTimesString.substring(start, end));
                keyTimes.add(new Float(keyTime));
            } catch (NumberFormatException nfEx ) {
                throw new BridgeException
                    (ctx, element, nfEx, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
                     new Object[] { SVG_KEY_TIMES_ATTRIBUTE, keyTimesString });
            }
        }
        len = keyTimes.size();
        float[] ret = new float[len];
        for (int j = 0; j < len; j++) {
            ret[j] = ((Float) keyTimes.get(j)).floatValue();
        }
        return ret;
    }

    /**
     * Returns the parsed 'keySplines' attribute from the animation element.
     */
    protected float[] parseKeySplines() {
        String keySplinesString =
            element.getAttributeNS(null, SVG_KEY_SPLINES_ATTRIBUTE);
        int len = keySplinesString.length();
        if (len == 0) {
            return null;
        }
        List keySplines = new ArrayList(7);
        int count = 0, i = 0, start = 0, end;
        char c;
outer:  while (i < len) {
            while (keySplinesString.charAt(i) == ' ') {
                i++;
                if (i == len) {
                    break outer;
                }
            }
            start = i++;
            if (i != len) {
                c = keySplinesString.charAt(i);
                while (c != ' ' && c != ',' && c != ';') {
                    i++;
                    if (i == len) {
                        break;
                    }
                    c = keySplinesString.charAt(i);
                }
                end = i++;
                if (c == ' ') {
                    do {
                        if (i == len) {
                            break;
                        }
                        c = keySplinesString.charAt(i++);
                    } while (c == ' ');
                    if (c != ';' && c != ',') {
                        i--;
                    }
                }
                if (c == ';') {
                    if (count == 3) {
                        count = 0;
                    } else {
                        throw new BridgeException
                            (ctx, element,
                             ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
                             new Object[] { SVG_KEY_SPLINES_ATTRIBUTE,
                                            keySplinesString });
                    }
                } else {
                    count++;
                }
            } else {
                end = i++;
            }
            try {
                float keySplineValue =
                    Float.parseFloat(keySplinesString.substring(start, end));
                keySplines.add(new Float(keySplineValue));
            } catch (NumberFormatException nfEx ) {
                throw new BridgeException
                    (ctx, element, nfEx, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
                     new Object[] { SVG_KEY_SPLINES_ATTRIBUTE, keySplinesString });
            }
        }
        len = keySplines.size();
        float[] ret = new float[len];
        for (int j = 0; j < len; j++) {
            ret[j] = ((Float) keySplines.get(j)).floatValue();
        }
        return ret;
    }

    /**
     * Returns the calcMode that the animation defaults to if none is specified.
     */
    protected int getDefaultCalcMode() {
        return SimpleAnimation.CALC_MODE_LINEAR;
    }

    /**
     * Returns whether the animation element being handled by this bridge can
     * animate attributes of the specified type.
     * @param type one of the TYPE_ constants defined in {@link org.apache.batik.util.SVGTypes}.
     */
    protected boolean canAnimateType(int type) {
        return true;
    }
}
