/////////////////////////////////////////////////////////////////////////////
// Name:        wxDbListCtrl
// Purpose:     
// Author:      Aleksandras Gluchovas
// Modified by:
// Created:     2000/07/27
// RCS-ID:      $Id: dblist.h,v 1.1 2001/02/25 11:56:04 aleksandras Exp $
// Copyright:   (c) 2000 PM-Soft
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

#ifndef __DBLIST_G__
#define __DBLIST_G__

#include "wx/wspp/glist.h"
#include "wx/thread.h"

// choose ODBC-cursor implementation:

//#define USE_WX_ODBC   1
//#define USE_ODBC_PLUS 1
#define USE_MY_ODBC 1


class DataCursorBase : public wxObject
{
public:
  virtual bool ExecuteQuery( const wxString& query ) = 0;
  virtual bool CloseQuery() = 0;

  virtual bool FetchFirst() = 0;

  virtual bool FetchNext() = 0;
  virtual bool FetchPrevious() = 0;

  virtual void SetSortOrder( wxStringList& cols, wxArrayInt& accendingFlags ) = 0;
  virtual void GetColumnNames( wxStringList& names ) = 0;

  virtual wxString GetValue( int colIndex ) = 0;

  virtual bool IsEof() = 0;
  virtual void ClearEof() = 0;

  // FOR NOW:: ODBC-specific method in the interface of abstract-cursor

  virtual void ODBCSetup( const wxString& dsn,
              const wxString& user,
              const wxString& passwd );

  virtual void SetSortOrder( const wxString& col, bool accendingFlag );

  // optional overridables

  virtual bool SetCurrentRowPos( int pos );
  virtual int  GetCurrentRowPos();

  virtual void InsertCacheRowAt( int row, wxStringList& values  );
  virtual void RemoveCacheRow( int row );
  virtual void UpdateCacheRow( int row, wxStringList& values );
  virtual int FindInsertionPos( int col, const wxString& insValue , bool isAscending );

protected:
  wxString mDsn;
  wxString mUser;
  wxString mPasswd;
};

#if USE_WX_ODBC

class BrowserDB;
class wxDbTableInf;

class ODBCDataCursor : public DataCursorBase
{
public:
  ODBCDataCursor();
  ~ODBCDataCursor();

  // overriden methods of DataCursorBase

  virtual bool ExecuteQuery( const wxString& query );
  virtual bool CloseQuery();

  virtual bool FetchFirst();

  virtual bool FetchNext();
  virtual bool FetchPrevious();

  virtual void SetSortOrder( wxStringList& colNames, wxArrayInt& accendingFlags );
  virtual void GetColumnNames( wxStringList& names );

  virtual wxString GetValue( int colIndex );

  virtual bool IsEof();
  virtual void ClearEof();

protected:

  // wxODBC-specific objects

  static BrowserDB* mpBrowser;
  wxDbTableInf* mpTableInfo;
  bool   mVerbose;
  bool   mIsEof;

  wxString mOrderSuffix;
};

#endif // USE_WX_ODBC


#if USE_ODBC_PLUS

namespace odbc {
  class Connection;
  class ResultSet;
  class Statement;
};

class ODBCPlusCursor: public DataCursorBase
{
public:
  ODBCPlusCursor();
  ~ODBCPlusCursor();

  // overriden methods of DataCursorBase

  virtual bool ExecuteQuery( const wxString& query );
  virtual bool CloseQuery();

  virtual bool FetchFirst();

  virtual bool FetchNext();
  virtual bool FetchPrevious();

  virtual void SetSortOrder( wxStringList& cols, wxArrayInt& accendingFlags );
  virtual void GetColumnNames( wxStringList& names );

  virtual wxString GetValue( int colIndex );

  virtual bool IsEof();
  virtual void ClearEof();

protected:
  // odbc++ specific objects

  odbc::Connection* mpCon;
  odbc::ResultSet*  mpRSet;
  odbc::Statement*  mpStmt;

  wxString mOrderSuffix;
};

#endif // USE_ODBC_PLUS

#if USE_MY_ODBC

class MyConnection;
class MyResultSet;
class MyStatement;

class MyODBCCursor: public DataCursorBase
{
public:
  MyODBCCursor();
  ~MyODBCCursor();

  // overriden methods of DataCursorBase

  virtual bool ExecuteQuery( const wxString& query );
  virtual bool CloseQuery();

  virtual bool FetchFirst();

  virtual bool FetchNext();
  virtual bool FetchPrevious();

  virtual void SetSortOrder( wxStringList& cols, wxArrayInt& accendingFlags );
  virtual void GetColumnNames( wxStringList& names );

  virtual wxString GetValue( int colIndex );

  virtual bool IsEof();
  virtual void ClearEof();

  virtual bool SetCurrentRowPos( int pos );
  virtual int  GetCurrentRowPos();

  virtual void InsertCacheRowAt( int row, wxStringList& values  );
  virtual void RemoveCacheRow( int row );
  virtual void UpdateCacheRow( int row, wxStringList& values );
  virtual int FindInsertionPos( int col, const wxString& insValue, bool isAscending );

  // other methods
  virtual int GetCacheUsed();
  virtual MyConnection* GetConnection();

protected:
  // odbc++ specific objects

  MyConnection* mpCon;
  MyResultSet*  mpRSet;
  MyStatement*  mpStmt;

  wxString mOrderSuffix;
};

#endif // USE_MY_ODBC

class SampleDataCursor : public DataCursorBase
{
public:
  virtual bool ExecuteQuery( const wxString& query );
  virtual bool CloseQuery();

  virtual bool FetchFirst();

  virtual bool FetchNext();
  virtual bool FetchPrevious();

  virtual void SetSortOrder( wxStringList& colNames, wxArrayInt& accendingFlags );
  virtual void GetColumnNames( wxStringList& names );

  virtual wxString GetValue( int colIndex );

  virtual bool IsEof();
  virtual void ClearEof();

  void SetRowCount( int count ) { mCount = count; }
public:
  wxString mStr;
  int      mRow;
  int    mCount;
};

class wxDbListCtrl : public wxGenericListCtrl,
           public wxListModel
{
public:

  wxDbListCtrl();

  wxDbListCtrl( wxWindow *parent, wxWindowID id = -1,
			    const wxPoint& pos = wxDefaultPosition, 
				const wxSize& size = wxDefaultSize,
				long style = 0, const wxString& name = "gListCtrl" );

  ~wxDbListCtrl();

  // overriden methods of wxListModel

  virtual const wxString GetValue( int row, int col );
  virtual int GetRowCount();
  virtual int GetFinalRowCount();
  virtual void Sort( size_t byColumn, bool acending );
  virtual void Sort( const wxString& byColumn, bool acending );

  // overriden method of wxGenericListCtrl

  virtual void DrawPageContent( wxDC& dc );

  virtual void SetDataCursor( DataCursorBase* pCursor );
  virtual DataCursorBase* GetDataCursor();

  virtual void SetODBCDataSource( const wxString& dsn,
                  const wxString& user,
                  const wxString& passwd );

  virtual bool RunQuery( const wxString& query );
  virtual wxStringList& GetQueryColumnNames();

  virtual void ClearCache();
  virtual void HandleFetchRuest();

  enum ENUM_ROW_CHANGE_TYPE
  {
    MODIFIED, INSERTED, REMOVED
  };

  // notifications send to notify about external changes to the 
  // currently browsed data-set

  virtual void OnRowChanged( ENUM_ROW_CHANGE_TYPE changeType, 
                 const wxString& PKValue, int PKColIndex,
                 wxStringList& newValues,
                 bool refreshNow = FALSE );

  virtual bool FindRow( const wxString& pattern, wxStringList& inColumns,
              bool startOver, bool exactMatch, 
              bool ignoreCase, bool matchBegining,
              bool forward = TRUE );

  void FetchMoreRows( int count );

  void OnActivate( wxActivateEvent& event );

  DECLARE_EVENT_TABLE()
  DECLARE_DYNAMIC_CLASS( wxDbListCtrl )

protected:
  virtual void CacheCursorRow();
  virtual bool IsCached( int row );
  virtual bool DoFetchNext( bool forward );

protected:
  // Variablen declared in order as used in constuctor, avoiding warnings in gcc
  bool                    mUseInternalCache; // default: TRUE
  DataCursorBase         *mpCursor;
  int                     mMaxCacheSize;
  int                     mMaxPrefetchRows;
  int                     mFirstCached;
  //--

  wxArrayPtrVoid          mCachedData;
  wxString                mCurQueryString;
  wxStringList            mQueryColumnNames;
  bool					  mQueryFailed;
      
  int                     mCursorPos;
  int                     mMaxScrolled;
  int                     mMaxRows;

  int                     mReqFromRow;       // parameters attributed to fetch-request
  int                     mReqRowCcount;     // parameters attributed to fetch-request

  // values passed to sort before RunQuery()
  wxString                mSortReqColName; 
  bool                    mSortReqFlag;
};

#endif __DBLIST_G__
