var TrimQueryUtilities =
{
	inferTableDefinitions: function(inData)
	{
		var theTableName;
		var theColumnName;
		var theResult;
		var theTableDefinition;

		theResult = new Object();
		for (theTableName in inData)
		{
			theTableDefinition = new Object();
			if (inData[theTableName].length == 0)
				continue;
			for (theColumnName in inData[theTableName][0])
			{
				//if (inData[theTableName][0][theColumnName] instanceof Number)
				if (typeof(inData[theTableName][0][theColumnName]) == 'number')
					theTableDefinition[theColumnName] = { type: "Number" };
				else
					theTableDefinition[theColumnName] = { type: "String" };
			}

			theResult[theTableName] = theTableDefinition;
		}

		return (theResult);
	},


	inferFromClause: function(inData)
	{
		var theTableName;
		var theResult;

		theResult = new Array();
		for (theTableName in inData)
			theResult.push(theTableName);

		return (theResult.join(","));
	},


	getPropertiesDrivenWhereEqualsClause: function(inConstraints)
	{
		var theClause = "";
		var i,j;
		var theNames;
		var theParameters;
		var theValue;

		theParameters = new Array();
		if (inConstraints !== undefined)
		{
			theNames = inConstraints.getKeys();
			for (i = 0; i < theNames.length; i++)
			{
				theValue = inConstraints.getProperty(theNames[i]);
				if (theValue instanceof Array)
				{
					theClause = theClause + (i > 0 ? " AND (" : " (");

					for (j = 0; j < theValue.length; j++)
					{
						theClause = theClause
							+ (j > 0 ? " OR " : " ")
							+ theNames[i]
							+ " = ?";
						theParameters.push(theValue[j]);
					}

					theClause = theClause + ")";
				}
				else
				{
					theClause = theClause
						+ (i > 0 ? " AND " : " ")
						+ theNames[i]
						+ " = ?";
					theParameters.push(theValue);
				}
			}

			if (theNames.length > 0)
				theClause = "WHERE" + theClause;
		}

		return ({ clause: theClause, parameters: theParameters });
	},


	/*
	 * getFilterFunctionByWhereClauseFunction
	 *
	 * Create a function suitable for use with a Filter that executes the specified select
	 * against the specified data using the specified function to generate the WHERE clause.
	 *
	 * The where clause function should have the signature (inParameters) and return an
	 * object { clause: "...", parameters: [...] }.  The clause should be a string, even if empty;
	 * the parameters can be undefined if they are not needed.
	 */
	getFilterFunctionByWhereClauseFunction: function(inData,inSelectClause,inWhereClauseFunction)
	{
		var theTableDefinitions;
		var theQueryEngine;
		var theTableName;
		var theQuery;

		theTableDefinitions = TrimQueryUtilities.inferTableDefinitions(inData);
		theQueryEngine = TrimPath.makeQueryLang(theTableDefinitions);
		theQuery = "SELECT " + inSelectClause + " FROM " + TrimQueryUtilities.inferFromClause(inData);

		if (inWhereClauseFunction === undefined)
		{
			return (function(inParameters)
			{
				return (theQueryEngine.parseSQL(theQuery + " " + inParameters.clause,inParameters.parameters).filter(inData));
			});
		}

		return (function(inParameters)
		{
			var theClause;

			theClause = inWhereClauseFunction(inParameters);
			return (theQueryEngine.parseSQL(theQuery + " " + theClause.clause,theClause.parameters).filter(inData));
		});
	}
};
