#import <appkit/nextstd.h>

#import <appkit/Window.h>
#import <appkit/Panel.h>
#import <appkit/OpenPanel.h>
#import <appkit/Matrix.h>
#import <appkit/Speaker.h>

#import <appkit/Listener.h>
#import <appkit/defaults.h>
#import <mach.h>

#import "Thinker.h"
#import "PrefController.h"

static const char *module = "SlideShow";
static const char *Yes = "YES";
static const char *No = "NO";

static id fakeSelf;

@implementation PrefController

- init
{
    [super init];
    fakeSelf = self;	// kludge - but it works.
    return self;
}

- formActions:sender
{
    const char *name;
    int tag;
    float value;
    const char *taglist[] = { "Steptime", "Waittime", "FadeDelta", 0 };

    for (tag = 0; tag < 3; tag++) {
        name = taglist[tag];
        value = [[sender findCellWithTag:tag] floatValue];
        switch (tag) {
            case 0: defv.steptime = value; break;
            case 1: defv.waittime = value; break;
            case 2: defv.fadedelta = value; break;
        }
    }

    return self;
}

- switchActions:sender
{
    const char *name;
    int tag, value;
    const char *taglist[] = { "Fancy", "Randomize", "Slide", "Debug", 0 };

    for (tag = 0; tag < 3; tag++) {
        name = taglist[tag];
        value = [[sender findCellWithTag:tag] intValue];
        switch (tag) {
            case 0: defv.fancy = value; break;
            case 1: defv.randomize = value; break;
            case 2: defv.slide = value; break;
            case 3: defv.debug = value; break;
        }
    }

    return self;
}

- okAction:sender
{
    char buf[BUFSIZ];

    NXWriteDefault(module, "Fancy", defv.fancy > 0 ? Yes : No);
    NXWriteDefault(module, "Randomize", defv.randomize > 0 ? Yes : No);
    NXWriteDefault(module, "Slide", defv.slide > 0 ? Yes : No);

    sprintf(buf, "%d\0", defv.debug);
    NXWriteDefault(module, "Debug", buf);

    sprintf(buf, "%d\0", (int)defv.steptime);
    NXWriteDefault(module, "Steptime", buf);

    sprintf(buf, "%d\0", (int)defv.waittime);
    NXWriteDefault(module, "Waittime", buf);

    sprintf(buf, "%f\0", defv.fadedelta);
    NXWriteDefault(module, "FadeDelta", buf);

    NXWriteDefault(module, "Filelist", defv.filelist);

    [SlideShowView updateSettings];

    return self;
}

- revertAction:sender
{
    [self loadDefaults];
    [self dispDefaults];

    return self;
}

// override method;  runModalForDirectory
- allowMultipleFiles
{
    return NO;
}

- setAction:sender
{
    const char *dir, *file;
    const char *const *ret_filenames;
    const char *ret_directory;
    char buf[MAXPATHLEN], *b;
    OpenPanel *pan;

    strcpy(buf, defv.filelist);

    if (strlen(buf) == 0)
        strcpy(buf, NXGetDefaultValue(module, "Filelist"));

    if (strlen(buf) == 0) {
        // this should never happen
        strcpy(buf, "/LocalLibrary/Images/.list");
    }

    if ((b = rindex(buf, '/')) != NULL)
        *b = '\0';
    else
        b = buf;    // punt

    dir = buf;
    file = b+1;

    pan = [OpenPanel new];
    [pan runModalForDirectory:dir file:file];

    ret_directory = [pan directory];
    ret_filenames = [pan filenames];

    sprintf(buf, "%s/%s\0", ret_directory, *ret_filenames);
    strcpy(defv.filelist, buf);

    [self dispDefaults];

    return self;
}

// code borrowed from NextStep/Reference/02_Classes/AppKit/Speaker.rtf
- editAction:sender
{
    int msgDelivered, fileOpened;
    id mySpeaker;
    port_t thePort;
    char buf[MAXPATHLEN];

    strcpy(buf, defv.filelist);
    if (strlen(buf) == 0)
        strcpy(buf, NXGetDefaultValue(module, "Filelist"));

    mySpeaker = [[Speaker alloc] init];
    thePort = NXPortFromName("Edit", NULL);

    if (thePort != PORT_NULL) {
        [mySpeaker setSendPort:thePort];
        msgDelivered = [mySpeaker openFile:buf ok:&fileOpened];
    } else
        NXRunAlertPanel([NXApp appName],
        "Could not get port for Edit", NULL, NULL, NULL);

    [mySpeaker free];
    port_deallocate(task_self(), thePort);

    return self;
}

- fileAction:sender
{
    strcpy(defv.filelist, [sender stringValue]);
    return self;
}

- loadDefaults
{
    const char *value;
    extern int defaultIntValue(const char *);

    value = NXGetDefaultValue(module, "Fancy");
    defv.fancy = defaultIntValue(value);

    value = NXGetDefaultValue(module, "Randomize");
    defv.randomize = defaultIntValue(value);

    value = NXGetDefaultValue(module, "Slide");
    defv.slide = defaultIntValue(value);

    value = NXGetDefaultValue(module, "Debug");
    defv.debug = defaultIntValue(value);

    value = NXGetDefaultValue(module, "Steptime");
    defv.steptime = atof(value);

    value = NXGetDefaultValue(module, "Waittime");
    defv.waittime = atof(value);

    value = NXGetDefaultValue(module, "FadeDelta");
    defv.fadedelta = atof(value);

    value = NXGetDefaultValue(module, "Filelist");
    strcpy(defv.filelist, (char *)value);

    return self;
}

- dispDefaults
{
    [[formOutlets findCellWithTag:0] setIntValue:(int)defv.steptime];
    [[formOutlets findCellWithTag:1] setIntValue:(int)defv.waittime];
    [[formOutlets findCellWithTag:2] setFloatValue:defv.fadedelta];

    [[switchOutlets findCellWithTag:0] setIntValue:defv.fancy];
    [[switchOutlets findCellWithTag:1] setIntValue:defv.randomize];
    [[switchOutlets findCellWithTag:2] setIntValue:defv.slide];
    [[switchOutlets findCellWithTag:3] setIntValue:defv.debug];

    [filelistOutlet setStringValue:defv.filelist];

    return self;
}

// this is a kludge.  is there a cleaner way?

+ updatePanel
{
	[fakeSelf loadDefaults];
	[fakeSelf dispDefaults];

	return self;
}

@end
