///////////////////////////////////////////////////////////////////////////////////////////
// File:	FftTool.OGS
// Purpose:	Modularized Code for performing FFT's
// Modification Log:
///////////////////////////////////////////////////////////////////////////////////////////

[MenuInit]
	if(exist(%H)==2)
	{
		if(run.section(,WksInit)==0)
		{
			hw=dialog.domodal(OTools,FFTTool);
			return 0;
		}
	}
	if(exist(%H)==3)
	{
		if(run.section(,GraphInit)==0)
		{
			dialog.domodal(OTools,FFTTool);
			return 0;
		}
	}
	
[WksInit]	
	FFT.reset();
	fftdt=1.0;
	if(wks.iscolsel()<1||wks.iscolsel()>3)
	{
		type -b $FFT.SelcRang;
		return 1;
	}
	loop(ii,0,wks.iscolsel()-1)
	{
		colnum=wks.c1+%(%H,@O,ii);
		coltype=wks.col$(colnum).type;
		if(coltype==2||coltype==3||coltype==5||coltype==6||coltype==7)
		{
			type -b $FFT.SelcRang;
			return 1;
		}
	}
	switch (wks.iscolsel())
	{
	case 1:
		if(wks.col$(wks.c1).type==4)
		{
			type -b $FFT.SelcRang;		//If selected column is X, type Error message
			return 1;
		}
		else
		{
			%M=%(%H,wks.c1);
			run.section(,FFTSearchForX);
			%N="";			//Set imaginary to null
			FFT.real=1;
		}
		break;
	case 2:
		if(wks.col$(wks.c1).type==4 && wks.col$(wks.c1+%(%H,@O,1)).type==4)
		{
			type -b $FFT.SelcRang;		//If both columns are X, type Error message
			return 1;
		}
		if(wks.col$(wks.c1).type==1)
		{
			%M=%(%H,wks.c1);		//Set first column to real
			if(wks.col$(wks.c1+%(%H,@O,1)).type==1)
			{
				%N=%(%H,wks.c1+%(%H,@O,1));	//If second colum is Y, set it to imaginary
				fft.real=0;
				run.section(,FFTSearchForX);
			}
			else
			{		
				%O=%(%H,wks.c1+%(%H,@O,1));	//If second colum is X, set it to time
				%N="";				//Set imaginary to null
				fft.real=1;
			}
		}
		else
		{
			%O=%(%H,wks.c1);		//First column selected is X and set to Time
			%M=%(%H,wks.c1+%(%H,@O,1));	//Second column selected is Y and set to Real
			%N="";				//Set imaginary to null
			fft.real=1;
		}
		break;
	case 3:	
		NumX=0;
		for(ii=0;ii<3;ii++)
		{
			if(wks.col$(wks.c1+%(%H,@O,ii)).type==4)
			NumX++;
		}
		if(NumX!=1) 
		{
			type -b $FFT.SelcRang;
			return 1;
		}
		//Search for the X column
		if(wks.col$(wks.c1).type==4)
		{
			%O=%(%H,wks.c1);		//First column selected is X and set to Time
			%M=%(%H,wks.c1+%(%H,@O,1));	//Second column selected is Y and set to Real
			%N=%(%H,wks.c1+%(%H,@O,2));	//Third column selected is Y and set to Imaginary
		}			
		if(wks.col$(wks.c1+%(%H,@O,1)).type==4)
		{
			%O=%(%H,wks.c1+%(%H,@O,1));	//Second column selected is X and set to Time
			%M=%(%H,wks.c1);		//First column selected is Y and set to Real
			%N=%(%H,wks.c1+%(%H,@O,2));	//Third column selected is Y and set to Imaginary
		}			
		if(wks.col$(wks.c1+%(%H,@O,2)).type==4)
		{
			%O=%(%H,wks.c1+%(%H,@O,2));	//Third column selected is X and set to Time
			%M=%(%H,wks.c1);		//First column selected is Y and set to Imaginary
			%N=%(%H,wks.c1+%(%H,@O,1));	//Second column selected is Y and set to Real
		}			
		FFT.real=0;
		break;		
	}
	delete -v colnum;
	delete -v coltype;
	delete -v NumX;
	run.section(,FFTdatasets); 
	run.section(,FFTCheckres);

[GraphInit]
	fft.reset();
	fft.forward.Realdata$ = %C;
	%O = xof(%C);
	if(%[%O,'_']=="")
	{
		%O="";
		get %C -i fftdt;
		fft.forward.tdelta=fftdt;
	}
	fft.forward.timedata$ = %O;
	
	fft.forward=1;
	fft.real=1;
	if(fft.chkres())
		type -b $FFT.badResolution;

	i1=fft.chkres.i1;
	i2=fft.chkres.i2;
	return 0;

[Tab.Operation.OnInit]
	FFTTool!Tab.Operation.Forward.choice=1;
	FFTTool!Tab.Operation.Amplitude.choice=1;


[Tab.Settings.OnInit]
	FFTTool!Tab.Settings.WinMethod.choice=1;
	FFTTool!Tab.Settings.Phasefact=1;
	FFTTool!Tab.Settings.NormAmp=1;
	FFTTool!Tab.Settings.Shift=1;
	FFTTool!Tab.Settings.Unwrap=1;
	if(exist(%H)==2)
	{
		FFTTool!Tab.Settings.Sampling$=%O;
		FFTTool!Tab.Settings.Real$=%M;
		FFTTool!Tab.Settings.Imaginary$=%N;
	   	if( %O != "")
	   	{
	   			FFTTool!Tab.Settings.SampInt$=$(FFT.forward.tdelta);
	   	}
	   	else
	   	{
	   		FFTTool!Tab.Settings.SampInt.v1=fftdt;	
	   	}
		return 0;
	}
	if(exist(%H)==3)
	{
	   	FFTTool!Tab.Settings.Sampling$=%O;
		FFTTool!Tab.Settings.Real$=%C;
		FFTTool!Tab.Settings.Imaginary$="";
	   	FFTTool!Tab.Settings.SampInt$=$(fft.forward.tdelta);	
		FFTTool!Tab.Settings.WinMethod.choice=fft.windowing;
		FFTTool!Tab.Settings.NormAmp=fft.normalize;
		FFTTool!Tab.Settings.Shift=fft.shifted;
		FFTTool!Tab.Settings.Unwrap=fft.unwrap;
	}

[FFTSearchForX]
	if hasx(%(%H,wks.c1))
		%O=xof(%(%H,Wks.c1));
	else
	{
		%O="";
		get %(%H,Wks.c1) -i fftdt;
	}
[FFTdatasets]
	fft.forward.timedata$=%O;
	fft.forward.realdata$=%M;
	fft.forward.imagdata$=%N;

[FFTCheckres]
	if(fft.chkres())
		type -b $FFT.badResolution;
    i1=fft.chkres.i1;
    i2=fft.chkres.i2;
    
[Tab.Operation.OK.OnClick]
	if (exist(%H)==3 && Layer.is3D==1)
	{
		type -b $general.2DGraphsOnly;
		return 1;
	}
	run.section(,FFTsetting);
	switch(FFTTool!Tab.Operation.Forward.choice)
	{
		case 1:
			FFT.forward =1;
			run.section(,FFTforward);
			break;
		case 2:
			FFT.forward=0;
			run.section(,FFTBackward);
			break;
	};
	run.section(,FFTplotting);
	run.section(,FFTreportSize);
	run.section(,FFTcleanUp);     
	dialog.close(OTools,ffttool);

[Tab.Operation.Cancel.OnClick]
	dialog.close(OTools,ffttool);

[FFTsetting]
	fft.windowing=FFTTool!Tab.Settings.WinMethod.choice;
	fft.normalize=FFTTool!Tab.Settings.NormAmp;
	fft.shifted=FFTTool!Tab.Settings.Shift;
	fft.unwrap=FFTTool!Tab.Settings.Unwrap;

	fft.convention=FFTTool!Tab.Settings.PhaseFact.choice-1;			//fft.convention=0 for EE as in Origin 5.0 and 1 for Science

	return 0;

//////////////////////////////////////////////////////////////////////
//
// Forward FFT
//
///////////////////////////////////////////////////////////////////////
[FFTForward]
	FFT.forward.tdelta=FFTTool!Tab.Settings.SampInt.v1;
	fft.forward.timedata$=FFTTool!Tab.Settings.Sampling$;
	fft.forward.realdata$=FFTTool!Tab.Settings.Real$;
	fft.forward.imagdata$=FFTTool!Tab.Settings.Imaginary$;
	if( %O != "")
   	{
   		if(FFT.forward.tdelta==0.0)
   		{
   			type -b $fft.zerosample;
   			return;
   		}
   	}

	GetEnumWks FFT;
	%W=%H;
	fft.output.samplingdata$=%H_freq;
	run.section(,FFToutputDataset);

	fft.forward(i1,i2);
	
	switch(FFTTool!Tab.Operation.Amplitude.choice)
	{
		case 1:
			GetEnumWin FFTPlot;
			break;
		case 2:
			GetEnumWin FFTPower;
			break;
	}; 

[FFToutputDataset]
	fft.output.Realdata$=%H_real;
	fft.output.Imagdata$=%H_imag;
	fft.output.ampdata$=%H_r;
	fft.output.phasedata$=%H_phi;
	fft.output.powerdata$=%H_power;


//////////////////////////////////////////////////////////////////////
//
// Backward FFT
//
///////////////////////////////////////////////////////////////////////

[FFTBackward]
	fft.forward.tdelta=1.0;
	fft.forward.timedata$="";
	fft.forward.realdata$="";
	fft.forward.imagdata$="";
	
	fft.backward.fdelta=FFTTool!Tab.Settings.SampInt.v1;
	fft.backward.freqdata$=FFTTool!Tab.Settings.Sampling$;
	fft.backward.realdata$=FFTTool!Tab.Settings.Real$;
	fft.backward.imagdata$=FFTTool!Tab.Settings.Imaginary$;

	if( %O != "")
   	{
   		if(FFT.backward.fdelta==0.0)
   		{
   			type -b $fft.zerosample;
   			return;
   		}
   	}

	/* Get Enum Named Wks */
	getenumwks IFFT;
	%W=%H;
	fft.output.samplingdata$=%H_time;
	run.section(,FFToutputDataset);

	fft.backward(i1,i2);
	
	switch(FFTTool!Tab.Operation.Amplitude.choice)
	{
		case 1:
			GetEnumWin IFFTPlot;
			break;
		case 2:
			GetEnumWin IFFTPowe;
			break;
	};

[FFTplotting]
	layer -s 1;
	/* use global variable FixedFrom */
	FixedFrom=0;
	if( (fft.real) || (fft.shifted==0) ) 
		FixedFrom=1;
    
	layer -s 2;layer -i200 %(%W,5);
	switch(FFTTool!Tab.Operation.Amplitude.choice)
	{
		case 1:
			layer -s 1;layer -i200 %(%W,4);
			break;
		case 2:
			layer -s 1;layer -i200 %(%W,6);
			break;
	};
	
	/* CPY v3.73 set rescale type depending on real or complex */
	//TC commented folowing block
	/*
	doc -e -lw 
	{
		if (FixedFrom) 
		{
			layer.x.rescale=4;
			X1=0;
			layer -a;
		} 
		else
		{ 
			layer.x.rescale=2;
			layer -a;
		}
	}; 
	*/ 

	//TC: the two X-axes are linked
	if (FixedFrom) 
	{
		layer.x.rescale=4;
		X1=0;
	} 
	else
	{ 
		layer.x.rescale=2;
	}

	layer -s 1; layer -a;
	layer -s 2; layer -a;
	return 0;
    
[FFTreportSize]
	SaveRedirection=type.Redirection(16,3);	// SDB 1/7/99 v6.0148 REPORT_TO_OUTPUTLOG
	type.BeginResults();		/// RKM 12/10/98 v6.0141 REPORT_TO_OUTPUTLOG
	type $Wksanaly.ReportSize;
	type.EndResults();
	type.Redirection=SaveRedirection; // restore previous redirection.
	delete -v SaveRedirection;

[FFTcleanUp]
	dialog.close(ffttool);
	del -v %M; del -v %N; del -v %O; del -v %W;
	del -v FixedFrom;  del -v i1; del -v i2; del -v interval;
	return 0;
	//end NEW_FFT
