/*
**************************************************************************
                                 description
                             --------------------
    copyright            : (C) 2000-2001 by Andreas Zehender
    email                : zehender@kde.org
**************************************************************************

**************************************************************************
*                                                                        *
*  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.                                   *
*                                                                        *
**************************************************************************/


#include "pmobject.h"
#include "pmcontrolpoint.h"
#include "pmglobals.h"
#include "pmdialogeditbase.h"
#include "pmmemento.h"


PMObject::PMObject( )
{
   m_pParent = 0;
   m_selected = false;
   m_pPrevSibling = 0;
   m_pNextSibling = 0;
   m_pMemento = 0;
   m_readOnly = false;
}

PMObject::~PMObject( )
{
}

bool PMObject::isA( PMObjectType t ) const
{
   if( t == PMTObject )
      return true;
   return false;
}

bool PMObject::insertChildAfter( PMObject*, PMObject* )
{
   kdError( PMArea ) << "Tried to insert object into a non composite object" << "\n";
   return false;
}

bool PMObject::insertChildBefore( PMObject*, PMObject* )
{
   kdError( PMArea ) << "Tried to insert object into a non composite object" << "\n";
   return false;
}

void PMObject::setSelected( bool s )
{
   if( m_selected != s )
   {
      if( s )
      {
         if( isSelectable( ) )
         {
            m_selected = true;
            if( m_pParent )
               m_pParent->adjustSelectedChildren( 1 );
         }
      }
      else
      {
         m_selected = false;
         if( m_pParent )
            m_pParent->adjustSelectedChildren( -1 );
      }
   }
}

bool PMObject::isSelectable( )
{
   bool is = true;
   PMObject* o;

   for( o = m_pParent; o && is; o = o->m_pParent )
      if( o->isSelected( ) )
         is = false;
   
   return is;
}

bool PMObject::isReadOnly( ) const
{
   if( m_readOnly )
      return true;
   if( m_pParent )
      return m_pParent->isReadOnly( );
   return false;
}

bool PMObject::takeChild( PMObject* )
{
   kdError( PMArea ) << "Tried to remove object out of a non composite object" << "\n";
   return false;
}

bool PMObject::takeChild( uint )
{
   kdError( PMArea ) << "Tried to remove object out of a non composite object" << "\n";
   return false;
}

PMDialogEditBase* PMObject::editWidget( QWidget* parent ) const
{
   return new PMDialogEditBase( parent );
//   return 0;
}

void PMObject::createMemento( )
{
   if( m_pMemento )
      delete m_pMemento;
   m_pMemento = new PMMemento( this );
}

PMMemento* PMObject::takeMemento( )
{
   PMMemento* tmp = m_pMemento;
   m_pMemento = 0;
   return tmp;
}

void PMObject::restoreMemento( PMMemento* /* s */ )
{
   // nothing to be done at the moment
}

PMMatrix PMObject::transformedWith( ) const
{
   PMMatrix result = PMMatrix::identity( );
   const PMObject* o = this;

   if( o->firstChild( ) )
      o = o->firstChild( );
   else if( o->nextSibling( ) )
      o = o->nextSibling( );
   else
      o = o->parent( );
   
   while( o )
   {
      if( o->hasTransformationMatrix( ) )
         result = o->transformationMatrix( ) * result;
      
      if( o->nextSibling( ) )
         o = o->nextSibling( );
      else
         o = o->parent( );
   }
   
   return result;   
}

QDomElement PMObject::serialize( QDomDocument& doc ) const
{
   QDomElement e = doc.createElement( className( ) );
   serialize( e, doc );
   return e;
}

void PMObject::readAttributes( const PMXMLHelper& )
{
}

int PMObject::canInsert( const PMObjectList& list,
                         const PMObject* after ) const
{
   int num = 0;
   PMObjectListIterator it( list );
   
   for( ; it.current( ); ++it )
      if( canInsert( it.current( ), after ) )
         num++;
   return num;
}

int PMObject::canInsert( const QValueList<PMObjectType>& list,
                         const PMObject* after ) const
{
   int num = 0;
   QValueList<PMObjectType>::ConstIterator it;
   
   for( it = list.begin( ); it != list.end( ); ++it )
      if( canInsert( *it, after ) )
         num++;
   return num;
}
