// Filename:	WKS.OGS
// Creation:	by Joe Przechocki, 8/9/96
// Purpose:	Worksheet Analysis Menu scripts common to Context Menus and Standard tool
//**********************************************
// Modification Log:
//		RKM 11/09/96 Added [GoToRow][AddNewCol]
//		RKM 11/11/96 added [Worksheet][Column][ColorPalette]
//		RKM 11/12/96 added matrix sections
//		RKM 11/20/96 removed [Worksheet] [Column] [ColorPalette] sections, 
//		put the script in the string for ID
//		RKM 12/04/96 added 6 sort sections for Context Sensitive menus
//		RKM 12/10/98 v6.0141 REPORT_TO_OUTPUTLOG
//		SDB 1/7/99   v6.0148 REPORT_TO_OUTPUTLOG
//		CPY 6/30/00 v6.0295 t7988 ADD_SUM_TO_ROW_STAT
//		CPY v6.0303 t8198 7/13/00 LARGE_ROW_NUMBER_LOW_SIG_DIGITS
//		GJL 5/28/02 v7.0313 QA70-1868 ADD_DATA_FROM_PAGE_LABEL
//		GJL 5/28/02 v7.0313 QA70-1889 CHECK_FREQ_COUNT_INPUT_ERROR
//		GJL 11/26/02 v7.0445 QA70-3136 FREQ_COUNT_INCLUDE_TRUE_MAX
//		GJL 6/06/02 v7.0316 QA70-2003 ADD_DDK_DIRECT_MATRIX_CONVERT_DB
//		ML 4/20/2003 QA70-4155 CLASS_SECTION_NAME_WITH_ARG_FOR_70
//		LAS 7/17/03 QA-3648 Modified [ConvSparse]
//**********************************************


//////////////////////////////////////////////////////////////////////
//
// Statistics on Columns
//
///////////////////////////////////////////////////////////////////////

/// ML 4/20/2003 QA70-4155 CLASS_SECTION_NAME_WITH_ARG_FOR_70
[DescStats]
	if((0 < macro.narg) && %1)
	{
		run.section(,StatRow);
	}
	else
	{
		run.section(,StatCol);
	}
	return 0;
/// end CLASS_SECTION_NAME_WITH_ARG_FOR_70

[StatCol]
	#Descriptive statistics on the selected columns; results in new worksheet
	//JMP v3.83 Change to check selection using wks.sel
	if (wks.sel&8!=8) 
	{
		type -b $general.SelectionError;
		break 1;
	} 
	%W = %H; /* save worksheet name */
	ii=wks.sel;
	win -T Wks ColStat;

	if(ii&2==2)
		Range.Choice=1;
	else
		Range.Choice=2;

	store.v1$=%W;
	count=1;
	loop(ii,1,%W!wks.iscolsel())
	{
		jj=%W!wks.c1+%(%W,@O,ii-1);
		if ((%W!wks.col$(jj).type)!=2 && (%W!wks.col$(jj).format)!=2)
		{
			%A=%(%W,@Col,jj);
			wcol(1)[count]$ = "%A";
						//--------- CPY v6.0303 t8198 7/13/00 LARGE_ROW_NUMBER_LOW_SIG_DIGITS
			//wcol(2)[count]$ = "[$(%W!wks.r1):$(%W!wks.r2)]";
			wcol(2)[count]$ = "[$(%W!wks.r1,%d):$(%W!wks.r2,%d)]";
						//---------	end t8198 $(x,%d) will get integer row numbers
			count+=1;
		}
	}
	Recalculate.run();
	// GJL 5/28/02 v7.0313 QA70-1868 ADD_DATA_FROM_PAGE_LABEL	
	page.label$=statlabel.text$;
	page.title=3;
	return 0;
	// End GJL 5/28/02 v7.0313 QA70-1868 ADD_DATA_FROM_PAGE_LABEL

//////////////////////////////////////////////////////////////////////
//
// Statistics on Rows
//
///////////////////////////////////////////////////////////////////////

[StatRow]
	#Descriptive statistics across rows of the selection; results in new worksheet
	if (wks.sel&8!=8) 
	{
		type -b $general.SelectionError;
		break 1;
	} 
	if (wks.iscolsel()!=(wks.c2-wks.c1+1)) 
	{
		type -b $general.ContiguousError;
		break 1;
	} 

	select1=wks.c1;
	select2=wks.c2;

	loop(ii,wks.c1,wks.c2)
	{
		if ((wks.col$(ii).type)==2 || (wks.col$(ii).format)==2)
		{
			if(ii==select1)
				select1+=1;
			else
				set %(%H,ii) -es 0;
		}
	}

	for(ii=select2;ii>=select1;ii-=1)
	{
		if ((wks.col$(ii).type)==2 || (wks.col$(ii).format)==2)
			select2-=1;
		else
			break;
	}
	if(select2<select1)
	{
		type -b $general.ContiguousError;
		break;
	}
	//----------- CPY 6/30/00 v6.0295 t7988 ADD_SUM_TO_ROW_STAT
	//sum(%H,select1,select2);
	_sum = sum(%H,select1,select2);
	//-----------
	get %(%H,select1) -e ii;
	ii=ii<wks.r2?ii:wks.r2;
	%W = %H; /* save worksheet name */
	win -T Wks RowStat;
	%A="Col(%(%W,@Col,select1)) => Col(%(%W,@Col,select2))";
	// GJL 5/28/02 v7.0313 QA70-1868 ADD_DATA_FROM_PAGE_LABEL
	%B=$WksStat.StatLabel;
	label -s -sa -n stat "%B\r\n%A";
	page.label$="%B %A";
	page.title=3;
	// End GJL 5/28/02 v7.0313 QA70-1868 ADD_DATA_FROM_PAGE_LABEL

	set %H -er (ii-%W!wks.r1+1);
	col(row)=data(%W!wks.r1,ii,1);
	copy -b %W!wks.r1 _mean col(mean) -b 1 -e (ii-%W!wks.r1+1);
	copy -b %W!wks.r1 _sd col(sd) -b 1 -e (ii-%W!wks.r1+1);
	copy -b %W!wks.r1 _min col(min) -b 1 -e (ii-%W!wks.r1+1);
	copy -b %W!wks.r1 _max col(max) -b 1 -e (ii-%W!wks.r1+1);
	copy -b %W!wks.r1 _npts col(n) -b 1 -e (ii-%W!wks.r1+1);
	copy -b %W!wks.r1 _range col(range) -b 1 -e (ii-%W!wks.r1+1);
	//----------- CPY 6/30/00 v6.0295 t7988 ADD_SUM_TO_ROW_STAT
	copy -b %W!wks.r1 _sum col(sum) -b 1 -e (ii-%W!wks.r1+1);
	//-----------
	col(se)=col(sd)/sqrt(col(n));
	delete -v select1;
	delete -v select2;
	return 0;

//////////////////////////////////////////////////////////////////////
//
// Frequency Count
//
///////////////////////////////////////////////////////////////////////

[FreqCount]
	%W = %H; /* save worksheet name */
	
	#Count frequency for histogram
	TestColSel;
	/* we will contiune if %C is OK. Remember %C is the data set name
	 * of the selected column
	 */
	if(wks.iscolsel()!=1)
	{
		type -b $General.Only1YColumn;
		break;
	}
	if(wks.col$(wks.c1).format==2)
	{
		type -b $General.BadFormat;
		break;
	}
	
	sum(%C);/* We need to find the maximum and minimum */

	/* we may also print the statistics on the script window */
	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 $Statistics.StatHeader1;
	type;
	type $Statistics.StatHeader2;
	separator 3;
	type "$(sum.mean)\t$(sum.sd)\t$(sum.n)";
	type;
	
	if (sum.n < 200) {/* don't do this if too many points */
		/* To find the median, we sort the data and find the mid point */
		w1=sort(%C);
		get w1 -b i1;get w1 -e i2;/* i1 and i2 now contains begin and end index */
		i=int((i2-i1+1)/2);
		type $Statistics.StatHeader3;
		separator 3;
		type "$(mod(i2-i1,2)==0?w1[i+1]:0.5*(w1[i+1]+w1[i]))";
		type;
				/* notice the C notation? */
		del w1;		/* we are done with w1 for the time being */
	} 

	i = nint(sqrt(sum.N));
	if(i < 2) 
	{
		type -b $Plot.HistNoPts;
		break 1;
	} 

	getenumwks Count; //LAS added; open a worksheet template called Count
				
	// GJL 5/28/02 v7.0313 QA70-1889 CHECK_FREQ_COUNT_INPUT_ERROR
	def OnApply {
		if( inc > 0 && inc < (sum.max-sum.min)/2 )
			run.section(,MakeFreqCount);
		else
			type -b $WksAnaly.FreqCountInputError;
	}	

	if(run.section(,GetNFreqCount) == 0)
		run.section(,MakeFreqCount);
	else
		win -cd %H;  //delete Count wks if Cancel
					
	type.EndResults();
	type.Redirection=SaveRedirection; // restore previous redirection.
	delete -v SaveRedirection;
	return 0;
	
[GetNFreqCount]
	// GJL 11/26/02 v7.0445 QA70-3136 FREQ_COUNT_INCLUDE_TRUE_MAX
	MaxVal=sum.max;
	limit -r sum.min sum.max i inc; /* round these numbers */
	if(MaxVal==sum.max)             // If true max==rounded max go up one more bin to include true max
		sum.max+=inc;
	delete -v MaxVal;
	// End FREQ_COUNT_INCLUDE_TRUE_MAX
	
	GetNumber $WksAnaly.FreqCountMin sum.min $WksAnaly.FreqCountMax sum.max $WksAnaly.FreqCountStep inc $WksAnaly.FreqCountCount;
	/* the three variables inc, sum.min, sum.max will contain user choices. */

	if( inc > 0 && inc < (sum.max-sum.min)/2 ) 	// GJL 5/28/02 v7.0313 QA70-1889 CHECK_FREQ_COUNT_INPUT_ERROR
		return 0;

	type -b $WksAnaly.FreqCountInputError;

	return 1;

[MakeFreqCount]
	ClearWorksheet %H;
		
	col(1)=data(sum.min+(1/2)*inc,sum.max+(1/2)*inc,inc);
		/*  X column for the new worksheet. Note that this must
		 *  be done before the sum function is called again.
		 *  Also, this actually may create one more point than
		 * is needed.
		 */
	
	win -o %W {w1=histogram(%C,inc,sum.min, sum.max);}  
	col(2)=w1;
	del w1;

	col(3)=col(1);col(3)+=(1/2)*inc;
		/* this is the X column for the cumulative sum, it needs to be
		 * offseted for inbetween bins
		 */
	col(4)=sum(col(2));
		/* col 4 contains cumulative counts. sum.max, min etc are modified. */
	
	set %H -e sum.n;
		/* to make sure all columns have the same size */
	return 0;
	
//////////////////////////////////////////////////////////////////////
//
// Data Normalization
//
///////////////////////////////////////////////////////////////////////

[Normalize]
	#Enter a factor to normalize %C
	if(wks.iscolsel()!=1)
	{
		type -b $General.Only1Column;
		break;
	}
	sum(%C);/* We need to find the maximum and minimum */
	divider=sum.max;
	
	GetNumber -s $WksAnaly.NormalizeCurrent divider
	$WksAnaly.NormalizeDataset;
	
	if (divider==0 || divider==0/0 )
	{
		type -b $General.Normalize;
		return 1;
	}

	/* divide %C by divider
	 * may need to check for zero here
	 */

	/* QZCao_undo, v3.69 */
	undo -wr;
	/* QZCao_undo, v3.69 */	
	
	%C/divider;
	del divider;
	return 0;

[Sort]
	#Arranges the worksheet in ascending/descending order according to the highlighted column
	/*Laurie modified v3.83*/
	if (exist(%C)!=1) 
	{
		type -b $general.SelectionError;
		break 1;
	} 
	%A=$General.SortUporDown;
	%B=$General.SortWksorCol;

	checkVar SortOrder 1;
	checkVar selectorder 1;

	/* QZCao_undo, v3.69 */
	undo -wc %H;
	/* QZCao_undo */
	
	if(SortOrder < 1 || SortOrder>2) SortOrder=1;
	if (selectorder<1 || selectorder>2) selectorder=1;

	if (wks.c1==wks.c2)
	{
		getn $WksAnaly.SortSort sortorder:A $WksAnaly.SortSelect selectorder:B $WksAnaly.SortSortData;
		if (sortorder==1 && selectorder==1)
		sort -w %H %C;
		
		if (sortorder==1 && selectorder==2)
		sort -c wks.c1 wks.c2 %C;
		
		if (sortorder==2 && selectorder==2)
		sort -cd wks.c1 wks.c2 %C;
		
		if (sortorder==2 && selectorder==1)
		sort -wd %H %C;
		
	}
	else
	{
		getn $WksAnaly.SortSecond sortorder:A $WksAnaly.SortRegion;
		if (sortorder==1)
			sort -c wks.c1 wks.c2 %C;
		else
			sort -cd wks.c1 wks.c2 %C;
	}
	return 0;

[SortRangeAsc]
	sort -c wks.c1 wks.c2 %C;
	return 0;

[SortRangeDesc]
	sort -cd wks.c1 wks.c2 %C;
	return 0;

[SortColAsc]
	sort -c wks.c1 wks.c2 %C;
	return 0;

[SortColDesc]
	sort -cd wks.c1 wks.c2 %C;
	return 0;

[SortWksAsc]
	sort -w %H %C;
	return 0;

[SortWksDesc]
	sort -wd %H %C;
	return 0;

[GoToRow]
	v1=y1+1;
	GetNum -s $EXEmessage.GotoRow v1 $EXEmessage.GotoTitle;
	y1=v1-1;
	return 0;

[AddNewCol]
	if(run.section(,CheckForSelection, AddColNoSelection)==0)
	{
		v1=1;
		GetNum -s $EXEmessage.HowManyCol v1 $EXEmessage.HowManyColTitle;
		worksheet -a v1;
	}
	return 0;

[Wks2Mat]
	// GJL 6/06/02 v7.0316 QA70-2003 ADD_DDK_DIRECT_MATRIX_CONVERT_DB
	// Open Dialog Builder Direct Matrix Conversion dialog box
	run.section(DBRoutines.OGS,SaveAndSetAtOC);

	if(run.section(DBRoutines.OGS,LoadOMatWorkspace)==0)
		OnOpenDMC();

	run.section(DBRoutines.OGS,RestoreAtOC);
	
//	if(run.section(,CheckForSelection, SelectionIgnored)==0)
//	{
//		mat.wksname$ = %H;
//		win -T M;
//		mat.matname$ = %H;
//		//mat.errout = 2;  
//		mat.w2m();
//	}
	
	return 0;

[ExpRow2Mat]
	if(run.section(,CheckForSelection, SelectionIgnored)==0)
	{
		//checkVar nExpCols 5;
	  
		/// ML 8/18/95  SUBPROP_AND_ARGHANDLING
		//getnumber -s [Expand for every column] nExpCols;
		///CPY v3.83 9/20/95 LABMATRIX_BEFORE_RELEASE
		//getnumber -s [Expand for every column] mat.exp2m.cols;
		getnumber -s $Wksheet.ExpRow2MatRow mat.exp2m.cols;
		///
		mat.wksname$ = %H;
		win -T M ;
		mat.matname$ = %H;
		//mat.errout = 2;   
		/// ML 8/18/95  SUBPROP_AND_ARGHANDLING
		//mat.exp2m($(nExpCols));
		mat.exp2m();
	}
	return 0;

[SetColumnValues]
	#Opens the Set Column Values dialog box
	menu -e menu.find(co,sv);
	return 0;

[Multix]
	wks.multix=wks.multix==0?1:0;
	return 0;

////////////////////////////////////////////////////////////////////////////////
//
// Binning Code 
//
// Code to perform 2-D binning of data in selected y column.  Highlight
// a Y-column in a worksheet and click the Custom button on the Standard toolbar.  A
// dialog will open allowing the user to input the X and Y bin limits and increment.  A
// matrix will then be created to hold the binned data.
//
// Bins:     bin >= values > bin
//
////////////////////////////////////////////////////////////////////////////////

[2DBinning]
	if(run.section(,BinInit)!=0)
	{
			type -b $General.NeedAssocXColumn;
			break;
	}	
	if(run.section(,GetLimits)==0) 
	{				 	//user input
		run.section(,CreateMatrix,%A);	//get bin values and load matrix
		run.section(,Cleanup);		//clean up datasets and variables
	}
	return 0;

[BinInit]
	switch(wks.iscolsel())
	{
		case 1:
			if(%(%H,@Y#,2)!=1||exist(xof(%C))!=1)
				return 1;
			break;
		case 2:
			if(%(%H,@Y#,2)!=1)
				return 1;
			if(%(%H,@type,selc1)!=4&&%(%H,@type,selc2)!=4)
				return 1;
			
			break;
		default:
			return 1;
	};

	%A=%(%H,%(%H,@YS,1));
	limit %A;				//find limiting values of datasets
	sum(%A);
	i = nint(sqrt(sum.N));
	XInc=1;YInc=1;
	limit -r limit.xmin limit.xmax i XInc;
	limit -r limit.ymin limit.ymax i YInc;
	return 0;

[GetLimits]
	//allow user to change bins
	YInc=abs(YInc);
	XInc=abs(XInc);
	getn
	($Wksheet.Xmin) limit.xmin
	($Wksheet.Xmax) limit.xmax
	($Wksheet.Xincrement) XInc
	($Wksheet.Ymin) limit.ymin
	($Wksheet.Ymax) limit.ymax
	($Wksheet.Yincrement) YInc
	($Wksheet.BinMatrix);
	XBins=(limit.xmax-limit.xmin)/xinc;
	YBins=(limit.ymax-limit.ymin)/yinc;
	if(int(YBins)!=$(YBins))
		YBins+=1;
	if(int(XBins)!=$(XBins))
		XBins+=1;
	return 0;

[CreateMatrix]
	undo -wc %H;
	get %1 -b bd;
	get %1 -e ed;
	sort.wksname$=%H;
	sort.missing=0;
	sort.r1=bd;
	sort.r2=ed;
	%B=xof(%1);
	sort.cname1$=D: %[%B,>"_"];
	sort.wks();
	create _matrix -t 1;
	create _dummy -t 1;
	kk=xindex1(limit.xmin,%1);
	loop(ii,1,XBins)
	{
		%A=%1;
		jj=xindex((limit.xmin+(XInc*ii)),%1);
		for(;xof(%1)[jj]==xof(%1)[jj+1]&&xof(%1)[jj]>=(limit.xmin+(XInc*ii))&&xof(%1)[jj]!=0/0;)
			jj+=1;
		if(jj>=ed)
			%A=_dummy;
		if(jj==0/0)
			jj=1;
		if(xof(%1)[jj]>=(limit.xmin+(XInc*ii)))
			jj+=1;
		set %1 -b jj;
		set %1 -e kk;
		copy -a histogram(%A,YInc,limit.ymin,limit.ymax) _matrix;
		kk=jj-1;
		set %1 -b bd;
		set %1 -e ed;
	};
	undo;
	win -t matrix matrix;
	matrix -ps DIM YBins XBins;
	matrix -ps X (limit.xmin+(xinc/2)) (limit.xmax-(xinc/2));
	matrix -ps Y (limit.ymin+(yinc/2)) (limit.ymax-(yinc/2));
	copy -b 2 _matrix %H;			//copy bin data to matrix
	matrix -t;
	return 0;

[Cleanup]
	delete _Matrix;			//cleanup datasets and global variables
	delete _Dummy;			
	delete -v XBins;
	delete -v YBins;
	delete -v XInc;
	delete -v YInc;
	delete -v kk;
	delete -v bd;
	delete -v ed;
	return 0;

[CheckForSelection]
	if(wks.iscolsel()!=0)
	{
		type -n $Wksheet.%1;
	}
	return 0;

[ConvReg]
	CheckWksSelection;	
	create.wksName$="TempWks";
	create.enumwks=1;
	create.template$="CREATE";
	create.type1=4;
	create.type2=1;
	create.type3=6;
	create.type4=1;
	create.type5=1;
	create.wks(A B C D E);
	%A=create.wksname$;
	if(run.LoadOC("OriginLab\ConvertRegularXYZ.OCW",4)!=0)	
	{
		run.section(DBRoutines.OGS,ReportError,$GriddingXYZ.LoadGridErr);
		return 1;
	}
	run.section(DBRoutines,SaveAndSetAtOC);

	// first of all, remove duplicate X,Y data pairs and replace them with mean values
	ii=RemoveDuplicates("%H",$(nXcol-1),$(nYcol-1),$(nZcol-1),"%A");
	if (ii > 0)
		type -b $GriddingXYZ.Duplicates;
	if (ii < 0)
		type -b $GriddingXYZ.ErrSort;

	ii = ConvertRegularXYZ("%H",$(nXcol-1),$(nYcol-1),$(nZcol-1),"%A");
	run.section(DBRoutines,RestoreAtOC);
	switch(ii)
	{
		case 0:
			mat.res=0.0;
			mat.wksname$="%A";
			mat.xcol=1;
			mat.ycol=2;
			mat.zcol=3;
			//Create a new matrix
			win -t mat;
			mat.matname$=%H;
			//Convert the XYZ data to a matrix
			mat.xyz2m( );
			win -cd %A;
			break;
		case 2:
			type -b $GriddingXYZ.ErrStepSize;
			break;
		case 3:
			type - b $GriddingXYZ.ErrNotRegData;
			break;
		default:
			type -b $GriddingXYZ.ErrDeviation;
			break;
	}
	return 0;

[ConvSparse]	
	if(run.LoadOC("OriginLab\ConvertSparseXYZ.OCW",4)!=0)	
	{
		run.section(DBRoutines.OGS,ReportError,$GriddingXYZ.LoadGridErr);
		return 1;
	}
	run.section(DBRoutines,SaveAndSetAtOC);
	CheckWksSelection;
	ConvertSparseXYZ(%H, nXcol-1, nYcol-1, nZcol-1);	
	return;
