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

// Elements
#include "animatedlengthattr.h"
#include "lengthattribute.h"
#include "urireference.h"

// Visitors
#include "visitors/visitor.h"

RadialGradient::RadialGradient()
    : Gradient()
{
  init();
}


RadialGradient::~RadialGradient()
{
  delete m_cx;
  delete m_cy;
  delete m_r;
  delete m_fx;
  delete m_fy;
}


RadialGradient::RadialGradient( const RadialGradient &other )
    : Gradient()
{
  init();
  (*this) = other;
}

RadialGradient& RadialGradient::operator=(const RadialGradient &other)
{
  Gradient::operator=(other);
  *m_cx = other.getCX();
  *m_cy = other.getCY();
  *m_r = other.getR();
  *m_fx = other.getFX();
  *m_fy = other.getFY();
  return *this;
}

RadialGradient& RadialGradient::operator|=(const RadialGradient &other)
{
  Gradient::operator=(other);
  *m_cx = other.getCX(true);
  *m_cy = other.getCY(true);
  *m_r = other.getR(true);
  *m_fx = other.getFX(true);
  *m_fy = other.getFY(true);
  return *this;
}

ElementNode* RadialGradient::clone()
{
  RadialGradient* retElem = new RadialGradient();
  *retElem = *this;
  return ( retElem );
}

/**
 * Set the SVG spec's defaults
 */
void RadialGradient::init()
{
  m_cx = new AnimatedLength();
  m_cx->baseVal().newValueSpecifiedUnits(LengthAttribute::SVG_LENGTHTYPE_PERCENTAGE, 50);
  m_cx->baseVal().setValid(false);
  m_cy = new AnimatedLength();
  m_cy->baseVal().newValueSpecifiedUnits(LengthAttribute::SVG_LENGTHTYPE_PERCENTAGE, 50);
  m_cy->baseVal().setValid(false);
  m_r = new AnimatedLength();
  m_r->baseVal().newValueSpecifiedUnits(LengthAttribute::SVG_LENGTHTYPE_PERCENTAGE, 50);
  m_r->baseVal().setValid(false);
  m_fx = new AnimatedLength();
  m_fx->baseVal().setValid(false);
  m_fy = new AnimatedLength();
  m_fy->baseVal().setValid(false);
}

void RadialGradient::accept( Visitor& visitor )
{
  visitor.visit( *this );
}


AnimatedLength & RadialGradient::getCX( bool inherited ) const
{
  if ( inherited && !m_cx->isValid() )
  {
    if ( m_ref->getRefElement() && m_ref->getRefElement()->inherits("RadialGradient") )
    {
      RadialGradient* ref = static_cast<RadialGradient*>(m_ref->getRefElement());
      AnimatedLength& inheritedAttr = ref->getCX(true);
      if ( inheritedAttr.isValid() )
        return inheritedAttr;
    }
  }
  return *m_cx;
}

AnimatedLength & RadialGradient::getCY( bool inherited ) const
{
  if ( inherited && !m_cy->isValid() )
  {
    if ( m_ref->getRefElement() && m_ref->getRefElement()->inherits("RadialGradient") )
    {
      RadialGradient* ref = static_cast<RadialGradient*>(m_ref->getRefElement());
      AnimatedLength& inheritedAttr = ref->getCY(true);
      if ( inheritedAttr.isValid() )
        return inheritedAttr;
    }
  }
  return *m_cy;
}

AnimatedLength & RadialGradient::getR( bool inherited ) const
{
  if ( inherited && !m_r->isValid() )
  {
    if ( m_ref->getRefElement() && m_ref->getRefElement()->inherits("RadialGradient") )
    {
      RadialGradient* ref = static_cast<RadialGradient*>(m_ref->getRefElement());
      AnimatedLength& inheritedAttr = ref->getR(true);
      if ( inheritedAttr.isValid() )
        return inheritedAttr;
    }
  }
  return *m_r;
}

AnimatedLength & RadialGradient::getFX( bool inherited ) const
{
  if ( inherited && !m_fx->isValid() )
  {
    if ( m_ref->getRefElement() && m_ref->getRefElement()->inherits("RadialGradient") )
    {
      RadialGradient* ref = static_cast<RadialGradient*>(m_ref->getRefElement());
      AnimatedLength& inheritedAttr = ref->getFX(true);
      if ( inheritedAttr.isValid() )
        return inheritedAttr;
    }
  }
  return *m_fx;
}

AnimatedLength & RadialGradient::getFY( bool inherited ) const
{
  if ( inherited && !m_fy->isValid() )
  {
    if ( m_ref->getRefElement() && m_ref->getRefElement()->inherits("RadialGradient") )
    {
      RadialGradient* ref = static_cast<RadialGradient*>(m_ref->getRefElement());
      AnimatedLength& inheritedAttr = ref->getFY(true);
      if ( inheritedAttr.isValid() )
        return inheritedAttr;
    }
  }
  return *m_fy;
}

Attribute * RadialGradient::getAttrByName( const QString & name )
{
  if (name == "cx")
    return m_cx;
  else if (name == "cy")
    return m_cy;
  else if (name == "r")
    return m_r;
  else if (name == "fx")
    return m_fx;
  else if (name == "fy")
    return m_fy;
  else
    return Gradient::getAttrByName( name );
}
#include "radialgradient.moc"
