/***************************************************************************
                          sq_threaddirlister.cpp  -  description
                             -------------------
    begin                : Feb 10 2007
    copyright            : (C) 2007 by Baryshev Dmitry
    email                : ksquirrel.iv@gmail.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <tqfile.h>
#include <tqdir.h>
#include <tqobject.h>
#include <tqfileinfo.h>
#include <tqdatetime.h>
#include <tqapplication.h>

#include <tdeconfig.h>
#include <tdeglobal.h>

#include "sq_threaddirlister.h"

SQ_ThreadDirLister::SQ_ThreadDirLister(TQObject *o) 
    : TQThread(), obj(o)
{
    cache = new TDEConfig("ksquirrel-tree-cache");
    dir = 0;
}

SQ_ThreadDirLister::~SQ_ThreadDirLister()
{
    // sync() & delete
    delete cache;
}

void SQ_ThreadDirLister::run()
{
    KURL      url;
    TQString   path, name, filepath;
    dirent   *file;
    int       count_files, count_dirs;
    TQDateTime dt, dt_def;
    TQFileInfo fi;
    bool b_read;

    static const TQString &dot    = TDEGlobal::staticQString(".");
    static const TQString &dotdot = TDEGlobal::staticQString("..");

    while(true)
    {
        waitMutex();
        count_files = todo.count();
        unlock();

        if(!count_files) break;

        waitMutex();
        url = todo.first();
        unlock();

        path = url.path();
        count_files = count_dirs = 0;
        b_read = true;
        fi.setFile(path);

        if(cache->hasGroup(path))
        {
            cache->setGroup(path);
            dt = cache->readDateTimeEntry("modified", &dt_def);

            // compare cached time and real time
            if(dt.isValid() && fi.lastModified() == dt)
            {
                count_files = cache->readNumEntry("count_files", 0);
                count_dirs = cache->readNumEntry("count_dirs", 0);
                b_read = false;
            }
        }

        if(b_read)
        {
            dir = opendir(TQFile::encodeName(path));
            dt = fi.lastModified(); // save directory last modified time

            if(dir)
            {
                while((file = readdir(dir)))
                {
                    name = TQFile::decodeName(file->d_name);

                    if(name != dot && name != dotdot)
                    {
                       filepath = path + TQDir::separator() + name;

                       fi.setFile(filepath);

                       if(fi.isDir())
                            count_dirs++;
                        else
                            count_files++;
                    }
                }

                closeDir();
            }
            else // opendir() failed, this value won't be cached
                b_read = false;
        }

        waitMutex();
        todo.pop_front();
        unlock();

        // cache only new values
        if(b_read)
        {
            cache->setGroup(path);
            cache->writeEntry("modified", dt);
            cache->writeEntry("count_files", count_files);
            cache->writeEntry("count_dirs", count_dirs);
        }

        TQApplication::postEvent(obj, new SQ_ItemsEvent(url, count_files, count_dirs));
    }// while
}

void SQ_ThreadDirLister::closeDir()
{
    if(dir)
    {
        closedir(dir);
        dir = 0;
    }
}
