/////////////////////////////////////////////////////////////////////////////
// Name:        test_mod_camera_gui.cpp
// Author:      Cesar Mauri Loba
// Copyright:   (C) 2011 Cesar Mauri Loba - CREA Software Systems
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
/////////////////////////////////////////////////////////////////////////////


#include "spcore/coreruntime.h"
#include "testcommon/testcommon.h"
#include "3rdparty/nvwa/debug_new.h"

#if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXX11__)
	// Include Xlib for latter use on main
	#include <X11/Xlib.h>
#endif
#include <wx/app.h>
#include <wx/image.h>
#include <wx/msgdlg.h>
#include <wx/frame.h>
#include <wx/panel.h>
#include <wx/sizer.h>

using namespace spcore;

/*
	Check threads enabled
*/
#if !wxUSE_THREADS
     #error "This program requires thread support."
#endif // wxUSE_THREADS

/*
	main app class
*/
class TestWXApp: public wxApp
{
	DECLARE_CLASS( TestWXApp )
public:
	TestWXApp();	// Constructor

private:
	virtual bool OnInit();	// Initialises the application
	virtual int OnExit();	// Called on exit

	SmartPtr<spcore::IComponent> m_comp;
};

/*
	main frame class
*/
class MyFrame : public wxFrame
{
public:
    MyFrame();
	void OnCloseWindow( wxCloseEvent& event );
	static MyFrame* CreateAddPanel ( spcore::IComponent& component );
private:
	void OnSize(wxSizeEvent& event);
    // any class wishing to process wxWidgets events must use this macro
    DECLARE_EVENT_TABLE()
};

/*
	myframe event table
*/
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
	EVT_CLOSE( MyFrame::OnCloseWindow )
	EVT_SIZE ( MyFrame::OnSize)
END_EVENT_TABLE()

void MyFrame::OnCloseWindow(wxCloseEvent &event)
{
	event.Skip(); // Equivalent to: wxFrame::OnCloseWindow(event);
}

void MyFrame::OnSize(wxSizeEvent& event)
{
	Layout();
	Fit();

	event.Skip (false);
}

/*!
 * Application instance declaration
 */
DECLARE_APP(TestWXApp)

/*!
 * TestWXApp type definition
 */
IMPLEMENT_CLASS( TestWXApp, wxApp )

/*
	Application instance implementation

	we use IMPLEMENT_APP_NO_MAIN instead of IMPLEMENT_APP
	because we define our own main
 */
IMPLEMENT_APP_NO_MAIN(TestWXApp)

// ============================================================================
// implementation
// ============================================================================

// ----------------------------------------------------------------------------
// main frame
// ----------------------------------------------------------------------------
MyFrame::MyFrame()
: wxFrame(NULL, wxID_ANY, _T(""), wxDefaultPosition, wxDefaultSize, wxCAPTION|wxSYSTEM_MENU|wxCLOSE_BOX)
{

}

MyFrame* MyFrame::CreateAddPanel ( spcore::IComponent& component )
{
	MyFrame* mf= new MyFrame;
	wxBoxSizer* sizer= new wxBoxSizer(wxVERTICAL);
	mf->SetSizer(sizer);
	wxWindow* pan= component.GetGUI(mf);
	if (!pan) {
		delete mf;
		return NULL;
	}
	sizer->Add (static_cast<wxWindow*>(pan), 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 0);
	mf->GetSizer()->SetSizeHints(mf);	// Fit to content

	return mf;
}

// ----------------------------------------------------------------------------
// the application class
// ----------------------------------------------------------------------------

TestWXApp::TestWXApp() {
}

/*
  Initialisation for TestWXApp

  Return true to signal correct initialization or false when error
 */
bool TestWXApp::OnInit()
{
#if wxUSE_XPM
	wxImage::AddHandler(new wxXPMHandler);
#endif
#if wxUSE_LIBPNG
	wxImage::AddHandler(new wxPNGHandler);
#endif
#if wxUSE_LIBJPEG
	wxImage::AddHandler(new wxJPEGHandler);
#endif
#if wxUSE_GIF
	wxImage::AddHandler(new wxGIFHandler);
#endif

#if defined(WIN32)
	// Uncomment this to enable a console in Windows for debug purposes
	//AllocConsole(); freopen("CONOUT$", "wb", stdout);
#endif

	ICoreRuntime* cr= getSpCoreRuntime();

	int retval= cr->LoadModule("mod_camera");
	DumpCoreRuntime(cr);
	if (retval!= 0)
		ExitErr("error loading mod_camera");


	// Create camera_config component
	m_comp= cr->CreateComponent ("camera_config", "testcomponent", 0, NULL);
	if (!m_comp.get())
		ExitErr("error cannot create component");


	// Create dialog
	MyFrame* mf= MyFrame::CreateAddPanel ( *m_comp );
	if (!mf) ExitErr("error error creating pannel");

	mf->Show();

	return true;
}


/*!
  Cleanup for TestWXApp
 */

int TestWXApp::OnExit()
{
	return wxApp::OnExit();
}

// ----------------------------------------------------------------------------
// main
// ----------------------------------------------------------------------------

int main(int argc, char *argv[]) {

#if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXX11__)
	// Under X11 it's necessary enable threading support
	if ( XInitThreads() == 0 ) {
		ExitErr("Unable to initialize multithreaded X11 code (XInitThreads failed)");
		exit( EXIT_FAILURE );
	}
#endif

	// Initialize spcore
	ICoreRuntime* cr= getSpCoreRuntime();
	if (!cr) return false;

	// Run wxWidgets message pump
	wxEntry(argc, argv);

	// Free spcore
	freeSpCoreRuntime();

	// If execution reaches this => all tests ok
	return 0;
}
