/////////////////////////////////////////////////////////////////////////////
// Name:        No names yet.
// Purpose:     Contrib. demo
// Author:      Aleksandras Gluchovas
// Modified by:
// Created:     2000/02/08
// RCS-ID:      $Id: wkp_main.cpp,v 1.35 2001/05/10 11:26:32 georgetasker Exp $
// Copyright:   (c) Aleksandras Gluchovas
// Licence:   	GPL (version 2.0 or later)
/////////////////////////////////////////////////////////////////////////////

#ifdef __GNUG__
    #pragma implementation "minimal.cpp"
    #pragma interface "minimal.cpp"
#endif

#include "wx/wxprec.h"

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

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

#if defined(__WXGTK__) || defined(__WXMOTIF__)
    #include "mondrian.xpm"
#endif

#define USE_PM_GUI 1
#define USE_RESOURCE_EDITING 1

#include "build.h"  // wxWorkshop PROGRAM_xxxxx constants

#include "wkp_main.h"
#include "pm_sample.h"
#include "myutils.h" // IntToStr()

#include "wx/pmf/pm_flalg.h"
#include "wx/pmf/pm_prjtempl.h"
#include "wx/pmf/pm.h"
#include "wx/pmf/lseditor.h"  // glt

#include "wx/fileconf.h"

#include "hellosvc.h"

#include "build_svc.h"
#include "indexing_svc.h"
#include "helpfinder_svc.h"
#include "classfinder_svc.h"

#include "wx/pmf/srceditordoc.h"

#include "mimetypes.h"

#if USE_RESOURCE_EDITING

#include "res_doc.h"
#include "widgeteditor.h"
#include "menuedit.h"
#include "ui_lookeditor.h"
#include "bmpeditor.h"

#endif

#include "wx/pmf/pm_undef.h"

#include "wx/log.h"
#include <stdio.h> // sprintf()

#include "wx/xml/xmlres.h"
#include "wx/wspp/init.h"

#include "wx/splash.h"

class MyApp : public wxApp
{
public:
    virtual bool OnInit();
};

wxPMDocManager* _gDocMgr = NULL;
wxDocTemplate* _gMyTestPrjTempl = NULL;

#if USE_PM_GUI
#include "wx/pmf/pm_gui.h"
#endif

bool MyApp::OnInit()
{
	InitWSPP();
	wxTheXmlResource->InitAllHandlers();
	bool ok = wxTheXmlResource->Load("workshop.xrc");
	wxASSERT( ok ); // DBG::
	wxTheXmlResource->UpdateResources();
	wxASSERT( ok ); // DBG::


	_gDocMgr = new wxPMDocManager();

    wxString StarDotStr;
    StarDotStr = "*.";
    wxString MaskStr;

    MaskStr = StarDotStr+wxwEXT_WORKPLACE;
	new wxDocTemplate( _gDocMgr, "Workplace...", MaskStr,
					   "", // default dir
					   wxwEXT_WORKPLACE, wxwMIME_WORKPLACE,
					   "view-type-name", 
					   CLASSINFO( wxPMSimpleWorkplace ), 
					   NULL // no view
					 );

#if USE_PM_GUI
    MaskStr = StarDotStr+wxwEXT_PROJECT;
	new wxPMProjectCreatorTemplate( _gDocMgr, "Project...", MaskStr, 
					   "", // default dir
					   wxwEXT_PROJECT, "",  // type is EMPTY string to allow autodetection of concrete type
					                        // upon loading of the document
					   "", 
					   CLASSINFO( wxPMProject ),
                       NULL
					 );
#endif

	new wxDocTemplate( _gDocMgr, "Other files", "*.*", 
					   "", // default dir
					   "", "",
                       "",
					   CLASSINFO( wxPMTempProject ),
					   NULL, // no view
					   wxTEMPLATE_INVISIBLE // !!
					 );

    MaskStr = StarDotStr+wxwEXT_PLAIN_TEXT;
	new wxDocTemplate( _gDocMgr, "Text Document", MaskStr, 
					   "", // default dir
					   wxwEXT_PLAIN_TEXT, wxwMIME_PLAIN_TEXT,
					   "wxw-text-viewer", 
					   CLASSINFO( wxPlainTextDocument ), 
					   CLASSINFO( wxPlainTextView )
					 );

#if USE_RESOURCE_EDITING

    MaskStr = StarDotStr+wxwEXT_WX_RESOURCE;
	new wxDocTemplate( _gDocMgr, "wxWindows Resource", MaskStr, 
					   "", // default dir
					   wxwEXT_WX_RESOURCE, wxwMIME_WX_RESOURCE,
					   "wxw-resource-viewer", 
					   CLASSINFO( ResDocument ), 
					   NULL
					 );

    MaskStr = StarDotStr+wxwEXT_WIDGET_RESOURCE;
	new wxDocTemplate( _gDocMgr, "wxWindows Widget Resource", MaskStr, 
					   "", // default dir
					   wxwEXT_WIDGET_RESOURCE, wxwMIME_WIDGET_RESOURCE,
					   "wxw-widget-resource-viewer", 
					   CLASSINFO( WidgetDocument ), 
					   CLASSINFO( WidgetView ), 
					   wxTEMPLATE_INVISIBLE  // used only through ResDocument
					 );

    MaskStr = StarDotStr+wxwEXT_BITMAP_RESOURCE;
	wxDocTemplate* pBmpTempl = 
	new wxDocTemplate( _gDocMgr, "wxWindows Bitmap Resource", MaskStr, 
					   "", // default dir
					   wxwEXT_BITMAP_RESOURCE, wxwMIME_BITMAP_RESOURCE,
					   "wxw-bitmap-resource-viewer", 
					   CLASSINFO( BitmapEditorDoc ), 
					   CLASSINFO( BitmapEditorView ) 
					   //wxTEMPLATE_INVISIBLE  // used only through ResDocument
					 );

    MaskStr = StarDotStr+wxwEXT_MENUBAR_RESOURCE;
	new wxDocTemplate( _gDocMgr, "wxWindows Menubar Resource", MaskStr, 
					   "", // default dir
					   wxwEXT_MENUBAR_RESOURCE, wxwMIME_MENUBAR_RESOURCE,
					   "wxw-menubar-resource-viewer", 
					   CLASSINFO( MenuEditorDoc ), 
					   CLASSINFO( MenuEditorView ), 
					   wxTEMPLATE_INVISIBLE 
					 );

    MaskStr = StarDotStr+wxwEXT_WIDGET_LOOK;
	new wxDocTemplate( _gDocMgr, "Widget-Look Resource", MaskStr, 
					   "", // default dir
					   wxwEXT_WIDGET_LOOK, wxwMIME_WIDGET_LOOK,
					   "wxw-widget-look-viewer", 
					   CLASSINFO( wxUILookDocument ), 
					   CLASSINFO( wxUILookView )
					 );

#endif // USE_RESOURCE_EDITING

    MaskStr = StarDotStr + wxwEXT_HTML;
    MaskStr.Replace(";",";*.");
    wxString tempStr;
    tempStr = wxwEXT_HTML;
	new wxDocTemplate( _gDocMgr, "HTML Document", MaskStr, 
					   "", // default dir
					   tempStr.BeforeFirst(';'), wxwMIME_HTML,
					   "html-text-viewer", 
					   CLASSINFO( wxPlainTextDocument ), 
					   CLASSINFO( wxHtmlView )
					 );

    MaskStr = StarDotStr + wxwEXT_HTM;
    MaskStr.Replace(";",";*.");
    tempStr = wxwEXT_HTM;
	new wxDocTemplate( _gDocMgr, "HTM Document", MaskStr, 
					   "", // default dir
					   tempStr.BeforeFirst(';'), wxwMIME_HTM,
					   "htm-text-viewer", 
					   CLASSINFO( wxPlainTextDocument ), 
					   CLASSINFO( wxHtmlView )
					 );

    MaskStr = StarDotStr + wxwEXT_C_HEADER;
    MaskStr.Replace(";",";*.");
    tempStr = wxwEXT_C_HEADER;
	new wxDocTemplate( _gDocMgr, "C++ Header File", MaskStr, 
					   "", // default dir
					   tempStr.BeforeFirst(';'), wxwMIME_C_HEADER,
					   "h-source-code-document", 
					   CLASSINFO( wxSourceCodeDocument ), 
					   CLASSINFO( wxSourceCodeView )
					 );

    MaskStr = StarDotStr + wxwEXT_CPP_SOURCE;
    MaskStr.Replace(";",";*.");
    tempStr = wxwEXT_CPP_SOURCE;
	new wxDocTemplate( _gDocMgr, "C++ Source File", MaskStr, 
					   "", // default dir
					   tempStr.BeforeFirst(';'), wxwMIME_CPP_SOURCE,
					   "cpp-source-code-document", 
					   CLASSINFO( wxSourceCodeDocument ), 
					   CLASSINFO( wxSourceCodeView )
					 );

    MaskStr = StarDotStr + wxwEXT_C_SOURCE;
    MaskStr.Replace(";",";*.");
    tempStr = wxwEXT_C_SOURCE;
	new wxDocTemplate( _gDocMgr, "C Source File", MaskStr, 
					   "", // default dir
					   tempStr.BeforeFirst(';'), wxwMIME_C_SOURCE,
					   "c-source-code-document", 
					   CLASSINFO( wxSourceCodeDocument ), 
					   CLASSINFO( wxSourceCodeView )
				     );
    MaskStr = StarDotStr + wxwEXT_JAVA;
	new wxDocTemplate( _gDocMgr, "Java Source File", MaskStr, 
					   "", // default dir
					   wxwEXT_JAVA, wxwMIME_JAVA,
					   "java-source-code-document", 
					   CLASSINFO( wxSourceCodeDocument ), 
					   CLASSINFO( wxSourceCodeView )
				     );
    MaskStr = StarDotStr + wxwEXT_PYTHON;
	new wxDocTemplate( _gDocMgr, "Python Source File", MaskStr, 
					   "", // default dir
					   wxwEXT_PYTHON, wxwMIME_PYTHON,
					   "python-source-code-document", 
					   CLASSINFO( wxSourceCodeDocument ), 
					   CLASSINFO( wxSourceCodeView )
					 );

	// templates for actual projects

    MaskStr = StarDotStr + wxwEXT_CPP_PROJECT;
	_gMyTestPrjTempl =
		new wxDocTemplate( _gDocMgr, "C++ Project", MaskStr, 
						   "", // default dir
						   wxwEXT_CPP_PROJECT, wxwMIME_CPP_PROJECT,
						   "", 
						   CLASSINFO( wxPMProject ), 
						   NULL//, // no view
						   //wxTEMPLATE_INVISIBLE // !!
						 );

	wxPMFileInfo::RegisterDefaultTypeFallbacks(); // "text/plain", "text/html", etc
	wxPMFileInfo::RegisterTypeFallback( wxwMIME_WORKPLACE,  wxwEXT_WORKPLACE );
	wxPMFileInfo::RegisterTypeFallback( wxwMIME_CPP_PROJECT,wxwEXT_CPP_PROJECT );

    wxString titleStr;
    titleStr.Printf("%s %s",PROGRAM_NAME,PROGRAM_VERSION);
    MyFrame *frame = new MyFrame( _gDocMgr, titleStr.c_str(),
                                 wxPoint(50, 50), wxSize(650, 500));

    frame->Show(TRUE);
    SetTopWindow(frame);

	// activate pane-layout algorithm

	#if 0
		wxPMBootSvc().StartServicesByClass( CLASSINFO(wxPMSashLayoutAlgorithm) );
	#else
		wxPMBootSvc().StartServicesByClass( CLASSINFO(wxPMFLAlgorithm) );
	#endif

	// build service is started early...

	wxPMBootSvc().StartServicesByClass( CLASSINFO(wxPMBuildService) );

	wxPMBootSvc().StartServicesByClass( CLASSINFO(wxPMIndexingService) );

	wxPMBootSvc().StartServicesByClass( CLASSINFO(wxPMHelpFinderService) );

	wxPMBootSvc().StartServicesByClass( CLASSINFO(wxPMClassFinderService) );

    // auto-open some project (for debugging purposes)
	
#if 0
	wxPMFileInfo finfo( "d:\\projects\\wxWorkshop\\wx_contrib_mods\\samples\\wsrad\\ok.wsw" );

	if ( ::wxFileExists( finfo.GetPath() ) )
	{
		ok = (_gDocMgr->OpenDocument( finfo, NULL ) != NULL);
		//ok = _gDocMgr->OpenDocument( wxPMFileInfo( "d:\\projects\\wxWorkshop\\ws\\workshop.xrc" ), NULL );
	}

	ok = _gDocMgr->OpenDocument( wxPMFileInfo( "first_cool.wsw" ), NULL );
	wxPMDocument* pPrjDoc = wxPMBootSvc().GetWorkplace()->GetActiveProject();

	//_gDocMgr->OpenDocument( wxPMFileInfo( "D:\\projects\\wxs\\ws\\unnamed2.xml" ), pPrjDoc );
	wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED  );
	evt.SetId( wxID_NEW );
	_gDocMgr->ProcessEvent( evt );

	//wxPMDocument* pDoc = _gDocMgr->OpenDocument( wxPMFileInfo( "D:\\projects\\aworkplace\\gamma.xml" ), pPrjDoc );

	//wxPMDocument* pDoc = _gDocMgr->OpenDocument( wxPMFileInfo( "D:\\projects\\aworkplace\\config_stdwlooks.wlk" ), pPrjDoc );

	//pDoc->Modify( TRUE );
	//wxPMBootSvc().GetDocManager()->SaveDocument( pDoc );
	//wxPMDocument* pDoc = _gDocMgr->OpenDocument( wxPMFileInfo( "D:\\projects\\aworkplace\\a.cpp" ), pPrjDoc );
	//_gDocMgr->ActivateDocument( pDoc );
#endif

    return TRUE;
}

IMPLEMENT_APP(MyApp)

// global helper functions

extern void TestFileConfig();

/***** Implementation for class MyFrame *****/

BEGIN_EVENT_TABLE(MyFrame, wxDocMDIParentFrame)
    EVT_MENU(Minimal_Quit,  MyFrame::OnQuit)
    EVT_MENU(Minimal_About, MyFrame::OnAbout)
	EVT_CHAR_HOOK( MyFrame::OnCharHook )

	EVT_CLOSE( MyFrame::OnClose )
END_EVENT_TABLE()

MyFrame::~MyFrame()
{
	if ( mpLogFrm )
	{
		delete wxLog::SetActiveTarget(NULL);
		mpLogFrm->Destroy();
	}

    wxTextEditorView::KillTimer();

#if USE_PM_GUI
	wxPMProjectCreatorDialog::RemoveAllTemplates();
#endif

	if ( _gDocMgr ) 
	{
		delete _gDocMgr;
		_gDocMgr = NULL;
	}
}

MyFrame::MyFrame( wxDocManager* manager, const wxString& title, 
				  const wxPoint& pos, const wxSize& size)
       : wxDocMDIParentFrame( manager, (wxFrame *)NULL, -1, title, pos, size),
		 mpLogFrm( NULL ),
		 mpDocMgr( manager )
{
#if wxCHECK_VERSION(2,3,0) && !defined(__WXDEBUG__)
	/* Show Splash screen in none Debug */
	wxImage			wsSplashBitmap(::wxGetCwd() + "/images/splash/wsSplashScreen.bmp", wxBITMAP_TYPE_BMP);
	if (wsSplashBitmap.Ok())
	{
		wxSplashScreen	*wsSplashScreen 
						= new wxSplashScreen( wsSplashBitmap.ConvertToBitmap(), 
											wxSPLASH_CENTRE_ON_PARENT | wxSPLASH_TIMEOUT, 
											4000, this, -1);
	}
#endif

	/***** debug ******/
	#if 1
		mpLogFrm = new wxFrame( NULL,-1,"Log", wxDefaultPosition, wxSize(500,200) );
		wxTextCtrl *textCtrl = new wxTextCtrl(mpLogFrm, -1, "",wxDefaultPosition,wxDefaultSize, wxTE_MULTILINE | wxSUNKEN_BORDER);
		wxLogTextCtrl *logWindow = new wxLogTextCtrl(textCtrl);
		delete wxLog::SetActiveTarget(logWindow);
		mpLogFrm->Show(TRUE);
	#endif
	/*******************************/

    // set the frame icon
    SetIcon(wxICON(mondrian));

	/********* PMF-initialization from user-code **********/
	wxPMBitmapManager* pBmpMgr = new wxPMBitmapManager();
	pBmpMgr->SetRelativePath( ::wxGetCwd() + "/images" );
	pBmpMgr->SetDefaultExtension( "bmp" );

	wxPMBootstrapService* pBootSvc = new wxPMBootstrapService( this, _gDocMgr );

	RegisterCreationTemplates();

	#if 0
		TestProjectCreator();
		return;
	#endif

	#if 0
		TestKeyBinder();
		return;
	#endif

	#if 0
		TestFileConfig();
	#endif


	pBootSvc->Start();

/*
	HelloService* hello = new HelloService();
	pBootSvc->AddService( hello );
	pBootSvc->StartService( hello );
*/
#if wxUSE_STATUSBAR
    // create a status bar just for fun (by default with 1 pane only)
    CreateStatusBar(2);
    SetStatusText("Welcome to wxWindows!");
#endif // wxUSE_STATUSBAR

}

// event handlers							

void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
	if ( wxPMBootSvc().CleanUp() )

	    // TRUE is to force the frame to close
		Close(TRUE);
}

DECLARE_APP(MyApp);

void MyFrame::OnClose(wxCloseEvent& event)
{
	if ( &wxPMBootSvc() && wxPMBootSvc().CleanUp() )
	{
		event.Skip(); // allow closure if PMF has "agreed"

		// FIXME:: find out why some dialogs do not get destroyed
		//		   forcing us to use this:

		wxGetApp().ExitMainLoop();
	}
}

void MyFrame::OnCharHook( wxKeyEvent& event )
{
	if ( event.AltDown() || event.ControlDown() )
	
		wxPMBootSvc().TranslateKeyEvent( event );
	else
		event.Skip();
}

void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
    wxString msg;
    msg.Printf( "This is the about dialog of wxUIEditor.\n"
                "Welcome to %s"
#ifdef wxBETA_NUMBER
               " (beta %d)!"
#endif // wxBETA_NUMBER
               , wxVERSION_STRING
#ifdef wxBETA_NUMBER
               , wxBETA_NUMBER
#endif // wxBETA_NUMBER
              );

    wxMessageBox(msg, "About wxWorkplace-Test", wxOK | wxICON_INFORMATION, this);
}


void MyFrame::RegisterCreationTemplates()
{
#if USE_PM_GUI
	PMProjectTypeTemplateListT lst;
	wxDocTemplate* t = _gMyTestPrjTempl;

	// empty

	lst.Add( new wxPMProjectTypeTemplate( "/", 
										  "Empty Project", "", "misc/32x32_empty", t) );

	// C++

	lst.Add( new wxPMProjectTypeTemplate( "/wxWindows C++ Applications/", 
										  "Classical wxApp", "", "misc/32x32_wx", t) );
	lst.Add( new wxPMProjectTypeTemplate( "/wxWindows C++ Applications/", 
										  "MDI-App Wizard", "", "misc/32x32_wizard", t) );
	lst.Add( new wxPMProjectTypeTemplate( "/wxWindows C++ Applications/", 
										  "Dynamic Library", "", "misc/32x32_dll", t) );
	lst.Add( new wxPMProjectTypeTemplate( "/wxWindows C++ Applications/", 
										  "Dialog-driven App", "", "misc/32x32_applet", t) );
	lst.Add( new wxPMProjectTypeTemplate( "/wxWindows C++ Applications/", 
										  "Netscape Plug-in", "", "misc/32x32_appletcode", t) );
	lst.Add( new wxPMProjectTypeTemplate( "/wxWindows C++ Applications/", 
										  "wxODBC Database App", "", "misc/32x32_db", t) );
	lst.Add( new wxPMProjectTypeTemplate( "/wxWindows C++ Applications/", 
										  "Console wxApp", "", "misc/32x32_selfextract", t) );
	lst.Add( new wxPMProjectTypeTemplate( "/wxWindows C++ Applications/", 
										  "wxSockServer\nWizard", "", "misc/32x32_service", t) );

	// Python

	lst.Add( new wxPMProjectTypeTemplate( "/wxPython Applications/", 
										  "wxPython Classic", "", "misc/32x32_python", t) );
	lst.Add( new wxPMProjectTypeTemplate( "/wxPython Applications/", 
										  "Python Distributed", "", "misc/32x32_vdiff", t) );
	lst.Add( new wxPMProjectTypeTemplate( "/wxPython Applications/", 
										  "wxPython XML-App", "", "misc/32x32_notemaker", t) );

	// distr

	lst.Add( new wxPMProjectTypeTemplate( "/Distribution Projects/Packaging/", 
										  "ZIP\nArichive", "", "misc/32x32_zip", t) );
	lst.Add( new wxPMProjectTypeTemplate( "/Distribution Projects/Packaging/", 
										  "RPM\nPackage", "", "misc/32x32_zipfile", t) );
	lst.Add( new wxPMProjectTypeTemplate( "/Distribution Projects/Packaging/", 
										  "Debian\nPackage", "", "misc/32x32_cab", t) );

	// installers

	lst.Add( new wxPMProjectTypeTemplate( "/Distribution Projects/Installers/", 
										  "WIN32 Installer (x86)", "", "misc/32x32_installer.bmp", t) );
	lst.Add( new wxPMProjectTypeTemplate( "/Distribution Projects/Installers/", 
										  "Python App-Installer", "", "misc/32x32_python", t) );
	lst.Add( new wxPMProjectTypeTemplate( "/Distribution Projects/Installers/", 
										  "GNOME\nShield..;-)", "", "misc/32x32_util", t) );

	wxPMProjectCreatorDialog::SetDefaultCategory( "/wxWindows C++ Applications/" );

	wxPMProjectCreatorDialog::AddTemplates( lst );

#endif
}

void MyFrame::TestProjectCreator()
{
#if USE_PM_GUI

	//--------- code to test wxPMProjectCreatorDialog -----------
	wxPMProjectCreatorDialog dlg( NULL, "Project1", 
								  ::wxGetWorkingDirectory() );
	dlg.ShowModal();

	Destroy();

#endif
}

void MyFrame::TestKeyBinder()
{
	wxKeyBinder* pBinder = new wxKeyBinder();

	wxCommandGroup* g1 = new wxCommandGroup( "File" );
	wxCommandInfo* pInfo1 = new wxCommandInfo( 7, "Open", "Open a file for editing", "" );
	wxCommandInfo* pInfo2 = new wxCommandInfo( 8, "Save", "Save modifications to file", "" );

	pInfo2->AddKey( WXK_SPACE, wxCONTROL_DOWN | wxSHIFT_DOWN );
	
	g1->AddSubcommand( pInfo1 );
	g1->AddSubcommand( pInfo2 );

	pBinder->AddGroup( g1 );

	wxKeyConfigDialog dlg( this, pBinder );
	dlg.ShowModal();

	delete pBinder;
}

void TestFileConfig()
{
	//wxTextFile fl("c:\\0\\raibas.txt");
	//fl.Open();
	//wxASSERT( fl.IsOpened() );


	//wxFileConfig fc( "MyAppName","", "", "c:\\0\\raibas.txt",
	//				 wxCONFIG_USE_GLOBAL_FILE );
	wxFileConfig fc( "MyAppName","", "d:\\0\\raibas.txt","",
					 wxCONFIG_USE_LOCAL_FILE );

	//wxFileConfig fc( "apas" );

	fc.SetPath( "/" );
#if 0
	fc.Write( "root_key1", "root_val1_modified" );
#else
	fc.SetPath( "/firstdir" );
	fc.Write( "fdir_myvar0", "fdir_myvalue0" );
	fc.Write( "fdir_myvar1", "fdir_myvalue1" );
	fc.SetPath( "/firstdir/subdir1" );
	fc.Write( "fdir_sub_myvar1", "fdir_sub_myvalue10" );
	fc.SetPath( "subdir2" );
	fc.Write( "stj_ub", "uhiuh" );
	fc.SetPath( "../.." );
	fc.Write( "fdir_myvar2", "fdir_myvalue22-10" );
#endif
	fc.Flush();

};

#ifdef __HACK_MY_MSDEV40__

char wxDummyChar = 0;

#endif
