/******************************************************************************
 SyGPrefsMgr.cc

	<Description>

	BASE CLASS = public JUNIXPrefsManager

	Copyright © 1998 by Glenn W. Bach.  All rights reserved.
	
	Base code generated by Codemill v0.1.0

 *****************************************************************************/

#include <SyGPrefsMgr.h>
#include <SyGGlobals.h>
#include <SyGApplication.h>
#include <SyGBindingsManager.h>
#include <SyGEditPrefsDialog.h>

#include <JXApplication.h>
#include <JXDisplay.h>
#include <JXChooseSaveFile.h>
#include <JXFontManager.h>
#include <JXStringHistoryMenu.h>

#include <JStaticBuffer.h>
#include <JPtrArray-JString.h>
#include <JOrderedSet.h>

#include <jUNIXUtil.h>
#include <jTypes.h>
#include <jStrStreamUtil.h>
#include <jDirUtil.h>
#include <jProcessUtil.h>

#include <unistd.h>
#include <stdlib.h>
#include <strstream.h>
#include <iostream.h>
#include <jAssert.h>

const JFileVersion kCurrentPrefsFileVersion 	= 4;

const JCharacter* kSyGAppSig 					= "gSystemG";
const JCharacter* kSyGDefaultTermCmd			= "xterm -title $n -n $n";
const JCharacter* kSyGDefaultManCmd				= "jcc --man";

extern const JCharacter* kSyGFileName;
extern const JCharacter* kSystemGVersionNumberStr;

const JCharacter* SyGPrefsMgr::kSyGPrefsChanged	= "SyGPrefsChanged::SyGPrefsMgr";

/******************************************************************************
 Constructor

 *****************************************************************************/

SyGPrefsMgr::SyGPrefsMgr
	(
	JBoolean* isNew
	)
	:
   JUNIXPrefsManager(kSyGAppSig, kCurrentPrefsFileVersion, kTrue)
{
	itsDialog	= NULL;
	
	*isNew = JPrefsManager::UpgradeData();
}

/******************************************************************************
 Destructor

 *****************************************************************************/

SyGPrefsMgr::~SyGPrefsMgr()
{
	SetData(kSProgramVersionID, kSystemGVersionNumberStr);

	SaveToDisk();
}

/******************************************************************************
 GetJCCVersionStr

 ******************************************************************************/

JString
SyGPrefsMgr::GetSystemGVersionStr()
	const
{
	JStaticBuffer data;
	if (GetData(kSProgramVersionID, &data))
		{
		return JString(data);
		}
	else
		{
		return JString("< 0.4.0");		// didn't exist before this version
		}
}

/******************************************************************************
 UpgradeData (virtual protected)

 ******************************************************************************/

void
SyGPrefsMgr::UpgradeData
	(
	const JBoolean		isNew,
	const JFileVersion	currentVersion
	)
{

	if (isNew)
		{
		JBoolean prefs[7] = {kFalse,kFalse,kFalse,kFalse,kFalse,kFalse,kFalse};
		SetTreePreferences(prefs);
		SaveDefaultWindowSize(380, 300);
		SaveFilterStatePref(kFalse);
		}
	else if (currentVersion < 4)
		{
		SaveDefaultWindowSize(380, 480);
		}
}

/******************************************************************************
 Receive (virtual protected)

 ******************************************************************************/

void
SyGPrefsMgr::Receive
	(
	JBroadcaster* 	sender, 
	const Message&	message
	)
{
	if (sender == itsDialog && message.Is(JXDialogDirector::kDeactivated))
		{
		const JXDialogDirector::Deactivated* info = 
			dynamic_cast(const JXDialogDirector::Deactivated*, &message);
		assert(info != NULL);
		if (info->Successful())
			{
			UpdatePrefs();
			}
		itsDialog = NULL;
		}
}

/******************************************************************************
 EditPrefs (public)

 ******************************************************************************/

void
SyGPrefsMgr::EditPrefs()
{
	assert(itsDialog == NULL);

	JString manCmd 	= GetManViewCmd();
	JString termCmd = GetTerminalCmd();
	JBoolean move	= IsMovingByDefault();
	JBoolean trash	= BSIsTrashing();
	JBoolean warn	= IsWarningBeforeTrash();

	itsDialog = 
		new SyGEditPrefsDialog(JXGetApplication(), termCmd, manCmd, 
			move, trash, warn);
	assert(itsDialog != NULL);

	itsDialog->BeginDialog();
	ListenTo(itsDialog);
}

/******************************************************************************
 UpdatePrefs (public)

 ******************************************************************************/

void
SyGPrefsMgr::UpdatePrefs()
{
	assert(itsDialog != NULL);
	JString manCmd, termCmd;
	JBoolean move, trash, warn;

	itsDialog->GetPrefs(&termCmd, &manCmd, &move, &trash, &warn);
	SetTerminalCmd(termCmd);
	SetManViewCmd(manCmd);
	ShouldMoveByDefault(move);
	BSShouldTrash(trash);
	ShouldWarnBeforeTrash(warn);
	Broadcast(SyGPrefsChanged());
}

/******************************************************************************
 SetManViewCmd (public)

 ******************************************************************************/

void
SyGPrefsMgr::SetManViewCmd
	(
	const JCharacter* manCmd
	)
{
	ostrstream data;
	data << JString(manCmd);

	SetData(kSManCmdID, data);
}

/******************************************************************************
 GetManViewCmd (public)

 ******************************************************************************/

JString
SyGPrefsMgr::GetManViewCmd()
	const
{
	JString manCmd;
	if (IDValid(kSManCmdID))
		{
		JStaticBuffer data;
		GetData(kSManCmdID, &data);
		jistrstream(dataStream, data.GetData(), strlen(data));
		dataStream >> manCmd;
		}
	else
		{
		manCmd = kSyGDefaultManCmd;
		}
	return manCmd;
}

/******************************************************************************
 SetTerminalCmd (public)

 ******************************************************************************/

void
SyGPrefsMgr::SetTerminalCmd
	(
	const JCharacter* termCmd
	)
{
	ostrstream data;
	data << JString(termCmd);

	SetData(kSTermCmdID, data);
}

/******************************************************************************
 GetTerminalCmd (public)

 ******************************************************************************/

JString
SyGPrefsMgr::GetTerminalCmd()
	const
{
	JString termCmd;
	if (IDValid(kSTermCmdID))
		{
		JStaticBuffer data;
		GetData(kSTermCmdID, &data);
		jistrstream(dataStream, data.GetData(), strlen(data));
		dataStream >> termCmd;
		}
	else
		{
		termCmd = kSyGDefaultTermCmd;
		}
	return termCmd;
}

/******************************************************************************
 TreePreferences

 ******************************************************************************/

void
SyGPrefsMgr::SetTreePreferences
	(
	JBoolean 		prefs[]
	)
{
	ostrstream data;
	for (JIndex i = 0; i < 7; i++)
		{
		data << prefs[i];
		}
		
	SetData(kSTreeOptionsID, data);
}

void
SyGPrefsMgr::GetTreePreferences
	(
	JBoolean prefs[]
	)
	const
{
	JStaticBuffer data;
	const JBoolean ok = GetData(kSTreeOptionsID, &data);
	assert( ok );

	jistrstream(dataStream, data.GetData(), strlen(data));
	for (JIndex i = 0; i < 7; i++)
		{
		dataStream >> prefs[i];
		}
}

/******************************************************************************
 DefaultWindowSize

 ******************************************************************************/

void
SyGPrefsMgr::GetDefaultWindowSize
	(
	JSize* w, 
	JSize* h
	)
	const
{
	JStaticBuffer data;
	const JBoolean ok = GetData(kSDefaultWindowSizeID, &data);
	assert( ok );

	jistrstream(dataStream, data.GetData(), strlen(data));
	dataStream >> *w;
	dataStream >> *h;
}

void
SyGPrefsMgr::SaveDefaultWindowSize
	(
	const JSize w, 
	const JSize h
	)
{
	ostrstream data;
	data << w << ' ' << h;
	SetData(kSDefaultWindowSizeID, data);
}

/******************************************************************************
 FilterHistoryPrefs

 ******************************************************************************/

void
SyGPrefsMgr::SaveFilterHistoryPrefs
	(
	JXStringHistoryMenu* filterHistory
	)
{
	ostrstream data;
	filterHistory->WriteSetup(data);
	SetData(kSFilterHistoryID, data);
}

void
SyGPrefsMgr::GetFilterHistoryPrefs
	(
	JXStringHistoryMenu* filterHistory
	)
	const
{
	if (IDValid(kSFilterHistoryID))
		{
		JStaticBuffer data;
		GetData(kSFilterHistoryID, &data);
		jistrstream(dataStream, data.GetData(), strlen(data));
		filterHistory->ReadSetup(dataStream);
		}
}

/******************************************************************************
 FilterStatePref

 ******************************************************************************/

void
SyGPrefsMgr::SaveFilterStatePref
	(
	const JBoolean show
	)
{
	ostrstream data;
	data << show << ' ';
	SetData(kSFilterVisibleID, data);
}

JBoolean
SyGPrefsMgr::GetFilterStatePref()
	const
{
	JBoolean show = kFalse;
	if (IDValid(kSFilterVisibleID))
		{
		JStaticBuffer data;
		GetData(kSFilterVisibleID, &data);
		jistrstream(dataStream, data.GetData(), strlen(data));
		dataStream >> show;
		}
	return show;
}

/******************************************************************************
 Shortcuts

 ******************************************************************************/

void
SyGPrefsMgr::SaveShortcuts
	(
	const JPtrArray<JString>& shortcuts
	)
{
	JSize count = shortcuts.GetElementCount();
	ostrstream data;
	data << count << ' ';
	for (JSize i = 1; i <= count; i++)
		{
		data << *(shortcuts.NthElement(i));
		}
	SetData(kSShortcutStringsID, data);
}

void
SyGPrefsMgr::GetShortcuts
	(
	JPtrArray<JString>* shortcuts
	)
	const
{
	if (IDValid(kSShortcutStringsID))
		{
		JStaticBuffer data;
		GetData(kSShortcutStringsID, &data);
		jistrstream(dataStream, data.GetData(), strlen(data));

		JSize count;
		dataStream >> count;		
		for (JSize i = 1; i <= count; i++)
			{
			JString* str = new JString;
			dataStream >> *str;
			shortcuts->Append(str);
			}
		}
}

/******************************************************************************
 ChildWindows

 ******************************************************************************/

void
SyGPrefsMgr::SaveChildWindows
	(
	const JPtrArray<JString>& children
	)
{
	JSize count = children.GetElementCount();
	ostrstream data; 
	data << count << ' ';
	for (JSize i = 1; i <= count; i++)
		{
		data << *(children.NthElement(i));
		}
	SetData(kSChildWindowListID, data);
}

void
SyGPrefsMgr::GetChildWindows
	(
	JPtrArray<JString>* children
	)
	const
{
	if (IDValid(kSChildWindowListID))
		{
		JStaticBuffer data;
		GetData(kSChildWindowListID, &data);
		jistrstream(dataStream, data.GetData(), strlen(data));
		JSize count;
		dataStream >> count;		
		for (JSize i = 1; i <= count; i++)
			{
			JString* str = new JString;
			dataStream >> *str;
			children->Append(str);
			}
		}
}

/******************************************************************************
 Default DND action

 ******************************************************************************/

void
SyGPrefsMgr::ShouldMoveByDefault
	(
	const JBoolean move
	)
{
	ostrstream data;
	data << move << ' ';
	SetData(kSDefActionID, data);
}

JBoolean
SyGPrefsMgr::IsMovingByDefault()
	const
{
	JBoolean move = kTrue;
	if (IDValid(kSDefActionID))
		{
		JStaticBuffer data;
		GetData(kSDefActionID, &data);
		jistrstream(dataStream, data.GetData(), strlen(data));
		dataStream >> move;
		}
	return move;
}

/******************************************************************************
 Backspace action

 ******************************************************************************/

void
SyGPrefsMgr::BSShouldTrash
	(
	const JBoolean trash
	)
{
	ostrstream data;
	data << trash << ' ';
	SetData(kSBSActionID, data);
}

JBoolean
SyGPrefsMgr::BSIsTrashing()
	const
{
	JBoolean trash = kTrue;
	if (IDValid(kSBSActionID))
		{
		JStaticBuffer data;
		GetData(kSBSActionID, &data);
		jistrstream(dataStream, data.GetData(), strlen(data));
		dataStream >> trash;
		}
	return trash;
}

/******************************************************************************
 Trash warning

 ******************************************************************************/

void
SyGPrefsMgr::ShouldWarnBeforeTrash
	(
	const JBoolean warn
	)
{
	ostrstream data;
	data << warn << ' ';
	SetData(kSWarnTrashID, data);
}

JBoolean
SyGPrefsMgr::IsWarningBeforeTrash()
	const
{
	JBoolean warn = kTrue;
	if (IDValid(kSWarnTrashID))
		{
		JStaticBuffer data;
		GetData(kSWarnTrashID, &data);
		jistrstream(dataStream, data.GetData(), strlen(data));
		dataStream >> warn;
		}
	return warn;
}
