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

// LineCmd.cpp : implementation file
//

#include "stdafx.h"

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

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

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

#include "LineCmd.h"
#include "CvsArgs.h"
#include "PromptFiles.h"
#include "CPStr.h"
#include "TextBinary.h"

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

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

#ifdef qMacCvsPP
static void DoDataExchange_CmdlineMain(LWindow *theDialog, CStr & cmdline, CPStr & path, bool & hasPath, bool putValue)
{
	LCheckBoxGroupBox *cbox = dynamic_cast<LCheckBoxGroupBox*>
		(theDialog->FindPaneByID(item_CheckGroupPath));
	LPushButton *epath = dynamic_cast<LPushButton*>
		(theDialog->FindPaneByID(item_EditPath));
	LTextEditView *cline = dynamic_cast<LTextEditView*>
		(theDialog->FindPaneByID(item_NonEmptyTextEdit));
	
	if(putValue)
	{
		cline->SetTextPtr((Ptr)(const char *)cmdline, cmdline.length());
		cbox->SetValue(hasPath ? Button_On : Button_Off);
		epath->SetDescriptor(path);
		
		// this will take care about an empty module name
		theDialog->SetLatentSub(cline);
		//cline->AddListener(CMacCvsApp::app);
		if(cmdline.length() == 0)
		{
			LPushButton *theOK = dynamic_cast<LPushButton*>
										(theDialog->FindPaneByID(item_OK));
			Assert_(theOK != 0L);
			theOK->Disable();
		}
	}
	else
	{
		Handle hdl = cline->GetTextHandle();
		Assert_(hdl != 0L);
		cmdline.set(*hdl, GetHandleSize(hdl));
		
		Str255 outDescriptor;
		epath->GetDescriptor(outDescriptor);
		path = outDescriptor;
		hasPath = cbox->GetValue() == Button_On;
	}
}
#endif /* qMacCvsPP */

#ifdef WIN32
#include "GetPrefs.h"
#include "CvsPrefs.h"

IMPLEMENT_DYNCREATE(CCmdLine_MAIN, CPropertyPage)

CCmdLine_MAIN::CCmdLine_MAIN(const char *lastcmd, bool hasPath,
							 const char *lastpath) : CPropertyPage(CCmdLine_MAIN::IDD)
{
	//{{AFX_DATA_INIT(CCmdLine_MAIN)
	m_checkpath = hasPath;
	m_cmdline = lastcmd;
	m_folderloc = lastpath;
	//}}AFX_DATA_INIT
}

CCmdLine_MAIN::CCmdLine_MAIN() : CPropertyPage(CCmdLine_MAIN::IDD)
{
}

CCmdLine_MAIN::~CCmdLine_MAIN()
{
}

void CCmdLine_MAIN::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CCmdLine_MAIN)
	DDX_Control(pDX, IDC_SELFOLDER, m_selfolder);
	DDX_Check(pDX, IDC_CHECKPATH, m_checkpath);
	DDX_Text(pDX, IDC_CMDLINE, m_cmdline);
	DDV_MinChars(pDX, m_cmdline, 1);
	DDX_Text(pDX, IDC_FOLDERLOC, m_folderloc);
	//}}AFX_DATA_MAP

	if(!pDX->m_bSaveAndValidate)
	{
		m_selfolder.EnableWindow(m_checkpath);
	}
}


BEGIN_MESSAGE_MAP(CCmdLine_MAIN, CPropertyPage)
	//{{AFX_MSG_MAP(CCmdLine_MAIN)
	ON_BN_CLICKED(IDC_CHECKPATH, OnCheckpath)
	ON_BN_CLICKED(IDC_SELFOLDER, OnSelfolder)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCmdLine_MAIN message handlers

void CCmdLine_MAIN::OnCheckpath() 
{
	CButton* but = (CButton *)GetDlgItem(IDC_CHECKPATH);
	int isChecked = but->GetCheck();
	m_selfolder.EnableWindow(isChecked);
	if(isChecked)
	{
		OnSelfolder();
	}
}

void CCmdLine_MAIN::OnSelfolder() 
{
	const char *dir = BrowserGetDirectory("Select where to execute :", IsWindow(this->m_hWnd) ? this : NULL);
	SetDlgItemText(IDC_FOLDERLOC, dir != 0L ? dir : "");

	if(dir == 0L)
	{
		CButton* but = (CButton *)GetDlgItem(IDC_CHECKPATH);
		but->SetCheck(FALSE);
		m_selfolder.EnableWindow(FALSE);
	}
}
#endif /* WIN32 */

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

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

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

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

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

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

class UCvsCmdline_MAIN : public UWidget
{
	UDECLARE_DYNAMIC(UCvsCmdline_MAIN)
public:
	UCvsCmdline_MAIN(const char *lastcmd, bool hasPath,
					 const char *lastpath);
	virtual ~UCvsCmdline_MAIN() {}

	enum
	{
		kEditCmd = EV_COMMAND_START,	// 0
		kCheckPath,			// 1
		kStatPath,			// 2
		kBtnPath			// 3
	};

	virtual void DoDataExchange(bool fill);

	bool m_checkpath;
	UStr m_cmdline;
	UStr m_folderloc;
protected:
	ev_msg int OnCheckPath(void);
	ev_msg int OnBtnPath(void);

	UDECLARE_MESSAGE_MAP()
};

UIMPLEMENT_DYNAMIC(UCvsCmdline_MAIN, UWidget)

UBEGIN_MESSAGE_MAP(UCvsCmdline_MAIN, UWidget)
	ON_UCOMMAND(UCvsCmdline_MAIN::kCheckPath, UCvsCmdline_MAIN::OnCheckPath)
	ON_UCOMMAND(UCvsCmdline_MAIN::kBtnPath, UCvsCmdline_MAIN::OnBtnPath)
UEND_MESSAGE_MAP()

UCvsCmdline_MAIN::UCvsCmdline_MAIN(const char *lastcmd, bool hasPath,
							 const char *lastpath) : UWidget(::UEventGetWidID())
{
	m_checkpath = hasPath;
	m_cmdline = lastcmd;
	m_folderloc = lastpath;
}

int UCvsCmdline_MAIN::OnCheckPath()
{
	int state = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kCheckPath, 0L);
	UEventSendMessage(GetWidID(), EV_ENABLECMD, UMAKEINT(kStatPath, state), 0L);
	UEventSendMessage(GetWidID(), EV_ENABLECMD, UMAKEINT(kBtnPath, state), 0L);
	return 0;
}

int UCvsCmdline_MAIN::OnBtnPath()
{
	const char *dir = BrowserGetDirectory("Select where to execute :");
	if(dir != 0L)
		UEventSendMessage(GetWidID(), EV_SETTEXT, kStatPath, (void *)dir);
	return 0;
}

void UCvsCmdline_MAIN::DoDataExchange(bool fill)
{
	if(fill)
	{
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(kCheckPath, m_checkpath), 0L);
		UEventSendMessage(GetWidID(), EV_SETTEXT, kEditCmd, (void *)(const char *)m_cmdline);
		UEventSendMessage(GetWidID(), EV_SETTEXT, kStatPath, (void *)(const char *)m_folderloc);

		OnCheckPath();
	}
	else
	{
		m_checkpath = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kCheckPath, 0L) != 0;
		UEventSendMessage(GetWidID(), EV_GETTEXT, kEditCmd, &m_cmdline);
		UEventSendMessage(GetWidID(), EV_GETTEXT, kStatPath, &m_folderloc);
	}
}
#endif // qUnix

bool CompatGetCommand(CvsArgs &args, const char * &dir)
{
	char cmd[MAX_CMD_LEN] = {'\0'};
	dir = 0L;

	static CStr sLastCmdline("cvs ");
#ifdef macintosh
	static CPStr sLastPath("pick:a:mac:path:");
#else /* !macintosh */
	static CPStr sLastPath("");
#endif /* !macintosh */
	static bool sLastHasPath = false;

#ifdef WIN32
	CPropertySheet pages("Command line settings");
	pages.m_psh.dwFlags |= PSH_NOAPPLYNOW;
	CCmdLine_MAIN page1(sLastCmdline, sLastHasPath, sLastPath);
	CGetPrefs_GLOBALS page2;
	pages.AddPage(&page1);
	pages.AddPage(&page2);
	if(pages.DoModal() == IDOK)
	{
		sLastCmdline = page1.m_cmdline;
		sLastHasPath = page1.m_checkpath == TRUE;
		sLastPath = page1.m_folderloc;

		dir = page1.m_checkpath ? (const char *)sLastPath : 0L;
		strcpy(cmd, page1.m_cmdline);

		page2.StoreValues();
		gCvsPrefs.save();
	}
	else
		return false;
#endif /* WIN32 */
#if qUnix
	void *wid = UCreate_CmdlineDlg();

	UCvsCmdline *dlg = new UCvsCmdline();
	UCvsCmdline_MAIN *tab1 = new UCvsCmdline_MAIN(sLastCmdline, sLastHasPath, sLastPath);
	UEventSendMessage(dlg->GetWidID(), EV_INIT_WIDGET, kUMainWidget, wid);	
	dlg->AddPage(tab1, UCvsCmdline::kTabGeneral, 0);

	if(dlg->DoModal())
	{
		sLastCmdline = tab1->m_cmdline;
		sLastHasPath = tab1->m_checkpath;
		sLastPath = tab1->m_folderloc;

		dir = tab1->m_checkpath ? (const char *)sLastPath : 0L;
		strcpy(cmd, tab1->m_cmdline);
	}
	else
	{
		delete dlg;
		return false;
	}

	delete dlg;
#endif // qUnix
#ifdef qMacCvsPP
	StDialogHandler	theHandler(dlg_Cmdline, 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);
	
	multiView->SwitchToPanel(2);
	DoDataExchange_Globals(theDialog, true);
	multiView->SwitchToPanel(1);
	DoDataExchange_CmdlineMain(theDialog, sLastCmdline, sLastPath, sLastHasPath, true);

	LCheckBoxGroupBox *cbox = dynamic_cast<LCheckBoxGroupBox*>
		(theDialog->FindPaneByID(item_CheckGroupPath));
	LPushButton *epath = dynamic_cast<LPushButton*>
		(theDialog->FindPaneByID(item_EditPath));
	epath->AddListener(&theHandler);
	cbox->AddListener(&theHandler);
	
	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_CheckGroupPath || hitMessage == item_EditPath)
		{
			cbox = dynamic_cast<LCheckBoxGroupBox*>
				(theDialog->FindPaneByID(item_CheckGroupPath));
			epath = dynamic_cast<LPushButton*>
				(theDialog->FindPaneByID(item_EditPath));
			if(cbox->GetValue() == Button_Off)
			{
				dir = 0L;
				continue;
			}
			
			dir = BrowserGetDirectory("Select where to execute :");
			if(dir != 0L)
			{
				CPStr tmp(dir);
				epath->SetDescriptor(tmp);
			}
			else if(hitMessage == item_CheckGroupPath)
			{
				cbox->SetValue(Button_Off);
			}
		}

	}
	theDialog->Hide();
	sRuntimePanel = groupView->GetValue();
	
	if(hitMessage == msg_OK)
	{
		multiView->SwitchToPanel(1);
		DoDataExchange_CmdlineMain(theDialog, sLastCmdline, sLastPath, sLastHasPath, false);
		multiView->SwitchToPanel(2);
		DoDataExchange_Globals(theDialog, false);
		
		strcpy(cmd, sLastCmdline);
		Assert_(sLastCmdline.length() != 0);
		dir = sLastHasPath ? (const char *)sLastPath : 0L;
	}
	else
		return false;
#endif /* qMacCvsPP */
	
	if(cmd[0] == '\0' || (dir != 0L && dir[0] == '\0'))
		return false;

	char *argv[MAX_ARGS];
	int argc = StringToArgv(cmd, argv);

	for (int i = 0; i < argc; i++)
		args.add(argv[i]);

	return true;
}
