/*
**************************************************************************
                                 description
                             -------------------
    and                  : (C) 2002 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 "pmlookslike.h"

#include "pmoutputdevice.h"
#include "pmxmlhelper.h"
#include "pmmemento.h"
#include "pmnamedobjectedit.h"

#include <kdebug.h>
#include "pmglobals.h"

#include <klocale.h>

PMLooksLike::PMLooksLike( )
      : Base( )
{
}

PMLooksLike::~PMLooksLike( )
{
}


QString PMLooksLike::description( ) const
{
   return i18n( "looks like" );
}

bool PMLooksLike::isA( PMObjectType t ) const
{
   if( t == PMTLooksLike )
      return true;
   return Base::isA( t );
}

void PMLooksLike::serialize( PMOutputDevice& dev ) const
{
   dev.objectBegin( "looks_like" );
   serializeName( dev );
   Base::serialize( dev );
   dev.objectEnd( );
}

void PMLooksLike::serialize( QDomElement& e, QDomDocument& doc ) const
{
   Base::serialize( e, doc );
}

void PMLooksLike::readAttributes( const PMXMLHelper& h )
{
   Base::readAttributes( h );
}

PMDialogEditBase* PMLooksLike::editWidget( QWidget* parent ) const
{
   return new PMNamedObjectEdit( parent );
}

void PMLooksLike::restoreMemento( PMMemento* s )
{
   Base::restoreMemento( s );
}

bool PMLooksLike::containsObject( ) const
{
   bool result = false;
   PMObject* o = firstChild( );
   while( o && !result )
   {
      if( o->type( ) != PMTComment && o->type( ) != PMTRaw )
         result = true;
      o = o->nextSibling( );
   }
   return result;
}

bool PMLooksLike::canInsert( PMObjectType t ) const
{
   switch( t )
   {
      case PMTComment:
      case PMTRaw:
      case PMTBox:
      case PMTSphere:
      case PMTCylinder:
      case PMTCone:
      case PMTTorus:
      case PMTLathe:
      case PMTPrism:
      case PMTBlob:
      case PMTSurfaceOfRevolution:
      case PMTSuperquadricEllipsoid:
      case PMTJuliaFractal:
      case PMTHeightField:
      case PMTText:
      case PMTPlane:
      case PMTPolynom:
      case PMTDisc:
      case PMTBicubicPatch:
      case PMTTriangle:
      case PMTCSG:
      case PMTObjectLink:
         return true;
      default:
         break;
   }
   return false;
}

bool PMLooksLike::canInsert( PMObjectType t, const PMObject* ,
                             const PMObjectList* objectsBetween ) const
{
   if( t == PMTComment || t == PMTRaw )
      return true;
   
   bool objects = containsObject( );
   if( objectsBetween )
   {
      PMObjectListIterator it( *objectsBetween );
      for( ; it.current( ); ++it )
         if( it.current( )->type( ) != PMTComment
             && it.current( )->type( ) != PMTRaw )
            objects = true; 
   }

   if( objects )
      return false;
   return canInsert( t );
}

int PMLooksLike::canInsert( const QValueList<PMObjectType>& list,
                            const PMObject* ) const
{
   bool objects = containsObject( );
   QValueList<PMObjectType>::ConstIterator it;
   int num = 0;
   
   for( it = list.begin( ); it != list.end( ); ++it )
   {
      if( ( *it ) == PMTComment || ( *it ) == PMTRaw )
         num++;
      else if( !objects && canInsert( *it ) )
      {
         objects = true;
         num++;
      }
   }
   return num;
}

int PMLooksLike::canInsert( const PMObjectList& list,
                            const PMObject* ) const
{
   bool objects = containsObject( );
   PMObjectListIterator it( list );
   int num = 0;
   
   for( ; it.current( ); ++it )
   {
      if( it.current( )->type( ) == PMTComment
          || it.current( )->type( ) == PMTRaw )
         num++;
      else if( !objects && canInsert( it.current( )->type( ) ) )
      {
         objects = true;
         num++;
      }
   }
   return num;
}
