#import "Alexandra.h"
#import "MainWindowControl.h"
#import "NewsgroupSetMatrix.h"
#import "NewsgroupSet.h"
#import "Newsgroup.h"
#import "SideSplitView.h"
#import "NntpPanelControl.h"
#import "ArticleViewControl.h"
#import "Decoding.subproj/DecoderController.h"
#import "NNTP.h"
#import "KillFile.h"
#include <math.h>
#import <misckit/MiscAppDefaults.h>
#import "descriptors.h"
#import "KeyEventResponder.h"

@implementation MainWindowControl

- free
{
   [otherNGView free];
   [theNGSet dumpNewsrc:self];
   [[mainWindow close] free];
   [offscreenWindow free];
   [theNGSet free];
   [theArticleSet free];
   [nntpServer free];
   [theArticleViewControl free];
   [killFile free];

   return [super free];
}

- (BOOL) connectNNTP:(const char *)servername slowLink:(BOOL)slow
{
   char buf1[100],buf2[100];
   const char *sideSplitViewW;
   const char *splitViewH;
   id keyHandler;

   [nntpServer init];
   [nntpServer setSlowLink:slow];
   if([nntpServer openServerNamed:servername]==nil)
      return FALSE;
   
   [killFile setPath];
   [postButton setEnabled:[nntpServer canPost]];
   if(![nntpServer canPost])
   		{
		[postButton setTitle:[postButton altTitle]];
		[postButton setIcon:[postButton altIcon]];
		}
		
   EM_DURING
	
	[theNGSet scanNewsrcAndActive];
	
	EM_HANDLER
		if([EMLocalException exceptionClass]==EMClassNNTPErrors)
			return(FALSE);
		NX_RERAISE();
   
	EM_ENDHANDLER
	
   sprintf(buf1,"SideSplitView %s",servername);
   sprintf(buf2,"SplitView %s",servername);
   sideSplitViewW=[NXApp defaultValue:buf1];
   splitViewH=[NXApp defaultValue:buf2];
   if(sideSplitViewW!=NULL){
      NXRect theRect;

      [upperPartLeft getFrame:&theRect];
      [upperPartLeft sizeTo:atof(sideSplitViewW) :NX_HEIGHT(&theRect)];
   }
   if(splitViewH!=NULL){
      NXRect theRect;
      int uheight,lheight;
      
      sscanf(splitViewH,"%d %d",&uheight,&lheight);
      [sideSplitView getFrame:&theRect];
      [sideSplitView sizeTo:(NX_WIDTH(&theRect)) :(NXCoord)(uheight+4)];
      [articleView getFrame:&theRect];
      [articleView sizeTo:(NX_WIDTH(&theRect)) :(NXCoord)(lheight+4)];
   }

   [sideSplitView setLeftView:upperPartLeft];
   [sideSplitView setRightView:upperPartRight];
   [sideSplitView initViews];

   [splitView addSubview:sideSplitView];
   [splitView addSubview:articleView];
   [splitView adjustSubviews];

   [[theArticleViewControl theText] setDelegate:theArticleViewControl];
   [theNGSetMatrix setMatrixCellList:[theNGSet matrixList]];
   [theNGSetMatrix loadMatrix];
   [otherNGView setMatrixCellList:[theNGSet matrixList]];
   [mainWindow setTitle:servername];
   [mainWindow setFrameAutosaveName:servername];
   [mainWindow setFrameUsingName:servername];
   [mainWindow makeFirstResponder:theNGSetMatrix];

   keyHandler=[[KeyEventResponder alloc] init];
   [keyHandler setNextResponder:[splitView nextResponder]];
   [splitView setNextResponder:keyHandler];
   [keyHandler setNGSet:theNGSet];
   [keyHandler setArticleSet:theArticleSet];
   
   sprintf(buf1,"BrowserViewEnabled %s",servername);
   if([NXApp defaultBoolValue:buf1])
      [theNGSet switchToBrowserView:self];
		
   [mainWindow display];
   [mainWindow makeKeyAndOrderFront:self];

   return TRUE;
}

- disconnectAndClose:sender;
{
	return [mainWindow performClose:sender];
}


- nntpServer
{
   return nntpServer;
}

- killFile
{
   return killFile;
}

- articleText
{
   return [theArticleViewControl theText];
}

- newsgroupMatrix
{
   return [theNGSet theMatrix];
}

- articleMatrix
{
   return [theArticleSet theMatrix];
}

- articleViewControll
{
   return theArticleViewControl;
}

- newsgroupSet
{
   return theNGSet;
}

- articleSet
{
   return theArticleSet;
}

- (BOOL)articleSelected
{
   return ([theArticleSet numSelCells]==1);
}

- (BOOL)articlesSelected
{
   return ([theArticleSet numSelCells]>0);
}

- (BOOL)newsgroupSelected
{
   return ([theNGSet numSelCells]==1);
}

- (BOOL)newsgroupsSelected
{
   return ([theNGSet numSelCells]>0);
}

- printText:sender
{
   [theArticleViewControl printText:sender];
   return self;
}

- uudecode:sender
{
	if ([self articlesSelected]) {
		// Lazily load the decoder controller.
		if (decoderController == nil) { 
			decoderController = [ [DecoderController alloc] init];
		}

		// Begin the uudecoding, and pass self since the uudecoder needs
		// access to the article list, etc.
		[decoderController doDecoding:self];
	}
	else {
		NXBeep();
	}
	return self;
}

- forward:(SEL)aSelector :(marg_list)argFrame
{
   if([theArticleSet respondsTo:aSelector])
      return [theArticleSet performv:aSelector :argFrame];
   if([theNGSet respondsTo:aSelector])
      return [theNGSet performv:aSelector :argFrame];
   if([theArticleViewControl respondsTo:aSelector])
      return [theArticleViewControl performv:aSelector :argFrame];
   if([killFile respondsTo:aSelector])
      return [killFile performv:aSelector :argFrame];

   [self doesNotRecognize:aSelector];
   return self;
}

- (BOOL)respondsTo:(SEL)aSelector
{
   if([theArticleSet respondsTo:aSelector])
      return TRUE; 
   if([theNGSet respondsTo:aSelector])
      return TRUE;
   if([theArticleViewControl respondsTo:aSelector])
      return TRUE;
   if([killFile respondsTo:aSelector])
      return TRUE;

   return [super respondsTo:aSelector];
}

- sideSplitViewDidResizeSubviews:sender
{
   char buf1[80];
   char buf2[80];
   NXRect frameRect;

   [upperPartLeft getFrame:&frameRect];

   sprintf(buf1,"SideSplitView %s",[nntpServer serverName]);
   sprintf(buf2,"%d",(int)floor(NX_WIDTH(&frameRect)));
   [NXApp setDefault:buf1 to:buf2];

   return self;
}

- splitViewDidResizeSubviews:sender
{
   NXRect frameRect1,frameRect2;
   char buf1[80],buf2[80];

   [sideSplitView getFrame:&frameRect1];
   [articleView getFrame:&frameRect2];

   sprintf(buf1,"SplitView %s",[nntpServer serverName]);
   sprintf(buf2,"%d %d", (int)floor(NX_HEIGHT(&frameRect1)), (int)floor(NX_HEIGHT(&frameRect2)));

   [NXApp setDefault:buf1 to:buf2];

   return self;
}

- windowWillMiniaturize:sender toMiniwindow:miniwindow
{
   [sender setMiniwindowIcon:"app"];
   return self;
}

- (BOOL)killAuthorEnabled
{
   if((![nntpServer usesNov])&&(![nntpServer doesPrefetchFrom]))
      return FALSE;
   return TRUE;
}

- (BOOL)sortCellEnabled:menueCell
{
   BOOL answer=TRUE;
   char buf1[255];
   int sortType;
   BOOL useNov=[nntpServer usesNov];

   sprintf(buf1,"SortType %s",[nntpServer serverName]);
   sortType=[NXApp defaultIntValue:buf1];

   if(!useNov){
      if((![nntpServer doesPrefetchDate])&&
	  				([menueCell action]==@selector(sortArticlesByDate:)))
         return FALSE;
      if((![nntpServer doesPrefetchFrom])&&
	  				([menueCell action]==@selector(sortArticlesByName:)))
         return FALSE;
   }

   switch(sortType){
      case SORT_BY_NUMBER:
         if([menueCell action]==@selector(sortArticlesByNumber:)) answer=FALSE;
         break;
      case SORT_BY_SUBJECT:
         if([menueCell action]==@selector(sortArticlesBySubject:)) answer=FALSE;
         break;
      case SORT_BY_DATE:
         if([menueCell action]==@selector(sortArticlesByDate:)) answer=FALSE;
         break;
      case SORT_BY_REAL_NAME:
         if([menueCell action]==@selector(sortArticlesByName:)) answer=FALSE;
         break;
   }
   return answer;
}

- freeAndClose:sender
{
   [myOwner serverWillClose:self];
   [self free];
   
   return self;
}

- windowWillClose:sender
{
   int answer=NXRunAlertPanel("ALEXANDRA","Close connection to NNTP Server %s?",NULL, "Cancel",NULL,[nntpServer serverName]);
   if(answer!=NX_ALERTALTERNATE){
      [self freeAndClose:self];
      return self;
   }

   return nil;
}

@end
