/*
    Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org>
                  2004, 2005 Rob Buis <buis@kde.org>

    This file is part of the KDE project

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

#include "config.h"
#ifdef SVG_SUPPORT
#include "Attr.h"

#include <kcanvas/RenderPath.h>
#include <kcanvas/KCanvasMatrix.h>

#include "SVGAngle.h"
#include "SVGMatrix.h"
#include "SVGTransform.h"
#include "SVGStyledTransformableElement.h"
#include "SVGTransformList.h"
#include "SVGAnimatedTransformList.h"
#include "SVGAnimateTransformElement.h"
#include "KSVGTimeScheduler.h"
#include "Document.h"
#include "SVGDocumentExtensions.h"
#include "SVGSVGElement.h"

#include <math.h>

using namespace std;

namespace WebCore {

SVGAnimateTransformElement::SVGAnimateTransformElement(const QualifiedName& tagName, Document *doc)
    : SVGAnimationElement(tagName, doc)
    , m_currentItem(-1)
    , m_type(SVG_TRANSFORM_UNKNOWN)
    , m_rotateSpecialCase(false)
    , m_toRotateSpecialCase(false)
    , m_fromRotateSpecialCase(false)
{
}

SVGAnimateTransformElement::~SVGAnimateTransformElement()
{
}

void SVGAnimateTransformElement::parseMappedAttribute(MappedAttribute *attr)
{
    if (attr->name() == SVGNames::typeAttr) {
        const String& value = attr->value();
        if (value == "translate")
            m_type = SVG_TRANSFORM_TRANSLATE;
        else if (value == "scale")
            m_type = SVG_TRANSFORM_SCALE;
        else if (value == "rotate")
            m_type = SVG_TRANSFORM_ROTATE;
        else if (value == "skewX")
            m_type = SVG_TRANSFORM_SKEWX;
        else if (value == "skewY")
            m_type = SVG_TRANSFORM_SKEWY;
    } else
        SVGAnimationElement::parseMappedAttribute(attr);
}

void SVGAnimateTransformElement::handleTimerEvent(double timePercentage)
{
    // Start condition.
    if (!m_connected) {
        m_initialTransform = 0;
        
        // Save initial transform... (needed for fill="remove" or additve="sum")
        if (targetElement()->isStyledTransformable()) {
            SVGStyledTransformableElement *transform = static_cast<SVGStyledTransformableElement *>(targetElement());
            RefPtr<SVGTransformList> transformList = transform->transform()->baseVal();
            if (transformList) {
                for (unsigned long i = 0; i < transformList->numberOfItems(); i++) {
                    SVGTransform *value = transformList->getItem(i);
                    if (!value)
                        continue;
                        
                    if (value->type() == m_type) {
                        m_initialTransform = value;
                        break;
                    }
                }
            }
        }
                
        // Animation mode handling
        switch(detectAnimationMode())
        {
            case TO_ANIMATION:
            case FROM_TO_ANIMATION:
            {        
                m_toTransform = parseTransformValue(m_to);
                m_toRotateSpecialCase = m_rotateSpecialCase;

                if (!m_from.isEmpty()) // from-to animation
                {
                    m_fromTransform = parseTransformValue(m_from);
                    m_fromRotateSpecialCase = m_rotateSpecialCase;
                }
                else // to animation
                {
                    m_fromTransform = m_initialTransform;
                    m_fromRotateSpecialCase = false;
                }

                if (!m_fromTransform)
                    m_fromTransform = new SVGTransform();
                
                break;
            }
            case BY_ANIMATION:
            case FROM_BY_ANIMATION:
            {
                m_toTransform = parseTransformValue(m_by);
                m_toRotateSpecialCase = m_rotateSpecialCase;

                if (!m_from.isEmpty()) // from-by animation
                {
                    m_fromTransform = parseTransformValue(m_from);
                    m_fromRotateSpecialCase = m_rotateSpecialCase;
                }
                else // by animation
                {
                    m_fromTransform = m_initialTransform;
                    m_fromRotateSpecialCase = false;
                }

                if (!m_fromTransform)
                    m_fromTransform = new SVGTransform();

                SVGMatrix *byMatrix = m_toTransform->matrix();
                SVGMatrix *fromMatrix = m_fromTransform->matrix();

                byMatrix->multiply(fromMatrix);

                break;
            }
            case VALUES_ANIMATION:
                break;
            default:
            {
                //kdError() << k_funcinfo << " Unable to detect animation mode! Aborting creation!" << endl;
                return;
            }
        }
        
        ownerSVGElement()->timeScheduler()->connectIntervalTimer(this);
        m_connected = true;

        return;
    }

    // Calculations...
    if (timePercentage >= 1.0)
        timePercentage = 1.0;
    
    AffineTransform qToMatrix, qFromMatrix;
    double useTimePercentage = timePercentage;

    if (m_values) {
        int itemByPercentage = calculateCurrentValueItem(timePercentage);

        if (itemByPercentage == -1)
            return;
        
        if (m_currentItem != itemByPercentage) // Item changed...
        {
            // Extract current 'from' / 'to' values
            String value1 = String(m_values->getItem(itemByPercentage));
            String value2 = String(m_values->getItem(itemByPercentage + 1));

            // Calculate new from/to transform values...
            if (!value1.isEmpty() && !value2.isEmpty()) {
                bool apply = false;
                if (m_toTransform && m_fromTransform) {    
                    qToMatrix = m_toTransform->matrix()->matrix();
                    qFromMatrix = m_fromTransform->matrix()->matrix();
                    
                    apply = true;
                    useTimePercentage = 1.0;
                }

                m_toTransform = parseTransformValue(value2.deprecatedString());
                m_toRotateSpecialCase = m_rotateSpecialCase;
    
                m_fromTransform = parseTransformValue(value1.deprecatedString());
                m_fromRotateSpecialCase = m_rotateSpecialCase;

                m_currentItem = itemByPercentage;

                if (!apply)
                    return;
            }
        }
        else if (m_toTransform && m_fromTransform)
            useTimePercentage = calculateRelativeTimePercentage(timePercentage, m_currentItem);
    }

    if (m_toTransform && m_toTransform->matrix() && qToMatrix.isIdentity())
        qToMatrix = m_toTransform->matrix()->matrix();

    if (m_fromTransform && m_fromTransform->matrix() && qFromMatrix.isIdentity())
        qFromMatrix = m_fromTransform->matrix()->matrix();

    if (!m_transformMatrix)
        m_transformMatrix = new SVGMatrix();
    else {
        m_transformMatrix->reset();

        if (isAccumulated() && repeations() != 0.0 && m_lastMatrix)
            m_transformMatrix->multiply(m_lastMatrix.get());
    }
    
    switch(m_type)
    {
        case SVG_TRANSFORM_TRANSLATE:
        {
            double dx = ((qToMatrix.dx() - qFromMatrix.dx()) * useTimePercentage) + qFromMatrix.dx();
            double dy = ((qToMatrix.dy() - qFromMatrix.dy()) * useTimePercentage) + qFromMatrix.dy();

            m_transformMatrix->translate(dx, dy);
            break;
        }
        case SVG_TRANSFORM_SCALE:
        {
            double sx = ((qToMatrix.m11() - qFromMatrix.m11()) * useTimePercentage) + qFromMatrix.m11();
            double sy = ((qToMatrix.m22() - qFromMatrix.m22()) * useTimePercentage) + qFromMatrix.m22();

            m_transformMatrix->scaleNonUniform(sx, sy);
            break;
        }
        case SVG_TRANSFORM_ROTATE:
        {
            double toAngle, toCx, toCy, fromAngle, fromCx, fromCy;
            calculateRotationFromMatrix(qToMatrix, toAngle, toCx, toCy);
            calculateRotationFromMatrix(qFromMatrix, fromAngle, fromCx, fromCy);

            if (m_toRotateSpecialCase) {
                if (lround(toAngle) == 1)
                    toAngle = 0.0;
                else
                    toAngle = 360.0;
            }

            if (m_fromRotateSpecialCase) {
                if (lround(fromAngle) == 1)
                    fromAngle = 0.0;
                else
                    fromAngle = 360.0;
            }
                    
            double angle = ((toAngle - fromAngle) * useTimePercentage) + fromAngle;
            double cx = (toCx - fromCx) * useTimePercentage + fromCx;
            double cy = (toCy - fromCy) * useTimePercentage + fromCy;

            m_transformMatrix->translate(cx, cy);
            m_transformMatrix->rotate(angle);
            m_transformMatrix->translate(-cx, -cy);
            break;
        }
        case SVG_TRANSFORM_SKEWX:
        {
            double sx = (SVGAngle::todeg(atan(qToMatrix.m21()) - atan(qFromMatrix.m21())) *
                         useTimePercentage) + SVGAngle::todeg(atan(qFromMatrix.m21()));

            m_transformMatrix->skewX(sx);
            break;
        }
        case SVG_TRANSFORM_SKEWY:
        {
            double sy = (SVGAngle::todeg(atan(qToMatrix.m12()) - atan(qFromMatrix.m12())) *
                         useTimePercentage) + SVGAngle::todeg(atan(qFromMatrix.m12()));

            m_transformMatrix->skewY(sy);
            break;
        }
        default:
            break;
    }

    // End condition.
    if (timePercentage == 1.0)
    {
        if ((m_repeatCount > 0 && m_repeations < m_repeatCount - 1) || isIndefinite(m_repeatCount))
        {
            m_lastMatrix = new SVGMatrix();
            
            if (m_transformMatrix)
                m_lastMatrix->copy(m_transformMatrix.get());

            m_repeations++;
            return;
        }

        ownerSVGElement()->timeScheduler()->disconnectIntervalTimer(this);
        m_connected = false;

        // Reset...
        m_currentItem = -1;
        m_toTransform = 0;
        m_fromTransform = 0;
        m_initialTransform = 0;

        if (!isFrozen()) {
            SVGMatrix *initial = initialMatrix();
            if (initial)
                m_transformMatrix = initial;
            else
                m_transformMatrix = new SVGMatrix();
        }
    }
}

RefPtr<SVGTransform> SVGAnimateTransformElement::parseTransformValue(const DeprecatedString &data) const
{
    DeprecatedString parse = data.stripWhiteSpace();
    if (parse.isEmpty())
        return 0;
    
    int commaPos = parse.find(','); // In case two values are passed...

    RefPtr<SVGTransform> parsedTransform = new SVGTransform();
    
    switch(m_type)
    {
        case SVG_TRANSFORM_TRANSLATE:
        {
            double tx = 0.0, ty = 0.0;
            if (commaPos != - 1) {
                tx = parse.mid(0, commaPos).toDouble();
                ty = parse.mid(commaPos + 1).toDouble();
            } else 
                tx = parse.toDouble();

            parsedTransform->setTranslate(tx, ty);
            break;    
        }
        case SVG_TRANSFORM_SCALE:
        {
            double sx = 1.0, sy = 1.0;
            if (commaPos != - 1) {
                sx = parse.mid(0, commaPos).toDouble();
                sy = parse.mid(commaPos + 1).toDouble();
            } else {
                sx = parse.toDouble();
                sy = sx;
            }

            parsedTransform->setScale(sx, sy);
            break;
        }
        case SVG_TRANSFORM_ROTATE:
        {
            double angle = 0, cx = 0, cy = 0;
            if (commaPos != - 1) {
                angle = parse.mid(0, commaPos).toDouble(); // TODO: probably needs it's own 'angle' parser
    
                int commaPosTwo = parse.find(',', commaPos + 1); // In case three values are passed...
                if (commaPosTwo != -1) {
                    cx = parse.mid(commaPos + 1, commaPosTwo - commaPos - 1).toDouble();
                    cy = parse.mid(commaPosTwo + 1).toDouble();
                }
            }
            else 
                angle = parse.toDouble();

            // Ok now here's a hack to make it possible to calculate cx/cy values, if angle = 0 
            // or angle=360 -> for angle=0 our matrix is m11: 1 m12: 0 m21: 0 m22: 1 dx: 0 dy: 0
            // As you can see there is no way to retrieve the cx/cy values for these angles.
            // -> set 'm_rotateSpecialCase' to true, and save angle = 1/359 -> this way we can calculate
            //    the cx/cy values, while keeping this uber-optimized way of handling <animateTransform>!
            m_rotateSpecialCase = false;
            
            if (angle == 0.0) {
                angle = angle + 1.0;
                m_rotateSpecialCase = true;
            } else if (angle == 360.0) {
                angle = angle - 1.0;
                m_rotateSpecialCase = true;
            }
            
            parsedTransform->setRotate(angle, cx, cy);
            break;    
        }
        case SVG_TRANSFORM_SKEWX:
        case SVG_TRANSFORM_SKEWY:
        {
            double angle = parse.toDouble(); // TODO: probably needs it's own 'angle' parser
            
            if (m_type == SVG_TRANSFORM_SKEWX)
                parsedTransform->setSkewX(angle);
            else
                parsedTransform->setSkewY(angle);

            break;
        }
        default:
            return 0;
    }
    
    return parsedTransform;
}

void SVGAnimateTransformElement::calculateRotationFromMatrix(const AffineTransform &matrix, double &angle, double &cx, double &cy) const
{
    double cosa = matrix.m11();
    double sina = -matrix.m21();

    if (cosa != 1.0)
    {
        // Calculate the angle via magic ;)
        double temp = SVGAngle::todeg(asin(sina));
        angle = SVGAngle::todeg(acos(cosa));
        if (temp < 0)
            angle = 360.0 - angle;
        
        double res = (1 - cosa) + ((sina * sina) / (1 - cosa));
        
        cx = (matrix.dx() - ((sina * matrix.dy()) / (1 - cosa))) / res;
        cy = (matrix.dy() + ((sina * matrix.dx()) / (1 - cosa))) / res;

        return;
    }

    cx = 0.0;
    cy = 0.0;
    angle = 0.0;
}

SVGMatrix *SVGAnimateTransformElement::initialMatrix() const
{
    if (!targetElement()->isStyledTransformable())
        return 0;
    SVGStyledTransformableElement *transform = static_cast<SVGStyledTransformableElement *>(targetElement());
    SVGTransformList *transformList = (transform ? transform->transform()->baseVal() : 0);
    if (!transformList)
        return 0;
    
    RefPtr<SVGTransform> result = transformList->concatenate();
    if (!result)
        return 0;

    SVGMatrix *ret = result->matrix();
    ret->ref();

    return ret;
}

SVGMatrix *SVGAnimateTransformElement::transformMatrix() const
{
    return m_transformMatrix.get();
}

}

// vim:ts=4:noet
#endif // SVG_SUPPORT

