<?php
/*
This script is called from cron/task scheduler with arguments DB name and output_id
It works independently of EnTrak and accesses DB in order to run a service
*/
require '../Common/openDB.php';
require '../Common/preferences.php';

$dbase = $argv[1];
$output_id = $argv[2];

mysql_select_db($dbase, $con);
mysql_query("SET foreign_key_checks = 0",$con);
$db_not_found = false;
$output_not_found = false;
$logfilename = "{$OutputsFolder}/error.log";
$res = mysql_query("USE {$dbase}",$con);


// DO CHECKS AND CREATE/REPORT IN LOG FILE
if (!$res){
	$db_not_found = true;
}else{
	$res = mysql_query("SELECT name FROM Output WHERE output_id = {$output_id}",$con);

	if(!$res){
		$output_not_found = true;
	}else{
		while ($row = mysql_fetch_array($res))$output_name = $row[0];
		if($output_name == NULL || $output_name == ""){
			$output_not_found = true;
		}else{
			// Generate folder structure for this service if it does not exist already
			if(!file_exists("{$OutputsFolder}/{$dbase}"))mkdir("{$OutputsFolder}/{$dbase}");
			if(!file_exists("{$OutputsFolder}/{$dbase}/{$output_name}_{$output_id}"))mkdir("{$OutputsFolder}/{$dbase}/{$output_name}_{$output_id}/");
			if($URLOutput){
				if(!file_exists("{$OutputWebFolder}/{$dbase}"))mkdir("{$OutputWebFolder}/{$dbase}");
				if(!file_exists("{$OutputWebFolder}/{$dbase}/{$output_name}_{$output_id}"))mkdir("{$OutputWebFolder}/{$dbase}/{$output_name}_{$output_id}/");
			}
			if($URLOutput2){
				if(!file_exists("{$OutputWebFolder2}/{$dbase}"))mkdir("{$OutputWebFolder2}/{$dbase}");
				if(!file_exists("{$OutputWebFolder2}/{$dbase}/{$output_name}_{$output_id}"))mkdir("{$OutputWebFolder2}/{$dbase}/{$output_name}_{$output_id}/");
			}
			if($CloudOutput){
				if(!file_exists("{$CloudLocation}/{$dbase}"))mkdir("{$CloudLocation}/{$dbase}");
				if(!file_exists("{$CloudLocation}/{$dbase}/{$output_name}_{$output_id}"))mkdir("{$CloudLocation}/{$dbase}/{$output_name}_{$output_id}/");
			}
			$logfilename =  "{$OutputsFolder}/{$dbase}/{$output_name}_{$output_id}.log";
		}
	}
}

// Get time to add to file name
date_default_timezone_set($TimeZone);
$current_time = date('D M d Y H:i:s');
$current_time_filename = date('Y-m-d')."T".date('His');
$current_mnth = date('F');
$current_year = date('Y');

// Write log file header
if(file_exists($logfilename)){
	$logfile = fopen($logfilename,"a");
}else{
	$logfile = fopen($logfilename,"w");
	if(!$db_not_found && !$output_not_found){
		fwrite($logfile,"ENTRAK Version {$Version} data output log file \n");
		fwrite($logfile,"website:       {$website}\n");
		fwrite($logfile,"userid:        {$userid}\n");
		fwrite($logfile,"database name: {$dbase}\n");
		fwrite($logfile,"service name:  {$output_name}\n");
		fwrite($logfile,"service id:    {$output_id}\n");
	}
}

// Error checks
if($db_not_found){
	fwrite($logfile,"ERROR at {$current_time}: database by the name ({$dbase}) not found, service run aborting\n");
	exit;
}
if($output_not_found){
	fwrite($logfile,"ERROR at {$current_time}: service id ({$output_id}) in database ({$dbase}) not found, service run aborting\n");
	exit;
}

// CHECKS COMPLETED GET GOVERNING PARAMETERS
// $NOUT = number of operations to be performed for this service
// $NSLOTS = number of rows expected for dynamic items

// Get $NOUT
$res = mysql_query("SELECT COUNT(name) FROM Operation WHERE output_id = {$output_id}",$con);
while($row = mysql_fetch_array($res))$NOUT = $row[0];

// Get $NSLOTS
$res = mysql_query("SELECT frequency_id,es_data_freq_id,ranupto FROM Output WHERE output_id = {$output_id}",$con);
while($row = mysql_fetch_array($res)){
	$ESFreq_id = $row[0];
	$DataFreq_id = $row[1];
	$ranupto = $row[2];
	if($ranupto == NULL || $ranupto == "0000-00-00 00:00:00")$ranupto = "none";
}
$res = mysql_query("SELECT period,times_per_period,start FROM Frequency WHERE frequency_id = {$ESFreq_id}",$con);
while($row = mysql_fetch_array($res)){
	$PD = $row[0];
	$TPP = $row[1];
	$FreqStart = $row[2];
	if($FreqStart == NULL || $FreqStart == "0000-00-00 00:00:00")$ErrorCode2 = 2;
}
$ES_time_period = GetTimePeriodFromFrequency($PD,$TPP,$current_mnth,$current_year);

$res = mysql_query("SELECT period,times_per_period FROM Frequency WHERE frequency_id = {$DataFreq_id}",$con);
while($row = mysql_fetch_array($res)){
	$PD = $row[0];
	$TPP = $row[1];
}
$data_processing_time_period = GetTimePeriodFromFrequency($PD,$TPP,$current_mnth,$current_year);
$NSLOTS = $ES_time_period / $data_processing_time_period;

// GET START AND STOP TIMESTAMPS
if($ServiceFromNow){

	// EService starts one time period in the past (as defined in associated run frequency)
	$dateinsec = strtotime($current_time) - $ES_time_period - $global_service_run_timestamp_delay;
}elseif($ranupto != "none"){

	// service previously run so start it from when it was stopped previously
	$dateinsec = strtotime($ranupto);
}elseif($ErrorCode2 != 2){

	// Start time defined in frequency table
	$dateinsec=strtotime($FreqStart);
}else{

	// EService starts at earliest time stamp of all DID whichever is later
	// e.g. for two DID one has data for 12,13,14,15,16.... the other for 15,16,17,18...
	// earliest time stamp of all DID whichever is later will be 15
	$dateinsec = get_DID_TS($output_id,$con,"earliest");
}
//$dateinsec = strtotime("2016-06-08 07:44:00");
$ESStart = date('D M d Y H:i:s',$dateinsec);
$ESStop  = date('D M d Y H:i:s',$dateinsec + $ES_time_period);

// START WRITE OF XML FILE
$xmlfilename = "{$OutputsFolder}/{$dbase}/{$output_name}_{$output_id}/{$current_time_filename}.xml";
$xmlfilename_latest = "{$OutputsFolder}/{$dbase}/{$output_name}_{$output_id}/latest_file.xml";
$xmlfilebasename = "{$current_time_filename}.xml";
$xmlfile = fopen($xmlfilename,"w");
$xml_write_success = fwrite($xmlfile,"<?xml version='1.0' encoding='UTF-8'?>\n");
fwrite($xmlfile,"<?xml-stylesheet type='text/css' href='../../style.css'?>\n");
fwrite($xmlfile,"<report name='{$output_name}'> \n");
fwrite($xmlfile,"  <period>\n");
fwrite($xmlfile,"    <start_time>{$ESStart}</start_time>\n");
fwrite($xmlfile,"    <stop_time>{$ESStop}</stop_time>\n");
fwrite($xmlfile,"    <data_processing_period>{$data_processing_time_period}</data_processing_period>\n");
fwrite($xmlfile,"    <data_processing_period_unit>second</data_processing_period_unit>\n");
fwrite($xmlfile,"    <service_period>{$ES_time_period}</service_period>\n");
fwrite($xmlfile,"    <service_period_unit>second</service_period_unit>\n");
fwrite($xmlfile,"  </period>\n");
$ESStop  = date('Y-m-d H:i:s',$dateinsec + $ES_time_period);

if(!$xml_write_success){
	fwrite($logfile,"WARNING: New xml file could not be written at {$current_time}\n");
}else{
	fwrite($logfile,"New xml file written at {$current_time}\n");
}

// WHILE LOOP FOR EVERY OUTPUT/OPERATION IN THIS SERVICE
// First define variables
fwrite($xmlfile,"  <data>\n");
$output = array();
$IOUT = 0;                 // 0          1      2          3         4          5
$res = mysql_query("SELECT operation_id,output,SelectionA,operation,SelectionB,name FROM Operation WHERE output_id = {$output_id}",$con);
unset($OutputYN);
$OutputYN = array();
array_push($OutputYN,0); // No operation for zeroth output (numbering for outputs starts from 1 and not from 0)
$prev_A_iout = array();
$prev_B_iout = array();
while($row = mysql_fetch_array($res)){
	$write_xml = false;
	$operation_id = $row[0];
	$output = $row[1];
	$SelectionA = $row[2];
	$operation = $row[3];
	$SelectionB = $row[4];
	$operation_name = $row[5];
	if($output != "no")$write_xml = true;
	$IOUT++;

	// STEP 1 Get details of operands
	// For operand A and B get number of scoped items if operand is defined from scope NSCPD will be +ve
	// for operand A or B if NSCPD is -ve it means it is a previously defined output
	// $NSCPD if +ve = number of vectors expected (either with one row for static items or $NSLOTS number of rows for dynamic items)
	// $NSCPD if -ve = number of vectors expected (i.e. when it is output from an operation)
	// For each operand get id of static and dynamic id of scoped items
	//               or get id of previous output referenced
	unset($operA_type);
	unset($operB_type);
	unset($operA_id);
	unset($operB_id);
	unset($operA_desc);
	unset($operB_desc);
	$operA_type = array(); // may be "SID", "DID" or "OUT" (previous output)
	$operB_type = array();
	$operA_id = array(); // holds id of SID, DID or OUT defined above
	$operB_id = array();
	$operA_desc = array(); // holds source name, and static or dynamic name or operation-description
	$operB_desc = array();
	array_push($OutputYN,$output); // is this operation to be output to xml YN?
	$operA_name = get_operand_name($con,$SelectionA,"name");
	$operB_name = get_operand_name($con,$SelectionB,"name");
	if($write_xml)fwrite($xmlfile,"    <operation number=\"{$IOUT}\" name=\"{$operation_name}\">\n");
	$operationW = $operation;
	if($operation == ">"){
		$operationW = "greater than";
	}elseif($operation == ">="){
		$operationW = "greater than or equal to";
	}elseif($operation == "<"){
		$operationW = "less than";
	}elseif($operation == "<="){
		$operationW = "less than or equal to";
	}
	if($operB_name != NULL){
		if($write_xml)fwrite($xmlfile,"      <operation-description>({$operA_name}) {$operationW} ({$operB_name})</operation-description>\n");
	}else{
		if($write_xml)fwrite($xmlfile,"      <operation-description>({$operA_name}) {$operationW}</operation-description>\n");
	}
	unset($Operands);
	$Operands = array($SelectionA, $SelectionB);
	$working_on_A = true;
	foreach ($Operands as $operand){
		$sel = intval($operand);

		 // this is a scoped item
		if($sel > 0){
			// Get attribute, rule and text
			$resA = mysql_query("SELECT attribute,rule,text FROM Scope WHERE scope_id = {$sel}",$con);
			while($rowA = mysql_fetch_array($resA)){
				$attribute = $rowA[0];
				$rule = $rowA[1];
				$text = $rowA[2];
			}
			$MatchedSID = array();
			$MatchedDID = array();
			$MatchedSID = getMatchedEntities($attribute,$rule,$text,$con,"SID");
			$MatchedDID = getMatchedEntities($attribute,$rule,$text,$con,"DID");
			foreach($MatchedDID as $matched_items){
				$resA = mysql_query("SELECT attribute,value,source_id FROM Dynamic WHERE dynamic_id = {$matched_items}",$con);
				while($rowA = mysql_fetch_array($resA)){
					$att = $rowA[0];
					$value = $rowA[1];
					$source_id = $rowA[2];
					$resB = mysql_query("SELECT name FROM Source WHERE source_id = {$source_id}",$con);
					while($rowB = mysql_fetch_array($resB))$source = $rowB[0];
				}
				if($working_on_A){
					array_push($operA_type,"DID");
					array_push($operA_id,$matched_items);
					array_push($operA_desc,"Entity called {$source} (ID={$source_id}) with dynamic tag {$att} (ID={$matched_items}) and value {$value}");
				}else{
					array_push($operB_type,"DID");
					array_push($operB_id,$matched_items);
					array_push($operB_desc,"Entity called {$source} (ID={$source_id}) with dynamic tag {$att} (ID={$matched_items}) and value {$value}");
				}
			}
			foreach($MatchedSID as $matched_items){
				$resA = mysql_query("SELECT attribute,value,source_id FROM Static WHERE static_id = {$matched_items}",$con);
				while($rowA = mysql_fetch_array($resA)){
					$att = $rowA[0];
					$value = $rowA[1];
					$source_id = $rowA[2];
					$resB = mysql_query("SELECT name FROM Source WHERE source_id = {$source_id}",$con);
					while($rowB = mysql_fetch_array($resB))$source = $rowB[0];
				}
				if($working_on_A){
					array_push($operA_type,"SID");
					array_push($operA_id,$matched_items);
					array_push($operA_desc,"Entity called {$source} (ID={$source_id}) with static tag {$att} (ID={$matched_items}) and value {$value}");
				}else{
					array_push($operB_type,"SID");
					array_push($operB_id,$matched_items);
					array_push($operB_desc,"Entity called {$source} (ID={$source_id}) with static tag {$att} (ID={$matched_items}) and value {$value}");
				}
			}
		}elseif($sel < 0){
				$id = -1 * $sel;
				$resA = mysql_query("SELECT name FROM Operation WHERE operation_id = {$id}",$con);

				while($rowA = mysql_fetch_array($resA))$name = $rowA[0];

				// If pervious operation then get its iout
				$i = 1;
				$prev_iout_found = false;
				$resA = mysql_query("SELECT name FROM Operation WHERE output_id = {$output_id}",$con);
				while($rowA = mysql_fetch_array($resA)){
					$prev_name = $rowA[0];
					if($i < $IOUT){
						if($name == $prev_name){
							$prev_iout = $i;
							$prev_iout_found = true;
						}
					}
					$i++;
					if($prev_iout_found){
						if($working_on_A){
							$prev_A_iout[$IOUT] = $prev_iout;
						}else{
							$prev_B_iout[$IOUT] = $prev_iout;
						}
					}
					if($prev_iout_found)break;
				}

				if($working_on_A){
					array_push($operA_type,"OUT");
					array_push($operA_id,$id);
					array_push($operA_desc,"Output operation called {$name}");
				}else{
					array_push($operB_type,"OUT");
					array_push($operB_id,$id);
					array_push($operB_desc,"Output operation called {$name}");
				}
		}else{
			// ERROR
		}

		// switch operands A to B or B to A
		if($working_on_A){
			$working_on_A = false;
		}else{
			$working_on_A = true;
		}
	}

	// STEP 2 Read in values, a is the number of dynamic and/or static attributes that have been scoped on
	for($a = 0; $a < count($operA_type); $a++){

		// operation is erroneous
		if(only_one_operand_needed($operation) == -1){
			echo "only_one_operand_needed returned with value " . only_one_operand_needed($operation) . "<<<<";

		// operand requires only one operand
		}elseif(only_one_operand_needed($operation) == 1){
			$aplus1 = $a + 1;
			if($write_xml)fwrite($xmlfile,"      <sub-operation number=\"{$aplus1}\">\n");
			if($write_xml)fwrite($xmlfile,"        <sub-operation-description1>({$operA_desc[$a]}) {$operationW}</sub-operation-description1>\n");
			compute_operation($operA_type[$a],$operA_id[$a],$operation,"ONE",NULL,$ESStart,$ESStop,$NSLOTS,$con,$xmlfile,$OutputYN[$IOUT],$IOUT,$prev_A_iout[$IOUT],$prev_B_iout[$IOUT]);
			if($write_xml)fwrite($xmlfile,"      </sub-operation>\n");

		// operand requires two operands
		}elseif(only_one_operand_needed($operation) == 0){
			if(count($operB_type) > 0){
				for($b = 0; $b < count($operB_type); $b++){
					$bplus1 = $b + 1;
					if($write_xml)fwrite($xmlfile,"      <sub-operation number=\"{$bplus1}\">\n");
					if($write_xml)fwrite($xmlfile,"        <sub-operation-description1>({$operA_desc[$a]}) {$operationW} ({$operB_desc[$b]})</sub-operation-description1>\n");
					compute_operation($operA_type[$a],$operA_id[$a],$operation,$operB_type[$b],$operB_id[$b],$ESStart,$ESStop,$NSLOTS,$con,$xmlfile,$OutputYN[$IOUT],$IOUT,$prev_A_iout[$IOUT],$prev_B_iout[$IOUT]);
					if($write_xml)fwrite($xmlfile,"      </sub-operation>\n");
				}
			}else{
				if($write_xml)fwrite($xmlfile,"        <sub-operation-description1>{$operationW} ({$operA_desc[$a]}) -- Second operand not defined</sub-operation-description1>\n");
				if($write_xml)fwrite($xmlfile,"      </sub-operation>\n");
			}

		// some other error has occured, write this out even if output to xml is turned off
		}else{
			if(!$write_xml)fwrite($xmlfile,"      <sub-operation number=\"{$aplus1}\">\n");
			fwrite($xmlfile,"        <sub-operation-description1>Unknown error has occured</sub-operation-description1>\n");
			if(!$write_xml)fwrite($xmlfile,"      </sub-operation>\n");

		}
	}
	if($write_xml)fwrite($xmlfile,"    </operation>\n");

} // end While loop for each operation (output)

// PERFORM RUN END ACTIONS
$ranupto = $ESStop;
mysql_query("UPDATE Output SET ranupto='{$ranupto}' WHERE output_id={$output_id}",$con);
fwrite($xmlfile,"  </data>\n");
fwrite($xmlfile,"</report>\n");
fclose($xmlfile);
fclose($logfile);
copy($xmlfilename,$xmlfilename_latest);
if($URLOutput){
	//copy($xmlfilename,"{$OutputWebFolder}/{$dbase}/{$output_name}_{$output_id}/{$xmlfilebasename}");
	copy($xmlfilename,"{$OutputWebFolder}/{$dbase}/{$output_name}_{$output_id}/latest_file.xml");
}

if($URLOutput2){
	//copy($xmlfilename,"{$OutputWebFolder2}/{$dbase}/{$output_name}_{$output_id}/{$xmlfilebasename}");
  copy($xmlfilename,"{$OutputWebFolder2}/{$dbase}/{$output_name}_{$output_id}/latest_file.xml");
}

if($CloudOutput){
	copy($xmlfilename,"{$CloudLocation}/{$dbase}/{$output_name}_{$output_id}/{$xmlfilebasename}");
  copy($xmlfilename,"{$CloudLocation}/{$dbase}/{$output_name}_{$output_id}/latest_file.xml");
}
exit;

// This function computes the actual values as required by a service.
// Possible types of operand A being SID, DID and OUT
// Operatnd B may be SID, DID, OUT or ONE (i.e. just one operand is required and B is redundant)
// For operations in which just one operand is required are computed within this function
// with operations requiring two operands being passed on to compute_two_operands
// All calls to compute_two_operands are made from this function only.
function compute_operation($A,$AID,$oper,$B,$BID,$ESStart,$ESStop,$NSLOTS,$con,$xmlfile,$outYN,$ioper,$Aprev,$Bprev){
	global $oper_value; // result of operation on one/two operands
	global $oper_desc; // description of operation (operA oper operB)
	global $oper_type; // description of the type of element in array v or s
	$write_xml = false;
	if($outYN != "no")$write_xml = true;
	unset($timestamps);
	$timestamps = array();
	$timestamps = get_slotted_var(NULL,$ESStart,$ESStop,$NSLOTS,NULL,"time");

	// The symbols < and > confuse xml so remove these
	if($oper == ">"){
		$oper = "greater than";
	}elseif($oper == ">="){
		$oper = "greater than or equal to";
	}elseif($oper == "<"){
		$oper = "less than";
	}elseif($oper == "<="){
		$oper = "less than or equal to";
	}

	if($A == "SID"){
		// get operand A values
		$res = mysql_query("SELECT value,attribute FROM Static WHERE static_id = {$AID}",$con);
		while($row = mysql_fetch_array($res)){$A_val = $row[0];$A_name = $row[1];}

		// get operand B values
		if($B == "SID"){
			$res = mysql_query("SELECT value,attribute FROM Static WHERE static_id = {$BID}",$con);
			while($row = mysql_fetch_array($res)){$B_val = $row[0];$B_name = $row[1];}

			// workout operation
			$result = compute_two_operands($A_val,$oper,$B_val);
			$datatype = get_res_datatype($oper);
			if($write_xml)fwrite($xmlfile,"      <reading>\n");
			if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
			if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
			if($write_xml)fwrite($xmlfile,"      </reading>\n");

			//bookkeep_SID_SID:
			$oper_value[$ioper][] = $result;
			$oper_desc[$ioper][] = "({$A_name}) {$oper} ({$B_name})";
			$oper_type[$ioper] .= "s";

		}elseif($B == "DID"){
			$res = mysql_query("SELECT attribute FROM Dynamic WHERE dynamic_id = {$BID}",$con);
			while($row = mysql_fetch_array($res))$B_name = $row[0];
			unset($B_val);
			$B_val = array();
			$B_val = get_slotted_var($BID,$ESStart,$ESStop,$NSLOTS,$con,"value");
			for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
				$result = compute_two_operands($A_val,$oper,$B_val[$ISLOT]);
				$datatype = get_res_datatype($oper);
				if($write_xml)fwrite($xmlfile,"      <reading>\n");
				if($write_xml)fwrite($xmlfile,"        <timestamp>{$timestamps[$ISLOT]}</timestamp>\n");
				if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
				if($write_xml)fwrite($xmlfile,"      </reading>\n");

				//bookkeep_SID_DID:
				$oper_value[$ioper][] = $result;
				$oper_desc[$ioper][] = "({$A_name}) {$oper} ({$B_name})";
			}
			$oper_type[$ioper] .= "v";
		}elseif($B == "OUT"){

			$oper_type[$ioper] = $oper_type[$Bprev];

			// write to xml
			$string = get_str_as_array($oper_type[$ioper]);
			$j = 0;
			for ($i=0; $i<count($string); $i++){
				$MasterSlot = 0;
				if($string[$i] == "v"){
					if($write_xml)fwrite($xmlfile,"        <sub-operation-description2>({$A_name}) {$oper} ({$oper_desc[$Bprev][$j]})</sub-operation-description2>\n");

					for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
						$result = compute_two_operands($A_val,$oper,$oper_value[$Bprev][$j]);
						$datatype = get_res_datatype($oper);

						//bookkeep_SID_OUT:
						$oper_value[$ioper][] = $result;
						$oper_desc[$ioper][] = "({$A_name}) {$oper} ({$oper_desc[$Bprev][$j]})";
						if($write_xml)fwrite($xmlfile,"        <reading>\n");
						if($write_xml)fwrite($xmlfile,"          <timestamp>{$timestamps[$ISLOT]}</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"          <value datatype='{$datatype}'>{$oper_value[$ioper][$j]}</value>\n");
						if($write_xml)fwrite($xmlfile,"        </reading>\n");
						$j++;
					}
				}elseif($string[$i] == "s"){
					if($write_xml)fwrite($xmlfile,"        <sub-operation-description2>{$oper_desc[$ioper][$j]}</sub-operation-description2>\n");
					if($write_xml)fwrite($xmlfile,"        <reading>\n");
					if($write_xml)fwrite($xmlfile,"          <timestamp>NA</timestamp>\n");
					if($write_xml)fwrite($xmlfile,"          <value datatype='{$datatype}'>{$oper_value[$ioper][$j]}</value>\n");
					if($write_xml)fwrite($xmlfile,"        </reading>\n");
					$j++;
				}else{
					if($write_xml)fwrite($xmlfile,"        <sub-operation-description2>{$oper_desc[$ioper][$j]}</sub-operation-description2>\n");
					if($write_xml)fwrite($xmlfile,"        <reading>\n");
					if($write_xml)fwrite($xmlfile,"          <timestamp>NA</timestamp>\n");
					if($write_xml)fwrite($xmlfile,"          <value datatype='{$datatype}'>Value cannot be computed for unknown reason</value>\n");
					if($write_xml)fwrite($xmlfile,"        </reading>\n");
					$j++;
				}
			}

		}elseif($B == "ONE"){
			if($oper == "List" || $oper == "List (raw)"){
				$result = $A_val;
			}elseif($oper == "Count" || $oper == "Count (raw)"){
				$result = "1";
			}elseif($oper == "Integrate"){
				$result = "Bad calculation: no time step defined";
			}elseif($oper == "Sum"){
				$result = $A_val;
			}elseif($oper == "Mean"){
				$result = $A_val;
			}elseif($oper == "Maximum"){
				$result = $A_val;
			}elseif($oper == "Minimum"){
				$result = $A_val;
			}elseif($oper == "Median"){
				$result = $A_val;
			}elseif($oper == "Mode"){
				$result = $A_val;
			}elseif($oper == "NOT"){
				if($A_val == 1 || $A_val == "1"){
					$result = "0";
				}elseif($A_val == 0 || $A_val == "0"){
					$result = "1";
				}else{
					$result = "Error: 1 or 0 expected as input";
				}
			}elseif($oper == "Standard deviation"){
				$result = "Bad calculation: standard deviation is not defined for one value";
			}elseif($oper == "5th percentile"){
				$result = "Bad calculation: percentile is not defined for one value";
			}elseif($oper == "10th percentile"){
				$result = "Bad calculation: percentile is not defined for one value";
			}elseif($oper == "25th percentile"){
				$result = "Bad calculation: percentile is not defined for one value";
			}elseif($oper == "75th percentile"){
				$result = "Bad calculation: percentile is not defined for one value";
			}elseif($oper == "90th percentile"){
				$result = "Bad calculation: percentile is not defined for one value";
			}elseif($oper == "95th percentile"){
				$result = "Bad calculation: percentile is not defined for one value";
			}else{
				$result = "ERROR: Bad operation in ServiceCron.php in function compute_operation";
			}
			if($write_xml)fwrite($xmlfile,"      <reading>\n");
			if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
			if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
			if($write_xml)fwrite($xmlfile,"      </reading>\n");

			//bookkeep_SID_ONE:
			$oper_value[$ioper][] = $result;
			$oper_desc[$ioper][] = "({$A_name}) {$oper}";
			$oper_type[$ioper] .= "s";

		}else{
			echo "ERROR: Bad operand B type in ServiceCron.php in function compute_operation";
		}
	}elseif($A == "DID"){
		$res = mysql_query("SELECT attribute FROM Dynamic WHERE dynamic_id = {$AID}",$con);
		while($row = mysql_fetch_array($res))$A_name = $row[0];

		unset($A_val);
		$A_val = array();
		$A_val = get_slotted_var($AID,$ESStart,$ESStop,$NSLOTS,$con,"value");

		if($B == "SID"){
			$res = mysql_query("SELECT value,attribute FROM Static WHERE static_id = {$BID}",$con);
			while($row = mysql_fetch_array($res)){$B_val = $row[0]; $B_name = $row[1];}

			for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
				$result = compute_two_operands($A_val[$ISLOT],$oper,$B_val);
				$datatype = get_res_datatype($oper);
				if($write_xml)fwrite($xmlfile,"      <reading>\n");
				if($write_xml)fwrite($xmlfile,"        <timestamp>{$timestamps[$ISLOT]}</timestamp>\n");
				if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
				if($write_xml)fwrite($xmlfile,"      </reading>\n");

				//bookkeep_DID_SID:
				$oper_value[$ioper][] = $result;
				$oper_desc[$ioper][] = "({$A_name}) {$oper} ({$B_name})";
			}
			$oper_type[$ioper] .= "v";

		}elseif($B == "DID"){
			$res = mysql_query("SELECT attribute FROM Dynamic WHERE dynamic_id = {$BID}",$con);
			while($row = mysql_fetch_array($res))$B_name = $row[0];
			unset($B_val);
			$B_val = array();
			$B_val = get_slotted_var($BID,$ESStart,$ESStop,$NSLOTS,$con,"value");
			for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
				$result = compute_two_operands($A_val[$ISLOT],$oper,$B_val[$ISLOT]);
				$datatype = get_res_datatype($oper);
				if($write_xml)fwrite($xmlfile,"      <reading>\n");
				if($write_xml)fwrite($xmlfile,"        <timestamp>{$timestamps[$ISLOT]}</timestamp>\n");
				if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
				if($write_xml)fwrite($xmlfile,"      </reading>\n");

				//bookkeep_DID_DID:
				$oper_value[$ioper][] = $result;
				$oper_desc[$ioper][] = "({$A_name}) {$oper} ({$B_name})";
			}
			$oper_type[$ioper] .= "v";
		}elseif($B == "OUT"){

			$oper_type[$ioper] = $oper_type[$Bprev];
			$string = get_str_as_array($oper_type[$ioper]);
			$j = 0;
			for ($i=0; $i<count($string); $i++){
				if($write_xml)fwrite($xmlfile,"        <sub-operation-description2>({$A_name}) {$oper} ({$oper_desc[$Bprev][$j]})</sub-operation-description2>\n");
				if($string[$i] == "v"){
					for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
						$result = compute_two_operands($A_val[$ISLOT],$oper,$oper_value[$Bprev][$j]);
						$datatype = get_res_datatype($oper);
						$oper_value[$ioper][] = $result;
						$oper_desc[$ioper][] = "({$A_name}) {$oper} ({$oper_desc[$Bprev][$j]})";
						if($write_xml)fwrite($xmlfile,"      <reading>\n");
						if($write_xml)fwrite($xmlfile,"        <timestamp>{$timestamps[$ISLOT]}</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
						if($write_xml)fwrite($xmlfile,"      </reading>\n");
						$j++;
					}
				}elseif($string[$i] == "s"){
					// allow calculation if this is not a compound output (mixture of v and s or more than one s)
					if(count($string) == 1){
						$oper_type[$ioper] = "v"; // change oper type as this is a special case
						for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
							$result = compute_two_operands($A_val[$ISLOT],$oper,$oper_value[$Bprev][$j]);
							$datatype = get_res_datatype($oper);
							$oper_value[$ioper][] = $result;
							$oper_desc[$ioper][] = "({$A_name}) {$oper} ({$oper_desc[$Bprev][$j]})";
							if($write_xml)fwrite($xmlfile,"      <reading>\n");
							if($write_xml)fwrite($xmlfile,"        <timestamp>{$timestamps[$ISLOT]}</timestamp>\n");
							if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
							if($write_xml)fwrite($xmlfile,"      </reading>\n");
						}
						$j++;
					}else{
						$result = "Error: array size mismatch";
						$oper_value[$ioper][] = $result;
						$oper_desc[$ioper][] = "({$A_name}) {$oper} ({$oper_desc[$Bprev][$j]})";
						if($write_xml)fwrite($xmlfile,"      <reading>\n");
						if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
						if($write_xml)fwrite($xmlfile,"      </reading>\n");
						$j++;
					}
				}else{
					// Error handling: Still to do
				}
			}

			// compute result
			for($i = 0; $i < count($oper_value[$Bprev]); $i++){
				$result = compute_two_operands($A_val,$oper,$oper_value[$Bprev][$i]);
				$datatype = get_res_datatype($oper);

				//bookkeep_SID_OUT:
				$oper_value[$ioper][] = $result;
				$oper_desc[$ioper][] = "({$A_name}) {$oper} ({$oper_desc[$Bprev][$i]})";
			}

			// write to xml
			$string = get_str_as_array($oper_type[$ioper]);
			$j = 0;
			for ($i=0; $i<count($string); $i++){
				if($string[$i] == "v"){
					if($write_xml)fwrite($xmlfile,"        <sub-operation-description2>{$oper_desc[$ioper][$j]}</sub-operation-description2>\n");
					for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
						if($write_xml)fwrite($xmlfile,"        <reading>\n");
						if($write_xml)fwrite($xmlfile,"          <timestamp>{$timestamps[$ISLOT]}</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"          <value datatype='{$datatype}'>{$oper_value[$ioper][$j]}</value>\n");
						if($write_xml)fwrite($xmlfile,"        </reading>\n");
						$j++;
					}
				}elseif($string[$i] == "s"){
					if($write_xml)fwrite($xmlfile,"        <sub-operation-description2>{$oper_desc[$ioper][$j]}</sub-operation-description2>\n");
					if($write_xml)fwrite($xmlfile,"        <reading>\n");
					if($write_xml)fwrite($xmlfile,"          <timestamp>NA</timestamp>\n");
					if($write_xml)fwrite($xmlfile,"          <value datatype='{$datatype}'>{$oper_value[$ioper][$j]}</value>\n");
					if($write_xml)fwrite($xmlfile,"        </reading>\n");
					$j++;
				}else{
					if($write_xml)fwrite($xmlfile,"        <sub-operation-description2>{$oper_desc[$ioper][$j]}</sub-operation-description2>\n");
					if($write_xml)fwrite($xmlfile,"        <reading>\n");
					if($write_xml)fwrite($xmlfile,"          <timestamp>NA</timestamp>\n");
					if($write_xml)fwrite($xmlfile,"          <value datatype='{$datatype}'>Value cannot be computed for unknown reason</value>\n");
					if($write_xml)fwrite($xmlfile,"        </reading>\n");
					$j++;
				}
			}

		}elseif($B == "ONE"){
			if($oper == "List"){
				for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
					if($write_xml)fwrite($xmlfile,"      <reading>\n");
					if($write_xml)fwrite($xmlfile,"        <timestamp>{$timestamps[$ISLOT]}</timestamp>\n");
					$result = $A_val[$ISLOT];
					if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
					if($write_xml)fwrite($xmlfile,"      </reading>\n");

					//bookkeep_DID_ONE:
					$oper_value[$ioper][] = $result;
					$oper_desc[$ioper][] = "({$A_name}) {$oper}";
				}
				$oper_type[$ioper] .= "v";
			}elseif($oper == "Count"){
				$tmp_str = count($A_val);
				if($write_xml)fwrite($xmlfile,"      <reading>\n");
				if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
				$result = $tmp_str;
				if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
				if($write_xml)fwrite($xmlfile,"      </reading>\n");

				//bookkeep_DID_ONE:
				$oper_value[$ioper][] = $result;
				$oper_desc[$ioper][] = "({$A_name}) {$oper}";
				$oper_type[$ioper] .= "s";
			}elseif($oper == "List (raw)" || $oper == "Count (raw)"){
				if($write_xml){
					$count_raw = get_slotted_var($AID,$ESStart,$ESStop,$NSLOTS,$con,"raw_value");

					unset($A_val_raw);
					$A_val_raw = array();
					$A_val_raw = get_slotted_var($AID,$ESStart,$ESStop,$NSLOTS,$con,"raw_value");

					unset($A_val_raw_time);
					$A_val_raw_time = array();
					$A_val_raw_time = get_slotted_var($AID,$ESStart,$ESStop,$NSLOTS,$con,"raw_time");

					if($oper == "Count (raw)"){
						fwrite($xmlfile,"      <reading>\n");
						fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
						fwrite($xmlfile,"        <value datatype='{$datatype}'>{$count_raw}</value>\n");
						fwrite($xmlfile,"      </reading>\n");

					}else{
						for($ii = 0; $ii < $count_raw; $ii++){
							fwrite($xmlfile,"      <reading>\n");
							fwrite($xmlfile,"        <timestamp>{$A_val_raw_time[$ii]}</timestamp>\n");
							fwrite($xmlfile,"        <value datatype='{$datatype}'>{$A_val_raw[$ii]}</value>\n");
							fwrite($xmlfile,"      </reading>\n");
						}
					}
				}

				//bookkeep_DID_ONE:
				for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
					$oper_value[$ioper][] = "Cannot do operations on raw data";
					$oper_desc[$ioper][] = "({$A_name}) {$oper}";
				}
				$oper_type[$ioper] .= "?";
			}elseif($oper == "Integrate" || $oper == "Sum" || $oper == "Mean"|| $oper == "Maximum"|| $oper == "Minimum"){
				$period = get_slotted_var($AID,$ESStart,$ESStop,$NSLOTS,$con,"period");
				$period = floatval($period);
				$ii = 0;
				for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
					$ii = floatval($A_val[$ISLOT]);
					$runt += $ii; // running total
				}
				$tmp_str = $period * $runt;
				$mean = $runt / $NSLOTS;
				if($oper == "Sum"){
					$result = $runt;
				}elseif($oper == "Integrate"){
					$result = $tmp_str;
				}elseif($oper == "Mean"){
					$result = $mean;
				}elseif($oper == "Maximum"){
					$result = max($A_val);
			  }elseif($oper == "Minimum"){
					$result = min($A_val);
				}
				if($write_xml)fwrite($xmlfile,"      <reading>\n");
				if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
				if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
				if($write_xml)fwrite($xmlfile,"      </reading>\n");

				//bookkeep_DID_ONE:
				$oper_value[$ioper][] = $result;
				$oper_desc[$ioper][] = "({$A_name}) {$oper}";
				$oper_type[$ioper] .= "s";

			}elseif($oper == "NOT"){
				for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
					if($A_val[$ISLOT] == 1 || $A_val[$ISLOT] == "1"){
						$result = "0";
					}elseif($A_val[$ISLOT] == 0 || $A_val[$ISLOT] == "0"){
						$result = "1";
					}else{
						$result = "      Error: 1 or 0 expected as input";
					}
					if($write_xml)fwrite($xmlfile,"      <reading>\n");
					if($write_xml)fwrite($xmlfile,"        <timestamp>{$timestamps[$ISLOT]}</timestamp>\n");
					if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
					if($write_xml)fwrite($xmlfile,"      </reading>\n");

					//bookkeep_DID_ONE:
					$oper_value[$ioper][] = $result;
					$oper_desc[$ioper][] = "({$A_name}) {$oper}";
				}
				$oper_type[$ioper] .= "v";
			}elseif($oper == "Median"){
				$result = mypercentile($A_val,50);
				if($write_xml)fwrite($xmlfile,"      <reading>\n");
				if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
				if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
				if($write_xml)fwrite($xmlfile,"      </reading>\n");
				$oper_type[$ioper] .= "s";

				//bookkeep_DID_ONE:
				$oper_value[$ioper][] = $result;
				$oper_desc[$ioper][] = "({$A_name}) {$oper}";

			}elseif($oper == "Mode"){
				$mode_val = array_mode($A_val);
				if($mode_val[0] == false){
					if($write_xml)fwrite($xmlfile,"      <reading>\n");
					if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
					if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>No mode found</value>\n");
					if($write_xml)fwrite($xmlfile,"      </reading>\n");

					//bookkeep_DID_ONE:
					$oper_value[$ioper][] = "No mode found";
					$oper_desc[$ioper][] = "({$A_name}) {$oper}";
				}else{
					for($i = 0; $i < count($mode_val); $i++){
						if($write_xml)fwrite($xmlfile,"      <reading>\n");
						if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$mode_val[$i]}</value>\n");
						if($write_xml)fwrite($xmlfile,"      </reading>\n");

						//bookkeep_DID_ONE:
						$oper_value[$ioper][] = $mode_val[$i];
						$oper_desc[$ioper][] = "({$A_name}) {$oper}";
					}
				}
				$oper_type[$ioper] .= "?";
			}elseif($oper == "Standard deviation"){
				$result = standard_deviation_population($A_val);
				if($write_xml)fwrite($xmlfile,"      <reading>\n");
				if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
				if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
				if($write_xml)fwrite($xmlfile,"      </reading>\n");

				//bookkeep_DID_ONE:
				$oper_value[$ioper][] = $result;
				$oper_desc[$ioper][] = "({$A_name}) {$oper}";
				$oper_type[$ioper] .= "s";
			}elseif($oper == "5th percentile"){
				$tmp_str = mypercentile($A_val,5);
				if($write_xml)fwrite($xmlfile,"      <reading>\n");
				if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
				if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$tmp_str}</value>\n");
				if($write_xml)fwrite($xmlfile,"      </reading>\n");

				//bookkeep_DID_ONE:
				$oper_value[$ioper][] = $tmp_str;
				$oper_desc[$ioper][] = "({$A_name}) {$oper}";
				$oper_type[$ioper] .= "s";
			}elseif($oper == "10th percentile"){
				$tmp_str = mypercentile($A_val,10);
				if($write_xml)fwrite($xmlfile,"      <reading>\n");
				if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
				if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$tmp_str}</value>\n");
				if($write_xml)fwrite($xmlfile,"      </reading>\n");

				//bookkeep_DID_ONE:
				$oper_value[$ioper][] = $tmp_str;
				$oper_desc[$ioper][] = "({$A_name}) {$oper}";
				$oper_type[$ioper] .= "s";
			}elseif($oper == "25th percentile"){
				$tmp_str = mypercentile($A_val,25);
				if($write_xml)fwrite($xmlfile,"      <reading>\n");
				if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
				if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$tmp_str}</value>\n");
				if($write_xml)fwrite($xmlfile,"      </reading>\n");

				//bookkeep_DID_ONE:
				$oper_value[$ioper][] = $tmp_str;
				$oper_desc[$ioper][] = "({$A_name}) {$oper}";
				$oper_type[$ioper] .= "s";
			}elseif($oper == "75th percentile"){
				$tmp_str = mypercentile($A_val,75);
				if($write_xml)fwrite($xmlfile,"      <reading>\n");
				if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
				if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$tmp_str}</value>\n");
				if($write_xml)fwrite($xmlfile,"      </reading>\n");

				//bookkeep_DID_ONE:
				$oper_value[$ioper][] = $tmp_str;
				$oper_desc[$ioper][] = "({$A_name}) {$oper}";
				$oper_type[$ioper] .= "s";
			}elseif($oper == "90th percentile"){
				$tmp_str = mypercentile($A_val,90);
				if($write_xml)fwrite($xmlfile,"      <reading>\n");
				if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
				if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$tmp_str}</value>\n");
				if($write_xml)fwrite($xmlfile,"      </reading>\n");

				//bookkeep_DID_ONE:
				$oper_value[$ioper][] = $tmp_str;
				$oper_desc[$ioper][] = "({$A_name}) {$oper}";
				$oper_type[$ioper] .= "s";
			}elseif($oper == "95th percentile"){
				$tmp_str = mypercentile($A_val,95);
				if($write_xml)fwrite($xmlfile,"      <reading>\n");
				if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
				if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$tmp_str}</value>\n");
				if($write_xml)fwrite($xmlfile,"      </reading>\n");

				//bookkeep_DID_ONE:
				$oper_value[$ioper][] = $tmp_str;
				$oper_desc[$ioper][] = "({$A_name}) {$oper}";
				$oper_type[$ioper] .= "s";
			}else{
				echo "ERROR: Bad operation in ServiceCron.php in function compute_operation";
			}
		}else{
			echo "ERROR: Bad operand B type in ServiceCron.php in function compute_operation";
		}

	}elseif($A == "OUT"){

		$oper_type[$ioper] = $oper_type[$Aprev]; // order of this array is almost never changed, exceptions overwrite this variable assignment
		if($B == "SID"){
			$res = mysql_query("SELECT value,attribute FROM Static WHERE static_id = {$BID}",$con);
			while($row = mysql_fetch_array($res)){$B_val = $row[0]; $B_name = $row[1];}

			$string = get_str_as_array($oper_type[$ioper]);
			$j = 0;
			for ($i=0; $i<count($string); $i++){
				if($write_xml)fwrite($xmlfile,"        <sub-operation-description2>({$oper_desc[$Aprev][$j]}) {$oper} ({$B_name})</sub-operation-description2>\n");
				if($string[$i] == "v"){
					for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
						$result = compute_two_operands($oper_value[$Aprev][$j],$oper,$B_val);
						$datatype = get_res_datatype($oper);
						$oper_value[$ioper][] = $result;
						$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper} ({$B_name})";
						if($write_xml)fwrite($xmlfile,"      <reading>\n");
						if($write_xml)fwrite($xmlfile,"        <timestamp>{$timestamps[$ISLOT]}</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
						if($write_xml)fwrite($xmlfile,"      </reading>\n");
						$j++;
					}
				}elseif($string[$i] == "s"){
					$result = compute_two_operands($oper_value[$Aprev][$j],$oper,$B_val);
					$datatype = get_res_datatype($oper);
					$oper_value[$ioper][] = $result;
					$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper} ({$B_name})";
					if($write_xml)fwrite($xmlfile,"      <reading>\n");
					if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
					if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
					if($write_xml)fwrite($xmlfile,"      </reading>\n");
					$j++;
				}else{
					// Error handling: Still to do
				}
			}

		}elseif($B == "DID"){
			$res = mysql_query("SELECT attribute FROM Dynamic WHERE dynamic_id = {$BID}",$con);
			while($row = mysql_fetch_array($res))$B_name = $row[0];
			unset($B_val);
			$B_val = array();
			$B_val = get_slotted_var($BID,$ESStart,$ESStop,$NSLOTS,$con,"value");

			$string = get_str_as_array($oper_type[$ioper]);
			$j = 0;
			for ($i=0; $i<count($string); $i++){
				if($write_xml)fwrite($xmlfile,"        <sub-operation-description2>({$oper_desc[$Aprev][$j]}) {$oper} ({$B_name})</sub-operation-description2>\n");
				if($string[$i] == "v"){
					for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
						$result = compute_two_operands($oper_value[$Aprev][$j],$oper,$B_val[$ISLOT]);
						$datatype = get_res_datatype($oper);
						$oper_value[$ioper][] = $result;
						$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper} ({$B_name})";
						if($write_xml)fwrite($xmlfile,"      <reading>\n");
						if($write_xml)fwrite($xmlfile,"        <timestamp>{$timestamps[$ISLOT]}</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
						if($write_xml)fwrite($xmlfile,"      </reading>\n");
						$j++;
					}
				}elseif($string[$i] == "s"){
					// allow calculation if this is not a compound output (mixture of v and s or more than one s)
					if(count($string) == 1){
						$oper_type[$ioper] = "v";
						for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
							$result = compute_two_operands($oper_value[$Aprev][$j],$oper,$A_val[$ISLOT]);
							$datatype = get_res_datatype($oper);
							$oper_value[$ioper][] = $result;
							$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper} ({$B_name})";
							if($write_xml)fwrite($xmlfile,"      <reading>\n");
							if($write_xml)fwrite($xmlfile,"        <timestamp>{$timestamps[$ISLOT]}</timestamp>\n");
							if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
							if($write_xml)fwrite($xmlfile,"      </reading>\n");
						}
						$j++;
					}else{
						$result = "Error: array size mismatch";
						$oper_value[$ioper][] = $result;
						$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper} ({$B_name})";
						if($write_xml)fwrite($xmlfile,"      <reading>\n");
						if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
						if($write_xml)fwrite($xmlfile,"      </reading>\n");
						$j++;
					}
				}else{
					// Error handling: Still to do
				}
			}
		}elseif($B == "OUT"){
			// This is only possible if A and B have the same rank
			if($write_xml)fwrite($xmlfile,"        <sub-operation-description2>({$oper_desc[$Aprev][0]}) {$oper} ({$oper_desc[$Bprev][0]})</sub-operation-description2>\n");
			if($oper_type[$Aprev] != $oper_type[$Bprev]){

				$result = "Error: array size mismatch";
				if($write_xml)fwrite($xmlfile,"      <reading>\n");
				if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
				if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
				if($write_xml)fwrite($xmlfile,"      </reading>\n");

			}else{
				$string = get_str_as_array($oper_type[$ioper]);
				$j = 0;
				for ($i=0; $i<count($string); $i++){
					if($write_xml)fwrite($xmlfile,"        <sub-operation-description2>({$oper_desc[$Aprev][$j]}) {$oper} ({$oper_desc[$Bprev][$j]})</sub-operation-description2>\n");
					if($string[$i] == "v"){
						for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
							$result = compute_two_operands($oper_value[$Aprev][$j],$oper,$oper_value[$Bprev][$j]);
							$datatype = get_res_datatype($oper);
							$oper_value[$ioper][] = $result;
							$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper} ({$oper_desc[$Bprev][$j]})";
							if($write_xml)fwrite($xmlfile,"      <reading>\n");
							if($write_xml)fwrite($xmlfile,"        <timestamp>{$timestamps[$ISLOT]}</timestamp>\n");
							if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
							if($write_xml)fwrite($xmlfile,"      </reading>\n");
							$j++;
						}
					}elseif($string[$i] == "s"){
						$result = compute_two_operands($oper_value[$Aprev][$j],$oper,$oper_value[$Bprev][$j]);
						$datatype = get_res_datatype($oper);
						$oper_value[$ioper][] = $result;
						$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper} ({$oper_desc[$Bprev][$j]})";
						if($write_xml)fwrite($xmlfile,"      <reading>\n");
						if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
						if($write_xml)fwrite($xmlfile,"      </reading>\n");
						$j++;
					}else{
						// Error handling: Still to do
					}
				}
			}
		}elseif($B == "ONE"){
			if($oper == "List"){
				$oper_type[$ioper] = $oper_type[$Aprev];
				$string = get_str_as_array($oper_type[$ioper]);
				$j = 0;
				for ($i=0; $i<count($string); $i++){
					if($write_xml)fwrite($xmlfile,"        <sub-operation-description2>({$oper_desc[$Aprev][$j]}) {$oper}</sub-operation-description2>\n");
					if($string[$i] == "v"){
						for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
							$result = $oper_value[$Aprev][$j];
							$oper_value[$ioper][] = $result;
							$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper}";
							if($write_xml)fwrite($xmlfile,"      <reading>\n");
							if($write_xml)fwrite($xmlfile,"        <timestamp>{$timestamps[$ISLOT]}</timestamp>\n");
							if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
							if($write_xml)fwrite($xmlfile,"      </reading>\n");
							$j++;
						}
					}elseif($string[$i] == "s"){
						$result = $oper_value[$Aprev][$j];
						$oper_value[$ioper][] = $result;
						$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper}";
						if($write_xml)fwrite($xmlfile,"      <reading>\n");
						if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
						if($write_xml)fwrite($xmlfile,"      </reading>\n");
						$j++;
					}else{
						$j++;
					}
				}

			}elseif($oper == "Count"){
				$oper_type[$ioper] = "";
				$string = get_str_as_array($oper_type[$Aprev]);
				$j = 0;
				for ($i=0; $i<count($string); $i++){
					if($write_xml)fwrite($xmlfile,"        <sub-operation-description2>({$oper_desc[$Aprev][$j]}) {$oper}</sub-operation-description2>\n");
					if($string[$i] == "v"){
						$result = $NSLOTS;
						for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
							$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper}";
							$j++;
						}
						$result = $NSLOTS;
						$oper_value[$ioper][] = $result;
						if($write_xml)fwrite($xmlfile,"      <reading>\n");
						if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
						if($write_xml)fwrite($xmlfile,"      </reading>\n");
						$oper_type .= "s";
					}elseif($string[$i] == "s"){
						$result = 1;
						$oper_value[$ioper][] = $result;
						$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper}";
						if($write_xml)fwrite($xmlfile,"      <reading>\n");
						if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
						if($write_xml)fwrite($xmlfile,"      </reading>\n");
						$oper_type .= "s";
						$j++;
					}else{
						$j++;
					}
				}

			}elseif($oper == "List (raw)" || $oper == "Count (raw)"){
				$oper_type[$ioper] = "";
				$string = get_str_as_array($oper_type[$Aprev]);
				$j = 0;
				for ($i=0; $i<count($string); $i++){
					if($write_xml)fwrite($xmlfile,"        <sub-operation-description2>({$oper_desc[$Aprev][$j]}) {$oper}</sub-operation-description2>\n");
					if($string[$i] == "v"){
						for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
							$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper}";
							$j++;
						}
						$result = "Error: raw output is only defined for dynamic attributes not for results of operations";
						$oper_value[$ioper][] = $result;
						if($write_xml)fwrite($xmlfile,"      <reading>\n");
						if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
						if($write_xml)fwrite($xmlfile,"      </reading>\n");
						$oper_type .= "?";
					}elseif($string[$i] == "s"){
						$result = "Error: raw output is only defined for dynamic attributes not for results of operations";
						$oper_value[$ioper][] = $result;
						$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper}";
						if($write_xml)fwrite($xmlfile,"      <reading>\n");
						if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
						if($write_xml)fwrite($xmlfile,"      </reading>\n");
						$oper_type .= "?";
						$j++;
					}else{
						$j++;
					}
				}
			}elseif($oper == "Integrate" || $oper == "Sum" || $oper == "Mean"|| $oper == "Maximum"|| $oper == "Minimum"){

				$ESStartSec = strtotime($ESStart);
				$ESStopSec = strtotime($ESStop);

				// Get time period
				$period = ($ESStopSec - $ESStartSec) / $NSLOTS;

				$oper_type[$ioper] = "";
				$string = get_str_as_array($oper_type[$Aprev]);
				$j = 0;
				for ($i=0; $i<count($string); $i++){
					if($write_xml)fwrite($xmlfile,"        <sub-operation-description2>({$oper_desc[$Aprev][$j]}) {$oper}</sub-operation-description2>\n");
					$int_sum = 0;
					$sum = 0;
					$mean = 0;
					if($string[$i] == "v"){
						for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
							if($ISLOT == 0){
								$maxval = $oper_value[$Aprev][$j];
								$minval = $oper_value[$Aprev][$j];
							}
							$maxval = max($oper_value[$Aprev][$j],$maxval);
							$minval = min($oper_value[$Aprev][$j],$minval);
							$int_sum += $oper_value[$Aprev][$j] * $period;
							$sum += $oper_value[$Aprev][$j];
							$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper}";
							$j++;
						}
						$mean = $sum / $NSLOTS;

						if($oper == "Sum"){
							$result = $sum;
						}elseif($oper == "Integrate"){
							$result = $int_sum;
						}elseif($oper == "Mean"){
							$result = $mean;
						}elseif($oper == "Maximum"){
							$result = $maxval;
						}elseif($oper == "Minimum"){
							$result = $minval;
						}
						$oper_value[$ioper][] = $result;
						if($write_xml)fwrite($xmlfile,"      <reading>\n");
						if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
						if($write_xml)fwrite($xmlfile,"      </reading>\n");
						$oper_type[$ioper] .= "s";
					}elseif($string[$i] == "s"){
						$int_sum = $oper_value[$Aprev][$j] * $period;
						$sum = $oper_value[$Aprev][$j];
						$mean = $oper_value[$Aprev][$j];
						$maxval = $oper_value[$Aprev][$j];
						$minval = $oper_value[$Aprev][$j];
						if($oper == "Sum"){
							$result = $sum;
						}elseif($oper == "Integrate"){
							$result = $int_sum;
						}elseif($oper == "Mean"){
							$result = $mean;
						}elseif($oper == "Maximum"){
							$result = $maxval;
						}elseif($oper == "Minimum"){
							$result = $minval;
						}
						$oper_value[$ioper][] = $result;
						$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper}";
						if($write_xml)fwrite($xmlfile,"      <reading>\n");
						if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
						if($write_xml)fwrite($xmlfile,"      </reading>\n");
						$oper_type[$ioper] .= "s";
						$j++;
					}else{
						$j++;
					}
				}

			}elseif($oper == "NOT"){
				$oper_type[$ioper] = $oper_type[$Aprev];
				$string = get_str_as_array($oper_type[$ioper]);
				$j = 0;
				for ($i=0; $i<count($string); $i++){
					if($write_xml)fwrite($xmlfile,"        <sub-operation-description2>({$oper_desc[$Aprev][$j]}) {$oper}</sub-operation-description2>\n");
					if($string[$i] == "v"){
						for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
							if($oper_value[$Aprev][$j] == 1 || $oper_value[$Aprev][$j] == "1"){
								$result = "0";
							}elseif($oper_value[$Aprev][$j] == 0 || $oper_value[$Aprev][$j] == "0"){
								$result = "1";
							}else{
								$result = "      Error: 1 or 0 expected as input";
							}
							$oper_value[$ioper][] = $result;
							$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper}";
							if($write_xml)fwrite($xmlfile,"      <reading>\n");
							if($write_xml)fwrite($xmlfile,"        <timestamp>{$timestamps[$ISLOT]}</timestamp>\n");
							if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
							if($write_xml)fwrite($xmlfile,"      </reading>\n");
							$j++;
						}
					}elseif($string[$i] == "s"){
						if($oper_value[$Aprev][$j] == 1 || $oper_value[$Aprev][$j] == "1"){
							$result = "0";
						}elseif($oper_value[$Aprev][$j] == 0 || $oper_value[$Aprev][$j] == "0"){
							$result = "1";
						}else{
							$result = "      Error: 1 or 0 expected as input";
						}
						$oper_value[$ioper][] = $result;
						$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper}";
						if($write_xml)fwrite($xmlfile,"      <reading>\n");
						if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
						if($write_xml)fwrite($xmlfile,"      </reading>\n");
						$j++;
					}else{
						$j++;
					}
				}

			}elseif($oper == "Mode"){
				$oper_type[$ioper] = "";
				$string = get_str_as_array($oper_type[$Aprev]);
				$j = 0;
				for ($i=0; $i<count($string); $i++){
					if($write_xml)fwrite($xmlfile,"        <sub-operation-description2>({$oper_desc[$Aprev][$j]}) {$oper}</sub-operation-description2>\n");
					if($string[$i] == "v"){
						unset($tmp_array);
						$tmp_array = array();
						for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
							$tmp_array[] = $oper_value[$Aprev][$j];
							$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper}";
							$j++;
						}
						$mode_val = array_mode($tmp_array);
						if($mode_val[0] == false){
							$result = "No mode found";
						}else{
							$result = $mode_val[0]; // To do. Handle situations which are multi-modal
						}
						$oper_value[$ioper][] = $result;
						if($write_xml)fwrite($xmlfile,"      <reading>\n");
						if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
						if($write_xml)fwrite($xmlfile,"      </reading>\n");
						$oper_type[$ioper] .= "s";
					}elseif($string[$i] == "s"){
						$result = $oper_value[$Aprev][$j];
						$oper_value[$ioper][] = $result;
						$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper}";
						if($write_xml)fwrite($xmlfile,"      <reading>\n");
						if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
						if($write_xml)fwrite($xmlfile,"      </reading>\n");
						$oper_type[$ioper] .= "s";
						$j++;
					}else{
						$j++;
					}
				}
			}elseif($oper == "Standard deviation"){
				$oper_type[$ioper] = "";
				$string = get_str_as_array($oper_type[$Aprev]);
				$j = 0;
				for ($i=0; $i<count($string); $i++){
					if($write_xml)fwrite($xmlfile,"        <sub-operation-description2>({$oper_desc[$Aprev][$j]}) {$oper}</sub-operation-description2>\n");
					if($string[$i] == "v"){
						unset($tmp_array);
						$tmp_array = array();
						for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
							$tmp_array[] = $oper_value[$Aprev][$j];
							$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper}";
							$j++;
						}
						$result = standard_deviation_population($tmp_array);
						$oper_value[$ioper][] = $result;
						if($write_xml)fwrite($xmlfile,"      <reading>\n");
						if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
						if($write_xml)fwrite($xmlfile,"      </reading>\n");
						$oper_type[$ioper] .= "s";
					}elseif($string[$i] == "s"){
						$result = 0;
						$oper_value[$ioper][] = $result;
						$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper}";
						if($write_xml)fwrite($xmlfile,"      <reading>\n");
						if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
						if($write_xml)fwrite($xmlfile,"      </reading>\n");
						$oper_type[$ioper] .= "s";
						$j++;
					}else{
						$j++;
					}
				}
			}elseif($oper == "Median" ||
					$oper == "5th percentile" ||
					$oper == "10th percentile" ||
					$oper == "25th percentile" ||
					$oper == "75th percentile" ||
					$oper == "90th percentile" ||
					$oper == "95th percentile")
			{
				if($oper == "Median"){
					$perc = 50;
				}elseif($oper == "5th percentile"){
					$perc = 5;
				}elseif($oper == "10th percentile"){
					$perc = 10;
				}elseif($oper == "25th percentile"){
					$perc = 25;
				}elseif($oper == "75th percentile"){
					$perc = 75;
				}elseif($oper == "90th percentile"){
					$perc = 90;
				}elseif($oper == "95th percentile"){
					$perc = 95;
				}

				$oper_type[$ioper] = "";
				$string = get_str_as_array($oper_type[$Aprev]);
				$j = 0;
				for ($i=0; $i<count($string); $i++){
					if($write_xml)fwrite($xmlfile,"        <sub-operation-description2>({$oper_desc[$Aprev][$j]}) {$oper}</sub-operation-description2>\n");
					if($string[$i] == "v"){
						unset($tmp_array);
						$tmp_array = array();
						for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
							$tmp_array[] = $oper_value[$Aprev][$j];
							$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper}";
							$j++;
						}
						$result = mypercentile($tmp_array,$perc);
						$oper_value[$ioper][] = $result;
						if($write_xml)fwrite($xmlfile,"      <reading>\n");
						if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
						if($write_xml)fwrite($xmlfile,"      </reading>\n");
						$oper_type[$ioper] .= "s";
					}elseif($string[$i] == "s"){
						$result = $oper_value[$Aprev][$j];
						$oper_value[$ioper][] = $result;
						$oper_desc[$ioper][] = "({$oper_desc[$Aprev][$j]}) {$oper}";
						if($write_xml)fwrite($xmlfile,"      <reading>\n");
						if($write_xml)fwrite($xmlfile,"        <timestamp>NA</timestamp>\n");
						if($write_xml)fwrite($xmlfile,"        <value datatype='{$datatype}'>{$result}</value>\n");
						if($write_xml)fwrite($xmlfile,"      </reading>\n");
						$oper_type[$ioper] .= "s";
						$j++;
					}else{
						$j++;
					}
				}
			}else{
				echo "ERROR: Bad operation in ServiceCron.php in function compute_operation";
			}

		}
	}else{
		// ERROR
		echo "ERROR: Bad operand A type in ServiceCron.php in function compute_operation";
	}
}

// function to compute values from two operands
function compute_two_operands($A,$oper,$B){
	if(strcasecmp(substr($A,0,5),"error") == 0)return $A;
	if(strcasecmp(substr($B,0,5),"error") == 0)return $B;
	$A = strval($A);
  $B = strval($B);
	$null_mes = "null data provided";
	if($A == NULL || $B == NULL || $A == $null_mes || $B == $null_mes)return $null_mes;

	if($oper == "greater than"){
		$oper = ">";
	}elseif($oper == "greater than or equal to"){
		$oper = ">=";
	}elseif($oper == "less than"){
		$oper = "<";
	}elseif($oper == "less than or equal to"){
		$oper = "<=";
	}

	if($oper == "+"){
		$answer = $A + $B;
	}elseif($oper == "-"){
		$answer = $A - $B;
	}elseif($oper == "*"){
		$answer = $A * $B;
	}elseif($oper == "/"){
		$answer = $A / $B;
	}elseif($oper == "Equals"){
		if($A == $B ){
			$answer = "1"; // 1 = true, 0 = false
		}else{
			$answer = "0";
		}
	}elseif($oper == ">"){
		if($A > $B ){
			$answer = "1";
		}else{
			$answer = "0";
		}
	}elseif($oper == ">="){
		if($A >= $B ){
			$answer = "1";
		}else{
			$answer = "0";
		}
	}elseif($oper == "<"){
		if($A < $B ){
			$answer = "1";
		}else{
			$answer = "0";
		}
	}elseif($oper == "<="){
		if($A <= $B ){
			$answer = "1";
		}else{
			$answer = "0";
		}
	}elseif($oper == "AND"){
		if($A AND $B ){
			$answer = "1";
		}else{
			$answer = "0";
		}
	}elseif($oper == "OR"){
		if($A OR $B ){
			$answer = "1";
		}else{
			$answer = "0";
		}
	}else{
		$answer = "ERROR: Bad operation in ServiceCron.php in function compute_two_operands";
	}
	return $answer;
}

function only_one_operand_needed($oper){
	if($oper == "+"){
		return 0;
	}elseif($oper == "-"){
		return 0;
	}elseif($oper == "*"){
		return 0;
	}elseif($oper == "/"){
		return 0;
	}elseif($oper == "Equals"){
		return 0;
	}elseif($oper == ">"){
		return 0;
	}elseif($oper == ">="){
		return 0;
	}elseif($oper == "<"){
		return 0;
	}elseif($oper == "<="){
		return 0;
	}elseif($oper == "AND"){
		return 0;
	}elseif($oper == "OR"){
		return 0;
	}elseif($oper == "List"){
		return 1;
	}elseif($oper == "Count"){
		return 1;
	}elseif($oper == "List (raw)"){
		return 1;
	}elseif($oper == "Count (raw)"){
		return 1;
	}elseif($oper == "Integrate"){
		return 1;
	}elseif($oper == "Sum"){
		return 1;
	}elseif($oper == "Mean"){
		return 1;
	}elseif($oper == "Maximum"){
		return 1;
	}elseif($oper == "Minimum"){
		return 1;
	}elseif($oper == "Median"){
		return 1;
	}elseif($oper == "Mode"){
		return 1;
	}elseif($oper == "NOT"){
		return 1;
	}elseif($oper == "Standard deviation"){
		return 1;
	}elseif($oper == "5th percentile"){
		return 1;
	}elseif($oper == "10th percentile"){
		return 1;
	}elseif($oper == "25th percentile"){
		return 1;
	}elseif($oper == "75th percentile"){
		return 1;
	}elseif($oper == "90th percentile"){
		return 1;
	}elseif($oper == "95th percentile"){
		return 1;
	}else{
		return -1;
	}
}

// function to return timestamps or dynamic data as array within any time range
// in NSLOTS number of rows. If raw option is selected then the original timestamps are
// retained and data returned as is (which may not be the same as NSLOTS number of rows)
// if data rows in the time range > NSLOTS averaging is employed
// if data rows in the time range < NSLOTS interpolation is employed
// range checks are done if there is adequate historic data for that element
function get_slotted_var($DID,$ESStart,$ESStop,$NSLOTS,$con,$mode){
	require "../Common/preferences.php";
	$value = array();
	$TS = array();

	// Error checks
	if($NSLOTS <= 0)return "ERROR: NSLOTS ill defined";

	$ESStart = strtotime($ESStart);
	$ESStop = strtotime($ESStop);

	// Get time period
	$period = ($ESStop - $ESStart ) / $NSLOTS;
	if($mode == "period")return $period;

	$RealESStart = $ESStart - ($period / 2);
	$RealESStop  = $ESStop + ($period / 2);

	for($ISLOT = 0; $ISLOT < $NSLOTS; $ISLOT++){
		$StartTime = $RealESStart + $ISLOT * $period;
		$StopTime = $StartTime + $period;

		// Get time in mysql format
		$StartTime = date('Y-m-d H:i:s',$StartTime);
		$StopTime  = date('Y-m-d H:i:s',$StopTime);

		// Put time stamp in array
		array_push($TS,$StartTime);

		if($mode != "time"){
			// Get dynamic data within this time
			$res = mysql_query("SELECT count(value) FROM DynamicValue WHERE dynamic_id = {$DID}
								AND	timestamp >= '{$StartTime}' AND timestamp < '{$StopTime}'",$con);
			while($row = mysql_fetch_array($res))$actual_slots = $row[0];

			// actual slots of data may be 0, 1 or more each is treated differently
			// If no slots then use previous value or return no data as defined in preferences
			if($actual_slots == 0){
				if($DynData_gap_fill == 1 || $DynData_gap_fill == "1"){ // use previous value
					$res = mysql_query("SELECT count(value) FROM DynamicValue WHERE dynamic_id = {$DID}
										AND timestamp < '{$StartTime}' order by timestamp desc limit 1",$con);
					while($row = mysql_fetch_array($res))$count = $row[0];
					if($count > 0){
						$res = mysql_query("SELECT value FROM DynamicValue WHERE dynamic_id = {$DID}
											AND timestamp < '{$StartTime}' order by timestamp desc limit 1",$con);
						while($row = mysql_fetch_array($res))array_push($value,$row[0]);
					}else{
						array_push($value,NULL); // there are no previous values
					}
				}elseif($DynData_gap_fill == 0 || $DynData_gap_fill == "0"){ // use no value
					array_push($value,NULL);
				}

			// if just one value is present then take that value
			}elseif($actual_slots == 1){
				$res = mysql_query("SELECT value FROM DynamicValue WHERE dynamic_id = {$DID}
									AND	timestamp >= '{$StartTime}' AND timestamp < '{$StopTime}'",$con);
				while($row = mysql_fetch_array($res))array_push($value,$row[0]);

			// if more than one value is present then do a time average
			}elseif($actual_slots > 1){
				$val = 0;
				unset($raw_val);
				$raw_val = array();
				unset($raw_time);
				$raw_time = array();
				$res = mysql_query("SELECT value,timestamp FROM DynamicValue WHERE dynamic_id = {$DID}
									AND	timestamp >= '{$StartTime}' AND timestamp < '{$StopTime}'",$con);
				while($row = mysql_fetch_array($res)){
					array_push($raw_val,$row[0]);
					array_push($raw_time,$row[1]);
					$val += $row[0];
				}
				$val = $val / $actual_slots;
				array_push($value,$val);

			// should never come here
			}else{
				array_push($value,NULL);
			}
		}
	}

	// return parameter depending on mode
	if($mode == "value"){
		return $value;
	}elseif($mode == "time"){
		return $TS;
	}elseif($mode == "raw_count"){
		return $actual_slots;
	}elseif($mode == "raw_value"){
		return $raw_val;
	}elseif($mode == "raw_time"){
		return $raw_time;
	}
}

// function to return string as array of characters
function get_str_as_array($string){
	$length = strlen($string);
	$type_arr = array();
	for ($i=0; $i<$length; $i++)$type_arr[$i] = $string[$i];
	return $type_arr;
}

function get_res_datatype($oper){
	if($oper == "greater than"){
		$oper = ">";
	}elseif($oper == "greater than or equal to"){
		$oper = ">=";
	}elseif($oper == "less than"){
		$oper = "<";
	}elseif($oper == "less than or equal to"){
		$oper = "<=";
	}

	if($oper == "+"){
		return "real";
	}elseif($oper == "*"){
		return "real";
	}elseif($oper == "/"){
		return "real";
	}elseif($oper == "Equals"){
		return "bool";
	}elseif($oper == ">"){
		return "bool";
	}elseif($oper == ">="){
		return "bool";
	}elseif($oper == "<"){
		return "bool";
	}elseif($oper == "<="){
		return "bool";
	}elseif($oper == "AND"){
		return "bool";
	}elseif($oper == "OR"){
		return "bool";
	}elseif($oper == "List"){
		return "unknown";
	}elseif($oper == "Count"){
		return "int";
	}elseif($oper == "List (raw)"){
		return "unknown";
	}elseif($oper == "Count (raw)"){
		return "int";
	}elseif($oper == "Integrate"){
		return "real";
	}elseif($oper == "Sum"){
		return "real";
	}elseif($oper == "Mean"){
		return "real";
	}elseif($oper == "Maximum"){
		return "real";
	}elseif($oper == "Minimum"){
		return "real";
	}elseif($oper == "Median"){
		return "real";
	}elseif($oper == "Mode"){
		return "real";
	}elseif($oper == "NOT"){
		return "bool";
	}elseif($oper == "Standard deviation"){
		return "real";
	}elseif($oper == "5th percentile"){
		return "real";
	}elseif($oper == "10th percentile"){
		return "real";
	}elseif($oper == "25th percentile"){
		return "real";
	}elseif($oper == "75th percentile"){
		return "real";
	}elseif($oper == "90th percentile"){
		return "real";
	}elseif($oper == "95th percentile"){
		return "real";
	}else{
		return "error: get_res_datatype";
	}
}







?>
