//
// C++ Implementation: komposetaskcontainerwidget
//
// Description:
//
//
// Author: Hans Oischinger <hans.oischinger@kde-mail.net>, (C) 2004
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "komposetaskcontainerwidget.h"
#include "komposetaskmanager.h"
#include "komposeviewmanager.h"
#include "komposelayout.h"
#include "komposesettings.h"
#include "komposetaskwidget.h"

#include <tqobjectlist.h>
#include <tqwidget.h>
#include <tqtimer.h>
#include <kdebug.h>

static bool controlHold = false; // is the control key pressed

KomposeTaskContainerWidget::KomposeTaskContainerWidget( int desk, TQWidget *parent, KomposeLayout *l, const char *name)
    : KomposeWidget(parent, l, name),
    desktop( desk )
{
  connect(KomposeTaskManager::instance(), SIGNAL(taskDesktopChanged(KomposeTask*, int, int )),
          SLOT(reparentTaskWidget(KomposeTask*, int, int )) );
}


KomposeTaskContainerWidget::~KomposeTaskContainerWidget()
{}

void KomposeTaskContainerWidget::reparentTaskWidget( KomposeTask* task, int fromDesktop, int toDesktop )
{
  // noops
  if ( (fromDesktop==-1 && ((toDesktop==-1) || desktop == toDesktop-1)) || desktop==-2)
    return;

  kdDebug() << "KomposeTaskContainerWidget::reparentTaskWidget()" << endl;

  // Delete from current
  if ( (toDesktop!= -1) && (desktop == fromDesktop-1 || fromDesktop==-1) )
  {
    KomposeTaskWidget *child;
    TQPtrListIterator<KomposeWidget> it( *(layout->getManagedWidgets()));
    while ( (child = dynamic_cast<KomposeTaskWidget*>(it.current()) ) != 0 )
    {
      ++it;
      if (child->getTask() == task)
      {
        removeChild( task );
        layout->remove(child);
        //child->deleteLater();
        child->close(true);
        return;
      }
    }
  }

  // Add to new
  if ( desktop == toDesktop -1 || (toDesktop == -1 && fromDesktop-1!=desktop) )
  {
    createTaskWidget( task, true );
    //TQTimer::singleShot( 200, layout, SLOT( arrangeLayout() ) );
    //        layout->arrangeLayout();
  }
}

void KomposeTaskContainerWidget::keyPressEvent ( TQKeyEvent * e )
{
  if ( e->key() == TQt::Key_Control )
  {
    controlHold = true;
    e->accept();
  }
}

void KomposeTaskContainerWidget::keyReleaseEvent ( TQKeyEvent * e )
{
  if ( e->key() == TQt::Key_Control )
  {
    controlHold = false;
    e->accept();
    return;
  }

  if ( e->key() == TQt::Key_Right || e->key() == TQt::Key_D || e->key() == TQt::Key_H ||
       e->key() == TQt::Key_Left  || e->key() == TQt::Key_A || e->key() == TQt::Key_J ||
       e->key() == TQt::Key_Up    || e->key() == TQt::Key_W || e->key() == TQt::Key_K ||
       e->key() == TQt::Key_Down  || e->key() == TQt::Key_S || e->key() == TQt::Key_L )
  {
    if ( controlHold && desktop != -1 )
    {
      e->ignore();
      return;
    }

    kdDebug() << "KomposeTaskContainerWidget::keyReleaseEvent - " << className() << ", Movement key pressed" << endl;
    // Map keys to directions
    int direction = DLAYOUT_RIGHT;
    switch( e->key() )
    {
    case TQt::Key_Right:
      direction = DLAYOUT_RIGHT;
      break;
    case TQt::Key_D:
      direction = DLAYOUT_RIGHT;
      break;
    case TQt::Key_L:
      direction = DLAYOUT_RIGHT;
      break;
    case TQt::Key_Left:
      direction = DLAYOUT_LEFT;
      break;
    case TQt::Key_A:
      direction = DLAYOUT_LEFT;
      break;
    case TQt::Key_H:
      direction = DLAYOUT_LEFT;
      break;
    case TQt::Key_Up:
      direction = DLAYOUT_TOP;
      break;
    case TQt::Key_W:
      direction = DLAYOUT_TOP;
      break;
    case TQt::Key_K:
      direction = DLAYOUT_TOP;
      break;
    case TQt::Key_Down:
      direction = DLAYOUT_BOTTOM;
      break;
    case TQt::Key_S:
      direction = DLAYOUT_BOTTOM;
      break;
    case TQt::Key_J:
      direction = DLAYOUT_BOTTOM;
      break;
    }

    focusNeighbourChild( direction );
    e->accept();

    return;
  }

  e->ignore();
}


bool KomposeTaskContainerWidget::focusNeighbourChild( int direction )
{
  bool successfull = false;
  if ( !children()->containsRef(focusWidget()) )
  {
    kdDebug() << "KomposeTaskContainerWidget::keyReleaseEvent - No widget focussed. Focussing first" << endl;
    const TQObjectList *lst = children();

    if ( lst )
    {
      TQObjectListIterator it( *lst );
      TQWidget *widget;
      while ( (widget = (TQWidget*)it.current() ) )
      {
        if (widget->inherits("KomposeTaskWidget") || widget->inherits("KomposeDesktopWidget"))
        {
          kdDebug() << "KomposeTaskContainerWidget::keyReleaseEvent - Focussing " << widget->className() << endl;
          widget->setFocus();
          successfull = true;
          break;
        }
        ++it;
      }
    }
  }
  else
  {
    KomposeWidget *widget;
    if ( ( widget = layout->getNeighbour( dynamic_cast<KomposeWidget*>(focusWidget()), direction, WLAYOUT_BOTH  ) ) != 0 )
    {
      kdDebug() << "KomposeTaskContainerWidget::keyReleaseEvent - Focussing " << widget->className() << endl;
      widget->setFocus();
      successfull = true;
    }
  }

  return successfull;
}


void KomposeTaskContainerWidget::createTaskWidgets()
{
  TaskList tl = KomposeTaskManager::instance()->getTasks();
  TQPtrListIterator<KomposeTask> it( tl );
  KomposeTask *task;
  while ( (task = it.current()) != 0 )
  {
    ++it;
    TQ_CHECK_PTR(task);
    createTaskWidget( task);
  }
}


void KomposeTaskContainerWidget::createTaskWidget( KomposeTask* task, bool manualShow )
{
  if ( desktop == -1 || desktop == task->onDesktop()-1 || task->onDesktop()==-1)
  {
    kdDebug() << "KomposeTaskContainerWidget::createTaskWidget() (Container: " << this->className() << ", WId: " << task->window() << ", onDesktop: " << task->onDesktop() << ")" << endl;
    KomposeTaskWidget *taskwidget = new KomposeTaskWidget( task, this );
    if (manualShow)
      taskwidget->show();
    connect( taskwidget, SIGNAL(requestRemoval(KomposeWidget*)), SLOT(requestRemoval(KomposeWidget*)) );
  }
}

int KomposeTaskContainerWidget::getHeightForWidth( int ) const
{
  return -1;
}

int KomposeTaskContainerWidget::getWidthForHeight( int ) const
{
  return -1;
}

double KomposeTaskContainerWidget::getAspectRatio()
{
  return -1;
}

void KomposeTaskContainerWidget::requestRemoval( KomposeWidget *obj )
{
  layout->remove(obj);
  // removeChild( obj );  // FIXME: This causes segfaults although it would
  // be the correct way (ChildRemoveEvents to rearrange the layout...)
  !obj->close(true);
  layout->arrangeLayout();
}

void KomposeTaskContainerWidget::childEvent( TQChildEvent * ce)
{
  KomposeWidget::childEvent(ce);
  // ReLayout when we are in a active view and a new window appeared somewhere
  if ( KomposeViewManager::instance()->hasActiveView() )
    layout->arrangeLayout();
}

#include "komposetaskcontainerwidget.moc"