/////////////////////////////////////////////////////////////////////////////
// Name:        No names yet.
// Purpose:     Contrib. demo
// Author:      Aleksandras Gluchovas
// Modified by:
// Created:     2000/02/08
// RCS-ID:      $Id: build_svc.h,v 1.1 2001/04/03 20:10:27 aleksandras Exp $
// Copyright:   (c) Aleksandras Gluchovas (alex@soften.ktu.lt)
// Licence:   	GPL (version 2.0 or later)
/////////////////////////////////////////////////////////////////////////////

#ifndef __BUILDSVC_G__
#define __BUILDSVC_G__

#include "wx/pmf/pm.h"
#include "wx/list.h"
#include "wx/dialog.h"
#include "wx/process.h"
#include "wx/timer.h"
#include "wx/dynarray.h"
#include "scriptproc.h"

#include "wx/pmf/inf/outputwin.h"

class wxPMBuildService;
class BuildControllerThread;

class wxPagingCtrl;		// from WSPP

class BuildArgInfo : public wxObject
{
public:
	wxString mName;
	wxStringList mValues;
	void* mpUserData;
};

WX_DEFINE_ARRAY( BuildArgInfo*, BuildArgInfoListT );

class BuildTemplateInfo;
      
class BuildTemplateInfo : public wxObject
{
public:
	~BuildTemplateInfo();

	wxString mName;

	ScriptTemplate mContent;
	ScriptTemplate mOutputFile;
	ScriptTemplate mBuildCmdLine;
	ScriptTemplate mCleanCmdLine;
	ScriptTemplate mExecCmdLine;

	wxStringList mErrorFilter;
	wxStringList mWarningFilter;

	BuildArgInfoListT mArgs;
};

WX_DEFINE_ARRAY( OutputWindowInfo*,  OutputWindowInfoListT );
WX_DEFINE_ARRAY( BuildTemplateInfo*, BuildTemplateInfoListT );

class BuildConfiguration : public wxObject
{
public:
	BuildConfiguration();

public:
	wxString     mName;

	wxStringList mFields;
	wxStringList mValues;
	BuildTemplateInfo* mpTempl;

	wxString mOutputFile;
	wxString mBuildCmdLine;
	wxString mCleanCmdLine;
	wxString mExecCmdLine;

	bool mIsActive;
};

WX_DEFINE_ARRAY( BuildConfiguration*, BuildConfigurationListT );

class PMProjectConfigSet : public wxObject
{
public:
	~PMProjectConfigSet();
	virtual void CleanUp();

	void AddConfig( BuildConfiguration* cfg );
	void RemoveConfig( BuildConfiguration* cfg );
	BuildConfigurationListT& GetConfigs();

	BuildConfiguration* GetActiveConfig();

protected:
	BuildConfigurationListT mConfigs;
};

class wxGenericListCtrl;

class wxPMBuildService : public wxPMPane,
						 public I_OutputWindow, // implements interface(!)
						 public ScriptProcessor,
						 public wxPMDocumentListener
{
public:
	wxPMBuildService();
	~wxPMBuildService();

	// overriden methods of wxPMPane and wxPMService

	virtual bool Start();
	virtual bool Stop();
	virtual void* GetInterface( const char* infName, const char* version = NULL );
	virtual wxPMMergableMenuChain* GetMergableMenuChain();
	
	virtual wxWindow* GetPaneWindow();
	virtual void CreatePaneWindow( wxWindow* pParent );
	virtual wxPMLayoutPreference* GetLayoutPefs();

	// overriden notifications of wxPMDocumentListener

	virtual bool OnClosingDocument( wxPMDocument& doc, wxOutputStream* s, wxPMSerializer* ser );
	virtual bool OnOpeningDocument( wxPMDocument& doc, wxInputStream* s, wxPMSerializer* ser );

	// overriden methods of ScriptProcessor

	virtual bool ProcessSection( Record& rec );
	virtual void CleanUp();
	
	// other methods
	
	virtual BuildTemplateInfo* FindTemplateByName( const wxString& name );
	virtual void UpdateFiles();

	// called from build-controller thread
	void DetectMessageInfo( wxString line, OutputMsgInfo& info );
	
	// command handlers

	void OnBuild( wxCommandEvent& event );
	void OnClean( wxCommandEvent& event );
	void OnConfigure( wxCommandEvent& event );
	void OnBuildAndExecute( wxCommandEvent& event );
	void OnExecute( wxCommandEvent& event );
	void OnToggleOutputWindow( wxCommandEvent& event );

	// notification commands received from build-controller thread

	void OnBuildStarted( wxCommandEvent& event );
	void OnBuildMessageListUpdated( wxCommandEvent& event );
	void OnBuildFinished( wxCommandEvent& event );
	void OnProcessTerminated( wxProcessEvent& event );
	void OnBuildTimer( wxTimerEvent& event );

	// implementation of "I_OutputWindow" interface

	virtual void ClearOutputWindow( const wxString& name );
	virtual void AddMessageLine( const wxString& line, 
								 const wxString& outWndName,
								 bool detect = FALSE );

	virtual bool AddOutputWindow( const wxString& name, const wxString& displayName );
	virtual bool DeleteOutputWindow( const wxString& name );
	virtual OutputWindowInfo* FindOutputWindow( const wxString& outWndName );

	DECLARE_DYNAMIC_CLASS( wxPMBuildService )
	DECLARE_EVENT_TABLE()

protected:
	void GetStringListVar( Record& fromRec, const wxString& name, wxStringList& toLst );
	PMProjectConfigSet* DoGetConfigForProject( wxPMDocument& project );

	virtual bool GenerateOutputFile( BuildConfiguration& cfg, wxPMProject& project );
	virtual void ReduceBuildTimeVars( BuildConfiguration& cfg, wxPMProject& project );

	virtual bool DoUpdateOutputFiles( PMProjectConfigSet* set, bool clean );
	virtual void SuckBuildOutput( bool fromTiemr );
	virtual void DoExecute( bool build );

protected:
	BuildTemplateInfoListT mTemplates;
	wxProcess* mpBuildProcess;
	BuildConfiguration* mpBuildingCfg;
	bool mNeedToExecute;

	wxTimer    mTimer;
	wxWindow* mpPanel;
	wxPagingCtrl* mpPageCtrl;

	OutputWindowInfoListT mOutputWindows;
};

class BuildControllerThread : public wxThread
{
public:
	BuildControllerThread( wxPMBuildService* buildSvc, BuildConfiguration* cfg );

	void OnTerminated();

	// overriden method of wxThread
	virtual void* Entry();

protected:
	wxPMBuildService* mpBuildSvc;
	BuildConfiguration* mpCfg;
	volatile bool mIsTerminated;
};

class BuildScriptTemplateHandler : public BasicScriptProcessorTemplate
{
public:
	BuildScriptTemplateHandler( wxPMBuildService* buildSvc );

	// overriden method of ScriptTemplate

	virtual wxString HandleSpecialSubstitution( char* at, ScriptTemplate& templ  );

protected:
	virtual wxString Handle_file_list( char* at, ScriptTemplate& templ );

protected:
	wxPMBuildService* mpBuildSvc;
};

class BuildConfigurationsDialog : public wxDialog
{
public:
	BuildConfigurationsDialog( BuildConfigurationListT* pConfigs,
							   BuildTemplateInfoListT* pTemplates,
							   wxPMBuildService* buildSvc );
	~BuildConfigurationsDialog();

	void OnNew( wxCommandEvent& event );
	void OnEdit( wxCommandEvent& event );
	void OnActivate( wxCommandEvent& event );
	void OnRemove( wxCommandEvent& event );

	void OnInitDialog( wxInitDialogEvent& event );

	DECLARE_EVENT_TABLE()

protected:
	void RefillList();

protected:
	BuildConfigurationListT* mpConfigs;
	BuildTemplateInfoListT*  mpTemplates;

	wxPMBuildService* mpBuildSvc;
	wxListBox* mpList;
};

class BuildConfigurationEditDialog : public wxDialog
{
public:
	BuildConfigurationEditDialog( BuildConfiguration* pCfg, 
								  const wxString& title,
								  BuildTemplateInfoListT& templates );

	void OnChoice( wxCommandEvent& event );

	void ExchangeValues( bool toControls );

	DECLARE_EVENT_TABLE()

protected:
	void RecreateUI();

protected:
	BuildConfiguration* mpCfg;
	wxTextCtrl* mpName;
	wxChoice* mpTempl;
	BuildTemplateInfoListT* mpTemplates;
};

#endif // __BUILDSVC_G__