CAutoConnector::CAutoConnector() {
	 write_log(preferences.debug_autoconnector(), "[CAutoConnector] CAutoConnector()\n");
  CString MutexName = preferences.mutex_name() + "AutoConnector";
	_autoconnector_mutex = new CMutex(false, MutexName);
  p_sharedmem->MarkPokerWindowAsUnAttached();
	set_attached_hwnd(NULL);
}
CAutoConnector::~CAutoConnector() {
	// Releasing the mutex in case we hold it.
	// If we don't hold it, Unlock() will "fail" silently.
	 write_log(preferences.debug_autoconnector(), "[CAutoConnector] ~CAutoConnector()\n");
	_autoconnector_mutex->Unlock();
	if (_autoconnector_mutex != NULL)	{
     write_log(preferences.debug_autoconnector(), "[CAutoConnector] ~CAutoConnector() Deleting auto-connector-mutex\n");
		delete _autoconnector_mutex;
		_autoconnector_mutex = NULL;
	}
	 write_log(preferences.debug_autoconnector(), "[CAutoConnector] ~CAutoConnector() Marking table as not atached\n");
	p_sharedmem->MarkPokerWindowAsUnAttached();
	set_attached_hwnd(NULL);
	 write_log(preferences.debug_autoconnector(), "[CAutoConnector] ~CAutoConnector() Finished\n");
}
void CAutoConnector::Disconnect() {
	write_log(preferences.debug_autoconnector(), "[CAutoConnector] Disconnect()\n");

  // First close scraper-output-dialog,
  // as an updating dialog without a connected table can crash.
  CDlgScraperOutput::DestroyWindowSafely();

	// Wait for mutex - "forever" if necessary, as we have to clean up.
	ASSERT(_autoconnector_mutex->m_hObject != NULL); 
	write_log(preferences.debug_autoconnector(), "[CAutoConnector] Locking autoconnector-mutex\n");
	_autoconnector_mutex->Lock(INFINITE);

	// Make sure autoplayer is off
	write_log(preferences.debug_autoconnector(), "[CAutoConnector] Stopping autoplayer\n");
	p_autoplayer->EngageAutoplayer(false);

	p_engine_container->ResetOnDisconnection();

	// Send "disconnect" to scraper DLL, if loaded
	if (theApp._dll_scraper_process_message)
		(theApp._dll_scraper_process_message) ("disconnect", NULL);

	theApp.UnloadScraperDLL();

	// Clear "attached" info
	set_attached_hwnd(NULL);

	// Unattach OH.
	p_flags_toolbar->UnattachOHFromPokerWindow();
	p_flags_toolbar->ResetButtonsOnDisconnect();

	// Mark table as not attached
	write_log(preferences.debug_autoconnector(), "[CAutoConnector] Marking table as not attached\n");
	p_sharedmem->MarkPokerWindowAsUnAttached();

	// Release mutex as soon as possible, after critical work is done
	write_log(preferences.debug_autoconnector(), "[CAutoConnector] Unlocking autoconnector-mutex\n");
	_autoconnector_mutex->Unlock();	

	// Delete bitmaps
	p_scraper->DeleteBitmaps();

	// Clear scraper fields
	p_table_state->Reset();

	// Reset symbols
	p_engine_container->ResetOnConnection();

	write_log(preferences.debug_autoconnector(), "[CAutoConnector] ResetOnConnection executed (disconnection)\n");
	write_log(preferences.debug_autoconnector(), "[CAutoConnector] Going to continue with window title\n");

	// Change window title
	p_openholdem_title->UpdateTitle();

	// Reset Display 
	PMainframe()->ResetDisplay();

	// Reset "ScraperOutput" dialog, if it is live
	if (m_ScraperOutputDlg)	{
		m_ScraperOutputDlg->Reset();
	}
	WriteLogTableReset();

	// Close OH, when table disappears and leaving enabled in preferences.
	if (preferences.autoconnector_close_when_table_disappears()) {
		PostQuitMessage(0);
	}
	write_log(preferences.debug_autoconnector(), "[CAutoConnector] Disconnect done\n");
}
bool CAutoConnector::Connect(HWND targetHWnd) {
	int					N = 0, line = 0, ret = 0;
	char				title[MAX_WINDOW_TITLE] = {0};
	int					SelectedItem = -1;
	CString			current_path = "";
	BOOL				bFound = false;
	CFileFind   hFile;

	write_log(preferences.debug_autoconnector(), "[CAutoConnector] Connect(..)\n");

	ASSERT(_autoconnector_mutex->m_hObject != NULL); 
	write_log(preferences.debug_autoconnector(), "[CAutoConnector] Locking autoconnector-mutex\n");
	if (!_autoconnector_mutex->Lock(500))	{
		write_log(preferences.debug_autoconnector(), "[CAutoConnector] Could not grab mutex; early exit\n");
		return false; 
	}
  // Clear global list for holding table candidates
	g_tlist.RemoveAll();
	write_log(preferences.debug_autoconnector(), "[CAutoConnector] Number of tablemaps loaded: %i\n",
    p_tablemap_loader->NumberOfTableMapsLoaded());
	for (int tablemap_index=0; tablemap_index<p_tablemap_loader->NumberOfTableMapsLoaded(); tablemap_index++) {
		write_log(preferences.debug_autoconnector(), "[CAutoConnector] Going to check TM nr. %d out of %d\n", 
			tablemap_index, p_tablemap_loader->NumberOfTableMapsLoaded());
		Check_TM_Against_All_Windows_Or_TargetHWND(tablemap_index, targetHWnd);
	}
	
	// Put global candidate table list in table select dialog variables
	N = (int) g_tlist.GetSize();
  write_log(preferences.debug_autoconnector(), "[CAutoConnector] Number of table candidates> %i\n", N);
	if (N == 0) {
		FailedToConnectBecauseNoWindowInList();
	}	else 	{
		SelectedItem = SelectTableMapAndWindow(N);
		if (SelectedItem == k_undefined) {
			FailedToConnectProbablyBecauseAllTablesAlreadyServed();
		}	else {
			write_log(preferences.debug_autoconnector(), "[CAutoConnector] Window [%d] selected\n", g_tlist[SelectedItem].hwnd);
			p_sharedmem->MarkPokerWindowAsAttached(g_tlist[SelectedItem].hwnd);
			write_log(preferences.debug_autoconnector(), "[CAutoConnector] Window marked at shared memory\n");

			// Load correct tablemap, and save hwnd/rect/numchairs of table that we are "attached" to
			set_attached_hwnd(g_tlist[SelectedItem].hwnd);
			assert(p_tablemap != NULL);
			CString tablemap_to_load = g_tlist[SelectedItem].path.GetString();
			write_log(preferences.debug_autoconnector(), "[CAutoConnector] Selected tablemap: %s\n", tablemap_to_load);
			p_tablemap->LoadTablemap(tablemap_to_load);
			write_log(preferences.debug_autoconnector(), "[CAutoConnector] Tablemap loaded\n");

			// Create bitmaps
			p_scraper->CreateBitmaps();
			write_log(preferences.debug_autoconnector(), "[CAutoConnector] Scraper-bitmaps created\n");

			// Clear scraper fields
			p_table_state->Reset();
			write_log(preferences.debug_autoconnector(), "[CAutoConnector] Table state cleared\n");

			// Reset symbols
			p_engine_container->ResetOnConnection();

			write_log(preferences.debug_autoconnector(), "[CAutoConnector] ResetOnConnection executed (during connection)\n");
			write_log(preferences.debug_autoconnector(), "[CAutoConnector] Going to continue with scraper output and scraper DLL\n");

			// Reset "ScraperOutput" dialog, if it is live
			if (m_ScraperOutputDlg) {
				m_ScraperOutputDlg->Reset();
			}

			LoadScraperDLL();
			p_flags_toolbar->ResetButtonsOnConnect();

			// Send "connect" and HWND to scraper DLL, if loaded
			if (theApp._dll_scraper_process_message) {
				(theApp._dll_scraper_process_message) ("connect", &_attached_hwnd);
      }

			p_scraper_access->InitOnConnect();
			// Reset display
			PMainframe()->ResetDisplay();

			// log OH title bar text and table reset
			::GetWindowText(_attached_hwnd, title, MAX_WINDOW_TITLE);
      WriteLogTableReset();

			p_table_positioner->PositionMyWindow();
			p_autoplayer->EngageAutoPlayerUponConnectionIfNeeded();
		}
	}
	write_log(preferences.debug_autoconnector(), "[CAutoConnector] Unlocking autoconnector-mutex\n");
	_autoconnector_mutex->Unlock();
	return (SelectedItem != -1);
}