/*
**************************************************************************
                                 description
                             --------------------
    copyright            : (C) 2000-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 "pmobjectselect.h"
#include "pmfactory.h"
#include <klocale.h>
#include <kiconloader.h>

PMListBoxObject::PMListBoxObject( QListWidget* listbox, PMObject* obj,
                                  QListWidgetItem* after )
      : QListWidgetItem( KIcon( obj->pixmap( ) ),
                      checkName( obj->name( ) ) )
{
   listbox->insertItem( listbox->row( after ) + 1, this );
   m_pObject = obj;
}

PMListBoxObject::PMListBoxObject( QListWidget* listbox, PMObject* obj )
      : QListWidgetItem( KIcon( obj->pixmap( ) ),
                      checkName( obj->name( ) ), listbox )
{
   m_pObject = obj;
}

PMListBoxObject::PMListBoxObject( PMObject* obj )
      : QListWidgetItem( KIcon( obj->pixmap( ) ),
                      checkName( obj->name( ) ) )
{
   m_pObject = obj;
}

PMListBoxObject::PMListBoxObject( QListWidget* listbox, PMObject* obj,
                                  const QString& text, QListWidgetItem* after )
      : QListWidgetItem( KIcon( obj->pixmap( ) ), text )
{
   listbox->insertItem( listbox->row( after ) + 1, this );
   m_pObject = obj;
}

PMListBoxObject::PMListBoxObject( QListWidget* listbox, PMObject* obj,
                                  const QString& text )
      : QListWidgetItem( SmallIcon( obj->pixmap( ) ), text, listbox)
{
   m_pObject = obj;
}

PMListBoxObject::PMListBoxObject( PMObject* obj, const QString& text )
      : QListWidgetItem( SmallIcon( obj->pixmap( )), text )
{
   m_pObject = obj;
}

QString PMListBoxObject::checkName( const QString& text )
{
   if( text.isEmpty( ) )
      return i18n( "(unnamed)" );
   return text;
}

PMListBoxObject::~PMListBoxObject( )
{
}


QSize PMObjectSelect::s_size = QSize( 200, 300 );


PMObjectSelect::PMObjectSelect( QWidget* parent, bool modal )
      : KDialog( parent )
{
	setCaption( i18n( "Choose Object" ) );
	setButtons( Ok | Cancel );
	setModal( modal );
   m_pSelectedObject = 0;
   m_pListWidget = new QListWidget( this );
   setMainWidget( m_pListWidget );
   setInitialSize( s_size );

   connect( m_pListWidget, SIGNAL( itemChanged( QListWidgetItem* ) ),
            SLOT( slotChanged( QListWidgetItem* ) ) );
   connect( m_pListWidget, SIGNAL( itemActivated( Q3ListBoxItem* ) ),
            SLOT( slotActivated( Q3ListBoxItem* ) ) );
   enableButton( Ok, false );
}

PMObjectSelect::~PMObjectSelect( )
{
   s_size = size( );
}

void PMObjectSelect::addObject( PMObject* obj )
{
   m_pListWidget->addItem( new PMListBoxObject( obj ) );
}

int PMObjectSelect::selectObject( PMObject* link, const QString& t,
                                  PMObject* & obj, QWidget* parent )
{
   PMObject* last = link;
   PMObject* scene;
   bool stop = false;
   bool found = false;

   do
   {
      scene = last->parent( );
      if( scene )
      {
         if( scene->type( ) == "Scene" )
         {
            last = last->prevSibling( );
            stop = true;
            found = true;
         }
         else
            last = last->parent( );
      }
      else
         stop = true;
   }
   while( !stop );

   if( found )
   {
      PMObjectSelect s( parent );

      PMObject* o = scene->firstChild( );
      bool l = false;

      while( o && !l && last )
      {
         if( o->type( ) == t )
            s.m_pListWidget->addItem( new PMListBoxObject( o ) );

         if( o == last )
            l = true;
         else
            o = o->nextSibling( );
      }

      int result = s.exec( );
      if( result == Accepted )
         obj = s.selectedObject( );

      return result;
   }
   else
      kError( PMArea ) << "PMObjectSelect: Link does not seem to be correctly inserted in the scene.\n";
   return Rejected;
}

int PMObjectSelect::selectObject( PMObject* link,
                                  const QStringList& t,
                                  PMObject* & obj, QWidget* parent )
{
   PMObject* last = link;
   PMObject* scene;
   bool stop = false;
   bool found = false;

   do
   {
      scene = last->parent( );
      if( scene )
      {
         if( scene->type( ) == "Scene" )
         {
            last = last->prevSibling( );
            stop = true;
            found = true;
         }
         else
            last = last->parent( );
      }
      else
         stop = true;
   }
   while( !stop );

   if( found )
   {
      PMObjectSelect s( parent );

      PMObject* o = scene->firstChild( );
      bool l = false;

      while( o && !l && last )
      {
         if( t.indexOf( o->type( ) ) >= 0 )
            s.m_pListWidget->addItem( new PMListBoxObject( o ) );

         if( o == last )
            l = true;
         else
            o = o->nextSibling( );
      }

      int result = s.exec( );
      if( result == Accepted )
         obj = s.selectedObject( );

      return result;
   }
   else
      kError( PMArea ) << "PMObjectSelect: Link does not seem to be correctly inserted in the scene.\n";
   return Rejected;
}

int PMObjectSelect::selectDeclare( PMObject* link, const QString& declareType,
                                   PMObject* & obj, QWidget* parent )
{
   PMObject* last = link;
   PMObject* scene;
   bool stop = false;
   bool found = false;

   do
   {
      scene = last->parent( );
      if( scene )
      {
         if( scene->type( ) == "Scene" )
         {
            last = last->prevSibling( );
            stop = true;
            found = true;
         }
         else
            last = last->parent( );
      }
      else
         stop = true;
   }
   while( !stop );

   if( found )
   {
      PMObjectSelect s( parent );

      PMObject* o = scene->firstChild( );
      PMDeclare* decl;

      bool l = false;

      while( o && !l && last )
      {
         if( o->type( ) == "Declare" )
         {
            decl = ( PMDeclare* ) o;
            if( decl->declareType( ) == declareType )
               s.m_pListWidget->addItem( new PMListBoxObject( o ) );
         }

         if( o == last )
            l = true;
         else
            o = o->nextSibling( );
      }

      int result = s.exec( );
      if( result == Accepted )
         obj = s.selectedObject( );

      return result;
   }
   else
      kError( PMArea ) << "PMObjectSelect: Link does not seem to be correctly inserted in the scene.\n";
   return Rejected;
}

int PMObjectSelect::selectDeclare( PMObject* link, const QStringList& declareTypes,
                                   PMObject* & obj, QWidget* parent )
{
   PMObject* last = link;
   PMObject* scene;
   bool stop = false;
   bool found = false;

   do
   {
      scene = last->parent( );
      if( scene )
      {
         if( scene->type( ) == "Scene" )
         {
            last = last->prevSibling( );
            stop = true;
            found = true;
         }
         else
            last = last->parent( );
      }
      else
         stop = true;
   }
   while( !stop );

   if( found )
   {
      PMObjectSelect s( parent );

      PMObject* o = scene->firstChild( );
      PMDeclare* decl;

      bool l = false;

      while( o && !l && last )
      {
         if( o->type( ) == "Declare" )
         {
            decl = ( PMDeclare* ) o;
            if( declareTypes.indexOf( decl->declareType( ) ) >= 0 )
               s.m_pListWidget->addItem( new PMListBoxObject( o ) );
         }

         if( o == last )
            l = true;
         else
            o = o->nextSibling( );
      }

      int result = s.exec( );
      if( result == Accepted )
         obj = s.selectedObject( );

      return result;
   }
   else
      kError( PMArea ) << "PMObjectSelect: Link does not seem to be correctly inserted in the scene.\n";
   return Rejected;
}

void PMObjectSelect::slotChanged( QListWidgetItem* lbi )
{
   m_pSelectedObject = ( ( PMListBoxObject* ) lbi )->object( );
   enableButtonOk( true );
}

void PMObjectSelect::slotActivated( QListWidgetItem* lbi )
{
   m_pSelectedObject = ( ( PMListBoxObject* ) lbi )->object( );
   enableButtonOk( true );
   accept( );
}
#include "pmobjectselect.moc"
