////////////////////////////////////////////////////////////////
// This is the object that runs the app.

#import "GopherDispatcher.h"
#import <stdio.h>
int shouldUseSound = 0;

@implementation GopherDispatcher

// These are the global variables used to hold the
// hostname and port of the next Gopher to be opened.
char defaultHost[256];
int defaultPort;
int defaultApp;

//////////////////////////////////////////////////////////////
// Create a new Gopher window.

- newGopher:sender
{
    id		newWindow;

    strncpy(defaultHost, NXGetDefaultValue("Gopher", "GopherHost"), 256);
    [GopherHostTextItem setStringValue:defaultHost];

    defaultPort = atoi(NXGetDefaultValue("Gopher", "GopherPort"));
    [GopherPortTextItem setIntValue:defaultPort];

    defaultApp = atoi(NXGetDefaultValue("Gopher", "TermApp"));

    newWindow = [[GopherClient new] setDispatcher:self];
    [self newFrontWindow:newWindow];

    return self;
}

//////////////////////////////////////////////////////////////
// Open the Open window

- openWindow:sender
{
    [OpenHostTextItem setStringValue:defaultHost];
    [OpenPortTextItem setIntValue:defaultPort];
    [OpenWindow makeKeyAndOrderFront:self];

    return self;
}

//////////////////////////////////////////////////////////////
// Open a new Gopher.

- openGopher:sender
{
    id		newWindow;

    [OpenWindow performClose:self];

    strncpy(defaultHost, [OpenHostTextItem stringValue], 250);
    defaultPort = [OpenPortTextItem intValue];

    newWindow = [[GopherClient new] setDispatcher:self];
    [self newFrontWindow:newWindow];


    return self;
}

//////////////////////////////////////////////////////////////
// Close the current Gopher.

- closeGopher:sender
{
    [self oldFrontWindow:currentWindow];
    [currentWindow close];

    return self;
}

//////////////////////////////////////////////////////////////
// Print the contents of the current window.
// Since the Print... menu item should be disabled when necessary,
// the current window should always be a Gopher window when this
// comes up.

- print:sender
{
    [currentWindow print];

    return self;
}

//////////////////////////////////////////////////////////////
// Save the contents of the current window.

- save:sender
{
    id mySavePanel;

    mySavePanel = [SavePanel new];
    [mySavePanel setTitle:"Save Gopher text"];
    [mySavePanel setPrompt:"Save text into :"];

    if ([mySavePanel runModalForDirectory:"." 
                                            file:[currentWindow  currentCellName]])
	[currentWindow saveAs:(char *)[mySavePanel filename]];

    return self;
}

///////////////////////////////////////////////////////////////
// Find the next text string if possible

- findText:sender
{
     [currentWindow highlightNextWord];
	
     return self;
}


//////////////////////////////////////////////////////////////
// Show current item info.

- itemInfo:sender
{
    [currentWindow showItemInfo];

    return self;
}

//////////////////////////////////////////////////////////////
// Stop currently playing sound (if any).

- stopSound:sender
{
    if (mutex_try_lock(soundIsPlaying) != 0) {	// No sound playing
	mutex_unlock(soundIsPlaying);
	return self;
	}

    if (mutex_try_lock(soundShouldStop) != 0) {
	soundShouldStopFlag = 1;
	mutex_unlock(soundShouldStop);
	}

    return self;
}

//////////////////////////////////////////////////////////////
// This is called every time a Gopher window becomes active.
// The sender is NOT the window itself, but the GopherClient
// responsible for it (which is its delegate).

- newFrontWindow:sender
{
    [PrintMenuCell setEnabled:YES];
    [SaveMenuCell setEnabled:YES];
    [CloseMenuCell setEnabled:YES];
    currentWindow = sender;

    return self;
}

//////////////////////////////////////////////////////////////
// This is called every time a Gopher window becomes inactive.
// The sender is NOT the window itself, but the GopherClient
// responsible for it (which is its delegate).

- oldFrontWindow:sender
{
    if (currentWindow == sender) {	// Only if this was the current window
	[PrintMenuCell setEnabled:NO];
	[SaveMenuCell setEnabled:NO];
	[CloseMenuCell setEnabled:NO];
	currentWindow = NIL;
	}

    return self;
}

//////////////////////////////////////////////////////////////
// 

- savePreferences:sender
{
	
    NXWriteDefault("Gopher", "GopherHost", [GopherHostTextItem stringValue]);
    NXWriteDefault("Gopher", "GopherPort", [GopherPortTextItem stringValue]);

    defaultApp = [teminalApp selectedRow];
    if ( defaultApp == 1 )
	NXWriteDefault("Gopher", "TermApp", "1");
    else
	NXWriteDefault("Gopher", "TermApp", "0");
		
    [PreferenceWindow performClose:self];

    return self;
}

///////////////////////////////////////////////////////////////////////////////
// Delegate methods


//////////////////////////////////////////////////////////////
// Is called after the application has opened.

- appDidInit:sender
{
    static NXDefaultsVector GopherDefaults = {
	{"GopherHost", DEFAULT_SERVER},
	{"GopherPort", DEFAULT_PORT},
	{"TermApp", "0"},
	{NULL}
    };
    struct stat myStat;

    if (NXRegisterDefaults("Gopher", GopherDefaults) == 0)
	/*error*/;

    strncpy(defaultHost, NXGetDefaultValue("Gopher", "GopherHost"), 256);
    [GopherHostTextItem setStringValue:defaultHost];

    defaultPort = atoi(NXGetDefaultValue("Gopher", "GopherPort"));
    [GopherPortTextItem setIntValue:defaultPort];

    defaultApp = atoi(NXGetDefaultValue("Gopher", "TermApp"));
    [teminalApp selectCellAt:defaultApp:0];

    soundIsPlaying = mutex_alloc();
    soundShouldStop = mutex_alloc();

    if (stat(PlayCommand, &myStat) == 0)
	if (myStat.st_mode & 0000001)
		shouldUseSound = 1;

    [[GopherClient new] setDispatcher:self];

    return self;
}

@end
