
/* Generated by Interface Builder */

#import "PigApp.h"
#import <libc.h>
#import <string.h>
#import <defaults/defaults.h>
#import <appkit/Button.h>
#import <appkit/Panel.h>
#import <appkit/TextField.h>
#import <dpsclient/dpsclient.h>
#import <sys/types.h>
#import <sys/vfs.h>

@implementation PigApp

static double perc=100.0;

// update display to reflect current disk usage
void showUsage(PigApp *self)
{
    struct statfs fs;
    long used, availblks;
    char foo[16];

    // A better implementation might look at the username passed
    // to us by loginwindow, find the corresponding home
    // directory, and derive the filesystem name from that.
    if (statfs("/Users", &fs)<0) {
	(void)NXRunAlertPanel("UNIX Error", "statfs /Users: %s",
	    "OK", (char *)NULL, (char *)NULL, strerror(errno));
	[self terminate:nil];
    }
    // computations stolen from df (shh!)
    used = fs.f_blocks - fs.f_bfree;
    availblks = fs.f_bavail + used;
    perc=availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0;
    (void)sprintf(foo, fs.f_bavail*fs.f_bsize<104857600 ? "%6.3fMB free" :
	"%6.2fMB free", fs.f_bavail*fs.f_bsize/1048576.0);
    [self->oinkFree setTextGray:perc>=90.0 ? NX_WHITE : NX_DKGRAY];
    [self->oinkFree setStringValue:foo];
    (void)sprintf(foo, "%3.0f%%", perc);
    [self->oinkBar setFloatValue:(float)(perc/100.0)];
    [self->oinkPercent setTextGray:perc>=90.0 ? NX_WHITE : NX_BLACK];
    [self->oinkPercent setStringValue:foo];
}

// called on a periodic basis
void timedout(DPSTimedEntry tid, double now, PigApp *self) {
    static int loser;

    showUsage(self);
    // dismiss after some number of ticks
    if (++loser>=10) [self->OKButton perform:@selector(performClick:) with:nil
	afterDelay:1 cancelPrevious:NO];
}

static DPSTimedEntry tid=(DPSTimedEntry)-1;

- appDidInit:sender
{
    showUsage(self);
    if (![self mainMenu]) {	// if not running under Workspace
	// if usage is less than 60%, just go away
	if (perc<60.0) [self terminate:nil];
	// this is IMPORTANT--loginwindow doesn't deactivate itself!
	(void)[self activateSelf:YES];
    }
    [oinkWin center];
    [oinkWin makeKeyAndOrderFront:nil];
    // This causes the display to be updated every two seconds
    // (probably too frequent!)
    tid=DPSAddTimedEntry(2.0, (DPSTimedEntryProc)timedout,
	(void *)self, NX_MODALRESPTHRESHOLD+1);
    return self;
}

// clean up
- appWillTerminate:sender
{
    if (tid!=(DPSTimedEntry)-1) {
	DPSRemoveTimedEntry(tid);
	DPSFlush();
	[oinkWin orderOut:nil];
    }
    return self;
}

// UNDOCUMENTED: suppress app tile and remove main menu
// [this is messaged before appDidInit:]
- _replyToLaunch
{
    if (NXGetDefaultValue("ApplicationKit", "MachLaunch"))
	[super _replyToLaunch];	// ignore the warnings this generates
    else [self setMainMenu:nil];
    return self;
}

// delegate method to catch close button
- windowWillClose:sender
{
    [OKButton performClick:nil];
    return self;
}


@end
