/***************************************************************************
 *   Copyright (C) 2004 by Hans Oischinger                                 *
 *   oisch@users.berlios.de                                                *
 *                                                                         *
 *   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 "vectorpath.h"

// Elements
#include "animatedlengthattr.h"

// KCanvas
#include <kcanvas/KCanvas.h>
#include <kcanvas/KCanvasPath.h>
#include <kcanvas/KCanvasItem.h>

// Qt
#include <qpoint.h>

// KDE
#include <kdebug.h>

#include <math.h>

VectorPath::VectorPath(ShapeMetaType type) :
    m_shapeMetaType(type)
{
  m_x1 = new AnimatedLength();
  m_y1 = new AnimatedLength();
  m_x2 = new AnimatedLength();
  m_y2 = new AnimatedLength();
  m_x3 = new AnimatedLength();
  m_y3 = new AnimatedLength();

  m_pathData = new KCPathDataList();
}


VectorPath::~VectorPath()
{}

VectorPath::VectorPath( const VectorPath &other )
{
  (*this) = other;
}

VectorPath& VectorPath::operator=(const VectorPath &other)
{
  m_shapeMetaType = other.shapeMetaType();
  delete m_pathData;

  m_pathData = new KCPathDataList(*(other.m_pathData));

  delete m_x1;
  delete m_x2;
  delete m_x3;
  delete m_y1;
  delete m_y2;
  delete m_y3;
  m_x1 = new AnimatedLength(other.getX1());
  m_y1 = new AnimatedLength(other.getY1());
  m_x2 = new AnimatedLength(other.getX2());
  m_y2 = new AnimatedLength(other.getY2());
  m_x3 = new AnimatedLength(other.getX3());
  m_y3 = new AnimatedLength(other.getY3());

  return *this;
}

VectorPath* VectorPath::clone()
{
  VectorPath* retElem = new VectorPath( m_shapeMetaType );
  *retElem = *this;
  return ( retElem );
}

void VectorPath::moveTo(double x, double y, bool abs)
{
  m_pathData->moveTo(x,y);
}

void VectorPath::lineTo(double x, double y, bool abs)
{
  if (!abs)
  {
    x+=m_pathData->last().x3;
    y+=m_pathData->last().y3;
  }
  m_pathData->lineTo(x,y);
}

void VectorPath::lineToHorizontal(double x, bool abs)
{
  double y = 0;
  if (!abs)
  {
    x+= m_pathData->last().x3;
    y = m_pathData->last().y3;
  }
  m_pathData->lineTo(x,y);
}

void VectorPath::lineToVertical(double y, bool abs)
{
  double x = 0;
  if (!abs)
  {
    y+= m_pathData->last().y3;
    x = m_pathData->last().x3;
  }
  m_pathData->lineTo(x,y);
}

void VectorPath::curveTo(double x1, double y1, double x2, double y2, double x, double y, bool abs)
{
  if (!abs)
  {
    x += m_pathData->last().x3;
    y += m_pathData->last().y3;
    x1 += m_pathData->last().x3;
    y1 += m_pathData->last().y3;
    x2 += m_pathData->last().x3;
    y2 += m_pathData->last().y3;
  }
  m_pathData->curveTo(x1,y1,x2,y2,x,y);
}

void VectorPath::curveToCubicSmooth(double x2, double y2, double x, double y, bool absolute)
{
  if (!absolute)
  {
    x += m_pathData->last().x3;
    y += m_pathData->last().y3;
    x2 += m_pathData->last().x3;
    y2 += m_pathData->last().y3;
  }

  double x1 = m_pathData->last().x3;
  double y1 = m_pathData->last().y3;
  if ( m_pathData->last().cmd == CMD_CURVE )
  {
    x1 += m_pathData->last().x3 - m_pathData->last().x2;
    y1 += m_pathData->last().y3 - m_pathData->last().y2;
  }
  m_pathData->curveTo(x1,y1,x2,y2,x,y);
}

#include <math.h>

void VectorPath::curveToArc( double x, double y, double r1, double r2, double angle, bool largeArcFlag, bool sweepFlag, bool abs )
{
  // TODO: Implement
}

void VectorPath::closePath()
{
  lineTo( m_pathData->first().x3, m_pathData->first().y3 );
}

QPoint VectorPath::currentPoint()
{
  KCPathData pathData = m_pathData->last();
  return QPoint(pathData.x3, pathData.y3);
}

QString VectorPath::getReadeableShapeMetaType( )
{
  switch(m_shapeMetaType)
  {
  case SHAPE_NONE:
    return "None";
    break;
  case SHAPE_CIRCLE:
    return "Circle";
    break;
  case SHAPE_RECT:
    return "Rectangle";
    break;
  case SHAPE_RRECT:
    return "Rounded Rectangle";
    break;
  case SHAPE_ELLIPSE:
    return "Ellipse";
    break;
  case SHAPE_LINE:
    return "Line";
    break;
  case SHAPE_POLYLINE:
    return "Polyline";
    break;
  case SHAPE_POLYGON:
    return "Polygon";
    break;
  case SHAPE_PATH:
    return "Path";
    break;
  }
  return "None";
}

Attribute * VectorPath::getAttrByName( const QString & name )
{
  if (name == "x" || name == "cx" || name == "x1")
    return m_x1;
  else if (name == "y" || name == "cy" || name == "y1")
    return m_y1;
  else if (name == "width" || name == "x2" || name == "r")
    return m_x2;
  else if (name == "height" || name == "y2" )
    return m_y2;
  else if ( name == "rx" || name == "x3" )
    return m_x3;
  else if ( name == "ry" || name == "y3" )
    return m_y3;
  else
    return 0;
}

