/***************************************************************************
*                                tdefileio.cpp
*                             -------------------
*
*    Revision     : $Id$
*    begin        : Tue Jan 29 2002
*    copyright    : (C) 2002 by Patrick Charbonnier
*
*    email        : pch@freeshell.org
*
***************************************************************************/

// Author: Stefan Taferner <taferner@kde.org>

#include <tqapplication.h>
#include <tqstring.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <tqfile.h>
#include <tqfileinfo.h>

#include <kdebug.h>
#include <tdelocale.h>
#include <tdemessagebox.h>

#include "tdefileio.h"

//-----------------------------------------------------------------------------
TQString kFileToString(const TQString & aFileName, bool aEnsureNL, bool aVerbose)
{
    TQCString result;

    TQFileInfo info(aFileName);
    unsigned int readLen;
    unsigned int len = info.size();
    TQFile file(aFileName);

    // assert(aFileName!=NULL);
    if (aFileName == NULL)
        return "";

    if (!info.exists()) {
        if (aVerbose)
            KMessageBox::error(tqApp->mainWidget(), i18n("The specified file does not exist:\n%1").arg(aFileName));
        return TQString();
    }
    if (info.isDir()) {
        if (aVerbose)
            KMessageBox::error(tqApp->mainWidget(), i18n("This is a folder and not a file:\n%1").arg(aFileName));
        return TQString();
    }
    if (!info.isReadable()) {
        if (aVerbose)
            KMessageBox::error(tqApp->mainWidget(), i18n("You do not have read permission for the file:\n%1").arg(aFileName));
        return TQString();
    }
    if (len <= 0)
        return TQString();

    if (!file.open(IO_Raw | IO_ReadOnly)) {
        if (aVerbose)
            switch (file.status()) {
            case IO_ReadError:
                KMessageBox::error(tqApp->mainWidget(), i18n("Could not read file:\n%1").arg(aFileName));
                break;
            case IO_OpenError:
                KMessageBox::error(tqApp->mainWidget(), i18n("Could not open file:\n%1").arg(aFileName));
                break;
            default:
                KMessageBox::error(tqApp->mainWidget(), i18n("Error while reading file:\n%1").arg(aFileName));
            }
        return TQString();
    }

    result.resize(len + (int) aEnsureNL + 1);
    readLen = file.readBlock(result.data(), len);
    if (aEnsureNL && result[len - 1] != '\n') {
        result[len++] = '\n';
        readLen++;
    }
    result[len] = '\0';

    if (readLen < len) {
        TQString msg = i18n("Could only read %1 bytes of %2.").arg(TDEGlobal::locale()->formatNumber(readLen,
                      0)).arg(TDEGlobal::locale()->formatNumber(len, 0));

        KMessageBox::error(tqApp->mainWidget(), msg);
        return TQString();
    }

    kdDebug() << "kFileToString: " << readLen << " bytes read" << endl;
    return result;
}


//-----------------------------------------------------------------------------
static bool kBytesToFile(const char *aBuffer, int len, const TQString & aFileName, bool aAskIfExists, bool aBackup, bool aVerbose)
{
    TQFile file(aFileName);
    TQFileInfo info(aFileName);
    int writeLen, rc;

    // assert(aFileName!=NULL);
    if (aFileName.isNull())
        return false;

    if (info.exists()) {
        if (aAskIfExists) {
            TQString str = i18n("File %1 exists.\nDo you want to replace it?").arg(aFileName);

            rc = KMessageBox::questionYesNo(tqApp->mainWidget(), str, TQString(), i18n("Replace"),KStdGuiItem::cancel());
            if (rc != KMessageBox::Yes)
                return FALSE;
        }
        if (aBackup) {
            // make a backup copy
            TQString bakName = aFileName;

            bakName += '~';
            TQFile::remove(bakName);
            rc = rename(TQFile::encodeName(aFileName), TQFile::encodeName(bakName));
            if (rc) {
                // failed to rename file
                if (!aVerbose)
                    return FALSE;
                rc = KMessageBox::warningContinueCancel(tqApp->mainWidget(), i18n("Failed to make a backup copy of %1.\nContinue anyway?").arg(aFileName));
                if (rc != KMessageBox::Continue)
                    return FALSE;
            }
        }
    }

    if (!file.open(IO_Raw | IO_WriteOnly)) {
        if (aVerbose)
            switch (file.status()) {
            case IO_WriteError:
                KMessageBox::error(tqApp->mainWidget(), i18n("Could not write to file:\n%1").arg(aFileName));
                break;
            case IO_OpenError:
                KMessageBox::error(tqApp->mainWidget(), i18n("Could not open file for writing:\n%1").arg(aFileName));
                break;
            default:
                KMessageBox::error(tqApp->mainWidget(), i18n("Error while writing file:\n%1").arg(aFileName));
            }
        return FALSE;
    }

    writeLen = file.writeBlock(aBuffer, len);

    if (writeLen < 0) {
        KMessageBox::error(tqApp->mainWidget(), i18n("Could not write to file:\n%1").arg(aFileName));
        return FALSE;
    } else if (writeLen < len) {
        TQString msg = i18n("Could only write %1 bytes of %2.").arg(TDEGlobal::locale()->formatNumber(writeLen,
                      0)).arg(TDEGlobal::locale()->formatNumber(len,
                                                              0));

        KMessageBox::error(tqApp->mainWidget(), msg);
        return FALSE;
    }

    return TRUE;
}

bool kCStringToFile(const TQCString & aBuffer, const TQString & aFileName, bool aAskIfExists, bool aBackup, bool aVerbose)
{
    return kBytesToFile(aBuffer, aBuffer.length(), aFileName, aAskIfExists, aBackup, aVerbose);
}

bool kByteArrayToFile(const TQByteArray & aBuffer, const TQString & aFileName, bool aAskIfExists, bool aBackup, bool aVerbose)
{
    return kBytesToFile(aBuffer, aBuffer.size(), aFileName, aAskIfExists, aBackup, aVerbose);
}
