GLFitManager::GLFitManager()
    :
    JPrefObject(GetPrefsMgr(), kFitManagerID),
    itsIsInitialized(kJFalse)
{
    itsFitDescriptions	= new JPtrArray<GLFitDescription>(JPtrArrayT::kDeleteAll);
    assert(itsFitDescriptions != NULL);

    itsFitDescriptions->SetCompareFunction(GLFitDescription::CompareFits);

    JPrefObject::ReadPrefs();

    InitializeList();
}
void
GLFitDirector::HandlePrefsMenu
	(
	const JIndex index
	)
{
	if (index == kPrefsCmd)
		{
//		GWIGetPrefsMgr()->EditPrefs();
		}
	else if (index == kEditToolBarCmd)
		{
		itsToolBar->Edit();
		}
	else if (index == kSaveWindowSizeCmd)
		{
		GetPrefsMgr()->WriteFitDirectorSetup(this);
		}
}
void
GXDataDocument::BuildWindow()
{
	JSize w = 453;
	JSize h = 360;

	JXWindow* window = jnew JXWindow(this, w,h, "");
	assert( window != NULL );

	JXMenuBar* menuBar =
		jnew JXMenuBar(window,
					JXWidget::kHElastic, JXWidget::kFixedTop,
					0,0, w, kJXDefaultMenuBarHeight);
	assert( menuBar != NULL );

	JXToolBar* toolBar =
		jnew JXToolBar(GetPrefsMgr(), kDataToolBarID, menuBar,
					window,
					JXWidget::kHElastic, JXWidget::kVElastic,
					0,kJXDefaultMenuBarHeight,
					w,h - kJXDefaultMenuBarHeight);
	assert( toolBar != NULL );

	window->SetMinSize(150, 150);

	itsFileMenu = menuBar->AppendTextMenu(kFileMenuTitleStr);
	itsFileMenu->SetMenuItems(kFileMenuStr);
	ListenTo(itsFileMenu);

	JXImage* image = jnew JXImage(GetDisplay(), JXPM(filenew));
	assert(image != NULL);
	itsFileMenu->SetItemImage(kNewCmd, image, kJTrue);

	image = jnew JXImage(GetDisplay(), JXPM(fileopen));
	assert(image != NULL);
	itsFileMenu->SetItemImage(kOpenCmd, image, kJTrue);

	image = jnew JXImage(GetDisplay(), JXPM(filefloppy));
	assert(image != NULL);
	itsFileMenu->SetItemImage(kSaveCmd, image, kJTrue);

	image = jnew JXImage(GetDisplay(), JXPM(fileprint));
	assert(image != NULL);
	itsFileMenu->SetItemImage(kPrintCmd, image, kJTrue);

	const JCoordinate scrollheight =
		toolBar->GetWidgetEnclosure()->GetBoundsHeight();

	itsScrollbarSet =
		jnew JXScrollbarSet(toolBar->GetWidgetEnclosure(),
					JXWidget::kHElastic, JXWidget::kVElastic,
					0,0,
					w, scrollheight);
	assert( itsScrollbarSet != NULL );

	AdjustWindowTitle();

	// layout table and headers

	const JCoordinate kRowHeaderWidth  = 30;
	const JCoordinate kColHeaderHeight = 20;

	JXContainer* encl = itsScrollbarSet->GetScrollEnclosure();
	JRect enclApG     = encl->GetApertureGlobal();

	JXTextButton* okButton =
		jnew JXTextButton("OK", encl,
						JXWidget::kFixedLeft, JXWidget::kFixedTop,
						0, 0, kRowHeaderWidth-2, kColHeaderHeight-2);
	assert(okButton != NULL);

	itsTable =
		jnew GXRaggedFloatTable(this, okButton, itsData, 6,
							menuBar, itsScrollbarSet, encl,
							JXWidget::kHElastic, JXWidget::kVElastic,
							kRowHeaderWidth,kColHeaderHeight,
							enclApG.width()  - kRowHeaderWidth,
							enclApG.height() - kColHeaderHeight);
	assert( itsTable != NULL );

	enclApG = encl->GetApertureGlobal();	// JXScrollableWidget forces a change in this

	GXRowHeaderWidget* rowHeader =
		jnew GXRowHeaderWidget(itsTable, itsScrollbarSet, encl,
							  JXWidget::kFixedLeft, JXWidget::kVElastic,
							  0,kColHeaderHeight, kRowHeaderWidth,
							  enclApG.height() - kColHeaderHeight);
	assert( rowHeader != NULL );

	GXColHeaderWidget* colHeader =
		jnew GXColHeaderWidget(itsTable, itsScrollbarSet, encl,
							  JXWidget::kHElastic, JXWidget::kFixedTop,
							  kRowHeaderWidth,0, enclApG.width() - kRowHeaderWidth,
							  kColHeaderHeight);
	colHeader->TurnOnColResizing(20);
	assert( colHeader != NULL );

	JXDocumentMenu* windowListMenu =
		jnew JXDocumentMenu(kWindowListMenuTitleStr, menuBar,
			JXWidget::kFixedLeft, JXWidget::kVElastic, 0,0, 10,10);
	assert( windowListMenu != NULL );
	menuBar->AppendMenu(windowListMenu);

	itsExportMenu = jnew JXTextMenu(itsFileMenu, kExportCmd, menuBar);
	assert( itsExportMenu != NULL );
	itsExportMenu->SetMenuItems(kExportMenuStr);
	itsExportMenu->SetUpdateAction(JXMenu::kDisableNone);
	ListenTo(itsExportMenu);

	itsHelpMenu = menuBar->AppendTextMenu(kHelpMenuTitleStr);
	itsHelpMenu->SetMenuItems(kHelpMenuStr);
	itsHelpMenu->SetUpdateAction(JXMenu::kDisableNone);
	ListenTo(itsHelpMenu);

	image = jnew JXImage(GetDisplay(), JXPM(manual));
	assert(image != NULL);
	itsHelpMenu->SetItemImage(kTOCCmd, image, kJTrue);

	toolBar->LoadPrefs();
	if (toolBar->IsEmpty())
		{
		toolBar->AppendButton(itsFileMenu, kNewCmd);
		toolBar->AppendButton(itsFileMenu, kOpenCmd);
		toolBar->AppendButton(itsFileMenu, kSaveCmd);
		toolBar->NewGroup();
		toolBar->AppendButton(itsFileMenu, kPrintCmd);

		itsTable->LoadDefaultToolButtons(toolBar);

		toolBar->NewGroup();
		toolBar->AppendButton(itsHelpMenu, kTOCCmd);
		}
}
void
GLFitDirector::BuildWindow()
{
	JCoordinate w = 600;
	JCoordinate h = 420;
	JXWindow* window = new JXWindow(this, w,h, "Fit");
    assert( window != NULL );
	window->SetCloseAction(JXWindow::kDeactivateDirector);
    
	JXMenuBar* menuBar =
		new JXMenuBar(window, JXWidget::kHElastic, JXWidget::kFixedTop, 
			0,0, w,kJXDefaultMenuBarHeight);
	assert( menuBar != NULL );

	itsToolBar =
		new JXToolBar(GetPrefsMgr(), kFitToolBarID,
			menuBar, w, h,
			window, JXWidget::kHElastic, JXWidget::kVElastic, 
			0,kJXDefaultMenuBarHeight, w,h - kJXDefaultMenuBarHeight);
	assert( itsToolBar != NULL );

	JSize newHeight = itsToolBar->GetWidgetEnclosure()->GetBoundsHeight();

	const JCoordinate kPartitionHandleWidth	= 5;
	const JCoordinate kFitListWidth			= 155;

	JArray<JCoordinate> widths(2);
	widths.AppendElement(kFitListWidth);
	widths.AppendElement(w - kFitListWidth - kPartitionHandleWidth);

	JIndex elasticIndex = 2;

	JArray<JCoordinate> minWidths(2);
	minWidths.AppendElement(100);
	minWidths.AppendElement(300);

	itsMainPartition =
		new JXHorizPartition(widths, elasticIndex, minWidths,
							 itsToolBar->GetWidgetEnclosure(), 
							 JXWidget::kHElastic,JXWidget::kVElastic,
							 0, 0, w, newHeight);
	assert( itsMainPartition != NULL );

	// This is the first column the contains the curve and fit lists.
	
	JXContainer* container = itsMainPartition->GetCompartment(1);

	const JCoordinate kCurveListHeight	= 100;
	const JCoordinate kColHeaderHeight	= 20;
	const JCoordinate kExprHeight		= 50;
	const JCoordinate kFitListHeight	= newHeight - kCurveListHeight - 2 * kPartitionHandleWidth - kExprHeight;
	
	JArray<JCoordinate> heights(3);
	heights.AppendElement(kCurveListHeight);
	heights.AppendElement(kFitListHeight);
	heights.AppendElement(kExprHeight);

	elasticIndex = 2;

	JArray<JCoordinate> minHeights(3);
	minHeights.AppendElement(50);	
	minHeights.AppendElement(100);
	minHeights.AppendElement(40);

	itsListPartition =
		new JXVertPartition(heights, elasticIndex, minHeights, container,
			JXWidget::kHElastic, JXWidget::kVElastic, 0, 0, kFitListWidth, newHeight);
    assert( itsListPartition != NULL );

	container = itsListPartition->GetCompartment(1);
	
	JXScrollbarSet* scrollbarSet =
		new JXScrollbarSet(container, 
						   JXWidget::kHElastic,JXWidget::kVElastic,
						   0, kColHeaderHeight,
						   kFitListWidth, kCurveListHeight - kColHeaderHeight);
	assert( scrollbarSet != NULL );

	// This will be the curve list

	itsCurveList	= 
		new GLCurveNameList(itsDir, itsPlot, 
			scrollbarSet, scrollbarSet->GetScrollEnclosure(),
			JXWidget::kHElastic, JXWidget::kVElastic,
			0, 0,  kFitListWidth, kCurveListHeight - kColHeaderHeight);
	assert(itsCurveList != NULL);
	ListenTo(itsCurveList);

	JXColHeaderWidget* header =
		new JXColHeaderWidget(itsCurveList, scrollbarSet,
			container,
			JXWidget::kHElastic, JXWidget::kFixedTop,
			0, 0,  
			kFitListWidth, 
			kColHeaderHeight);
	assert(header != NULL);

	header->SetColTitle(1, "Curves");
	
	container = itsListPartition->GetCompartment(2);
	
	scrollbarSet =
		new JXScrollbarSet(container, 
						   JXWidget::kHElastic,JXWidget::kVElastic,
						   0, kColHeaderHeight,
						   kFitListWidth, 
						   kFitListHeight - kColHeaderHeight);
	assert( scrollbarSet != NULL );

	// This will be the fit list
	
	itsFitList	= 
		new GLFitDescriptionList(scrollbarSet, scrollbarSet->GetScrollEnclosure(),
			JXWidget::kHElastic, JXWidget::kVElastic,
			0, 0,  
			kFitListWidth, 
			kFitListHeight - kColHeaderHeight);
	assert(itsFitList != NULL);
	ListenTo(itsFitList);

	header =
		new JXColHeaderWidget(itsFitList, scrollbarSet,
			container,
			JXWidget::kHElastic, JXWidget::kFixedTop,
			0, 0,  
			kFitListWidth, 
			kColHeaderHeight);
	assert(header != NULL);

	header->SetColTitle(1, "Fits");

	// this is the expression widget that displays the current JFunction

	container = itsListPartition->GetCompartment(3);
	
	scrollbarSet =
		new JXScrollbarSet(container, 
						   JXWidget::kHElastic,JXWidget::kVElastic,
						   0, 0,
						   kFitListWidth, 
						   kExprHeight);
	assert( scrollbarSet != NULL );

	itsExprVarList	= new GVarList();
	assert(itsExprVarList != NULL);

	itsExprWidget	= 
		new JXExprWidget(itsExprVarList,
			scrollbarSet, scrollbarSet->GetScrollEnclosure(),
			JXWidget::kHElastic, JXWidget::kVElastic,
			0, 0, 
			kFitListWidth, 
			kExprHeight);
	assert(itsExprWidget != NULL);
	itsExprWidget->Hide();

	// This is the second column that will contain the parameter table
	// and the plots

	container = itsMainPartition->GetCompartment(2);

	const JCoordinate kParmsTableHeight		= 50;
	const JCoordinate kChiSqHeight			= 20;
	const JCoordinate kTotalParmsHeight		= kParmsTableHeight + kColHeaderHeight + kChiSqHeight;
	const JCoordinate kFirstPlotHeight		= 120;
	const JCoordinate kMinPlotHeight		= 100;

	heights.RemoveAll();
	heights.AppendElement(kTotalParmsHeight);
	heights.AppendElement(kFirstPlotHeight);
	heights.AppendElement(newHeight - kFirstPlotHeight - kTotalParmsHeight - 2 * kPartitionHandleWidth);

	elasticIndex = 2;

	minHeights.RemoveAll();
	minHeights.AppendElement(kTotalParmsHeight - 20);
	minHeights.AppendElement(kMinPlotHeight);
	minHeights.AppendElement(kMinPlotHeight);
	
	itsPlotPartition =
		new JXVertPartition(heights, elasticIndex, minHeights, container,
			JXWidget::kHElastic, JXWidget::kVElastic, 
			0, 0, w - kFitListWidth - kPartitionHandleWidth, newHeight);
    assert( itsPlotPartition != NULL );

	container = itsPlotPartition->GetCompartment(1);
	
	scrollbarSet =
		new JXScrollbarSet(container, 
						   JXWidget::kHElastic,JXWidget::kVElastic,
						   0, kColHeaderHeight,
						   w - kFitListWidth - kPartitionHandleWidth, 
						   kParmsTableHeight);
	assert( scrollbarSet != NULL );

	// this will be the parameter table
	itsParameterTable =
		new GLFitParameterTable(scrollbarSet, scrollbarSet->GetScrollEnclosure(),
			JXWidget::kHElastic, JXWidget::kVElastic,
			0, 0,  
			w - kFitListWidth - kPartitionHandleWidth, 
			kParmsTableHeight);
	assert(itsParameterTable != NULL);
	ListenTo(itsParameterTable);

	itsParameterColHeader = 
		new GLParmColHeaderWidget(itsParameterTable, scrollbarSet,
			container,
			JXWidget::kHElastic, JXWidget::kFixedTop,
			0, 0,  
			w - kFitListWidth - kPartitionHandleWidth, 
			kColHeaderHeight);
	assert(itsParameterColHeader != NULL);

	itsParameterTable->SetColHeaderWidget(itsParameterColHeader);
	    
	itsFitMenu = menuBar->AppendTextMenu(kFitMenuTitleStr);
	itsFitMenu->SetMenuItems(kFitMenuStr);
	itsFitMenu->SetUpdateAction(JXMenu::kDisableAll);
	ListenTo(itsFitMenu);

	const JCoordinate kChiSqLabelWidth	= 170;

	GLChiSqLabel* label = 
		new GLChiSqLabel(container, 
			JXWidget::kFixedLeft, JXWidget::kFixedBottom,
			0, kParmsTableHeight + kColHeaderHeight,
			kChiSqLabelWidth, kChiSqHeight);
	assert(label != NULL);

	JXDownRect* downRect =
		new JXDownRect(container,
			JXWidget::kHElastic, JXWidget::kFixedBottom,
			kChiSqLabelWidth, kParmsTableHeight + kColHeaderHeight,
			w - kFitListWidth - kPartitionHandleWidth, kChiSqHeight);
	assert(downRect != NULL);

	itsChiSq =
		new JXStaticText("", container,
			JXWidget::kHElastic, JXWidget::kFixedBottom,
			kChiSqLabelWidth + kJXDefaultBorderWidth, 
			kParmsTableHeight + kColHeaderHeight + kJXDefaultBorderWidth,
			w - kFitListWidth - kPartitionHandleWidth - 2 * kJXDefaultBorderWidth, 
			kChiSqHeight - 2 * kJXDefaultBorderWidth);
	assert(itsChiSq != NULL);
	itsChiSq->SetBackColor(GetColormap()->GetWhiteColor());

	// now add the 2 plots

	container = itsPlotPartition->GetCompartment(2);

	itsFitPlot	= 
		new JX2DPlotWidget(menuBar, container,
			JXWidget::kHElastic, JXWidget::kVElastic,
			0, 0, 
			w - kFitListWidth - kPartitionHandleWidth,
			container->GetApertureHeight());
	assert(itsFitPlot != NULL);
	itsFitPlot->SetTitle(kFitPlotTitle);
	itsFitPlot->SetXLabel(itsPlot->GetXLabel());
	itsFitPlot->SetYLabel(itsPlot->GetYLabel());

	container = itsPlotPartition->GetCompartment(3);

	itsDiffPlot	= 
		new JX2DPlotWidget(itsFitPlot, container,
			JXWidget::kHElastic, JXWidget::kVElastic,
			0, 0, 
			w - kFitListWidth - kPartitionHandleWidth,
			newHeight - kFirstPlotHeight - kTotalParmsHeight - 2 * kPartitionHandleWidth);
	assert(itsDiffPlot != NULL);
	itsDiffPlot->SetTitle(kDiffPlotTitle);
	itsDiffPlot->SetXLabel(itsPlot->GetXLabel());
	itsDiffPlot->SetYLabel(itsPlot->GetYLabel());
	itsDiffPlot->ShowFrame(kJFalse);

	itsPrefsMenu = menuBar->AppendTextMenu(kPrefsMenuTitleStr);
	itsPrefsMenu->SetMenuItems(kPrefsMenuStr);
	itsPrefsMenu->SetUpdateAction(JXMenu::kDisableNone);
	ListenTo(itsPrefsMenu);

	itsHelpMenu = menuBar->AppendTextMenu(kHelpMenuTitleStr);
	itsHelpMenu->SetMenuItems(kHelpMenuStr);
	itsHelpMenu->SetUpdateAction(JXMenu::kDisableNone);
	ListenTo(itsHelpMenu);

	itsHelpMenu->SetItemImage(kTOCCmd, jx_help_toc);
	itsHelpMenu->SetItemImage(kThisWindowCmd, JXPM(jx_help_specific));

	itsCurveList->SetCurrentCurveIndex(1);

	GetPrefsMgr()->ReadFitDirectorSetup(this);
}