/***************************************************************************
 *   Copyright (C) 2004 by Hans Oischinger                                 *
 *   hans.oischinger@kdemail.net                                           *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program 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 General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA.             *
 ***************************************************************************/
#include "vconsolidatetransform.h"

// Elements
#include "elements/elementtreeiterator.h"
#include "elements/vectorelement.h"

#include "elements/documentelement.h"
#include "elements/animateelement.h"
#include "elements/animatedlengthattr.h"
#include "elements/animatedcolorattr.h"
#include "elements/lengthattribute.h"
#include "elements/fillattribute.h"
#include "elements/strokeattribute.h"
#include "elements/colorattribute.h"
#include "elements/vectorpath.h"
#include "elements/matrix.h"
#include "elements/animatedtransformlist.h"
#include "elements/transformlist.h"
#include "elements/transformable.h"
#include "elements/groupelement.h"
#include "elements/useelement.h"
#include "elements/defselement.h"
#include "elements/transformlist.h"

// KDE
#include <kdebug.h>

VConsolidateTransform::VConsolidateTransform()
    : Visitor(),
    m_processAnimvals(true)
{
  m_matrix = new Matrix();
}


VConsolidateTransform::~VConsolidateTransform()
{
  delete m_matrix;
}

bool VConsolidateTransform::visit( VectorElement& element )
{
  if ( element.getState() == Element::deleted )
    return false;

  consolidateTransformable( element );
  return true;
}

bool VConsolidateTransform::visit( GroupElement& element )
{
  if ( element.getState() == Element::deleted )
    return false;

  consolidateTransformable( element );
  return true;
}

bool VConsolidateTransform::visit( UseElement& element )
{
  if ( element.getState() == Element::deleted )
    return false;

  consolidateTransformable( element );
  return true;
}

bool VConsolidateTransform::visit( DefsElement& element )
{
  if ( element.getState() == Element::deleted )
    return false;

  consolidateTransformable( element );
  return true;
}

void VConsolidateTransform::consolidateTransformable( Transformable& element )
{
  Transform* consolidatedTrans = new Transform();
  if (m_processAnimvals)
    element.transformList().animVal().consolidate( *consolidatedTrans );
  else
    element.transformList().baseVal().consolidate( *consolidatedTrans );

  /*  kdDebug() << consolidatedTrans->matrix()->a() << "  " << consolidatedTrans->matrix()->c() << "  " << consolidatedTrans->matrix()->e() << endl;
    kdDebug() << consolidatedTrans->matrix()->b() << "  " << consolidatedTrans->matrix()->d() << "  " << consolidatedTrans->matrix()->f() << endl;*/

  m_matrix->postMultiply( *consolidatedTrans->matrix() );
  delete consolidatedTrans;
}


Matrix* VConsolidateTransform::calcCTM( ElementNode& element, bool processAnimvals, bool discardOwn )
{
  ElementNode *currentElement = &element;

  VConsolidateTransform* vConsTransform = new VConsolidateTransform();
  vConsTransform->setProcessAnimvals(processAnimvals);
  while (currentElement)
  {
    // kdDebug() << "XX " << currentElement->className() << endl;
    if ( !(discardOwn && &element == currentElement) )
      currentElement->accept( *vConsTransform );
    currentElement = currentElement->getParent();
    // Set m_processAnimvals back to true after the first element:
    if ( !vConsTransform->getProcessAnimvals() )
      vConsTransform->setProcessAnimvals(true);
  }

  Matrix* retMatrix = new Matrix(vConsTransform->ctm().qmatrix());
  // kdDebug() << k_funcinfo << endl;
  // kdDebug() << retMatrix->a() << "  " << retMatrix->c() << "  " << retMatrix->e() << endl;
  // kdDebug() << retMatrix->b() << "  " << retMatrix->d() << "  " << retMatrix->f() << endl;

  delete vConsTransform;
  return retMatrix;
}


