<?php
/**  
*     @class BaseManager
*     @brief Management of user uploaded data files in data base
*     @author Elena
*     @version $Id: BaseManager.php 2914 2015-05-19 10:31:38Z elena $
*    
*/
 
class BaseManager {

    public $xp, $xslt;
    public $baseDom; 
    private $fileDomName, $baseDomName;

    function __construct() 
    {  
        if (getenv('USER_DATA_PATH') != "")
            $this->baseDomName = getenv('USER_DATA_PATH')."base.xml";
        else 
            $this->baseDomName = USERDATADIR."base.xml";

        $this->fileDomName = USERWSDIR."Files.xml";
        $this->baseDom =  new DomDocument("1.0");

        if (file_exists($this->baseDomName)) 
                $this->baseDom->load($this->baseDomName);
        else {
            $baseElement = $this->baseDom->createElement("base");
            $this->baseDom->appendChild($baseElement);
        } 
  
        $this->xp = new domxpath($this->baseDom);    
        $this->xslt = new XSLTProcessor();

        $xsl = new DomDocument("1.0");
        $xsl->load(XMLPATH."base.xsl");

        $this->xslt->importStylesheet($xsl);
      }

/*
*   Provide an unique ID
*/
    public function getNewId() 
    {
        //  Get all ID attributes
        $vis = $this->xp->query("//vi/@id");
 
        if ($vis->length > 0) {
                $idList = array();
                if($vis->length > 0) for ($i = 0; $i < $vis->length; $i++) 
                                                $idList[] = $vis->item($i)->nodeValue;                 
                sort($idList);

                for ($i = 0; $i < count($idList); $i++) {
                    if ($idList[$i] > $i) { 
                                $newID = $i;
                                break;
                        }  
                        $newID = $i+1;  
                    }                 
            } else
                $newID = 0; 

       return $newID;
    }
    
    public function fileMask($fileName, $maskName) 
    {
        $mask = explode("*", $maskName);
         
        for ($i = 0; $i < count($mask); $i++)  
          if ($mask[$i] != null)
             if (strpos($fileName, $mask[$i]) === false) return false;  
         return true;
     }

/*
*    new file is uploaded -> check if it should be added into MASK 
*/
    public function addFile($fileName) 
    {
        $fileDom = new DomDocument("1.0");
        $fileDom->load($this->fileDomName);       
        $file = $fileDom->getElementById($fileName); 
        $lastMask = null; 
        
        $masks = $this->baseDom->getElementsByTagName("mask");

        if ($masks->length > 0) 
        {
            foreach ($masks as $mask)                       
                if ($this->fileMask($fileName, $mask->nodeValue)) 
                {
                    $lastMask = $mask->nodeValue;

                    $newFile = $this->baseDom->createElement("file");              
                    $newFile->setAttribute('name', $fileName);			
                    $start = $file->getAttribute('start');
                    $stop = $file->getAttribute('stop');
                    $newFile->setAttribute('start', $start);
                    $newFile->setAttribute('stop', $stop);

                    $vi = $mask->parentNode;
                    $vi->appendChild($newFile);

                    $vi_start = $vi->getAttribute('start');
                    if ($vi_start > $start) $vi->setAttribute('start',$start);
                    $vi_stop = $vi->getAttribute('stop');
                    if ($vi_stop < $stop) $vi->setAttribute('stop',$stop);                          
                } 
        } 

        $this->xslt->transformToDoc($this->baseDom)->save($this->baseDomName);
                              
        return $lastMask;           
      }

/*
*       special add method for "simulation" files
*/      
    public function addWsFile($fileName, $start, $stop) 
    {
        // add file description to base.xml file
        $masks = $this->baseDom->getElementsByTagName("mask");

        if ($masks->length > 0) 
        {
            foreach ($masks as $mask)                       
                if ($this->fileMask($fileName, $mask->nodeValue)) 
                {
                    $lastMask = $mask->nodeValue;
                    $newFile = $this->baseDom->createElement("file");              
                    $newFile->setAttribute('name', $fileName);			
                    $newFile->setAttribute('start', $start);
                    $newFile->setAttribute('stop', $stop);
                    $vi = $mask->parentNode;
                    $vi->appendChild($newFile);

                    $vi_start = $vi->getAttribute('start');
                    if ($vi_start > $start) $vi->setAttribute('start',$start);
                    $vi_stop = $vi->getAttribute('stop');
                    if ($vi_stop < $stop) $vi->setAttribute('stop',$stop);                          
                } 
        }
 
        $this->xslt->transformToDoc($this->baseDom)->save($this->baseDomName);
                              
        return $lastMask;           
    }

/*
*        File was deleted
*/
    public function delFile($fileObj) 
    {                            
            $start = $fileObj->getAttribute($start);
            $stop = $fileObj->getAttribute($stop);
            $vi =  $fileObj->parentNode;                                                                                   
            $vi->removeChild($fileObj);
            $mask = $vi->getElementsByTagName("mask")->item(0)->nodeValue;
            $length = $vi->getElementsByTagName("file")->length;

            if ($length == 0) 
            {               
                $this->baseDom->getElementsByTagName("base")->item(0)->removeChild($vi);
            }  
            else  
            {                           
                 $vi->setAttribute('start', $this->updateStart($vi));            
                 $vi->setAttribute('stop',$this->updateStop($vi)); 
             } 

            $this->baseDom->save($this->baseDomName); 
 
          return array('mask' => $mask, 'length' => $length);
      }

/*
*      Delete simu VI and simu Download Files
*/
    public function delSimuFiles($data)
    {
        if (file_exists(USERWSDIR.'WsParams.xml')) 
        {
            $simuVIs = $this->xp->query("//vi[@moreData = 'true']"); 
            $dom = new DomDocument("1.0");
            $dom->load(USERWSDIR.'WsParams.xml'); 
            $xp = new domxpath($dom); 
	    $dataList = $data.'List';
            $mysimudataList = $dom->getElementsByTagName($dataList);
            foreach ($simuVIs as $simuVI)
                {
                    $files = $simuVI->getElementsByTagName('file');
                    foreach ($files as $file) 
                    {	 
                        $fileName = $file->getAttribute('name');
                        if (file_exists(USERDATADIR.$fileName)) unlink(USERDATADIR.$fileName);
                    } 
                    $vi =  $simuVI->getAttribute("id");
		    $mask = $simuVI->getElementsByTagName('mask')->item(0)->nodeValue; 
		    if ((strpos($mask, 'CLWEB_') !== false && $data == "mywsrdata") || (strpos($mask, 'CLWEB_') === false && $data == "mysimudata")) { 
		    $mysimdata = $xp->query("//".$data."[@mask='".$mask."']/@*[namespace-uri()='http://www.w3.org/XML/1998/namespace' and local-name()='id']");
		    $sumuParamName = $mysimdata->item(0)->nodeValue;
                    $base = $simuVI->parentNode;   
                    $base->removeChild($simuVI);
 
                    if (file_exists(USERWSDIR.$sumuParamName.'.xml'))
                                    unlink(USERWSDIR.$sumuParamName.'.xml');
		    }
                }

                $mysimudata = $xp->query("//".$data.""); 

                if ($mysimudata->length > 0)
                {
                    foreach($mysimudata as $simudata)
                                    $mysimudataList->item(0)->removeChild($simudata);
                } 
                
                $dom->save(USERWSDIR.'WsParams.xml');
                $this->baseDom->save($this->baseDomName);
        }

      return;
     }

/*
*
*/      
    public function updateStart($vi) 
    {        
        $files = $vi->getElementsByTagName("file");
        if ($files->length == 0) return "EMPTY";

        $starts = Array();
        foreach ($files as $file) 
                $starts[] =  $file->getAttribute("start");

        return  min($starts);
     }

/*
*
*/   
    public function updateStop($vi) 
    {    
        $files = $vi->getElementsByTagName("file");
        if ($files->length == 0) return "EMPTY";

        $stops = Array();
        foreach ($files as $file) 
                $stops[] =  $file->getAttribute("stop");

        return  max($stops);
     }
     
/*
*     New mask was added  
*/
    public function appendFiles($newVi, $fileMask) 
    {
        $fileDom = new DomDocument("1.0");
        $fileDom->load($this->fileDomName);
        $files = $fileDom->getElementsByTagName("file");

        if ($files->length > 0) 
        {
            $starts = Array();
            $stops = Array();

            foreach ($files as $file) 
            {
                $fileName = $file->getAttribute("name"); 
                if ($this->fileMask($fileName, $fileMask)) 
                {
                    $newFile = $this->baseDom->createElement("file");              
                    $newFile->setAttribute('name', $fileName);
                    $start = $file->getAttribute("start");
                    $stop = $file->getAttribute("stop");
                    $newFile->setAttribute('start', $start);
                    $newFile->setAttribute('stop', $stop);
                    $newVi->appendChild($newFile);
                    $starts[] = $start;
                    $stops[] = $stop;
                } 
            } 

            $newVi->setAttribute("start", min($starts));
            $newVi->setAttribute("stop", max($stops));
        }                          
      }

/*
*       
*/
    public function getOldMask($fileMask) 
    {               
        $masks = $this->baseDom->getElementsByTagName("mask");
        
        if ($masks->length > 0) 
        {
            foreach ($masks as $mask) {
                // mask exists  
                if (strcmp($mask->nodeValue, $fileMask) == 0) return null;                            
                
                if (strncmp($mask->nodeValue, $fileMask, 5) == 0) 
                {                               
                    // less common
                    if (strlen($mask->nodeValue) <= strlen($fileMask)) return null;
                    // more common - delete old, create new                                                               
                    return $mask->nodeValue;                                                                                                                       
                } 
            }
        }
        return null;
    }

/*
*       
*/
     public function addVI($fileMask, $format) 
    {                                                             
        $newVi = $this->baseDom->createElement("vi");
        $newId = $this->getNewId();
        $newVi->setAttribute('id', $newId);
        if ($format == 'txt') $format = 'ascii';
        $newVi->setAttribute('format', strtoupper($format));
        $newVi->appendChild($this->baseDom->createElement("mask",$fileMask)); 
        $this->appendFiles($newVi, $fileMask);
        
        $this->baseDom->getElementsByTagName("base")->item(0)->appendChild($newVi); 
        /* SORT files by Start Time */         
        $this->xslt->transformToDoc($this->baseDom)->save($this->baseDomName); 

        return $newId;            
      }

/*
*       
*/      
    public function addSimuVI($p)
    {
            $newVi = $this->baseDom->createElement("vi");
            $newId = $this->getNewId();
            $newVi->setAttribute('id', $newId);
            $newVi->appendChild($this->baseDom->createElement("mask",$p->mask)); 
            $newVi->appendChild($this->baseDom->createElement("param",$p->name)); 
            $newVi->setAttribute("start", $p->start);
            $newVi->setAttribute("stop", $p->stop);
            $newVi->setAttribute("moreData", "true");
            
//               $this->appendFiles($newVi, $fileMask);
            $newFile = $this->baseDom->createElement("file");
            $newFile->setAttribute('name', $p->file);
            $newFile->setAttribute('start', $p->start);
            $newFile->setAttribute('stop', $p->stop);
            $this->baseDom->getElementsByTagName("base")->item(0)->appendChild($newVi);

            if (strpos($p->mask,'___CCMC_')=== FALSE){
                $arguments = $this->baseDom->createElement("arguments");
                
                foreach ($p->args[$p->name] AS $key => $val) {
                  $arguments->appendChild($this->baseDom->createElement($key,$val)); 
                }
                $newVi->appendChild($arguments);
              } 
             
            $newVi->appendChild($newFile);
//          $this->baseDom->getElementsByTagName("base")->item(0)->appendChild($newFile); 
            /* SORT files by Start Time */         
            $this->xslt->transformToDoc($this->baseDom)->save($this->baseDomName); 
        return $newId;            
      }

    public function delVI($fileMask) 
    {          
           $vi = $this->xp->query("//vi[mask='".$fileMask."']");

           if ($vi->length > 0) 
                    $vi->item(0)->parentNode->removeChild($vi->item(0));

           $this->baseDom->save($this->baseDomName); 
    } 

    public function getVI($fileMask) 
    {
        $vi = $this->xp->query("//vi[mask='".$fileMask."']");

        if ($vi->length > 0) 
                    return $vi->item(0)->getAttribute("id");

        return -1;
     }
     
    public function existsSimuMask($start,$stop,$mask)
    {
        $vi = $this->xp->query("//vi[mask='".$mask."' and @start<=".$start." and @stop>=".$stop."]");

        if ($vi->length > 0) 
                    return true;
        else 
                    return false;
    }
    
    public function existsWsrMask($start,$stop,$mask)
    {
        $vi = $this->xp->query("//vi[mask='".$mask."' and @start<=".$start." and @stop>=".$stop."]");

        if ($vi->length > 0) 
                    return true;
        else 
                    return false;
    }

    public function intervalsToGet($requestStart, $requestStop, $mask)
    {       
        $vis = $this->xp->query("//vi[mask='".$mask."']");
        if ($vis->length == 0)  return false;

        $vi = $vis->item(0);
        $files = $vi->getElementsByTagName('file'); 

        $start = array();
        $stop = array();

        $globalStart = (int)$vi->getAttribute("start");
        $globalStop = (int)$vi->getAttribute("stop");

        if ($requestStart > $globalStop  ||  $requestStop < $globalStart)  
        {  
            $start[] = $requestStart; 
            $stop[]  = $requestStop;  
        }                
        else
        { 
             if ($requestStart < $globalStart - DELTA ) {
                      $start[] = $requestStart;
                      $stop[] = $globalStart;
            }

            if ($requestStop > $globalStop + DELTA ) {
                      $start[] = $globalStop;
                      $stop[] = $requestStop;
            } 
   
            for ($i = 0; $i < $files->length; $i++)      
                if ((int)$files->item($i)->getAttribute("stop") >= $requestStart) break;
  
            for ($j = $i; $j < $files->length; $j++)  
                if ((int)$files->item($j)->getAttribute("start") >= $requestStop) break;
   
            $d = $j+1 < $files->length -1  ? $j+1 : $files->length - 1;
 
            for ($k = $i; $k < $d ; $k++) {
                $stopT = (int)$files->item($k)->getAttribute("stop");
                $startT = (int)$files->item($k+1)->getAttribute("start");
                if ($startT - $stopT > DELTA) {         
                    $start[] = $stopT;
                    $stop[] = $startT;         
                }
            }
        }
                       
      return array('start' => $start, 'stop' => $stop);
    }

     public function getStartStopParam ($start,$stop,$mask) {
        $vi = $this->xp->query("//vi[mask='".$mask."']");
        $isData = $this->xp->query("//vi[mask='".$mask."' and @start<=".$start." and @stop>=".$stop."]");
        
        if ($isData->length > 0) 
		    return true;
        else {
        if ($vi->length > 0) {
	    $viStart = $vi->item(0)->getAttribute('start');
	    $viStop  = $vi->item(0)->getAttribute('stop');
	    if ($start < $viStart){
	      if (($viStart - $start) > 60){
		  $newStart = $start; 
		  $newStop  = $viStart;
		}
	    }
	    elseif ($start >= $viStop){
	      $newStart = $start; 
	      $newStop  = $stop;
	    }
	    elseif (($start = $viStart) && ($stop > $viStop)){
	      $newStart = $viStop;
	      $newStop  = $stop;
	    }
	    else {
	      if ($stop <= $viStart){
		$newStart = $start; 
		$newStop  = $stop;
		}
	      elseif ($stop > $viStop){
		$newStart = $viStop; 
		$newStop  = $stop;
	      }
	    }
	  }
	   return  array('start' => $newStart, 'stop' => $newStop);
	}
                   
      }
    
    public function getStartStop($id) 
    {  
       $this->baseDom->load($this->baseDomName);
       $xpath = new DOMXpath($this->baseDom);
      
       $vis = $xpath->query("//vi[@id=".$id."]");
 
       if ($vis->length == 0) 
			return "nodata";
 
        $vi = $vis->item(0);
             
        $start = $vi->getAttribute("start"); 
        $stop = $vi->getAttribute("stop");

        return date("Y-m-d", $start)."T".date("H:i:s", $start)."-".date("Y-m-d", $stop)."T".date("H:i:s", $stop);
    } 
 

    public function getViDesc($vi)
    { 
        return $this->getStartStop($vi);   
    }
     
}
?>