/* This file is part of the KDE project
   Copyright (C) 2002   Lucijan Busch <lucijan@gmx.at>
   Copyright (C) 2003-2004 Jaroslaw Staniek <js@iidea.pl>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library 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.
*/

#ifndef KEXIRELATIONVIEW_H
#define KEXIRELATIONVIEW_H

#include <qguardedptr.h>
#include <qscrollview.h>
#include <qptrlist.h>
#include <qdict.h>

#include "kexirelationviewconnection.h"

class QFrame;

class KexiRelationViewTable;
class KexiRelationViewTableContainer;
class KAction;
class KPopupMenu;

namespace KexiDB
{
	class TableSchema;
	class Reference;
	class Connection;
}

typedef QDict<KexiRelationViewTableContainer> TablesDict;
typedef QDictIterator<KexiRelationViewTableContainer> TablesDictIterator;
typedef QPtrList<KexiRelationViewConnection> ConnectionList;
typedef QPtrListIterator<KexiRelationViewConnection> ConnectionListIterator;

struct SourceConnection
{
	QString	masterTable;
	QString detailsTable;
	QString masterField;
	QString detailsField;
};

/*! KexiRelationView class provides a view for displaying relations between database tables.
 It is currently used for two purposes:
 - displaying global database relations
 - displaying relations defined for a database query

 The class is for displaying only - retrieving data and updating data on the backend side is implemented 
 in KexiRelationWidget, and more specifically in: Kexi Relation Part and Kexi Query Part.
*/

class KEXIRELATIONSVIEW_EXPORT KexiRelationView : public QScrollView
{
	Q_OBJECT

	public:
		KexiRelationView(QWidget *parent, const char *name=0);
		virtual ~KexiRelationView();

		//! \return a dictionary of added tables
		TablesDict* tables() { return &m_tables; }

		/*! Adds a table \a t to the area. This changes only visual representation.
		 If \a rect is valid, table widget rgeometry will be initialized.
		 */
		KexiRelationViewTableContainer* addTable(KexiDB::TableSchema *t, const QRect &rect = QRect());

		//! Adds a connection \a con to the area. This changes only visual representation.
		void addConnection(const SourceConnection& _conn /*, bool interactive=true*/);

//		RelationList	getConnections()const { return m_connections; };
		void setReadOnly(bool);

		inline KexiRelationViewConnection* selectedConnection() const { return m_selectedConnection; }
		inline KexiRelationViewTableContainer* focusedTableView() const { return m_focusedTableView; }

		virtual QSize sizeHint() const;

		const ConnectionList* connections() const { return &m_connectionViews; }

	signals:
		void tableContextMenuRequest( const QPoint& pos );
		void connectionContextMenuRequest( const QPoint& pos );
		void emptyAreaContextMenuRequest( const QPoint& pos );
		void tableViewGotFocus();
		void connectionViewGotFocus();
		void emptyAreaGotFocus();
		void tableHidden(KexiDB::TableSchema& t);
		void tablePositionChanged(KexiRelationViewTableContainer*);
		void aboutConnectionRemove(KexiRelationViewConnection*);

	public slots:
		//! Clears current selection - table/query or connection
		void clearSelection();

		/*! Removes all tables and coonections from the view. 
		 Does not emit signals like tableHidden(). */
		void clear();

		void		slotTableScrolling(QString);
//		void		removeSelectedConnection();
//		void		removeSelectedTableQuery();

		//! removes selected table or connection
		void removeSelectedObject();

	protected slots:
		void		containerMoved(KexiRelationViewTableContainer *c);
		void		slotListUpdate(QObject *s);
		void		slotTableViewEndDrag();
		void		slotTableViewGotFocus();
//		void		tableHeaderContextMenuRequest(const QPoint& pos);

	protected:

		/*! executes popup menu at \a pos, or, 
		 if \a pos not specified: at center of selected table view (if any selected),
		 or at center point of the relations view. */
//		void executePopup( QPoint pos = QPoint(-1,-1) );

		void		drawContents(QPainter *p, int cx, int cy, int cw, int ch);
		void		contentsMousePressEvent(QMouseEvent *ev);
//		virtual void	keyPressEvent(QKeyEvent *ev);

		void		recalculateSize(int width, int height);
		void		stretchExpandSize();
//		void		invalidateActions();

//		void clearTableSelection();
//		void clearConnSelection();

		void hideTable(KexiRelationViewTableContainer* tableView);
		void removeConnection(KexiRelationViewConnection *conn);

		TablesDict		m_tables;
//		RelationList		m_connections;
		bool			m_readOnly;
//		KexiRelation    	*m_relation;
		ConnectionList		m_connectionViews;
		KexiRelationViewConnection* m_selectedConnection;
		QGuardedPtr<KexiRelationViewTableContainer> m_focusedTableView;
	/*
		KPopupMenu *m_tableQueryPopup //over table/query
			, *m_connectionPopup //over connection
			, *m_areaPopup; //over outer area
		KAction *m_openSelectedTableQueryAction;
*/
};

#endif
