/////////////////////////////////////////////////////////////////////////////
// Name:        No names yet.
// Purpose:     Contrib. demo
// Author:      Aleksandras Gluchovas
// Modified by:
// Created:     2000/02/08
// RCS-ID:      $Id: codecompl_svc.h,v 1.2 2001/04/22 19:58:14 aleksandras Exp $
// Copyright:   (c) Aleksandras Gluchovas
// Licence:   	GPL (version 2.0 or later)
/////////////////////////////////////////////////////////////////////////////

#ifndef __CODECOMPL_SVC_G__
#define __CODECOMPL_SVC_G__

#include "wx/panel.h"
#include "wx/pmf/lseditor.h"
#include "wx/pmf/pm.h"
#include "wx/pmf/inf/textediting.h"

#include "cjparser.h"

class wxsTypingMonitor;
class wxsSourceEditorPlugin;

class AutoComplBox;
class ArgListBox;
class AutoComplPanel;

class wxPMCodeCompletionService : public wxPMSimpleService
{
public:
	wxPMCodeCompletionService();
	~wxPMCodeCompletionService();

	// overriden methods of wxPMService

	virtual bool Start();
	virtual bool Stop();

	virtual wxPMMergableMenuChain* GetMergableMenuChain();

	DECLARE_DYNAMIC_CLASS( wxPMCodeCompletionService )
	DECLARE_EVENT_TABLE()

protected:
};

class wxsTypingMonitor : public wxEvtHandler
{
public:
	wxsTypingMonitor( wxPMCodeCompletionService* svc, wxPMDocument* doc );

	void OnChar( wxKeyEvent& event );
	void OnKeyDown( wxKeyEvent& event );

	void Enable( bool enable );

	DECLARE_EVENT_TABLE()

protected:
	wxPMCodeCompletionService* mpSvc; // back-reference 
	wxPMDocument*			   mpDoc;
	bool                       mIsEnabled;
};

class AutoComplPanel : public wxPanel
{
public:
	AutoComplPanel( wxPMDocument* doc,
				    wxsTypingMonitor* monitor,
				    MMemberListT& ctxList,
				    const wxPoint& pos,
				    const wxSize&  size );

	~AutoComplPanel();

	bool CalcPanelPosition( bool      above,
						    wxSize&   size,
						    wxPoint&  pos );

	void StoreScreenPos();

	// overriden methods of ContextListBox

	virtual void OnCloseList( wxKeyEvent& key );
	virtual void OnKeyReceived( wxKeyEvent& key );
	virtual void OnFocusKilled();

	void OnSize( wxSizeEvent& event );

	DECLARE_EVENT_TABLE()

protected:
	bool MethodPresent( const wxString& name );
	void FindOverloads( MMemberListT& ops, const wxString& name );

	void CompleteName();
	void RepositionPanel();
	void SwitchToHintMode( MMemberListT& ops );
	bool TrySwitching();

protected:
	AutoComplBox*	   mpCtxBox;
	ArgListBox*        mpArgBox;
	wxsTypingMonitor*  mpMonitor;
	wxPMDocument*	   mpDoc;

	// obtained interfaces
	I_EditableText*    mpInfTextEdit;
	I_ContainingText*  mpInfContText;

	MMemberListT       mCtxList;
	wxSize             mCharDim;

	bool               mArgHintMode; // TRUE, if argument list is being shown now,
									 // otherwise method-list pop-up

	bool               mIsAbove;
	int                mPrevCursorLine;
	int                mPrevPageLine;
	int                mPrevPageCol;
};

#define CTX_LIST_PIN_TC (BOOKMARK_PIN_TC + 100)

class CtxListPin : public TPinBase
{
public:
	int mIconNo;

public:
	CtxListPin( size_t row, int iconNo )
		: TPinBase( CTX_LIST_PIN_TC, row ),
		  mIconNo( iconNo )
	{}

	static int GetPinTypeCode() { return CTX_LIST_PIN_TC; }
};

class TCtxListPinPainter : public TPinPainterBase
{
protected:
	wxBrush mBkBrush;
	static wxBitmap mBmps[11];
public:
	TCtxListPinPainter();

	virtual void DrawPin( TPinBase* pPin, wxTextEditorView& view, wxDC& dc, 
						  const wxPoint& pos, const wxSize& dim );

	enum { CLASS_IMAGE = 0,
		   PRIV_MTD_IMAGE,
		   PROT_MTD_IMAGE,
		   PUB_MTD_IMAGE,
		   PRIV_VAR_IMAGE,
		   PROT_VAR_IMAGE,
		   PUB_VAR_IMAGE,
		   PUB_PURE_MDT_IMAGE,
		   PRIV_MTD_DEF_IMAGE,
		   PROT_MTD_DEF_IMAGE,
		   PUB_MTD_DEF_IMAGE
		 };
};

class ContextListBox : public wxTextEditorView 
{
public:
	ContextListBox( wxWindow*     parent, 
		               wxWindowID    id,
					   MMemberListT& ctxList,
					   spFile*       pFile );

	~ContextListBox();

	void OnChar( wxKeyEvent& event );
	void OnKeyDown( wxKeyEvent& event );
	void OnKillFocus( wxFocusEvent& event );
	void OnDblClick( wxMouseEvent& event );

	void SetPopupMode( bool on );

	wxString GetTypedName() { return mName; }

	spContext* GetMatchingContext();

	// notifications sent to the derived class

	virtual void OnCloseList( wxKeyEvent& key )   {}
	virtual void OnKeyReceived( wxKeyEvent& key ) {}
	virtual void OnFocusKilled() {}

	DECLARE_EVENT_TABLE()

protected:
	int FindClosestMatch();

protected:
	MMemberListT mCtxList;
	wxString       mName;
	spFile*      mpFile;
	bool         mPopupMode;
};

class AutoComplBox : public ContextListBox
{
public:
	AutoComplBox( AutoComplPanel* panel, 
				  MMemberListT&   ctxList,
				  spFile*         file );

	virtual void OnCloseList( wxKeyEvent& key );

	virtual void OnKeyReceived( wxKeyEvent& key );

	virtual void OnFocusKilled();

	void SetEnabled( bool enabled );

protected:
	AutoComplPanel* mpPanel;
	bool     mEnabled;
};

class ArgListBox : public wxTextEditorView
{
	AutoComplPanel* mpPanel;

	wxSize mBoxDim;
	wxString mName;   // current arg.list wxString

public:
	ArgListBox( AutoComplPanel* pPanel,
			    MMemberListT&      mtdList,
			    int                maxWidth, 
			    const wxSize&      charDim );

	void OnChar( wxKeyEvent& event );
	void OnKeyDown( wxKeyEvent& event );
	void OnKillFocus( wxFocusEvent& event );

	wxSize& GetBoxSize() { return mBoxDim; }

	DECLARE_EVENT_TABLE()
};

#endif // __CODECOMPL_SVC_G__