#ifndef __PIXIE_BROWSER_H
#define __PIXIE_BROWSER_H

#include <qscrollbar.h>
#include <qfontmetrics.h>
#include <qtooltip.h>
#include <qintdict.h>
#include <qtimer.h>
#include <qdict.h>
#include <qstringlist.h>
#include <kdirwatch.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <utime.h>
#include <unistd.h>
#include "imageutils.h"
#include "browser_sort.h"
#include "catagorymgr.h"

#include <kio/previewjob.h>
class KFileItem;
class UIManager;

typedef struct __thumbnail_type
{
    char *filename;
    char *formattedText;
    char *tooltip;
    char *thumbnailData;
    char *mimetype;
    QPixmap *pixmap;
    struct stat *status;
    bool thumbnailed;
    bool isDir;
    bool textDirty;
    bool selected;
    bool isImage;
    bool extensionChecked;
    bool mimetypeChecked;
    bool imageHasThumb;
} Thumbnail;


typedef struct __pixie_rect_type
{
    int x, y, w, h;
} PixieRect;


class BrowserTip : public QToolTip
{
public:
    BrowserTip(QWidget *parent, QToolTipGroup *group) : QToolTip(parent, group){;}
    void maybeTip(const QPoint &p);
};

class PixieBrowser : public QWidget
{
    Q_OBJECT
friend class BrowserTip;
public:
    PixieBrowser(UIManager *manager, QWidget *parent=0, const char *name=0);
    ~PixieBrowser();
    void clear();
    void selectAll();
    void clearSelection(bool redraw=false);
    QValueList<int>* selection();
    bool selectionStringList(QStringList &list);
    void sortSelectionByView();
    bool selectionHasImages();
    bool selectionHasFolders();
    int count();
    QString absPath(){return(absFileStr);}
    QString currentDirStr(){return(currentDir);}
    bool nameFiltered(){return(hasNameFilter);}
    int currentSortType(){return(currentSort);}
    int thumbnailSize(){return(iSize);}
    QIntDict<CatInfo>* catagoryDict(){return(&catDict);}

    int itemAt(int x, int y);
    QRect itemRect(int idx);
    Thumbnail* currentItem();
    bool setCurrentItem(int idx);
    Thumbnail* allItems();
    int currentIndex();
    bool isItemVisible(int i);
    bool paintThumbnail(int i, QPainter *p=0);
    int findItem(const char *filename);

    int oldest(){return(oldestFile);}
    int newest(){return(newestFile);}

    void copy();
    void paste();

    void convertToKonqThumbs();
    void convertToPixieThumbs();

    bool loadCatagories();
    bool saveCatagories();
    void addCatagory(Thumbnail *i, int id);
    void removeCatagory(Thumbnail *i, int id);
    QStringList itemCatagories(Thumbnail *i);

    void stop();
    KDirWatch* watch(){return(dirWatch);}

    void loadPath(const QString &path, int iconSize, int sortType,
                  int showOnlyCatagory, bool catagoriesFirst, bool iconOnly,
                  bool imagesFirst, const QString &nameFilter);
    bool eventFilter(QObject *obj, QEvent *ev);

    // embedded data header can be included only once
    static QImage uicImage(const QString &name);

    // mimetype stuff
    bool isImage(Thumbnail *i, const QString &absPath=QString::null,
                 bool useExtensionOnly=true);
    bool isVideo(Thumbnail *i, const QString &absPath=QString::null,
                 bool useExtensionOnly=true);
    void processThumbnailMimeType(Thumbnail *i, const QString &path,
                              int iconSize = -1);

    // used for sorting
    bool placeCatagoriesOnTop(){return(sortCatagories);}
    bool placeImagesOnTop(){return(imagesOnTop);}
    struct dirinfo **currentListArray(){return(listarray);}
    int listArrayCount(){return(arrayCount);}
public slots:
    void slotGenerateThumbnails();
protected slots:
    void slotScrollBarChanged(int value);
    void slotDirChanged(const QString &);
    void slotScrollOutsideView();

    void slotThumbJobResult(KIO::Job *job);
    void slotThumbJobProgress(KIO::Job *job, unsigned long percent);
    void slotThumbJobPreview(const KFileItem *item, const QPixmap &preview);
    void slotThumbJobFailed(const KFileItem *item);
signals:
    void clicked(Thumbnail *i);
    void doubleClicked(Thumbnail *i);
    void rightButtonClicked(Thumbnail *i, const QPoint &pos);
    void returnPressed(Thumbnail *i);

    void enableStopButton(bool);
    void enableFolderChanges(bool);
    void updateProgress(int);
    void setStatusBarText(const QString &);
    void updateMe();
    void dirChanged(const QString &path);

    void enableUpDir(bool);
    void enableBackDir(bool);
    void enableForwardDir(bool);
protected:
    bool allocateArray(int c);
    bool updateThumbnail(int index);
    void paintItem(QPainter *p, int index, int x, int y);
    void resetFrames();

    void viewportPaintEvent(QPaintEvent *ev);
    void viewportResizeEvent(QResizeEvent *ev);
    void viewportMousePressEvent(QMouseEvent *ev);
    void viewportMouseReleaseEvent(QMouseEvent *ev);
    void viewportMouseDoubleClickEvent(QMouseEvent *ev);
    void viewportMouseMoveEvent(QMouseEvent *ev);
    void viewportDropEvent(QDropEvent *ev);
    void viewportDragMoveEvent(QDragMoveEvent *ev);
    void viewportKeyEvent(QKeyEvent *ev);
    void viewportWheelEvent(QWheelEvent *ev);

    void recalcColumns(int w, int h);
    void recalcRects();
    bool viewToIconRect(const QRect &viewRect, QRect &destRect);

    QString calcKonqThumbPath(const QString &path, int iconSize);
    void calcTextWrapping(Thumbnail *i);
    void calcTooltip(Thumbnail *i);
    void clearTips();

    Thumbnail *itemList;
    int itemCount;
    QWidget *view;
    QScrollBar *sb;
    QBrush selectBrush;
    KDirWatch *dirWatch;

    // size stuff
    QFontMetrics *fm;
    int viewportHeight;
    int iSize, textHeight;
    int totalItemWidth, totalItemHeight;
    int columns;

    // thumbnails and paths
    QString currentDir, absFileStr;
    bool hasNameFilter;
    QString pixieThumbPath, konqThumbPath;
    bool hasKonqThumbnails;
    int currentSort;

    // selections
    int curIdx;
    QValueList<int> selectList;
    QPoint selectStartPos, currentSelPos;
    bool inSelection, selectStarted, dndStarted, dndSent;
    QTimer scrollOutsideViewTimer;

    // directory loading
    bool stopProcessing, inGenerateThumbs;
    bool inDirLoad, invalidDir;
    KIO::Job *thumbJob;
    int kioCurrentThumb, kioThumbCount;
    int curPreviewingIdx;

    bool imagesOnTop, sortCatagories;
    struct dirinfo **listarray;
    int arrayCount;

    // used in rect calculation
    int firstVisibleIdx;
    int visibleRectCount;
    PixieRect *visibleRects;

    // icons and frames
    QImage curFrameImage, curGraphicsImage;
    QPixmap *tmpIconPix, *curFramePix, *curTextPix, *curSelTextPix,
        *curGraphicsPix, *curPreviewingPix;
    QDict<QPixmap>iconDict;

    // catagories
    QIntDict<CatInfo>catDict;
    bool catError;
    bool supportCatagories;

    UIManager *mgr;
    BrowserTip *tips;

    time_t oldestFile, newestFile;
    bool hasInitialLoad;
};


#endif


