/*
 *
 * Copyright (C) 2003-2008 Sebastian Trueg <trueg@k3b.org>
 *
 * This file is part of the K3b project.
 * Copyright (C) 1998-2008 Sebastian Trueg <trueg@k3b.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.
 * See the file "COPYING" for the exact licensing terms.
 */


#include "k3btempdirselectionwidget.h"
#include <k3bglobals.h>
#include <k3bcore.h>

#include <qlabel.h>
#include <q3groupbox.h>
#include <qlayout.h>
#include <qtimer.h>

#include <qtooltip.h>

#include <qfileinfo.h>

#include <kconfig.h>
#include <klocale.h>
#include <kfiledialog.h>
#include <kdialog.h>
#include <kstandarddirs.h>
#include <kiconloader.h>
#include <kurlrequester.h>
#include <kio/global.h>
#include <klineedit.h>
#include <kvbox.h>


K3bTempDirSelectionWidget::K3bTempDirSelectionWidget( QWidget *parent )
    : Q3GroupBox( 4, Qt::Vertical, parent ),
      m_labelCdSize(0),
      m_defaultImageFileName( "k3b_image.iso" )
{
    layout()->setSpacing( KDialog::spacingHint() );
    layout()->setMargin( KDialog::marginHint() );

    m_imageFileLabel = new QLabel( this );
    m_editDirectory = new KUrlRequester( this );

    m_imageFileLabel->setBuddy( m_editDirectory );

    KHBox* freeTempSpaceBox = new KHBox( this );
    freeTempSpaceBox->setSpacing( KDialog::spacingHint() );
    (void)new QLabel( i18n( "Free space in temporary directory:" ), freeTempSpaceBox );
    m_labelFreeSpace = new QLabel( "                       ",freeTempSpaceBox );
    m_labelFreeSpace->setAlignment( Qt::AlignVCenter | Qt::AlignRight );


    connect( m_editDirectory, SIGNAL(openFileDialog(KUrlRequester*)),
             this, SLOT(slotTempDirButtonPressed(KUrlRequester*)) );
    connect( m_editDirectory, SIGNAL(textChanged(const QString&)),
             this, SLOT(slotUpdateFreeTempSpace()) );
    connect( m_editDirectory->lineEdit(), SIGNAL(lostFocus()),
             this, SLOT(slotFixTempPath()) );

    // choose a default
    setSelectionMode( DIR );

    m_editDirectory->setUrl( K3b::defaultTempPath() );
    slotUpdateFreeTempSpace();

    // ToolTips
    // --------------------------------------------------------------------------------
    m_editDirectory->setToolTip( i18n("The directory in which to save the image files") );

    // What's This info
    // --------------------------------------------------------------------------------
    m_editDirectory->setWhatsThis( i18n("<p>This is the directory in which K3b will save the <em>image files</em>."
                                        "<p>Please make sure that it resides on a partition that has enough free space.") );
}


K3bTempDirSelectionWidget::~K3bTempDirSelectionWidget()
{
}


unsigned long K3bTempDirSelectionWidget::freeTempSpace() const
{
    QString path = m_editDirectory->url().path();

    if( !QFile::exists( path ) )
        path.truncate( path.lastIndexOf('/') );

    unsigned long size;
    K3b::kbFreeOnFs( path, size, m_freeTempSpace );

    return m_freeTempSpace;
}


void K3bTempDirSelectionWidget::slotUpdateFreeTempSpace()
{
    // update the temp space
    freeTempSpace();

    m_labelFreeSpace->setText( KIO::convertSizeFromKiB(m_freeTempSpace) );

    if( m_labelCdSize ) {
        QPalette pal( m_labelCdSize->palette() );
        if( m_freeTempSpace < m_requestedSize/1024 )
            pal.setColor( QPalette::Text, Qt::red );
        else
            pal.setColor( QPalette::Text, palette().color( QPalette::Text ) );
        m_labelCdSize->setPalette( pal );
    }

    QTimer::singleShot( 1000, this, SLOT(slotUpdateFreeTempSpace()) );
}


void K3bTempDirSelectionWidget::slotTempDirButtonPressed( KUrlRequester* r )
{
    // set the correct mode for the filedialog
    if( m_mode == DIR ) {
        r->setWindowTitle( i18n("Select Temporary Directory") );
        r->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly );
    }
    else {
        r->setWindowTitle( i18n("Select Temporary File") );
        r->setMode( KFile::File | KFile::LocalOnly );
    }
}


void K3bTempDirSelectionWidget::setTempPath( const QString& dir )
{
    m_editDirectory->setUrl( dir );
    slotUpdateFreeTempSpace();
}


QString K3bTempDirSelectionWidget::tempPath() const
{
    QFileInfo fi( m_editDirectory->url().path() );

    if( fi.exists() ) {
        if( m_mode == DIR ) {
            if( fi.isDir() )
                return fi.absoluteFilePath();
            else
                return fi.absolutePath();
        }
        else {
            if( fi.isFile() )
                return fi.absoluteFilePath();
            else
                return fi.absoluteFilePath() + "/k3b_image.iso";
        }
    }
    else {
        return fi.absoluteFilePath();
    }
}


QString K3bTempDirSelectionWidget::plainTempPath() const
{
    return m_editDirectory->url().path();
}


QString K3bTempDirSelectionWidget::tempDirectory() const
{
    QString td( m_editDirectory->url().path() );

    // remove a trailing slash
    while( !td.isEmpty() && td[td.length()-1] == '/' )
        td.truncate( td.length()-1 );

    QFileInfo fi( td );
    if( fi.exists() && fi.isDir() )
        return td + "/";

    // now we treat the last section as a filename and return the path
    // in front of it
    td.truncate( td.lastIndexOf( '/' ) + 1 );
    return td;
}


void K3bTempDirSelectionWidget::setSelectionMode( int mode )
{
    m_mode = mode;

    if( m_mode == DIR ) {
        m_imageFileLabel->setText( i18n( "Wri&te image files to:" ) );
        setTitle( i18n("Temporary Directory") );
    }
    else {
        m_imageFileLabel->setText( i18n( "Wri&te image file to:" ) );
        setTitle( i18n("Temporary File") );
    }
}


void K3bTempDirSelectionWidget::setNeededSize( KIO::filesize_t bytes )
{
    m_requestedSize = bytes;
    if( !m_labelCdSize ) {
        KHBox* cdSizeBox = new KHBox( this );
        cdSizeBox->setSpacing( KDialog::spacingHint() );
        (void)new QLabel( i18n( "Size of project:" ), cdSizeBox );
        m_labelCdSize = new QLabel( KIO::convertSize(bytes), cdSizeBox );
        m_labelCdSize->setAlignment( Qt::AlignVCenter | Qt::AlignRight );
    }
    m_labelCdSize->setText( KIO::convertSize(bytes) );
}


void K3bTempDirSelectionWidget::saveConfig()
{
    KConfigGroup grp( k3bcore->config(), "General Options" );
    grp.writePathEntry( "Temp Dir", tempDirectory() );
}


void K3bTempDirSelectionWidget::readConfig( const KConfigGroup& c )
{
    setTempPath( c.readPathEntry( "image path", K3b::defaultTempPath() ) );
}


void K3bTempDirSelectionWidget::saveConfig( KConfigGroup& c )
{
    c.writePathEntry( "image path", tempPath() );
}


void K3bTempDirSelectionWidget::setDefaultImageFileName( const QString& name, bool changeImageName )
{
    if ( !name.isEmpty() ) {
        if ( selectionMode() == FILE ) {
            if ( plainTempPath().section( '/', -1 ) == m_defaultImageFileName ) {
                changeImageName = true;
            }
        }

        m_defaultImageFileName = name;
        if ( !m_defaultImageFileName.contains( '.' ) ) {
            m_defaultImageFileName += ".iso";
        }
        fixTempPath( changeImageName );
    }
}


void K3bTempDirSelectionWidget::slotFixTempPath()
{
    fixTempPath( false );
}


void K3bTempDirSelectionWidget::fixTempPath( bool forceNewImageName )
{
    // if in file selection mode and no image file is specified or
    // forceNewImageName is true set the default image file name
    if ( selectionMode() == FILE ) {
        if ( forceNewImageName ||
             QFileInfo( plainTempPath() ).isDir() ) {
            setTempPath( tempDirectory() + m_defaultImageFileName );
        }
    }
}

#include "k3btempdirselectionwidget.moc"
