/*
** Copyright (C) 2000 Peter Putzer <putzer@kde.org>
**
*/

/*
** 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 of the License, 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.
**
** You should have received a copy of the GNU General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
** MA 02110-1301, USA.
*/

/*
** Bug reports and questions can be sent to kde-devel@kde.org
*/
/***************************************************************************
 *                                                                         *
 *   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; version 2.                              *
 *                                                                         *
 ***************************************************************************/

#ifndef KSVDRAGLIST_H
#define KSVDRAGLIST_H

#include <tqstring.h>
#include <tqcolor.h>
#include <tqpixmap.h>

#include <tdelistview.h>

#include "Data.h"

class TQPen;
class KSVAction;
class SimpleAction;
class KSVDragList;
class TDEPopupMenu;
class KSVConfig;
class KDLToolTip;

class KSVItem : public TQListViewItem
{
public:
  typedef enum {
	SortNumber = 0,
	Icon,
	ServiceName,
	FileName,

	// insert additional columns here

	Last
  } Columns;

  KSVItem (TDEListView*);
  KSVItem (const KSVItem&);
  explicit KSVItem (KSVDragList*, const KSVData&);
  KSVItem (TDEListView* view, TQString file, TQString path, TQString label, TQ_INT8 nr );
  virtual ~KSVItem ();

  virtual TQString key (int col, bool ascending) const;

  inline bool isChanged() const { return mData->changed(); }
  
  inline bool isNumChanged() const { return mData->numberChanged(); }
  inline bool isLabelChanged() const { return mData->labelChanged(); }
  inline bool isNew() const { return mData->newEntry(); }

  inline const TQString& oldFilename() const { return mData->oldFilename(); }
  inline const TQString& filename() const { return mData->filename(); }
  inline const TQString& oldLabel() const { return mData->oldLabel(); }
  inline const TQString& label() const { return mData->label(); }
  inline const TQString& runlevel() const { return mData->runlevel(); }
  
  inline TQString filenameAndPath() const { return mData->filenameAndPath (); }

  inline const TQString& path() const { return mData->path(); }

  inline TQ_INT8 number() const { return mData->number(); }
  inline TQ_INT8 oldNumber() const { return mData->oldNumber(); }

  void copy (const KSVData&);

  KSVData* data () { return mData; }
  const KSVData* data () const { return mData; }

  TQString toString () const;

  inline bool operator== (const KSVItem & rhs) const { return mData == rhs.mData; }

  inline const TQColor& newNormalColor () const
  {
    return mNewNormalColor;
  }

  inline const TQColor& changedNormalColor () const
  {
    return mChangedNormalColor;
  }

  inline TQString originalRunlevel() const { return mData->originalRunlevel(); }  
  
  void setIcon (const TQPixmap& icon);
  void setLabel (const TQString& label);
  void setFilename (const TQString& file);
  void setRunlevel (const TQString& runlevel);
  void setNumber (TQ_INT8 nr);
  void setPath (const TQString& path);
  void setChanged (bool);
  void setNewNormalColor (const TQColor&);
  void setChangedNormalColor (const TQColor&);
  void setNewSelectedColor (const TQColor&);
  void setChangedSelectedColor (const TQColor&);
  void setNew (bool);
  void setOriginalRunlevel (const TQString&);

  inline void setNumberChanged (bool val) { mData->setNumberChanged (val); }

  TQString tooltip () const;
  virtual void paintCell (TQPainter* p, const TQColorGroup& cg, int column, int width, int align);

protected:
  friend class KSVDragList;
  friend class KServiceDragList;

  TQPixmap paintDragIcon (const TQFont& f, const TQColorGroup& g) const;

private:
  friend class KSVDrag;

  KSVData* mData;
  KSVConfig* mConfig;

  TQColor mNewNormalColor;
  TQColor mNewSelectedColor;
  TQColor mChangedNormalColor;
  TQColor mChangedSelectedColor;
};

class KSVDragList : public TDEListView
{
  Q_OBJECT
  

public:
  KSVDragList ( TQWidget* parent = 0, const char* name = 0 );
  virtual ~KSVDragList();

  virtual void clear();

  inline bool displayToolTips () const { return mDisplayToolTips; }
  inline bool commonToolTips () const { return mCommonToolTips; }

  inline const TQString& tooltip () const { return mToolTip; }
  inline const TQString& horizontalScrollBarTip () const { return mHorizontalTip; }
  inline const TQString& verticalScrollBarTip () const { return mVerticalTip; }

  virtual void initItem (TQString file, TQString path, TQString name, TQ_INT8 nr);
  TQPtrList<KSVData>& getDeletedItems() { return mRMList; }
  
  /**
   * @return whether this is the currently "selected" KSVDragList.
   */
  inline bool isOrigin() const { return mOrigin; }

  inline KSVItem* currentItem() { return static_cast<KSVItem*> (TDEListView::currentItem()); }

  inline KSVItem* lastItem () { return static_cast<KSVItem*> (TDEListView::lastItem()); }

  /**
   * @return true if the insertion was successful.
   */
  bool insert (const KSVData& data, const KSVData* above = 0L, const KSVData* below = 0L);

  bool insert (const KSVData& data, const KSVItem* where, KSVAction*& action);

  inline const TQPixmap& defaultIcon() const { return mIcon; }

  bool removeFromRMList (const KSVData&);
  bool addToRMList (const KSVData&);
  void clearRMList();

  KSVItem* match (const KSVData&);

  inline void setDisplayToolTips (bool val) { mDisplayToolTips = val; }
  inline void setCommonToolTips (bool val) { mCommonToolTips = val; }
  inline void setHorizontalScrollBarTip (const TQString& t) { mHorizontalTip = t; }
  inline void setVerticalScrollBarTip (const TQString& t) { mVerticalTip = t; }
  inline void setToolTip (const TQString& t) { mToolTip = t; }

public slots:
  void setNewNormalColor (const TQColor &);
  void setChangedNormalColor (const TQColor &);
  void setNewSelectedColor (const TQColor &);
  void setChangedSelectedColor (const TQColor &);

  void setOrigin (bool);
  inline void slotNewOrigin() { setOrigin (false); }

  void setDefaultIcon (const TQPixmap& icon);

  void drop (TQDropEvent*, TQListViewItem*);

  virtual void setEnabled (bool);

protected:
  virtual void focusInEvent (TQFocusEvent*);
  virtual bool acceptDrag (TQDropEvent*) const;
  virtual TQDragObject* dragObject ();
//  virtual KSVDrag* dragObject ();

  virtual void startDrag ();

  /**
   * Generates a sorting number for an item at
   * the given index by taking the average of the item
   * above and the item below.
   */
  TQ_INT8 generateNumber (TQ_INT8 high, TQ_INT8 low) const;

  /**
   * A convenience function that also takes the label into account
   */
  TQ_INT8 generateNumber (const TQString& label, const KSVData* itemAbove, const KSVData* itemBelow) const;
  
  KSVItem* mItemToDrag;

private:
  TQPixmap mIcon;
  
  bool mOrigin;
  TQPtrList<KSVData> mRMList;

  TQColor mNewNormalColor;
  TQColor mNewSelectedColor;
  TQColor mChangedNormalColor;
  TQColor mChangedSelectedColor;

  TDEPopupMenu* mDragMenu;
  TDEPopupMenu* mDragCopyMenu;
  TDEPopupMenu* mDragMoveMenu;
  KDLToolTip* toolTip;
  typedef enum { Copy, Move } DragAction;

  TQString mToolTip, mHorizontalTip, mVerticalTip;
  bool mDisplayToolTips, mCommonToolTips;

signals:
  void newOrigin();
  void newOrigin (KSVDragList*);

  void cannotGenerateNumber();
  void undoAction(KSVAction*);
};

class KServiceDragList : public KSVDragList
{
public:
  KServiceDragList (TQWidget* parent = 0L, const char* name = 0L);
  virtual ~KServiceDragList ();

protected:
  virtual void startDrag ();
};

#endif
