<?php
/**
 * @class NewFilesMgr
 * @brief
 * @author Elena
 * @version $Id: FilesMgr.php 2830 2015-03-26 10:33:05Z elena $ 
 */

// private $userDirs = array('USERWSDIR' => 'WS', 'USERREQDIR' => 'REQ', 'USERDATADIR' => 'DATA',
//			     'USERWORKINGDIR' =>'RES', 'USERTTDIR' => 'TT', 'USERJOBDIR' => 'JOBS');	

class FilesMgr extends AmdaObjectMgr 
{

	private  $fileName, $fileId, $theFile;

	public $xp;
	private $fileMgr = NULL; //used when a file format needs to use a specific manager
	private $sampling = -100.0, $maxSampling = -100.0;
	private $ncID = NULL;
	private $simuContentRootId;

	function __construct() 
	{   
		parent::__construct('Files.xml');
		$this->contentRootId = 'myData-treeRootNode';
		$this->contentRootTag = 'fileList';
		$this->attributes = array('name' => '', 'start' => '', 'stop' => '');
		$this->optionalAttributes = array();
		$this->objTagName = 'file';

		if (!file_exists($this->xmlName)) 
		{
			$this->createDom();
			$this->xp = new domxpath($this->contentDom); 
		} 
	}

/*
*       Create Content Dom 'Files.xml' if it doesn't exist 	
*/	
	protected function createDom() 
	{                            
		$rootElement = $this->contentDom->createElement('ws');   
		
		$typeElement = $this->contentDom->createElement($this->contentRootTag);
		$typeElement->setAttribute('xml:id', $this->contentRootId);
		$rootElement->appendChild($typeElement);		
		$this->contentDom->appendChild($rootElement);
	 		
		$this->contentDom->save($this->xmlName);          
	}
	
/*
 *    VOTable format processing done by an instance of VOTableMgr
 */
	protected function getVotFileMgr()
	{
		if (!$this->fileMgr)
		{
			$this->fileMgr = new VOTableMgr();
			$this->fileMgr->load($this->fileName);
		}
		return $this->fileMgr;
	}
     
/*
*     CDF format processing
*/      
	protected function getCdfStartStop() 
	{  
		exec('cdfstartstopfromdata '.$this->fileName, $start_stop); 
		return $start_stop[0];  
	}

	protected function getCdfVars() 
	{
		exec('cdfinfo '.$this->fileName, $results);
		return $results;
	}

	public function getCdfVarInfo($cdfVarId) 
	{
		exec('cdfvarinfo '.$this->fileName.' '.$cdfVarId, $results);
		$tempArr = explode(' ', $results[0]);
		// data type
		switch ($tempArr[0]) 
		{
			case "CDF_FLOAT" :
			case "CDF_REAL4" : $data_type = 'FLOAT';
									break;
			case "CDF_INT2":  
			case "CDF_UCHAR":  
			case "CDF_UINT1" : $data_type = 'SHORT';
									break;
			case "CDF_UINT2":
			case "CDF_INT4" : $data_type = 'INTEGER';
									break;
			case "CDF_DOUBLE":  
			case "CDF_REAL8":   
			case "CDF_UINT4":  $data_type = 'DOUBLE'; 
									break;
			default : $data_type = 'FLOAT';
		}
		// data dimensions & number of records
		$n_recs = $tempArr[2];

		if ($tempArr[1] != 0) {		 
			$size = $tempArr[3];
			//TODO 2D,3D,4D array no processing	
			//   if ($tempArr[1] > 1) 
		}
		else {
			$size = 1;		  
		} 
		
		$units =  exec('cdfvar_attr '.$this->fileName.' '.$cdfVarId.' UNITS');
		$fillval =  exec('cdfvar_attr '.$this->fileName.' '.$cdfVarId.' FILLVAL');
		
		return array('type' => $data_type, 'size' => $size, 'n_records' => $n_recs, 'units' => $units, 'fillvalue' => $fillval);
	}

	public function getCdfSampling() {   
		exec('cdfsamplingfromdata '.$this->fileName, $results);
		return $results;
	}
	
	public function getCdfSamplings() {        
		exec('cdfsamplingsfromdata '.$this->fileName, $results);
		return $results;
	}
/*
*       CEF format processing
*/
	protected function getcefstartstop() 
	{  
		exec("cefstartstop ".$this->filename, $start_stop);
		return $start_stop[0];
	}

	protected function getCefTimeInfo() 
	{  
		$timeinfo = exec("ceftimeinfo ".$this->fileName);
		return $timeinfo;
	}

	protected function getCefVars() 
	{
		exec('cefinfo '.$this->fileName, $results);
		return $results;
	}

	protected function getCefVarInfo($cdfVarId) 
	{
		exec('cefvarinfo '.$this->fileName." ".$cdfVarId, $results);

		$tempArr = explode(' ', $results[0]);
		// data type
		switch ($tempArr[0]) {
			case "CEF_FLOAT" : $data_type = 'FLOAT';
					break;
			case "CEF_SHORT":  $data_type = 'SHORT';
					break;
			case "CEF_INT":  $data_type = 'INTEGER';
					break;
			case "CEF_DOUBLE": $data_type = 'DOUBLE'; 
					break;
			default : $data_type = 'FLOAT';
			}
		// data dimensions & number of records3
		$n_recs = $tempArr[2];

		if ($tempArr[1] != 0) {		 
			$size = $tempArr[3];
		//TODO 2D,3D,4D array no processing	
		//   if ($tempArr[1] > 1) 
		}
		else {
			$size = 1;		  
		} 
		return array('type' => $data_type, 'size' => $size, 'n_records' => 'TBD');       
	}

	protected function getCefSampling() 
	{
		exec('cefsampling '.$this->fileName, $results);        
		return $results;
	}

/*
*       netCDF format processing if needed
*/
	protected function reformatNcTime() 
	{
		exec('nctimestring2double '.$this->fileName, $results); 
		return $results[0]; 
	}
        
	protected function getNcTimeInfo() 
	{
		exec('nctimeinfo '.$this->fileName, $result); 
		return $result[0];  
	}

	protected function  getNcVars()
	{
		exec('getncvars '.$this->fileName, $result);
		
		if ($result[0] < 0)
			return $result[0];
		$varsArr = explode("#",$result[0]);
	
		return  $varsArr;
	}

	protected function getNcVarInfo($varId) 
	{
		exec('ncvarinfo '.$this->fileName.' '.$this->param2dd($varId), $results);
		$tempArr = explode(' ', $results[0]); 
		// data type
		switch ($tempArr[0]) {
			case "5": $data_type = 'FLOAT';
						break;
			case "3": $data_type = 'SHORT';
						break;
			case "4" : $data_type = 'INTEGER';
						break;
			case "6": $data_type = 'DOUBLE';               
						break;
			default: $data_type = 'FLOAT';
			}
		// data dimensions & number of records
		$n_recs = $tempArr[2];

		if (count($tempArr) > 3) {		 
				$size = $tempArr[3];
		//TODO 2D,3D,4D array no processing	
		//   if ($tempArr[1] > 1) 
		}
		else {
				$size = 1;		  
		}  
		
		$units =  exec('ncvar_attr '.$this->fileName.' '.$this->param2dd($varId).' UNITS');  
		if (substr($units, 0,5) == 'error') $units = '';
		
		$fillval =  exec('ncvar_attr '.$this->fileName.' '.$this->param2dd($varId).' _Fillvalue'); // _Fillvalue
		if (substr($fillval, 0,5) == 'error') $fillval =  exec('ncvar_attr '.$this->fileName.' '.$this->param2dd($varId).' Fillvalue');
		if (substr($fillval, 0,5) == 'error') $fillval =  exec('ncvar_attr '.$this->fileName.' '.$this->param2dd($varId).' Fillval');
		if (substr($fillval, 0,5) == 'error') $fillval = '';
		
		return array('type' => $data_type, 'size' => $size, 'n_records' => $n_recs, 'units' => $units, 'fillvalue' => $fillval);
	}
	
	protected function param2dd($paramID)
	{
		$pairs = array("-" => "_", "%" => "_","\\" => "_","$" => "_",":" => "_","+" =>" _","-" => "_","#" => "_","@" => "_", "." => "_",">" => "_", "<" => "_");    
		return strtr($paramID, $pairs); 
	}

/*
*      ascii format processing
*/    
	protected function getTxtSampling() 
	{		
		$StartTime = null;
		if (!file_exists($this->fileName)) return -100;     
		$i = 0;
		$dt = -10;
		
		$handler = fopen($this->fileName, 'r');
		if ($handler) {
				while (!feof($handler) && !$StartTime) {
						$oneLine = trim(preg_replace('/\s+/', ' ', fgets($handler)));
						$elems = explode(' ', $oneLine);
						if ((strlen($elems[0]) < 16) || !($time = strtotime($elems[0]))) {
								$i++;
								continue;
					}                   
					$StartTime = $time;                    
					if (is_numeric($elems[1])) $dt = $elems[1];  
					//else Array for sure !!!
				}
		}

		if (feof($handler)) return -10;

		$oneLine = trim(preg_replace('/\s+/', ' ', fgets($handler)));
		$elems = explode(' ',$oneLine);

		if (count($elems) < 2) return -10;

		// dT else Array
		if (!($time = strtotime($elems[0]))) {
				return $dt;
		}
		
		return $time  - $StartTime;          
	}

 
	public function getTxtSamplings() 
	{    
		$StartTime = null;
		if (!file_exists($this->fileName)) return array(-100);

		$handler = fopen($this->fileName, 'r');
		if ($handler) {
			$i = 0;
			while (!feof($handler) && !$StartTime) {
						$oneLine = trim(preg_replace('/\s+/', ' ', fgets($handler)));
						$elems = explode(' ',$oneLine);
						if (strlen($elems[0]) < 16 || !($time = strtotime($elems[0]))) { 
									$i++;
									continue;
					}   
			
						$StartTime = $time;
						if (!(is_numeric($elems[1]))) return array(-10); 
						$dt = $elems[1];                  
			} 
		} 
		
		if (feof($handle)) return array(-10);
		$oneLine = trim(preg_replace('/\s+/', ' ', fgets($handler)));
		$elems = explode(' ',$oneLine);
		if (count($elems) < 2) return array (-1);
        // dT else Array
		if (!($time = strtotime($elems[0]))) 
			return array($dt);
		else 
		{
			$minSampling = +1.e31;
			$maxSampling = 0.0;

			while (!feof($handler)) 
			{
				$oneLine = trim(preg_replace('/\s+/', ' ', fgets($handler)));
				$elems = explode(' ',$oneLine);

				if (count($elems) < 2) continue;
				$StartTime = $time;
				if (!($time = strtotime($elems[0]))) return array(-1);                       
				$deltaT[$time  - $StartTime]++;                                       
			}

			foreach ($deltaT as $key => $value) 
			{
							if ($value < 5) continue;
							if ($key < $minSampling) $minSampling = $key;
							if ($key > $maxSampling) $maxSampling = $key;
			} 

	return array($minSampling,$maxSampling); 
		}         
	}

/*
*        Delete comments and convert time into double
*/
	public function reformatTxt() 
	{        
		$StartTime = null;
		if (!file_exists($this->fileName)) return  -100;

		$handler = fopen($this->fileName, 'r');
		if ($handler) 
		{  
			$offset = ftell($handler);
			$i = 0;
			while (!$StartTime && !feof($handler)) 
			{
				$oneLine = trim(preg_replace('/\s+/', ' ', fgets($handler)));
				$elems = explode(' ',$oneLine);

				if (!($time = strtotime($elems[0]))) 
				{
						$offset = ftell($handler);
						$i++;
						continue;
				}            
				$StartTime = $time;
				$dt = $elems[1];
			}  
		}
                 
		$newfile = fopen(USERDATADIR."temp", "w");

		$oneLine = trim(preg_replace('/\s+/', ' ', fgets($handler)));
		$elems = explode(' ',$oneLine);

		// dT
		if (!($time = strtotime($elems[0])))
		{ 
			$newtime = $StartTime;  
			settype($dt, "float"); 
			if ($oneLine != PHP_EOL && count($elems) > 0) fwrite($newfile,  $newtime." ".$oneLine.PHP_EOL);
			$newtime += $dt; 

			while (!feof($handler)) 
			{
				$oneLine = trim(preg_replace('/\s+/', ' ', fgets($handler)));
				if ($oneLine != PHP_EOL && count($elems) > 0) fwrite($newfile,  $newtime." ".$oneLine.PHP_EOL);
				$newtime += $dt;  
			}
		}
		// Array
		else 
		{ 
			fseek($handler, $offset);
			while (!feof($handler)) 
			{
				$oneLine = trim(preg_replace('/\s+/', ' ', fgets($handler)));
				$elems = explode(' ',$oneLine);
				// empty lines
				if (count($elems) < 2) continue;
				$newtime = strtotime($elems[0]); 
				//TODO Error message if wrong time format...???
				if (!$newtime) continue; 
				unset($elems[0]); 
				$newline = join($elems," ");
				fwrite($newfile,$newtime." ". $newline.PHP_EOL);                                   
			}
		}
		fclose($newfile);

		rename(USERDATADIR."temp",$this->fileName);     

		return $StartTime." ".$newtime; 
	}

/*
*  Convert time into ISO
*/
	protected function reformatTime($timeFormat, $timeLength, $doy) 
	{                   
		$formatLength = $timeLength == 'auto' ? strlen($timeFormat) + (strpos($timeFormat,"Y") !== false)*3 + (strpos($timeFormat,"y") !== false)
						+ (strpos($timeFormat,"M") !== false)*2  + (strpos($timeFormat,"m") !== false)
						+ (strpos($timeFormat,"d") !== false) + (strpos($timeFormat,"H") !== false)
						+ (strpos($timeFormat,"i") !== false) + (strpos($timeFormat,"s") !== false) 
						+ (strpos($timeFormat,".u") !== false)*2 : $timeLength;
 
		if (strpos($timeFormat,".u") !== false) 
		{
			$formatLength = $formatLength - 4;
			$timeFormat = substr($timeFormat, 0, strlen($timeFormat)-2);
		}

		if (strpos($timeFormat,".k") !== false) 
		{
			$formatLength = $formatLength - 2;
			$timeFormat = substr($timeFormat, 0, strlen($timeFormat)-2);
		}

		$handle = fopen($this->fileName,'r');
   
		if ($handle) 
		{    
			$newfile = fopen(USERDATADIR."temp", "w");
			while (!feof($handle)) 
			{
				$oneLine = trim(preg_replace('/\s+/', ' ', fgets($handle)));

				if ($oneLine !== false)
				{
					if (strlen($oneLine) > $formatLength)
					{   
						try 
						{
							$date = DateTime::createFromFormat($timeFormat, trim(substr($oneLine,0,$formatLength)));
							if (!$date) 
							{
								if (strpos($oneLine,'#') === 0)  fwrite($newfile, $oneLine.PHP_EOL);
							}
							else 
							{
								// DOY starts from 1
								if ($doy) {
									$date->modify('-1 day');
								}
								$suffix =  preg_replace('/\s+/', ' ',substr($oneLine, $formatLength));
								fwrite($newfile,$date->format('Y-m-d')."T".$date->format('H:i:s').$suffix.PHP_EOL);
							}
						}
						catch (Exception $e) 
						{		  			  
							// fwrite($newfile,$line.PHP_EOL);			   
						}               	       
					} 
					else 
						if (strpos($oneLine,'#') === 0) fwrite($newfile,$oneLine.PHP_EOL);
				}
			}
		}
		else 
		{
			if (file_exists($this->fileName)) 
			{
				fclose($handle); 
				unlink($this->fileName);
			}
			return false;
		}

		fclose($newfile); 
		fclose($handle);

		rename(USERDATADIR."temp", $this->fileName);  
		return true; 
	}
   

/*
*    Returns number of columns in text file to create data model fields in MyDataUI.js 
*/
	protected function getTxtColNumber($timeDouble) 
	{	  
		if (!file_exists($this->fileName)) return  -100;
		$handle = fopen($this->fileName,'r');

		if ($handle) 
		{
			$found = false;
			$i = 0;
			while (($line = trim(fgets($handle))) !== false && $i < 100) 
			{
				$elems = explode(" ", preg_replace('/\s+/', ' ', $line));
				if (count($elems) < 2 || strpos($elems[0], '#') === 0) continue;

				$i++;		
				if (!$timeDouble) 
				{
					if (strlen($elems[0]) >= 16 && ($time = strtotime($elems[0]))) 
					{
						$found = true;
						break; 
					}
				}
				else 
				{
					$found = true;
					break; 
				}
			}

			if (!feof($handle) && !$found) 
			{
				fclose($handle);
				unlink($this->fileName);
				return -1;
			}
		}       
		fclose($handle);

		if (!$found) 
		{
			unlink($this->fileName);
			return 0; 
		}
		
		return count($elems);
	}
    
/*
*      new file tag in Files.xml
*/      
	protected function createSimuFile($format) 
	{              
		$newFile = $this->contentDom->createElement('file');
		$newFile->setAttribute('xml:id', $this->fileId);
		$newFile->setAttribute('name', $this->fileId);
		$newFile->setAttribute('format', $format);

		$start_stop = explode(" ",$this->getVotFileMgr()->getStartStop());
		$samplings = $this->getVotFileMgr()->getSamplings();
		$minSamp = $samplings["minSampling"];
		$maxSamp = $samplings["maxSampling"];
		$desc = $this->getVotFileMgr()->getDescription();

		$start =  $start_stop[0];
		$stop =  $start_stop[1];
                
		$newFile->setAttribute("start",$start);
		$newFile->setAttribute("stop",$stop);
		$newFile->setAttribute('minsampling',$minSamp);
		$newFile->setAttribute('maxsampling',$maxSamp);
		$newFile->setAttribute('uploaded', date('Y-m-d H:i:s'));
		  
		// generic MASK without datas for simu params
		if ((strncmp($this->fileId, "impex___", 8) == 0) || (strncmp($this->fileId, "spase___", 8) == 0))
			$newFile->setAttribute('mask', $this->getGenericMask());

		$newFile->nodeValue = date('Y-m-d',$start)."T".date('H:i:s',$start)."-".date('Y-m-d',$stop)."T".date('H:i:s',$stop);
		if ($desc != '')
				$newFile->nodeValue .= (PHP_EOL.$desc);
				
		return $newFile;   
	}


	protected function createFile($format, $samplingType) 
	{              
		$newFile = $this->contentDom->createElement('file');
		$newFile->setAttribute('xml:id', $this->fileId);
		$newFile->setAttribute('name', $this->fileId);
		$newFile->setAttribute('format', $format);
		
		$minSamp = $this->sampling;
		$maxSamp = $this->maxSampling;
		
		switch ($format)
		{
			case "cdf":  
					$start_stop = explode(" ",$this->getCdfStartStop());
					if ($minSamp < 0) {
						if ($samplingType == 'constant') {
							$result = $this->getCdfSampling();
							//TODO process errors
							$minSamp = $result[count($result)-1];
							$maxSamp =  $minSamp;
						} else {
							// $result = $this->getCdfSamplings();
						}
					}
				break;            
			case "txt":   
					$start_stop =  explode(" ",$this->reformatTxt());
					if ($start_stop[0] < 0)  return $start_stop;
					$minSamp = $this->sampling;
					$maxSamp = $this->maxSampling;
				break; 
			case "cef":
					// Test if 'standard' meta exist in CEF
					$cefMetaTest = $this->getCefStartStop(); 

					if ($cefMetaTest != -1) {
						$cefStartStop = explode("/",$cefMetaTest); 
						$start_stop[] = strtotime($cefStartStop[0]);
						$start_stop[] = strtotime($cefStartStop[1]); 			   
						$result = $this->getCefSampling();
						$minSamp = $result[count($result)-1];
					}
					else {
						// no META data - so time processing
						$timeInfo = $this->getCefTimeInfo();
						$timeInfoArr = explode(" ", $timeInfo);
						$start_stop[] =  $timeInfoArr[0];
						$start_stop[] =  $timeInfoArr[1];
						$minSamp = $timeInfoArr[2];
					}
					//TODO if min & max
					$maxSamp =  $minSamp;
				break;
			case "vot" :
					$start_stop = explode(" ",$this->getVotFileMgr()->getStartStop());
					$samplings = $this->getVotFileMgr()->getSamplings();
					if ($minSamp < 0) { 
						$minSamp = $samplings["minSampling"];
						$maxSamp = $samplings["maxSampling"];
					}
					$desc = $this->getVotFileMgr()->getDescription();
				break;  
			case "nc":  
					$ncInfo = $this->getNcTimeInfo();
					if ($ncInfo < 0) {
							unlink($this->fileName);
							return $ncInfo;
					}
					$ncInfoArr = explode("#",$ncInfo);
					$start_stop = explode(":",$ncInfoArr[0]);
					if ($minSamp < 0) {
						//TODO process errors
						$minSamp = $ncInfoArr[1];
						//TODO if min & max
						$maxSamp =  $minSamp;
					}
				break;   
			default: 
		}
		$start =  $start_stop[0];
		$stop =  $start_stop[1];
					
		$newFile->setAttribute("start",$start);
		$newFile->setAttribute("stop",$stop);
		$newFile->setAttribute('minsampling',$minSamp);
		$newFile->setAttribute('maxsampling',$maxSamp);
		$newFile->setAttribute('uploaded', date('Y-m-d H:i:s'));
		  
		// generic MASK without datas for simu params		  
		if ((strncmp($this->fileId, "impex___", 8) === 0) || (strncmp($this->fileId, "spase___", 8) === 0))
			$newFile->setAttribute('mask', $this->getGenericMask());
		else
			$newFile->setAttribute('mask', $this->fileId);

		$newFile->nodeValue = date('Y-m-d',$start)."T".date('H:i:s',$start)."-".date('Y-m-d',$stop)."T".date('H:i:s',$stop);
		if (!empty($desc))
			$newFile->nodeValue .= (PHP_EOL.$desc);
		
		return $newFile;   
	}
     
	protected function getGenericMask() 
	{
		if (strncmp($this->fileId, "impex___", 8) == 0) {
			$prefix = "impex___";
			$tmpFileName = str_replace ("impex___", "", $this->fileId);
		}
		elseif (strncmp($this->fileId, "spase___", 8) == 0) {
			$prefix = "spase___";
			$tmpFileName = str_replace ("spase___", "", $this->fileId);
		}
		$tmpFileArray = explode( '.', $tmpFileName);
		$tmpParamArray = explode( '_', $tmpFileArray[0]);
		array_pop($tmpParamArray);
		array_pop($tmpParamArray);
		$tmpName =  implode("_", $tmpParamArray);
		
		$mask = $prefix.$tmpName."_*.xml";
		return $mask;
	}

/*
//TODO  check how to upgrade this
*/
	protected function getFormat() 
	{         
		$ext = pathinfo($this->fileName, PATHINFO_EXTENSION);   

		if (PHP_VERSION_ID < 50300) 
		{
			$finfo = new finfo(FILEINFO_MIME, MAGIC_FILE);    
			$file_info =   explode(";", $finfo->file($this->fileName));
		}
		else 
		{
			// PHP v >= 5.3 comes with its own magic file  !!!!   
			$finfo = finfo_open(FILEINFO_MIME); 
			$file_info =  explode(";",finfo_file($finfo, $this->fileName));
		}

		if (strpos($file_info[0],"plain") !== false) 
		{
			if (strpos($ext,"cef") !== false) return "cef";
			return "txt";
		}

		if (strpos($file_info[0],"application/x-gzip") !== false) 
		{
			if (strpos($this->fileName,"cef.gz") !== false) return "cef";  
		}

		if (strpos($file_info[0],"application/xml") !== false)
		{
			//if ($this->getVotFileMgr()->isValidSchema()) //BRE : No schema validation for the moment due to some trouble with Topcat (it can create not valid VOTable)
			return "vot";
		}
	
		// check binary at different machines - if it works.....
		if (strpos($file_info[0],"octet-stream") !== false) 
		{
			if (strpos($ext,"cdf") !== false) return "cdf"; 
			if (strpos($ext,"nc") !== false) return "nc";		
		}
		
		return "unknown";      
	}

/*
*         PUBLIC FUNCTIONS
*/     
	public function getAsciiFile($name) 
	{ 
		$this->fileName = USERDATADIR.$name;

		if (!file_exists(USERDATADIR.$name)) 
			return  array('success' => false, 'error' => 'No such file');
 	 
		$handle = fopen($this->fileName, "r");
		$fileToReturn = array();
		$index = 0;
		$tempFileToReturn =  array();

		while (!feof($handle)) 
		{
			$line = trim(fgets($handle));
			$tempArr = explode(' ', preg_replace('/\s+/', ' ', $line));
			if (count($tempArr) > 1) 
			{
				for ($i = 0; $i < count($tempArr); $i++) 
				{
					$name = $i === 0 ? 'Time' : 'n'.$i;
					//transform double time to ISO
					if ($name == 'Time') 
					{
						$temp = $tempArr[0];
						settype($temp, 'double');
						$tempArr[0] = date('Y-m-d H:i:s', $temp);
					}
					$tempFileToReturn[$name] = $tempArr[$i];
				}
				
				$fileToReturn[$index] = $tempFileToReturn;
				$index++;
				if ($index > MAX_FILE_INDEX_TO_SHOW) break;
			}
		}
		return $fileToReturn;
	}
/*
*     Get  info on parameter
*/
	public function getParamInfo($obj)
	{
		$this->fileName = USERDATADIR.$obj->file;
		$varId = $obj->varName;
		$format = $obj->format;

		// at first info from Files.xml
		$file = $this->contentDom->getElementById($obj->file);
		if ($file) 
		{
			if ($file->parentNode->tagName == 'folder') 
				$mask = $file->parentNode->getAttribute('name');
			else 
				$mask = $file->getAttribute('mask');
				
			$dom_info =  array( 'name' => $varId,
							'minsampling' => $file->getAttribute('minsampling'),
							'maxsampling' => $file->getAttribute('maxsampling'),
							'mask' => $mask);		 
		}
		else 
		{
			if ($format == "nc")
			{ 
				$status = $this->reformatNcTime();
				if ($status <= 0) 
				{
					unlink($this->fileName);
					return array('success' => false, 'error' => 'error '.$timeFormat.PHP_EOL.'Time Format problem');	
				}
				$ncInfo = $this->getNcTimeInfo(); 
				$ncVars = $this->getNcVars();
				
				if ($ncInfo < 0) 
				{
					unlink($this->fileName);
					return $ncInfo;
				}
				
				$ncInfoArr = explode("#",$ncInfo);
				$start_stop = explode(":",$ncInfoArr[0]);			   
				//TODO process errors
				$minSamp = $ncInfoArr[1];
				//TODO if min & max
				$maxSamp =  $minSamp;
			      
				$dom_info =  array( 'name' => $varId,
								'minsampling' => $minSamp,
								'maxsampling' => $maxSamp,
								'mask' => $obj->mask);	
			}
		}

		switch ($format)
		{
			case "cdf":  
				$info = $this->getCdfVarInfo($varId);			      
				break;   
			case "txt":   			  
				break; 
			case "cef":   
				$info = $this->getCefVarInfo($varId);
				break; 
			case "nc":  
				$info = $this->getNcVarInfo($varId);
				break;
			case "vot":
				$info = $this->getVotFileMgr()->getFieldInfoByID($varId);
				break;
			default: 

		}
		return  array('success' => true, 'info' => array_merge($dom_info,$info));
	}

 
	public function deleteObject($obj) 
	{
		$myBaseManager = new BaseManager();
  
		$paramMgr = new DerivedParamMgr('myDataParam');                
		$xpd = new domxpath($paramMgr->contentDom); 

		//File, not a folder
		if ($obj->leaf) 
		{  
			$this->fileName = USERDATADIR.$obj->id;

			if (file_exists($this->fileName)) 
					unlink($this->fileName);

			$theFile = $this->contentDom->getElementById($obj->id);               
			// Update data base	                   
			$fileInBase = $myBaseManager->xp->query("//file[@name='".$obj->id."']");
 
			if ($fileInBase->length > 0) 
			{ 
				$viInfo = $myBaseManager->delFile($fileInBase->item(0));

				$mask = $viInfo['mask'];
				$length = $viInfo['length'];
			
				$params = $xpd->query("//mydata[@mask='".$mask."']"); 

				if ($params->length > 0) 
				{  
					// NO FILES in the mask;  corresponding parameters are to be deleted
					if ($length == 0) 
					{
						$paramsToDelete = array();
						for ($i = $params->length; --$i >= 0; )
						{
							$id = $params->item($i)->getAttribute('xml:id');
							$paramMgr->deleteParameter($id);
							$paramMgr->deleteFromContent($params->item($i));
							$paramsToDelete[] = $id;
						}                                       
					}
					// update params description in Content Dom
					else 
					{
						$vi = $myBaseManager->getVi($mask);   
						$desc =  $myBaseManager->getStartStop($vi);
						foreach ($params as $param) $param->setAttribute("desc",$desc); 
						$paramMgr->saveContent();
					}				  		
				}                
			}  
			// WS/Files.xml
			if ($theFile) 
			{
				if (isset($desc)) 
						$theFile->parentNode->setAttribute('info', $desc);
				$theFile->parentNode->removeChild($theFile);               
				$this->contentDom->save($this->xmlName); 
			}
		}
		// Folder
		else 
		{
			$mask = $obj->id;
			$theMask = $this->contentDom->getElementById($obj->id);
			$files = $theMask->getElementsByTagName('file');

			foreach ($files as $file) 
			{
				$fileName = USERDATADIR.$file->getAttribute('name');  	  
				if (file_exists($fileName)) unlink($fileName); 
			}

			$this->deleteFromContent($theMask); 
			$myBaseManager->delVI($mask);  

			$params = $xpd->query("//mydata[@mask='".$mask."']");  
			$paramsToDelete = array();
			for ($i = $params->length; --$i >= 0; ) 
			{
				$id = $params->item($i)->getAttribute('xml:id');
				$paramMgr->deleteParameter($id);
				$paramMgr->deleteFromContent($params->item($i));
				$paramsToDelete[] = $id;
			}
		}
		// No more files for myDataParams	
		if (isset($paramsToDelete)) 
				return array('id' => $obj->id, 'params' => $paramsToDelete);

		// update info for myDataParams Start Stop were changed
		return  array('id' => $obj->id, 'mask' => isset($mask) ? $mask : NULL, 'maskDesc' => isset($desc) ? $desc : NULL);
	}
         
/*
*      recombine files in Files.xml according to new Mask
*/
	public function addMask($fileMask) 
	{ 
		if ($this->contentDom ->getElementById($fileMask) != null) return false; 
		$filesInRoot = $this->xp->query("/ws/fileList/file");                                   
		$newMask = $this->contentDom->createElement("folder");
		$newMask->setAttribute('xml:id', $fileMask);
		$newMask->setAttribute('name', $fileMask);
     
		for ($i =  $filesInRoot->length; --$i >= 0;)  
		{
			$aFile =  $filesInRoot->item($i);  
			// mask corresponds to file name		 
			if ($this->fileMask($aFile->getAttribute("name"),$fileMask))
			{                          
				$newMask->appendChild($aFile); 
			}                          
		}

		$files = $newMask->getElementsByTagName("file");
		if ($files->length == 0) return false;
 
		foreach ($files as $file) 
		{
			$starts[] =  $file->getAttribute("start");
			$stops[] =  $file->getAttribute("stop");
		}
 
		$newMask->setAttribute('info',date('Y-m-d',min($starts))."T".date('H:i:s',min($starts))."-".date('Y-m-d',max($stops))."T".date('H:i:s',max($stops)));

		$fileList = $this->contentDom->getElementById($this->contentRootId);
	      
		$fileList->appendChild($newMask);
		$this->contentDom->save($this->xmlName); 
		return true;
	}

/*
*    check correspondence FleName <=> Mask
*    returns true if Mask fits FileName
*/
	public function fileMask($fileName, $maskName) 
	{    
		$mask = explode("*", $maskName); 
		if (strpos($fileName, $mask[0]) !== 0) return false; 
		if (count($mask) == 1) return true;

		for ($i = 1; $i < count($mask); $i++)  
			if ($mask[$i] != null)
				if (strpos($fileName, $mask[$i]) === false) return false;  

		return true;
	} 

/*
*    Delete Mask
*/
	public function delMask($oldMask) 
	{ 
		$mask = $this->contentDom->getElementById($oldMask);

		if ($mask != null && $mask->tagName == "folder") 
		{                                                                                                               
			$filesInMask = $mask->getElementsByTagName("file");
			$fileList = $this->contentDom->getElementById($this->contentRootId); 

			while ($filesInMask->length > 0) 
				$fileList->appendChild($filesInMask->item(0));
					
			$fileList->removeChild($mask); 
			$this->contentDom->save($this->xmlName);

			return true;
		}

		return false;
	}

/*
*     mask or file
*/
	public function getObject($name) 
	{
		$object = $this->contentDom->getElementById($name);
		
		if (is_object($object)) 
		{   
			// mask
			if ($object->tagName == 'folder') 
			{
				$file = $object->getElementsByTagName('file');
				if ($file->length > 0) 
					return $this->getUploadedObject($file->item(0)->getAttribute('name'));
				else 
					return array('success' => false, 'error' => 'Mask is empty');
			}
		}
		else 
			return array('success' => false, 'error' => 'No such mask in DOM');
		// file
		return $this->getUploadedObject($name);
	}

/*
*  Get generic info on uploaded file
*/
	public function getUploadedObject($name) 
	{
		$this->fileName = USERDATADIR.$name;
		$file = $this->contentDom->getElementById($name);
		if (!$file) 
				return array('success' => false, 'error' => 'No such file in DOM');

		$format = $file->getAttribute('format');
		$minSamp =  $file->getAttribute('minsampling');
		$maxSamp =  $file->getAttribute('maxsampling');

		$mask = $file->parentNode->tagName  == "folder" ? $file->parentNode->getAttribute("name") : null;
		$maskDesc = $mask ? $file->parentNode->getAttribute('info') : null;
		$desc = $file->nodeValue;
		
		$foundTime = true;
                
		switch ($format)
		{
			case "cdf":  
							$vars = $this->getCdfVars(); 
							break;            
			case "txt":   
							$vars = $this->getTxtColNumber(true);                                 
							break; 
			case "nc" :
							$vars = $this->getNcVars();
							break;
			case "cef":   
							$vars = $this->getCefVars(); 
							break;
			case "vot" :
							$vars = $this->getVotFileMgr()->getFieldsInfo();
							$foundTime = ($this->getVotFileMgr()->getTimeFieldIndex() > -1);
							break;          
			default: 
		}

			return  array('success' => true, 'format' => $format, 'vars' => $vars, 'fileName' => $name, 
							'minsampling' => $minSamp, 'maxsampling' => $maxSamp, 'mask' => $mask, 'maskDesc' => $maskDesc,
							'description' => $desc, 'foundTime' => $foundTime);
	}

/*
*      The very first processing of newly uploaded file file
*      $formats = array('fileFormat', 'timeFormat', 'timeSampling', 'nonStandard', 'doy');
*/
	public function addFile($fileName, $formats) 
	{  
		$this->fileName = USERDATADIR.$fileName;
		$this->fileId = $fileName;

		$format = $this->getFormat();

		if ($format === 'unknown') { 	           
			unlink($this->fileName);                   
			return array('success' => false, 'error' => 'Sorry, unknown format of '.$fileName);	
		}

		// if sampling is defined by user
		if ($formats["samplingType"] == "manual") {
			$this->sampling = $formats["min_sampling"];
			if ($formats["max_sampling"])
				$this->maxSampling = $formats["max_sampling"];
			else
				$this->maxSampling = $this->sampling;
		}
		
		
		if ($format == 'txt') 
		{  
			if ($formats["timeFormat"] == "user") {
				$res =  $this->reformatTime($formats["nonStandard"], $formats["timeLength"], $formats["doy"]);

				if (!$res) {
					unlink($this->fileName); 
					return array('success' => false, 'error' => 'can\'t reformat time'); 
				}
			}
			// check if file is not empty
			$vars = $this->getTxtColNumber(false);

			if ($vars == -100) {
					return array('success' => false, 'error' => 'no such file');
			}
			
			if ($vars == -1) { 
					unlink($this->fileName); 
					return array('success' => false, 'error' => 'while reading file');
			}

			if ($vars === 0) {
					unlink($this->fileName);
					return array('success' => false, 'error' => 'file contains no data');
			}
			
			// sampling is to be defined automatically
			if ($this->sampling < 0) {
				if ($formats["timeSampling"] == "constant") {          
					$this->sampling = $this->getTxtSampling();	 
					$this->maxSampling = $this->sampling;
				}
				else {
					$samplings = $this->getTxtSamplings();
					$this->sampling = $samplings[0];
					$this->maxSampling = $samplings[1];
				}

				if ($this->sampling <= 0) {  
						unlink($this->fileName); 
						if ($this->sampling == -10) {
								return array('success' => false, 'error' => 'Sorry, can\'t process'.$fileName.PHP_EOL.'. Check if there are non numeric chars in the data');
						}
						return array('success' => false, 'error' => 'Sorry, can\'t process Time for '.$fileName.PHP_EOL.'. Check time format, start time (> 1970-01-01) or sampling time (>= 1s)');		           
				}
			}
		}

		if ($format == 'nc')
		{  
			$status = $this->reformatNcTime();
			if ($status <= 0) {
				unlink($this->fileName);
				return array('success' => false, 'error' => 'error '.$timeFormat.PHP_EOL.'Time Format problem');	
			}
		}

		//create new file tag with all attributes and add it to the content DOM   
		$newFile = $this->createFile($format, $formats["timeSampling"]);
		if (is_int($newFile) && ($newFile < 0)) { 
			unlink($this->fileName);
			return array( 'success' => false, 'file' => $fileName);
		}

		$isMask = false;
		$masks = $this->contentDom->getElementsByTagName("folder");
 
		foreach ($masks as $mask) 
		{
			$folderMask =  $mask->getAttribute("name");  
			if ($this->fileMask($fileName, $folderMask)) 
			{                                                      
				$mask->appendChild($newFile);
				
				$files = $mask->getElementsByTagName("file");
				
				foreach ($files as $file) {
					$starts[] = $file->getAttribute("start");
					$stops[] =  $file->getAttribute("stop");
				}
				$mask->setAttribute("info", date('Y-m-d',min($starts))."T".date('H:i:s',min($starts))."-".date('Y-m-d',max($stops))."T".date('H:i:s',max($stops)));
				
				$isMask = true;
				break;
			}	
		}                     
		// no corresponding masks => add to fileList      
		if (!$isMask) {					  
			$filesList = $this->contentDom->getElementById($this->contentRootId); 
			$filesList->appendChild($newFile);
		}        
     
		$this->contentDom->save($this->xmlName);

		//if mask exists - add to data base
		$myBaseManager = new BaseManager();
		$mask = $myBaseManager->addFile($fileName); 
		if ($mask != null) {
			$startstop = $myBaseManager->getStartStop($myBaseManager->getVi($mask));
			$myParamMgr = new DerivedParamMgr('myDataParam');
			$myParamMgr->updateMydata($mask,$startstop);      
		}

		return array( 'success' => true, 'file' => $fileName);
	}
	
	public function setFileName($name) 
	{     
		$this->fileName = USERDATADIR.$name;
	}
}
?>