/* HDrawApp	By Paul Kunz	May 1992
 * Global object for application incorporating HippoDraw.
 *
 * Copyright (C)  1992  The Board of Trustees of
 * The Leland Stanford Junior University.  All Rights Reserved.
 */
 
#import "Draw.subproj/draw.h"
#import "HDrawApp.h"

const char HDrawApp_h_rcsid[] = HDRAWAPP_H_ID;
const char HDrawApp_m_rcsid[] = "$Id: HDrawApp.m,v 2.57.2.2 1994/02/08 20:28:36 rensing Exp $";


#import "HGraphicView.h"
#import "InspectAxes.h"
#import "InspectCut.h"
#import "InspectFunc.h"
#import "InspectPFunc.h"
#import "InspectPlot.h"
#import "InspectStat.h"
#import "InspectTuple.h"
#import "NewInspector.h"
#import "SpreadSheetMgr.h"

@implementation HDrawApp

/* Addition Methods */

+ allocFromZone:(NXZone *)aZone
{
    NXZone	*zone;
    
    zone = NXCreateZone(vm_page_size, vm_page_size, YES);
    NXNameZone(zone, "HippoDraw");
    self = [super allocFromZone:zone];
    return self;
}

+ alloc
{
    return [self allocFromZone:NULL];
}

- init
{
    Box		*box;
    Panel	*inspectorPanel;
    
    [super init];
    
    NXNameObject( "HDrawInstance", self, NXApp );
    drawInstance  = [[DrawApp allocFromZone:[self zone]] init];
    
    theNewInspector = [[NewInspector allocFromZone:[self zone]] init ]; 
    inspectTuple = [[InspectTuple allocFromZone:[self zone]] initInspFor:self];
    inspectPlot =  [[InspectPlot allocFromZone:[self zone]] initInspFor:self];
    inspectAxes =  [[InspectAxes allocFromZone:[self zone]] initInspFor:self];
    inspectStat =  [[InspectStat allocFromZone:[self zone]] initInspFor:self];
    inspectCut =   [[InspectCut allocFromZone:[self zone]]  initInspFor:self];
    inspectFunc =  [[InspectFunc allocFromZone:[self zone]]  initInspFor:self];
    inspectPFunc = [[InspectPFunc allocFromZone:[self zone]]
                                  initInspFor:self];
    
  /* Get the original Draw Inspector Panel and merge it into our Inspector */
    inspectorPanel = [drawInstance inspectorPanel];
    box = [drawInstance contentBox];
    [theNewInspector addView:box
		withName:"Graphics"
		withSupervisor:[inspectorPanel delegate]];
    [theNewInspector showPanelWithName:"Data Selection"];	  
    [theNewInspector orderFrontPanel:self];
    return self;
}

- appDidInit:(Application *)sender
{
    [[NXApp appListener ] setServicesDelegate:self];
    return [drawInstance appDidInit:sender];
}
- loadMinuit:sender
{
    NXBundle 	*bundle;
    id		fitter;
    char 	buffer[MAXPATHLEN+1];
    
    if ( minuitLoaded ) return self;
    
    bundle = [NXBundle bundleForClass:[self class]];
    if ( [bundle getPath:buffer forResource:"Minuit" ofType:"bundle"] ) {
	bundle = [[NXBundle alloc] initForDirectory:buffer];
	fitter = [[[bundle classNamed:"Minuit"]
	                   allocFromZone:[self zone]] init];
	[inspectPFunc setFitter:fitter];
    } else {
	NXRunAlertPanel( "Error",
	    "Can not find Minuit bundle", "Ok", NULL, NULL );
    }
    minuitLoaded = YES;
    return self;
}
- addToAvailFuncs:sender
{
    return [inspectPFunc addToAvailFuncs:sender];
}
- (BOOL)validateCommand:(MenuCell *)menuCell
 /*
 * The only command DrawApp itself controls is saveAll:.
 * Save All is enabled only if there are any documents open.
 * Within HippoDraw, loadMinuit: needs also to be handled.
 */
{
    SEL action = [menuCell action];

    if (action == @selector(saveAll:)) {
	return [drawInstance validateCommand:menuCell];
    }
    return YES;
}
- info:sender
{
    NXBundle	*bundle;
    char	buffer[MAXPATHLEN+1];
    
    if (!infoPanel) {
	NXZone *zone = NXCreateChildZone([self zone],
	                      vm_page_size, vm_page_size, YES);
	NXNameZone(zone, "HippoInfoPanel");
	bundle = [NXBundle bundleForClass:[self class]];
	if ( [bundle getPath:buffer forResource:"InfoPanel" ofType:"nib"] ) {
	    [NXApp loadNibFile:buffer owner:self
			withNames:NO  fromZone:zone];
	}
	NXMergeZone(zone);
    }

    [infoPanel orderFront:self];

    return self;
}
- legal:sender
{
    NXBundle	*bundle;
    char	buffer[MAXPATHLEN+1];
    
    if( ! legalPanel ){
	NXZone *zone = NXCreateChildZone([self zone],
	                      vm_page_size, vm_page_size, YES);
	NXNameZone(zone, "LegalPanel");
	bundle = [NXBundle bundleForClass:[self class]];
	if ( [bundle getPath:buffer forResource:"Legal" ofType:"nib"] ) {
	    [NXApp loadNibFile:buffer owner:self
			withNames:NO  fromZone:zone];
	}
	NXMergeZone(zone);
    }
    [legalPanel makeKeyAndOrderFront:sender];
    return self;
}
- cernPanel:sender
{
    NXBundle	*bundle;
    char	buffer[MAXPATHLEN+1];
    
    if( ! cernPanel ){
	NXZone *zone = NXCreateChildZone([self zone],
	                      vm_page_size, vm_page_size, YES);
	NXNameZone(zone, "cernPanel");
	bundle = [NXBundle bundleForClass:[self class]];
	if ( [bundle getPath:buffer forResource:"cern" ofType:"nib"] ) {
	    [NXApp loadNibFile:buffer owner:self
			withNames:NO  fromZone:zone];
	}
	NXMergeZone(zone);
    }
    [cernPanel makeKeyAndOrderFront:sender];
    return self;
}
- open:sender
{
    return [drawInstance open:sender];
}
- setCurrentGraphic:sender
{
    return [drawInstance setCurrentGraphic:sender];
}
- terminate:sender
{
    return [drawInstance terminate:sender];
}
- newInspector
{
    return theNewInspector;
}

- orderFrontTools:sender
{
    [drawInstance orderFrontTools:sender];
    return self;
}

- orderFrontTupleInsp:sender
{

    theNewInspector = [ self newInspector];
    [theNewInspector orderFrontPanel:self];
    return self;
}
- addTuple:(ntuple) nt
{
    return [inspectTuple addTuple:nt];
}
- addPlotOfType:(graphtype_t) type
{
    [[[drawInstance currentDocument] view] addPlotOfType:type];
    return self;
}
- (Window *)documentWindow
{
    return [[[drawInstance currentDocument] view] window];
}
/* Public methods internal to Hippo.bproj */
- currentInspector
{
    return [theNewInspector currentInspector];
}

- inspectAxes
{
    return inspectAxes;
}
- inspectCut
{
    return inspectCut;
}
- inspectFunc
{
    return inspectFunc;
}
- inspectPFunc
{
    return inspectPFunc;
}
- inspectPlot
{
    return inspectPlot;
}
- inspectTuple
{
    return inspectTuple;
}
- replaceNtuple:(ntuple)oldnt with:(ntuple)newnt andFree:(BOOL)flag
{
    [inspectTuple replaceNtuple:oldnt with:newnt andFree:flag];
    return self;
}
- openTuple:sender
{
    [inspectTuple openTuple:sender];
    return self;
}
- openTupleAsText:sender
{
    [inspectTuple openTupleAsText:sender];
    return self;
}

- openTuple:pasteBoard userData:(const char *)args error:(char **)errorMsg
{
    DrawDocument	*drawdoc;

    drawdoc = [self newDocument];
    [[drawdoc view] openTuple:pasteBoard userData:args
				   error:errorMsg];

    return self;
}
- closeTuple:sender
{
    [inspectTuple closeTuple:sender];
    return self;
}

- newDocument
{
    id	drawdoc, view;

    drawdoc = [DrawDocument new:[HGraphicView class]];
    view = [drawdoc view];
    [view setGridSpacing:10];
    [view setGridVisible:YES];
    [view setGridEnabled:YES];
    [drawdoc clean: self];  /* new documents are NOT dirty */
    return drawdoc;
}
- showTupleAsTable:sender
{
    
    if ( !ssmanager) {
    	ssmanager = [SpreadSheetMgr new:self];
    }
    if ( ![inspectTuple currentTuple] ) {
	NXRunAlertPanel("Alert", "No opened n-tuple",
	    "OK", NULL, NULL );
	return self;
    }
    [ssmanager tupleToSpreadSheet:[inspectTuple currentTuple]];
    [[ssmanager window] makeKeyAndOrderFront:self];
    return self;
}

- new:sender
{
    DrawDocument	*drawdoc;

    drawdoc = [self newDocument];
    return self;
}



- (int)app:sender openFile:(const char *)path type:(const char *)type
 /*
  * This method is performed whenever a user double-clicks on an icon
  * in the Workspace Manager representing a Draw program document.
  */
{
    BOOL	flag;
    
    flag = [drawInstance app:sender openFile:path type:type];
    if ( flag ) {
        return YES;
    }
    if (type && !strcmp(type, "hippo")) {
        flag = [ self appOpenHippoFile: path];
	return flag;
    }
    return NO;
}

- app:sender powerOffIn:(int)ms andSave:(int)andSave
{
    return [drawInstance app:sender powerOffIn:ms andSave:andSave];
}    

- (BOOL)menuItemUpdate:(MenuCell *)menuCell
{
    return [drawInstance menuItemUpdate:menuCell];
}
- (int)appOpenHippoFile:(const char *)path
{
    DrawDocument	*currentDoc;
    int		irc;

    currentDoc = [drawInstance currentDocument];
    if ( !currentDoc ) {
	currentDoc = [self newDocument];
    }
    irc = [inspectTuple openTupleFile:path by:YES];
    if ( irc == HD_REPLACE ) {
	[inspectTuple bindDisplays];
    }
    [[currentDoc view] reDrawPlot];
    [drawInstance setHaveOpenedDocument:YES];
    return YES;
}
@end
