<?php

/**
 * @class TimeTableMgr
 * @version $Id: TimeTableMgr.php 2809 2015-03-05 09:50:52Z natacha $
 * @todo MANAGE TT created by Search and Plot interactive - HERE?
 *
 */

function timeFormat($myString) 
{
	if (format == "Y z H i s")  {
		$tt = getdate(strtotime($myString));
		return sprintf("%04d",$tt["year"])." "
			.sprintf("%03d",$tt["yday"]+1)." "
			.sprintf("%02d",$tt["hours"])." "
			.sprintf("%02d",$tt["minutes"])." "
			.sprintf("%02d",$tt["seconds"]);
	}
	return date(format,strtotime($myString));     
}

class TimeTableMgr extends AmdaObjectMgr
{     
	function __construct($user = NULL, $sharedObject = FALSE) 
	{
		parent::__construct('Tt.xml');
		$this->contentRootId = 'timeTable-treeRootNode';
		$this->contentRootTag = 'timetabList';
		$this->attributes = array('name' => '', 'intervals' => '');
		$this->optionalAttributes = array();
		$this->objTagName = 'timetab';
		$this->id_prefix = 'tt_';

		if (!$sharedObject && !file_exists($this->xmlName)) {
			  $this->createDom();
			  $this->xp = new domxpath($this->contentDom); 
		}
	}
	
	protected function createDom() 
	{
		$types = array('timetab' => 'timeTable', 'catalog' => 'catalog');

		$rootElement = $this->contentDom->createElement('ws');
		
		foreach ($types as $key => $value) {
			$contentId = $value.'-treeRootNode';
			$contentTag = $key.'List';
			$typeElement = $this->contentDom->createElement($contentTag);
			$typeElement->setAttribute('xml:id', $contentId);
			$rootElement->appendChild($typeElement);
		}
		$this->contentDom->appendChild($rootElement);
		$this->contentDom->save($this->xmlName);
	}

	/*
	*       rename  Time Table in  id.xml
	*/
	protected function renameInResource($name, $id) 
	{
		if (!file_exists(USERTTDIR.$id.'.xml')) return false;

		$this->objectDom -> load(USERTTDIR.$id.'.xml');
		if (!($objToRename = $this->objectDom->getElementById($id))) return false;
		$objToRename -> getElementsByTagName('name')->item(0)->nodeValue = $name;
		$this->objectDom ->save(USERTTDIR.$id.'.xml');
		 
		return true;
	}

	protected function deleteParameter($id)
	{
		if (file_exists(USERTTDIR.$id.'.xml')) unlink(USERTTDIR.$id.'.xml');
	}

	/*
	*        Check if difference is name and info only
	*/
	protected function renameOnly($p) {
		//if (!($p->intervals)) return true;
		return false;
	}
         
        /*
        *  In case of catalogs
        */
        protected function setParamDescription($param) { }

        
	/*
	 *         Create Time Table
	 */
	protected function createParameter($p, $folder)
	{
		if ($this -> objectExistsByName($p->name)) {
			$p -> id  = $this -> getObjectIdByName($p->name);
			$this -> deleteObject($p);
		}
		
		$this->id = $this->setId();
		$this->created = date('Y-m-d\TH:i:s');
		if (!$this->id) return array('error' => ID_CREATION_ERROR);
		
		$this->resFileName = USERTTDIR.$this->id.'.xml';
		//TODO catalog root element = 'timetable'
		$rootElement = $this->objectDom->createElement('timetable');
		$rootElement->setAttribute('xml:id',$this->id);
	 
		foreach ($p as $key => $value)		
			if ($key != 'id' && $key != 'leaf' && $key != 'nodeType' &&
				$key != 'objName' && $key != 'objFormat' && $key != 'folderId' && $key != 'cacheToken') {
					if ($key == 'created') {
						$rootElement->appendChild($this->objectDom->createElement($key, $this->created));
					}
					// it is catalog 
					else if ($key == 'parameters') {
					$paramsElement = $this->setParamDescription($value);
					if ($paramsElement) $rootElement->appendChild($paramsElement);
					
					}
					else if ($key != 'intervals')
						$rootElement->appendChild($this->objectDom->createElement($key, htmlspecialchars($value)));
			}

		$this->objectDom->appendChild($rootElement);
		$this->objectDom->save($this->resFileName);
		$obj = new stdClass();
		$obj->name = $p->name;
		$obj->intervals = $p->nbIntervals;
		$this -> addToContent($obj, $folder);
		return array('id' => $this->id,'created' => $this->created,'info' =>$obj->intervals.' intervals' );
	}

	protected function call_intersection($fst, $snd) 
	{
		$inf = ( $fst[0] > $snd[0] ) ? $fst[0] : $snd[0];
		$sup = ( $fst[1] < $snd[1] ) ? $fst[1] : $snd[1];
		if ( $inf >= $sup ) { $inter[] = array(0,0); }
		else {$inter[] = array($inf,$sup); }
		return $inter;
	}
    
	/*
	* Uploaded text file => convert to array
	*/
	protected function text2amda($tmp_file, $onlyDescription = false) 
	{  
		$suffix = explode('.', basename($tmp_file));
		$lines = file($tmp_file,FILE_SKIP_EMPTY_LINES);
		$description="Uploaded Time Table".PHP_EOL; 

		$recordsNumber = count($lines);
		$descNumber = 0;
		
		foreach ($lines as $line)
		{  
			if ($line[0] == '#') {
				$description=$description.PHP_EOL.substr($line,1,-1);
			}
			else {
				$date = explode(' ', trim(preg_replace('!\s+!', ' ',$line)));
				
				if (!strtotime(trim($date[0]))) {
					$description=$description.PHP_EOL.$line;
					$descNumber++;
					continue;
				}
				// check if it is ISO format
				if (!isset($isIso)) 
					$isIso = preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})$/', trim($date[0]));
					
				if (!$isIso) {
					// y-m-d h:m:s for example
					$dateLength = count($date) / 2;

					$tempStart = $date[0];
					$tempStop = $date[$dateLength];
					
					if ($dateLength > 1) {
						for ($i = 1; $i < $dateLength; $i++)
							$tempStart.= $date[$i];	
						
						for ($i = $dateLength + 1; $i < $dateLength * 2; $i++)
							$tempStop .= $date[$i];
					}

					$startDate = date('Y-m-d\TH:i:s',strtotime($tempStart));
					$stopDate = date('Y-m-d\TH:i:s',strtotime($tempStop));
					
					if (!$onlyDescription)
							$attributesToReturn['intervals'][] = array('start' => $startDate, 'stop' => $stopDate); 
				}
				else {
					if (!$onlyDescription)
						$attributesToReturn['intervals'][] = array('start' => trim($date[0]), 'stop' => trim($date[1]));
				} 
			}
		}
      if ( $recordsNumber == $descNumber )
			$description = "Looks like we can not read your time format...".PHP_EOL.$description;
			
		$attributesToReturn['description'] = $description;
		$attributesToReturn['name'] = basename($tmp_file, '.'.$suffix[1]);
		$attributesToReturn['created'] = date('Y-m-d\TH:i:s');

		return $attributesToReturn;
	}

      /*
      * Uploaded vot TT => convert to array
      */
	protected function vot2amda($tmp_file, $onlyDescription = false) {		  
	// Load Time table		
		$this->objectDom -> load($tmp_file);
		$objToGet = $this->objectDom->getElementsByTagName('TABLEDATA')->item(0);
		$attributesToReturn['name'] = $tmp_file;
		$attributes = $objToGet -> childNodes;
		foreach($attributes as $attribute)
			if ($attribute->tagName == 'TR') {
				$start = $attribute -> getElementsByTagName('TD')->item(0) -> nodeValue;
				$stop = $attribute -> getElementsByTagName('TD')->item(1) -> nodeValue;
				if (!$onlyDescription)
						$attributesToReturn['intervals'][] = array('start' => $start, 'stop' => $stop);
			}
		$suffix = explode('.', basename($tmp_file));   
		$attributesToReturn['name'] = basename($tmp_file, '.'.$suffix[1]); 
		$attributesToReturn['created'] = date('Y-m-d')."T".date('H:i:s');
		$attributesToReturn['description'] = htmlspecialchars($this->objectDom->getElementsByTagName('DESCRIPTION')->item(0) -> nodeValue);
		return($attributesToReturn);
	}
	
	/*****************************************************************
	 *                           PUBLIC FUNCTIONS
	 *****************************************************************/
	 
	/*
	 *   Get Object into Edit
	 */
	function getObject($id, $nodeType) {
		if (substr($nodeType,0,6) == 'shared') {
			//Shared object
			$sharedObjMgr = new SharedObjectsMgr();
			$path = $sharedObjMgr->getDataFilePath(str_replace('shared', '', $nodeType), $id);
		}
		else {
			$path = USERTTDIR.$id.'.xml';
		}

		if (!file_exists($path)) return array('error' => NO_OBJECT_FILE);
		$this->objectDom -> load($path);
		if (!($objToGet = $this->objectDom->getElementById($id))) return array('error' => NO_SUCH_ID);
		$attributesToReturn['id'] = $objToGet->getAttribute('xml:id');
		$attributes = $objToGet -> childNodes;

		$nbInt = 0;
		foreach($attributes as $attribute)
			if($attribute->nodeType == XML_ELEMENT_NODE){
			/*if ($attribute->tagName == 'intervals') {
				$start = $attribute -> getElementsByTagName('start')->item(0) -> nodeValue;
				$stop = $attribute -> getElementsByTagName('stop')->item(0) -> nodeValue;
				$attributesToReturn['intervals'][] = array('start' => $start, 'stop' => $stop);
			}
			else
			$attributesToReturn[$attribute->tagName] =  $attribute->nodeValue;*/
				//BRE - load all except intervals - Intervals will be loaded later with 'loadIntervalsFromTT' function
				if ($attribute->tagName != 'intervals')
					$attributesToReturn[$attribute->tagName] =  $attribute->nodeValue;
				else
					$nbInt++;
			}
		
		$attributesToReturn['nbIntervals'] = $nbInt;
		
		return  $attributesToReturn;
	}
	
	public function createObject($p, $folder)
	{	
		if ($p -> leaf){
			$result = $this->createParameter($p, $folder);
			if ($result['error'])
				return $result;
			$cacheMgr = new TimeTableCacheMgr();
			if (isset($p->cacheToken) && ($p->cacheToken != ''))
			{
				$resultSaveInt = $cacheMgr->saveInTT($result['id'], "update", $p->cacheToken);
				if (!$resultSaveInt['success'])
				{
					if ($resultSaveInt['message'])
						return array('error' => $resultSaveInt['message']);
					else
						return array('error' => 'Unknown error during intervals save');
				}
			}
			return $result;
		}
		//      else return $this->createFolder($p);
		//TODO check if this is possible?
		else return array('error' => 'createFolder should be called from RENAME');	
	}
	
	
	public function modifyObject($p) {
		$folder = $this->getObjectFolder($p->id);
		
		//Copy TT in a tempory file
		$ttFilePath = USERTTDIR.$p->id.'.xml';
		$tmpFileExist = FALSE;
		if (file_exists($ttFilePath))
			$tmpFileExist = copy($ttFilePath,$ttFilePath.".tmp");
		
		//Delete TT
		$this->deleteObject($p);
		
		//Save modifications
		try {
			$result = $this->createObject($p, $folder);			
			if ($result['error'])
				throw new Exception($result['error']);
			if ($tmpFileExist)
				unlink($ttFilePath.".tmp");
			return array('id' => $p->id, 'info' => $result['info']);
		}
		catch (Exception $e) {
			//Restore TT file
			if ($tmpFileExist)
			{
				copy($ttFilePath.".tmp", $ttFilePath);
				unlink($ttFilePath.".tmp");
			}
			return array ('error' => $e->getMessage());
		}
	}
	
	public function loadIntervalsFromTT($id,$typeTT,$start = NULL, $limit = NULL)
	{
		if ($typeTT == 'sharedtimeTable') {
			//Shared object
			$sharedObjMgr = new SharedObjectsMgr();
			$path = $sharedObjMgr->getDataFilePath('timeTable', $id);
		}
		else {
			$path = USERTTDIR.$id.'.xml';
		}
		
  	 //load intervals from TT id
		if (!file_exists($path))
			return array('success' => false, 'message' => "Cannot find TT file ".$id);
			
		$this->objectDom -> load($path);
		if (!($objToGet = $this->objectDom->getElementById($id)))
			return array('success' => false, 'message' => NO_SUCH_ID." ".$id);
    
		$xpath = new DOMXPath($this->objectDom);
		$intervals =  $xpath->query('//intervals');
		
		$result = array();
    
		if (!isset($start) || !isset($limit)) {
			foreach ($intervals as $interval) {
				$startTime = $interval->getElementsByTagName('start')->item(0)->nodeValue;
				$stopTime  = $interval->getElementsByTagName('stop')->item(0)->nodeValue;
				array_push($result, array('start' => $startTime, 'stop' => $stopTime));
			}
		}
		else {
			for ($i = 0; $i < $limit; ++$i) {
				if ($start+$i >= $intervals->length)
					break;
				$startTime = $intervals->item($start+$i)->getElementsByTagName('start')->item(0)->nodeValue;
				$stopTime  = $intervals->item($start+$i)->getElementsByTagName('stop')->item(0)->nodeValue;
				array_push($result, array('start' => $startTime, 'stop' => $stopTime));
			}
		}
    
		return array(
		'totalCount' => $intervals->length,
		'intervals'  => $result,
		'start' => isset($start) ? $start : 0,
		'limit' => isset($limit) ? $limit : 0,
		'success'    => true
		);   
	}
  
	protected function createIntervalElement($interval) 
	{  
		$newInterval = $this->objectDom->createElement('intervals');
		$newInterval->appendChild($this->objectDom->createElement('start',$interval->start));
		$newInterval->appendChild($this->objectDom->createElement('stop',$interval->stop));
		return $newInterval;
	}
	
	public function saveIntervals($id,$intervals,$action)
	{
		if (substr($id,0,6) == 'shared') {
			return array('success' => false, 'message' => "Cannot save shared TimeTable");
		}
		else {
			$path = USERTTDIR.$id.'.xml';		
		} 
		if (!file_exists($path))
			return array('success' => false, 'message' => "Cannot find TT file ".$id);
		$this->objectDom -> load($path);
    
		if (!($objToGet = $this->objectDom->getElementById($id))) 
			return array('success' => false, 'message' => NO_SUCH_ID." ".$id);

		//remove old intervals
		$crtNode = $objToGet->firstChild;
    
		while ($crtNode) {
			if (($crtNode->nodeType != XML_ELEMENT_NODE) || ($crtNode->tagName != 'intervals')) {	
				$crtNode = $crtNode->nextSibling;
				continue;
			}
			$toRemove = $crtNode;
			$crtNode = $crtNode->nextSibling;
			$objToGet->removeChild($toRemove);
			unset($toRemove);
		}
      
		//add new intervals
		foreach ($intervals as $interval) {	 
			$newInterval = $this-> createIntervalElement($interval);
			$this->objectDom->documentElement->appendChild($newInterval);
		}

		//save modifications
		$this->id = $id;
		$this->resFileName = USERTTDIR.$this->id.'.xml';
		$this->objectDom->save($this->resFileName);
    
		unset($this->objectDom);
    
		return array('success' => true,'action' => $action, 'nbIntervals' => count($intervals));
	}
	
      
	public function getUploadedObject($name, $format, $onlyDescription = false) 
	{
		if (strpos($name,'.txt') !== false || strpos($name,'.asc') !== false || strpos($name,'.') == false) {
			$attributesToReturn = $this->text2amda(USERTEMPDIR.$name, $onlyDescription);
			$attributesToReturn['objName'] = $name;
			$attributesToReturn['objFormat'] = $format;
			
			return $attributesToReturn;
		}
		
		if ($format == 'VOT') {
			 $attributesToReturn = $this->vot2amda(USERTEMPDIR.$name, $onlyDescription);
			 $attributesToReturn['objName'] = $name;
			 $attributesToReturn['objFormat'] = $format;
			 
			 return $attributesToReturn;
		}
	 
		if (strpos($name,'.xml') !== false) {
			$temp = explode('.xml', $name);
			$name = $temp[0];
		}
	
		if (!file_exists(USERTEMPDIR.$name.'.xml')) 
				return array('error' => 'no such name');
			  
		$this->objectDom->load(USERTEMPDIR.$name.'.xml');
		if (!($objToGet = $this->objectDom->getElementsByTagName('timetable')->item(0)) && 
			!($objToGet = $this->objectDom->getElementsByTagName('TimeTable')->item(0))) 
					return array('error' => 'no time table');

		$attributes = $objToGet -> childNodes;
		$attributesToReturn['name'] = $name;
		$attributesToReturn['objName'] = $name;
		$attributesToReturn['objFormat'] = $format;

		foreach($attributes as $attribute) {
			if($attribute->nodeType == XML_ELEMENT_NODE){
				if ($attribute->tagName == 'intervals') {
					$start = $attribute -> getElementsByTagName('start')->item(0) -> nodeValue;
					$stop = $attribute -> getElementsByTagName('stop')->item(0) -> nodeValue;
					if (!$onlyDescription)
						$attributesToReturn['intervals'][] = array('start' => $start, 'stop' => $stop);
				} 
				else if ($attribute->tagName == 'Interval') {
					$start = $attribute -> getElementsByTagName('Start')->item(0) -> nodeValue;
					$stop = $attribute -> getElementsByTagName('Stop')->item(0) -> nodeValue;
					if (!$onlyDescription)
						$attributesToReturn['intervals'][] = array('start' => $start, 'stop' => $stop);
				}
				else {
					switch (strtolower($attribute->tagName)) {
						case 'created' : 
							$attributesToReturn['created'] =  $attribute->nodeValue;
							break;
						case 'chain'  :
						case 'source' :  
							$attributesToReturn['description'] = $attribute->nodeValue;
							break;
						default:  break;
					}
				}
			}
		}
		return  $attributesToReturn;
	}

	//TODO getObject only!!!! => change DD_Search output
	public function getTmpObject($folderId, $name, $onlyDescription = false) {
		$filePath = USERWORKINGDIR.$folderId.'/'.$name.'.xml';
		if (!file_exists($filePath)) 
			return array('error' => 'Cannot find result file');
		
		$dom = new DomDocument('1.0'); 
		$dom->formatOutput = true;
		
		if (!$dom -> load($filePath))
			return array('error' => 'Cannot load result file');
		
		$descNodes = $dom->getElementsByTagName('description');
		if ($descNodes->length > 0)
			$attributesToReturn['description'] = $descNodes->item(0)->nodeValue;
		
		$creatNodes = $dom->getElementsByTagName('created');
		if ($creatNodes->length > 0)
			$attributesToReturn['created'] = $creatNodes->item(0)->nodeValue;
		
		$histNodes = $dom->getElementsByTagName('history');
		if ($histNodes->length > 0)
			$attributesToReturn['history'] = $histNodes->item(0)->nodeValue;
	
		$attributesToReturn['objName'] = $name;
		$attributesToReturn['folderId'] = $folderId;
	
		if (!$onlyDescription)
		{
			$intNodes = $dom->getElementsByTagName('intervals');
			foreach ($intNodes as $intNode)
			{
				$startNodes = $intNode->getElementsByTagName('start');
				if ($startNodes->length <= 0)
					return array('error' => 'Error detected in result file');
				$stopNodes = $intNode->getElementsByTagName('stop');
				if ($stopNodes->length <= 0)
					return array('error' => 'Error detected in result file');
				$attributesToReturn['intervals'][] = array('start' => $startNodes->item(0)->nodeValue,
														'stop' => $stopNodes->item(0)->nodeValue);
			}
		}
		
		return  $attributesToReturn;
	}

	/*
	* merge time tables
	*/
	public  function merge($obj)   {
	/**
	* Array of intervals, used like : 
	* [{start:'2010-01-01T23:00:00',stop:'2011-01-01T20:00:00'},{start:'2009-01-01T23:00:00',stop:'2010-01-01T20:00:00'}]
	* $attributesToReturn['intervals'][] = array('start' => $start, 'stop' => $stop);
	*/
		
		$intervals = 0;	
    		
		for ( $i = 0; $i < count($obj->ids); $i++ ) {
			$table[$i] = $this->loadIntervalsFromTT($obj->ids[$i]);
			for ($j=0; $j < count($table[$i]['intervals']); $j++) {
				$interval[$i][$j][0] = $table[$i]['intervals'][$j]['start'];
				$interval[$i][$j][1] = $table[$i]['intervals'][$j]['stop'];
			}
			$intervals += count($interval[$i]);
		}  
    		if ( $intervals > 10000) set_time_limit(1800);
    		
    		$final = array();
    		for ( $i = 0; $i < count($obj->ids); $i++ ) {
    			$final = array_merge($final, $interval[$i]);        		
      		}
    		sort($final);
    		
    		// Algorithm of union
    		$line = 0;
        	$i = 0;
        	$a = $final[$i][0];
	        while ($i < count($final)-1) {
	           if ($final[$i+1][1] <= $final[$i][1])
	           {
	                  array_splice($final,$i+1,1);
	           }
	           else if (($final[$i+1][0] <= $final[$i][1]) && ($final[$i+1][1] >= $final[$i][1]))
	           {
	                  $i++;
	           }
	           else {
	                $start[$line] = $a;
	                $stop[$line] = $final[$i][1];
	                $i++;
	                $line++;
	                $a = $final[$i][0];
	           }
	        }
	        $start[$line] = $a;
	        $stop[$line] = $final[$i][1];
	        $line++;
        
		$objTT = new stdClass();	            	        
		$objTT->name = $obj->name;
    	$objTT->nodeType = 'timeTable';
    	$objTT->leaf = true;
    	$objTT->created = null;
    	$objTT->history = $obj->history;
    	for ($i=0; $i < count($start); $i++) {	
							$inter = new stdClass();
							$inter->start = $start[$i];
							$inter->stop = $stop[$i];
							$objTT->intervals[] = $inter;
    	}
    	$objTT->nbIntervals = count($start);
		$this->objectDom = new DomDocument('1.0'); 
		$this->objectDom->formatOutput = true;
 		
		$res = $this->createParameter($objTT, $folder);
		if ($res['error'])
		  return $res;
 		  
		$this->saveIntervals($res['id'],$objTT->intervals,'merge');
 		
		return $res;
		
    } 
    
/*
 * intersect time tables
 */
    public  function intersect($obj)   {
    	
    	for ( $i = 0; $i < count($obj->ids); $i++ ) {
    		$table[$i] = $this->loadIntervalsFromTT($obj->ids[$i]);
    		for ($j=0; $j < count($table[$i]['intervals']); $j++) {
  				$interval[$i][$j][0] = $table[$i]['intervals'][$j]['start'];
  				$interval[$i][$j][1] = $table[$i]['intervals'][$j]['stop'];
  			}
    		$intervals += count($interval[$i]);
    	}  
    	if ( $intervals > 10000) set_time_limit(1800);

    	// Sort intervals in time tables
        sort($interval[0]);
        sort($interval[1]);
            	
    	$i = 0;
	    $j = 0;
	    $line = 0;
	
	    while ( ($i < count($interval[0])) && ($j < count($interval[1])) ) {
	    	$inter = $this->call_intersection($interval[0][$i], $interval[1][$j]);
	
	        if ($inter[0][0] != 0 && $inter[0][1] != 0)
	        {
	        	$start[$line] = $inter[0][0];
	            $stop[$line] = $inter[0][1];
	            $line++;
	        }
	
	        if ( $interval[0][$i][1] < $interval[1][$j][1] ) { $i++; }
	        else {  $j++; }
	    }
	
	    // Intersection is empty
	    if ( $line == 0 ) {
	    	$result ="empty";
	    } 
	    else {
	    	$objTT->name = $obj->name;
    		$objTT->nodeType = 'timeTable';
    		$objTT->leaf = true;
    		$objTT->created = null;
    		$objTT->history = $obj->history;
    		for ($i=0; $i < count($start); $i++) {	
				$inter = new stdClass();
				$inter->start = $start[$i];
				$inter->stop = $stop[$i];
				$objTT->intervals[] = $inter;
    		}
    		$objTT->nbIntervals = count($start);
    		
    		if (count($objTT->intervals) == 0)
    		  $result ="empty";
    		else
    		{
    		  $this->objectDom = new DomDocument('1.0'); 
			     $this->objectDom->formatOutput = true;
	    	  $result = $this->createObject($objTT, $folder);
	    	
	       if (!isset($result['error']))
		        $this->saveIntervals($result['id'],$objTT->intervals,'intersect');
		
		     }  	
	    }
	    return  $result;		
    }
    
         
         function validNameObject($p){
         	// overwritten
         	$res = parent::validNameObject($p);
         	 
         	if (!$res['valid'])
         		return $res;
         	 
         	//no space
         	if (strpos($p->name, ' ') === FALSE)
         		return array('valid' => true);
         	
         	return array('valid' => false, 'error' => 'Space character is not allowed');
         }
         
	public function copyTT($src_path, $dst_path, $newId, $newName, $newDescription = NULL) 
	{
		if (!file_exists($src_path))
			return FALSE;
		
		if (!is_dir($dst_path))
			return FALSE;
		
		$dom = new DomDocument('1.0');
		$dom->formatOutput = true;
		
		if (!$dom->load($src_path))
			return FALSE;
		
		$timeTableNodes = $dom->getElementsByTagName('timetable');
		if ($timeTableNodes->length <= 0)
			return FALSE;
		
		$timeTableNode = $timeTableNodes->item(0);
		
		$timeTableNode->setAttribute('xml:id', $newId);
		
		$nameNodes = $timeTableNode->getElementsByTagName('name');
		
		if ($nameNodes->length <= 0) {
			//create name node (normally never append)
			$nameNode = $dom->createElement('name');
			$timeTableNode->appendChild($nameNode);
		}
		else
			$nameNode = $nameNodes->item(0);
		
		$nameNode->nodeValue = $newName;
		
		if (isset($newDescription) && !empty($newDescription)) {
			$descriptionNodes = $timeTableNode->getElementsByTagName('description');
			if ($descriptionNodes->length <= 0) {
				//create description node (normally never append)
				$descriptionNode = $dom->createElement('description');
				$timeTableNode->appendChild($descriptionNode);
			}
			else
				$descriptionNode = $descriptionNodes->item(0);
	
			$descriptionNode->nodeValue = $newDescription;
		}
		
		$dst_file_path = $dst_path."/".$newId.".xml";
		if ($dom->save($dst_file_path) === FALSE)
			return FALSE;
		
		chgrp($dst_file_path, APACHE_USER);
		chmod($dst_file_path, 0775);
			
		return TRUE;
	}
}
?>