// Listing 9.10. Kod źródłowy obiektu WxMoviePlayer z pliku WxMoviePlayer.cpp
//
#include "WxMoviePlayer.hpp"
BEGIN_EVENT_TABLE( WxMoviePlayer, wxWindow )
  EVT_PAINT( WxMoviePlayer::OnPaint )
  EVT_TIMER( TIMER_ID, WxMoviePlayer::OnTimer )
  EVT_CHAR( WxMoviePlayer::OnKey )
END_EVENT_TABLE()

// Najpierw definiujemy funkcje zwrotne, które będą powiązane z poszczególnymi
// zdarzeniami. Robimy to za pośrednictwem makr dostarczanych przez bibliotekę wxWidgets.
WxMoviePlayer::WxMoviePlayer(
  wxWindow*      parent,
  const wxPoint& pos,
  const wxSize&  size
) : wxWindow( parent, -1, pos, size, wxSIMPLE_BORDER ) {
  m_timer         = NULL;
  m_parent        = parent;
}

// Będziemy musieli wiedzieć, którą ramką jest rodzic, kiedy będziemy chcieli zamknąć aplikację w odpowiedzi na naciśnięcie klawisza Esc.
void WxMoviePlayer::OnPaint( wxPaintEvent& event ) {
	wxPaintDC dc( this );
	if( !dc.Ok() ) return;
	int x,y,w,h;
	dc.BeginDrawing();
	dc.GetClippingBox( &x, &y, &w, &h );
	dc.DrawBitmap( m_wx_bmp, x, y );
	dc.EndDrawing();
	return;
}

// Metoda WxMoviePlayer::_copyImage() będzie wywoływana za każdym razem, gdy z obiektu cv::VideoCapture zostanie wczytany nowy obraz.
void WxMoviePlayer::_copyImage( void ) {
	m_wx_bmp = wxBitmap( m_wx_img );
	Refresh( FALSE ); // wskazuje, że obiekt jest nieczysty
	Update();
}

// Metoda WxMoviePlayer::open() także wykonuje kilka ważnych czynności.Najpierw
// otwiera obiekt cv::VideoCapture, ale to nie wszystko.Następnie wczytuje obraz
// z odtwarzacza i przy jego użyciu tworzy obiekt wxImage „wskazujący” obraz OpenCV
// cv::Mat.Jest to odwrotne podejście niż to, które zastosowaliśmy w przykładzie
// dotyczącym Qt : w tym przypadku nieco wygodniej jest nam najpierw utworzyć obiekt
// cv::Mat i przekazać mu dane, a potem utworzyć obiekt obrazu biblioteki GUI i uczynić
// go tylko nagłówkiem istniejących danych.

bool WxMoviePlayer::open( wxString file ) {
	
	if( !m_cap.open( std::string( file.mb_str() ) )) {
	return false;
	}

	// jeśli menu jest otwarte, definiujemy wszystkie ustawienia:
	//
	m_cap.read( m_cv_img );
	m_wx_img = wxImage(
	m_cv_img.cols,
	m_cv_img.rows,
	m_cv_img.data,
	TRUE // statyczne dane, nie usuwać w delete()
	);
	_copyImage();
	m_timer = new wxTimer( this, TIMER_ID );
	m_timer->Start( 1000. / m_cap.get( cv::CAP_PROP_FPS ) );
	return true;
}

//Procedura ta nie ma zbyt wiele pracy. Jej głównym zadaniem 
// jest wczytanie nowej klatki filmu, przekonwertowanie jej 
// z formatu BGR na RGB, a następnie wywołanie funkcji 
// WxMoviePlayer::_copyImage(), która tworzy kolejną mapę bitową.
void WxMoviePlayer::OnTimer( wxTimerEvent& event ) {
	if( !m_cap.isOpened() ) return;
	m_cap.read( m_cv_img );
	cv::cvtColor( m_cv_img, m_cv_img, cv::BGR2RGB );
	_copyImage();
}

// obsługa naciśnięć klawiszy
void WxMoviePlayer::OnKey( wxKeyEvent& e ) {
	if( e.GetKeyCode() == WXK_ESCAPE ) m_parent->Close();
}
