/* ============================================================
 *
 * This file is a part of digiKam project
 * http://www.digikam.org
 *
 * Date        : 2007-08-31
 * Description : a widget to display free space for a mount-point.
 * 
 * Copyright (C) 2007 by Gilles Caulier <caulier dot gilles at gmail dot 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, 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.
 * 
 * ============================================================ */

// TQt includes.

#include <tqwhatsthis.h>
#include <tqtooltip.h>
#include <tqpainter.h>
#include <tqpixmap.h>
#include <tqpalette.h>
#include <tqcolor.h>
#include <tqtimer.h>
#include <tqfont.h> 
#include <tqfontmetrics.h> 

// KDE includes.

#include <kurl.h>
#include <tdelocale.h>
#include <kdiskfreesp.h>
#include <tdeio/global.h>
#include <kiconloader.h>

// Local includes.

#include "albumsettings.h"
#include "freespacewidget.h"
#include "freespacewidget.moc"

namespace Digikam
{

class FreeSpaceWidgetPriv
{
public:

    FreeSpaceWidgetPriv()
    {
        timer       = 0;
        isValid     = false;
        kBSize      = 0;
        kBUsed      = 0;
        kBAvail     = 0;
        dSizeKb     = 0;
        percentUsed = 0;
    }

    bool           isValid;
    
    int            percentUsed;

    unsigned long  dSizeKb;
    unsigned long  kBSize;
    unsigned long  kBUsed;
    unsigned long  kBAvail;
    
    TQString        mountPoint;

    TQTimer        *timer;
    
    TQPixmap        pix;
};

FreeSpaceWidget::FreeSpaceWidget(TQWidget* parent, int width)
               : TQWidget(parent, 0, WResizeNoErase|WRepaintNoErase)
{
    d = new FreeSpaceWidgetPriv;
    setBackgroundMode(TQt::NoBackground);
    setFixedWidth(width);
    setMaximumHeight(fontMetrics().height()+4);
    slotTimeout();
    
    d->timer = new TQTimer(this);
    
    connect(d->timer, TQ_SIGNAL(timeout()),
            this, TQ_SLOT(slotTimeout()));

    d->timer->start(10000);
}

FreeSpaceWidget::~FreeSpaceWidget()
{
    d->timer->stop();
    delete d->timer;
    delete d;
}

void FreeSpaceWidget::setEstimatedDSizeKb(unsigned long dSize)
{
    d->dSizeKb = dSize;
    updatePixmap();
    repaint();
}

unsigned long FreeSpaceWidget::estimatedDSizeKb()
{
    return d->dSizeKb;
}

bool FreeSpaceWidget::isValid()
{
    return d->isValid;
}

int FreeSpaceWidget::percentUsed() 
{
    return d->percentUsed;
}

unsigned long FreeSpaceWidget::kBSize()
{
    return d->kBSize;
}

unsigned long FreeSpaceWidget::kBUsed()
{
    return d->kBUsed;
}

unsigned long FreeSpaceWidget::kBAvail()
{
    return d->kBAvail;
}

TQString FreeSpaceWidget::mountPoint()
{
    return d->mountPoint;
}

void FreeSpaceWidget::updatePixmap()
{
    TQPixmap fimgPix = SmallIcon("folder_image");
    d->pix          = TQPixmap(size());
    d->pix.fill(colorGroup().background());
    
    TQPainter p(&d->pix);
    p.setPen(colorGroup().mid());
    p.drawRect(0, 0, d->pix.width(), d->pix.height());
    p.drawPixmap(2, d->pix.height()/2-fimgPix.height()/2, 
                 fimgPix, 0, 0, fimgPix.width(), fimgPix.height());
                 
    if (isValid())
    {
        // We will compute the estimated % of space size used to download and process.
        unsigned long eUsedKb = d->dSizeKb + d->kBUsed;
        int peUsed            = (int)(100.0*((double)eUsedKb/(double)d->kBSize));
        int pClamp            = peUsed > 100 ? 100 : peUsed;
        p.setBrush(peUsed > 95 ? TQt::red : TQt::darkGreen);
        p.setPen(TQt::white);
        TQRect gRect(fimgPix.height()+2, 1,
                    (int)(((double)d->pix.width()-2.0-fimgPix.width()-2.0)*(pClamp/100.0)),
                    d->pix.height()-2);
        p.drawRect(gRect);

        TQRect tRect(fimgPix.height()+2, 1, d->pix.width()-2-fimgPix.width()-2, d->pix.height()-2);
        TQString text = TQString("%1%").arg(peUsed);
        p.setPen(colorGroup().text());
        TQFontMetrics fontMt = p.fontMetrics();
        TQRect fontRect      = fontMt.boundingRect(tRect.x(), tRect.y(),
                                                  tRect.width(), tRect.height(), 0, text);
        p.drawText(tRect, TQt::AlignCenter, text);

        TQString tipText, value; 
        TQString header = i18n("Album Library");
        TQString headBeg("<tr bgcolor=\"orange\"><td colspan=\"2\">"
                        "<nobr><font size=\"-1\" color=\"black\"><b>");
        TQString headEnd("</b></font></nobr></td></tr>");
        TQString cellBeg("<tr><td><nobr><font size=-1>");
        TQString cellMid("</font></nobr></td><td><nobr><font size=-1>");
        TQString cellEnd("</font></nobr></td></tr>");
        tipText  = "<table cellspacing=0 cellpadding=0>";
        tipText += headBeg + header + headEnd;

        if (d->dSizeKb > 0)
        {
            tipText += cellBeg + i18n("Capacity:") + cellMid;
            tipText += TDEIO::convertSizeFromKB(d->kBSize) + cellEnd;

            tipText += cellBeg + i18n("Available:") + cellMid;
            tipText += TDEIO::convertSizeFromKB(d->kBAvail) + cellEnd;

            tipText += cellBeg + i18n("Require:") + cellMid;
            tipText += TDEIO::convertSizeFromKB(d->dSizeKb) + cellEnd;
        }
        else
        {
            tipText += cellBeg + i18n("Capacity:") + cellMid;
            tipText += TDEIO::convertSizeFromKB(d->kBSize) + cellEnd;

            tipText += cellBeg + i18n("Available:") + cellMid;
            tipText += TDEIO::convertSizeFromKB(d->kBAvail) + cellEnd;
        }

        tipText += "</table>";

        TQWhatsThis::add(this, tipText);
        TQToolTip::add(this, tipText);
    }
    
    p.end();
}    

void FreeSpaceWidget::paintEvent(TQPaintEvent*)
{
    bitBlt(this, 0, 0, &d->pix);
}

void FreeSpaceWidget::slotTimeout()
{
    TQString mountPoint = TDEIO::findPathMountPoint(AlbumSettings::instance()->getAlbumLibraryPath());
    KDiskFreeSp *job   = new KDiskFreeSp;
    connect(job, TQ_SIGNAL(foundMountPoint(const unsigned long&, const unsigned long&,
                                        const unsigned long&, const TQString&)),
            this, TQ_SLOT(slotAvailableFreeSpace(const unsigned long&, const unsigned long&,
                                              const unsigned long&, const TQString&)));
    job->readDF(mountPoint);
}

void FreeSpaceWidget::slotAvailableFreeSpace(const unsigned long& kBSize, const unsigned long& kBUsed,
                                             const unsigned long& kBAvail, const TQString& mountPoint)
{
    d->mountPoint  = mountPoint;
    d->kBSize      = kBSize;
    d->kBUsed      = kBUsed;
    d->kBAvail     = kBAvail;
    d->percentUsed = 100 - (int)(100.0*kBAvail/kBSize);
    d->isValid     = true;
    updatePixmap();
    repaint();
}

}  // namespace Digikam
