/////////////////////////////////////////////////////////////////////////////
// Name:        No names yet.
// Purpose:     Contrib. demo
// Author:      Aleksandras Gluchovas
// Modified by:
// Created:     2000/02/08
// RCS-ID:      $Id: markersvc.cpp,v 1.3 2001/04/04 12:42:37 aleksandras Exp $
// Copyright:   (c) Aleksandras Gluchovas
// Licence:   	GPL (version 2.0 or later)
/////////////////////////////////////////////////////////////////////////////

#ifdef __GNUG__
    #pragma implementation "markersvc.cpp"
    #pragma interface "markersvc.h"
#endif

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#ifndef WX_PRECOMP
    #include "wx/wx.h"
#endif

#include "markersvc.h"

#include "wx/textdlg.h"

/***** Implementation for class MarkerService *****/

static wxCommandInfo gMarkerCommands[] = {

	wxCommandInfo( MarkerService::ADDMARK,     "&Add Mark",    "", "Alt+F1" ),
	wxCommandInfo( MarkerService::REMOVE_MARK, "&Remove Mark", "", "Alt+F2" ),
	wxCommandInfo( MarkerService::SHOW_MARKS,  "&Show Marks",  "", "Alt+F3" ),
	wxCommandInfo( MarkerService::HIDE_MARKS,  "&Hide Marks",  "", "Alt+F4" ),

	wxCommandInfo( 0, "" ) // list-terminator
};

static wxPMMergableMenuChain gMarkerChains[] = {

	wxPMMergableMenuChain( "/&Marks/", gMarkerCommands ),

	wxPMMergableMenuChain( "", NULL ) // list-terminator
};


IMPLEMENT_DYNAMIC_CLASS( MarkerService, wxPMPane )

BEGIN_EVENT_TABLE( MarkerService, wxPMPane )
	
	EVT_MENU( ADDMARK,     MarkerService::OnAddMark )
	EVT_MENU( REMOVE_MARK, MarkerService::OnRemoveMark )
	EVT_MENU( SHOW_MARKS,  MarkerService::OnShowMarks )
	EVT_MENU( HIDE_MARKS,  MarkerService::OnHideMarks )

EVT_LISTBOX( ID_MARKS_LIST, MarkerService::OnListItemSelected )

END_EVENT_TABLE()

MarkerService::MarkerService()

	: mpMarksBox( NULL )
{
	SetRefData( (wxObjectRefData*)(wxPMService*)this );
}

MarkerService::~MarkerService()
{
	SetRefData( NULL ); // part of the above hack..
}

wxPMMergableMenuChain* MarkerService::GetMergableMenuChain()
{
	return gMarkerChains;
}

wxWindow* MarkerService::GetPaneWindow()
{
	return mpMarksBox;
}

void MarkerService::CreatePaneWindow( wxWindow* pParent )
{
	mpMarksBox = new wxListBox( pParent, ID_MARKS_LIST );

	mpMarksBox->PushEventHandler( this ); // to catch EVT_LISTBOX
}

wxStringList* MarkerService::GetDocumentTypes()
{
	return NULL; // NULL says that pane is associated
				 // with all types of documents
}

bool MarkerService::Stop()
{
	if ( mpMarksBox )

		mpMarksBox->PopEventHandler();

	return TRUE;
}

// event-handlers

void MarkerService::OnAddMark( wxCommandEvent& event )
{
	// check for supported interfaces first

	wxPMDocument* pDoc = (wxPMDocument*)wxPMBootSvc().GetDocManager()->GetCurrentDocument();

	I_MarkableText* pMarkInf = GetMarkingInterface();
	I_ContainingText* pTextInf = GetTextInterface();

	if ( !pMarkInf || !pTextInf ) return;

	wxTextEntryDialog dlg( wxPMBootSvc().GetMainWindow(), "Mark name", "Name:" );

	if ( dlg.ShowModal() == wxID_OK )
	{
		int line = 0, col = 0;

		pTextInf->GetCursorPosition( &line, &col );

		long id = pMarkInf->AddMark( I_MarkableText::BOOKMARK, line );

		MarkData* pMark = new MarkData();

		wxASSERT( pDoc->GetFileInfo() ); // DBG::

		pMark->mFile = *pDoc->GetFileInfo();
		pMark->mLine = line;
		pMark->mName = dlg.GetValue();
		pMark->mId   = id;
		mMarks.Add( pMark );

		wxString lineStr;
		lineStr.Printf("%d", line );

		mpMarksBox->Append( pMark->mName + " [" + 
							pMark->mFile.GetNameWithoutPath() + ":" + lineStr + "]" );

		mpMarksBox->SetSelection( mpMarksBox->Number() - 1 );
	}
}

void MarkerService::OnRemoveMark( wxCommandEvent& event )
{
	if ( mpMarksBox->GetSelection() == -1 ||
		 mpMarksBox->Number() == 0 )

		 return;

	MarkData* pMark = mMarks[ mpMarksBox->GetSelection() ];

	wxPMDocManager* pMgr = wxPMBootSvc().GetDocManager();

	mpMarksBox->Delete( mpMarksBox->GetSelection() );

	wxPMDocument* pDoc =
		pMgr->OpenDocument( pMark->mFile, wxPMBootSvc().GetWorkplace()->GetActiveProject() );

	if ( pDoc )
	{
		I_MarkableText* pMarkInf = 
			(I_MarkableText*)pDoc->GetInterface( "I_MarkableText" );

		pMarkInf->RemoveMark( pMark->mId );
	}

	mMarks.Remove( pMark );
	delete pMark;
}

void MarkerService::OnShowMarks( wxCommandEvent& event )
{
	wxPMBootSvc().ShowPane( this );
}

void MarkerService::OnHideMarks( wxCommandEvent& event )
{
	wxPMBootSvc().HidePane( this );
}

void MarkerService::OnListItemSelected( wxCommandEvent& event )
{
	MarkData* pMark = mMarks[ mpMarksBox->GetSelection() ];

	wxPMDocManager* pMgr = wxPMBootSvc().GetDocManager();

	wxPMDocument* pDoc =
		pMgr->OpenDocument( pMark->mFile, wxPMBootSvc().GetWorkplace()->GetActiveProject() );

	I_MarkableText* pMarkInf = 
		(I_MarkableText*)pDoc->GetInterface( "I_MarkableText" );

	pMarkInf->JumpToMark( pMark->mId );
}

/*** protected methods ***/

// helpers

I_MarkableText* MarkerService::GetMarkingInterface()
{
	wxPMDocument* pDoc = (wxPMDocument*)wxPMBootSvc().GetDocManager()->GetCurrentDocument();

	if ( !pDoc ) return NULL;

	return (I_MarkableText*)pDoc->GetInterface( "I_MarkableText" );
}

I_ContainingText* MarkerService::GetTextInterface()
{
	wxPMDocument* pDoc = (wxPMDocument*)wxPMBootSvc().GetDocManager()->GetCurrentDocument();

	if ( !pDoc ) return NULL;

	return (I_ContainingText*)pDoc->GetInterface( "I_ContainingText" );
}
