/* This file is part of FSView.
   Copyright (C) 2002, 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>

   KCachegrind 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, version 2.

   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.

   You should have received a copy of the GNU General Public License
   along with this program; see the file COPYING.  If not, write to
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
*/

/*
 * FSView specialisaton of TreeMap classes.
 */

#ifndef FSVIEW_H
#define FSVIEW_H

#include <qmap.h>
#include <qptrlist.h>
#include <qfileinfo.h>
#include <qstring.h>

#include <kmimetype.h>

#include "treemap.h"

/**
 * A specialized version of a TreeMapItem
 * for representation of an Inode.
 *
 * This includes a QFileInfo object and a size including
 * all subdirs.
 */
class Inode: public TreeMapItem
{
public:
  Inode(QString);
  Inode(QFileInfo&);
  double value() const;

  double size() const;     // returns a size estimation
  double realSize() const; // returns 0.0 if size not known
  unsigned int files() const;
  void update();
  void setPath(QString);
  QString path() const;
  QString text(int i) const;
  QPixmap pixmap(int i) const;
  QColor backColor() const;
  KMimeType::Ptr mimeType() const;
  const QFileInfo& fileInfo() const { return _info; }

private:
  void init(QFileInfo&);
  void finishUpdate();
  void setMetrics(double, unsigned int);
  void gotChildSize(double, unsigned int);

  QFileInfo _info;
  double _size, _sizeEstimation;
  unsigned int _files, _filesEstimation;
  int _subDirsUnknown;

  // Cached values, calculated lazy.
  // This means a change even in const methods, thus has to be "mutable"
  mutable bool _mimeSet, _mimePixmapSet;
  mutable KMimeType::Ptr _mimeType;
  mutable QPixmap _mimePixmap;
};

/**
 * The root object for the treemap.
 *
 * Does context menu handling and
 * asynchronous file size update
 */
class FSView : public TreeMapWidget
{
  Q_OBJECT

public:
  enum ColorMode { None = 0, Depth, Name, Owner, Group, Mime };

  FSView(Inode*, QWidget* parent=0, const char* name=0);

  void setPath(QString);
  QString path() { return _path; }
  int pathDepth() { return _pathDepth; }
  
  void setColorMode(FSView::ColorMode cm);
  FSView::ColorMode colorMode() const { return _colorMode; }
  // returns true if string was recognized
  bool setColorMode(QString);
  QString colorModeString() const;

  void requestUpdate(Inode*);
  /* called when a inode update is done */
  void finished(Inode*);

  void stop();

  static bool getDirMetric(QString, double&, unsigned int&);
  static void setDirMetric(QString, double, unsigned int);
  void saveMetric(KConfigGroup*);
  void saveFSOptions();

  // for color mode
  void addColorItems(QPopupMenu*, int);

  KURL::List selectedUrls();

public slots:
  void selected(TreeMapItem*);
  void contextMenu(TreeMapItem*, const QPoint &);
  void quit();
  void doUpdate();
  void doRedraw();
  void colorActivated(int);

 signals:
  void started();
  void progress(int percent, int dirs, QString lastDir);
  void completed(int dirs);

private:

  // list of Inode objects (directories) with still unknown content
  QPtrList<Inode> _needsUpdate;
  // when a contextMenu is shown, we don't allow async. refreshs
  bool _allowRefresh;
  // a cache for directory sizes with long lasting updates
  static QMap<QString, QPair<double, unsigned int> > _dirMetric;

  // current root path
  int _pathDepth;
  QString _path;

  // for progress info
  int _progress, _progressSize, _dirsFinished;
  Inode* _lastDir;

  ColorMode _colorMode;
  int _colorID;
};

#endif // FSVIEW_H

