/***************************************************************************
 *   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 "svgserializer.h"

// Elements
#include "elements/elementnode.h"
#include "elements/vectorelement.h"
#include "elements/groupelement.h"
#include "elements/defselement.h"
#include "elements/useelement.h"
#include "elements/stopelement.h"
#include "elements/lineargradient.h"
#include "elements/radialgradient.h"
#include "elements/animateelement.h"
#include "elements/vectorpath.h"
#include "elements/fillattribute.h"
#include "elements/strokeattribute.h"
#include "elements/animatedlengthattr.h"
#include "elements/lengthattribute.h"
#include "elements/animatedcolorattr.h"
#include "elements/colorattribute.h"
#include "elements/fillattribute.h"
#include "elements/strokeattribute.h"
#include "elements/animatednumber.h"
#include "elements/number.h"
#include "elements/transformlist.h"
#include "elements/animatedtransformlist.h"
#include "elements/enumeration.h"
#include "elements/animatedenum.h"

SVGSerializer::SVGSerializer()
    : Visitor()
{}

SVGSerializer::~SVGSerializer()
{}

QString SVGSerializer::serializeAttribute( ElementNode & element, Attribute * attr )
{
  m_svgAttribute = QString::null;
  if (!attr)
    return m_svgAttribute;
  m_attr = attr;
  element.accept( *this );
  return m_svgAttribute;
}

bool SVGSerializer::visit( VectorElement & element )
{
  if ( processTransformable( element ) )
    return true;
  if ( processStylable( element ) )
    return true;

  switch(element.vectorPath().shapeMetaType())
  {
  case VectorPath::SHAPE_CIRCLE:
    if (m_attr == &element.vectorPath().getX())
      m_svgAttribute = "cx";
    else if (m_attr == &element.vectorPath().getY())
      m_svgAttribute = "cy";
    else if (m_attr == &element.vectorPath().getRadius())
      m_svgAttribute = "r";
    break;
  case VectorPath::SHAPE_RECT:
  case VectorPath::SHAPE_RRECT:
    if (m_attr == &element.vectorPath().getX())
      m_svgAttribute = "x";
    else if (m_attr == &element.vectorPath().getY())
      m_svgAttribute = "y";
    else if (m_attr == &element.vectorPath().getWidth())
      m_svgAttribute = "width";
    else if (m_attr == &element.vectorPath().getHeight())
      m_svgAttribute = "height";
    else if (m_attr == &element.vectorPath().getRX())
      m_svgAttribute = "rx";
    else if (m_attr == &element.vectorPath().getRY())
      m_svgAttribute = "ry";
    break;
  case VectorPath::SHAPE_ELLIPSE:
    if (m_attr == &element.vectorPath().getX())
      m_svgAttribute = "cx";
    else if (m_attr == &element.vectorPath().getY())
      m_svgAttribute = "cy";
    else if (m_attr == &element.vectorPath().getRadiusX())
      m_svgAttribute = "rx";
    else if (m_attr == &element.vectorPath().getRadiusY())
      m_svgAttribute = "ry";
    break;
  case VectorPath::SHAPE_LINE:
    if (m_attr == &element.vectorPath().getX1())
      m_svgAttribute = "x1";
    else if (m_attr == &element.vectorPath().getY1())
      m_svgAttribute = "y1";
    else if (m_attr == &element.vectorPath().getX2())
      m_svgAttribute = "x2";
    else if (m_attr == &element.vectorPath().getY2())
      m_svgAttribute = "y2";
    break;
  case VectorPath::SHAPE_POLYLINE:
  case VectorPath::SHAPE_POLYGON:
    break;
  case VectorPath::SHAPE_PATH:
    break;
  case VectorPath::SHAPE_NONE:
    break;
  }

  return true;
}

bool SVGSerializer::visit( GroupElement & element )
{
  if ( !processTransformable(element) )
    processStylable(element);
  return true;
}

bool SVGSerializer::visit( DefsElement & element )
{
  if ( !processTransformable(element) )
    processStylable(element);
  return true;
}

bool SVGSerializer::visit( UseElement & element )
{
  if ( !processTransformable(element) )
    processStylable(element);
  return true;
}

bool SVGSerializer::visit( StopElement & element )
{
  if ( m_attr == &element.getOffset() )
    m_svgAttribute = "offset";
  else if ( m_attr == &element.getStopColor() )
    m_svgAttribute = "stop-color";
  else if ( m_attr == &element.getStopOpacity() )
    m_svgAttribute = "stop-opacity";

  return true;
}

bool SVGSerializer::visit( LinearGradient & element )
{
  if ( processGradient( element ) )
    return true;

  if ( m_attr == &element.getX1() )
    m_svgAttribute = "x1";
  else if ( m_attr == &element.getX2() )
    m_svgAttribute = "x2";
  else if ( m_attr == &element.getY1() )
    m_svgAttribute = "y1";
  else if ( m_attr == &element.getY2() )
    m_svgAttribute = "y2";

  return true;
}

bool SVGSerializer::visit( RadialGradient & element )
{
  if ( processGradient( element ) )
    return true;

  if ( m_attr == &element.getCX() )
    m_svgAttribute = "cx";
  else if ( m_attr == &element.getCY() )
    m_svgAttribute = "cy";
  else if ( m_attr == &element.getR() )
    m_svgAttribute = "r";
  else if ( m_attr == &element.getFX() )
    m_svgAttribute = "fx";
  else if ( m_attr == &element.getFY() )
    m_svgAttribute = "fy";

  return true;
}

bool SVGSerializer::visit( AnimateTransformElement & element )
{
  // TODO!!!
}

bool SVGSerializer::visit( AnimateLengthElement & element )
{
  // TODO!!!
}

bool SVGSerializer::visit( AnimateNumberElement & element )
{
  // TODO!!!
}

bool SVGSerializer::processStylable( Stylable & element )
{
  if ( m_attr == &element.fill().fillOpacity() )
    m_svgAttribute = "fill-opacity";
  else if ( m_attr == &element.stroke().strokeOpacity() )
    m_svgAttribute = "stroke-opacity";
  else if ( m_attr == &element.stroke().strokeWidth() )
    m_svgAttribute = "stroke-width";
  else
    return false;
  return true;
}

bool SVGSerializer::processTransformable( Transformable & element )
{
  if ( m_attr == &element.transformList() )
    m_svgAttribute = "transform";
  else
    return false;
  return true;
}

bool SVGSerializer::processGradient( Gradient & element )
{
  if ( m_attr == &element.gradientTransformList() )
    m_svgAttribute = "gradienttransform";
  else if ( m_attr == &element.gradientUnits() )
    m_svgAttribute = "gradientUnits";
  else if ( m_attr == &element.spreadMethod() )
    m_svgAttribute = "spreadMethod";
  else
    return false;
  return true;
}

bool SVGSerializer::processElementNode( ElementNode & element )
{
  // Nothing to do yet
  return true;
}

bool SVGSerializer::processAnimateElement( AnimateElement & element )
{
  // TODO!!!
}
