/*

   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.AngleParser;
import org.apache.batik.parser.DefaultAngleHandler;
import org.apache.batik.parser.ParseException;

import org.w3c.dom.DOMException;
import org.w3c.dom.svg.SVGAngle;

/**
 * Implementation of an {@link SVGAngle} not associated with any attribute.
 *
 * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
 * @version $Id$
 */
public class SVGOMAngle implements SVGAngle {

    /**
     * The type of this angle.
     */
    protected short unitType;

    /**
     * The value of this angle.
     */
    protected float value;

    /**
     * The unit string representations.
     */
    protected static final String[] UNITS = {
        "", "", "deg", "rad", "grad"
    };

    /**
     * <b>DOM</b>: Implements {@link SVGAngle#getUnitType()}.
     */
    public short getUnitType() {
        revalidate();
        return unitType;
    }

    /**
     * <b>DOM</b>: Implements {@link SVGAngle#getValue()}.
     */
    public float getValue() {
        revalidate();
        return toUnit(unitType, value, SVG_ANGLETYPE_DEG);
    }

    /**
     * <b>DOM</b>: Implements {@link SVGAngle#setValue(float)}.
     */
    public void setValue(float value) throws DOMException {
        revalidate();
        this.unitType = SVG_ANGLETYPE_DEG;
        this.value = value;
        reset();
    }

    /**
     * <b>DOM</b>: Implements {@link SVGAngle#getValueInSpecifiedUnits()}.
     */
    public float getValueInSpecifiedUnits() {
        revalidate();
        return value;
    }

    /**
     * <b>DOM</b>: Implements {@link
     * SVGAngle#setValueInSpecifiedUnits(float)}.
     */
    public void setValueInSpecifiedUnits(float value) throws DOMException {
        revalidate();
        this.value = value;
        reset();
    }

    /**
     * <b>DOM</b>: Implements {@link SVGAngle#getValueAsString()}.
     */
    public String getValueAsString() {
        revalidate();
        return Float.toString(value) + UNITS[unitType];
    }

    /**
     * <b>DOM</b>: Implements {@link SVGAngle#setValueAsString(String)}.
     */
    public void setValueAsString(String value) throws DOMException {
        parse(value);
        reset();
    }

    /**
     * <b>DOM</b>: Implements {@link
     * SVGAngle#newValueSpecifiedUnits(short,float)}.
     */
    public void newValueSpecifiedUnits(short unit, float value) {
        unitType = unit;
        this.value = value;
        reset();
    }

    /**
     * <b>DOM</b>: Implements {@link
     * SVGAngle#convertToSpecifiedUnits(short)}.
     */
    public void convertToSpecifiedUnits(short unit) {
        value = toUnit(unitType, value, unit);
        unitType = unit;
    }

    /**
     * Resets the associated attribute value according to the current value.
     * This should be overridden in descendant classes that associate the
     * angle object with an attribute.
     */
    protected void reset() {
    }

    /**
     * Updates the values in this object according to the associated attribute
     * value.  This should be overridden in descendant classes that associate
     * the angle object with an attribute.
     */
    protected void revalidate() {
    }

    /**
     * Parse a String value as an SVGAngle.
     */
    protected void parse(String s) {
        try {
            AngleParser angleParser = new AngleParser();
            angleParser.setAngleHandler(new DefaultAngleHandler() {
                public void angleValue(float v) throws ParseException {
                    value = v;
                }
                public void deg() throws ParseException {
                    unitType = SVG_ANGLETYPE_DEG;
                }
                public void rad() throws ParseException {
                    unitType = SVG_ANGLETYPE_RAD;
                }
                public void grad() throws ParseException {
                    unitType = SVG_ANGLETYPE_GRAD;
                }
            });
            unitType = SVG_ANGLETYPE_UNSPECIFIED;
            angleParser.parse(s);
        } catch (ParseException e) {
            unitType = SVG_ANGLETYPE_UNKNOWN;
            value = 0;
        }
    }

    /**
     * Table of multipliers for angle unit conversion.
     */
    protected static double[][] K = {
        {             1,      Math.PI / 180,        Math.PI / 200 },
        { 180 / Math.PI,                  1, 1800 / (9 * Math.PI) },
        {           0.9, 9 * Math.PI / 1800,                    1 }
    };

    /**
     * Converts an angle from one unit to another.
     */
    public static float toUnit(short fromUnit, float value, short toUnit) {
        if (fromUnit == 1) {
            fromUnit = 2;
        }
        if (toUnit == 1) {
            toUnit = 2;
        }
        return (float) (K[fromUnit - 2][toUnit - 2] * value);
    }
}
