/***************************************************************************
 *   Copyright (C) 2005 by Roland Weigert   *
 *   roweigert@t-online.de   *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "cleanup.h"

extern rcdatei settingsfile;
extern databasewrapper *database;

cleanup::cleanup(QWidget *pointer)
{
    parent=pointer;
    url=new QUrlOperator();
    abort=FALSE;
    directoriesok=FALSE;
    goodfiles=0;
    badfiles=0;
    progresswindow=new progressmainwindow(FALSE);
    progresswindow->show();
    progressinfo *initmessage=progresswindow->startInfo(i18n("Checking directories"));
    //First of all, check if directories are ok
    QFileInfo filecheck(settingsfile.destination_dir);
    if (!filecheck.exists())
    {
        QMessageBox::warning(parent,i18n("Access error"),i18n("The destination directory doesn't exist"),"&Ok",QString::null,QString::null,1);
        return;
    }
    else
    {
        if (!filecheck.isWritable())
        {
            QMessageBox::warning(parent,i18n("Access error"),i18n("You have no writeprivilegs for the  destination directory"),"&Ok",QString::null,QString::null,1);
            return;
        }
    }
    filecheck=QFileInfo(settingsfile.reject_dir);
    if (!filecheck.exists())
    {
        QMessageBox::warning(parent,i18n("Access error"),i18n("The reject directory doesn't exist"),"&Ok",QString::null,QString::null,1);
        return;
    }
    else
    {
        if (!filecheck.isWritable())
        {
            QMessageBox::warning(parent,i18n("Access error"),i18n("You have no writeprivilegs for the reject directory"),"&Ok",QString::null,QString::null,1);
            return;
        }
    }
    directoriesok=TRUE;
    //split up filter,and check if ok
    initmessage->setText(i18n("Checking filters"));
    cleanupfilter=new filter(settingsfile.filter,settingsfile.reading_dir);
    if (!cleanupfilter->filterOk)
    {
        abort=TRUE;
        QMessageBox::warning(parent,i18n("Filter-error"),cleanupfilter->errorText,"&Ok",QString::null,QString::null,1);
    }
    else
        filterok=TRUE;
    progresswindow->killProgress(initmessage);
}

cleanup::~ cleanup()
{
    delete url;
    delete cleanupfilter;
}

void cleanup::cleanupdir(QStringList *selectedFiles,long counter)
{
    progresswithbar *cleanupprogress=progresswindow->startProgress(i18n("Cleaning up files"),counter);
    connect (cleanupprogress,SIGNAL(cancelled()),SLOT(abortslot()));
    QStringList::Iterator index=selectedFiles->begin();
    long runningcounter=0;
    while (index!=selectedFiles->end()&&!abort)
    {
        bool isproppertagged=FALSE;//Indicates if the operated file is tagged right
        int iswritten=FALSE;//Indicates if the file was written successfully
        cleanupprogress->setProgress(++runningcounter);
        QString filename=*index;
        QString newfilename;
        int status=cleanupfilter->makeDirectories(filename,settingsfile.destination_dir);
        if (status==-1)
        {
            abort=TRUE;
            QMessageBox::warning(parent,i18n("Process canceled"),cleanupfilter->errorText,"&Ok",QString::null,QString::null,1);
        }
        else if (status==0)
        {
            badfiles++;
            int position=filename.findRev("/");
            newfilename=QString("%1%2").arg(settingsfile.reject_dir,filename.right(filename.length()-(position+1)));
        }
        //�erprfen, ob Datei schon existiert
        else if (status==1)
        {
            status=cleanupfilter->generateName(filename);
            if (status==-1)
            {
                abort=TRUE;
                QMessageBox::warning(parent,i18n("Process canceled"),cleanupfilter->errorText,"&Ok",QString::null,QString::null,1);
            }
            if (status==0)
            {
                //no good tags, move to reject
                badfiles++;
                int position=filename.findRev("/");
                newfilename=QString("%1%2").arg(settingsfile.reject_dir,filename.right(filename.length()-(position+1)));
            }
        }
        if (status==1)
        {
            //Set flag for propper tagged, so we can write a picture in the directory the file exists in
            isproppertagged=TRUE;
            goodfiles++;
            newfilename=QString("%1%2.%3").arg(settingsfile.destination_dir,cleanupfilter->filenamesuggest,QString(*index).right(3));
        }
        QFileInfo filecheck(newfilename);
        if (!filecheck.exists())
        {
            if (!settingsfile.remove)
            {
                iswritten=copyfile(filename,newfilename);
            }
            else
            {
                QFileInfo movecheck(filename);
                cerr<<"This is the result of movecheck:"<<movecheck.isWritable()<<endl;
                if (movecheck.isWritable())
                {
                    if((iswritten=copyfile(filename,newfilename))==1)
                    {
                        QDir transaction;
                        transaction.remove(filename);
                        checkdirempty(filename);
                    }
                }
                else
                {
                    QString message=QString(i18n("File %1 is writeprotected.<br>File will be copied only, if you press OK.")).arg(filename);
                    if (QMessageBox::warning(parent,i18n("Delete error"),message,"&Ok",i18n("&Cancel"),QString::null,1))
                        abort=TRUE;
                    else
                    {
                        iswritten=copyfile(filename,newfilename);
                    }
                }
            }
        }
        else
        {
            if (settingsfile.overwrite)
            {
                if (settingsfile.better)
                {
                    mediafile newfile(filename);
                    mediafile oldfile(newfilename);
                    if (newfile.readsuccess&&oldfile.readsuccess)
                    {
                        if (newfile.bitrate>oldfile.bitrate)
                        {
                            if (!settingsfile.remove)
                            {
                                iswritten=copyfile(filename,newfilename);
                            }
                            else
                            {
                                //First of all, check if filename changed. Never delete files that are not renamed!!!!!!
                                //Otherwise:No more files, if user writes his cleaned up files into the reading-dir.
                                if (filename.compare(newfilename))
                                {
                                    QFileInfo movecheck(filename);
                                    if (movecheck.isWritable())
                                    {
                                        iswritten=copyfile(filename,newfilename);
                                        if(iswritten==1)
                                        {
                                            QDir transaction;
                                            transaction.remove(filename);
                                            checkdirempty(filename);
                                        }
                                        else
                                        {
                                            QString message=QString(i18n("File %1 will not be removed because, because %2 was not written!")).arg(filename,newfilename);
                                            if (QMessageBox::warning(parent,i18n("Write error"),message,"&Ok",i18n("&Cancel"),QString::null,1))
                                                abort=TRUE;
                                        };
                                    }
                                    else
                                    {
                                        QString message=QString(i18n("File %1 is writeprotected.<br>File will be copied only, if you press OK.")).arg(filename);
                                        if (QMessageBox::warning(parent,i18n("Delete error"),message,"&Ok",i18n("&Cancel"),QString::null,1))
                                            abort=TRUE;
                                        else
                                            iswritten=copyfile(filename,newfilename);
                                    }
                                }
                            }
                        }
                        else //Bitrate less or equal. Check if we need to delete original
                        {
                            if (settingsfile.remove)
                            {
                                //First of all, check if filename changed. Never delete files that are not renamed!!!!!!
                                //Otherwise:No more files, if user writes his cleaned up files into the reading-dir.
                                if (filename.compare(newfilename))
                                {
                                    QFileInfo movecheck(filename);
                                    if (movecheck.isWritable()&&iswritten==1)
                                    {
                                        QDir transaction;
                                        transaction.remove(filename);
                                        checkdirempty(filename);
                                    }
                                    else
                                    {
                                        QString message=QString(i18n("File %1 is writeprotected.<br>File will be copied only, if you press OK.")).arg(filename);
                                        if (QMessageBox::warning(parent,i18n("Delete error"),message,"&Ok",i18n("&Cancel"),QString::null,1))
                                            abort=TRUE;
                                    }
                                }
                            }
                            //we need to set this flag, because we want to save any existing covers
                            iswritten=TRUE;
                        }
                    }
                }
                else
                {
                    if (!settingsfile.remove)
                    {
                        iswritten=copyfile(filename,newfilename);
                    }
                    else
                    {
                        QString message=QString(i18n("File %1 is writeprotected.<br>File will be copied only, if you press OK.")).arg(filename);
                        if (QMessageBox::warning(parent,i18n("Delete error"),message,"&Ok",i18n("&Cancel"),QString::null,1))
                            abort=TRUE;
                        else
                            iswritten=copyfile(filename,newfilename);
                    }
                }
            }
        }
        if((iswritten==1||iswritten==0)&&isproppertagged)
        {
            //file is written and moved in destinationdir, so we can add a picture to the dir
            //read tags once again
            int retrycounter=0;
            mediafile *processedfile=NULL;
            while (!processedfile&&retrycounter++<5)
            {
                //Wait a little, and retry reading the file
                kapp->processEvents();
                processedfile=new mediafile(newfilename);
                if(!processedfile->readsuccess)
                    delete processedfile;
            }
            if (processedfile->readsuccess)
            {
                processedfile->readTags();
                if (processedfile->picturepossible)
                {
                    processedfile->readPicture();
                    if (!processedfile->taginfo.cdcover.isNull()&&settingsfile.savepicture)
                    {
                        //There is a picture. Store it in the dir under given filename in settingsfile
                        //Scale it to the size given in settingsfile
                        QPixmap picture=processedfile->taginfo.cdcover;
                        QImage scaledcover;
                        scaledcover=picture;
                        scaledcover=scaledcover.smoothScale(settingsfile.picturesize,settingsfile.picturesize,QImage::ScaleMin);
                        //Write it in the actual directory, so we need to get this out of our filename
                        QString workingdirectory=newfilename.left(newfilename.findRev("/")+1);
                        QString picturename=QString("%1%2.%3").arg(workingdirectory,settingsfile.picturename,settingsfile.pictureformat);
                        QFileInfo picturecheck(picturename);
                        if (!picturecheck.exists())
                        {
                            //Only save picture, if we don't already have a picture by that name in the directory
                            if (!settingsfile.pictureformat.compare("jpg"))
                                scaledcover.save(picturename,"JPEG");
                            else if (!settingsfile.pictureformat.compare("png"))
                                scaledcover.save(picturename,"PNG");
                            else if (!settingsfile.pictureformat.compare("bmp"))
                                scaledcover.save(picturename,"BMP");
                        }
                    }
                }
                //Enter the values in the mysql-tables for the new generated files
                if (settingsfile.databasetype)
                {
                    database->writetag(&processedfile->taginfo,newfilename);
                    if (settingsfile.remove)
                    {
                        //Remove old database-entry
                        database->removefile(filename);
                    }
                }
                delete processedfile;
            }
            else
                cerr<<"Cant open written file"<<endl;
        }
        ++index;
    }
    delete progresswindow;
    if (!abort&&goodfiles>0||badfiles>0)
    {
        //Only popup on error, when verbose not set
        if (badfiles>0||settingsfile.verbose)
        {
            QString erfolg=QString(i18n("%1 files recognized as propper tagged. %2 files have incomplete or missing tags.")).arg(QString::number(goodfiles),QString::number(badfiles));
            QMessageBox::information(parent,i18n("Process ready"),erfolg,"&Ok");
        }
    }
}

void cleanup::cleanupcd(QStringList *selectedFiles,long counter)
{
    progresswithbar *cleanupprogress=progresswindow->startProgress(i18n("Cleaning up files"),counter);
    connect (cleanupprogress,SIGNAL(cancelled()),SLOT(abortslot()));
    QStringList::Iterator index=selectedFiles->begin();
    long runningcounter=0;
    while (index!=selectedFiles->end()&&!abort)
    {
        bool isproppertagged=FALSE;//Indicates if the operated file is tagged right
        int iswritten=0;//Indicates if the file was written successfully
        cleanupprogress->setProgress(++runningcounter);
        QString filename=*index;
        QString newfilename;
        int status=cleanupfilter->makeDirectories(filename,settingsfile.destination_dir);
        if (status==-1)
        {
            abort=TRUE;
            QString errormessage=QString(i18n("%1<br>The ripped files will stay in the <b>Temp-directory!")).arg(cleanupfilter->errorText);
            QMessageBox::warning(parent,i18n("Process canceled"),errormessage,"&Ok",QString::null,QString::null,1);
        }
        else
        {
            status=cleanupfilter->generateName(filename);
            if (status==-1)
            {
                abort=TRUE;
                QString errormessage=QString(i18n("%1<br>The ripped files will stay in the <b>Temp-directory!")).arg(cleanupfilter->errorText);
                QMessageBox::warning(parent,i18n("Process canceled"),errormessage,"&Ok",QString::null,QString::null,1);
            }
            else
            {
                isproppertagged=TRUE;
                newfilename=QString("%1%2.%3").arg(settingsfile.destination_dir,cleanupfilter->filenamesuggest,QString(*index).right(3));
                QFileInfo filecheck(newfilename);
                if (!filecheck.exists())
                {
                    iswritten=copyfile(filename,newfilename);
                    if (iswritten==1)
                    {
                        QDir transaction;
                        transaction.remove(filename);
                    }
                }
                else
                {
                    if (settingsfile.overwrite)
                    {
                        if (settingsfile.better)
                        {
                            mediafile newfile(filename);
                            mediafile oldfile(newfilename);
                            if (newfile.readsuccess&&oldfile.readsuccess)
                            {
                                if (newfile.bitrate>=oldfile.bitrate)
                                {
                                    QFileInfo movecheck(newfilename);
                                    if (movecheck.isWritable())
                                    {
                                        iswritten=copyfile(filename,newfilename);
                                        if (iswritten==1)
                                        {
                                            QDir transaction;
                                            transaction.remove(filename);
                                        }
                                        else
                                        {
                                            QString message=QString(i18n("File %1 could for some reason not be written<br>The ripped files will stay in the <b>Temp-directory!")).arg(newfilename);
                                            QMessageBox::warning(parent,i18n("Write-error"),message,"&Ok",i18n("&Cancel"),QString::null,1);
                                            abort=TRUE;
                                        }
                                    }
                                    else
                                    {
                                        QString message=QString(i18n("File %1 is already existing and writeprotected.<br>The ripped files will stay in the <b>Temp-directory!")).arg(newfilename);
                                        QMessageBox::warning(parent,i18n("Overwrite-error"),message,"&Ok",i18n("&Cancel"),QString::null,1);
                                        abort=TRUE;
                                    }
                                }
                            }
                            else
                            {
                                QDir transaction;
                                transaction.remove(filename);
                            }
                        }
                        else //Bitrate less or equal. Check if we need to delete original
                        {
                            QDir transaction;
                            transaction.remove(filename);
                            //only for writing pictures needed
                            iswritten=1;
                        }
                    }
                    else
                    {
                        QDir transaction;
                        transaction.remove(filename);
                        //only for writing pictures needed
                        iswritten=1;
                    }
                }
            }
        }
        if((iswritten==1||iswritten==0)&&isproppertagged&!abort)
        {

            //file is written and moved in destinationdir, so we can add a picture to the dir
            //read tags once again
            int retrycounter=0;
            mediafile *processedfile=NULL;
            while (!processedfile&&retrycounter++<5)
            {
                //Wait a little, and retry reading the file
                kapp->processEvents();
                processedfile=new mediafile(newfilename);
                if(!processedfile->readsuccess)
                    delete processedfile;
            }
            if (processedfile->readsuccess)
            {
                processedfile->readTags();
                if (processedfile->picturepossible)
                {
                    processedfile->readPicture();
                    if (!processedfile->taginfo.cdcover.isNull()&&settingsfile.savepicture)
                    {
                        //There is a picture. Store it in the dir under given filename in settingsfile
                        //Scale it to the size given in settingsfile
                        QPixmap picture=processedfile->taginfo.cdcover;
                        QImage scaledcover;
                        scaledcover=picture;
                        scaledcover=scaledcover.smoothScale(settingsfile.picturesize,settingsfile.picturesize,QImage::ScaleMin);
                        //Write it in the actual directory, so we need to get this out of our filename
                        QString workingdirectory=newfilename.left(newfilename.findRev("/")+1);
                        QString picturename=QString("%1%2.%3").arg(workingdirectory,settingsfile.picturename,settingsfile.pictureformat);
                        QFileInfo picturecheck(picturename);
                        if (!picturecheck.exists())
                        {
                            //Only save picture, if we don't already have a picture by that name in the directory
                            if (!settingsfile.pictureformat.compare("jpg"))
                                scaledcover.save(picturename,"JPEG");
                            else if (!settingsfile.pictureformat.compare("png"))
                                scaledcover.save(picturename,"PNG");
                            else if (!settingsfile.pictureformat.compare("bmp"))
                                scaledcover.save(picturename,"BMP");

                        }
                    }
                }
                if (settingsfile.databasetype)
                {
                    database->writetag(&processedfile->taginfo,newfilename);
                }
                delete processedfile;
            }
            else
                cerr<<"Cant open written file"<<endl;
        }
        index++;
    }
    delete cleanupprogress;
    delete progresswindow;
}

void cleanup::abortslot()
{
    abort=TRUE;
}

void cleanup::checkdirempty(QString file)
{
    //extract directoryname out of filename
    QString cleandir=file.left(file.findRev('/'));
    QDir *checkdir=new QDir();
    checkdir->setCurrent(cleandir);
    checkdir->setNameFilter("*");
    QStringList buffer=checkdir->entryList();
    QStringList::Iterator index=buffer.begin();
    int counter=0;
    while (index!=buffer.end())
    {
        index++;
        counter++;
    }
    if (!(counter>2))
    {
        //if directory is empty (except the /. and /.. entry), check if we are still not in startdir
        if (cleandir.compare(settingsfile.reading_dir.left(settingsfile.reading_dir.length()-1)))
            checkdir->rmdir(cleandir);
        checkdirempty(cleandir);//recursively check the next lower dir, untill startdir is reached
    }
    delete checkdir;
}
