/*
** 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 1, 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, write to the Free Software
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/*
 * Author : Alexandre Parenteau <aubonbeurre@hotmail.com> --- December 1997
 */

// GetPrefs.cpp : implementation file
//

#include "stdafx.h"

#ifdef qMacCvsPP
#	include <UModalDialogs.h>
#	include <LMultiPanelView.h>
#	include <LPopupGroupBox.h>

#	include "MacCvsApp.h"
#	include "MacBinEncoding.h"
#	include "uwidget.h"
#endif /* qMacCvsPP */

#if qUnix
#	include "UCvsDialogs.h"
#endif

#ifdef WIN32
#	include "wincvs.h"
#	include "umain.h"
#	include <afxdao.h>
#endif /* WIN32 */

#include "GetPrefs.h"
#include "CvsPrefs.h"
#include "Authen.h"
#include "AppConsole.h"
#include "PromptFiles.h"
#include "MultiFiles.h"
#include "CvsArgs.h"
#include "FileTraversal.h"
#include "MakeSurePathExists.h"

#ifdef WIN32

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// CVSROOT page
IMPLEMENT_DYNCREATE(CGetPrefs_CVSROOT, CPropertyPage)

CGetPrefs_CVSROOT::CGetPrefs_CVSROOT() : CPropertyPage(CGetPrefs_CVSROOT::IDD), m_didInteract(false)
{
	//{{AFX_DATA_INIT(CGetPrefs_CVSROOT)
	m_cvsroot = (const char *)gCvsPrefs;
	m_cvsvers = gCvsPrefs.CvsVersion();
	m_cvsconsole = gCvsPrefs.CvsConsole();
	m_authen = gAuthen.kind();
	m_host = _T("");
	m_login = _T("");
	m_path = _T("");
	//}}AFX_DATA_INIT
	m_flag = false;
}

CGetPrefs_CVSROOT::~CGetPrefs_CVSROOT()
{
}

BOOL CGetPrefs_CVSROOT::OnInitDialog()
{
	CDialog::OnInitDialog();
	CenterWindow();

	for(int i =0; i < NUM_CVSROOT; i++)
	{
		const CPStr & strroot =
			(*(const CvsPrefs *)&gCvsPrefs).get_cvsroot_list(i);
		if(!strroot.empty())
			m_ctrlroot.InsertString(-1, (const char *)strroot);
	}

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CGetPrefs_CVSROOT::DoDataExchange(CDataExchange* pDX)
{
	m_didInteract = true;

	CPropertyPage::DoDataExchange(pDX);

	//{{AFX_DATA_MAP(CGetPrefs_CVSROOT)
	DDX_Control(pDX, IDC_CVSVERS, m_combovers);
	DDX_Control(pDX, IDC_AUTHEN, m_comboauthen);
	DDX_Control(pDX, IDC_COMBOROOT, m_ctrlroot);
	DDX_CBString(pDX, IDC_COMBOROOT, m_cvsroot);
	DDV_MinChars(pDX, m_cvsroot, 1);
	DDX_Text(pDX, IDC_HOST, m_host);
	DDX_Text(pDX, IDC_LOGIN, m_login);
	DDX_Text(pDX, IDC_PATH, m_path);
	DDX_Check(pDX, IDC_CONSOLE, m_cvsconsole);
	//}}AFX_DATA_MAP
	DDV_CheckCVSROOT( pDX, m_cvsroot );	//it is out here to avoid the class wizard parsing error

	if(pDX->m_bSaveAndValidate)
	{
		CString theUser, theHost, thePath;

		GetDlgItem(IDC_PATH)->GetWindowText(thePath);
		GetDlgItem(IDC_HOST)->GetWindowText(theHost);
		GetDlgItem(IDC_LOGIN)->GetWindowText(theUser);

		UStr root;
		if(m_authen != local)
		{
			root << theUser;
			root << '@';
			root << theHost;
			root << ':';
			root << thePath;
		}
		else
			root = thePath;
		
		m_cvsroot = root;
		m_cvsvers = m_combovers.GetCurSel();
	}
	else
	{	
		m_combovers.SetCurSel(m_cvsvers);

		m_comboauthen.ResetContent();
		std::vector<AuthenModel *> & allAuthen = AuthenModel::GetAllInstances();
		std::vector<AuthenModel *>::iterator j;
		for(j = allAuthen.begin(); j != allAuthen.end(); ++j)
		{
			m_comboauthen.InsertString(-1, (*j)->GetToken());
		}
		
		AuthenModel *model = AuthenModel::GetInstance(m_authen);
		m_comboauthen.SetCurSel(Authen::kindToNum(m_authen));

		FillFields();
		OnSelchangeAuthen();
	}
}

void CGetPrefs_CVSROOT::StoreValues()
{
	if(!m_didInteract)
		return;

	gCvsPrefs = (const char *)m_cvsroot;
	gAuthen.setkind(m_authen);
	gCvsPrefs.SetCvsVersion(m_cvsvers);
	gCvsPrefs.SetCvsConsole(m_cvsconsole != 0);
}

void CGetPrefs_CVSROOT::OnSelchangeAuthen() 
{
	m_authen = Authen::numToKind(m_comboauthen.GetCurSel());

	AuthenModel *model = AuthenModel::GetInstance(m_authen);

	GetDlgItem(IDC_HOST)->EnableWindow(model->HasHost());
	GetDlgItem(IDC_LOGIN)->EnableWindow(model->HasUser());
	GetDlgItem(IDC_SETTINGS)->EnableWindow(model->HasSettings());
	
	if(!model->HasHost())
		GetDlgItem(IDC_HOST)->SetWindowText("");
	if(!model->HasUser())
		GetDlgItem(IDC_LOGIN)->SetWindowText("");

	UStr desc;
	model->GetSettingsDesc(desc);
	GetDlgItem(IDC_AUTHENDESC)->SetWindowText(desc);
	
	// ntserver
	// the default *is* ntserver now
	// TODO : something more elaborated that is querying cvs
#if 0
	if(m_authen == ntserver && m_combovers.GetCurSel() != 1)
	{
		AfxMessageBox("For the ntserver support, you got to switch the cvs used from"
			" \"cvs-1.10 (Standard)\" to \"cvs-1.10 (NT server)\". Check"
			" http://www.cvsnt.org for more informations."
			, MB_ICONEXCLAMATION | MB_OK);
	}
#endif
}

void CGetPrefs_CVSROOT::OnChangePath() 
{
	OnChangeFields();
}

void CGetPrefs_CVSROOT::OnChangeHost() 
{
	OnChangeFields();
}

void CGetPrefs_CVSROOT::OnChangeLogin() 
{
	OnChangeFields();
}

void CGetPrefs_CVSROOT::OnSettings() 
{
	AuthenModel *model = AuthenModel::GetInstance(m_authen);
	model->DoSettings();
	UStr desc;
	model->GetSettingsDesc(desc);
	GetDlgItem(IDC_AUTHENDESC)->SetWindowText(desc);
}

void CGetPrefs_CVSROOT::FillFields(void)
{
	UStr theMethod, theUser, theHost, thePath;
	USemaphore policeman(m_flag);
	if(policeman.IsEnteredTwice())
		return;

	UStr root;
	root = gAuthen.token();
	root << Authen::skiptoken(m_cvsroot);

	if(Authen::parse_cvsroot(root, theMethod, theUser, theHost, thePath))
	{
		GetDlgItem(IDC_PATH)->SetWindowText(thePath);
		GetDlgItem(IDC_HOST)->SetWindowText(theHost);
		GetDlgItem(IDC_LOGIN)->SetWindowText(theUser);
	}
}

void CGetPrefs_CVSROOT::OnEditchangeComboroot() 
{
	m_ctrlroot.GetWindowText(m_cvsroot);
	FillFields();
}

void CGetPrefs_CVSROOT::OnChangeFields(void)
{
	USemaphore policeman(m_flag);
	if(policeman.IsEnteredTwice())
		return;

	CString theUser, theHost, thePath;

	GetDlgItem(IDC_PATH)->GetWindowText(thePath);
	GetDlgItem(IDC_HOST)->GetWindowText(theHost);
	GetDlgItem(IDC_LOGIN)->GetWindowText(theUser);
	
	m_cvsroot = "";
	AuthenModel *model = AuthenModel::GetInstance(m_authen);
	if(model->HasUser())
		m_cvsroot += theUser;
	if(model->HasHost())
	{
		m_cvsroot += '@';
		m_cvsroot += theHost;
	}
	if(model->HasUser() || model->HasHost())
		m_cvsroot += ':';
	m_cvsroot += thePath;

	m_ctrlroot.SetWindowText(m_cvsroot);
}

void CGetPrefs_CVSROOT::OnSelchangeComboroot() 
{
	int nCurSel = m_ctrlroot.GetCurSel();
	m_ctrlroot.GetLBText(nCurSel, m_cvsroot);
	FillFields();
}

BEGIN_MESSAGE_MAP(CGetPrefs_CVSROOT, CPropertyPage)
	//{{AFX_MSG_MAP(CGetPrefs_CVSROOT)
	ON_CBN_SELCHANGE(IDC_AUTHEN, OnSelchangeAuthen)
	ON_EN_CHANGE(IDC_PATH, OnChangePath)
	ON_EN_CHANGE(IDC_HOST, OnChangeHost)
	ON_EN_CHANGE(IDC_LOGIN, OnChangeLogin)
	ON_BN_CLICKED(IDC_SETTINGS, OnSettings)
	ON_CBN_SELCHANGE(IDC_COMBOROOT, OnSelchangeComboroot)
	ON_CBN_EDITCHANGE(IDC_COMBOROOT, OnEditchangeComboroot)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

// Globals options page
IMPLEMENT_DYNCREATE(CGetPrefs_GLOBALS, CPropertyPage)

CGetPrefs_GLOBALS::CGetPrefs_GLOBALS() : CPropertyPage(CGetPrefs_GLOBALS::IDD), m_didInteract(false)
{
	//{{AFX_DATA_INIT(CGetPrefs_GLOBALS)
	m_checkoutro = gCvsPrefs.CheckoutRO();
	m_prune = gCvsPrefs.PruneOption();
	m_tcpip = gCvsPrefs.Z9Option();
	m_quiet = gCvsPrefs.QuietOption();
	m_cntladd = gCvsPrefs.AddControl();
	m_dirty = gCvsPrefs.DirtySupport();
	m_alwaysroot = gCvsPrefs.AlwaysUseCvsroot();
	m_logout = gCvsPrefs.LogoutTimeOut() > 0;
	m_editlogout = gCvsPrefs.LogoutTimeOut();
	m_unixlf = gCvsPrefs.UnixLF();
	m_zlevel = gCvsPrefs.ZLevel();
	//}}AFX_DATA_INIT
}

CGetPrefs_GLOBALS::~CGetPrefs_GLOBALS()
{
}

void CGetPrefs_GLOBALS::DoDataExchange(CDataExchange* pDX)
{
	m_didInteract = true;

	CPropertyPage::DoDataExchange(pDX);

	//{{AFX_DATA_MAP(CGetPrefs_GLOBALS)
	DDX_Control(pDX, IDC_ZSPIN, m_zspin);
	DDX_Control(pDX, IDC_SPINLOGOUT, m_spin);
	DDX_Check(pDX, IDC_CHECKOUTRO, m_checkoutro);
	DDX_Check(pDX, IDC_PRUNE, m_prune);
	DDX_Check(pDX, IDC_TCPIP, m_tcpip);
	DDX_Check(pDX, IDC_QUIET, m_quiet);
	DDX_Check(pDX, IDC_CTNLADD, m_cntladd);
	DDX_Check(pDX, IDC_DIRTYSUPPORT, m_dirty);
	DDX_Check(pDX, IDC_ALWAYSROOT, m_alwaysroot);
	DDX_Check(pDX, IDC_LOGOUT, m_logout);
	DDX_Text(pDX, IDC_EDITLOGOUT, m_editlogout);
	DDV_MinMaxUInt(pDX, m_editlogout, 0, 999999);
	DDX_Check(pDX, IDC_CHECKUNIXLF, m_unixlf);
	DDX_Text(pDX, IDC_ZLEVEL, m_zlevel);
	DDV_MinMaxUInt(pDX, m_zlevel, 1, 9);
	//}}AFX_DATA_MAP

	if(!pDX->m_bSaveAndValidate)
	{
		m_spin.SetBase(10);
		m_spin.SetRange(0, 30000);
		m_spin.SetBuddy(GetDlgItem(IDC_EDITLOGOUT));

		m_zspin.SetBase(1);
		m_zspin.SetRange(1, 9);
		m_zspin.SetBuddy(GetDlgItem(IDC_ZLEVEL));

		OnTcpip();
		OnLogout();
	}
}

void CGetPrefs_GLOBALS::StoreValues()
{
	if(!m_didInteract)
		return;

	gCvsPrefs.SetCheckoutRO(m_checkoutro ? true : false);
	gCvsPrefs.SetPruneOption(m_prune ? true : false);
	gCvsPrefs.SetZ9Option(m_tcpip ? true : false);
	gCvsPrefs.SetQuietOption(m_quiet ? true : false);
	gCvsPrefs.SetAddControl(m_cntladd ? true : false);
	gCvsPrefs.SetDirtySupport(m_dirty ? true : false);
	gCvsPrefs.SetAlwaysUseCvsroot(m_alwaysroot ? true : false);
	gCvsPrefs.SetLogoutTimeOut(m_logout ? (int)m_editlogout : 0);
	gCvsPrefs.SetUnixLF(m_unixlf != 0);
	gCvsPrefs.SetZLevel(m_zlevel);
}

BEGIN_MESSAGE_MAP(CGetPrefs_GLOBALS, CPropertyPage)
	//{{AFX_MSG_MAP(CGetPrefs_GLOBALS)
	ON_BN_CLICKED(IDC_LOGOUT, OnLogout)
	ON_BN_CLICKED(IDC_CHECKUNIXLF, OnCheckunixlf)
	ON_BN_CLICKED(IDC_TCPIP, OnTcpip)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CGetPrefs_GLOBALS::OnTcpip() 
{
	CButton* but = (CButton *)GetDlgItem(IDC_TCPIP);
	CWnd* wnd = (CButton *)GetDlgItem(IDC_ZLEVEL);
	wnd->EnableWindow(but->GetCheck() == 1);
	wnd = (CButton *)GetDlgItem(IDC_ZSPIN);
	wnd->EnableWindow(but->GetCheck() == 1);
}

void CGetPrefs_GLOBALS::OnLogout() 
{
	CButton* but = (CButton *)GetDlgItem(IDC_LOGOUT);
	CWnd* wnd = (CButton *)GetDlgItem(IDC_EDITLOGOUT);
	wnd->EnableWindow(but->GetCheck() == 1);
	wnd = (CButton *)GetDlgItem(IDC_SPINLOGOUT);
	wnd->EnableWindow(but->GetCheck() == 1);
}

void CGetPrefs_GLOBALS::OnCheckunixlf() 
{
	AfxMessageBox("Be carefull when toggling this option : you *CANNOT* use WinCvs in"
		" both mode. You got to use either one or the other. If you experience some"
		" problems, try to remove the global cvs files (such as .cvspass) because they probably"
		" don't match the new line feeds.", MB_ICONEXCLAMATION | MB_OK);
}

IMPLEMENT_DYNCREATE(CGetPrefs_PORTS, CPropertyPage)

CGetPrefs_PORTS::CGetPrefs_PORTS() : CPropertyPage(CGetPrefs_PORTS::IDD), m_didInteract(false)
{
	//{{AFX_DATA_INIT(CGetPrefs_PORTS)
	m_checkkserver = gCvsPrefs.KserverPort() != -1;
	m_checkpserver = gCvsPrefs.PserverPort() != -1;
	m_checkrhost = gCvsPrefs.RhostPort() != -1;
	m_portkserver = gCvsPrefs.KserverPort() != -1 ? gCvsPrefs.KserverPort() : 0;
	m_portpserver = gCvsPrefs.PserverPort() != -1 ? gCvsPrefs.PserverPort() : 0;
	m_portrhost = gCvsPrefs.RhostPort() != -1 ? gCvsPrefs.RhostPort() : 0;
	m_checksname = gCvsPrefs.ServerName() != 0L;
	m_sname = gCvsPrefs.ServerName() == 0L ? _T("cvs") : gCvsPrefs.ServerName();
	m_checkrsh = gCvsPrefs.RshName() != 0L;
	m_rshname = gCvsPrefs.RshName() == 0L ? _T("ssh") : gCvsPrefs.RshName();
	//}}AFX_DATA_INIT
}

CGetPrefs_PORTS::~CGetPrefs_PORTS()
{
}

void CGetPrefs_PORTS::DoDataExchange(CDataExchange* pDX)
{
	m_didInteract = true;

	CPropertyPage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CGetPrefs_PORTS)
	DDX_Check(pDX, IDC_CHECKKSERVERPORT, m_checkkserver);
	DDX_Check(pDX, IDC_CHECKPSERVERPORT, m_checkpserver);
	DDX_Check(pDX, IDC_CHECKRHOSTPORT, m_checkrhost);
	DDX_Text(pDX, IDC_KSERVERPORT, m_portkserver);
	DDV_MinMaxUInt(pDX, m_portkserver, 0, 999999);
	DDX_Text(pDX, IDC_PSERVERPORT, m_portpserver);
	DDV_MinMaxUInt(pDX, m_portpserver, 0, 999999);
	DDX_Text(pDX, IDC_RHOSTPORT, m_portrhost);
	DDV_MinMaxUInt(pDX, m_portrhost, 0, 999999);
	DDX_Check(pDX, IDC_CHECKSERVERNAME, m_checksname);
	DDX_Text(pDX, IDC_SERVERNAME, m_sname);
	DDX_Check(pDX, IDC_CHECKRSHNAME, m_checkrsh);
	DDX_Text(pDX, IDC_RSHNAME, m_rshname);
	//}}AFX_DATA_MAP

	if(!pDX->m_bSaveAndValidate)
	{
		OnCheckkserverport();
		OnCheckpserverport();
		OnCheckrhostport();
		OnCheckservername();
		OnCheckrshname();
	}
}

BEGIN_MESSAGE_MAP(CGetPrefs_PORTS, CPropertyPage)
	//{{AFX_MSG_MAP(CGetPrefs_PORTS)
	ON_BN_CLICKED(IDC_CHECKKSERVERPORT, OnCheckkserverport)
	ON_BN_CLICKED(IDC_CHECKPSERVERPORT, OnCheckpserverport)
	ON_BN_CLICKED(IDC_CHECKRHOSTPORT, OnCheckrhostport)
	ON_BN_CLICKED(IDC_CHECKSERVERNAME, OnCheckservername)
	ON_BN_CLICKED(IDC_CHECKRSHNAME, OnCheckrshname)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CGetPrefs_PORTS message handlers

void CGetPrefs_PORTS::OnCheckkserverport() 
{
	CButton* but = (CButton *)GetDlgItem(IDC_CHECKKSERVERPORT);
	CWnd* wnd = (CButton *)GetDlgItem(IDC_KSERVERPORT);
	wnd->EnableWindow(but->GetCheck() == 1);
}

void CGetPrefs_PORTS::OnCheckpserverport() 
{
	CButton* but = (CButton *)GetDlgItem(IDC_CHECKPSERVERPORT);
	CWnd* wnd = (CButton *)GetDlgItem(IDC_PSERVERPORT);
	wnd->EnableWindow(but->GetCheck() == 1);
}

void CGetPrefs_PORTS::OnCheckrhostport() 
{
	CButton* but = (CButton *)GetDlgItem(IDC_CHECKRHOSTPORT);
	CWnd* wnd = (CButton *)GetDlgItem(IDC_RHOSTPORT);
	wnd->EnableWindow(but->GetCheck() == 1);
}

void CGetPrefs_PORTS::OnCheckservername() 
{
	CButton* but = (CButton *)GetDlgItem(IDC_CHECKSERVERNAME);
	CWnd* wnd = (CButton *)GetDlgItem(IDC_SERVERNAME);
	wnd->EnableWindow(but->GetCheck() == 1);
}

void CGetPrefs_PORTS::OnCheckrshname() 
{
	CButton* but = (CButton *)GetDlgItem(IDC_CHECKRSHNAME);
	CWnd* wnd = (CButton *)GetDlgItem(IDC_RSHNAME);
	wnd->EnableWindow(but->GetCheck() == 1);
}

void CGetPrefs_PORTS::StoreValues()
{
	if(!m_didInteract)
		return;

	gCvsPrefs.SetKserverPort(m_checkkserver ? (int)m_portkserver : -1);
	gCvsPrefs.SetPserverPort(m_checkpserver ? (int)m_portpserver : -1);
	gCvsPrefs.SetRhostPort(m_checkrhost ? (int)m_portrhost : -1);
	gCvsPrefs.SetServerName(m_checksname ? (const char *)m_sname : 0L);
	gCvsPrefs.SetRshName(m_checkrsh ? (const char *)m_rshname : 0L);
}

/////////////////////////////////////////////////////////////////////////////
// CGetPrefs_PROXY property page

IMPLEMENT_DYNCREATE(CGetPrefs_PROXY, CPropertyPage)

CGetPrefs_PROXY::CGetPrefs_PROXY() : CPropertyPage(CGetPrefs_PROXY::IDD), m_didInteract(false)
{
	//{{AFX_DATA_INIT(CGetPrefs_PROXY)
	m_useproxy = gCvsPrefs.UseProxy();
	m_host = gCvsPrefs.ProxyHost();
	m_port = gCvsPrefs.ProxyPort();
	//}}AFX_DATA_INIT
}

CGetPrefs_PROXY::~CGetPrefs_PROXY()
{
}

void CGetPrefs_PROXY::DoDataExchange(CDataExchange* pDX)
{
	m_didInteract = true;

	CPropertyPage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CGetPrefs_PROXY)
	DDX_Check(pDX, IDC_CHECKPROXY, m_useproxy);
	DDX_Text(pDX, IDC_EDITHOST, m_host);
	DDX_Text(pDX, IDC_EDITPORT, m_port);
	DDV_MinMaxUInt(pDX, m_port, 0, 999999);
	//}}AFX_DATA_MAP
	if(!pDX->m_bSaveAndValidate)
	{
		OnCheckproxy();
	}
}

BEGIN_MESSAGE_MAP(CGetPrefs_PROXY, CPropertyPage)
	//{{AFX_MSG_MAP(CGetPrefs_PROXY)
	ON_BN_CLICKED(IDC_CHECKPROXY, OnCheckproxy)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CGetPrefs_PROXY::OnCheckproxy() 
{
	CButton* but = (CButton *)GetDlgItem(IDC_CHECKPROXY);
	CWnd* wnd = (CButton *)GetDlgItem(IDC_EDITHOST);
	wnd->EnableWindow(but->GetCheck() == 1);
	wnd = (CButton *)GetDlgItem(IDC_EDITPORT);
	wnd->EnableWindow(but->GetCheck() == 1);
}

void CGetPrefs_PROXY::StoreValues()
{
	if(!m_didInteract)
		return;

	gCvsPrefs.SetUseProxy(m_useproxy != 0);
	gCvsPrefs.SetProxyHost(m_host);
	gCvsPrefs.SetProxyPort(m_port);
}

// WinCvs options page
IMPLEMENT_DYNCREATE(CGetPrefs_WINCVS, CPropertyPage)

CGetPrefs_WINCVS::CGetPrefs_WINCVS() : CPropertyPage(CGetPrefs_WINCVS::IDD), m_didInteract(false)
{
	UStr cvsPath;
	//{{AFX_DATA_INIT(CGetPrefs_WINCVS)
	m_viewer = gCvsPrefs.Viewer() != 0L ? gCvsPrefs.Viewer() : "";
	m_diffprog = gCvsPrefs.ExtDiff() != 0L ? gCvsPrefs.ExtDiff() : "";
	m_chkdiff = gCvsPrefs.ExtDiff() != 0L;
	m_home = gCvsPrefs.Home() != 0L ? gCvsPrefs.Home() : "";
	m_chkUseViewerAlways = gCvsPrefs.UseViewerAlways() != 0L;
	m_cvschk = gCvsPrefs.WhichCvs(cvsPath, true) != 0L;
	m_cvsprog = gCvsPrefs.WhichCvs(cvsPath);
	//}}AFX_DATA_INIT
}

CGetPrefs_WINCVS::~CGetPrefs_WINCVS()
{
}

void CGetPrefs_WINCVS::DoDataExchange(CDataExchange* pDX)
{
	m_didInteract = true;

	CPropertyPage::DoDataExchange(pDX);

	//{{AFX_DATA_MAP(CGetPrefs_WINCVS)
	DDX_Text(pDX, IDC_PROGRAM, m_viewer);
	DDX_Text(pDX, IDC_DIFFPROG, m_diffprog);
	DDX_Check(pDX, IDC_EXTDIFF, m_chkdiff);
	DDX_Text(pDX, IDC_HOME, m_home);
	DDX_Check(pDX, IDC_USE_VIEWER_ALWAYS, m_chkUseViewerAlways);
	DDX_Check(pDX, IDC_ALTCVSCHK, m_cvschk);
	DDX_Text(pDX, IDC_ALTCVSPROG, m_cvsprog);
	//}}AFX_DATA_MAP
	if( pDX->m_bSaveAndValidate )
	{
		//check the home directory
		if( !CompatMakeSurePathExists(m_home) )
		{
			AfxMessageBox("Cannot find folder " + m_home);
			pDX->PrepareEditCtrl(IDC_HOME);
			pDX->Fail();
		}
	}
	else
	{
		OnExtdiff();
		OnAltcvschk();
	}
}

void CGetPrefs_WINCVS::StoreValues()
{
	if(!m_didInteract)
		return;

	if(!m_viewer.IsEmpty())
		gCvsPrefs.SetViewer(m_viewer);
	else
		gCvsPrefs.SetViewer(0L);
	if(m_chkdiff && !m_diffprog.IsEmpty())
		gCvsPrefs.SetExtDiff(m_diffprog);
	else
		gCvsPrefs.SetExtDiff(0L);
	if(!m_home.IsEmpty())
		gCvsPrefs.SetHome(m_home);
	gCvsPrefs.SetUseViewerAlways(m_chkUseViewerAlways ? true : false);

	if(m_cvschk && !m_cvsprog.IsEmpty())
		gCvsPrefs.SetWhichCvs(m_cvsprog);
	else
		gCvsPrefs.SetWhichCvs("");
}

BEGIN_MESSAGE_MAP(CGetPrefs_WINCVS, CPropertyPage)
	//{{AFX_MSG_MAP(CGetPrefs_WINCVS)
	ON_BN_CLICKED(IDC_BTNPROGRAM, OnBtnviewer)
	ON_BN_CLICKED(IDC_EXTDIFFSEL, OnExtdiffsel)
	ON_BN_CLICKED(IDC_EXTDIFF, OnExtdiff)
	ON_BN_CLICKED(IDC_BTNHOME, OnBtnhome)
	ON_BN_CLICKED(IDC_ALTCVSCHK, OnAltcvschk)
	ON_BN_CLICKED(IDC_ALTCVSSEL, OnAltcvssel)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CGetPrefs_WINCVS::OnBtnviewer()
{
	MultiFiles mf;
	if(!BrowserGetMultiFiles("Select a program :", mf, "Executable Files (*.exe)|*.exe|All Files (*.*)|*.*||"))
		return;

	CvsArgs args(false);
	mf.next();
	const char *dir = mf.add(args);
	char * const *argv = args.Argv();
	CStr fullpath;
	fullpath = dir;
	if(!fullpath.endsWith(kPathDelimiter))
		fullpath << kPathDelimiter;
	fullpath << argv[0];

	SetDlgItemText(IDC_PROGRAM, fullpath);
}

void CGetPrefs_WINCVS::OnExtdiffsel()
{
	MultiFiles mf;
	if(!BrowserGetMultiFiles("Select a diff program :", mf, "Executable Files (*.exe)|*.exe|All Files (*.*)|*.*||"))
		return;

	CvsArgs args(false);
	mf.next();
	const char *dir = mf.add(args);
	char * const *argv = args.Argv();
	CStr fullpath;
	fullpath = dir;
	if(!fullpath.endsWith(kPathDelimiter))
		fullpath << kPathDelimiter;
	fullpath << argv[0];

	SetDlgItemText(IDC_DIFFPROG, fullpath);
}

void CGetPrefs_WINCVS::OnExtdiff() 
{
	CButton* but = (CButton *)GetDlgItem(IDC_EXTDIFF);
	CWnd* wnd = GetDlgItem(IDC_DIFFPROG);
	wnd->EnableWindow(but->GetCheck() == 1);
	wnd = GetDlgItem(IDC_EXTDIFFSEL);
	wnd->EnableWindow(but->GetCheck() == 1);
}

void CGetPrefs_WINCVS::OnBtnhome()
{
	const char *dir = BrowserGetDirectory("Select a directory to be the HOME :");
	if(dir != NULL)
		SetDlgItemText(IDC_HOME, dir);
}

void CGetPrefs_WINCVS::OnAltcvschk() 
{
	CButton* but = (CButton *)GetDlgItem(IDC_ALTCVSCHK);
	CWnd* wnd = GetDlgItem(IDC_ALTCVSPROG);
	wnd->EnableWindow(but->GetCheck() == 1);
	wnd = GetDlgItem(IDC_ALTCVSSEL);
	wnd->EnableWindow(but->GetCheck() == 1);
}

void CGetPrefs_WINCVS::OnAltcvssel() 
{
	MultiFiles mf;
	if(!BrowserGetMultiFiles("Select a cvs program :", mf, "Executable Files (*.exe)|*.exe|All Files (*.*)|*.*||"))
		return;

	CvsArgs args(false);
	mf.next();
	const char *dir = mf.add(args);
	char * const *argv = args.Argv();
	CStr fullpath;
	fullpath = dir;
	if(!fullpath.endsWith(kPathDelimiter))
		fullpath << kPathDelimiter;
	fullpath << argv[0];

	SetDlgItemText(IDC_ALTCVSPROG, fullpath);
}

// Command Dialogs options page
IMPLEMENT_DYNCREATE(CGetPrefs_CVSCMD_DIALOGS, CPropertyPage)

CGetPrefs_CVSCMD_DIALOGS::CGetPrefs_CVSCMD_DIALOGS() : CPropertyPage(CGetPrefs_CVSCMD_DIALOGS::IDD), m_didInteract(false)
{
	//{{AFX_DATA_INIT(CGetPrefs_CVSCMD_DIALOGS)
	m_hideUpdate = gCvsPrefs.HideCommandDlgUpdate() != 0L;
	m_hideDiff = gCvsPrefs.HideCommandDlgDiff() != 0L;
	m_hideGraph = gCvsPrefs.HideCommandDlgGraph() != 0L;
	m_hideLog = gCvsPrefs.HideCommandDlgLog() != 0L;
	m_keyForce = gCvsPrefs.HideCommandDlgUseShift() != 0L ? 0 : 1;
	m_hideAnnotate = gCvsPrefs.HideCommandDlgAnnotate() != 0L;
	//}}AFX_DATA_INIT
}

CGetPrefs_CVSCMD_DIALOGS::~CGetPrefs_CVSCMD_DIALOGS()
{
}

void CGetPrefs_CVSCMD_DIALOGS::DoDataExchange(CDataExchange* pDX)
{
	m_didInteract = true;

	CPropertyPage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CGetPrefs_CVSCMD_DIALOGS)
	DDX_Check(pDX, IDC_CHECKUPDATE, m_hideUpdate);
	DDX_Check(pDX, IDC_CHECKDIFF, m_hideDiff);
	DDX_Check(pDX, IDC_CHECKGRAPH, m_hideGraph);
	DDX_Check(pDX, IDC_CHECKLOG, m_hideLog);
	DDX_Radio(pDX, IDC_RADIOSHIFT, m_keyForce);
	DDX_Check(pDX, IDC_CHECKANNOTATE, m_hideAnnotate);
	//}}AFX_DATA_MAP
}

void CGetPrefs_CVSCMD_DIALOGS::StoreValues()
{
	if(!m_didInteract)
		return;

	gCvsPrefs.SetHideCommandDlgUpdate(m_hideUpdate ? true : false);
	gCvsPrefs.SetHideCommandDlgDiff(m_hideDiff ? true : false);
	gCvsPrefs.SetHideCommandDlgGraph(m_hideGraph ? true : false);
	gCvsPrefs.SetHideCommandDlgAnnotate(m_hideAnnotate ? true : false);
	gCvsPrefs.SetHideCommandDlgLog(m_hideLog ? true : false);
	gCvsPrefs.SetHideCommandDlgUseShift(m_keyForce == 0);
}

BEGIN_MESSAGE_MAP(CGetPrefs_CVSCMD_DIALOGS, CPropertyPage)
//{{AFX_MSG_MAP(CGetPrefs_CVSCMD_DIALOGS)
// NOTE: the ClassWizard will add message map macros here
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

#endif /* WIN32 */

#if qUnix
class UCvsPrefs_MAIN : public UWidget
{
	UDECLARE_DYNAMIC(UCvsPrefs_MAIN)
public:
	UCvsPrefs_MAIN() : UWidget(::UEventGetWidID()) {}
	virtual ~UCvsPrefs_MAIN() {}

	enum
	{
		kOK = EV_COMMAND_START,	// 0
		kCancel,				// 1
		kTabGeneral				// 2
	};

	virtual void DoDataExchange(bool fill);
	
protected:
	ev_msg int OnOK(void);
	ev_msg int OnCancel(void);

	UDECLARE_MESSAGE_MAP()
};

UIMPLEMENT_DYNAMIC(UCvsPrefs_MAIN, UWidget)

UBEGIN_MESSAGE_MAP(UCvsPrefs_MAIN, UWidget)
	ON_UCOMMAND(UCvsPrefs_MAIN::kOK, UCvsPrefs_MAIN::OnOK)
	ON_UCOMMAND(UCvsPrefs_MAIN::kCancel, UCvsPrefs_MAIN::OnCancel)
UEND_MESSAGE_MAP()

int UCvsPrefs_MAIN::OnOK(void)
{
	EndModal(true);
	return 0;
}

int UCvsPrefs_MAIN::OnCancel(void)
{
	EndModal(false);
	return 0;
}

void UCvsPrefs_MAIN::DoDataExchange(bool fill)
{
	if(fill)
	{
	}
	else
	{
	}
}

class UCvsPrefs_CVSROOT : public UWidget
{
	UDECLARE_DYNAMIC(UCvsPrefs_CVSROOT)
public:
	UCvsPrefs_CVSROOT();
	virtual ~UCvsPrefs_CVSROOT() {}

	enum
	{
		kCvsrootCombo = EV_COMMAND_START,	// 0
		kRshRadio,				// 1
		kPserverRadio,			// 2
		kLocalRadio,			// 3
		kSshRadio,				// 4
		kKerberosRadio,			// 5
		kCvsVersionCombo		// 6
	};

	virtual void DoDataExchange(bool fill);

	void StoreValues(void);
	
protected:
	UStr m_cvsroot;
	AuthenKind m_kind;

	UDECLARE_MESSAGE_MAP()
};

UIMPLEMENT_DYNAMIC(UCvsPrefs_CVSROOT, UWidget)

UBEGIN_MESSAGE_MAP(UCvsPrefs_CVSROOT, UWidget)
UEND_MESSAGE_MAP()

UCvsPrefs_CVSROOT::UCvsPrefs_CVSROOT() : UWidget(::UEventGetWidID())
{
	if(!gCvsPrefs.empty())
		m_cvsroot = (const char *)gCvsPrefs;
	m_kind = gAuthen.kind();
}

void UCvsPrefs_CVSROOT::StoreValues(void)
{
	gCvsPrefs = m_cvsroot;
	gAuthen.setkind(m_kind);
}

void UCvsPrefs_CVSROOT::DoDataExchange(bool fill)
{
	if(fill)
	{
		UEventSendMessage(GetWidID(), EV_SETTEXT, kCvsrootCombo, (void *)(const char *)m_cvsroot);
		UEventSendMessage(GetWidID(), EV_COMBO_RESETALL, kCvsrootCombo, 0L);
		for(int i = 0; i < NUM_CVSROOT; i++)
		{
			const CPStr & strroot =
				(*(const CvsPrefs *)&gCvsPrefs).get_cvsroot_list(i);
			if(!strroot.empty())
				UEventSendMessage(GetWidID(), EV_COMBO_APPEND,
								  kCvsrootCombo, (void *)(const char *)strroot);
		}
		
		int item = kLocalRadio;
		switch(m_kind)
		{
		case local: item = kLocalRadio; break;
		case kserver: item = kKerberosRadio; break;
		case rhosts: item = kRshRadio; break;
		case pserver: item = kPserverRadio; break;
		case ssh: item = kSshRadio; break;
		case ntserver: item = kLocalRadio; break;
		}
		
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(item, 1), 0L);
	}
	else
	{
		UEventSendMessage(GetWidID(), EV_GETTEXT, kCvsrootCombo, &m_cvsroot);

		m_kind = local;
		if(UEventSendMessage(GetWidID(), EV_QUERYSTATE, kLocalRadio, 0L))
			m_kind = local;
		else if(UEventSendMessage(GetWidID(), EV_QUERYSTATE, kKerberosRadio, 0L))
			m_kind = kserver;
		else if(UEventSendMessage(GetWidID(), EV_QUERYSTATE, kRshRadio, 0L))
			m_kind = rhosts;
		else if(UEventSendMessage(GetWidID(), EV_QUERYSTATE, kPserverRadio, 0L))
			m_kind = pserver;
		else if(UEventSendMessage(GetWidID(), EV_QUERYSTATE, kSshRadio, 0L))
			m_kind = ssh;
	}
}

class UCvsPrefs_GLOBALS : public UWidget
{
	UDECLARE_DYNAMIC(UCvsPrefs_GLOBALS)
public:
	UCvsPrefs_GLOBALS();
	virtual ~UCvsPrefs_GLOBALS() {}

	enum
	{
		kcheckoutro = EV_COMMAND_START,	// 0
		kdirty,					// 1
		ktcpip,					// 2
		kprune,					// 3
		kquiet,					// 4
		kcntladd				// 5
	};

	virtual void DoDataExchange(bool fill);
	
	void StoreValues(void);

protected:
	bool m_checkoutro;
	bool m_dirty;
	bool m_tcpip;
	bool m_prune;
	bool m_quiet;
	bool m_cntladd;

	UDECLARE_MESSAGE_MAP()
};

UIMPLEMENT_DYNAMIC(UCvsPrefs_GLOBALS, UWidget)

UBEGIN_MESSAGE_MAP(UCvsPrefs_GLOBALS, UWidget)
UEND_MESSAGE_MAP()

UCvsPrefs_GLOBALS::UCvsPrefs_GLOBALS() : UWidget(::UEventGetWidID())
{
	m_checkoutro = gCvsPrefs.CheckoutRO();
	m_prune = gCvsPrefs.PruneOption();
	m_tcpip = gCvsPrefs.Z9Option();
	m_quiet = gCvsPrefs.QuietOption();
	m_cntladd = gCvsPrefs.AddControl();
	m_dirty = gCvsPrefs.DirtySupport();
}

void UCvsPrefs_GLOBALS::StoreValues(void)
{
	gCvsPrefs.SetCheckoutRO(m_checkoutro);
	gCvsPrefs.SetPruneOption(m_prune);
	gCvsPrefs.SetZ9Option(m_tcpip);
	gCvsPrefs.SetQuietOption(m_quiet);
	gCvsPrefs.SetAddControl(m_cntladd);
	gCvsPrefs.SetDirtySupport(m_dirty);
}

void UCvsPrefs_GLOBALS::DoDataExchange(bool fill)
{
	if(fill)
	{
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(kcheckoutro, m_checkoutro), 0L);
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(kprune, m_prune), 0L);
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(ktcpip, m_tcpip), 0L);
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(kquiet, m_quiet), 0L);
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(kcntladd, m_cntladd), 0L);
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(kdirty, m_dirty), 0L);
	}
	else
	{
		m_checkoutro = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kcheckoutro, 0L) != 0;
		m_prune = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kprune, 0L) != 0;
		m_tcpip = UEventSendMessage(GetWidID(), EV_QUERYSTATE, ktcpip, 0L) != 0;
		m_quiet = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kquiet, 0L) != 0;
		m_cntladd = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kcntladd, 0L) != 0;
		m_dirty = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kdirty, 0L) != 0;
	}
}

class UCvsPrefs_PORTS : public UWidget
{
	UDECLARE_DYNAMIC(UCvsPrefs_PORTS)
public:
	UCvsPrefs_PORTS();
	virtual ~UCvsPrefs_PORTS() {}

	enum
	{
		kcheckrhost = EV_COMMAND_START,	// 0
		kcheckpserver,			// 1
		kcheckkserver,			// 2
		kchecksname,			// 3
		kcheckrsh,				// 4
		kportrhost,				// 5
		kportpserver,			// 6
		kportkserver,			// 7
		ksname,					// 8
		krshname				// 9
	};

	virtual void DoDataExchange(bool fill);
	
	void StoreValues(void);

protected:
	bool m_checkrhost;
	bool m_checkpserver;
	bool m_checkkserver;
	bool m_checksname;
	bool m_checkrsh;
	int m_portrhost;
	int m_portpserver;
	int m_portkserver;
	UStr m_sname;
	UStr m_rshname;

	ev_msg int OnCheckPorts(int cmd);

	UDECLARE_MESSAGE_MAP()
};

UIMPLEMENT_DYNAMIC(UCvsPrefs_PORTS, UWidget)

UBEGIN_MESSAGE_MAP(UCvsPrefs_PORTS, UWidget)
	ON_UCOMMAND_RANGE(UCvsPrefs_PORTS::kcheckrhost, UCvsPrefs_PORTS::kcheckrsh, UCvsPrefs_PORTS::OnCheckPorts)
UEND_MESSAGE_MAP()

UCvsPrefs_PORTS::UCvsPrefs_PORTS() : UWidget(::UEventGetWidID())
{
	m_checkkserver = gCvsPrefs.KserverPort() != -1;
	m_checkpserver = gCvsPrefs.PserverPort() != -1;
	m_checkrhost = gCvsPrefs.RhostPort() != -1;
	m_checksname = gCvsPrefs.ServerName() != 0L;
	m_checkrsh = gCvsPrefs.RshName() != 0L;
		
	m_portkserver = gCvsPrefs.KserverPort() != -1 ? gCvsPrefs.KserverPort() : 0;
	m_portpserver = gCvsPrefs.PserverPort() != -1 ? gCvsPrefs.PserverPort() : 0;
	m_portrhost = gCvsPrefs.RhostPort() != -1 ? gCvsPrefs.RhostPort() : 0;
	m_sname = gCvsPrefs.ServerName() == 0L ? "cvs" : gCvsPrefs.ServerName();
	m_rshname = gCvsPrefs.RshName() == 0L ? "ssh" : gCvsPrefs.RshName();
}

void UCvsPrefs_PORTS::StoreValues(void)
{
	gCvsPrefs.SetKserverPort(m_checkkserver ? m_portkserver : -1);
	gCvsPrefs.SetPserverPort(m_checkpserver ? m_portpserver : -1);
	gCvsPrefs.SetRhostPort(m_checkrhost ? m_portrhost : -1);
	
	gCvsPrefs.SetServerName(m_checksname ? (const char *)m_sname : 0L);
	gCvsPrefs.SetRshName(m_checkrsh ? (const char *)m_rshname : 0L);
}

int UCvsPrefs_PORTS::OnCheckPorts(int cmd)
{
	int state = UEventSendMessage(GetWidID(), EV_QUERYSTATE, cmd, 0L);
	UEventSendMessage(GetWidID(), EV_ENABLECMD, UMAKEINT(cmd + 5, state), 0L);
	return 0;
}

void UCvsPrefs_PORTS::DoDataExchange(bool fill)
{
	if(fill)
	{
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(kcheckkserver, m_checkkserver), 0L);
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(kcheckpserver, m_checkpserver), 0L);
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(kcheckrhost, m_checkrhost), 0L);
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(kchecksname, m_checksname), 0L);
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(kcheckrsh, m_checkrsh), 0L);
		
		UEventSendMessage(GetWidID(), EV_SETINTEGER, UMAKEINT(kportkserver, m_portkserver), 0L);
		UEventSendMessage(GetWidID(), EV_SETINTEGER, UMAKEINT(kportpserver, m_portpserver), 0L);
		UEventSendMessage(GetWidID(), EV_SETINTEGER, UMAKEINT(kportrhost, m_portrhost), 0L);
		UEventSendMessage(GetWidID(), EV_SETTEXT, ksname, (void *)(const char *)m_sname);
		UEventSendMessage(GetWidID(), EV_SETTEXT, krshname, (void *)(const char *)m_rshname);

		OnCheckPorts(kcheckrhost);
		OnCheckPorts(kcheckpserver);
		OnCheckPorts(kcheckkserver);
		OnCheckPorts(kchecksname);
		OnCheckPorts(kcheckrsh);
	}
	else
	{
		m_checkkserver = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kcheckkserver, 0L) != 0;
		m_portkserver = UEventSendMessage(GetWidID(), EV_GETINTEGER, kportkserver, 0L);
		m_checkpserver = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kcheckpserver, 0L) != 0;
		m_portpserver = UEventSendMessage(GetWidID(), EV_GETINTEGER, kportpserver, 0L);
		m_checkrhost = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kcheckrhost, 0L) != 0;
		m_portrhost = UEventSendMessage(GetWidID(), EV_GETINTEGER, kportrhost, 0L);

		UEventSendMessage(GetWidID(), EV_GETTEXT, ksname, &m_sname);
		m_checksname = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kchecksname, 0L) != 0;
		UEventSendMessage(GetWidID(), EV_GETTEXT, krshname, &m_rshname);
		m_checkrsh = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kcheckrsh, 0L) != 0;
	}
}

class UCvsPrefs_PROXY : public UWidget
{
	UDECLARE_DYNAMIC(UCvsPrefs_PROXY)
public:
	UCvsPrefs_PROXY();
	virtual ~UCvsPrefs_PROXY() {}

	enum
	{
		kuseproxy = EV_COMMAND_START,	// 0
		kproxyhost,				// 1
		kproxyport				// 2
	};

	virtual void DoDataExchange(bool fill);
	
	void StoreValues(void);

protected:
	bool m_useproxy;
	UStr m_proxyhost;
	int m_proxyport;

	ev_msg int OnUseProxy(void);

	UDECLARE_MESSAGE_MAP()
};

UIMPLEMENT_DYNAMIC(UCvsPrefs_PROXY, UWidget)

UBEGIN_MESSAGE_MAP(UCvsPrefs_PROXY, UWidget)
	ON_UCOMMAND(UCvsPrefs_PROXY::kuseproxy, UCvsPrefs_PROXY::OnUseProxy)
UEND_MESSAGE_MAP()

UCvsPrefs_PROXY::UCvsPrefs_PROXY() : UWidget(::UEventGetWidID())
{
	m_useproxy = gCvsPrefs.UseProxy();
	m_proxyport = gCvsPrefs.ProxyPort();
	m_proxyhost = gCvsPrefs.ProxyHost();
}

void UCvsPrefs_PROXY::StoreValues(void)
{
	gCvsPrefs.SetUseProxy(m_useproxy);
	gCvsPrefs.SetProxyHost(m_proxyhost);
	gCvsPrefs.SetProxyPort(m_proxyport);
}

int UCvsPrefs_PROXY::OnUseProxy(void)
{
	int state = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kuseproxy, 0L);
	UEventSendMessage(GetWidID(), EV_ENABLECMD, UMAKEINT(kproxyhost, state), 0L);
	UEventSendMessage(GetWidID(), EV_ENABLECMD, UMAKEINT(kproxyport, state), 0L);
	return 0;
}

void UCvsPrefs_PROXY::DoDataExchange(bool fill)
{
	if(fill)
	{
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(kuseproxy, m_useproxy), 0L);
		UEventSendMessage(GetWidID(), EV_SETINTEGER, UMAKEINT(kproxyport, m_proxyport), 0L);
		UEventSendMessage(GetWidID(), EV_SETTEXT, kproxyhost, (void *)(const char *)m_proxyhost);

		OnUseProxy();
	}
	else
	{
		CStr str;
		m_useproxy = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kuseproxy, 0L) != 0;
		UEventSendMessage(GetWidID(), EV_GETTEXT, kproxyhost, &m_proxyhost);
		m_proxyport = UEventSendMessage(GetWidID(), EV_GETINTEGER, kproxyport, 0L);
	}
}

class UCvsPrefs_GCVS : public UWidget
{
	UDECLARE_DYNAMIC(UCvsPrefs_GCVS)
public:
	UCvsPrefs_GCVS();
	virtual ~UCvsPrefs_GCVS() {}

	enum
	{
		kdiffApp = EV_COMMAND_START,	// 0
		kviewerApp,				// 1
		kbrowserApp,			// 2
		khelpApp,				// 3
		kdiffBtn,				// 4
		kviewerBtn,				// 5
		kbrowserBtn,			// 6
		khelpBtn				// 7
	};

	virtual void DoDataExchange(bool fill);
	
	void StoreValues(void);

protected:
	UStr m_diffApp;
	UStr m_viewerApp;
	UStr m_browserApp;
	UStr m_helpApp;

	ev_msg int OnPickProgram(int cmd);

	UDECLARE_MESSAGE_MAP()
};

UIMPLEMENT_DYNAMIC(UCvsPrefs_GCVS, UWidget)

UBEGIN_MESSAGE_MAP(UCvsPrefs_GCVS, UWidget)
	ON_UCOMMAND_RANGE(UCvsPrefs_GCVS::kdiffBtn, UCvsPrefs_GCVS::khelpBtn, UCvsPrefs_GCVS::OnPickProgram)
UEND_MESSAGE_MAP()

UCvsPrefs_GCVS::UCvsPrefs_GCVS() : UWidget(::UEventGetWidID())
{
	m_diffApp = gCvsPrefs.ExtDiff();
	m_viewerApp = gCvsPrefs.Viewer();
	m_browserApp = gCvsPrefs.Browser();
	m_helpApp = gCvsPrefs.Helper();
}

void UCvsPrefs_GCVS::StoreValues(void)
{
	gCvsPrefs.SetExtDiff(m_diffApp);
	gCvsPrefs.SetViewer(m_viewerApp);
	gCvsPrefs.SetBrowser(m_browserApp);
	gCvsPrefs.SetHelper(m_helpApp);
}

int UCvsPrefs_GCVS::OnPickProgram(int cmd)
{
	MultiFiles mf;
	if(!BrowserGetMultiFiles("Select a program :", mf))
		return 0;

	CvsArgs args(false);
	mf.next();
	const char *dir = mf.add(args);
	char * const *argv = args.Argv();
	CStr fullpath;
	fullpath = dir;
	if(!fullpath.endsWith(kPathDelimiter))
		fullpath << kPathDelimiter;
	fullpath << argv[0];

	UEventSendMessage(GetWidID(), EV_SETTEXT, cmd - kdiffBtn + kdiffApp, (void *)(const char *)fullpath);
	return 0;
}

void UCvsPrefs_GCVS::DoDataExchange(bool fill)
{
	if(fill)
	{
		UEventSendMessage(GetWidID(), EV_SETTEXT, kdiffApp, (void *)(const char *)m_diffApp);
		UEventSendMessage(GetWidID(), EV_SETTEXT, kviewerApp, (void *)(const char *)m_viewerApp);
		UEventSendMessage(GetWidID(), EV_SETTEXT, kbrowserApp, (void *)(const char *)m_browserApp);
		UEventSendMessage(GetWidID(), EV_SETTEXT, khelpApp, (void *)(const char *)m_helpApp);
	}
	else
	{
		UEventSendMessage(GetWidID(), EV_GETTEXT, kdiffApp, &m_diffApp);
		UEventSendMessage(GetWidID(), EV_GETTEXT, kviewerApp, &m_viewerApp);
		UEventSendMessage(GetWidID(), EV_GETTEXT, kbrowserApp, &m_browserApp);
		UEventSendMessage(GetWidID(), EV_GETTEXT, khelpApp, &m_helpApp);
	}
}

#endif // qUnix
#if qMacCvsPP

class UCvsPrefs_CVSROOT : public UWidget
{
	UDECLARE_DYNAMIC(UCvsPrefs_CVSROOT)
public:
	UCvsPrefs_CVSROOT();
	virtual ~UCvsPrefs_CVSROOT() {}

	enum
	{
		kAuthenPopup = EV_COMMAND_START + 40,	// 40
		kPath,				// 41
		kHost,				// 42
		kUser,				// 43
		kRootPopup,			// 44
		kRootStat,			// 45
		kCvsVers,			// 46
		kAuthenSettings,	// 47
		kAuthenDesc			// 48
	};

	virtual void DoDataExchange(bool fill);
	
protected:
	UStr m_cvsroot;
	AuthenKind m_kind;

	ev_msg void OnAuthenPopup(int pos, const char *txt);
	ev_msg void OnRootPopup(int pos, const char *txt);
	ev_msg void OnEditChange(int cmd);
	ev_msg int OnAuthenSettings(void);
	ev_msg void OnDestroy(void);
	
	UDECLARE_MESSAGE_MAP()
};

UIMPLEMENT_DYNAMIC(UCvsPrefs_CVSROOT, UWidget)

UBEGIN_MESSAGE_MAP(UCvsPrefs_CVSROOT, UWidget)
	ON_COMBO_SEL(kAuthenPopup, OnAuthenPopup)
	ON_COMBO_SEL(kRootPopup, OnRootPopup)
	ON_EDITCHANGE_RANGE(kPath, kUser, OnEditChange)
	ON_UCOMMAND(kAuthenSettings, OnAuthenSettings)
	ON_UDESTROY(UCvsPrefs_CVSROOT)
UEND_MESSAGE_MAP()

UCvsPrefs_CVSROOT::UCvsPrefs_CVSROOT() : UWidget(::UEventGetWidID())
{
}

void UCvsPrefs_CVSROOT::OnAuthenPopup(int pos, const char *txt)
{
	m_kind = Authen::numToKind(pos);
	AuthenModel *model = AuthenModel::GetInstance(m_kind);
	UEventSendMessage(GetWidID(), EV_ENABLECMD, UMAKEINT(kHost, model->HasHost()), 0L);
	UEventSendMessage(GetWidID(), EV_ENABLECMD, UMAKEINT(kUser, model->HasUser()), 0L);
	UEventSendMessage(GetWidID(), EV_ENABLECMD, UMAKEINT(kAuthenSettings, model->HasSettings()), 0L);
	
	if(!model->HasHost())
		UEventSendMessage(GetWidID(), EV_SETTEXT, kHost, (void *)"");
	if(!model->HasUser())
		UEventSendMessage(GetWidID(), EV_SETTEXT, kUser, (void *)"");
	UStr desc;
	model->GetSettingsDesc(desc);
	UEventSendMessage(GetWidID(), EV_SETTEXT, kAuthenDesc, (void *)(const char *)desc);
}

void UCvsPrefs_CVSROOT::OnRootPopup(int pos, const char *txt)
{
	m_cvsroot = txt;
	UEventSendMessage(GetWidID(), EV_SETTEXT, kRootStat, (void *)txt);

	UStr theMethod, theUser, theHost, thePath;
	
	if(Authen::parse_cvsroot(txt, theMethod, theUser, theHost, thePath))
	{
		UEventSendMessage(GetWidID(), EV_SETTEXT, kPath, (void *)(const char *)thePath);
		UEventSendMessage(GetWidID(), EV_SETTEXT, kHost, (void *)(const char *)theHost);
		UEventSendMessage(GetWidID(), EV_SETTEXT, kUser, (void *)(const char *)theUser);
		if (theMethod.length () > 0)
			UEventSendMessage(GetWidID(), EV_COMBO_SETSEL,
							  UMAKEINT(kAuthenPopup, Authen::kindToNum(Authen::tokenToKind (theMethod.c_str ()))), 0L);
	}
}

void UCvsPrefs_CVSROOT::OnEditChange(int cmd)
{
	UStr theUser, theHost, thePath;

	UEventSendMessage(GetWidID(), EV_GETTEXT, kPath, &thePath);
	UEventSendMessage(GetWidID(), EV_GETTEXT, kHost, &theHost);
	UEventSendMessage(GetWidID(), EV_GETTEXT, kUser, &theUser);
	
	m_cvsroot = "";
	AuthenModel *model = AuthenModel::GetInstance(m_kind);
	if(model->HasUser())
		m_cvsroot << theUser;
	if(model->HasHost())
	{
		m_cvsroot << '@';
		m_cvsroot << theHost;
	}
	if(model->HasUser() || model->HasHost())
		m_cvsroot << ':';
	m_cvsroot << thePath;
	UEventSendMessage(GetWidID(), EV_SETTEXT, kRootStat, (void *)(const char *)m_cvsroot);
}

int UCvsPrefs_CVSROOT::OnAuthenSettings(void)
{
	AuthenModel *model = AuthenModel::GetInstance(m_kind);
	model->DoSettings();
	UStr desc;
	model->GetSettingsDesc(desc);
	UEventSendMessage(GetWidID(), EV_SETTEXT, kAuthenDesc, (void *)(const char *)desc);
	return 0;
}

void UCvsPrefs_CVSROOT::OnDestroy(void)
{
	delete this;
}

void UCvsPrefs_CVSROOT::DoDataExchange(bool fill)
{
	if(fill)
	{		
		if(!gCvsPrefs.empty())
			m_cvsroot = (const char *)gCvsPrefs;
		m_kind = gAuthen.kind();

		UEventSendMessage(GetWidID(), EV_COMBO_RESETALL, kAuthenPopup, 0L);
		std::vector<AuthenModel *> & allAuthen = AuthenModel::GetAllInstances();
		std::vector<AuthenModel *>::iterator i;
		for(i = allAuthen.begin(); i != allAuthen.end(); ++i)
		{
			UEventSendMessage(GetWidID(), EV_COMBO_APPEND,
							  kAuthenPopup, (void *)(*i)->GetToken());
		}
		
		AuthenModel *model = AuthenModel::GetInstance(m_kind);
		UEventSendMessage(GetWidID(), EV_COMBO_SETSEL,
						  UMAKEINT(kAuthenPopup, Authen::kindToNum(model->GetKind())), 0L);
		
		UEventSendMessage(GetWidID(), EV_COMBO_RESETALL, kRootPopup, 0L);
		for(int i = 0; i < NUM_CVSROOT; i++)
		{
			const CPStr & strroot =
				(*(const CvsPrefs *)&gCvsPrefs).get_cvsroot_list(i);
			if(!strroot.empty())
				UEventSendMessage(GetWidID(), EV_COMBO_APPEND,
								  kRootPopup, (void *)(const char *)strroot);
		}
		
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(kCvsVers, 1), 0L);

		UStr tmp(m_cvsroot);
		OnRootPopup(0, tmp);
		OnAuthenPopup(Authen::kindToNum(m_kind), 0L);

		UEventSendMessage(GetWidID(), EV_CHGFOCUS, kPath, 0L);
	}
	else
	{
		gAuthen.setkind(m_kind);

		UStr theUser, theHost, thePath;

		UEventSendMessage(GetWidID(), EV_GETTEXT, kPath, &thePath);
		UEventSendMessage(GetWidID(), EV_GETTEXT, kHost, &theHost);
		UEventSendMessage(GetWidID(), EV_GETTEXT, kUser, &theUser);

		UStr root;
		if(m_kind != local)
		{
			root << theUser;
			root << '@';
			root << theHost;
			root << ':';
			root << thePath;
		}
		else
			root = thePath;
		
		gCvsPrefs = root;
	}
}

static void DoDataExchange_Cvsroot(UCvsPrefs_CVSROOT *handler, bool putValue)
{
	handler->DoDataExchange(putValue);
}
#endif // qMacCvsPP

void CompatGetPrefs(void)
{
	bool userHitOK = false;

#ifdef WIN32
	CPropertySheet pages("WinCvs Preferences");
	pages.m_psh.dwFlags |= PSH_NOAPPLYNOW;
	CGetPrefs_CVSROOT page1;
	CGetPrefs_GLOBALS page2;
//	CGetPrefs_PORTS page3;
//	CGetPrefs_PROXY page3b;
	CGetPrefs_WINCVS page4;
	CGetPrefs_CVSCMD_DIALOGS page5;
	pages.AddPage(&page1);
	pages.AddPage(&page2);
//	pages.AddPage(&page3);
//	pages.AddPage(&page3b);
	pages.AddPage(&page4);
	pages.AddPage(&page5);
	if(pages.DoModal() == IDOK)
	{
		page1.StoreValues();
		page2.StoreValues();
//		page3.StoreValues();
//		page3b.StoreValues();
		page4.StoreValues();
		page5.StoreValues();
		userHitOK = true;
	}
#endif /* WIN32 */
#ifdef qMacCvsPP
	MacBinMaps maps;
	maps.LoadDefaults();
	CMacBinTable::SetCurrentMap(&maps);

	StDialogHandler	theHandler(dlg_Prefs, CMacCvsApp::app);
	LWindow *theDialog = theHandler.GetDialog();
	ThrowIfNil_(theDialog);
	static UInt16 sRuntimePanel = 1;
	
	LMultiPanelView *multiView = dynamic_cast<LMultiPanelView*>
		(theDialog->FindPaneByID(item_MultiViewPrefs));
	LPane *groupView = theDialog->FindPaneByID(item_GroupViewPrefs);
	
	UCvsPrefs_CVSROOT *handler = new UCvsPrefs_CVSROOT;
	ThrowIfNil_(handler);
	
	UEventSendMessage(handler->GetWidID(), EV_INIT_WIDGET, 0, theDialog);
	
	multiView->SwitchToPanel(5);
	DoDataExchange_Fonts(theDialog, true);
	multiView->SwitchToPanel(4);
	DoDataExchange_BinFiles(theDialog, maps, true);
	multiView->SwitchToPanel(3);
	DoDataExchange_TextFiles(theDialog, true);
	multiView->SwitchToPanel(2);
	DoDataExchange_Globals(theDialog, true);
	multiView->SwitchToPanel(1);
	DoDataExchange_Cvsroot(handler, true);
	
	groupView->SetValue(sRuntimePanel);
	theDialog->Show();
	MessageT hitMessage;
	while (true)
	{		// Let DialogHandler process events
		hitMessage = theHandler.DoDialog();
		
		if (hitMessage == msg_OK || hitMessage == msg_Cancel)
			break;
	}
	theDialog->Hide();
	sRuntimePanel = groupView->GetValue();
	
	if(hitMessage == msg_OK)
	{
		userHitOK = true;

		multiView->SwitchToPanel(1);
		DoDataExchange_Cvsroot(handler, false);
		multiView->SwitchToPanel(2);
		DoDataExchange_Globals(theDialog, false);
		multiView->SwitchToPanel(3);
		DoDataExchange_TextFiles(theDialog, false);
		multiView->SwitchToPanel(4);
		DoDataExchange_BinFiles(theDialog, maps, false);
		multiView->SwitchToPanel(5);
		DoDataExchange_Fonts(theDialog, false);

		maps.SaveDefaults();
	}
#endif /* qMacCvsPP */
#if qUnix
	void *wid = UCreate_gcvs_Settings();

	UCvsPrefs_MAIN *dlg = new UCvsPrefs_MAIN();
	UCvsPrefs_CVSROOT *tab1 = new UCvsPrefs_CVSROOT();
	UCvsPrefs_GLOBALS *tab2 = new UCvsPrefs_GLOBALS();
	UCvsPrefs_PORTS *tab3 = new UCvsPrefs_PORTS();
	UCvsPrefs_PROXY *tab4 = new UCvsPrefs_PROXY();
	UCvsPrefs_GCVS *tab5 = new UCvsPrefs_GCVS();
	UEventSendMessage(dlg->GetWidID(), EV_INIT_WIDGET, kUMainWidget, wid);
	dlg->AddPage(tab1, UCvsPrefs_MAIN::kTabGeneral, 0);
	dlg->AddPage(tab2, UCvsPrefs_MAIN::kTabGeneral, 1);
	dlg->AddPage(tab3, UCvsPrefs_MAIN::kTabGeneral, 2);
	dlg->AddPage(tab4, UCvsPrefs_MAIN::kTabGeneral, 3);
	dlg->AddPage(tab5, UCvsPrefs_MAIN::kTabGeneral, 4);

	if(dlg->DoModal())
	{
		tab1->StoreValues();
		tab2->StoreValues();
		tab3->StoreValues();
		tab4->StoreValues();
		tab5->StoreValues();

		userHitOK = true;
	}
	delete dlg;
#endif // qUnix

	if(userHitOK && !gCvsPrefs.empty())
	{
		cvs_out("NEW CVSROOT: %s (%s)\n", (const char *)gCvsPrefs, gAuthen.kindstr());
		gCvsPrefs.save();
	}
}
