/*
** 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> --- March 1998
 */

/*
 * ImportDlg.cpp : the cvs import dialog
 */

#include "stdafx.h"

#ifdef WIN32
#	include "wincvs.h"
#endif /* WIN32 */

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

#ifdef qMacCvsPP
#	include <UModalDialogs.h>
#	include <LMultiPanelView.h>
#	include <LPopupGroupBox.h>
#	include <LCheckBox.h>
#	include <LTextEditView.h>
#	include <LEditText.h>
#	include <LPushButton.h>

#	include "MacCvsConstant.h"
#endif /* qMacCvsPP */

#include "ImportDlg.h"
#include "CvsPrefs.h"
#include "MultiFiles.h"
#include "MultiString.h"
#include "PromptFiles.h"
#include "ItemListDlg.h"
#include "CvsCommands.h"

/// Default release tags
static char* sDefReleases[] = 
{
	"V10",
	"V101",
	0L
};

/// Default vendor tags
static char* sDefVendors[] = 
{
	"GNU",
	0L
};

/// Default module names
static char* sDefModuleNames[] = 
{
	"Module",
	"Project",
	0L
};

/// Default vendor branch ids
static char* sDefVendorBranchIds[] = 
{
	"1.1.7",
	"1.1.6",
	"1.1.5",
	"1.1.4",
	"1.1.3",
	"1.1.2",
	"1.1.1",
	0L
};

static CMString gVendorNames(10, "P_VendorNames", sDefVendors);
CMString gReleasesNames(10, "P_ReleaseNames", sDefReleases);
static CMString gImportModuleNames(10, "P_ImportModuleNames", sDefModuleNames);
static CMString gVendorBranchIds(10, "P_VendorBranchIds", sDefVendorBranchIds);

#ifdef WIN32
#	include "GetPrefs.h"
#	ifdef _DEBUG
#	define new DEBUG_NEW
#	undef THIS_FILE
	static char THIS_FILE[] = __FILE__;
#endif


//////////////////////////////////////////////////////////////////////////
// CImport_MAIN

IMPLEMENT_DYNAMIC(CImport_MAIN, CPropertyPage)

CImport_MAIN::CImport_MAIN(const MultiFiles* mf,
						   const char* logmsg, const char* modname,
						   const char* rtag, const char* vtag) 
						   : m_mf(mf), CPropertyPage(CImport_MAIN::IDD)
{
	//{{AFX_DATA_INIT(CImport_MAIN)
	m_logmsg = logmsg;
	m_vtag = vtag;
	m_rtag = rtag;
	m_moduleName = modname;
	//}}AFX_DATA_INIT

	m_moduleCombo.SetItems(&gImportModuleNames);
	m_rtagCombo.SetItems(&gReleasesNames);
	m_vtagCombo.SetItems(&gVendorNames);
}

CImport_MAIN::~CImport_MAIN()
{
}

void CImport_MAIN::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);

	//{{AFX_DATA_MAP(CImport_MAIN)
	DDX_Control(pDX, IDC_COMBOMODNAME, m_moduleCombo);
	DDX_Control(pDX, IDC_COMBORTAG, m_rtagCombo);
	DDX_Control(pDX, IDC_COMBOVTAG, m_vtagCombo);
	DDX_Text(pDX, IDC_LOGMSG, m_logmsg);
	DDX_CBString(pDX, IDC_COMBOVTAG, m_vtag);
	DDX_CBString(pDX, IDC_COMBORTAG, m_rtag);
	DDX_CBString(pDX, IDC_COMBOMODNAME, m_moduleName);
	//}}AFX_DATA_MAP

	DDV_MinChars(pDX, m_moduleName, 1);
	DDV_MinChars(pDX, m_rtag, 1);
	DDV_MinChars(pDX, m_vtag, 1);
	DDX_ComboMString(pDX, IDC_COMBOMODNAME, m_moduleCombo);
	DDX_ComboMString(pDX, IDC_COMBOVTAG, m_vtagCombo);
	DDX_ComboMString(pDX, IDC_COMBORTAG, m_rtagCombo);

	// Error if the vendor and release tags are same
	if( pDX->m_bSaveAndValidate )
	{
		if( m_vtag == m_rtag )
		{
			AfxMessageBox("Vendor Tag and Release Tag can't have the same values.", MB_ICONEXCLAMATION, AFX_IDP_PARSE_STRING_SIZE);
			pDX->Fail();
		}
	}
}


BEGIN_MESSAGE_MAP(CImport_MAIN, CPropertyPage)
	//{{AFX_MSG_MAP(CImport_MAIN)
	ON_BN_CLICKED(IDC_BROWSE_TAG1, OnBrowseTag1)
	ON_BN_CLICKED(IDC_BROWSE_TAG2, OnBrowseTag2)
	ON_BN_CLICKED(IDC_BROWSE_MODULES, OnBrowseModules)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CImport_MAIN message handlers

/// BN_CLICKED message handler, display browse tag/branch dialog
void CImport_MAIN::OnBrowseTag1() 
{
	CStr tagName;
	if( CompatGetTagListItem(m_mf, tagName) )
	{
		m_vtag = (const char*)tagName;
		m_vtagCombo.SetWindowText(m_vtag);
	}
}

/// BN_CLICKED message handler, display browse tag/branch dialog
void CImport_MAIN::OnBrowseTag2() 
{
	CStr tagName;
	if( CompatGetTagListItem(m_mf, tagName) )
	{
		m_rtag = (const char*)tagName;
		m_rtagCombo.SetWindowText(m_rtag);
	}
}

/// BN_CLICKED message handler, browse for file/directory
void CImport_MAIN::OnBrowseModules() 
{
	CStr moduleName;
	if( CompatGetModuleListItem(m_mf, moduleName) )
	{
		m_moduleName = (const char*)moduleName;
		m_moduleCombo.SetWindowText(m_moduleName);
	}
}

//////////////////////////////////////////////////////////////////////////
// CImport_OPTIONS

IMPLEMENT_DYNAMIC(CImport_OPTIONS, CPropertyPage)

CImport_OPTIONS::CImport_OPTIONS(const MultiFiles* mf,
								 const char* path, const bool useDefIgnore, const bool useFilesTime, const bool createSandbox) 
								 : m_mf(mf), CPropertyPage(CImport_OPTIONS::IDD)
{
	//{{AFX_DATA_INIT(CImport_OPTIONS)
	m_path = path;
	m_useDefIgnore = useDefIgnore;
	m_useFilesTime = useFilesTime;
	m_hasVendorBranch = FALSE;
	m_vendorBranch = _T("");
	m_createSandbox = createSandbox;
	//}}AFX_DATA_INIT

	m_vendorBranchCombo.SetItems(&gVendorBranchIds);
}

CImport_OPTIONS::~CImport_OPTIONS()
{
}

void CImport_OPTIONS::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);

	//{{AFX_DATA_MAP(CImport_OPTIONS)
	DDX_Control(pDX, IDC_COMBO_BRANCHID, m_vendorBranchCombo);
	DDX_Control(pDX, IDC_BROWSE_BRANCHID, m_vendorBranchButton);
	DDX_Control(pDX, IDC_BRANCHID, m_vendorBranchCheck);
	DDX_Control(pDX, IDC_PATH, m_pathEdit);
	DDX_Text(pDX, IDC_PATH, m_path);
	DDX_Check(pDX, IDC_USEDEFIGNORE, m_useDefIgnore);
	DDX_Check(pDX, IDC_USEFILESTIME, m_useFilesTime);
	DDX_Check(pDX, IDC_BRANCHID, m_hasVendorBranch);
	DDX_CBString(pDX, IDC_COMBO_BRANCHID, m_vendorBranch);
	DDX_Check(pDX, IDC_CREATESANDBOX, m_createSandbox);
	//}}AFX_DATA_MAP

	DDV_CheckPathExists(pDX, IDC_PATH, m_path, false);
	DDX_ComboMString(pDX, IDC_COMBO_BRANCHID, m_vendorBranchCombo);
	
	if( !pDX->m_bSaveAndValidate )
	{
		OnBranchid();
	}
}


BEGIN_MESSAGE_MAP(CImport_OPTIONS, CPropertyPage)
	//{{AFX_MSG_MAP(CImport_OPTIONS)
	ON_BN_CLICKED(IDC_BTNPATH, OnBtnpath)
	ON_BN_CLICKED(IDC_BROWSE_BRANCHID, OnBrowseBranchid)
	ON_BN_CLICKED(IDC_BRANCHID, OnBranchid)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CImport_OPTIONS message handlers

/// BN_CLICKED message handler, browse for import directory
void CImport_OPTIONS::OnBtnpath() 
{
	CString strPath;
    m_pathEdit.GetWindowText(strPath);
	
	CStr path(strPath);
	if( BrowserGetDirectory("Select a directory to import from", path, IsWindow(m_hWnd) ? this : NULL) )
	{
		m_pathEdit.SetWindowText(m_path);
	}
}

/// BN_CLICKED message handler, browse for vendor branch id
void CImport_OPTIONS::OnBrowseBranchid() 
{
	CStr branchName;
	if( CompatGetTagListItem(m_mf, branchName) )
	{
		m_vendorBranch = (const char*)branchName;
		m_vendorBranchCombo.SetWindowText(m_vendorBranch);
	}
}

/// BN_CLICKED message handler, enable vendor branch controls
void CImport_OPTIONS::OnBranchid() 
{
	m_vendorBranchCombo.EnableWindow(m_vendorBranchCheck.GetCheck());
	m_vendorBranchButton.EnableWindow(m_vendorBranchCheck.GetCheck());
}

#endif /* WIN32 */

#ifdef qMacCvsPP
static void DoDataExchange_ImportMain(LWindow *theDialog, CPStr & modname, CStr & logmsg, bool putValue)
{
	LEditText *mname = dynamic_cast<LEditText*>
		(theDialog->FindPaneByID(item_ModuleName));
	LTextEditView *editLog = dynamic_cast<LTextEditView*>
		(theDialog->FindPaneByID(item_LogMsg));
	
	if(putValue)
	{
		mname->SetText((Ptr)(const char *)modname, modname.length());	
		editLog->SetTextPtr((Ptr)(const char *)logmsg, logmsg.length());	
		theDialog->SetLatentSub(mname);
		
		// this will take care about an empty module name
		mname->AddListener(GetDlgHandler());
		if(modname.length() == 0)
		{
			LPushButton *theOK = dynamic_cast<LPushButton*>
										(theDialog->FindPaneByID(item_OK));
			Assert_(theOK != 0L);
			theOK->Disable();
		}
	}
	else
	{
		Handle hdl = editLog->GetTextHandle();
		Assert_(hdl != 0L);
		logmsg.set(*hdl, GetHandleSize(hdl));
		
		char buf[512];
		Size len;
		mname->GetText(buf, 511, &len);
		modname.set(buf, len);
		
	}
}

static void DoDataExchange_ImportTags(LWindow *theDialog, CPStr & vendortag, CPStr & reltag, bool putValue)
{
	LEditText *vtag = dynamic_cast<LEditText*>
		(theDialog->FindPaneByID(item_Vendortag));
	LEditText *rtag = dynamic_cast<LEditText*>
		(theDialog->FindPaneByID(item_Reltag));
	
	if(putValue)
	{
		vtag->SetText((Ptr)(const char *)vendortag, vendortag.length());	
		rtag->SetText((Ptr)(const char *)reltag, reltag.length());	
		theDialog->SetLatentSub(vtag);
	}
	else
	{
		char buf[512];
		Size len;
		vtag->GetText(buf, 511, &len);
		vendortag.set(buf, len);
		rtag->GetText(buf, 511, &len);
		reltag.set(buf, len);
		
	}
}
#endif /* qMacCvsPP */

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

	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(UCvsImport, UWidget)

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

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

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

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

class UCvsImport_MAIN : public UWidget
{
	UDECLARE_DYNAMIC(UCvsImport_MAIN)
public:
	UCvsImport_MAIN(const char *logmsg, const char *modname,
					const char *rtag, const char *vtag);
	virtual ~UCvsImport_MAIN() {}

	enum
	{
		kEditModule = EV_COMMAND_START,	// 0
		kEditLog,						// 1
		kEditVendor,					// 2
		kEditRelease					// 3
	};

	virtual void DoDataExchange(bool fill);

	UStr m_logmsg;
	UStr m_modname;
	UStr m_rtag;
	UStr m_vtag;
protected:

	UDECLARE_MESSAGE_MAP()
};

UIMPLEMENT_DYNAMIC(UCvsImport_MAIN, UWidget)

UBEGIN_MESSAGE_MAP(UCvsImport_MAIN, UWidget)
UEND_MESSAGE_MAP()

UCvsImport_MAIN::UCvsImport_MAIN(const char *logmsg, const char *modname,
								 const char *rtag, const char *vtag) : UWidget(::UEventGetWidID())
{
	m_logmsg = logmsg;
	m_modname = modname;
	m_rtag = rtag;
	m_vtag = vtag;
}

void UCvsImport_MAIN::DoDataExchange(bool fill)
{
	::DoDataExchange(fill, GetWidID(), kEditModule, gOldModules);
	::DoDataExchange(fill, GetWidID(), kEditRelease, gReleasesNames);
	::DoDataExchange(fill, GetWidID(), kEditVendor, gVendorNames);

	if(fill)
	{
		UEventSendMessage(GetWidID(), EV_SETTEXT, kEditLog, (void *)(const char *)m_logmsg);
		UEventSendMessage(GetWidID(), EV_SETTEXT, kEditModule, (void *)(const char *)m_modname);
		UEventSendMessage(GetWidID(), EV_SETTEXT, kEditRelease, (void *)(const char *)m_rtag);
		UEventSendMessage(GetWidID(), EV_SETTEXT, kEditVendor, (void *)(const char *)m_vtag);
	}
	else
	{
		UEventSendMessage(GetWidID(), EV_GETTEXT, kEditLog, &m_logmsg);
		UEventSendMessage(GetWidID(), EV_GETTEXT, kEditModule, &m_modname);
		UEventSendMessage(GetWidID(), EV_GETTEXT, kEditRelease, &m_rtag);
		UEventSendMessage(GetWidID(), EV_GETTEXT, kEditVendor, &m_vtag);
	}
}

class UCvsImport_OPTIONS : public UWidget
{
	UDECLARE_DYNAMIC(UCvsImport_OPTIONS)
public:
	UCvsImport_OPTIONS(const char *path);
	virtual ~UCvsImport_OPTIONS() {}

	enum
	{
		kStatPath = EV_COMMAND_START,	// 0
		kBtnChange						// 1
	};

	virtual void DoDataExchange(bool fill);

	UStr m_path;
protected:

	ev_msg int OnChange(void);

	UDECLARE_MESSAGE_MAP()
};

UIMPLEMENT_DYNAMIC(UCvsImport_OPTIONS, UWidget)

UBEGIN_MESSAGE_MAP(UCvsImport_OPTIONS, UWidget)
	ON_UCOMMAND(UCvsImport_OPTIONS::kBtnChange, UCvsImport_OPTIONS::OnChange)
UEND_MESSAGE_MAP()

UCvsImport_OPTIONS::UCvsImport_OPTIONS(const char *path) : UWidget(::UEventGetWidID())
{
	m_path = path;
}

int UCvsImport_OPTIONS::OnChange()
{
	CStr dir;
	if( BrowserGetDirectory("Select a directory to import from", dir) )
	{
		UEventSendMessage(GetWidID(), EV_SETTEXT, kStatPath, (void*)dir.c_str());
	}

	return 0;
}

void UCvsImport_OPTIONS::DoDataExchange(bool fill)
{
	if(fill)
	{
		UEventSendMessage(GetWidID(), EV_SETTEXT, kStatPath, (void *)(const char *)m_path);
	}
	else
	{
		UEventSendMessage(GetWidID(), EV_GETTEXT, kStatPath, &m_path);
	}
}
#endif // qUnix

/// Get the import options
bool CompatGetImport(const MultiFiles* mf,
					 CPStr& modname, CStr& logmsg,
					 CPStr& vendortag, CPStr& reltag, CPStr& vendorBranchId, CPStr& path, 
					 bool& useDefIgnore, bool& useFilesTime, bool& createSandbox)
{
	bool userHitOK = false;

	modname = "";
	logmsg = "";
	vendortag = "";
	reltag = "";
	vendorBranchId = "";
	useDefIgnore = false;
	useFilesTime = false;
	createSandbox = false;

	static CPStr sLastModName;	/*Obsolete - remove it and always use sFolder! Get rid after all platforms have combo boxes for recent modules!*/
	
	static CPStr sFolder;
	static CStr sLastMsg;
	static CPStr sLastVTag("avendor");
	static CPStr sLastRTag("arelease");
	
	bool hasVendorBranchId = false;

	// Find out the folder so we can suggest the module name
	CStr uppath, folder;
	if( SplitPath(path, uppath, folder) )
		sFolder = folder;
	
	if( sLastModName.length() == 0L )	/*Obsolete - see above*/
	{
		sLastModName = folder;
	}

#ifdef WIN32
	CPropertySheet pages("Import settings");
	pages.m_psh.dwFlags |= PSH_NOAPPLYNOW;
	
	CImport_MAIN page1(mf, sLastMsg, sFolder, sLastRTag, sLastVTag);
	CImport_OPTIONS page2(mf, path, useDefIgnore, useFilesTime, createSandbox);
	CGetPrefs_CVSROOT page3;
	CGetPrefs_GLOBALS page4;

	pages.AddPage(&page1);
	pages.AddPage(&page2);
	pages.AddPage(&page3);
	pages.AddPage(&page4);
	
	if( pages.DoModal() == IDOK )
	{
		sLastModName = (const char*)page1.m_moduleName;
		sLastMsg = (const char*)page1.m_logmsg;
		sLastVTag = (const char*)page1.m_vtag;
		sLastRTag = (const char*)page1.m_rtag;
		hasVendorBranchId = page2.m_hasVendorBranch == TRUE;
		vendorBranchId = (const char*)page2.m_vendorBranch;
		path = (const char*)page2.m_path;
		
		useDefIgnore = page2.m_useDefIgnore == TRUE;
		useFilesTime = page2.m_useFilesTime == TRUE;
		createSandbox = page2.m_createSandbox == TRUE;

		page3.StoreValues();
		page4.StoreValues();
		userHitOK = true;
	}
#endif /* WIN32 */

#ifdef qMacCvsPP
	StDialogHandler	theHandler(dlg_Import, LCommander::GetTopCommander());
	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);
	
	multiView->SwitchToPanel(3);
	DoDataExchange_Globals(theDialog, true);
	multiView->SwitchToPanel(2);
	DoDataExchange (theDialog, item_ImportCvsIgnore, useDefIgnore, true);
	DoDataExchange (theDialog, item_ShowPath, path, true);
	dynamic_cast<LControl*> (theDialog->FindPaneByID (item_EditPath))->AddListener (&theHandler);
	
	multiView->SwitchToPanel(1);
	DoDataExchange_ImportMain(theDialog, sLastModName, sLastMsg, true);
	DoDataExchange_ImportTags(theDialog, sLastVTag, sLastRTag, 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;

		if(hitMessage == item_EditPath)
		{
			CStr dir;
			if( BrowserGetDirectory("Select a directory to import from", dir) )
			{
				CPStr tmp(dir.c_str());
				theDialog->SetDescriptorForPaneID(item_ShowPath, tmp);
			}
		}
	}
	theDialog->Hide();
	sRuntimePanel = groupView->GetValue();
	
	if(hitMessage == msg_OK)
	{
		multiView->SwitchToPanel(1);
		DoDataExchange_ImportMain(theDialog, sLastModName, sLastMsg, false);
		DoDataExchange_ImportTags(theDialog, sLastVTag, sLastRTag, false);
		multiView->SwitchToPanel(2);
		DoDataExchange (theDialog, item_ImportCvsIgnore, useDefIgnore, false);
		DoDataExchange (theDialog, item_ShowPath, path, false);
		multiView->SwitchToPanel(3);
		DoDataExchange_Globals(theDialog, false);
		
		Assert_(sLastModName.length() != 0);
		
		userHitOK = true;
	}
#endif /* qMacCvsPP */

#if qUnix
	void *wid = UCreate_ImportDlg();

	UCvsImport *dlg = new UCvsImport();
	UCvsImport_MAIN *tab1 = new UCvsImport_MAIN(sLastMsg, sLastModName, sLastRTag, sLastVTag);
	UCvsImport_OPTIONS *tab2 = new UCvsImport_OPTIONS(path);
	UEventSendMessage(dlg->GetWidID(), EV_INIT_WIDGET, kUMainWidget, wid);	
	dlg->AddPage(tab1, UCvsImport::kTabGeneral, 0);
	dlg->AddPage(tab2, UCvsImport::kTabGeneral, 1);

	if(dlg->DoModal())
	{
		sLastModName = tab1->m_modname;
		sLastMsg = tab1->m_logmsg;
		sLastVTag = tab1->m_vtag;
		sLastRTag = tab1->m_rtag;
		path = tab2->m_path;

		userHitOK = true;
	}

	delete dlg;
#endif // qUnix

	if( userHitOK )
	{
		gCvsPrefs.save();
		
		if( sLastMsg.length() == 0 )
			sLastMsg = "no message";

		if( sLastVTag.length() == 0 )
			sLastVTag = "initial";

		if( sLastRTag.length() == 0 )
			sLastRTag = "start";

		if( !hasVendorBranchId )
		{
			vendorBranchId = "";
		}

		modname = sLastModName;
		logmsg = sLastMsg;
		vendortag = sLastVTag;
		reltag = sLastRTag;

#ifdef TARGET_OS_MAC
		logmsg.replace('\015', '\012');
#endif /* TARGET_OS_MAC */
	}

	return userHitOK;
}
