/***************************************************************************
                          structtreeview.h  -  description
                             -------------------
    begin                : Sat Apr 29 2000
    copyright            : (C) 2000 by Yacovlev Alexander & Dmitry Poplavsky <pdima@mail.univ.kiev.ua>
                           (C) 2002, 2003 Andras Mantia <amantia@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.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef STRUCTTREEVIEW_H
#define STRUCTTREEVIEW_H

#include <tqmap.h>
#include <tqvaluelist.h>

#include <tdelistview.h>

/**view class of document structure
 *@author Andras Mantia & Paulo Moura Guedes & Yacovlev Alexander & Dmitry Poplavsky
 */

class TDEPopupMenu;
class TDEConfig;
class KURL;
class TQTime;

class Node;
class StructTreeTag;
class Parser;
class Document;
struct DTDStruct;

class StructTreeView : public TDEListView  {
   TQ_OBJECT
  
public:

  /**
   *  since this class is a singleton you must use this function to access it
   *
   *  the parameters are only used at the first call to create the class
   *
   */
  static StructTreeView* const ref(TQWidget *parent = 0L, const char *name = 0L)
  {
    static StructTreeView *m_ref;
    if (!m_ref) m_ref = new StructTreeView (parent, name);
    return m_ref;
  }

  ~StructTreeView();


  void setFollowCursor(bool);
  bool followCursor() { return followCursorFlag; }
  /** Show the element in tree according to cursor position (x,y) */
  void showTagAtPos(Node *node);
  /** Delete the items */
  void deleteList(bool groupOnly);
  void setParsingDTDs(const TQStringList &parsingDTDList);
  void showMessage(const TQString& message);
  
  
  bool useOpenLevelSetting;

public slots: // Public slots
  /** repaint document structure */
  void slotReparse(Document *w, Node* node, int openLevel = 3,bool groupOnly=false);
  void slotMouseClicked(int button, TQListViewItem*, const TQPoint&, int);
  void slotDoubleClicked( TQListViewItem * );

  // slots for RBM menu
  void slotReparseMenuItem();
  void slotSelectTag();
  void slotGotoTag( TQListViewItem *item );
  void slotGotoClosingTag();
  /** Recursively open the tree and all its subtrees */
  void slotOpenSubTree();
  /** Recursively close the tree and all its subtrees */
  void slotCloseSubTree();
  void changeFollowCursor() { setFollowCursor(!followCursorFlag); }
  /** No descriptions */
  void slotCollapsed(TQListViewItem *item);
  /** No descriptions */
  void slotExpanded(TQListViewItem *);
  void slotOpenFile();
  void slotNodeTreeChanged();
  void slotRemoveTags();

signals:
  void newCursorPosition( int col, int row );
  void selectTagArea(Node* node);
  void selectArea(int col1, int row1, int col2, int row2 );
  void needReparse();
  void onTag( const TQString &tag );
  void showGroupsForDTEP(const TQString& dtep, bool show);
  void openFile(const KURL&);
  void openImage(const KURL&);
  void showProblemMessage(const TQString&);
  void clearProblemOutput();

private:

  /** The constructor is private because we use singleton pattern.
   *  If you need the class use StructTreeView::ref() for
   *  construction and reference
   */
  StructTreeView(TQWidget *parent=0, const char *name=0);
  /** builds the structure tree */
  void buildTree(Node *baseNode, int openLevel, bool groupOnly);
  /** Do the recursive opening or closing of the trees */
  void setOpenSubTree(TQListViewItem *it, bool open);

  /** Make ctrl have the same behavior has shift */
  void setContiguousSelectedItems();
  
  void copySelectedItems(TQListViewItem* parent, TQListViewItem* after);
  void moveSelectedItems(TQListViewItem* parent, TQListViewItem* after);
  
private:

  int followCursorId;
  bool followCursorFlag;

  TDEPopupMenu *popupMenu;
  TDEPopupMenu *emptyAreaMenu;
  TDEPopupMenu *dtdMenu;
  StructTreeTag *lastTag;
  TDEConfig *config;
  TQStringList dtdList;
  TQValueList<const DTDStruct*> m_parsingDTDList;
  int openFileMenuId;
  TQMap<TQString, uint> groupIds;
  bool m_dirty;
  StructTreeTag *top;
  TQValueList<StructTreeTag*> groups;
  uint groupsCount;

  bool topOpened;
  TQValueList<bool> groupOpened;
  
  mutable TQListViewItem* m_marker;       //track that has the drag/drop marker under it
  TQListViewItem* m_draggedItem;
//   mutable TQWidget* m_thisWidget; // non const this hack for acceptDrag

protected: // Protected methods
  /** Do a reparse before showing. */
  virtual void showEvent(TQShowEvent*);
  /** Clear the problem output when hiding. */
  virtual void hideEvent(TQHideEvent*);
  
  // drag functions  
  virtual bool acceptDrag(TQDropEvent* e) const;
  virtual void startDrag();
  virtual void contentsMousePressEvent(TQMouseEvent* e);

protected slots: // Protected slots
  /** The treeview DTD  has changed to id. */
  void slotDTDChanged(int id);
    
  void slotMouseClickedVPL(int button, TQListViewItem*, const TQPoint&, int);
  virtual void slotDropped(TQDropEvent* e, TQListViewItem* parent, TQListViewItem* after);

protected: // Protected attributes
  Document *write;
  TQTime *timer;
};

#endif
