/*
    SambaManger. A graphical frontend to configure the NetInfo enhanced samba.
    Copyright (C) 1998  Robert Frank

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
		
		Robert Frank, frank@ifi.unibas.ch
*/

#import "Service.h"
#import "Controller.h"
#import "NIProperty.h"

// The property names of a service's directory:
#define S_NAME				"name"

// Static (class) variables:
static NXStringTable	*strings = nil;		// The localized strings.

@implementation Service

// ************************************************************************
// Local methods:
- free
{
		[ni_dirObj free];
		return [super free];
}

- init:sender dirObj:(NIDirectory *)dir delta:(NXCoord *)offset service:(const char *)sName
{
NXCoord		loffset;
NXRect		wframe;
char			ud[1024], *dName;


		// Do higher level inits first.
		[super init];
		controller = sender;
		ni_dirObj = dir;

		if (*offset < 100.0)
			loffset = *offset + 20.0;
		else
			loffset = 0.0;

		if (window == nil) {	
			strcpy(ud, [self name]);
			strcat(ud, ".nib");
			if (![NXApp loadNibSection:ud owner:self])
				return [super free];
		}

		// Move each new window by a little offset.
		[window getFrame:&wframe];
		wframe.origin.x+= loffset;
		wframe.origin.y-= loffset;
		[window moveTo:wframe.origin.x :wframe.origin.y];
		
		if (sName)
			[window setTitle:[strings valueForStringKey:"Title:Loading ..."]];
		else
			[window setTitle:[strings valueForStringKey:"Title:Untitled"]];
		
		[window makeKeyAndOrderFront:self];
		[window disableFlushWindow];
			
		if (![self setupAndLoad])
			return [super free];
		
		if (sName) {
			dName = (char *)[dir domainName];
			sprintf(ud, "%s/%s", (dName && *dName && (dName[1] != '\0'))?dName:"", sName);
			[window setTitleAsFilename:ud];
		}
		
		[window reenableFlushWindow];
		[window display];
		*offset = loffset;

		return self;
}

// ************************************************************************
// Class methods:
+ initialize
// Called once by the run time system
{
char	buf[MAXPATHLEN + 1];

		if (!strings)
			if ( [[NXBundle mainBundle] getPath:buf forResource:"Service" ofType:"strings"] )
				strings = [[[NXStringTable alloc] init] readFromFile:buf];
		return nil;
}

+ (const char *)stringFor:(const char *)strng
{
		return [strings valueForStringKey:strng];
}

+ new:sender at:(NXCoord *)offset
{
		return nil;
}

+ open:sender at:(NXCoord *)offset
{
		return nil;
}

// ************************************************************************
//	Methods:

- (BOOL)minimumOK
{
		if (![[ni_dirObj property:S_NAME] values]) {
			NXRunAlertPanel(getString("Alert:Alert"),
											getString("Message:Must have a name"),
											getString("Button:OK"),NULL,NULL);
			return NO;
		}
		return YES;
}

- revert:sender
{
		if ([ni_dirObj reset])
			[window setDocEdited:NO];
    return self;
}

- save:sender
{
char	ud[1024], *dName;
id	status = nil;

		if ([self minimumOK])
			if (status = [ni_dirObj save]) {
				[window setDocEdited:NO];
				dName = (char *)[ni_dirObj domainName];
				sprintf(ud, "%s/%s", (dName && *dName && (dName[1] != '\0'))?dName:"", [ni_dirObj baseName]);
				[window setTitleAsFilename:ud];
			}
		return status;
}

- saveToDomain:sender
{
char	ud[1024], *dName;
id		status = nil;

		if ([self minimumOK])
			if (status = [ni_dirObj saveToDomain]) {
				[window setDocEdited:NO];
				dName = (char *)[ni_dirObj domainName];
				sprintf(ud, "%s/%s", (dName && *dName && (dName[1] != '\0'))?dName:"", [ni_dirObj baseName]);
				[window setTitleAsFilename:ud];
			}
		return status;
}

- close:sender
{
int		choice;

		if ([window isDocEdited]) {
			choice = NXRunAlertPanel([strings valueForStringKey:"Alert:Warning"],
															 [strings valueForStringKey:"Message:Save changes?"],
															 [strings valueForStringKey:"Button:Save"],
															 [strings valueForStringKey:"Button:Don't Save"],
															 [strings valueForStringKey:"Button:Cancel"],
															 [ni_dirObj baseName]?[ni_dirObj baseName]:[window title]);

			switch (choice) {
				case NX_ALERTDEFAULT:
					if (![self save:self])
						return nil;
				case NX_ALERTALTERNATE:
					break;
				default:
					return nil;
			}
		}

		if (sender) {
			[window setDelegate:nil];
			[window close:self];
			[controller removeFromServiceList:self];
			[self free];
		}
    return self;
}

- delete:sender
{
int		status;

		status = NXRunAlertPanel([strings valueForStringKey:"Alert:Delete"],
															[strings valueForStringKey:"Message:Really delete this entry from NetInfo?"],
															[strings valueForStringKey:"Button:Yes"],
															[strings valueForStringKey:"Button:No"],
															NULL, NULL);
		switch (status) {
			case NX_ALERTDEFAULT: 
				break;
			case NX_ALERTALTERNATE:
			default:
				return nil;
		}

		if ([ni_dirObj delete]) {
			[window setDocEdited:NO];
			[window performClose:self];
			return self;
		} else
	    return nil;
}

// Display the window.
- show:sender
{
		[window makeKeyAndOrderFront:self];
		return self;
}

// Check if the item passed is identical to this one.
- (BOOL)isSame:(const char *)str inDomain:(const char *)dName
{
		return !strcmp([ni_dirObj directory], str) && !strcmp([ni_dirObj domainName], dName);
}

- (BOOL)isOld:sender
{
		return ([ni_dirObj domainName] != NULL);
}

- setupAndLoad
{
		return self;
}

// ************************************************************************
// Delegates:

- textDidGetKeys:sender isEmpty:(BOOL)flag
{
		[window setDocEdited:YES];
		return self;
}

- (BOOL)propertyWillChange:sender value:(char **)string default:(BOOL *)remove index:(int)anInt
{
		return NO;
}

- propertyDidChange:sender value:(const char *)string
{
		[window setDocEdited:YES];
		return self;
}

- windowWillClose:sender
{
		if ([self close:nil]) {
			[sender setDelegate:nil];
			[controller removeFromServiceList:self];
			[self free];
			return self;
		} else
			return nil;
}
@end
