/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/


#ifndef DBAUI_QUERYTABLEVIEW_HXX
#define DBAUI_QUERYTABLEVIEW_HXX

#ifndef DBAUI_JOINTABLEVIEW_HXX
#include "JoinTableView.hxx"
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef DBAUI_QUERYCONTROLLER_HXX
#include "querycontroller.hxx"
#endif

namespace dbaui
{

	struct TabWinsChangeNotification
	{
		enum ACTION_TYPE	{ AT_ADDED_WIN, AT_REMOVED_WIN };
		ACTION_TYPE			atActionPerformed;
		String				strAffectedTable;

		TabWinsChangeNotification(ACTION_TYPE at, const String& str) : atActionPerformed(at), strAffectedTable(str) { }
	};

	//========================================================================
	class OQueryTabWinUndoAct;
	class OQueryTabConnUndoAction;
	class OQueryTableConnection;
	class OQueryTableWindow;
	class OQueryDesignView;
	class OQueryTableView : public OJoinTableView
	{
		Link	m_lnkTabWinsChangeHandler;

	protected:
		virtual void ConnDoubleClicked(OTableConnection* pConnection);
		virtual void KeyInput(const KeyEvent& rEvt);

		virtual OTableWindow* createWindow(const TTableWindowData::value_type& _pData);

        /** called when init fails at the tablewindowdata because the m_xTable object could not provide columns, but no
            exception was thrown. Expected to throw.
        */
        virtual void    onNoColumns_throw();

        virtual bool supressCrossNaturalJoin(const TTableConnectionData::value_type& _pData) const;
	public:
		OQueryTableView(Window* pParent,OQueryDesignView* pView);
		virtual ~OQueryTableView();

		// Basisklasse ueberschrieben : Fenster kreieren und loeschen
		// (eigentlich nicht wirklich LOESCHEN, es geht in die Verantwortung einer UNDO-Action ueber)
        bool ContainsTabWin(const OTableWindow& rTabWin); // #122589# Allow to check if OTableWindow is registered
		virtual void AddTabWin( const ::rtl::OUString& _rTableName, const ::rtl::OUString& _rAliasName, sal_Bool bNewTable = sal_False );
		virtual void RemoveTabWin(OTableWindow* pTabWin);

		// und ein AddTabWin, das einen Alias vorgibt
		void	AddTabWin(const ::rtl::OUString& strDatabase, const ::rtl::OUString& strTableName, const ::rtl::OUString& strAlias, sal_Bool bNewTable = sal_False);
		// TabWin suchen
		OQueryTableWindow*	FindTable(const String& rAliasName);
		sal_Bool			FindTableFromField(const String& rFieldName, OTableFieldDescRef& rInfo, sal_uInt16& rCnt);

		// Basisklasse ueberschrieben : Connections kreieren und loeschen
		virtual void AddConnection(const OJoinExchangeData& jxdSource, const OJoinExchangeData& jxdDest);

		virtual bool RemoveConnection( OTableConnection* _pConn ,sal_Bool _bDelete);

		// Transfer von Connections von/zu einer UndoAction
		void GetConnection(OQueryTableConnection* pConn);
			// Einfuegen einer Connection in meine Struktur
		void DropConnection(OQueryTableConnection* pConn);
			// Entfernen einer Connection aus meiner Struktur

			// das resultiert effektiv in einem voelligen Leeren des Abfrageentwurfs, da alle Fenster versteckt werden, und dabei
			// natuerlich alle Connections an diesen Fenstern und alle Abfrage-Spalten, die auf diesen Tabellen basierten.

		// TabWin anzeigen oder verstecken (NICHT kreieren oder loeschen)
		sal_Bool	ShowTabWin(OQueryTableWindow* pTabWin, OQueryTabWinUndoAct* pUndoAction,sal_Bool _bAppend);
		void	HideTabWin(OQueryTableWindow* pTabWin, OQueryTabWinUndoAct* pUndoAction);

		// Sichbarkeit eines TabWins sicherstellen (+ Invalidieren der Connections)
		virtual void EnsureVisible(const OTableWindow* _pWin);

		// wieviel Tabellen mit einem bestimmten Namen habe ich schon ?
		sal_Int32	CountTableAlias(const String& rName, sal_Int32& rMax);

		// ein Feld einfuegen (wird einfach an das Elter weitergereicht
		void InsertField(const OTableFieldDescRef& rInfo);

		// alles (TabWins, Connections) neu aufbauen (PRECONDITION : vorher wurde ClearAll gerufen)
		virtual void ReSync();
		// alles (TabWins, Connections) loeschen, und zwar hart, es erfolgen also keinerlei Notifications
		virtual void ClearAll();

		// wird vom AddTabDlg benutzt, um festzustellen, ob noch Tabellen hinzugefuegt werden duerfen
		//virtual sal_Bool IsAddAllowed();

		// eine neu Connection bekanntgeben und einfuegen lassen, wenn nicht schon existent
		void NotifyTabConnection(const OQueryTableConnection& rNewConn, sal_Bool _bCreateUndoAction = sal_True);

		Link	SetTabWinsChangeHandler(const Link& lnk) { Link lnkRet = m_lnkTabWinsChangeHandler; m_lnkTabWinsChangeHandler = lnk; return lnkRet; }
			// der Handler bekommt einen Zeiger auf eine TabWinsChangeNotification-Struktur

		sal_Bool ExistsAVisitedConn(const OQueryTableWindow* pFrom) const;

		virtual OTableWindowData* CreateImpl(const ::rtl::OUString& _rComposedName
                                            ,const ::rtl::OUString& _sTableName
											,const ::rtl::OUString& _rWinName);

		/** createNewConnection opens the join dialog and allows to create a new join connection
		*/
		void createNewConnection();

    private:
        using OJoinTableView::EnsureVisible;
	};
}
#endif // DBAUI_QUERYTABLEVIEW_HXX
