/***************************************************************************
 *   Copyright (C) 2004, 2005 by Johnathan Burchill                              *
 *   jkerrb@users.sourceforge.net                                          *
 *                                                                         *
 *   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 "kdarEventHandler.h"

#include "kdarview.h"

#include "archiveHandle.h"
#include "controller.h"
#include "kdarConfig.h"
#include "kdardeclarations.h"
#include "kdarEnums.h"
#include "KDarInteraction.h"
#include "kdarListViewItem.h"
#include "kdarArchiveBrowserUpdatesEvent.h"
#include "kdarCancelButtonEvent.h"
#include "kdarCheckFileSizeEvent.h"
#include "kdarPostListViewItemEvent.h"
#include "kdarprogressdialog.h"
#include "kdarProgressEvent.h"
#include "kdarProgressDialogEvent.h"
#include "kdarSetCursorEvent.h"
#include "kdarStatusBarEvent.h"
#include "kdarTarListingEvent.h"
#include "kdarUserInteractionEvent.h"
#include "kdarUserInteractionStringEvent.h"
#include "kdarWarningEvent.h" //need

#include <kdebug.h> // need
#include <klocale.h> //need
#include <kmessagebox.h> //need
#include <kmimetype.h> //need

#include <qevent.h> //need
#include <qsemaphore.h>
#include <qstring.h> //need


kdarEventHandler::kdarEventHandler( QObject *parent, controller *aController, KDarConfig *kdarConfig )
    : QObject( parent ),
      m_controller( aController ),
      m_kdarconfig( kdarConfig ),
      m_view( 0 )
{
    m_view = static_cast<kdarView*>( parent );
}

kdarEventHandler::~kdarEventHandler()
{
}

void kdarEventHandler::handleEvent( QCustomEvent *e )
{
    if ( e->type() == ( QEvent::Type ) KDar::WARNING )
    {
        kdarWarningEvent* we = ( kdarWarningEvent* )e;
        QString message = we->message();
        if ( m_view ) m_view->appendMessage( message );
        writeLogMessage( message );
    }
    if ( ( e->type() == ( QEvent::Type ) KDar::USERINTERACTION ) || ( e->type() == ( QEvent::Type ) KDar::USERINTERACTIONSTRING ) )
    {
        QString logMessage;
        //Stop checking the slice size
        bool startTimer = false;
        if ( m_view ) startTimer = m_view->suspendFileSizeChecks();
        //Get the question:
        if ( e->type() == ( QEvent::Type ) KDar::USERINTERACTION )
        {
            kdDebug() << "kdarEventHandler::handleEvent(): USERINTERACTION" << endl;
            kdarUserInteractionEvent* uie = (kdarUserInteractionEvent*)e;
            QString question = uie->question();
            int ret = KMessageBox::warningYesNo(0, question );
            bool response = (ret == KMessageBox::Yes);
            if ( m_controller ) m_controller->setUserResponse( response );
            QString answer( i18n( "Negative answer to user interaction question", "NO.\n" ) );
            if ( response ) answer = i18n( "Positive answer to user interaction question", "YES.\n" );
            logMessage = i18n( "(Libdar question)...(user\'s answer)", "%1...%2\n" ).arg( question ).arg( answer );
        }
        else
        {
            kdDebug() << "kdarEventHandler::handleEvent(): USERINTERACTIONSTRING" << endl;
            kdarUserInteractionStringEvent* uise = (kdarUserInteractionStringEvent*)e;
            QString question = uise->question();
            bool echo = uise->echo();
            //TODO: We should not assume that libdar wants a password...
            if ( !echo )
            {
                kdDebug() << "kdarEventHandler::handleEvent(): calling m_controller->password" << endl;
                bool gotPassword = m_controller->obtainPassword();
                QString answer = i18n( "Did libdar get a password from the user?", "did not get password.\n" );
                if ( gotPassword ) QString answer = i18n( "Did libdar get a password from the user?", "got password.\n" );
                logMessage = i18n( "(Libdar request for text)...(user\'s reply)", "%1...%2\n" ).arg( question ).arg( answer );
            }
        }
        QSemaphore *s = m_controller->semaphore();
        if ( s )
        {
            (*s)--;
        }
        else
        {
            kdDebug() << "kdarEventHandler::handleEvent(): semaphore pointer is 0! Should throw an exception here, eh?" << endl;
        }
        writeLogMessage( logMessage );
        if ( startTimer )
        {
            if ( m_view ) m_view->resumeFileSizeChecks();
        }
    }
    if ( e->type() == (QEvent::Type) KDar::TARLISTING )
    {
        kdarTarListingEvent* te = (kdarTarListingEvent*)e;
        kdarListViewItem *directory = te->directory();
        QString filename = te->filename();
        std::cout << "Tar listing: filename is " << filename << std::endl;
        QString perm = te->perm();
        QString uid = te->uid();
        QString gid = te->gid();
        QString size = te->size();
        QString date = te->date();
        QString flag = te->flag();
        bool isDirectory = te->isDir();
        bool hasChild = te->hasChildren();

        if (directory == 0)
        {
            return;
        }
        QString url = "/" + directory->path() + "/" + filename;
        if ( isDirectory )
        {
            //get pixmapForURL to return a directory...This is ugly.
            url = "/";
        }
        QPixmap icon = KMimeType::pixmapForURL( url, 0, KIcon::Small );
        //remove "<empty>" from the current directory, if it exists
        kdarListViewItem * firstItem = directory->firstChild();
        if ( firstItem )
        {
            if ( firstItem->text( 0 ) == "<empty>" )
            {
                delete firstItem;
                firstItem = 0;
            }
        }
        kdarListViewItem *newItem =  new kdarListViewItem( directory, filename, perm, uid, gid, size, date, flag );
        newItem->setPixmap( 0, icon );
        //give this item an "<empty>" child if is a directory and has children
        if ( isDirectory && hasChild )
        {
            (void) new kdarListViewItem( newItem, "<empty>" );
        }
    }
    if ( e->type() == (QEvent::Type) KDar::STATUSBAR )
    {
        kdarStatusBarEvent* se = (kdarStatusBarEvent*)e;
        QString statusBarMessage( se->message() );
        int duration = se->duration();
        if ( m_view ) m_view->displayStatusBarMessage( statusBarMessage, duration );
        writeLogMessage( statusBarMessage );
    }
    if ( e->type() == (QEvent::Type) KDar::PROGRESSDIALOG )
    {
        kdarProgressDialogEvent* pde = (kdarProgressDialogEvent*)e;
        QString message( pde->message() );
	int field( pde->field() );
        if ( m_view )
        {
            if ( field == 0 )
            {
                m_view->updateProgressDialogFileInfo( message );
            }
            else
            {
                m_view->updateProgressDialogFileExtraInfo( message );
            }
        }
        writeLogMessage( message );
    }
    if ( e->type() == (QEvent::Type) KDar::SETCURSOR )
    {
        kdarSetCursorEvent* sce = (kdarSetCursorEvent*)e;
        if ( m_view ) m_view->setCursor( sce->cursor() );
    }
    if ( e->type() == (QEvent::Type) KDar::POSTLISTVIEWITEM )
    {
        kdarPostListViewItemEvent* pe = (kdarPostListViewItemEvent*) e;
        QString text( pe->text() );
        bool clearView = pe->clearView();
        if ( m_view ) m_view->displayNewArchive( text, clearView );
    }
    if ( e->type() == (QEvent::Type) KDar::CHECKFILESIZE )
    {
        kdarCheckFileSizeEvent* ce = (kdarCheckFileSizeEvent*) e;
        if ( ce->checkFileSizeAction() == kdarCheckFileSizeEvent::STARTTIMER )
        {
            if ( m_view ) m_view->startFileSizeChecks();
        }
        else
        {
            if ( m_view ) m_view->stopFileSizeChecks();
        }
    }
}

void kdarEventHandler::writeLogMessage( QString & message )
{
    if ( m_controller && m_kdarconfig && ( m_kdarconfig->logLevel() == KDar::LOG_FULL ) && !message.isEmpty() )
    {
        m_controller->writeLogMessage( message );
    }
}

#include "kdarEventHandler.moc"
