//
// C++ Implementation: %{MODULE}
//
// Description:
//
//
// Author: %{AUTHOR} <%{EMAIL}>, (C) %{YEAR}
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "komposeviewmanager.h"

#include "komposetaskmanager.h"
#include "komposeglobal.h"
#include "komposesettings.h"
#include "komposesystray.h"

#include <tqtimer.h>
#include <tqcursor.h>
#include <tqapplication.h>
#include <tqptrlist.h>
#include <tqwidgetlist.h>
#include <tqdesktopwidget.h>

#include <twin.h>
#include <tdeapplication.h>
#include <kdebug.h>


static KomposeViewManager* viewManagerInstance = 0;

/**
 * Viewmanager is a singleton
 */
KomposeViewManager* KomposeViewManager::instance()
{
  if ( !viewManagerInstance )
  {
    kdDebug() << "KomposeViewManager::instance() - Creating Singleton instance" << endl;
    viewManagerInstance = new KomposeViewManager();
  }
  return viewManagerInstance;
}

KomposeViewManager::KomposeViewManager():
    DCOPObject( "KomposeDcopIface" ),
    TQObject(),
    viewWidget(),
    activeView(0),
    blockScreenshots(0)
{
  viewManagerInstance = this;

  // Setup cursorupdate timer to check for mouse moves into corner
  cursorUpdateTimer = new TQTimer();
  slotStartCursorUpdateTimer();

  // dirty hack. see uglyTQtHackInitFunction()
  TQTimer::singleShot( 500, this, TQ_SLOT( uglyTQtHackInitFunction() ) );
}


KomposeViewManager::~KomposeViewManager()
{
  delete cursorUpdateTimer;
}


/**
 * This is a hack that should be called by a timer as this connect won't work in the constructor
 */
void KomposeViewManager::uglyTQtHackInitFunction()
{
  connect( KomposeSettings::instance(), TQ_SIGNAL( settingsChanged() ), TQ_SLOT( slotStartCursorUpdateTimer() ) );
}

/**
 * Starts the corner check timer which polls TQCursor::pos() every second
 @see checkCursorPos()
 */
void KomposeViewManager::slotStartCursorUpdateTimer()
{
  disconnect( cursorUpdateTimer, TQ_SIGNAL( timeout() ), this, TQ_SLOT( checkCursorPos() ) );

  if ( KomposeSettings::instance()->getActivateOnBottomLeftCorner() ||
       KomposeSettings::instance()->getActivateOnBottomRightCorner() ||
       KomposeSettings::instance()->getActivateOnTopLeftCorner() ||
       KomposeSettings::instance()->getActivateOnTopRightCorner() ||
       KomposeSettings::instance()->getActivateOnTopEdge() ||
       KomposeSettings::instance()->getActivateOnBottomEdge() ||
       KomposeSettings::instance()->getActivateOnLeftEdge() ||
       KomposeSettings::instance()->getActivateOnRightEdge() )
  {
    kdDebug() << "KomposeViewManager::slotStartCursorUpdateTimer() - TQCursor::pos() checks enabled" << endl;
    TQRect deskRect = TQApplication::desktop()->screenGeometry();

    topLeftCorner = deskRect.topLeft();
    topRightCorner = deskRect.topRight();
    bottomLeftCorner = deskRect.bottomLeft();
    bottomRightCorner = deskRect.bottomRight();

    connect( cursorUpdateTimer, TQ_SIGNAL( timeout() ), TQ_SLOT( checkCursorPos() ) );
    cursorUpdateTimer->start( 200, false ); // TODO: Find out why even an interval of 1ms doesn't hit performance!
  }
}


/**
 * Checks if cursor hovered over a corner that activates Kompose
 */
void KomposeViewManager::checkCursorPos()
{
  if (
    ( KomposeSettings::instance()->getActivateOnTopLeftCorner() &&
      !activeView && TQCursor::pos() == topLeftCorner ) ||
    ( KomposeSettings::instance()->getActivateOnTopRightCorner() &&
      !activeView && TQCursor::pos() == topRightCorner ) ||
    ( KomposeSettings::instance()->getActivateOnBottomLeftCorner() &&
      !activeView && TQCursor::pos() == bottomLeftCorner ) ||
    ( KomposeSettings::instance()->getActivateOnBottomRightCorner() &&
      !activeView && TQCursor::pos() == bottomRightCorner ) ||
    ( KomposeSettings::instance()->getActivateOnTopEdge() &&
      !activeView && TQCursor::pos().y() == topLeftCorner.y() ) ||
    ( KomposeSettings::instance()->getActivateOnBottomEdge() &&
      !activeView && TQCursor::pos().y() == bottomLeftCorner.y() ) ||
    ( KomposeSettings::instance()->getActivateOnLeftEdge() &&
      !activeView && TQCursor::pos().x() == topLeftCorner.x() ) ||
    ( KomposeSettings::instance()->getActivateOnRightEdge() &&
      !activeView && TQCursor::pos().x() == topRightCorner.x() )
  )
  {
    //cursorUpdateTimer->stop();
    TQTimer::singleShot( KomposeSettings::instance()->getAutoLockDelay(), this, TQ_SLOT( reCheckCursorPos() ) );
  }
}

/**
 * Called after the cursor was in a hotspot to check if it's still there
 */
void KomposeViewManager::reCheckCursorPos()
{
  if (
    ( KomposeSettings::instance()->getActivateOnTopLeftCorner() &&
      !activeView && TQCursor::pos() == topLeftCorner ) ||
    ( KomposeSettings::instance()->getActivateOnTopRightCorner() &&
      !activeView && TQCursor::pos() == topRightCorner ) ||
    ( KomposeSettings::instance()->getActivateOnBottomLeftCorner() &&
      !activeView && TQCursor::pos() == bottomLeftCorner ) ||
    ( KomposeSettings::instance()->getActivateOnBottomRightCorner() &&
      !activeView && TQCursor::pos() == bottomRightCorner ) ||
    ( KomposeSettings::instance()->getActivateOnTopEdge() &&
      !activeView && TQCursor::pos().y() == topLeftCorner.y() ) ||
    ( KomposeSettings::instance()->getActivateOnBottomEdge() &&
      !activeView && TQCursor::pos().y() == bottomLeftCorner.y() ) ||
    ( KomposeSettings::instance()->getActivateOnLeftEdge() &&
      !activeView && TQCursor::pos().x() == topLeftCorner.x() ) ||
    ( KomposeSettings::instance()->getActivateOnRightEdge() &&
      !activeView && TQCursor::pos().x() == topRightCorner.x() )
  )
  {
    cursorUpdateTimer->stop();
    createView();
  }
}


void KomposeViewManager::createView( int type )
{
  if (KomposeSettings::instance()->hasDialogOpen() ||
      KomposeGlobal::instance()->hasAboutDialogOpen())
  {
    kdDebug() << "KomposeViewManager::createView() - Another Kompose Dialog is open... close it first" << endl;
    return;
  }

  if (type == -1)
    type = KomposeSettings::instance()->getDefaultView();

  kdDebug() << "KomposeViewManager::createView( type " << type << " )" << endl;

  if ( !activeView )
  {
    // Remember current desktop
    deskBeforeSnaps = KWin::currentDesktop();
    kdDebug() << "KomposeViewManager::createView() - Remembering desktop " << deskBeforeSnaps << endl;
    // Update screenshot of the current window to be more up2date
    // KomposeTaskManager::instance()->simulatePasvScreenshotEvent();
    // Update all other
    blockScreenshots = true;
    if ( type == KOMPOSEDISPLAY_CURRENTDESK )
      KomposeTaskManager::instance()->slotUpdateScreenshots( false );
    else
      KomposeTaskManager::instance()->slotUpdateScreenshots();
    blockScreenshots = false;
  }

  if ( !activeView )
    viewWidget = new KomposeFullscreenWidget( type );
  else
    viewWidget->setType( type );

  viewWidget->show();
  KWin::forceActiveWindow( viewWidget->winId() );

  activeView = true;
}


void KomposeViewManager::closeCurrentView()
{
  if ( !activeView )
    return;

  blockScreenshots = true;
  activeView = false;

  //viewWidget->setUpdatesEnabled( false );
  //viewWidget->hide();
  viewWidget->close();
  viewWidget->deleteLater();
  //viewWidget = 0;

  emit viewClosed();

  if ( KomposeGlobal::instance()->getSingleShot() )
    tdeApp->quit();

  // Reset old Desktop
  KWin::setCurrentDesktop( deskBeforeSnaps );

  // A short delay until we allow screenshots again (would cause overlapping else
  TQTimer::singleShot( 400, this, TQ_SLOT( toggleBlockScreenshots() ) );

  // Restart Timer for corner checks
  slotStartCursorUpdateTimer();
}

void KomposeViewManager::toggleBlockScreenshots()
{
  blockScreenshots = !blockScreenshots;
}

void KomposeViewManager::setCurrentDesktop( int desknum )
{
  closeCurrentView();
  KWin::setCurrentDesktop(desknum+1);
}

void KomposeViewManager::activateTask( KomposeTask *task )
{
  closeCurrentView();
  task->activate();
}



#include "komposeviewmanager.moc"
