#include "rightclick.h"
#include "uimanager.h"
#include "menuid.h"
#include "fileop.h"
#include "batch.h"
#include "dialogs.h"
#include "aniplayer.h"
#include "attributedialog.h"

#include "ifapp.h"
#include "imageutils.h"
#include "catagorymgr.h"

#include <qpopupmenu.h>
#include <qclipboard.h>
#include <qcursor.h>
#include <qinputdialog.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qdir.h>
#include <qprocess.h>
#include <kmessagebox.h>
#include <kprogress.h>
#include <kpopupmenu.h>
#include <kpropsdlg.h>
#include <kiconloader.h>
#include <klocale.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <utime.h>
#include <string.h>

#include <X11/X.h>
#include <X11/Xlib.h>

EditMenu::EditMenu(UIManager *manager, QWidget *parent, const char *name)
    : KPopupMenu(parent, name)
{
    mgr = manager;
    view = mgr->browser();
    current = NULL;

    if(!parent)
        insertTitle(BarIcon("filenew", KIcon::SizeSmall),
                    i18n("File Options"));
    insertItem(i18n("Convert to..."), ConvertRMB);

    QPopupMenu *batchMnu = new QPopupMenu(this);
    QPopupMenu *transformMnu = new QPopupMenu(batchMnu);
    transformMnu->insertItem(i18n("Scale to Max Size..."), 100+Scale);
    transformMnu->insertItem(i18n("Flip Horizontal"), 100+FlipH);
    transformMnu->insertItem(i18n("Flip Vertical"), 100+FlipV);
    transformMnu->insertItem(i18n("Rotate 90 Degrees"), 100+Rot90);
    transformMnu->insertItem(i18n("Rotate 180 Degrees"), 100+Rot180);
    transformMnu->insertItem(i18n("Rotate 270 Degrees "), 100+Rot270);
    batchMnu->insertItem(i18n("Transform"), transformMnu);
    connect(transformMnu, SIGNAL(activated(int)), this,
            SLOT(activatedSlot(int)));

    QPopupMenu *enhanceMnu = new QPopupMenu(batchMnu);
    enhanceMnu->insertItem(i18n("Spiff"), 100+IncContrast);
    enhanceMnu->insertItem(i18n("Dull"), 100+DecContrast);
    enhanceMnu->insertItem(i18n("Equalize"), 100+Equalize);
    enhanceMnu->insertItem(i18n("Normalize"), 100+Normalize);
    enhanceMnu->insertItem(i18n("Invert"), 100+Invert);
    enhanceMnu->insertItem(i18n("Grayscale"), 100+Grayscale);
    batchMnu->insertItem(i18n("Enhance"), enhanceMnu);
    connect(enhanceMnu, SIGNAL(activated(int)), this,
            SLOT(activatedSlot(int)));

    QPopupMenu *effectsMnu = new QPopupMenu(batchMnu);
    effectsMnu->insertItem(i18n("Add Text..."), 100+AddText);
    effectsMnu->insertItem(i18n("Add Border..."), 100+Border);
    effectsMnu->insertSeparator();
    effectsMnu->insertItem(i18n("Add Noise..."), 100+AddNoise);
    effectsMnu->insertItem(i18n("Despeckle..."), 100+Despeckle);
    effectsMnu->insertItem(i18n("Emboss..."), 100+Emboss);
    effectsMnu->insertItem(i18n("Sharpen..."), 100+Sharpen);
    effectsMnu->insertItem(i18n("Blur..."), 100+Blur);
    effectsMnu->insertItem(i18n("Threshold..."), 100+Threshold);
    effectsMnu->insertItem(i18n("Edge Detect..."), 100+Edge);
    effectsMnu->insertItem(i18n("Spread..."), 100+Spread);
    effectsMnu->insertItem(i18n("Shade..."), 100+Shade);
    batchMnu->insertItem(i18n("Normal Effects"), effectsMnu);
    connect(effectsMnu, SIGNAL(activated(int)), this,
            SLOT(activatedSlot(int)));

    QPopupMenu *specialMnu = new QPopupMenu(batchMnu);
    specialMnu->insertItem(i18n("Solarize..."), 100+Solarize);
    specialMnu->insertItem(i18n("Swirl..."), 100+Swirl);
    specialMnu->insertItem(i18n("Implode..."), 100+Implode);
    specialMnu->insertItem(i18n("Wave..."), 100+Wave);
    specialMnu->insertItem(i18n("Oil Paint..."), 100+OilPaint);
    specialMnu->insertItem(i18n("Charcoal Draw..."), 100+Charcoal);
    batchMnu->insertItem(i18n("Special Effects"), specialMnu);
    insertItem(i18n("Batch Effects"), batchMnu, BatchRMB);
    connect(specialMnu, SIGNAL(activated(int)), this,
            SLOT(activatedSlot(int)));

    insertSeparator();
    insertItem(BarIcon("editcopy", KIcon::SizeSmall), i18n("Copy files"),
              CopyRMB);
    insertItem(BarIcon("editpaste", KIcon::SizeSmall), i18n("Paste"),
              PasteRMB);
    insertSeparator();
    insertItem(BarIcon("filenew", KIcon::SizeSmall),
                    i18n("Copy selection to FileList"), CopySelToFileListRMB);
    insertItem(BarIcon("filenew", KIcon::SizeSmall),
                    i18n("Copy all images to FileList"), CopyAllToFileListRMB);

    insertSeparator();
    insertItem(BarIcon("editcopy", KIcon::SizeSmall),
               i18n("Copy file location"), CopyFilePathRMB);
    insertItem(BarIcon("editcopy", KIcon::SizeSmall),
               i18n("Copy filename only"), CopyFileLocationRMB);

    insertSeparator();
    insertItem(i18n("Select All"), SelectAllRMB);
    insertItem(i18n("Unselect All"), UnselectAllRMB);
    insertSeparator();

    insertItem(i18n("Rename"), RenameRMB);
    insertItem(BarIcon("edittrash", KIcon::SizeSmall), i18n("Delete"),
               DeleteRMB);
#ifdef __ENABLE_WIPE
    insertItem(BarIcon("edittrash", KIcon::SizeSmall), i18n("Wipe"),
               WipeRMB);
#endif
    insertItem(BarIcon("wizard", KIcon::SizeSmall), i18n("Properties"),
              PropertiesRMB);
    insertItem(i18n("Play Animation (Fullscreen only)"), PlayAniRMB);

    insertSeparator();
    QPopupMenu *catMnu = new QPopupMenu(this);
    addMnu = new QPopupMenu;
    delMnu = new QPopupMenu;
    catMnu->insertItem(i18n("Add to category"), addMnu);
    catMnu->insertItem(i18n("Remove from category"), delMnu);
    connect(addMnu, SIGNAL(activated(int)), this, SLOT(activatedSlot(int)));
    connect(delMnu, SIGNAL(activated(int)), this, SLOT(activatedSlot(int)));
    insertItem(i18n("Categories..."), catMnu, CatagoryRMB);

    insertItem(i18n("Make newest file(s)"), MakeNewestRMB);
    insertItem(i18n("Make oldest file(s)"), MakeOldestRMB);
    insertTitle(BarIcon("mini-ray.png", KIcon::SizeSmall),
                         i18n("Copy to HotList (Shift to Move)"));

    connect(this, SIGNAL(aboutToShow()), this, SLOT(aboutToShowSlot()));
    connect(this, SIGNAL(aboutToHide()), this, SLOT(aboutToHideSlot()));
    connect(this, SIGNAL(activated(int)), this, SLOT(activatedSlot(int)));
}

void EditMenu::aboutToShowSlot()
{
    qWarning("In aboutToShowSlot()");
    QString currentDir(view->currentDirStr());
    bool supportCatagories = kifapp()->catagoryManager()->count() != 0;
    bool hasSelection = view->selection()->count();
    bool multipleSelected = view->selection()->count() > 1;
    bool isImage = view->selection()->count() == 1 &&
        view->selectionHasImages();
    QStringList nameList;
    int i;

    setItemEnabled(ConvertRMB, isImage ||
                   multipleSelected && view->selectionHasImages());
    setItemEnabled(BatchRMB, isImage || multipleSelected &&
                   view->selectionHasImages());
    setItemEnabled(PlayAniRMB, isImage);

    setItemEnabled(CopyRMB, hasSelection);
    setItemEnabled(CopySelToFileListRMB, isImage || multipleSelected &&
                   view->selectionHasImages());
    setItemEnabled(CopyFilePathRMB, hasSelection && !multipleSelected);
    setItemEnabled(CopyFileLocationRMB, hasSelection && !multipleSelected);
    setItemEnabled(DeleteRMB, hasSelection);
#ifdef __ENABLE_WIPE
    setItemEnabled(WipeRMB, hasSelection);
#endif
    setItemEnabled(RenameRMB, hasSelection && !multipleSelected);
    setItemEnabled(PropertiesRMB, hasSelection && !multipleSelected);
    setItemEnabled(MakeNewestRMB, hasSelection);
    setItemEnabled(MakeOldestRMB, hasSelection);
    setItemEnabled(CatagoryRMB, supportCatagories &&
                   !view->selectionHasFolders() &&
                   (multipleSelected || hasSelection));
    setItemEnabled(UnselectAllRMB, hasSelection);

    // clear old hotlist items
    for(i = 25; indexOf(i) != -1; ++i)
        removeItem(i);

    // add hotlist items
    KConfig *config = KGlobal::config();
    config->setGroup("Thumbnails");
    nameList = config->readListEntry("Names");
    nameList.prepend(i18n("Home"));
    i = 25;
    for(QStringList::Iterator it = nameList.begin();
        it != nameList.end(); ++it, ++i){
        insertItem(BarIcon("folder", KIcon::SizeSmall), (*it), i);
        setItemEnabled(i, multipleSelected || hasSelection);
    }
    // add catagories
    addMnu->clear();
    delMnu->clear();
    QStringList catList(*kifapp()->catagoryManager()->catagoryList());
    QStringList::Iterator it;
    Thumbnail *itemList = view->allItems();
    int idx = -1;
    i = 0;

    if(!multipleSelected && hasSelection){
        idx = *(view->selection()->begin());
        if(S_ISDIR(itemList[idx].status->st_mode))
            idx = -1;
    }
    if(idx != -1){
        Thumbnail *thumb = (Thumbnail *)&itemList[idx];
        QStringList itemList(view->itemCatagories(thumb));
         for(it=catList.begin(), i=1000; it != catList.end(); ++it, ++i){
             if(itemList.findIndex((*it)) == -1)
                 addMnu->insertItem((*it), i);
             else
                 delMnu->insertItem((*it), i+1000);
         }
    }
    else{
        for(it=catList.begin(), i=1000; it != catList.end(); ++it, ++i){
            addMnu->insertItem((*it), i);
            delMnu->insertItem((*it), i+1000);
        }
    }
}

void EditMenu::aboutToHideSlot()
{

}

void EditMenu::execItem(Thumbnail *i, const QPoint &pos)
{
    current = i;
    exec(pos);
    current = NULL;
}

void EditMenu::activatedSlot(int id)
{
    qWarning("In activatedSlot, id: %d", id);

    QString currentDir(view->currentDirStr());
    Thumbnail *itemList = view->allItems();
    Thumbnail *item = NULL;
    bool isDir = false;
    bool hasSelection = view->selection()->count();
    bool multipleSelected = view->selection()->count() > 1;
    bool isImage = view->selection()->count() == 1 &&
        view->selectionHasImages();

    if(hasSelection && !multipleSelected){
        int idx = *(view->selection()->begin());
        item = &itemList[idx];
        if(S_ISDIR(item->status->st_mode))
            isDir = true;
    }

    if(id == -1)
        return;
    else if(id == ConvertRMB){
        ConvertDialog dlg(view);
        if(dlg.exec() == QDialog::Rejected)
            return;
        else{
            QFileInfo fi;
            QImage img;
            QString fileStr, extStr;
            int i, c = view->count();
            int quality = -1;
            QString commentStr;
            bool useQuality = false;
            bool saved;

            if(formatUsesComment(dlg.format().latin1()))
                useQuality = true;
            if(useQuality){
                KIFAttributeDialog attrDlg(true, view);
                if(attrDlg.exec() == QDialog::Rejected)
                    return;
                else{
                    commentStr = attrDlg.comment();
                    quality = attrDlg.quality();
                }
            }
            view->watch()->stopDirScan(view->currentDirStr());
            QApplication::setOverrideCursor(WaitCursor);
            for(i=0; i < c; ++i){
                if(itemList[i].selected &&
                   view->isImage(&itemList[i], currentDir+"/"+
                                 itemList[i].filename, false)){
                    QFileInfo fi(currentDir + "/" + itemList[i].filename);
                    extStr = fi.extension();
                    if(extStr.isEmpty())
                        fileStr = fi.fileName() + dlg.extension();
                    else
                        fileStr = fi.baseName(true) + dlg.extension();
                    if(fileStr != itemList[i].filename){
                        mgr->progressLabel()->
                            setText(i18n("Converting %1 -> %2").arg(itemList[i].filename).arg(fileStr.latin1()));
                        qApp->processEvents();
                        if(loadImage(img, fi.absFilePath())){
                            saved = useQuality ?
                                saveImage(img, currentDir+"/"+fileStr,
                                          dlg.format().latin1(), quality,
                                          commentStr) :
                                saveImage(img, currentDir+"/"+fileStr,
                                          dlg.format().latin1());
                            if(!saved){
                                if(KMessageBox::warningContinueCancel(view,
                                    i18n("Could not save %1.").arg(fileStr),
                                    i18n("Convert Error")) == KMessageBox::Cancel){
                                    view->watch()->
                                        restartDirScan(view->currentDirStr());
                                    QApplication::restoreOverrideCursor();
                                    mgr->slotUpdateView();
                                    mgr->progressLabel()->
                                        setText(i18n("Canceled."));
                                    mgr->progressBar()->setValue(0);
                                    return;
                                }
                            }
                        }
                        else{
                            if(KMessageBox::warningContinueCancel(view,
                                i18n("Could not load %1.").arg(fi.fileName()),
                                i18n("Convert Error")) == KMessageBox::Cancel){
                                view->watch()->
                                    restartDirScan(view->currentDirStr());
                                QApplication::restoreOverrideCursor();
                                mgr->slotUpdateView();
                                mgr->progressLabel()->
                                    setText(i18n("Canceled."));
                                mgr->progressBar()->setValue(0);
                                return;
                            }

                        }
                    }
                }
                mgr->progressBar()->setValue((int)(((float)i/c)*100));
                qApp->processEvents();
            }
            QApplication::restoreOverrideCursor();
            view->watch()->restartDirScan(view->currentDirStr());
            mgr->slotUpdateView();
            mgr->progressLabel()->setText(i18n("Convert finished."));
            mgr->progressBar()->setValue(0);
        }
    }
    else if(id == CopyRMB){
        view->copy();
    }
    else if (id == PasteRMB){
        view->paste();
    }
    else if(id == CopySelToFileListRMB){
        int idx;
        QString fileStr;

        view->sortSelectionByView();
        QValueList<int> *selection = view->selection();
        QValueList<int>::Iterator it;

        if(!selection->count())
            return;
        for(it = selection->begin(); it != selection->end(); ++it){
            idx = (*it);
            fileStr = currentDir + "/" + itemList[idx].filename;
            if(view->isImage(&itemList[idx], fileStr, false))
                mgr->slotAddURL(fileStr);
        }
    }
    else if(id == CopyAllToFileListRMB){
        int i, c = view->count();
        QString fileStr;

        for(i=0; i < c; ++i){
            fileStr = currentDir + "/" + itemList[i].filename;
            if(view->isImage(&itemList[i], fileStr, false))
                mgr->slotAddURL(fileStr);
        }
    }
    else if(id == CopyFilePathRMB){
        if(!item)
            return;
        QFileInfo fi(currentDir + "/" + item->filename);
#if QT_VERSION & 0x00FF00
        QApplication::clipboard()->setText(fi.absFilePath(),
                                           QClipboard::Selection);
#else
        QApplication::clipboard()->setText(fi.absFilePath());
#endif
    }
    else if(id == CopyFileLocationRMB){
        if(!item)
            return;
#if QT_VERSION & 0x00FF00
        QApplication::clipboard()->setText(item->filename,
                                           QClipboard::Selection);
#else
        QApplication::clipboard()->setText(item->filename);
#endif
    }
    else if(id == RenameRMB){
        bool result = false;
        struct stat status;
        CatInfo *src, *dest;
        long inode;
        if(!item)
            return;
        QString str = QInputDialog::getText(i18n("Rename File"),
                                            i18n("Enter new filename:"),
                                            QLineEdit::Normal, item->filename,
                                            &result, view);
        if(!result || str.isEmpty())
            return;
        qWarning("Rename for %s to %s", item->filename,
                 str.latin1());

        view->watch()->stopDirScan(view->currentDirStr());
        inode = (long)item->status->st_ino;
        src = view->catagoryDict()->find(inode);
        KIFFileTransfer::transferFile(currentDir+"/"+item->filename,
                                      currentDir+"/"+str, QDropEvent::Move);
        if(src){
            if(stat(QFile::encodeName(currentDir+"/"+str), &status) != -1){
                dest = new CatInfo;
                for(int i=0; i < 8; ++i)
                    dest[i] = src[i];
                view->catagoryDict()->remove(inode);
                view->catagoryDict()->insert((long)status.st_ino, dest);
                view->saveCatagories();
                kifapp()->catagoryManager()->
                    saveFolderCatagories(view->currentDirStr(),
                                         view->catagoryDict());
            }
            else
                qWarning("Could not stat new filename to copy catagories!");
        }
        view->watch()->restartDirScan(view->currentDirStr());
        mgr->slotUpdateView();
    }
    else if(id == DeleteRMB){
        view->watch()->stopDirScan(view->currentDirStr());
        iconRightClickDelete(currentDir, view);
        view->watch()->restartDirScan(view->currentDirStr());
        mgr->slotUpdateView();
    }
#ifdef __ENABLE_WIPE
    // This is not enabled by default yet. The wipe utility is more secure
    // than KDE's shred so we should use it if availble. TODO - check if
    // available and save stderr
    else if(id == WipeRMB){
        int idx;
        QString fileStr;

        view->sortSelectionByView();
        view->watch()->stopDirScan(view->currentDirStr());
        QValueList<int> *selection = view->selection();
        QValueList<int>::Iterator it;
        QStringList argsList;
        argsList.append("wipe");
        argsList.append("-I");
        argsList.append("-s");
        argsList.append("-d");
        argsList.append("-k");
        argsList.append("-l2");

        if(!selection->count())
            return;
        for(it = selection->begin(); it != selection->end(); ++it){
            idx = (*it);
            if(!S_ISDIR(itemList[idx].status->st_mode)){
                argsList.append(itemList[idx].filename);
            }
        }
        QProcess proc(argsList);
        proc.setWorkingDirectory(currentDir);
        if(!proc.start()){
            KMessageBox::sorry(this,
                               i18n("Could not run the wipe command.") +
                               QString::number(proc.exitStatus()),
                               i18n("File Wipe Error"));
        }
        else{
            while(proc.isRunning())
                sleep(1);
            if(proc.exitStatus() != 0)
                KMessageBox::sorry(this,
                                   i18n("The wipe command failed. Exit status: ") +
                                   QString::number(proc.exitStatus()) + "\n" +
                                   strerror(proc.exitStatus()),
                                   i18n("File Wipe Error"));
        }
        view->watch()->restartDirScan(view->currentDirStr());
        mgr->slotUpdateView();
    }
#endif
    else if(id == PropertiesRMB){
        qWarning("In properties");
        if(!item)
            return;
        KFileItem fileitem(item->status->st_mode & S_IFMT,
                           item->status->st_mode & 07777,
                           KURL(QString("file:")+currentDir+"/"+
                           item->filename));
        qWarning("Creating dialog for %s", item->filename);
        (void) new KPropertiesDialog(&fileitem, view);
    }
    else if(id == PlayAniRMB){
        if(item && isImage)
            (void) new KIFAniPlayer(currentDir+"/"+item->filename);
    }
    else if(id == SelectAllRMB){
        view->selectAll();
    }
    else if(id == UnselectAllRMB){
        view->clearSelection(true);
    }
    else if(id == MakeNewestRMB){
        // Make newest file
        QString fileStr, thumbStr;
        struct utimbuf timeBuf;
        struct stat status;
        time_t modtime;
        QStringList newestList; // FIXME: preserve order for multiple selections
        view->sortSelectionByView();
        if(!view->selectionStringList(newestList))
            return;
        modtime = view->newest()+newestList.count()+1;
        for(QStringList::Iterator it = newestList.begin(); it != newestList.end(); ++it) {
            fileStr = (*it);
            if(stat(QFile::encodeName(fileStr), &status) == -1){
                if(KMessageBox::warningContinueCancel(view,
                                                      i18n("Could not access %1.").arg(*it),
                                                      i18n("File Error"))
                   == KMessageBox::Cancel){
                    mgr->slotUpdateView();
                    return;
                }
            }
            else{
                timeBuf.actime = status.st_atime;
                timeBuf.modtime = modtime;
                if(utime(QFile::encodeName(fileStr), &timeBuf) == -1){
                    if(KMessageBox::warningContinueCancel(view,
                                                          i18n("Could not update timestamp for %1.").arg(*it),
                                                          i18n("File Error"))
                       == KMessageBox::Cancel){
                        mgr->slotUpdateView();
                        return;
                    }
                }
                else{
                    // handle thumbnails, too, so they don't get marked as old
                    // don't worry about errors if they don't exist
                    thumbStr = currentDir + "/.pics/huge/" + (*it);
                    if(stat(QFile::encodeName(thumbStr), &status) == 0)
                        utime(QFile::encodeName(thumbStr), &timeBuf);
                    thumbStr = currentDir + "/.pics/large/" + (*it);
                    if(stat(QFile::encodeName(thumbStr), &status) == 0)
                        utime(QFile::encodeName(thumbStr), &timeBuf);
                    thumbStr = currentDir + "/.pics/med/" + (*it);
                    if(stat(QFile::encodeName(thumbStr), &status) == 0)
                        utime(QFile::encodeName(thumbStr), &timeBuf);
                    thumbStr = currentDir + "/.pics/small/" + (*it);
                    if(stat(QFile::encodeName(thumbStr), &status) == 0)
                        utime(QFile::encodeName(thumbStr), &timeBuf);
                }
            }
            --modtime;
        }
        mgr->slotUpdateView();
    }
    else if(id == MakeOldestRMB){
        // Make oldest file
        QString fileStr;
        struct utimbuf timeBuf;
        struct stat status;
        time_t modtime = view->oldest()-1;

        QStringList oldestList;
        view->sortSelectionByView();
        if(!view->selectionStringList(oldestList))
            return;

        for(QStringList::Iterator it = oldestList.begin(); it != oldestList.end(); ++it) {
            fileStr = (*it);
            if(stat(QFile::encodeName(fileStr), &status) == -1){
                if(KMessageBox::warningContinueCancel(view,
                                                      i18n("Could not access %1.").arg(*it),
                                                      i18n("File Error"))
                   == KMessageBox::Cancel){
                    mgr->slotUpdateView();
                    return;
                }
            }
            else{
                timeBuf.actime = status.st_atime;
                timeBuf.modtime = modtime;
                if(utime(QFile::encodeName(fileStr), &timeBuf) == -1){
                    if(KMessageBox::warningContinueCancel(view,
                                                          i18n("Could not update timestamp for %1.").arg(*it),
                                                          i18n("File Error"))
                       == KMessageBox::Cancel){
                        mgr->slotUpdateView();
                        return;
                    }

                }
                --modtime;
            }
        }
        mgr->slotUpdateView();
    }
    else if(id >= 25 && id < 100){
        // Hotlistbox Operations
        KConfig *config = KGlobal::config();
        config->setGroup("Thumbnails");
        QStringList pathList(config->readListEntry("Paths"));
        pathList.prepend(QDir::homeDirPath());

        id = id-25;
        qWarning("HotListBox drop for %s", pathList[id].latin1());
        QStringList fileList;
        view->sortSelectionByView();
        if(!view->selectionStringList(fileList))
            return;
        Window root;
        Window child;
        int root_x, root_y, win_x, win_y;
        uint keybstate;
        XQueryPointer(qt_xdisplay(), qt_xrootwin(), &root, &child,
                      &root_x, &root_y, &win_x, &win_y, &keybstate );
        if(keybstate & ShiftMask)
            KIFFileTransfer::transferFiles(fileList, pathList[id],
                                           QDropEvent::Move);
        else
            KIFFileTransfer::transferFiles(fileList, pathList[id],
                                           QDropEvent::Copy);
    }
    else if(id >= 100 && id < 300){
        // Batch Operations
        QStringList fileList;
        if(!view->selectionStringList(fileList))
            return;
        view->watch()->stopDirScan(view->currentDirStr());
        BatchEffect effectManager(mgr, view, fileList, id-100);
        if(effectManager.apply()){
            mgr->slotUpdateView();
            mgr->resetImageBuffer();
        }
        view->watch()->restartDirScan(view->currentDirStr());
    }
    else if(id >= 1000 && id < 2000){
        // add catagory
        QStringList catList(*kifapp()->catagoryManager()->catagoryList());
        int catId = kifapp()->catagoryManager()->id(catList[id-1000]);
        QValueList<int> *selList = view->selection();
        int idx;
        if(!selList->count()){
            qWarning("No selection!");
            return;
        }
        for(QValueList<int>::Iterator it = selList->begin(); it != selList->end(); ++it){
            idx = (*it);
            view->addCatagory(&itemList[idx], catId);
        }
        view->saveCatagories();
    }
    else{
        // remove catagory
        QStringList catList(*kifapp()->catagoryManager()->catagoryList());
        int catId = kifapp()->catagoryManager()->id(catList[id-2000]);
        QValueList<int> *selList = view->selection();
        int idx;
        if(!selList->count()){
            qWarning("No selection!");
            return;
        }
        for(QValueList<int>::Iterator it = selList->begin(); it != selList->end(); ++it){
            idx = (*it);
            view->removeCatagory(&itemList[idx], catId);
        }
        view->saveCatagories();
    }
}

void viewRightClickMenu(const QString &currentDir, UIManager *mgr,
                        PixieBrowser *view, const QPoint &pos)
{
    KPopupMenu *mnu = new KPopupMenu;
    mnu->insertTitle(BarIcon("filenew", KIcon::SizeSmall),i18n("Folder Options"));
    mnu->insertItem(BarIcon("folder", KIcon::SizeSmall), i18n("Create a new folder..."), 1);
    mnu->insertSeparator();
    mnu->insertItem(BarIcon("up", KIcon::SizeSmall), i18n("Up"), 3);
    mnu->insertItem(BarIcon("back", KIcon::SizeSmall), i18n("Back"), 4);
    mnu->insertItem(BarIcon("forward", KIcon::SizeSmall), i18n("Forward"), 5);
    mnu->insertItem(BarIcon("reload", KIcon::SizeSmall), i18n("Reload"), 6);
    mnu->insertSeparator();
    mnu->insertItem(BarIcon("editcopy", KIcon::SizeSmall), i18n("Copy folder location"), 8);
    mnu->insertItem(BarIcon("editcopy", KIcon::SizeSmall), i18n("Copy all images to FileList"), 9);
    mnu->insertItem(BarIcon("editpaste", KIcon::SizeSmall), i18n("Paste"), 10);
    mnu->insertSeparator();
    mnu->insertItem(BarIcon("wizard", KIcon::SizeSmall), i18n("Properties"), 12);
    mnu->setItemEnabled(3, mgr->isUpDirEnabled());
    mnu->setItemEnabled(4, mgr->isBackDirEnabled());
    mnu->setItemEnabled(5, mgr->isForwardDirEnabled());

    int id = mnu->exec(pos);
    delete mnu;
    if(id == 1){
        bool okay;
        QString folderStr = QInputDialog::getText(i18n("Folder Name"),
                                                  i18n("Please enter a name for the new folder."),
                                                  QLineEdit::Normal, QString::null,
                                                  &okay,
                                                  view);
        if(okay){
            if(mkdir(QFile::encodeName(currentDir + "/" + folderStr), 0777) == -1){
                KMessageBox::sorry(view, i18n("Could not create folder."));
            }
        }
    }
    else if(id == 3)
        mgr->slotUpDir();
    else if(id == 4)
        mgr->slotBackDir();
    else if(id == 5)
        mgr->slotForwardDir();
    else if(id == 6)
        mgr->slotReload();
    else if(id == 8){
#if QT_VERSION & 0x00FF00
        QApplication::clipboard()->setText(currentDir, QClipboard::Selection);
#else
        QApplication::clipboard()->setText(currentDir);
#endif
    }
    else if(id == 9){
        Thumbnail *itemList = view->allItems();
        int i, c = view->count();
        QString fileStr;
        for(i=0; i < c; ++i){
            fileStr = currentDir + "/" + itemList[i].filename;
            if(view->isImage(&itemList[i], fileStr, false))
                mgr->slotAddURL(fileStr);
        }

    }
    else if(id == 10){
        view->paste();
    }
    else if(id == 12){
        // Properties
        KFileItem fileitem(KFileItem::Unknown, KFileItem::Unknown,
                           KURL(QString("file:")+currentDir+"/"));
        (void) new KPropertiesDialog(&fileitem, view);
    }
}

void iconRightClickDelete(const QString &currentDir, PixieBrowser *view)
{
    QStringList fileList;
    struct stat status;
    view->selectionStringList(fileList);
    if(fileList.isEmpty()){
        qWarning("No items to delete!");
        return;
    }

    if(KMessageBox::warningContinueCancelList(view,
                                              i18n("Do you really want to delete these files?"),
                                              fileList,
                                              i18n("Delete Confirmation"),
                                              i18n("Delete")) ==
       KMessageBox::Cancel)
        return;
    QString fileStr;
    QFileInfo fi;
    bool saveCatagories = false;
    for(QStringList::Iterator it = fileList.begin(); it != fileList.end(); ++it) {
        fileStr = (*it);
        qWarning("Deleting %s", fileStr.latin1());
        fi.setFile(fileStr);
        if(fi.isDir()){
            qWarning("In folder removal");
            // recursive folder delete
            QStringList dirList;
            if(!KIFFileTransfer::recursiveParseDir(fi.absFilePath(),
                                                   dirList, true, false,
                                                   true, false)){
                // TODO Error dialog
                KMessageBox::sorry(view, i18n("Folder removal error."));
                return;
            }
            if(KMessageBox::warningContinueCancelList(view,
                                                      i18n("Do you really want to all these files?"),
                                                      dirList,
                                                      i18n("Folder Delete Confirmation"),
                                                      i18n("Delete")) ==
               KMessageBox::Cancel)
                return;
            for(QStringList::Iterator dit = dirList.begin(); dit != dirList.end(); ++dit){
                qWarning("removing %s", (*dit).latin1());
                fi.setFile(*dit);
                if(fi.isDir()){
                    if(rmdir(QFile::encodeName(*dit)) == -1){
                        qWarning("rmdir error");
                        KMessageBox::sorry(view, i18n("Could not remove folder %1.").arg((*dit).latin1()));
                        return;
                    }
                }
                else{
                    if(unlink(QFile::encodeName(*dit)) == -1){
                        qWarning("unlink error");
                        KMessageBox::sorry(view, i18n("Could not remove file %1.").arg((*dit).latin1()));
                        return;
                    }
                }
            }
        }
        else{
            if(stat(QFile::encodeName(fileStr), &status) == -1){
                KMessageBox::sorry(view, i18n("Could not stat file %1.").arg(fileStr.latin1()));
                return;
            }
            if(unlink(QFile::encodeName(fileStr)) == -1){
                KMessageBox::sorry(view, i18n("Could not remove file %1.").arg(fileStr.latin1()));
                return;
            }
            if(view->catagoryDict()->find((long)status.st_ino)){
                qWarning("Removing obselete catagory data");
                view->catagoryDict()->remove((long)status.st_ino);
                saveCatagories = true;
            }
            if(QFile::exists(currentDir + "/.pics/huge/" + (*it)))
                unlink(QFile::encodeName(currentDir + "/.pics/huge/" + (*it)));
            if(QFile::exists(currentDir + "/.pics/large/" + (*it)))
                unlink(QFile::encodeName(currentDir + "/.pics/large/" + (*it)));
            if(QFile::exists(currentDir + "/.pics/med/" + (*it)))
                unlink(QFile::encodeName(currentDir + "/.pics/med/" + (*it)));
            if(QFile::exists(currentDir + "/.pics/small/" + (*it)))
                unlink(QFile::encodeName(currentDir + "/.pics/small/" + (*it)));
        }
    }
    if(saveCatagories)
        view->saveCatagories();
}


#include "rightclick.moc"
