// generated 2002/10/6 15:34:21 CEST by triendl.kj@triendl.kj.(none)
// using glademm V1.1.1c_cvs
//
// newer (non customized) versions of this file go to CDlgAuthentication.cc_new

// This file is for your program, I won't touch it again!

#include "config.h"
#include "CFireFlierClientApp.hh"
#include "CDlgAuthentication.hh"
#include "gtkmm/messagedialog.h"
#if FF_DEBUG
#include <iostream>
using namespace std;
#endif


CDlgAuthentication::CDlgAuthentication()
	: Gtk::Window()
{
	initGUI();

	ffIO.networkThread.signal_Connection().connect(m_signalConnection.slot());
	ffIO.networkThread.signal_Authentication().connect(m_signalAuthentication.slot());
	ffIO.networkThread.signal_error().connect(m_signalNetworkThreadError.slot());

	m_signalConnection.connect(SigC::slot(*this, &CDlgAuthentication::on_Connection));
	m_signalAuthentication.connect(SigC::slot(*this, &CDlgAuthentication::on_Authentication));
	m_signalNetworkThreadError.connect(SigC::slot(*this, &CDlgAuthentication::on_networkthread_error));

	if (connected)
		m_pStatusbar->push(strConnection);
	else
		m_pStatusbar->push(strConnecting);
}

void CDlgAuthentication::initGUI() 
{  
	m_pStatusbar = manage(new Gtk::Statusbar);
	Gtk::Label *labelUser = manage(new class Gtk::Label("_User", Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, true));
	m_entryUser = manage(new class Gtk::Entry());
	
	Gtk::Label *labelPwd = manage(new class Gtk::Label("_Password", Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, true));
	m_entryPwd = manage(new class Gtk::Entry());
	
	Gtk::Table *table1 = manage(new class Gtk::Table(2, 2, false));
	m_butOk = manage(new class Gtk::Button(Gtk::Stock::OK));
	m_butOk->set_flags(Gtk::CAN_FOCUS|Gtk::CAN_DEFAULT|Gtk::HAS_DEFAULT);
	Gtk::Button *butCancel = manage(new class Gtk::Button(Gtk::Stock::CANCEL));
	Gtk::HButtonBox *hbuttonbox1 = manage(new class Gtk::HButtonBox(Gtk::BUTTONBOX_DEFAULT_STYLE, 0));
	Gtk::VBox *vbox8 = manage(new class Gtk::VBox(false, 0));
	labelUser->set_line_wrap(false);
	labelUser->set_mnemonic_widget(*m_entryUser);
	m_entryUser->set_flags(Gtk::CAN_FOCUS);
	m_entryUser->set_activates_default();
	m_entryUser->set_editable(true);
	m_entryUser->set_text(Glib::get_user_name());
	m_entryUser->select_region(0, -1);
	labelPwd->set_line_wrap(false);
	labelPwd->set_mnemonic_widget(*m_entryPwd);
	m_entryPwd->set_flags(Gtk::CAN_FOCUS);
	m_entryPwd->set_activates_default();
	m_entryPwd->set_editable(true);
	m_entryPwd->set_visibility(false);
	m_entryPwd->set_text("");
	table1->set_border_width(5);
	table1->set_row_spacings(5);
	table1->set_col_spacings(5);
	table1->attach(*labelUser, 0, 1, 0, 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0);
	table1->attach(*m_entryUser, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::AttachOptions(), 0, 0);
	table1->attach(*labelPwd, 0, 1, 1, 2, Gtk::FILL, Gtk::AttachOptions(), 0, 0);
	table1->attach(*m_entryPwd, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::AttachOptions(), 0, 0);
	m_butOk->set_sensitive(false);
	m_butOk->set_relief(Gtk::RELIEF_NORMAL);
	butCancel->set_flags(Gtk::CAN_FOCUS);
	butCancel->set_relief(Gtk::RELIEF_NORMAL);
	hbuttonbox1->set_border_width(5);
	hbuttonbox1->pack_start(*m_butOk);
	hbuttonbox1->pack_start(*butCancel);
	vbox8->pack_start(*table1, Gtk::PACK_SHRINK);
	vbox8->pack_start(*hbuttonbox1, Gtk::PACK_SHRINK);
	vbox8->pack_start(*m_pStatusbar);
	add(*vbox8);
	m_entryPwd->grab_focus();
	m_butOk->grab_default();

	set_title(strAppTitle+"::Authentication");
	set_modal();
	set_position(Gtk::WIN_POS_MOUSE);
	set_resizable(false);
	
	show_all_children();

	m_entryUser->signal_changed().connect(SigC::slot(*this, &CDlgAuthentication::on_entry_changed), true);
	m_entryPwd->signal_changed().connect(SigC::slot(*this, &CDlgAuthentication::on_entry_changed), true);
	m_butOk->signal_clicked().connect(SigC::slot(*this, &CDlgAuthentication::on_butOk_clicked));
	butCancel->signal_clicked().connect(SigC::slot(*this, &CDlgAuthentication::hide));
}

void CDlgAuthentication::on_Connection(bool bConnected)
{
#if FF_DEBUG
	cout << "CDlgAuthentication::on_Connection()::bConnected" << bConnected << endl;
#endif
	if (bConnected)
	{
		connected = true;
		m_pStatusbar->pop();
		m_pStatusbar->push(strConnection);
		on_entry_changed();
	}
	else
	{
		m_pStatusbar->pop();
		m_pStatusbar->push(strNoConnection);
		Gtk::MessageDialog dlg(*this, ustring("connecting to fireflier-server failed"), Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
		dlg.run();
		hide();
	}
}


void CDlgAuthentication::on_Authentication(int nAuthenticated)
{
	switch (nAuthenticated)
	{
		case 1:
			hide();
			break;
		case 2:
		{
			Gtk::MessageDialog dlg(*this, ustring("somebody else is already logged in, please try again later."), Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
			dlg.run();
			hide();
		}
			break;
		default:
		{
			Gtk::MessageDialog dlg(*this, ustring("login failed"), Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
			dlg.run();
		}
	}
}

void CDlgAuthentication::on_networkthread_error(CffIO::pCffIOError pErr, bool bDisconnected)
{
	if (bDisconnected)
	{
		connected = false;
		m_pStatusbar->pop();
		m_pStatusbar->push(strNoConnection);
		on_entry_changed();
		if (is_visible())
		{
			Gtk::MessageDialog dlg(*this, "connection to fireflier-server lost.\ndo you want to connect again now?", Gtk::MESSAGE_ERROR, Gtk::BUTTONS_YES_NO, true);
			int nResult = dlg.run();
			//dlg.hide();
			if (nResult == Gtk::RESPONSE_YES)
				ffIO.networkThread.start();
		}
	}
}

void CDlgAuthentication::on_butOk_clicked()
{  
	if (connected)
	{
		m_pStatusbar->pop();
		m_pStatusbar->push(strWait4Auth);
#if FF_DEBUG
		cerr << "wait for authentication" << endl;
#endif
		try
		{
			ffIO << CCO_Login(m_entryUser->get_text(), m_entryPwd->get_text());
		
			// not needed anymore:
			// tell network thread that ssl_write has finished
			//ffIO.networkThread.m_semWait.post();
		}
		catch (...)
		{
		}
	}
}

void CDlgAuthentication::on_entry_changed()
{
	bool bSensitive = (connected);// && m_entryUser->get_text_length() && m_entryPwd->get_text_length());
	m_butOk->set_sensitive(bSensitive);
}


bool CDlgAuthentication::on_idle()
{
	// tell the network thread that we are ready
	// otherwise the on_Connection signal comes too early and there are
	// problems then with the gui
	ffIO.networkThread.m_semWait.post();
	return false; // disconnect from idle signal
}

void CDlgAuthentication::run()
{
	on_entry_changed();
	Glib::signal_idle().connect(SigC::slot(*this, &CDlgAuthentication::on_idle));
	if (!ffIO.networkThread.isRunning())
	{
#if FF_DEBUG
		cout << "starting network thread" << endl;
#endif
		ffIO.networkThread.start();
	}
#if FF_DEBUG
	else
		cout << "networkThread still running" << endl;
#endif
#ifdef WITHGNOME
	Gnome::Main::run(*this);
#else
	Gtk::Main::run(*this);
#endif
}
