//		Written by Todd Thomas Copyright (c) 1995 by Todd Thomas.
//				Version 1.0.  All rights reserved.
//
//		This notice may not be removed from this source code.
//
//	This object is included in the MiscKit by permission from the author
//	and its use is governed by the MiscKit license, found in the file
//	"LICENSE.rtf" in the MiscKit distribution.  Please refer to that file
//	for a list of all applicable permissions and restrictions.
//	

#import "Controller.h"
#import "UIMgr.h"


@implementation UIMgr

- init
{
	[super init];
	reloadBrowser = YES;
	return self;
}


- allUsersClicked:sender
{
	// The "Show all Users" button was clicked, so show them all in the
	// browser.
	[self clearStatusLine];
	[controller loadAllUsers];
	[browser setTitle: "All Users"  ofColumn: 0];
	// Set so when you click on a selection, we send ourselves a userSelected
	// message.
	[browser setAction: @selector(userSelected:)];
	[browser loadColumnZero];
	
    return self;
}

- allGroupsClicked:sender
{
	// The "Show All Groups" button was clicked, so show them all in the
	// browser.
	[controller loadAllGroups];
	[browser setTitle: "All Groups" ofColumn: 0];
	// Set so when you click on a selection, we send a groupSelected message.
	[browser setAction: @selector (groupSelected:)];
	[browser loadColumnZero];
	
    return self;
}


- gidEntered:sender
{
	int  gid = [sender intValue];
	char tmp[100];
	
	// A group's Gid was entered, so look it up and display it. If successful 	// the controller will set the actual fields in the UI (through us).
	if ([controller lookupGid: gid] == NO)
	{
		[self setStatusLine: "No group exists for that Gid"];
		// Easier to clear all fields and put back the entered one...
		[self clearGroupInfo];
		[self setGid: gid];
		return self;
	 }

	[self clearStatusLine];
	sprintf (tmp, "Members of group %s", [self groupName]);
	// Browser is loaded with users, so send a userSelected if cell selected.
	[browser setAction: @selector (userSelected:)];
	[browser setTitle: tmp ofColumn: 0]; 
	[browser loadColumnZero];
    return self;
}


- groupEntered:sender
{
	char  tmp[100];
	
	if ([sender stringValue] == NULL)
		return self;
		
	// A group's name was entered, so look it up and display it.
	if ([controller lookupGroupName: [sender stringValue] ] == NO)
	{
		[self setStatusLine: "No group matches that name."];
		// Make a copy of the string before you clear the fields.
		strcpy (tmp, [sender stringValue]);
		[self clearGroupInfo];
		[self setGroupName: tmp ];
		return self;
	 }
	
	[self clearStatusLine]; 
	if (reloadBrowser == NO)
	{
		reloadBrowser = YES;
		return self;
	 }
	
	// The reloadBrowser stops this code from executing when the groups
	// are already in the browser and you wish to click through them
	// without having them all cleared if their members were to appear.	
	sprintf (tmp, "Members of group %s", [self groupName]);
	[browser setAction: @selector(userSelected:)];
	[browser setTitle: tmp ofColumn: 0]; 
	[browser loadColumnZero];
    return self;
}


- uidEntered:sender
{
	int  uid = [sender intValue];
	char  tmp[100];
	
	// A user id was entered, so look it up and display it.
	if ([controller lookupUid: uid] == NO)
	{	
		[self setStatusLine: "There is no user with that Uid"];
		[self clearUserInfo];
		[self setUid: uid];
		return self;
	 }	
	 
	[self clearStatusLine]; 
	sprintf (tmp, "%s's groups", [self username]);
	// There are now groups in the browser, so if one is selected...
	[browser setAction: @selector (groupSelected:)];
	[browser setTitle: tmp ofColumn: 0]; 
	[browser loadColumnZero];
    return self;
}

- usernameEntered:sender
{
	char  tmp[100];

	if ([sender stringValue] == NULL)
		return self;
		
	// A username was entered, so look it up.
	if ([controller lookupUsername: [sender stringValue] ] == NO)
	{
		[self setStatusLine: "There is no user with that name"];
		strcpy (tmp, [sender stringValue]);
		[self clearUserInfo];
		[self setUsername: tmp];
		return self;		
	 }

	[self clearStatusLine]; 
	if (reloadBrowser == NO)
	{
		reloadBrowser = YES;
		return self;
	 }

	// The reloadBrowser stops this code from executing when the users
	// are already in the browser and you wish to click through them
	// without having them all cleared by the user groups they belong to 
	// which normally would be displayed in the browser.	
	sprintf (tmp, "%s's groups", [self username]);
	[browser setAction: @selector (groupSelected:)];
	[browser setTitle: tmp ofColumn: 0]; 
	[browser loadColumnZero];
    return self;
}


// Methods for getting/setting values from the user interface.

- (const char *)username
{
	return [ [userMatrix cellAt: 0 : 0] stringValue];
}


- setUsername: (const char *)uname
{
	[ [userMatrix cellAt: 0 : 0] setStringValue: uname];
	return self;
}

	
- setUid: (int)uid
{
	[ [userMatrix cellAt: 1 : 0] setIntValue: uid];
	return self;
}


- setFullName: (const char *)fname
{
	[ [userMatrix cellAt: 2 : 0] setStringValue: fname];
	return self;
}


- setHomeDirectory: (const char *)homeDir
{
	[ [userMatrix cellAt: 3 : 0] setStringValue: homeDir];
	return self;
}


- setShell: (const char *)shell
{
	[ [userMatrix cellAt: 4 : 0] setStringValue: shell];
	return self;
}


- clearUserInfo
{
	int  rows, cols;
	int  i;
	
	[userMatrix getNumRows: &rows numCols: &cols];
	for (i=0; i<rows; i++)
		[ [userMatrix cellAt: i : 0] setStringValue: ""];
	return self;
}
		

- (const char *)groupName
{
	return [ [groupMatrix cellAt: 0 : 0] stringValue];
}


- setGroupName: (const char *)gname
{
	[ [groupMatrix cellAt: 0 : 0] setStringValue: gname];
	return self;
}


- setGid: (int)gid
{
	[ [groupMatrix cellAt: 1 : 0] setIntValue: gid];
	return self;
}


- clearGroupInfo
{
	int  rows, cols;
	int  i;
	
	[groupMatrix getNumRows: &rows numCols: &cols];
	for (i=0; i<rows; i++)
		[ [groupMatrix cellAt: i : 0] setStringValue: ""];
	return self;
}


- setStatusLine: (const char *)info
{
	[status setStringValue: info];
	return self;
}


- clearStatusLine
{
	[self setStatusLine: ""];
	return self;
}

@end


@implementation UIMgr (BrowserTarget)

- userSelected: sender
{
	// This is called when there is a list of users in the browser and 
	// one of them was selected. reLoadBrowser is set to NO so the browser
	// will not be overwritten with the user's groups.
	reloadBrowser = NO;
	[self setUsername: [sender stringValue] ];
	// This assumes that the sender is the cell and contains only the
	// username. If it changed, this would break.
	[self usernameEntered: sender];
	return self;
}


- groupSelected: sender
{
	// This is called when there is a list of groups in the browser and 
	// one of them was selected. reloadBrowser is NO because we don't want
	// the groupEntered method to fill the browser with the group's members.
	reloadBrowser = NO;
	[self setGroupName: [sender stringValue] ];
	// Assumes that the sender's (the selected cell) string value is just
	// a user group name.
	[self groupEntered: sender];
	return self;
}

@end


@implementation UIMgr (NibInitialization)

- awakeFromNib
{
	// Wake me up and clear out status line and browser title.
	[self clearStatusLine];
	[browser setTitle: "" ofColumn: 0];
	// When a cell is selected I want to know about it.
	[browser setTarget: self];
	// When you want to be loaded, let the controller know.
	[browser setDelegate: controller];
	return self;
}

@end

