/*
copyright 2002 Alexander Malmberg <alexander@malmberg.org>
*/

#include <Foundation/NSObject.h>
#include <Foundation/NSNotification.h>
#include <Foundation/NSValue.h>
#include <Foundation/NSBundle.h>
#include <AppKit/NSWindowController.h>
#include <AppKit/NSPanel.h>
#include <AppKit/NSTextField.h>
#include <AppKit/NSScrollView.h>
#include <AppKit/NSClipView.h>
#include <AppKit/NSTableView.h>
#include <AppKit/NSTableColumn.h>
#include <AppKit/NSButton.h>
#include <GNUstepGUI/GSVbox.h>
#include <GNUstepGUI/GSHbox.h>

#include "autokeyviewchain.h"

#include "NNTPSourceGUI.h"


/*
TODO:
group browser
*/


@interface NNTPSource (GUI2)

-(NSString *) getHostString;
-(NSString *) getPortString;
-(void) setHost: (NSString *)h  port: (NSString *)p;

-(int) numGroups;

-(NSString *) groupName: (int)idx;
-(int) groupLastMessage: (int)idx;

-(void) addGroup: (NSString *)s  lastMessage: (int)lmsg;
-(void) removeGroup: (int)idx;

-(void) queryGroup: (NSString *)g;

@end



@interface NNTPSourcePropertiesController : NSWindowController
{
	NNTPSource *ns;

	NSTextField *f_host,*f_port;
	NSTextField *f_group,*f_lastmsg;

	NSTableView *group_list;
	NSTableColumn *c_name,*c_lastmsg;
}

- initWithNNTPSource: (NNTPSource *)n;

@end

@implementation NNTPSourcePropertiesController

-(void) windowWillClose: (NSNotification *)n
{
	[self autorelease];
}


-(void) done: (id)sender
{
	[ns setHost: [f_host stringValue] port: [f_port stringValue]];
	[self close];
}

-(void) addGroup: (id)sender
{
	[ns addGroup: [f_group stringValue]  lastMessage: [f_lastmsg intValue]];
	[group_list reloadData];
}

-(void) removeGroup: (id)sender
{
	if ([group_list selectedRow]!=-1)
	{
		[ns removeGroup: [group_list selectedRow]];
		[group_list reloadData];
	}
}

-(void) queryGroup: (id)sender
{
	/* update host and port first to avoid confusing behaviour */
	[ns setHost: [f_host stringValue] port: [f_port stringValue]];

	[ns queryGroup: [f_group stringValue]];
	[f_lastmsg setStringValue: _(@"<look in the log window (alt-l)>")];
}


-(int) numberOfRowsInTableView: (NSTableView *)tv
{
	return [ns numGroups];
}

-(id) tableView: (NSTableView *)tv  objectValueForTableColumn: (NSTableColumn *)tc  row: (int)row
{
	if (tc==c_name)
		return [ns groupName: row];
	else
		return [NSNumber numberWithInt: [ns groupLastMessage: row]];
}


- initWithNNTPSource: (NNTPSource *)n
{
	NSPanel *win;

	win=[[NSPanel alloc] initWithContentRect: NSMakeRect(100,100,320,320)
		styleMask: NSClosableWindowMask|NSTitledWindowMask|NSResizableWindowMask|NSMiniaturizableWindowMask
		backing: NSBackingStoreRetained
		defer: YES];
	if (!(self=[super initWithWindow: win])) return nil;

	ASSIGN(ns,n);

	{
		GSVbox *vbox;

		vbox=[[GSVbox alloc] init];
		[vbox setBorder: 4];
		[vbox setDefaultMinYMargin: 4];
		[vbox setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable];

		{
			GSHbox *hbox;
			NSButton *b;

			hbox=[[GSHbox alloc] init];
			[hbox setDefaultMinXMargin: 4];
			[hbox setAutoresizingMask: NSViewMinXMargin];

			b=[[NSButton alloc] init];
			[b setTitle: _(@"Done")];
			[b setTarget: self];
			[b setAction: @selector(done:)];
			[b setKeyEquivalent: @"\r"];
			[b sizeToFit];
			[hbox addView: b];
			[b release];

			[vbox addView: hbox  enablingYResizing: NO];
			[hbox release];
		}

		[vbox addSeparator];

		{
			GSHbox *hbox;
			NSButton *b;
			NSTextField *tf;

			hbox=[[GSHbox alloc] init];
			[hbox setDefaultMinXMargin: 4];
			[hbox setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable];

			{
				GSVbox *vb;
				vb=[[GSVbox alloc] init];
				[vb setDefaultMinYMargin: 4];
				[vb setAutoresizingMask: NSViewMinYMargin|NSViewWidthSizable];

				tf=[[NSTextField alloc] init];
				[tf setStringValue: @""];
				[tf sizeToFit];
				[tf setAutoresizingMask: NSViewWidthSizable];
				[vb addView: tf];
				f_lastmsg=tf;

				tf=[[NSTextField alloc] init];
				[tf setStringValue: _(@"Last message (use query):")];
				[tf setEditable: NO];
				[tf setDrawsBackground: NO];
				[tf setBordered: NO];
				[tf setBezeled: NO];
				[tf setSelectable: NO];
				[tf sizeToFit];
				[tf setAutoresizingMask: NSViewWidthSizable];
				[vb addView: tf enablingYResizing: NO];
				[tf release];

				tf=[[NSTextField alloc] init];
				[tf setStringValue: @""];
				[tf sizeToFit];
				[tf setAutoresizingMask: NSViewWidthSizable];
				[vb addView: tf];
				f_group=tf;

				tf=[[NSTextField alloc] init];
				[tf setStringValue: _(@"Group name:")];
				[tf setEditable: NO];
				[tf setDrawsBackground: NO];
				[tf setBordered: NO];
				[tf setBezeled: NO];
				[tf setSelectable: NO];
				[tf sizeToFit];
				[tf setAutoresizingMask: NSViewWidthSizable];
				[vb addView: tf enablingYResizing: NO];
				[tf release];

				[hbox addView: vb];
				[vb release];
			}

			{
				GSVbox *vb;

				vb=[[GSVbox alloc] init];
				[vb setDefaultMinYMargin: 4];
				[vb setAutoresizingMask: NSViewMinYMargin];

				b=[[NSButton alloc] init];
				[b setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable];
				[b setTitle: _(@"Add")];
				[b setTarget: self];
				[b setAction: @selector(addGroup:)];
				[b sizeToFit];
				[vb addView: b enablingYResizing: NO];
				[b release];

				b=[[NSButton alloc] init];
				[b setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable];
				[b setTitle: _(@"Remove")];
				[b setTarget: self];
				[b setAction: @selector(removeGroup:)];
				[b sizeToFit];
				[vb addView: b enablingYResizing: NO];
				[b release];

				b=[[NSButton alloc] init];
				[b setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable];
				[b setTitle: _(@"Query")];
				[b setTarget: self];
				[b setAction: @selector(queryGroup:)];
				[b sizeToFit];
				[vb addView: b enablingYResizing: NO];
				[b release];

				[hbox addView: vb enablingXResizing: NO];
				[vb release];
			}

			[vbox addView: hbox enablingYResizing: NO];
			[hbox release];
		}

		[vbox addSeparator];

		{
			NSScrollView *sv;

			sv=[[NSScrollView alloc] init];
			[sv setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable];
			[sv setHasVerticalScroller: YES];
			[sv setHasHorizontalScroller: NO];
			[sv setBorderType: NSBezelBorder];

			c_name=[[NSTableColumn alloc] initWithIdentifier: @"Group"];
			[[c_name headerCell] setStringValue: _(@"Group")];
			[c_name setEditable: NO];
			[c_name setResizable: YES];
			[c_name setWidth: 200];

			c_lastmsg=[[NSTableColumn alloc] initWithIdentifier: @"Last msg"];
			[[c_lastmsg headerCell] setStringValue: _(@"Last msg")];
			[c_lastmsg setEditable: NO];
			[c_lastmsg setResizable: YES];
			[c_lastmsg setWidth: 32];

			group_list=[[NSTableView alloc] initWithFrame: [[sv contentView] frame]];
			[group_list setAllowsColumnReordering: YES];
			[group_list setAllowsColumnResizing: YES];
			[group_list setAllowsMultipleSelection: NO];
			[group_list setAllowsColumnSelection: NO];
			[group_list addTableColumn: c_name];
			[group_list addTableColumn: c_lastmsg];
			[group_list setDataSource: self];
			[group_list setDelegate: self];
//			[group_list setDoubleAction: @selector(openMessage:)];

			[sv setDocumentView: group_list];
			[vbox addView: sv];
			[sv release];
		}

		[vbox addSeparator];

		{
			NSTextField *tf;

			tf=[[NSTextField alloc] init];
			[tf setStringValue: [ns getPortString]];
			[tf sizeToFit];
			[tf setAutoresizingMask: NSViewWidthSizable];
			[vbox addView: tf enablingYResizing: NO];
			f_port=tf;

			tf=[[NSTextField alloc] init];
			[tf setStringValue: _(@"Port:")];
			[tf setEditable: NO];
			[tf setDrawsBackground: NO];
			[tf setBordered: NO];
			[tf setBezeled: NO];
			[tf setSelectable: NO];
			[tf sizeToFit];
			[tf setAutoresizingMask: NSViewWidthSizable];
			[vbox addView: tf enablingYResizing: NO];
			[tf release];

			tf=[[NSTextField alloc] init];
			[tf setStringValue: [ns getHostString]];
			[tf sizeToFit];
			[tf setAutoresizingMask: NSViewWidthSizable];
			[vbox addView: tf enablingYResizing: NO];
			f_host=tf;

			tf=[[NSTextField alloc] init];
			[tf setStringValue: _(@"Host:")];
			[tf setEditable: NO];
			[tf setDrawsBackground: NO];
			[tf setBordered: NO];
			[tf setBezeled: NO];
			[tf setSelectable: NO];
			[tf sizeToFit];
			[tf setAutoresizingMask: NSViewWidthSizable];
			[vbox addView: tf enablingYResizing: NO];
			[tf release];
		}

		[win setContentView: vbox];
		[vbox release];
	}
	[win setTitle: _(@"NNTPSource properties")];
	[win setDelegate: self];
	[win autoSetupKeyViewChain];
	[win release];

	return self;
}

-(void) dealloc
{
	DESTROY(f_host);
	DESTROY(f_port);
	DESTROY(f_group);
	DESTROY(f_lastmsg);
	DESTROY(c_name);
	DESTROY(c_lastmsg);
	DESTROY(group_list);
	DESTROY(ns);
	[super dealloc];
}

@end


#include "NNTPServer.h"

@implementation NNTPSource (GUI)

-(NSString *) sourceType
{
	return @"NNTP";
}

-(NSString *) sourceName
{
	const char *c=[mdb msg_getMetaHeader: "Host" : mmid];
	if (c)
		return [NSString stringWithCString: c];
	else
		return _(@"<unknown>");
}

-(void) displayPropertiesWindow
{
	NNTPSourcePropertiesController *w;

	w=[[NNTPSourcePropertiesController alloc] initWithNNTPSource: self];
	[w showWindow: self];
}

@end

@implementation NNTPSource (GUI2)

-(NSString *) getHostString
{
	const char *c=[mdb msg_getMetaHeader: "Host" : mmid];
	if (c)
		return [NSString stringWithCString: c];
	else
		return @"";
}

-(void) setHost: (NSString *)h  port: (NSString *)p
{
	[mdb msg_setMetaHeader: "Host" value: [h cString] : mmid];
	[mdb msg_setMetaHeader: "Port" value: [p cString] : mmid];

	[self recreateNNTPServer];
	/* this causes the return from sourceName to change */
	[[mdb notificationCenter]
		postNotificationName: MsgDB_SourceChangeNotification
		object: mdb];
}

-(NSString *) getPortString
{
	const char *c=[mdb msg_getMetaHeader: "Port" : mmid];
	if (c)
		return [NSString stringWithCString: c];
	else
		return @"";
}


-(int) numGroups
{
	return num_groups;
}

-(NSString *) groupName: (int)idx
{
	return [NSString stringWithCString: [NNTPServer getGroupName: groups[idx].idx]];
}

-(int) groupLastMessage: (int)idx
{
	return groups[idx].last_num;
}


-(void) addGroup: (NSString *)s  lastMessage: (int)lmsg
{
	char buf[32];
	int i,idx;
	const char *name;

	if (![s length]) return;
	name=[s cString];

	idx=[NNTPServer getGroupNum: name];

	for (i=0;i<num_groups;i++)
	{
		if (groups[i].idx==idx)
		{
			groups[i].last_num=lmsg;
			[self syncGroupHeaders: i];
			return;
		}
	}

	groups=realloc(groups,sizeof(struct nntpsource_group_s)*(num_groups+1));
	if (!groups) abort();
	num_groups++;

	groups[i].idx=idx;
	groups[i].last_num=lmsg;

	sprintf(buf,"G%i-name",i);
	[mdb msg_setMetaHeader: buf  value: name : mmid];

	sprintf(buf,"%i",num_groups);
	[mdb msg_setMetaHeader: "Groups" value: buf : mmid];

	[self syncAllGroupHeaders];
}

-(void) removeGroup: (int)idx
{
	int i;
	num_groups--;
	for (i=idx;i<num_groups;i++)
		groups[i]=groups[i+1];
	[self syncAllGroupHeaders];
}

-(void) queryGroup: (NSString *)g
{
	const char *name;
	int idx;

	if (![g length]) return;
	name=[g cString];

	idx=[NNTPServer getGroupNum: name];

	if (server)
		[server getGroupInfo: idx];
}

@end

