/*------------------------------------------------------------------------------*
 * File Name LT_PE.c: some Origin C basic utilities								*
 * Purpose: OriginC Source C file												*
 * Copyright (c) OriginLab Corp. 2007											*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 * Frank 9/16/05 CHANGE_OC_TO_XF_CODE_LT_PE										*
 * CPY 6/19/2007 I remove old codes and move LT_Math.c contents here			*
 *	Folger 01/06/09 QA81-14903 FILTER_DATAPLOTS_TAGS_WITH_FITCURVES				*
 *	Folger 08/02/10 ORG-672 INTEG1_SUPPORT_MULTIPLE_XYRANGES					*
 *------------------------------------------------------------------------------*/
 
////////////////////////////////////////////////////////////////////////////////////
// you can include just this typical header file for most Origin built-in functions and classes
// and it takes a reasonable amount of time to compile, 
#include <origin.h>


#pragma labtalk(0) //--- CPY 7/26/05 hide all functions in this file from LT access, as XF should be used instead

// return size of vsShortNames, or negative error codes
int find_workbook(vector<string>& vsShortNames, 
LPCSTR lpcszByLongName , LPCSTR lpcszBySheetName , 
LPCSTR lpcszByColLongName , BOOL bCaseSensitive,BOOL bWildCard )
{
	bool bMatchBook = false;
	
	string strByLongName = lpcszByLongName;
	string strBySheetName = lpcszBySheetName;
	string strByColLongName = lpcszByColLongName;
	
	if(strByLongName.IsEmpty())
		strByLongName = "*";
	if(strBySheetName.IsEmpty())
		strBySheetName = "*";
	if(strByColLongName.IsEmpty())
		strByColLongName = "*";
		
	foreach(WorksheetPage wpg in Project.WorksheetPages)
	{
		bMatchBook = false;
		if(compare_strings(wpg.GetLongName(), strByLongName, bCaseSensitive, bWildCard))
		{
				foreach(Layer lay in wpg.Layers)
				{
					if(compare_strings(lay.GetName(),strBySheetName, bCaseSensitive, bWildCard))
					{
						Worksheet wks(lay);
						foreach(Column col in wks.Columns)
						{
							if(compare_strings(col.GetName(),strByColLongName, bCaseSensitive, bWildCard))
							{
								bMatchBook = true;
								break;
							}
						}
						break;
					};
				}
			
		}
		if(bMatchBook)
			vsShortNames.Add(wpg.GetName());
	}
	return vsShortNames.GetSize();
}
static bool compare_strings(LPCSTR lpString1, LPCSTR lpString2 , bool bCaseSensitive  = false, bool bWildCase = true)
{
	
	if(bWildCase)
	{	
		string strMatch(lpString1);
		return strMatch.Match(lpString2, bCaseSensitive);
	}
	
	if(bCaseSensitive)
		return lstrcmp(lpString1, lpString2) == 0;
	else
		return lstrcmpi(lpString1, lpString2)== 0;
}
int	find_gp(vector<string>& vsShortNames,LPCSTR lpcszByLongName, BOOL bCaseSensitive,BOOL bWildCard )
{
	bool bMatchBook = false;
	
	string strByLongName = lpcszByLongName;
	
	if(strByLongName.IsEmpty())
		strByLongName = "*";

	foreach(GraphPage gp in Project.GraphPages)
	{
		bMatchBook = false;
		if(compare_strings(gp.GetLongName(), strByLongName, bCaseSensitive, bWildCard))
		{
				bMatchBook = true;
		}
		if(bMatchBook)
			vsShortNames.Add(gp.GetName());
	}
	return vsShortNames.GetSize();	
}


/// YuI 03/13/09 QA70-13281 TAGGING_AVECURVES_RESULTS_TO_EXCLUDE_THEM_FROM_FUTURE_AVERAGING
static  void _TagDataObject(DataObject & dobj, LPCSTR lpcszTag)
{
	if(dobj)
	{
		DatasetObject ds(dobj);
		if(ds)
			ds.Info.SYSTEM.PARAMETERS.TAG$ = lpcszTag;
		
	}
}

void	tag_columns_in_data_range(DataRange &rg, LPCSTR lpcszTag)
{
	if( !rg || NULL == lpcszTag )
		return;
	
	Datasheet dsRange;
	int r1, r2, c1, c2;
	r1=r2=c1=c2=0;
	int nSubRanges = rg.GetNumData();
	for(int ii = 0; ii < nSubRanges; ii ++)
	{
		if(rg.GetRange(ii, r1, c1, r2, c2, dsRange))
		{
			Worksheet wks = dsRange;
			if(wks)
			{
				for(int nCol = c1; nCol <= c2; nCol++)
				{
					Column col(wks, nCol);
					_TagDataObject(col, lpcszTag);
				}
			}
			MatrixLayer mlayer = dsRange;
			if(mlayer)
			{
				for(int nCol = c1; nCol <= c2; nCol++)
				{
					MatrixObject mobj(mlayer, nCol);
					_TagDataObject(mobj, lpcszTag);
				}
			}
			
		}
	}
}
/// end TAGGING_AVECURVES_RESULTS_TO_EXCLUDE_THEM_FROM_FUTURE_AVERAGING

///------ Folger 01/06/09 QA81-14903 FILTER_DATAPLOTS_TAGS_WITH_FITCURVES
BOOL	is_dataobj_tagged(DataObject& obj, LPCSTR lpcszTag)
{
	if ( obj )
	{
		DatasetObject ds(obj);
		if(ds)
			return lstrcmp(ds.Info.SYSTEM.PARAMETERS.TAG$, lpcszTag) == 0;
	}
	
	return FALSE;
}
///------ End FILTER_DATAPLOTS_TAGS_WITH_FITCURVES

//------- CPY 7/5/06 QA70-8798 ON_OK_EVENT_TO_ALLOW_XF_HANDLING
//int get_input_data_size(TreeNode& trInputData)	/// Max 11/25/06 RENAME_TO_GET_INPUT_XYRANGE_DATA_SIZE
int get_input_xyrange_data_size(TreeNode& trInputData)
{
	XYRange xyTemp;
	bool bOK = xy_range_from_GetN_data_node(trInputData, xyTemp);
	///------ Folger 08/02/10 ORG-672 INTEG1_SUPPORT_MULTIPLE_XYRANGES
	//if(bOK && xyTemp.IsValid())
	//{
		//vector vx, vy;
		//if(xyTemp.GetData(vy, vx,NULL, 0, 0))
			//return vy.GetSize();
	//}
	if ( bOK )
		return get_input_xyrange_data_size(xyTemp);
	///------ End INTEG1_SUPPORT_MULTIPLE_XYRANGES
	return -1;
}
//-------

///------ Folger 08/02/10 ORG-672 INTEG1_SUPPORT_MULTIPLE_XYRANGES
int get_input_xyrange_data_size(XYRange& xy)
{
	if( xy.IsValid() )
	{
		vector vx, vy;
		if(xy.GetData(vy, vx,NULL, 0, 0))
			return vy.GetSize();
	}
	return -1;
}
///------ End INTEG1_SUPPORT_MULTIPLE_XYRANGES

bool find_data_inside_tool(GraphObject& grTool, bool bUpdateTool, DataRange& dr, ButtonInfo& biMenu, int nMinPts, GraphObjInfo& ob2)// = 2, NULL)
{
	bool bFound = false;
	TreeNode trInfo = biMenu.GetUserData();
	bool bUpdateActive = trInfo.Settings.UpdateActiveData.nVal;
	DataPlot dp;
	int i1,i2;
	if(find_intersect_dataplot(grTool, dp, i1, i2, bUpdateActive))
	{
		//double x1, x2, y1, y2;
		dp.GetDataRange(dr, i1, i2);
		SetDataDisplayText(dr.GetDescription());
		if((i2-i1)+1 >= nMinPts)// && dp.GetDataPoint(i1, &x1, &y1) && dp.GetDataPoint(i2, &x2, &y2))
		{
			bFound = true;
			if(bUpdateTool)// only to move and arrange things
			{
				int nn = trInfo.Settings.RectSpan.nVal;
				if(nn > 0)
				{
					grobj_stretch_vertical(grTool, dr, nn == 1? true:false);
					arrange_buttons(biMenu, ob2);
				}
			}
		}
	}
	else
	{
		SetDataDisplayText("No data");
	}
	return bFound;
}

bool get_end_points(const DataRange& dr, double& x1, double& x2, double* py1, double* py2)//=NULL = NULL;
{
	DWORD dwPlotID;
	vector vv, vx;
	if(dr.GetData(DRR_GET_MISSING |  DRR_GET_DEPENDENT | DRR_NO_FACTORS, 0, &dwPlotID, NULL, &vv, &vx) < 0)
		return false;

	int nLast = vx.GetSize() - 1;
	if(nLast < 0)
		return false;
	
	x1 = vx[0];
	x2 = vx[nLast];
	if(py1)
		*py1 = vv[0];
	if(py2)
		*py2 = vv[nLast];
	
	return true;
}

/// YuI 01/16/06 XFUNCTION_OC_TO_VC_CONVERSION
static int	_font_size_to_page_pixels(double dSize)
{
	double	rPageXRes = 0;
	LT_get_var("page.resX", &rPageXRes);
	if (rPageXRes <= 0.)
		return 500;		// some default
	
	// This seems to be what RELATIVE_SCREEN_UNIT(lpDataFont->type.txHeight) does:
	dSize *= rPageXRes / 70.;
	
	return (int)(0.5 + dSize);
}

void arrange_buttons(ButtonInfo& bi, GraphObjInfo& bn2, GraphObjInfo& bn3 )// = NULL= NULL
{
	int nObjHeight = _font_size_to_page_pixels(bi.GetFontSize());
	int nGap = _font_size_to_page_pixels(5.0);
	// One font size offset rightward:
	bi.PageMoveTo(1, nGap, 0);
	if(bn2)
		bn2.PageMoveTo(1, nGap, 1.7*nObjHeight);
}
/// end XFUNCTION_OC_TO_VC_CONVERSION

//int get_input_range_num(TreeNode& trInputData)	/// Max 11/25/06 RENAME_TO_GET_INPUT_XYRANGE_NUM
int get_input_xyrange_num(TreeNode& trInputData)
{
	XYRange xyTemp;
	bool bOK = xy_range_from_GetN_data_node(trInputData, xyTemp);
	if(bOK && xyTemp.IsValid())
	{
		return xyTemp.GetNumData(DRR_GET_DEPENDENT);
	}
	
	return -1;
}

