/******************************************************************************
 SyGBindingsManager.cc

	<Description>

	BASE CLASS = virtual public JBroadcaster

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

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

#include <SyGBindingsManager.h>
#include <BindingsDir.h>
#include "BDDefBindingsFile.h"

#include <JXApplication.h>

#include <JString.h>

#include <jFileUtil.h>
#include <jDirUtil.h>
#include <jStreamUtil.h>
#include <jStrStreamUtil.h>
#include <jXGlobals.h>

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

static const JCharacter* kUserExtensionBindingFile = ".systemG.filebindings";
static const JCharacter* kGlobalExtensionBindingFile = "filebindings";
static const JCharacter* kDefaultFileAction = "xterm -e less \"$f\"";
static const JCharacter* kAltDefaultFileAction = "xterm -e vi \"$f\"";

const JIndex		kCurrentVersion 	= 1;
const JIndex		kCurrentRevision 	= 0;

const JCoordinate kCurrentPrefsVersion	= 1;

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

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

SyGBindingsManager::SyGBindingsManager
	(
	JPrefsManager* prefsMgr, 
	const JPrefID& id
	)
	:
   JBroadcaster(),
   JPrefObject(prefsMgr, id)
{
	itsBindingsDir = NULL;
	JPrefObject::ReadPrefs();
}

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

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

SyGBindingsManager::~SyGBindingsManager()
{
	JPrefObject::WritePrefs();
}

/******************************************************************************
 GetAppForFile (public)


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

JString
SyGBindingsManager::GetAppForFile
	(
	const JString& file, 
	const JBoolean alternate
	)
{
	JString homeDir;
	JString userBindings;
	JString globalBindings("/usr/local/lib/systemg/filebindings");
	JBoolean hasUserBindings 	= kFalse;
	JBoolean hasGlobalBindings 	= kFalse;
	JBoolean hasDefault 		= kFalse;

	if (JGetHomeDirectory(&homeDir))
		{
		userBindings 	= homeDir + kUserExtensionBindingFile;
		hasUserBindings = JFileExists(userBindings);
		if (!hasUserBindings)
			{
			GenerateDefaultBindingsFile();
			}
		}
		
	hasGlobalBindings 	= JFileExists(globalBindings);
	if (hasGlobalBindings)
		{
		hasGlobalBindings 	= JFileReadable(globalBindings);
		}

	JBoolean found = kFalse;
	JString ext;
	JString act;
	JString mAct;
	JString icon;
	JString nDefault;
	JString altDefault;
	JString theAction;

	ifstream is(userBindings);
	if (is.good())
		{
		int version;
		int revision;
		is >> version;
		if (is.fail())
			{
			is.clear();
			}
		else
			{
			is >> revision;
			is >> ws;
			}
		while ((found == kFalse) && !is.eof())
			{
			JBoolean success;
			JString line = JReadLine(is, &success);
			if (success)
				{
				const JCharacter* cline = line;
				jistrstream(linestream, cline, line.GetLength());
				
				linestream >> ext;
				linestream >> act;
				linestream >> mAct;
				linestream >> icon;   // This will hold icon file;
				
				if (linestream.fail())
					{
					icon = "";
					}
				
				if (ext == "<default>")
					{
					hasDefault	= kTrue;
					nDefault 	= act;
					altDefault 	= mAct;
					}
				
				else if (file.EndsWith(ext, kFalse))
					{
					found 		= kTrue;
					}
				}
			}
		}
	
	ifstream isg(globalBindings);
	if (isg.good())
		{
		int version;
		int revision;
		isg >> version;
		if (isg.fail())
			{
			isg.clear();
			}
		else
			{
			isg >> revision;
			}
		while ((found == kFalse) && !isg.eof())
			{
			JBoolean success;
			JString line = JReadLine(isg, &success);
			if (success)
				{
				const JCharacter* cline = line;
				jistrstream(linestream, cline, line.GetLength());
				
				linestream >> ext;
				linestream >> act;
				linestream >> mAct;
				linestream >> icon;   // This will hold icon file;
				
				if (linestream.fail())
					{
					icon = "";
					}
				
				if (!hasDefault && (ext == "<default>"))
					{
					hasDefault	= kTrue;
					nDefault 	= act;
					altDefault 	= mAct;
					}
				
				else if (file.EndsWith(ext, kFalse))
					{
					found 		= kTrue;
					}
				}
			}
		}
		
	if (found == kFalse)
		{
		if (alternate)
			{
			if (hasDefault)
				{
				theAction 	= altDefault;
				}
			else
				{
				theAction 	= kAltDefaultFileAction;
				}
			}
		else
			{
			if (hasDefault)
				{
				theAction 	= nDefault;
				}
			else
				{
				theAction 	= kDefaultFileAction;
				}
			}
		}
	else
		{
		if (alternate)
			{
			theAction = mAct;
			}
		else 
			{
			theAction = act;
			}
		}
	return theAction;
}

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

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

void
SyGBindingsManager::Receive
	(
	JBroadcaster* 	sender, 
	const Message&	message
	)
{
	if (sender == itsBindingsDir && message.Is(BindingsDir::kEditorClosing))
		{
		ostrstream data;
		itsBindingsDir->WriteSetup(data);
		itsDialogPrefs = data.str();
		JUnfreeze(data);
		itsBindingsDir = NULL;
		}
}

/******************************************************************************
 EditBindings (public)


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

void
SyGBindingsManager::EditBindings()
{
	if (itsBindingsDir == NULL)
		{
		JString homeDir;
		if (JGetHomeDirectory(&homeDir))
			{
			JString userBindings 		= homeDir + kUserExtensionBindingFile;
			JBoolean hasUserBindings	= JFileExists(userBindings);
			if (!hasUserBindings)
				{
				GenerateDefaultBindingsFile();
				}
			}
		if (BindingsDir::Create(JXGetApplication(), &itsBindingsDir))
			{
			if (!itsDialogPrefs.IsEmpty())
				{
				jistrstream(is, itsDialogPrefs.GetCString(), itsDialogPrefs.GetLength());
				itsBindingsDir->ReadSetup(is);
				}
			ListenTo(itsBindingsDir);
			if (!itsHelpSection.IsEmpty())
				{
				itsBindingsDir->SetHelpSection(itsHelpSection);
				}
			itsBindingsDir->Activate();
			}
		else
			{
			itsBindingsDir = NULL;
			}
		}
	else
		{
		itsBindingsDir->Activate();
		}
}

/******************************************************************************
 ReadPrefs

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

void
SyGBindingsManager::ReadPrefs
	(
	istream& input
	)
{
	JCoordinate version;
	input >> version;
	input >> itsDialogPrefs;
}

/******************************************************************************
 WritePrefs

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

void
SyGBindingsManager::WritePrefs
	(
	ostream& output
	)
	const
{
	output << kCurrentPrefsVersion << ' ';
	output << itsDialogPrefs << ' ';
}

/******************************************************************************
 GenerateDefaultBindingsFile (private)

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

void
SyGBindingsManager::GenerateDefaultBindingsFile()
{
	JString bindings(bdbindingdata);
	JString homeDir;
	if (JGetHomeDirectory(&homeDir))
		{
		JString userBindings 	= homeDir + kUserExtensionBindingFile;
		ofstream os(userBindings);
		bindings.Print(os);
		}
}

/******************************************************************************
 SetHelpSection (public)

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

void
SyGBindingsManager::SetHelpSection
	(
	const JCharacter* section
	)
{
	itsHelpSection = section;
}
