#include "hotlistbox.h"
#include "uimanager.h"
#include "fileop.h"
#include "ifapp.h"
#include <qdragobject.h>
#include <qpopupmenu.h>
#include <qtoolbutton.h>
#include <qinputdialog.h>
#include <qpainter.h>
#include <qdir.h>
#include <qstyle.h>
#include <klocale.h>
#include <kconfig.h>
#include <kiconloader.h>
#include <kglobal.h>
#include <kstddirs.h>
#include <kmessagebox.h>


KIFHotListBox::KIFHotListBox(UIManager *manager, QWidget *parent,
                             const char *name)
    : QListBox(parent, name)
{
    mgr = manager;
    setAcceptDrops(true);
    addBtn = new QToolButton(this);
    addBtn->setIconSet(BarIcon("hotlistadd", 16));
    addBtn->setTextLabel(i18n("Add Current Directory"));
    addBtn->resize(addBtn->sizeHint());
    connect(addBtn, SIGNAL(clicked()), this, SLOT(slotAddClicked()));
    
    delBtn = new QToolButton(this);
    delBtn->setIconSet(BarIcon("hotlistdel", 16));
    delBtn->setTextLabel(i18n("Remove Selected HotList Item"));
    delBtn->resize(delBtn->sizeHint());
    connect(delBtn, SIGNAL(clicked()), this, SLOT(slotDelClicked()));

    connect(this, SIGNAL(selected(int)), this, SLOT(slotSelected(int)));
    setSelectionMode(QListBox::Single);
    reload();

}

void KIFHotListBox::reload()
{
    clear();
    paths.clear();


    insertItem(BarIcon("kfm_home", KIcon::SizeMedium), i18n("Home"), 0);
    paths.append(QDir::homeDirPath());
    
    KConfig *config = KGlobal::config();

    config->setGroup("Thumbnails");
    QStringList nameList = config->readListEntry("Names");
    QStringList pathList = config->readListEntry("Paths");

    if(!nameList.count() || ! pathList.count())
        return;
    int i=1;
    for(QStringList::Iterator it = nameList.begin(); it != nameList.end();
        ++it, ++i){
        insertItem(BarIcon("folder", KIcon::SizeMedium),
                   (*it), i);
    }
    for(QStringList::Iterator pit = pathList.begin(); pit != pathList.end();
        ++pit)
        paths.append((*pit));
}

void KIFHotListBox::dragEnterEvent(QDragEnterEvent *ev)
{
    lastDndHighlight = NULL;;
    ev->accept(QUriDrag::canDecode(ev));
}

void KIFHotListBox::dragLeaveEvent(QDragLeaveEvent *)
{
    if(lastDndHighlight)
        setSelected(lastDndHighlight, false);
    lastDndHighlight = NULL;;
}

void KIFHotListBox::dragMoveEvent(QDragMoveEvent *ev)
{
    if(itemAt(ev->pos())){
        QRect r = itemRect(itemAt(ev->pos()));
        // itemAt is supposed to return NULL if not on an item, but returns
        // the last item no matter how far down you are :P
        if(r.contains(ev->pos())){
            if(lastDndHighlight != itemAt(ev->pos())){
                if(currentItem() != -1)
                    setSelected(currentItem(), false);
                lastDndHighlight = itemAt(ev->pos());
                setSelected(lastDndHighlight, true);
            }
            ev->accept();
        }
        else
            ev->ignore();
    }
    else
        ev->ignore();
}


void KIFHotListBox::dropEvent(QDropEvent *ev)
{
    int i = -1;
    if(lastDndHighlight){
        i = currentItem();
        setSelected(lastDndHighlight, false);
    }
    if(i == -1)
        return;
    qWarning("Drop on %s", text(i).latin1());
    QStringList fileList;
    if(!QUriDrag::decodeLocalFiles(ev, fileList)){
        qWarning("Pixie: Can't decode drop.");
        return;
    }
    if(!fileList.count())
        return;
    int op;
    QPopupMenu opPopup;
    opPopup.insertItem(i18n("&Copy Here"), 1);
    opPopup.insertItem(i18n("&Move Here"), 2);
    opPopup.insertItem(i18n("&Link Here"), 3);
    QPoint pos = contentsToViewport(ev->pos());
    op = opPopup.exec(viewport()->mapToGlobal(pos));
    switch(op){
    case 1:
        ev->setAction(QDropEvent::Copy);
        break;
    case 2:
        ev->setAction(QDropEvent::Move);
        break;
    case 3:
        ev->setAction(QDropEvent::Link);
        break;
    default:
        return;
    }
    // TESTING!!
    KIFFileTransfer::transferFiles(fileList, paths[i], ev->action());
}

void KIFHotListBox::resizeEvent(QResizeEvent *ev)
{
    QListBox::resizeEvent(ev);
    addBtn->move(viewport()->width()+1-addBtn->width()-delBtn->width(),
                 viewport()->y());
    delBtn->move(viewport()->width()+1-delBtn->width(), viewport()->y());
}

void KIFHotListBox::slotAddClicked()
{
    QString path = mgr->currentPath();
    QFileInfo fi(path);
    if(!fi.isDir()){
        qWarning("Pixie: Hotlist addition on invalid path!");
        return;
    }

    QString labelStr = QInputDialog::getText(i18n("HotList Name"),
                                             i18n("Please enter a symbolic name\
 to use when\n\
accessing this directory from the hotlist."), QLineEdit::Normal, fi.baseName(), 0, this);
    if(!labelStr)
        return;

    KConfig *config = KGlobal::config();
    config->setGroup("Thumbnails");
    QStringList nameList = config->readListEntry("Names");
    QStringList pathList = config->readListEntry("Paths");
    nameList.append(labelStr);
    pathList.append(fi.absFilePath());
    config->writeEntry("Names", nameList);
    config->writeEntry("Paths", pathList);
    config->sync();
    reload();
}

void KIFHotListBox::slotDelClicked()
{
    int id = currentItem();
    if(id == 0){
        KMessageBox::sorry(this,
                           i18n("Cannot remove the Home folder!"),
                           i18n("Pixie HotList Error"));
        return;
    }
    if(id != -1){
        KConfig *config = KGlobal::config();
        config->setGroup("Thumbnails");
        QStringList nameList;
        QStringList pathList;
        unsigned int i;
        // skip home dir
        for(i=1; i < count(); ++i){
            if(i != (unsigned int)id){
                nameList.append(text(i));
                pathList.append(paths[i]);
            }
        }
        config->writeEntry("Names", nameList);
        config->writeEntry("Paths", pathList);
        config->sync();
        reload();
    }
}



void KIFHotListBox::slotSelected(int idx)
{
    emit hotListClicked(paths[idx]);
}

void KIFHotListBox::paintCell(QPainter *p, int row, int col)
{
    const QColorGroup & g = colorGroup();
    QListBoxItem * i = item( col*numRows()+row );
    p->save();
    if (i->selected()) {
        p->fillRect( 0, 0, maxItemWidth(), i->height(this), g.brush( QColorGroup::Highlight ) );
        p->setPen( g.highlightedText() );
        p->setBackgroundColor( g.highlight() );
    }
    else {
        p->fillRect( 0, 0, maxItemWidth(), i->height(this),
                     row & 0x01 ? g.base().dark(110) : g.base());
    }

    if(i->pixmap())
        p->drawPixmap(3, 0, *i->pixmap());
    if (!i->text().isEmpty()){
        int pixW = i->pixmap() ? i->pixmap()->width() : 0;
        int pixH = i->pixmap() ? i->pixmap()->height() : 0;

        QFontMetrics fm = p->fontMetrics();
        int yPos;                       // vertical text position
        if (pixH < fm.height())
            yPos = fm.ascent() + fm.leading()/2;
        else
            yPos = pixH/2 - fm.height()/2 + fm.ascent();
        p->drawText(pixW + 5, yPos, i->text());
    }

    if(item(currentItem()) == i && hasFocus()){
        style().drawPrimitive( QStyle::PE_FocusRect, p,
                               QRect( 0, 0, maxItemWidth(), i->height(this)),
                               g, QStyle::Style_FocusAtBorder,
                               QStyleOption(i->isSelected() ? g.highlight() :
                                            g.base() ) );        
    }
    p->restore();
}




