<?php
/**
 * Gets a list of obects AND THEIR POSITIONS inside an environment
 *
 * Creates a list of objects within a given environment. 
 *
 * The 'id' parameters is the ID of the environment object.
 *
 * @author Steven Harding
 */	
 
 /**@api {get} /getvedetails /getvedetails
@apiGroup Client
@apiVersion 0.9.5
@apiPermission user

@apiParam {integer} id The ARDI ID of the asset to use as a base.

@apiSuccess {xml} response An XML response containing the assets in the environment.

@apiSuccessExample {xml} Response (XML):
  HTTP/1.1 200 OK
  <config>
	<relations>
		<relationship name="Location" id="2" upname="Inside" downname="Contains" passes="" colour="" type="heirachial"/>
		<relationship name="Type" id="3" upname="A Type Of" downname="Is Assigned To" passes="" colour="" type="category"/>
		<relationship name="Control" id="5" upname="Controled By" downname="Controls" passes="" colour="#ffffff" type="logical"/>
		<relationship name="Monitors" id="6" upname="Monitored By" downname="Monitors" passes="" colour="#22FF22" type="physical"/>
		<relationship name="Clarified Water" id="11" upname="supplied water from" downname="supplies water to" passes="" colour="#0F2EB8" type="physical"/>
		<relationship name="Compressed Air" id="12" upname="supplied compressed air from" downname="supplies compressed air to" passes="38" colour="#81F1D3" type="physical" energy="yes"/>
	</relations>
	<properties>
		<property name="Equipment Tag" id="2" type="TAG"/>
		<property name="Address" id="3" type="ADDRESS"/>
		<property name="Layout" id="9" type="LAYOUT"/>
		<property name="AR Marker" id="12" type="ARTAG"/>
		<property name="Placement" id="13" type="LOCATION"/>
		<property name="Appearance" id="14" type="MODEL"/>
		<property name="Isolation Point" id="15" type="ISOPOINT"/>
		<property name="Source Point" id="16" type="SRCPOINT"/>
		<property name="Non-Return Point" id="17" type="NRPOINT"/>
		<property name="Symbol" id="18" type="SYMBOL"/>
		<property name="Template Name" id="19" type="TEMPLATE"/>
		<property name="Citect ID" id="20" type="ID"/>
		<property name="Clarity" id="21" type="MEASUREMENT">
			<display>
				<range type="fixed" min="0" max="100"/>
			</display>
		</property>
		<property name="Ready" id="41" type="STATUS">
			<display>
				<range type="fixed" min="0" max="500"/>
				<gradient stops="0000ff_0_%25__40ff00_10.3_%25__caffb8_76_%25__ffa02d_90_%25__ff0000_100_%25"/>
				<option name="fadeother" value="false"/>
			</display>
		</property>
	</properties>
	<profiles>
		<profile name="Actual" id="1" port="8104"/>
	</profiles>
</config>
	
@apiError 500 Maintenance Mode or Server Error
	
@apiErrorExample {xml} Error Response (XML)
  HTTP/1.1 200 OK
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  <error>
  	<code>500</code>
  	<message>Server Unavailable</message>
  </error>
	
@apiDescription

This function gathers information about all of the assets in an environment and how to effectively present them in three-dimensional space.
*/
		$starttime = microtime(true);
		$totalbindtime = 0;
		$totalassettime = 0;
		$totaladditionaltime = 0;
		
		$tagbcache = array();
		$getenvironment = true;
	
		if (isset($_REQUEST['id']))
			$itemid = $_REQUEST['id'];
		else
		{
			if ($_REQUEST['onlyid'])
			{
				$getenvironment = false;
				$itemid = $_REQUEST['onlyid'];
				$envid = $itemid;
			}
		}
		$done = array();
		
		$bb = array();
		$bb['id'] = $itemid;
		$bb['name'] = 'This Asset';
		$tid = $itemid;
		
		$candidates = array();
		$candidates[] = $bb;
		
		$locationparents = array();	
		$envid = 0;

		if ($getenvironment == true) {		
			$query = $db->query('SELECT name,id FROM assetrelclosures JOIN assets ON (assetrelclosures.parentasset = assets.id) WHERE childasset='.$itemid.' AND depth > 0 ORDER BY depth DESC');

			$str = "";

			while($row = $query->fetch(PDO::FETCH_ASSOC)) 
			{		
				$candidates[] = $row;
			}			

			//print_r($candidates);

			$any = false;	
			$model = false;

			foreach($candidates as $v)
			{
				$dirname = $sitefolder.'/media/layouts/'.$v['id'];
				if (file_exists($dirname))
				{
					if (file_exists($dirname.'/details.inc'))
					{
						$envid = $v['id'];
						break;
					}
				}
			}
			
			if (isset($envid)) $tid = $envid;
		}
	
		header("Content-type: text/xml");
		echo '<contents>';
		
		$query = $db->query("SELECT typename,id FROM properties WHERE typename='MODEL' OR typename='LOCATION'");
		while($row = $query->fetch(PDO::FETCH_ASSOC)) 
		{
			if ($row['typename'] == 'MODEL')
			{
				$modelprop = $row['id'];
			}
			if ($row['typename'] == 'LOCATION')
			{
				$locationprop = $row['id'];
			}
		}
	       
		$modelid = array();    
		$modeltex = array();
		$modelcol = array();
		
		$query = $db->query("SELECT assets.id,assetvalues.value FROM assets JOIN assetrelclosures ON (assetrelclosures.childasset=assets.id) JOIN assetvalues ON (assets.id = assetvalues.assetid) WHERE assetvalues.propertyid=".$modelprop." AND assetrelclosures.parentasset = ".$tid);       
		while($row = $query->fetch(PDO::FETCH_ASSOC)) 
		{
			$bits = explode('|',$row['value']);
			$modelid[$row['id']] = $bits[0];
			if (count($bits) > 1)
			{
				$modeltex[$row['id']] = $bits[1];
				$modelcol[$row['id']] = $bits[2];
			}
		}
		
		$query = $db->query("SELECT link.childasset as id, value FROM assetrelclosures as link JOIN assetrelclosures as tagged ON (tagged.childasset=link.childasset AND tagged.relationship=3) JOIN assetvalues ON (tagged.parentasset = assetvalues.assetid) WHERE assetvalues.propertyid=".$modelprop." AND link.parentasset = ".$tid);       
		while($row = $query->fetch(PDO::FETCH_ASSOC)) 
		{
			$bits = explode('|',$row['value']);
			if (!isset($modelid[$row['id']]))
			{
				$modelid[$row['id']] = $bits[0];
				if (count($bits) > 1)
				{
					$modeltex[$row['id']] = $bits[1];
					$modelcol[$row['id']] = $bits[2];
				}
			}
		}
		
		if ($getenvironment == false)
		{
			$ass = new Asset($itemid);
			$props = $ass->GetProperties();
			$ass->GetValues($props);
			
			foreach($props as $p)
			{
				if ($p->type == "MODEL")
				{
					$modelid[$itemid] = $p->value['model'];
					$modeltex[$itemid] = $p->value['skin'];
					$modelcol[$itemid] = $p->value['colour'];
				}
			}
		}
		
		//echo "SELECT link.childasset as id, lastvalue,node FROM assetrelclosures as link JOIN datalinks ON (datalinks.assetid = link.childasset) WHERE datalinks.propertyid=".$locationprop." AND link.parentasset = ".$itemid;
		$dynamiclocations = array();
		$query = $db->query("SELECT link.childasset as id, lastvalue,node FROM assetrelclosures as link JOIN datalinks ON (datalinks.assetid = link.childasset) WHERE datalinks.propertyid=".$locationprop." AND link.parentasset = ".$envid);       
		while($row = $query->fetch(PDO::FETCH_ASSOC)) 
		{
			
			if (isset($dynamiclocations[$row['id']]))
			{
				$dynamiclocations[$row['id']][$row['node']] = $row['lastvalue'];
			}
			else
			{
				$dynamiclocations[$row['id']] = array();
				$dynamiclocations[$row['id']][$row['node']] = $row['lastvalue'];
			}
		}
		
		//print_r($dynamiclocations);
		
		
		
		$occluded = array();
		$forceit = false;
		//Figure out which assets are being occluded by other environments...
		$set = array();
		$files = glob($sitefolder.'/media/layouts/*');
		foreach($files as $f)
		{
			$n = pathinfo($f,PATHINFO_BASENAME);
			if ($n != $itemid)
			{
				$set[] = $n;
			}
			else
			{
				$forceit = true;
			}
		}
		
		//print_r($set);
		
		if (($forceit == true) || (count($set) > 1))
		{
			$myparents = array();
			
			$query = $db->query("SELECT parentasset FROM assetrelclosures WHERE relationship=2 AND childasset=".$itemid);
			
			while($row = $query->fetch(PDO::FETCH_ASSOC)) 
			{
				$myparents[] = $row['parentasset'];
			}
			//print_r($myparents);
			//echo '<br/><br/>';
			
			$finalset = array();
			foreach($set as $s)
			{
				if (!in_array($s,$myparents))
				{
					$finalset[] = $s;
				}
			}
			
			//print_r($finalset);
			//echo '<br/><br/>';
			if (count($finalset) > 0)
			{
				$query = $db->query("SELECT childasset,parentasset FROM assetrelclosures WHERE relationship=2 AND parentasset IN (".implode(',',$finalset).")");
				
				//echo "SELECT childasset,parentasset FROM assetrelclosures WHERE relationship=2 AND parentasset IN (".implode(',',$finalset).")";
				if ($query !== FALSE)
				{
					while($row = $query->fetch(PDO::FETCH_ASSOC)) 
					{
						if (!in_array($row['childasset'],$myparents))
						{
							$occluded[$row['childasset']] = $row['parentasset'];
						}
					}
				}
			}
		}
		
		$occids = array_keys($occluded);
		$occluders = array();

		$boundassets = array();
		$hasbehaviours = array();
		
		global $datalinkstried;
		global $datalinks;
		
		//Get environment id...
		
		//print_r($occluded);
		
		$totalsetuptime = microtime(true) - $starttime;

		if ($getenvironment == false)
			$query = $db->query("SELECT DISTINCT id,name,descript,value FROM assets LEFT OUTER JOIN assetvalues ON (assets.id = assetvalues.assetid AND assetvalues.propertyid=".$locationprop.") WHERE assets.id=".$tid);
		else
			$query = $db->query("SELECT DISTINCT id,name,descript,value FROM assets JOIN assetrelclosures ON (assetrelclosures.childasset=assets.id) JOIN assetvalues ON (assets.id = assetvalues.assetid) WHERE assetvalues.propertyid=".$locationprop." AND assetrelclosures.parentasset = ".$tid);
		
		//echo "SELECT DISTINCT id,name,descript,value FROM assets JOIN assetrelclosures ON (assetrelclosures.childasset=assets.id) JOIN assetvalues ON (assets.id = assetvalues.assetid) WHERE assetvalues.propertyid=".$locationprop." AND (assetrelclosures.parentasset = ".$tid.")";
		
		while($row = $query->fetch(PDO::FETCH_ASSOC)) 
		{
			if (in_array($row['id'],$occids)) 
			{
				if (!in_array($occluded[$row['id']],$occluders))
				{
					$occluders[] = $occluded[$row['id']];
				}
				continue;
			}
			if (!isset($row['value'])) 
				$ps = "";
			else
				$ps = $row['value'];
			$bits = explode('|',$ps);
			
			$datalinkstried = array();
			$datalinks = array();
		
			$currentass = new Asset($row['id']);
			$props = $currentass->GetLocalProperties();
			$currentass->GetValues($props,true);
			
			//echo '<!-- ';
			//print_r($props);
			//echo ' -->';
			
			$tagid = "";
			foreach($props as $prp)
			{
				if ($prp->origintype == 'reference') continue;
				if ($prp->type == "TAG")
				{
					$tagid = $prp->value['text'];
					break;
				}
			}
			
			if (isset($dynamiclocations[$row['id']]))
			{
				if (isset($dynamiclocations[$row['id']]['position']))
				{
					$bits[0] = '@position:'.$dynamiclocations[$row['id']]['position'];
				}
				if (isset($dynamiclocations[$row['id']]['scale']))
				{
					$bits[1] = '@scale:'.$dynamiclocations[$row['id']]['scale'];
				}
				if (isset($dynamiclocations[$row['id']]['rotation']))
				{
					$bits[2] = '@rotation:'.$dynamiclocations[$row['id']]['rotation'];
				}
			}
			
			if (count($bits) == 1)
			{
				$bits = explode('|','|||');
			}
			
			echo '  <asset id="'.$row['id'].'" name="'.$row['name'].'" position="'.$bits[0].'" rotation="'.$bits[2].'" scale="'.$bits[1].'"';
			if (count($bits) > 3)
			{
				echo ' relativeto="'.$bits[3].'"';
			}
			if ($row['descript'] != "")
			{
				echo ' desc="'.$row['descript'].'"';
			}
			if (isset($bundles[$row['id']]))
			{
				echo ' bundle="yes"';
			}
			if (isset($modelid[$row['id']]))
			{
				echo ' model="'.$modelid[$row['id']].'"';
				if ($modelid[$row['id']] == -1)
				{
					if (isset($modeltex[$row['id']]))
					{
						echo ' path="'.str_replace($sitefolder,$siteroot,$modeltex[$row['id']]).'"';
					}
					if (isset($modelcol[$row['id']]))
					{
						echo ' colour="'.$modelcol[$row['id']].'"';
					}
				}
				else
				{
					if (isset($modelcol[$row['id']]))
					{
						echo ' colour="'.$modelcol[$row['id']].'"';
					}
					if (isset($modeltex[$row['id']]))
					{
						echo ' skin="'.$modeltex[$row['id']].'"';
					}
				}
			}
			if ($tagid != '')
			{
				echo ' tag="'.$tagid.'"';
			}
			
			echo '>';
			
			$done[] = $row['id'];
													
			if (!isset($asset[$row['id']]))
			{
				include($sitefolder.'/cache/relationships/'.$row['id'].'.inc');					
			}
			
			/*echo '<!--';
			print_r($props);
			echo '-->';*/
			foreach($props as $prp)
			{
				//if ($prp->origintype == 'reference') continue;
				
				$proceed = false;
				//echo 'Checking '.$prp->type;
				switch($prp->type)
				{
					case 'MEASUREMENT':
					case 'ISOPOINT':
					case 'SOURCE':
					case 'NRPOINT':
					case 'STATUS':
					case 'STATE':
					case 'ENUM':
					case 'AOE':
						$proceed = true;
						break;
				};
				
				if ($proceed == false) continue;
				
				if ($prp->origintype == 'secondary') continue;
				
				echo '    <value id="'.$prp->id.'" proptype="'.$prp->type.'"';
				
				foreach($prp->value as $k => $v)
				{
					if ($k[0] == '_') continue;
					if ($k == 'live') continue;
					
					if (isset($prp->value['_dynamics']))
					{
						if (in_array($k,$prp->value['_dynamics']))
						{
							$orig = $row['id'];
							if (($prp->origintype == 'overridden') || ($prp->origintype == 'reference') || ($prp->origintype == 'monitors'))
								$orig = $prp->origin;
							echo ' '.htmlentities(str_replace(' ','_',$k)).'="@'.$orig.':'.$prp->id.':'.$k.':'.htmlentities($v).'"';
						}
						else
							echo ' '.htmlentities(str_replace(' ','_',$k)).'="'.htmlentities($v).'"';
					}
					else
							echo ' '.htmlentities(str_replace(' ','_',$k)).'="'.htmlentities($v).'"';
				}
				
				echo "/>\r\n";
			}
			
			/*$qry = $db->query('SELECT assetvalues.propertyid,typename,value,node FROM assetvalues JOIN properties ON (properties.id = propertyid) LEFT OUTER JOIN datalinks ON (datalinks.propertyid=assetvalues.propertyid AND datalinks.assetid=assetvalues.assetid) WHERE assetvalues.assetid='.$row['id'].' ORDER BY name ASC');	
	
			$lastpid = 0;
	
			while($rx = $qry->fetch(PDO::FETCH_ASSOC)) 
			{
				if ($rx['propertyid'] == $modelprop) continue;
				if ($rx['propertyid'] == $locationprop) continue;
				if ($rx['propertyid'] == $lastpid) continue;
					
				$lastpid = $rx['propertyid'];
				
				echo '    <value id="'.$rx['propertyid'].'" ';
				$fn = $_SERVER['DOCUMENT_ROOT'].'/modules/inputs/'.strtolower($rx['typename']).'.php';
				if (!file_exists($fn)) continue;
				
				include($fn);
				$bits = explode('|',$rx['value']);
				for($x=0;$x<count($inputs);$x++)
				{
					if (isset($bits[$x]))
					{
						echo str_replace(" ","_",$inputs[$x]['name']).'="';
						if ((isset($rx['node'])) && ($rx['node'] != "") && ($rx['node'] == $inputs[$x]['name']))	
						{
							if (($bits[$x] == "") && (isset($inputs[$x]['default'])))
								$initial = htmlentities($inputs[$x]['default']);
							else
								$initial = htmlentities($bits[$x]);
								
							echo '@'.$rx['node'].':'.$initial;							
						}
						else
						{								
							if (($bits[$x] == "") && (isset($inputs[$x]['default'])))
								echo htmlentities($inputs[$x]['default']);
							else
								echo htmlentities($bits[$x]);								
						}
						echo '" ';
					}
				}
				echo '/>';
			}*/
			
			$btime = microtime(true);
			$bf = $sitefolder.'/cache/bindings/'.$row['id'].'.xml';				
			if (file_exists($bf))
			{
				$content = file_get_contents($bf);
				preg_match_all("/boundasset=\"([0-9]*)\"/", $content, $matches);
				foreach($matches[1] as $m)
				{
					if ($m != "")
					{
						if (!in_array($m,$boundassets)) $boundassets[] = $m;
					}
					//echo 'Picked Up Bound Asset '.$m;
				};
				echo $content;
			}
			$totalbindtime += microtime(true) - $btime;
			
			$behive = array();
			$bf = $sitefolder.'/media/assets/'.$row['id'].'/behaviours.xml';
			if (file_exists($bf))
			{
				//echo '<!-- Using File-System Behaviour On Asset '.$row['id'].' ( '.$bf.' ) -->';
				ob_start();
				include($bf);
				$c = ob_get_clean();
				if ($c != '/>') echo $c;
				$behive[] = $row['id'];
			}
			
			if (isset($asset[$row['id']]['tags']))
			{
				foreach($asset[$row['id']]['tags'] as $tg)
				{
					if (in_array($tg,$behive)) continue;
					if (isset($tagbcache[$tg]))
					{
						if ($tagbcache[$tg] !== FALSE)
						{
							//echo '<!-- Using Cached Behaviour On Template '.$tg.' -->';
							echo $tagbcache[$tg];
						}
					}
					else
					{
						$bf = $sitefolder.'/media/assets/'.$tg.'/behaviours.xml';
						if (file_exists($bf))
						{
							//echo '<!-- Located Behaviour File on Template '.$bf.' -->';
							ob_start();
							include($bf);
							$c = ob_get_clean();
							if ($c != '/>') 
							{
								$tagbcache[$tg] = $c;
								echo $tagbcache[$tg];
							}
						}
						else
						{
							$tagbcache[$tg] = FALSE;
						}
					}
				}
			}

	    	echo '</asset>'."\r\n";
		}
		
		/*echo '<feedback>';
		echo '   <asset>Done</asset>';
		echo '</feedback>';
		
		echo '</contents>';	
		exit;*/
		
		foreach($occluders as $occ)
		{
			$ass = new Asset($occ);
			echo '<occluder id="'.$ass->id.'" name="'.$ass->name.'"/>';
			//echo ' id="'.$ass->id.'" name="'.$ass->name.'" position="'.$bits[0].'" rotation="'.$bits[2].'" scale="'.$bits[1].'"
			//echo '</asset>';
		}
		
		$btime = microtime(true);
		
		if (count($boundassets) > 0)
		{
			//$vvl = 0;
			foreach($boundassets as $bs)
			{
				if (in_array($bs,$done))
				{
					continue;
				}
			
				if (!isset($asset[$bs]))
				{
					include($sitefolder.'/cache/relationships/'.$bs.'.inc');					
				}
				
				if (isset($asset[$bs]))
				{
					$datalinkstried = array();
					$datalinks = array();
			
					$ast = new Asset($bs);	
					
					$stime = microtime(true);
					$props = $ast->GetLocalProperties();
					$ast->GetValues($props,true);
					
					
					echo '  <asset id="'.$bs.'" name="'.$ast->name.'">';
					
					//$qry = $db->query('SELECT assetvalues.propertyid,typename,value,node FROM assetvalues JOIN properties ON (properties.id = propertyid) LEFT OUTER JOIN datalinks ON (datalinks.propertyid=assetvalues.propertyid AND datalinks.assetid=assetvalues.assetid) WHERE assetvalues.assetid='.$bs.' ORDER BY name ASC');				
					
					
					foreach($props as $p)
					{
						$pass = false;
						switch($p->type)
						{
						case 'MEASUREMENT':
						case 'ISOPOINT':
						case 'SOURCE':
						case 'NRPOINT':
						case 'STATUS':
						case 'STATE':
						case 'ENUM':
						case 'AOE':
							$pass = true;
						}
						
						if ($pass == false) continue;
						
						$dyn = array();
						if (isset($p->value['_dynamics']))
						{
							$dyn = $p->value['_dynamics'];
						}
						
						echo '    <value proptype="'.$p->type.'" id="'.$p->id.'" ';
						foreach($p->value as $k => $v)
						{
							if ($k[0] == '_') continue;
							if (in_array($k,$dyn))
							{
								if ($p->origintype == 'overridden')
								{
									$v = '@'.$p->origin.':'.$p->id.':'.$k.':'.$v;
								}
								else
								{
									$v='@'.$k.':'.$v;
								}
							}
							echo ' '.str_replace(' ','_',$k).'="'.$v.'"';
						}
						
						echo "/>\r\n";
					}
					
					//$etime = microtime(true);
				
					echo '  </asset>'."\r\n";	
						
				}
			}
		}
		
		$secondarytime = microtime(true) - $btime;

	//Add any external behavioural scripts...
	if ($getenvironment == true)
	{
		echo ' <environment>';
		include_once($installfolder.'/model/behaviours.php');
		$bh = new Behaviours($envid,false);
		echo $bh->GetXML("behaviour");
		echo ' </environment>';
	}
		
	echo '<summary setup="'.$totalsetuptime.'" binding="'.$totalbindtime.'" secondary="'.$secondarytime.'" totalelapsed="'.(microtime(true) - $starttime).'"/>';
	
	echo '</contents>';
?>