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

// Elements
#include "elements/documentelement.h"
#include "elements/animatedlengthattr.h"
#include "elements/animateelement.h"
#include "elements/vectorelement.h"
#include "elements/vectorpath.h"
#include "elements/lengthattribute.h"
#include "elements/groupelement.h"
#include "elements/useelement.h"
#include "elements/defselement.h"
#include "elements/transformlist.h"
#include "elements/animatedtransformlist.h"
#include "elements/stylable.h"
#include "elements/fillattribute.h"
#include "elements/strokeattribute.h"
#include "elements/lineargradient.h"
#include "elements/stopelement.h"
#include "elements/animatedenum.h"
#include "elements/urireference.h"
#include "elements/animatednumber.h"
#include "elements/animatedcolorattr.h"

// Dockers
#include "dockers/attributelistview.h"

//  Qt
#include <qstring.h>

VPropertyItemCreator::VPropertyItemCreator( QListView *parent )
    : Visitor(),
    m_propParent(parent)
{}

VPropertyItemCreator::~VPropertyItemCreator()
{}

bool VPropertyItemCreator::visit( DocumentElement& element )
{
  appendPropItem( "Width",
                  new LengthListViewItem( &element, &element.width(), false,
                                              m_propParent,
                                              m_propItems.last() )
                );
  appendPropItem( "Height",
                  new LengthListViewItem( &element, &element.height(), false,
                                              m_propParent,
                                              m_propItems.last() )
                );
  return true;
}

bool VPropertyItemCreator::visit( VectorElement & element )
{
  visitAbstractTransformable(element);
  visitAbstractStylable(element);

  switch (element.vectorPath().shapeMetaType())
  {
  case VectorPath::SHAPE_LINE:
    appendPropItem( "X1",
                    new LengthListViewItem( &element, &element.vectorPath().getX1(), false,
                                                m_propParent,
                                                m_propItems.last() )
                  );
    appendPropItem( "Y1",
                    new LengthListViewItem( &element, &element.vectorPath().getY1(), false,
                                                m_propParent,
                                                m_propItems.last() )
                  );
    appendPropItem( "X2",
                    new LengthListViewItem( &element, &element.vectorPath().getX2(), false,
                                                m_propParent,
                                                m_propItems.last() )
                  );
    appendPropItem( "Y2",
                    new LengthListViewItem( &element, &element.vectorPath().getY2(), false,
                                                m_propParent,
                                                m_propItems.last() )
                  );
    break;
  case VectorPath::SHAPE_ELLIPSE:
    appendPropItem( "CX",
                    new LengthListViewItem( &element, &element.vectorPath().getX(), false,
                                                m_propParent,
                                                m_propItems.last() )
                  );
    appendPropItem( "CY",
                    new LengthListViewItem( &element, &element.vectorPath().getY(), false,
                                                m_propParent,
                                                m_propItems.last() )
                  );
    appendPropItem( "RX",
                    new LengthListViewItem( &element, &element.vectorPath().getRadiusX(), false,
                                                m_propParent,
                                                m_propItems.last() )
                  );
    appendPropItem( "RY",
                    new LengthListViewItem( &element, &element.vectorPath().getRadiusY(), false,
                                                m_propParent,
                                                m_propItems.last() )
                  );
    break;
  case VectorPath::SHAPE_RRECT:
    appendPropItem( "X",
                    new LengthListViewItem( &element, &element.vectorPath().getX(), false,
                                                m_propParent,
                                                m_propItems.last() )
                  );
    appendPropItem( "Y",
                    new LengthListViewItem( &element, &element.vectorPath().getY(), false,
                                                m_propParent,
                                                m_propItems.last() )
                  );
    appendPropItem( "Width",
                    new LengthListViewItem( &element, &element.vectorPath().getWidth(), false,
                                                m_propParent,
                                                m_propItems.last() )
                  );
    appendPropItem( "Height",
                    new LengthListViewItem( &element, &element.vectorPath().getHeight(), false,
                                                m_propParent,
                                                m_propItems.last() )
                  );
    appendPropItem( "RX",
                    new LengthListViewItem( &element, &element.vectorPath().getRadiusX(), false,
                                                m_propParent,
                                                m_propItems.last() )
                  );
    appendPropItem( "RY",
                    new LengthListViewItem( &element, &element.vectorPath().getRadiusY(), false,
                                                m_propParent,
                                                m_propItems.last() )
                  );
    break;
  case VectorPath::SHAPE_RECT:
    appendPropItem( "X",
                    new LengthListViewItem( &element, &element.vectorPath().getX(), false,
                                                m_propParent,
                                                m_propItems.last() )
                  );
    appendPropItem( "Y",
                    new LengthListViewItem( &element, &element.vectorPath().getY(), false,
                                                m_propParent,
                                                m_propItems.last() )
                  );
    appendPropItem( "Width",
                    new LengthListViewItem( &element, &element.vectorPath().getWidth(), false,
                                                m_propParent,
                                                m_propItems.last() )
                  );
    appendPropItem( "Height",
                    new LengthListViewItem( &element, &element.vectorPath().getHeight(), false,
                                                m_propParent,
                                                m_propItems.last() )
                  );
    break;
  case VectorPath::SHAPE_CIRCLE:
    appendPropItem( "CX",
                    new LengthListViewItem( &element, &element.vectorPath().getX(), false,
                                                m_propParent,
                                                m_propItems.last() )
                  );
    appendPropItem( "CY",
                    new LengthListViewItem( &element, &element.vectorPath().getY(), false,
                                                m_propParent,
                                                m_propItems.last() )
                  );
    appendPropItem( "Radius",
                    new LengthListViewItem( &element, &element.vectorPath().getRadius(), false,
                                                m_propParent,
                                                m_propItems.last() )
                  );
    break;
  default:
    break;
  }
  return true;
}

bool VPropertyItemCreator::visit( AnimateLengthElement & element )
{
  visitAbstractAnimateElement(element);
  appendPropItem( "from",
                  new LengthListViewItem( &element,
                    &element.fromAttribute(),
                    m_propParent,
                    m_propItems.last() )
                );
  appendPropItem( "by",
                  new LengthListViewItem( &element,
                    &element.byAttribute(),
                    m_propParent,
                    m_propItems.last() )
                );
  appendPropItem( "to",
                  new LengthListViewItem( &element,
                    &element.toAttribute(),
                    m_propParent,
                    m_propItems.last() )
                );
  return true;
}

bool VPropertyItemCreator::visit( AnimateTransformElement & element )
{
  visitAbstractAnimateElement(element);
  appendPropItem( "from",
                  new TransformListViewItem( &element,
                    &element.fromAttribute(),
                    m_propParent,
                    m_propItems.last() )
                );
  appendPropItem( "by",
                  new TransformListViewItem( &element,
                    &element.byAttribute(),
                    m_propParent,
                    m_propItems.last() )
                );
  appendPropItem( "to",
                  new TransformListViewItem( &element,
                    &element.toAttribute(),
                    m_propParent,
                    m_propItems.last() )
                );
  return true;
}

bool VPropertyItemCreator::visit( GroupElement & element )
{
  visitAbstractTransformable(element);
  visitAbstractStylable(element);
  return true;
}

bool VPropertyItemCreator::visit( UseElement & element )
{
  visitAbstractTransformable(element);
  appendPropItem( "href",
                  new URIRefListViewItem( &element,
                    &element.ref(),
                    m_propParent,
                    m_propItems.last() )
                );
  return true;
}

bool VPropertyItemCreator::visit( DefsElement & element )
{
  visitAbstractTransformable(element);
  return true;
}

bool VPropertyItemCreator::visit( StopElement & element )
{
  appendPropItem( "offset",
                  new NumberListViewItem( &element,
                    &element.getOffset(), false,
                    m_propParent,
                    m_propItems.last() )
                );
  appendPropItem( "stop-color",
                  new ColorListViewItem( &element,
                    &element.getStopColor(), false,
                    m_propParent,
                    m_propItems.last() )
                );
  appendPropItem( "stop-opacity",
                  new NumberListViewItem( &element,
                    &element.getStopOpacity(), false,
                    m_propParent,
                    m_propItems.last() )
                );
  return true;
}

bool VPropertyItemCreator::visit( LinearGradient & element )
{
  visitAbstractGradient(element);
  appendPropItem( "x1",
                  new LengthListViewItem( &element,
                    &element.getX1(), false,
                    m_propParent,
                    m_propItems.last() )
                );
  appendPropItem( "y1",
                  new LengthListViewItem( &element,
                    &element.getY1(), false,
                    m_propParent,
                    m_propItems.last() )
                );
  appendPropItem( "x2",
                  new LengthListViewItem( &element,
                    &element.getX2(), false,
                    m_propParent,
                    m_propItems.last() )
                );
  appendPropItem( "y2",
                  new LengthListViewItem( &element,
                    &element.getY2(), false,
                    m_propParent,
                    m_propItems.last() )
                );
  return true;
}










/**
 * Visit abstract AnimateElement class (call from visit(CLASS) methods)
 * @param element 
 * @return 
 */
bool VPropertyItemCreator::visitAbstractAnimateElement( AnimateElement& element )
{
  appendPropItem( "begin",
                  new TimeListViewItem( &element,
                    &element.getStartTime(),
                    m_propParent,
                    m_propItems.last() )
                );
  appendPropItem( "duration",
                  new TimeListViewItem( &element,
                    &element.getSimpleDuration(),
                    m_propParent,
                    m_propItems.last() )
                );
  return true;
}

/**
 * Visit abstract Gradient class (call from visit(CLASS) methods)
 * @param element 
 * @return 
 */
bool VPropertyItemCreator::visitAbstractGradient( Gradient & element )
{
  appendPropItem( "href",
                  new URIRefListViewItem( &element,
                    &element.ref(),
                    m_propParent,
                    m_propItems.last() )
                );
  appendPropItem( "gradientUnits",
                  new EnumListViewItem( &element,
                    &element.gradientUnits().baseVal(),
                    m_propParent,
                    m_propItems.last() )
                );
  appendPropItem( "spreadmethod",
                  new EnumListViewItem( &element,
                    &element.spreadMethod().baseVal(),
                    m_propParent,
                    m_propItems.last() )
                );

  for(unsigned int i = 0; i < element.gradientTransformList().baseVal().count(); i++)
  {
    appendPropItem( "GradientTransform",
                    new TransformListViewItem( &element,
                      element.gradientTransformList().baseVal().at(i),
                      m_propParent,
                      m_propItems.last() )
                  );
  }
  return true;
}

/**
 * Visit abstract Transformable class (call from visit(CLASS) methods)
 * @param element 
 * @return 
 */
bool VPropertyItemCreator::visitAbstractTransformable( Transformable &element )
{
  for(unsigned int i = 0; i < element.transformList().baseVal().count(); i++)
  {
    appendPropItem( "Transform",
                    new TransformListViewItem( &element,
                      element.transformList().baseVal().at(i),
                      m_propParent,
                      m_propItems.last() )
                  );
  }
  return true;
}


/**
 * Visit abstract Stylable class (call from visit(CLASS) methods)
 * @param element 
 * @return 
 */
bool VPropertyItemCreator::visitAbstractStylable( Stylable &element )
{
  appendPropItem( "FillType",
                  new FillAttrListViewItem( &element,
                    &element.fill(),
                    m_propParent,
                    m_propItems.last() )
                );
  appendPropItem( "Fill href",
                  new URIRefListViewItem( &element,
                    &element.fill().ref(),
                    m_propParent,
                    m_propItems.last() )
                );
  appendPropItem( "FillOpacity",
                  new NumberListViewItem( &element,
                    &element.fill().fillOpacity(), false,
                    m_propParent,
                    m_propItems.last() )
                );
  appendPropItem( "FillColor",
                  new ColorListViewItem( &element,
                    &element.fill().color(), false,
                    m_propParent,
                    m_propItems.last() )
                );

  appendPropItem( "StrokeType",
                  new StrokeAttrListViewItem( &element,
                    &element.stroke(),
                    m_propParent,
                    m_propItems.last() )
                );
  appendPropItem( "Stroke href",
                  new URIRefListViewItem( &element,
                    &element.stroke().ref(),
                    m_propParent,
                    m_propItems.last() )
                );
  appendPropItem( "StrokeOpacity",
                  new NumberListViewItem( &element,
                    &element.stroke().strokeOpacity(), false,
                    m_propParent,
                    m_propItems.last() )
                );
  appendPropItem( "StrokeWidth",
                  new NumberListViewItem( &element,
                    &element.stroke().strokeWidth(), false,
                    m_propParent,
                    m_propItems.last() )
                );
  appendPropItem( "StrokeColor",
                  new ColorListViewItem( &element,
                    &element.stroke().color(), false,
                    m_propParent,
                    m_propItems.last() )
                );

  return true;
}

/**
 * Use internally to add a new Item to the ListView and name it
 */
void VPropertyItemCreator::appendPropItem( QString name, AttributeListViewItem* item )
{
  m_propItems.append( item );
  m_propItems.last()->setText( 0, name );

}




