<?php
/**
 * @class RequestMgr
 * @version $Id: RequestMgr.php 2914 2015-05-19 10:31:38Z elena $
 *
 *
 */

class RequestMgr extends AmdaObjectMgr {

      public $obj;
      public $impex_prefix = array('impex___', 'spase__', 'CLWEB_');
      protected $searchChain;
      protected $jobXml, $jobXmlName;
      protected $parser, $paramBuilder;
      protected $derivedParamMgr;
      protected $request, $nObjects;
      protected $currentInt, $totalInt, $ttName;
      protected $paramsWithoutCode = false;
      protected $spectraParams = false;
      protected $dataBases;
      protected $types = array('request', 'condition');
      protected $argumentsByParam = array();
      protected $defaults = 'select...';
      protected $scatterOffset, $scatterOffsetX, $firstOffset;  
      protected $timeFormat = array('YYYY-MM-DDThh:mm:ss' => 0, 'YYYY MM DD hh mm ss' => 1, 'DD MM YYYY hh mm ss' => 2,  'YYYY DDD hh mm ss' => 3);
      protected $fileMgr;
      
      function __construct($type) {
 
        parent::__construct('Request.xml');
        $this->type = $type;

        $this->contentRootId = $type.'-treeRootNode';
        $this->contentRootTag = $type.'List';
        $this->objTagName = $type; //'request';
        $this->jobXmlName = USERDIR.'jobs.xml';
        $this->jobXml = new DomDocument("1.0");
        if (file_exists($this->jobXmlName)) {
           $this->jobXml->load($this->jobXmlName);
        }
        if ($type == 'request') {
           $this->id_prefix = 'req_';
           $this->attributes = array('name' => '');
           $this->optionalAttributes = array();
       }
       else {
           $this->id_prefix = 'cond_';
           $this->attributes = array('name' => '');
           //, 'timestep' => '', 'datagap' => '', 'buildchain' => '',
           //'StartTime' => '', 'TimeInt' => '');
           $this->optionalAttributes = array();
       }

       if (file_exists(paramListXml)) 
          $this->paramsWithoutCode = true;

       if (file_exists(spectraXml)) 
          $this->spectraParams = true;

       $this->parser = new Parser();
       $this->paramBuilder = new ParamBuilder();

       if (!file_exists($this->xmlName)) {
          $this->createDom();
          $this->xp = new domxpath($this->contentDom); 
       }
       //external bases       
       if (file_exists(RemoteData.'Bases.xml')) {
          $dataBasesDoc = new DomDocument("1.0");
          $dataBasesDoc->load(RemoteData.'Bases.xml');
          $this->dataBases = $dataBasesDoc->getElementsByTagName('dataCenter');
       }

       putenv("USER_DATA_PATH=".USERDATADIR);
       putenv("USER_WS_PATH=".USERWSDIR); 
       putenv("PHP_CLASSES_PATH=".CLASSPATH);
        
    }

/*********************************************************************
*   BEGIN : generic functions
**********************************************************************/
 protected function getWsdVars($vars){
   
    foreach($vars as $var) {           
            if(strpos($var, 'wsd_') === 0) 
            { 
                $wsdVars[] = $var;                
            }         
    }
 
    if (isset($wsdVars)) return $wsdVars;
    return false;
  }

  protected function getImpexVars($vars){
   
    foreach($vars as $var) {    
       foreach($this->impex_prefix as $prefix) {
            if(strpos($var, $prefix) === 0) 
            { 
                $impexVars[] = $var;   
            }
        }
    }
 
    if (isset($impexVars)) return $impexVars;
    return false;
  }

  protected function param2dd($paramID)
  {
      $pairs = array("-" => "_", "%" => "_","\\" => "_","$" => "_",":" => "_","+" =>" _","-" => "_","#" => "_","@" => "_", "." => "_",">" => "_", "<" => "_");    
      return strtr($paramID, $pairs); 
  }

  protected function param2dd_print($paramID)
  {
      $pairs = array("-" => "_", ":" => "_", "%" => "_","\\" => "_","$" => "_","+" =>" _","-" => "_","#" => "_","@" => "_", "." => "_",">" => "_", "<" => "_");    
      return strtr($paramID, $pairs); 
  }

  protected function setObject($obj) 
  {
      $this->obj = $obj;
  }

  /* temp name for output */
  protected function getRandomName() 
  {
      $length = 6;
      $characters = '0123456789abcdefghijklmnopqrstuvwxyz';
      $string = '';

      for ($p = 0; $p < $length; $p++) {
	  $string .= $characters[mt_rand(0, strlen($characters))];
      }

      return 'DD'.$string;
  }

  //DD notation 'DDDD:HH:MM:SS'  ATTENTION!!! DDDD => 4 digits!!!
  protected function getDdInterval() 
  {
      return $this->obj->durationDay.':'.$this->obj->durationHour.':'.
	      $this->obj->durationMin.':'.$this->obj->durationSec;
  }    

      
  //DD notation 'YYYY:DOY:HH:MM:SS' DOY => DOY-1
  protected function getDdTime($date)
  {
      $ddStart = getdate(strtotime($date));
      $DDTime = sprintf("%04d",$ddStart['year']).':'.sprintf("%03d", $ddStart['yday']).':'.
		  sprintf("%02d",$ddStart['hours']).':'.sprintf("%02d",$ddStart['minutes']).':'.
		  sprintf("%02d",$ddStart['seconds']);

      return $DDTime;
  }
       
/*
 * 
 */
/*public function isValidRequest()
{
 $usrMgr = new UserMgr();
 foreach ($this->obj->list as $param)
 {
  $usrMgr->isAvailableParamForUser();
 }
}*/
        protected function makeOrbitParam($stl) 
        {        
            $params = array( 'cluster1' => 'c1_xyz', 'cluster2' => 'c2_xyz', 'cluster3' => 'c3_xyz', 'cluster4' => 'c4_xyz',
                            'themisa'=> 'tha_xyz', 'themisb'=> 'thb_xyz', 'themisc'=> 'thc_xyz', 'themisd'=> 'thd_xyz', 'themise'=> 'the_xyz',
                            'geotail' => 'gtl_xyz',
                            'mex' => 'mex_xyz', 'mgs' => 'xyz_mgs_mso', 'maven' => 'mav_xyz_mso'); 

            $this->makeLocalParams(array($params[strtolower($stl)]));         
                    
        }

        protected function makeSWMonitorParam($swm) 
        {
            $params = array('omni' => array('omni5_sw_v', 'omni5_sw_n', 'omni5_imf'),
                            'amda' => array('ace_xyz', 'wnd_xyz', 'imp8_xyz', 'imf', 'wnd_b', 'imp8_b',
                                            'swp_n', 'swp_v', 'wnd_swe_n', 'wnd_swe_vmag', 'imp_mit_nfit', 'imp_mit_vfit'));
 
            $this->makeLocalParams($params[strtolower($swm)]);                             
        } 
          
        /* 
        *  plot objects - check Local Params without code
        */
        protected function isParamWithoutCode($id) 
        {           
            if (!$this->paramsWithoutCode) return false;            
            $localParams = new DomDocument('1.0');
            $localParams->load(paramListXml); 
            $xp = new domxpath($localParams);
            if ($xp->query('//PARAM[.="'.$id.'"]')->length != 0) {
                                $this->paramBuilder->paramLocalBuild($id);
                                return true;
            }
            return false;            
       }

        /* 
        *  plot objects - check and create Remote Params 
        */
        protected function isRemoteParam($object) 
        {
            if (!$this->dataBases) return false;
        
            foreach ($this->dataBases as $dataBase){
                        $dataBaseId = $dataBase->getAttribute('xml:id');
                        if (strncmp($object, $dataBaseId, strlen($dataBaseId)) === 0)  {
                                    return true;
                            }
                    }
            return false;
        }

        protected function makePlotRemoteParams($object, $file_name, $comp) 
        {
            require_once('paramBuild.php');
                    
            paramBuild($object);
            $SED = "sed 's/".$object."/".$this->param2dd($object)."/g' ".$file_name." > temp";
            system($SED);

            copy('temp',$file_name);

            if ($comp == 0) 
                        $comp = "0";
            if ($comp != -1) 
                        paramBuildComp($object, $comp);
            return true;

}

        /* 
        *  Process   Local Params without codes if exist
        */
        protected function makeLocalParams($realVars) 
        {     
            $localParams = new DomDocument('1.0');
            $localParams->load(paramListXml);
            $xp = new domxpath($localParams);
            foreach ($realVars as $var) {
            // process component
                        if (strpos($var, '(') !== false) {
                                    $var_arr = explode('(', $var);
                                    $var = $var_arr[0];
                        }
                        if ($xp->query('//PARAM[.="'.$var.'"]')->length  != 0) 
                                        $this->paramBuilder->paramLocalBuild($var);   
            }
            
        }

        /*
        *  Process  External Objects if exist
        */
        protected function makeRemoteParams($realVars) 
        {
            require_once 'paramBuild.php';

            foreach ($realVars as $var) 
            {
                foreach ($this->dataBases as $dataBase) 
                {  
                        $id = $dataBase->getAttribute('xml:id');
                        if ($dataBase->getAttribute('group') != 'IMPEX') { 
                                $pos = strpos($var, $id);
                                if ($pos === false) 
                                                    continue;
                                $arrComp = explode('(', $var);
                                $var_ = $arrComp[0];
                                paramBuild_($var_);
                                $this->searchChain = strtr($this->searchChain, $var, param2dd($var));
                                $var = param2dd($var);
                                break;
                         }
                }
            }
        }

    /*
    *         process  WS parameters
    */      
    protected function makeWsParams($realVars) {

      if (!$this->derivedParamMgr) $this->derivedParamMgr = new DerivedParamMgr('derivedParam');

      foreach ($realVars as $var){
                // Derived Params
           if (strncmp(strtolower($var), 'ws_', 3) == 0) {
               // check if resource file exists
               $varName = substr($var,3);

           if (!$this->derivedParamMgr->objectExistsByName($varName)) {
               return false; //TODO error processing
           }
           $varId = $this->derivedParamMgr->getObjectIdByName($varName);
           $resFile = $varId.'.res';

           if(!file_exists(USERWORKINGDIR.$resFile)) {
	      return false; //TODO process error
	    }
	    copy(USERWORKINGDIR.$resFile, $var.'.res'); 

            //TODO if needed to replace alias???
	    $realObject = $this->parser->replaceAll($var);

            $realWsVars = $this->parser->getVars($realObject); 
            foreach ($realWsVars as $wsVar) { 
                 if ((strncmp($wsVar, "impex___", 8) === 0) || (strncmp($wsVar, "spase___", 8) === 0)){
                      $tmpArr = explode('_',$wsVar);
                      $n = count($tmpArr); 
                      if ((strncmp($wsVar, "impex___LATMOS_", 15) === 0) || (strncmp($wsVar, "spase___IMPEX_NumericalOutput_LATMOS_", 37)=== 0)) {
                           $newVar = str_replace ("_".$tmpArr[$n-2]."_".$tmpArr[$n-1], "", $wsVar);
                      }
                      else {
                           $newVar = str_replace ("_".$tmpArr[$n-1], "", $wsVar);
                      }
                      $texte = file_get_contents($var.'.res'); 
                      $newText = str_replace($wsVar, $newVar,$texte);
                      file_put_contents($var.'.res' , $newText); 
                 }
             }
            //functions for plotting parameter
            $this->paramBuilder->makeWsParamPlot($var);
 
            // $realWsVars = $this->parser->getVars($realObject); 
 
            /*Check if WS_ is from Local Params without codes*/   
            if ($this->paramsWithoutCode) {            
               $this->makeLocalParams($realWsVars); 
            }

            /*Check if WS_ is from Spectra Params  */   
            if ($this->spectraParams) {          
               $this->makeSpectraParams($realWsVars); 
            }

            /*Check if WS_ is from Remote  Params  */   
            if ($this->dataBases) {          
                $this->makeRemoteParams($realWsVars);
            }

            /*Check if WS_ is from WS_ or WSD_ Params ONE LEVEL OF NESTING ONLY!!! */   
            foreach ($realWsVars as $wsVar) { 
                  if (strncmp(strtolower($wsVar), 'ws_', 3) === 0) {         
                     $this->paramBuilder->makeWsParamPlot($wsVar); 
                     $wsVarName = substr($wsVar,3);
                     $varId = $this->derivedParamMgr->getObjectIdByName($wsVarName);
                     $tempObj = $this->derivedParamMgr->getObject($varId);
                     $expression = $this->parser->replaceAll($tempObj["buildchain"]);
                     $resFile = $varId.'.res';
                     if(!file_exists(USERWORKINGDIR.$resFile)) 
                          return false; //TODO process error
                     
                     copy(USERWORKINGDIR.$resFile, $wsVar.'.res');
                     $lines = file($wsVar.'.res');
                     $wsWsVarsStr = explode(' ',$lines[0]);

                     $wsWsVars = array();
                     foreach ($wsWsVarsStr as $wsWsVar) if (trim($wsWsVar) != '') $wsWsVars[] = $wsWsVar;
                            $this->paramBuilder->makeParamCalcul($this->parser->convert2Idl($expression), $wsWsVars, $wsVar);
                            /*Check if WS_ is from Local Params without codes*/   
                            if ($this->paramsWithoutCode) {                                                      
                               $this->makeLocalParams($wsWsVars); 
                            }
                  }
                  elseif (strncmp(strtolower($wsVar), 'wsd_', 4) === 0)                                          
                      $this->makeWsdParams(array($wsVar));
                  elseif ((strncmp($wsVar, "impex___", 8) === 0) || (strncmp($wsVar, "spase___", 8) === 0)){
		    $imp = array('realVars'=> array($wsVar), 'fromWS' => true);
                    $this->makeWsrParams($imp);
                  }
            } 
            //function to calculate parameter
            $this->paramBuilder->makeParamCalcul($this->parser->convert2Idl($realObject),$realWsVars,$var);  
          }
      }

    } 

    /* Process WSD objects */
    protected function makeWsdParams($realVars) 
    {
        $paramMgr = new DerivedParamMgr('myDataParam');                
        $xpd = new domxpath($paramMgr->contentDom); 

        foreach ($realVars as $var)
            if (strncmp($var, "wsd_", 4) == 0) {
                        $name = explode('wsd_',$var);
                        $params = $xpd->query("//mydata[@name='".$name[1]."']");  
                        if ($params->length >  0)
                            $this->paramBuilder->makeWsdParam($params->item(0)->getAttribute('xml:id'));
            }
            elseif ((strncmp($var, "impex___", 8) === 0) || (strncmp($var, "spase___", 8) === 0))  {
    
            }
    }
    

     /* Process SIMU et INSITU request param*/
     protected function makeWsrParams($imp){
        $realVars = $imp['realVars'];
        $fromWS = $imp['fromWS'];
       
        $isMulti =  $this->obj->timeTables ? true: false; 
        if (!$isMulti){
           $startDate = $this->obj->startDate;
           $stopDate = $this->getStopDate();
        }
        else {
           $interval = $this->getFirstTimeTableInterval();
           $startDate = $interval['start'];
           $stopDate = $interval['stop'];
        }

        $paramMgr = new DerivedParamMgr('mySimuParam');
    
        $simuParamMgr = new SimuParamMgr();        
        $myWsrParamMgr = new WsrParamMgr();
             
        $myBaseManager = new BaseManager();
        $xpd = new domxpath($myBaseManager->baseDom);
        $data =  array();

        $paramDom = new DomDocument("1.0");
        $paramDom->load(getenv('USER_WS_PATH').'WsParams.xml');
        $xpdSimu = new domxpath($paramDom);  

        foreach ($realVars as $var) {

            $isVector = false;
            $isSimu = strncmp($var, "impex___", 8) === 0 || strncmp($var, "spase___", 8) === 0;
            $isClWeb = strncmp($var, "CLWEB_", 6) === 0;

        // All simulation parameters and arguments has prefix "spase___" or "impex___" (old version) 
            if ($isSimu || $isClWeb) { 
                if ($fromWS && !$isClWeb) {
                   $this->argumentsByParam = $this->cutSimuArgs($var);
                   foreach ($this->argumentsByParam as $key => $value) 
                        $var = $key;
                } 
                else $var = $this->param2dd($var);
 
                $fileExists = false;
               // ClWeb
                if ($isClWeb ){ 
                   $data['paramID'] = $var; 
                   $data['startDate'] = $startDate;
                   $data['stopDate'] = $stopDate;
                   // Creation request parameters
                   $myWsrParamMgr->setParams($data);
                   // definitions mask for wsr parameter
                   $mask = $myWsrParamMgr->getMask();
                   // definitions download file name for wsr parameter
                   $fileName = $myWsrParamMgr->getFileName(); 
//                   $dataType = "mywsrdata";
                }
                // Simulation
                else {
		    // Creation request simu parameters
                    $simuParamMgr->setParams($var, $startDate, $stopDate, $this->argumentsByParam);
                    // definitions mask for simu parameter
                    $mask = $simuParamMgr->getMask();
                     // definitions download file name for simu parameter
                    $fileName = $simuParamMgr->getFileName();
                    // test if request parameter is Vector
                    $isVector = $simuParamMgr->isVector();
//                    $dataType = "mysimudata";
                }

		// definition query for seaching mask in base.xml 
                $params = $xpd->query("//vi[mask='".$mask."']");

if (file_exists('/home/budnik/public_html/AMDA-NG4/trunk/data/budnik/LOG'))
                     unlink('/home/budnik/public_html/AMDA-NG4/trunk/data/budnik/LOG');
                // VI exists!!!   
                if ($params->length >  0) {  
                    // IMPORTANT !!! It is the public method of baseManager class to define ALL needed intervals to request!!!
                    // Used in moreData.php also 
                    //TODO move from moreData.php to PlotMgr.php for new kernel
                    $intervalsToGet = $myBaseManager->intervalsToGet(strtotime($startDate), strtotime($stopDate),$mask);
                    $paramsWsr = $xpdSimu->query("//*[@mask='".$mask."']");
                    $wsrID = $paramsWsr->item(0)->getAttribute('xml:id');         
                    // data recuperation
                   $start = $intervalsToGet['start'];
                   $stop = $intervalsToGet['stop'];

                    if (count($start) > 0) {
                      for ($i = 0; $i < count($start); $i++) {
                        if ($isClWeb) {
                            $myWsrParamMgr->updateInterval($start[$i],$stop[$i]);
                            $fileNames = $myWsrParamMgr->getData();
                          }
                        else {  
                            $simuParamMgr->updateInterval($start[$i],$stop[$i]);
                            $fileNames = $simuParamMgr->getSimuData();
                         }                           
                        }  
                     //   if (!$isClWeb) $isVector  = $simuParamMgr->isVector();
                    }
                    $this->paramBuilder->makeWsdParam($wsrID);
                }
               // No such VI - It is the very first request
                else {		 
                    if ($isClWeb){
                        $fileNames = $myWsrParamMgr->getData();
                        $var = $this->param2dd($var);
                    }
                    else {  
                        $fileNames = $simuParamMgr->getSimuData();
                        $isVector = $simuParamMgr->isVector();
                    }

                    $input = (object)array(
                        "varName" => $var,
                        "isVector"=> $isVector,
                        "fileName"=> $fileName,
                        "mask"=> $mask,
                        "startDate"=> strtotime($startDate),
                        "stopDate"=> strtotime($stopDate)
                    );     

                    if ($fileNames[$var]){
                        if ($isClWeb){
                            $tmpObj = $this->makeWsrParamsObj($input, $isClWeb);
                            $res = $paramMgr->createWsrParameter($tmpObj,'myWsrParam');
                        }
                        else {
                            $tmpObj = $this->makeWsrParamsObj($input);
                            $res = $paramMgr->createWsrParameter($tmpObj,'mySimuParam');
                        }
                    }
                    if ($res['id'])                                
                            $this->paramBuilder->makeWsdParam($res['id']);                    
                }
            }
        }
    }       
    /* Protected request param*/
    protected function makeWsrParamsObj($input, $isClWeb) {

      $params =  explode( '_', $input->varName);

      if (!$isClWeb){
        // Recuperation names of argument(s)
         if (!$input->isVector)
            $varName = $params[count($params) -1];
         else
            $varName = $params[count($params) -3].'_'.$params[count($params) -2].'_'.$params[count($params) -1];
      }
      else {
 
         $dom = new DomDocument();
         $dom->load(baseDirCLWEB);
         $param = $dom->getElementById($input->varName);
         // Name of parameter in CLWeb
         $varName = $param->getAttribute('var');
         // To know if it's Spectra data in ws param we need to indicate "plottype" => $spectra, but in RemoteParams.xml the atribute 'display_type' == 'spectrogram'
         // so we need create variable = 'Spectra'
         if ($param->hasAttribute('display_type') && ($param->getAttribute('display_type') == 'spectrogram')) $spectra = 'Spectra';
      }
      
      $myFileManager = new FilesMgr();
      $object = (object)array(
        "file"=> $input->fileName,
        "format"=> "nc",
        "varName"    => $this->param2dd($varName),
        "mask"=> $input->mask
      );

      if (!$isClWeb){  
      //delete different possible IMPEx prefix
         $tmpTmp =    str_replace ("impex___", "", $this->parameterID);
         $tmpT =    str_replace ("spase___IMPEX_NumericalOutput_", "", $tmpTmp);
         $tmp =    str_replace ("spase___IMPEX_SimulationRun_", "", $tmpT); 
         $tmpArr = explode('_',$tmp);
         $format = "vot";
         $parentTag = "mysimudataList";
         $contentRootId = "mySimuParam-treeRootNode";
         if ($this->getVotFileMgr($input->fileName)) {
	      $infos = $this->fileMgr->getFieldInfoByID($varName);
	      $samplings = $this->fileMgr->getSamplings();
	      $id = $infos['id'];
	      $type = $infos['type'];
	      $units = $infos['unit'];
          }
       }
       else {
         $tmpArr[0] = $this->parameterID;
         $format = "nc";
         $parentTag = "mywsrdataList";
         $varName = $input->varName;
         $contentRootId = "myWsrParam-treeRootNode";
         $infos = $myFileManager->getParamInfo($object);
         $samplings['minSampling'] = $infos["info"]["minsampling"];
         $samplings['maxSampling'] = $infos["info"]["maxsampling"];
         $id =  $infos["info"]["name"];
         $type = $infos["info"]["type"];
         $units = $infos["info"]["unit"];
      }

      //size definition
      if (($infos['size'] == '') && ($infos["info"]["size"] == ''))
         $size = 1;
      else {
        if ($infos["info"]["size"] != '') $size = $infos["info"]["size"];
        else
         $size = $infos['size'];
      }

      $obj = (object)array(
          "name"    => $input->varName,
          "format"=> $format,
          "size"=> $size,
          "realvar"=> $id,
          "file"=> $input->fileName,
          "minsampling" => $samplings['minSampling'],
          "maxsampling" => $samplings['maxSampling'],
          "type" => $type,
          "units" => $units,
//       "ytitle" => str_replace ("impex___", "", $input->varName),
          "ytitle" => $tmpArr[0].' '.$varName,
          "mask"=> $input->mask,
          "args"=> $this->argumentsByParam,
          "start"=> $input->startDate,
          "stop"=> $input->stopDate,
          "parentTag"=> $parentTag,
          "contentRootId" => $contentRootId,
          "plottype" => $spectra
        );


        return $obj;
    }
/* 
 *	Recuperation arguments from request variable name for download parameter
 */
    protected function cutSimuArgs ($var){
        $args = array();
        $tmpTmp =    str_replace ("impex___", "", $var);
        $tmpT =    str_replace ("spase___IMPEX_NumericalOutput_", "", $tmpTmp);
        $tmp =    str_replace ("spase___IMPEX_SimulationRun_", "", $tmpT); 
        $tmpArr = explode('_',$tmp);
        $n = count($tmpArr);
        //LATMOS parameters have 2 arguments: Satellite & ClockAngle others simulations have only Satellite arguments. 
        //Exceptions: LESIA simulations and SINP simulations with target different to Earth.
        if ($tmpArr[0] == 'LATMOS') {
           $args['Satellite'] = $tmpArr[$n-2];
           $args['ClockAngle'] = $tmpArr[$n-1];
           $var = str_replace ("_".$tmpArr[$n-2]."_".$tmpArr[$n-1], "", $var);
        }
        else {
          $args['Satellite'] = $tmpArr[$n-1];
          $var = str_replace ("_".$tmpArr[$n-1], "", $var);
        }
        return array($var => $args);
    }
    /*
    * VOTable format processing done by an instance of VOTableMgr
    */
    protected function getVotFileMgr($fileName) {
        if (!$this->fileMgr)
	    $this->fileMgr = new VOTableMgr();
      
        $this->fileMgr->load(USERDATADIR.$fileName);
        if ($this->fileMgr) 
           return true;
        else 
           return false;
   }

        /* Interval from StartTime and Stop Time */ 
   protected function calculateTimeInt($interval){
       $int = strtotime($interval['stop']) - strtotime($interval['start']);
  
       $days = floor($int / 86400);
       $int -= $days * 86400;

       $hours = floor($int / 3600);
       $int -= $hours * 3600;

       $minutes = floor($int / 60);
       $secs = $int - $minutes*60;
 
       $DdInterval  = sprintf("%04d:%02d:%02d:%02d", $days, $hours, $minutes, $secs); 

       return  $DdInterval; 

  }
/*********************************************************************
*  END : generic functions
**********************************************************************/

/*********************************************************************
*   BEGIN : Search specific functions
**********************************************************************/

        /*
        * Check if local_param  is Special Spectra Cases - to Create special PRO
        */
        protected function makeSpectraParams($realVars) 
        {
            if ($this->spectraParams)
            {
                $spectraParams = new DomDocument('1.0');
                $spectraParams->load(spectraXml);
                $allSpectraParams = $spectraParams->getElementsByTagName("PARAM");

                foreach ($realVars as $theVar) {
                    for ($j = 0; $j < $allSpectraParams->length; $j++) {
                        $paramNode = $allSpectraParams->item($j);
                        if (strpos($theVar, $paramNode->nodeValue) !== false) {
                                    $PRODIR = PRO;                                    
                                    $temp = explode("_",$theVar);
                                    $EMIN = $temp[3];
                                    $EMAX = $temp[4]; 
                                    // generate all necessary codes for models
                                    if ($paramNode->hasAttribute('model')) {
                                        if ($temp[0] == "bcain" || $temp[0] == "bmorsch") {
                                            // satellite
                                            $EMIN =  strtolower($temp[2]);
                                            // sampling
                                            $EMAX =  strtolower($temp[3]);
                                        }
                                        else {
                                            // satellite
                                            $EMIN = strtolower($temp[1]);
                                            //monitor sw  
                                            $EMAX = strtolower($temp[2]);
                                            $this->makeSWMonitorParam($EMAX); 
                                        }
                                        $this->makeOrbitParam($EMIN);                                         
                                    }
                                    else {
                                        $EMIN = $temp[3];
                                        $EMAX = $temp[4]; 
                                    }

                                    if ($EMAX) {
                                        $newFunctionName = $paramNode->nodeValue.$EMIN."_".$EMAX."_.pro";
                                        $SED = "sed 's/EMIN/".$EMIN."/g' ".$PRODIR.$paramNode->nodeValue.".pro | sed  's/EMAX/".$EMAX."/g' > ".$newFunctionName; 
                                    }
                                    else {
                                        $newFunctionName = $paramNode->nodeValue.$EMIN."_.pro";
                                        $SED = "sed 's/EMIN/".$EMIN."/g' ".$PRODIR.$paramNode->nodeValue.".pro > ".$newFunctionName;
                                     }                                    
                                    system($SED);
                                }
                        }
                }
            }
        }
 

        /*
        *   Create search.list with timing for DD_Search
        */        
        protected function createSearchRequestTime() 
        {
            $this->request = fopen(USERWORKINGDIR.'search.list','w');

            fwrite($this->request,$this->getDdTime($this->obj->startDate).PHP_EOL);
            fwrite($this->request,$this->getDdInterval().PHP_EOL);

            fclose($this->request);
        }

        /*
        * Create resource file for DD_Search
        */
        protected function createSearchRequest($realVars, $New_Table) 
        {
              $file = fopen(USERWORKINGDIR.'search.res','w');
              fwrite($file, $New_Table.PHP_EOL);
              fwrite($file,$this -> searchChain.PHP_EOL);
              foreach ($realVars as $var) fwrite($file, $var." ");
              fwrite($file,PHP_EOL.$this->obj->sampling.PHP_EOL);
              fwrite($file,$this->obj->gap.PHP_EOL);
              fclose($file);
            //TODO
            /*
            *   Create file WITH VARS DESCRIPTION
            */
            //              $file = fopen(USERWORKINGDIR.'search_info.res','w');
            //              fwrite($file,count($realVars).PHP_EOL);
            //             foreach ($realVars as $var) fwrite($file, $this->getFullName($searchChain, $var).PHP_EOL);
            //             fclose($file);
        }

        /*
        *  Generate codes for parameters wich are not 'hard-coded'
        */
        protected function makeSearchParams() 
        {
            $searchChain = $this->parser->replaceAll($this->obj->expression);
            $realVars = $this->parser->getVars($searchChain);
            $this -> searchChain = $searchChain;

            // Check if local_param  is Special Spectra Cases - to Create special PRO
            $this->makeSpectraParams($realVars);

            // Process   Local Params without codes if exist
            $this->makeLocalParams($realVars);

            // Make external params
            $this->makeRemoteParams($realVars);

            // Make WS params
            $this->makeWsParams($realVars);

            // Make WSD params
            $this->makeWsdParams($realVars);

            $this->paramBuilder->makeParamCalcul($this->parser->convert2Idl($this->searchChain), $realVars, "");

           return  $realVars;
        }

/*****************************************************************************
*  END:  Search specific functions
******************************************************************************/

/******************************************************************************
*   BEGIN : Plot specific functions
******************************************************************************/
        /*
        * Generic Plot Settings: Orientation: portrait, landscape;
        *                        ColorTable;
        *                        Font;
        *                        PPP
        */
        protected function setPlot()
        {
            $resFile = file(USERWORKINGDIR.'DD_Request.res');
            $res = fopen('./DD_Request.res','w');
            fwrite($res, strtolower($this->obj->orientation).PHP_EOL); 
            for ($k = 1; $k < 3; $k++) fwrite($res,$resFile[$k]);
            fwrite($res, $this->obj->ppp.PHP_EOL); 
            fclose($res);
                                    
            $res = fopen('./DD_PlotSettings.res','w');  
            fwrite($res,$this->obj->charSize.PHP_EOL);
            fwrite($res,$this->obj->thickness.PHP_EOL);
            fclose($res);
            //TODO forced layout with charsize
            $this->scatterOffsetX = $this->obj->format == 'PNG' && !$this->obj->forcedLayout ? $this->obj->charSize * 0.23 : 0.03;
            $this->scatterOffset = $this->obj->format == 'PNG' && !$this->obj->forcedLayout ? $this->obj->charSize * 0.05 : 0.06;
            $this->firstOffset =  $this->obj->format == 'PNG' && !$this->obj->forcedLayout ? $this->obj->charSize * 0.07 : 0.08;
        }

         protected function cmp($a, $b){ 
              return  $a->height < $b->height;
           }

/*
        *
        */
        protected function makeForcedLayout($panels) 
        { 
            $TotalHeight = 0.0;      
    $PWidth = 0.9;
            $ScatterCoef = 1;
            
            $PN = 1;
    
            $ScatterPanels = array();
            $TimePanels = array();

            foreach ($panels as $panel) { 
                    if ($panel->plotType == 'SCATTER') {
                        if (strtolower($this->obj->orientation) == 'portrait') $panel->width *= 1.625;
                            $ScatterPanels[] = $panel;
                    }
                    else $TimePanels[] = $panel;
            }

            usort($ScatterPanels, '$this->cmp');

            $widthArr = array();
            foreach ($ScatterPanels as $panel) $widthArr[] = $panel->width;

            $PlotPanels = array(array());

            for ($i = 0; $i < count($ScatterPanels); $i++) 
            { 
                $panel = $ScatterPanels[$i];
                if (!$panel->pN) { 
                    $width = $panel->width;  
                    $panel->pN = $PN;  
                    $PlotPanels[$PN][] = $panel;
                        for ($j = 1; $j < count($widthArr); $j++) { 
                        $panel1 = $ScatterPanels[$j];
                        if (!$panel1->pN) {
                            $widthNew = $width + $widthArr[$j];
                            if ($widthNew < $PWidth*$ScatterCoef) {
                            $width = $widthNew;
                            $panel1->pN = $PN;
                            $PlotPanels[$PN][] = $panel1;
                            if ($j == count($widthArr) -1) {
                                $PN++; break 1;
                            }
                            }
                            else if ($j < count($widthArr) -1) {
                                continue;
                            }
                            else {
                                $PN++; break 1;   
                            }
                        }
                    }
                }
            }
 
            foreach ($TimePanels as $panel) {
                            $TotalHeight += $panel->height;
            } 

            $ScatterMaxHeight = array();
            $ScatterTotalWidth = array();
            for ($i = 1; $i <= $PN; $i++) {
                $height = 0.0;
                $width = 0.0;
                foreach($PlotPanels[$i] as $panel){
                    $height = $panel->height > $height ? $panel->height : $height;
                    $width += $panel->width;
                } 
                $ScatterMaxHeight[$i] = $height;
                $ScatterTotalWidth[$i] = $width;
                $TotalHeight +=$height; 
            }
               
                
            $PHeight = 1.0 - $PN*$this->scatterOffset - $this->firstOffset;
            $heightCoeff = $TotalHeight > $PHeight ? $PHeight/$TotalHeight : 1.0;

            $first = true;  
      
            foreach (array_reverse($TimePanels) as $panel)
            {
                if ($panel->children[0]->paramArgs == "OrbitPresentation=CYL") {
                    $width = $panel->width*$heightCoeff;                    
                    $panel->XPmin = ($PWidth - $width)/2.0;
                    $panel->XPmax = $panel->XPmin + $width;
                }
                else { 
                    $panel->XPmin = 0.0;
                    $panel->XPmax = $PWidth;
                }
                //Start from lower panel
                $panel->YPmin =  $first  ? $this->firstOffset : $YPmax;
                $YPmax =  $panel->YPmin + $panel->height*$heightCoeff;
                $panel->YPmax = $YPmax;
                $first = false; 
            }

            if ($first) $YPmax = $this->firstOffset + 0.03;
            else  $YPmax += $this->scatterOffset;

            // Y coordinates     
            for ($i = 1; $i <= $PN; $i++) { 
                $newWidth = ($PN-1)*$this->scatterOffsetX;
                $realHeight = $ScatterMaxHeight[$i]*$heightCoeff;
                foreach ($PlotPanels[$i] as $panel) {                   
                    $panelCoeff = $panel->height > $realHeight ? $realHeight/$panel->height : 1;    
                    $panel->YPmin = $YPmax;
                    $panel->YPmax =  $panel->YPmin + $panel->height*$panelCoeff;     
                    $width = $panel->width*$panelCoeff;
                    $panel->panelCoeff = $panelCoeff;
                    $newWidth += $width;
                }          
                // X coordinates
                $xOffset = 0.0;
                foreach ($PlotPanels[$i] as $panel) {                          
                    $width = $panel->width*$panel->panelCoeff;
                    $panel->XPmin = ($PWidth - $newWidth)/2.0 + $xOffset;
                    $panel->XPmax = $panel->XPmin + $width;
                    $xOffset +=  $this->scatterOffsetX+$width;
                }

                $YPmax += $this->scatterOffset + $realHeight;
            }
            $arrayToReturn = array_reverse($TimePanels);

            for ($i = 1; $i <= $PN; $i++)
                    foreach ($PlotPanels[$i] as $panel)
                            $arrayToReturn[] =  $panel;

            return  $arrayToReturn;
        }

        /*
        *
        */
        protected function makeLayout($panels) 
        {
            $TotalHeight = 0.0;      
            $PWidth = 0.9;

            $ScatterN = 0;
            $TimeN = 0; 
            foreach ($panels as $panel){ 
                        if ($panel->plotType == 'SCATTER') {
                            $ScatterN++;
                            if (strtolower($this->obj->orientation) == 'portrait') 
                                            $panel->width *= 1.625; //0.65/0.4; coeff for portrait
                        }
                        else $TimeN++;

                        $TotalHeight += $panel->height;     
            }

            $addOffset = $TimeN > 0 && $panels[count($panels)-1]->plotType == 'SCATTER';
                
            $PHeight = 0.99 - $this->firstOffset - $ScatterN*$this->scatterOffset - $this->firstOffset*$addOffset;
            $heightCoeff = $TotalHeight > $PHeight ? $PHeight/$TotalHeight : 1.0;

            //Loop through all panels
            $first = true;
            $firstTime = true;
            $allPanels = array(); 

            foreach (array_reverse($panels) as $panel)
            {
                $isScatter = $panel->plotType == 'SCATTER';
                // width for scatter
                if ($isScatter) {                         
                    $width = $panel->width*$heightCoeff;                    
                    $panel->XPmin = ($PWidth - $width)/2.0;
                    $panel->XPmax = $panel->XPmin + $width;
                }
                else if ($panel->children[0]->paramArgs == "OrbitPresentation=CYL") {
                     $width = $panel->width*$heightCoeff;                    
                     $panel->XPmin = ($PWidth - $width)/2.0;
                     $panel->XPmax = $panel->XPmin + $width;
                }
                else {
                    $panel->XPmin = 0.0;
                    $panel->XPmax = $PWidth;
                }

                //Start from lower panel
                if ($first) 
                            $panel->YPmin = $this->firstOffset;
                else if ($isScatter) 
                            $panel->YPmin = $YPmax+$this->scatterOffset;
                else if ($addOffset &&  $firstTime && !$isScatter) {
                    $firstTime = false;
                    $panel->YPmin = $YPmax+$this->firstOffset;
                }
                else  
                    $panel->YPmin = $YPmax;

                $YPmax =  $panel->YPmin + $panel->height*$heightCoeff;
                $panel->YPmax = $YPmax;
                $first = false;
             }
            return array_reverse($panels);
        }

 protected function setPlotObjects($panels,$tmpname,$isMulti){

    require_once 'paramBuild.php';

    $this->request = fopen($tmpname,'w');
 
            if ($this->obj->forcedLayout) 
                    $panels = $this->makeForcedLayout($panels);  
            else 
                    $panels = $this->makeLayout($panels);
                     
    foreach ($panels as $panel){
                // if it is  SCATTER PLOT
                $isScatter = $panel->plotType == 'SCATTER';                
                $Xmin = $panel->xRangeMin;
                $Xmax = $panel->xRangeMax;
                $Ymin = $panel->y1RangeMin;
                $Ymax = $panel->y1RangeMax; 

                $Ytitle = $panel->y1Title;
                $Xtitle = $panel->xTitle;
   
                $objectsToDraw = $panel->children;
                    
                $multiOnePanel = false;
                // check if SPECIAL MULTI could be done
                if (count($objectsToDraw) > 1 && $this->obj->forcedMulti && !$isScatter) {
                        $multiOnePanel = true;
                        foreach ($objectsToDraw as $objectToDraw) {
                            // only scalars
                            if (!$objectToDraw->isScatter) {
                                            $multiOnePanel = false;
                            }
                        }
                    }

                if ($multiOnePanel) {
                        $aPanel = new stdClass(); 
                        $aPanel->XPmin = $panel->XPmin;
                        $aPanel->XPmax = $panel->XPmax;
                        $aPanel->YPmin = $panel->YPmin;
                        $aPanel->YPmax = $panel->YPmax;
                        $aPanel->Xmin = $Xmin;
                        $aPanel->Xmax = $Xmax;
                        $aPanel->Ymin = $Ymin;
                        $aPanel->Ymax = $Ymax; 

                        $aPanel->object = 'multi';
                        $aPanel->args = ''; 
                        foreach ($objectsToDraw as $objectToDraw) {
                            $aPanel->args .= '"'.$objectToDraw->name.'",';
                            $paramMulti =  explode('(',$objectToDraw->name);
                            $paramList[] = $paramMulti[0];
                        }
                        $aPanel->args = substr($aPanel->args, 0, -1);
                        $allPanels[] = $aPanel;  
                    }
                // loop though parameters : each parameter == panel if not MULTI
              else {
                  foreach ($objectsToDraw as $objectToDraw) {
                      $aPanel = new stdClass(); 
                      $aPanel->XPmin = $panel->XPmin;
                      $aPanel->XPmax = $panel->XPmax;
                      $aPanel->YPmin = $panel->YPmin;
                      $aPanel->YPmax = $panel->YPmax;
                      $aPanel->Xmin = $Xmin;
                      $aPanel->Xmax = $Xmax;
                      $aPanel->Ymin = $Ymin;
                      $aPanel->Ymax = $Ymax;

                      if ($isScatter) { 
                         $paramIDx = explode('(', $objectToDraw->name); 
                         $paramList[] = $paramIDx[0];
                         $paramIDy = explode('(',$panel->scatterParam->data->name);
 
                         $oneVI = $paramIDy[0] === $paramIDx[0] ? true : false;
 
                         if ($this->isRemoteParam($paramIDx[0])) {

                                if (!$infoMgr) $infoMgr = new ParamsInfoMgr();
                                $info = $infoMgr->getRemoteParamInfo($paramIDx[0]);
                                                                
                                paramBuild_($paramIDx[0]); 
                                $paramIDx[0] = param2dd($paramIDx[0]);
                                $objectToDraw->name = implode('(', $paramIDx);
                                                              
                                $YTitle_default = $info['title'] ? $info['title'].'('.$paramIDx[1] : $objectToDraw->name;

                                if ($oneVI) {   
                                        $paramIDy[0] = $paramIDx[0];
                                        $panel->scatterParam->data->name = implode('(', $paramIDy);
                                $XTitle_default = $info['title'] ? $info['title'].'('.$paramIDy[1] : $panel->scatterParam->data->name;
                                }
                            }
      
                            if (!$oneVI) {
 
                                if ($this->isRemoteParam($paramIDy[0])) {

                                    if (!$infoMgr) $infoMgr = new ParamsInfoMgr();
                                    $info = $infoMgr->getRemoteParamInfo($paramIDy[0]); 

                                    paramBuild_($paramIDy[0]); 
                                    $paramIDy[0] = param2dd($paramIDy[0]);
                                    $panel->scatterParam->data->name = implode('(', $paramIDy);
                                    $XTitle_default = $info['title'] ? $info['title'].'('.$paramIDy[1] : $panel->scatterParam->data->name;             
                                }        
                                        $paramList[] = $paramIDy[0];
                            }
                            $aPanel->object = 'scatter';
                            $aPanel->args = '"'.$objectToDraw->name.'",'.'"'.$panel->scatterParam->data->name.'"';
                            $aPanel->args .= $this->parseScatterArguments($objectToDraw->paramArgs);   
                                                 
                         if ($Xtitle || $XTitle_default) {
                            $Xtitle_ = $Xtitle ? $Xtitle : $XTitle_default; 
                            $aPanel->args .= ', XTITLE="'.$Xtitle_.'"';
                         }
                          
                        if ($Ytitle || $YTitle_default) {
                            $Ytitle_ = $Ytitle ? $Ytitle : $YTitle_default; 
                            $aPanel->args .= ', Y1TITLE="'.$Ytitle_.'"';
                        }
                     }
                     else {
                        // to make proper AMDA objects
                        $comp = -1;
                        $addArgs = $this->parseSimuArguments($objectToDraw->paramArgs);
                        $this->argumentsByParam[$objectToDraw->name] = (array)$addArgs;    
                        if (strpos($objectToDraw->name, '(') !== false) {
                            //first check params without codes 
                            $paramID = explode('(', $objectToDraw->name);
                            $comp =  substr($paramID[1], 0, -1);
                            //TODO double ??? of MakeLocalParam A CORRIGER
                            $paramWithoutCode = $this->isParamWithoutCode($paramID[0]);      
                            $currPairs = array("(" => "_", ")" => "",":" => "_");
                            $objectToDraw->name = strtr($objectToDraw->name, $currPairs);  
                        }    
                        else {
                            $paramWithoutCode = $this->isParamWithoutCode($objectToDraw->name);
                        }
                        if ($this->isRemoteParam($objectToDraw->name)) { 

                                if ($comp != -1) $this->makePlotRemoteParams($paramID[0], $tmpname, $comp);
                                else  $this->makePlotRemoteParams($objectToDraw->name, $tmpname, $comp);
                                                                                
                            $currPairs = array(":" => "_", '-' => "_");
                            $objectToDraw->name = strtr($objectToDraw->name, $currPairs); 
                        }
                        //================================================================
                        // TODO THEMIS_IRAP init is created from special templates!!!
                        $objToTest = str_replace("_", " ", $objectToDraw->name);
                        if (sscanf($objToTest, "th%s pe%s %s", $X, $mode, $property) == 3){       
                            $themis = "th".$X;
                            $mode = "pe".$mode;
                            $SED = "sed 's/X/".$X."/g' ".TEMPLATES."thX_YYYY_".$property."_init.pro | sed 's/YYYY/".$mode."/g' > ./".$themis."_".$mode."_".$property."_init.pro";
                            system($SED);
                            if ($property == 'v' || $property == 't' || $property == 'mode' ) {
                                for ($j = 0; $j < 3; $j++) {
                                    $SED = "sed 's/X/".$X."/g' ".TEMPLATES."thX_YYYY_".$property."_Z_init.pro | sed 's/YYYY/".$mode."/g' | sed 's/Z/".$j."/g' > ./".$themis."_".$mode."_".$property."_".$j."_init.pro";
                                    system($SED);  
                                }
                            }                       
                           }
                    
                        if (sscanf($objToTest, "th%s bh", $X) === 1){                                                                                                                                        
                            $themis = "th".$X;                    
                            $SED = "sed 's/X/".$X."/g'  ".TEMPLATES."thX_bh_init.pro  > ./".$themis."_bh_init.pro"; 
                            system($SED);   
                            for ($j = 0; $j < 3; $j++) {
                                    $SED = "sed 's/X/".$X."/g' ".TEMPLATES."thX_bh_Z_init.pro | sed 's/Z/".$j."/g' > ./".$themis."_bh_".$j."_init.pro";
                                    system($SED);               
                                } 
                                    
                        }       
//==================================================

                        $aPanel->object = $objectToDraw->name;
                        if ($objectToDraw->paramArgs != $this->defaults) {
                                    $aPanel->args = $this->parseArguments($objectToDraw->paramArgs);
                        }
                        // new Y Title
                        if ($Ytitle && ($paramWithoutCode || $this->isRemoteParam($objectToDraw->name) || (strncmp(strtolower($objectToDraw->name), 'ws_', 3) == 0))) {
                            if ($objectToDraw->paramArgs != $this->defaults) $aPanel->args .= ',';
                            $aPanel->args .=  'AY1TITLE="'.$Ytitle.'"';
                        }
                        // linear Z scaling for ros_mip
                        if (substr($objectToDraw->name,0,7) == 'ros_mip') {
                                if ($objectToDraw->paramArgs != $this->defaults) $aPanel->args .= ',';
                                $aPanel->args .= '/LLIN';
                        }
                        // linear Y scaling for ros_ies AZ, ELV
                        if (strpos($objectToDraw->name,'ros') === 0 && 
                            (strpos($objectToDraw->name,'elv') > 0 || strpos($objectToDraw->name,'az') > 0)) {
                                if ($objectToDraw->paramArgs != $this->defaults) $aPanel->args .= ',';
                                $aPanel->args .= '/LIN';
                        }
                        $paramList[] = $aPanel->object; 
 
                    } 
                    $allPanels[] = $aPanel;
                   }
                } //else
            } //foreach ($panels as $panel)

            //Now write everything into request file
            fwrite($this->request,count($allPanels).PHP_EOL);
        
            foreach ($allPanels as $aPanel) { 
                fwrite($this->request, 
                        $aPanel->object.' '.$aPanel->XPmin.' '.$aPanel->YPmin.' '.$aPanel->XPmax.' '.$aPanel->YPmax.' '.
                        $aPanel->Xmin.' '.$aPanel->Xmax.' '.$aPanel->Ymin.' '.$aPanel->Ymax.' '.$aPanel->args.PHP_EOL); 
            }

            $this->nObjects = count($allPanels);

            // Finish request file by StartTime and TimeInterval if ONE time only
            if (!$isMulti) {
                $StartTime = $this->getDdTime($this->obj->startDate);
                $TimeInt =  $this->getDdInterval();
                fwrite($this->request,$StartTime.PHP_EOL);
                fwrite($this->request,$TimeInt.PHP_EOL); 
            } 
            fclose($this->request); 
            
            return $paramList;
        }

        /*
        *  Arguments parser
        */ 
        protected function getColor($value) {

            switch ($value) {
               case  'black' :  return 'COLOR = !dnc-1'; 
               case  'red'   :  return 'COLOR = !dnc-2';
               case  'orange'   :  return 'COLOR = !dnc*190/256';
               case  'yellow'   :  return 'COLOR = !dnc*160/256';
               case  'green' :  return 'COLOR = !dnc*80/256';   
               case  'light-green' :  return 'COLOR = !dnc*100/256';
               case  'light-blue'  :  return 'COLOR = !dnc*40/256'; 
               case  'blue'  :  return 'COLOR = !dnc*15/256'; 
               default:         return 'COLOR = !dnc-1';
           }
        }

        /*
        *   Arguments parser
        */ 
  protected function parseArguments($args)
        {
            $argArr = explode('&',$args);
            foreach ($argArr as $key => &$arg) {
                $temp = explode('=', $arg);
                //translate some arguments
                if ($temp[1] == 'no') unset($argArr[$key]);
                if ($temp[1] == 'yes') $arg = '/'.$temp[0];
                if ($temp[0] == 'Scale') $arg = '/'.$temp[1];
                if ($temp[0] == 'RefFrame') $arg = 'FRAME="'.$temp[1].'"';
                if ($temp[0] == 'OrbitPresentation') $arg = '/'.$temp[1];

                if ($temp[0] == 'Spacecraft') {
                                    $arg = '/'.$temp[1];
                                    $this->makeOrbitParam($temp[1]);
                }

                if ($temp[0] == 'SW_Monitor') {
                                    $arg = '/'.$temp[1];
                                    $this->makeSWMonitorParam($temp[1]);
                }

                if ($temp[0] == 'Color') {
                            $arg = $this->getColor($temp[1]);                                    
                }
                if ($temp[0] == 'Channel' && ( $temp[1] == 'spectrogram' || $temp[1] == 'stack_plot')) unset($argArr[$key]); 
                if ( ($temp[0] == 'anode' || $temp[0] == 'channel') && $temp[1] == 'all') unset($argArr[$key]);

                if ($temp[0] == 'Symbol') {
                                if ($temp[1] == '0') $arg = 'PSYM = -3';
                                else $arg = 'PSYM = '.$temp[1];
                } 
// if ($temp[0] == 'energyCB') $arg = '/enaverage';
        //       if ($temp[0] == 'anodeCB') $arg = '/anaverage';
    }

            $argArrModif = array_values($argArr);
            return implode(',',$argArrModif);
}

        /*
        *  Scatter Arguments parser
        */ 
        protected function parseScatterArguments($args)
        {
            $argArr = explode('&',$args);
    
            foreach ($argArr as $key => &$arg) {
                
                $temp = explode('=', $arg);
                if ($temp[0] != 'Color' && $temp[0] != 'Symbol') unset($argArr[$key]);

                if ($temp[0] == 'Color') {
                                            $arg = $this->getColor($temp[1]);   
                }
                if ($temp[0] == 'Symbol') {
                                            if ($temp[1] == '0') $arg = 'PSYM = -3';
                    else $arg = 'PSYM = '.$temp[1];
                }    
            }        
            $argArrModif = array_values($argArr);
            if (count($argArrModif) > 0) return ','.implode(',',$argArrModif); 
                    else return ''; 
        }

        /*
        *  Simu Arguments parser
        */ 
        protected function parseSimuArguments($args)
        {
            $argArr = explode('&',$args);
            
            $arguments = array();
            foreach ($argArr as $key => &$arg) {
                
                $temp = explode('=', $arg);
                
                $arguments[$temp[0]] = $temp[1];
            }        
            return $arguments; 
        }


    /*
    *  put down list of time tables (tt) and current table (current)
    */   
        protected function prepareTimeTablePlot($dir) 
        {
            //set time from first time table first interval
            $ttMgr = new TimeTableMgr();      
            $timeTables = $this->obj->timeTables;
        //    $firstTable = $timeTables[0];
        //    $tt = $ttMgr->loadIntervalsFromTT($firstTable->id);
        //    $intervals = $tt['intervals']; 
            $offset = 0;  
            $file = fopen($dir.'/tt', 'w');
            foreach ($timeTables as $timeTable) {
                $ttType = (substr($timeTable->id,0,6) == 'shared') ?  'sharedtimeTable' : 'timeTable'; 
                $tt = $ttMgr->loadIntervalsFromTT($timeTable->id, $ttType);
                $intervals = $tt['intervals'];
                $totalCount = $tt['totalCount'];
                fwrite($file,json_encode($timeTable).PHP_EOL); 
                if ($offset == 0) {                        
                    $this->totalInt = $totalCount;
                    $this->ttName = $timeTable->timeTableName;
                    $this->currentInt = 1;
                    $ff = fopen($dir.'/current', 'w');
                    fwrite($ff, $this->totalInt.PHP_EOL);   
                    fwrite($ff, json_encode($timeTable));     
                    fclose($ff);
                    $firstInterval = $intervals[0];
                }
                $offset += $totalCount;
            }
            fclose($file);
            //save current tt object (first one)  and current time interval (first one)            
            return $firstInterval;
        }

        
        /*
        *  put down list of time tables (tt) and current table (current)
        */   
        protected function getFirstTimeTableInterval() 
        {
            //set time from first time table first interval
            $ttMgr = new TimeTableMgr();      
            $timeTables = $this->obj->timeTables;
            
            $firstTable = $timeTables[0];
            //    $tt = $ttMgr->loadIntervalsFromTT($firstTable->id);
            $ttType = (substr($firstTable->id,0,6) == 'shared') ?  'sharedtimeTable' : 'timeTable'; 
            $tt = $ttMgr->loadIntervalsFromTT($firstTable->id, $ttType); 
            $intervals = $tt['intervals']; 
            //save current tt object (first one)  and current time interval (first one)
            $firstInterval = $intervals[0];
            return $firstInterval;
        }
/******************************************************************************
 *  END:  Plot specific functions
*******************************************************************************/

        /*
        * Change NAME in JSON resource
        */
        protected function renameInResource($name, $id) {

                    $obj = json_decode(file_get_contents(USERREQDIR.$id));
                    $obj->name = $name;

                    $file = fopen(USERREQDIR.$id, 'w');
                    fwrite($file, json_encode($obj));
                    fclose($file);                
            }

 
        /*
        *    Make new request/condition resource file (JSON!!) and add it to content file
        *    ATTENTION : it is not DD parameter!!!
        */ 
protected function createParameter($p)
        {
            if ($this -> objectExistsByName($p->name)) {
                        $p->id  = $this->getObjectIdByName($p->name);
                        $this -> deleteObject($p);
                    }
                    $this->id = $this->setId(); 
                    if (!$this->id) return array('error' => ID_CREATION_ERROR);

            //if alias exists, replace alias name by parameter name        
            if (file_exists(USERWSDIR.'Alias.xml')) {
                            if ($this->type == 'condition') {
                                    $p->expression =  $this->resetAlias($p->expression); 
                                    $info = $p->expression;
                            }
                            else if ($this->type == 'request') {
                                    $info = '';
                                    for ($i=0; $i < count($p->children); $i++) {
                                            for ($j=0; $j < count($p->children[$i]->children); $j++) {
                                                    $p->children[$i]->children[$j]->name =  $this->resetAlias($p->children[$i]->children[$j]->name);
                                                    $info = $info.' '.$p->children[$i]->children[$j]->name;
                                            }
                                    }
                            }    
                }
    
                $this->descFileName = USERREQDIR.$this->id;
                $p->id = $this->id;
                // save request as json  
                $file = fopen($this->descFileName, 'w');
                fwrite($file, json_encode($p));
                fclose($file);

                $this -> addToContent($p, $folder);

            return array('id' => $this->id, 'info' => $info);
}
        
        /*
        *        Delete request/condition JSON file
        */
        protected function deleteParameter($id){

                if (file_exists(USERREQDIR.$id)) 
                                unlink(USERREQDIR.$id);
        }

        /*
        * TODO       Check file JSON objects differ in names only
        */
protected function renameOnly($p) {

return false;
        }

        /*
        * Add header in download result
        */  
public function addHeaderInDownloadResult($opts)
{
    //remove previous header if it exist
    if (file_exists('header.txt'))
    unlink('header.txt');
   
//use ParamsInfoMgr to get infor about parameters
$infoMgr = new ParamsInfoMgr();
   
$params = explode(' ',$opts['params']);

if (strcmp($opts['header'],'0') === 0)
{
                            //header in data files
  if (strcmp($opts['structure'],'2') === 0)  
  {
    //one file by param
    foreach ($params as $param)
   {
    $filenames = glob(strtoupper($param)."*.txt");
    if (count($filenames) === 0) 
                            continue;
     foreach ($filenames as $filename) {
        //parameter info
        $infos = $infoMgr->GetParamInfo($param);
        $str = $infoMgr->ParamInfosToString($infos);
        system("sed -i '1i\\#".$str."' '".$filename."'");
        //time info
        $str = "Time Format : ".$opts['timeformat'];
        
        if (strcmp($opts['milli'],'1') === 0)
        {
        if (strcmp($opts['timeformat'],'YYYY-MM-DDThh:mm:ss') === 0)
            $str .= ".mls";
        else
            $str .= " mls";  
        }
        
        system("sed -i '1i\\#".$str."' '".$filename."'");
                                       }
   }
  }
  else
  {
    //all in one file
    $str = "";
   
    foreach ($params as $param)
        {
        $infos = $infoMgr->GetParamInfo($param);
                                    $str .= ('#'.$infoMgr->ParamInfosToString($infos).PHP_EOL);
        }
                            
    $filenames = glob("ALL*.txt");
    if (count($filenames) > 0) 
     foreach ($filenames as $filename)
    {
      $ex_str = explode(PHP_EOL,$str);
       
      //parameters info
      for ($i = sizeof($ex_str)-1; $i >= 0 ; $i--)
       system("sed -i '1i\\".$ex_str[$i]."' '".$filename."'");
     //time info
     $str = "Time Format : ".$opts['timeformat'];
     
     if (strcmp($opts['milli'],'1') === 0)
    {
      if (strcmp($opts['timeformat'],'YYYY-MM-DDThh:mm:ss') === 0)
        $str .= ".mls";
      else
        $str .= " mls";  
    }
     
     system("sed -i '1i\\#".$str."' '".$filename."'");
                                   if (strpos($filename, "NONSTANDARD_SAMPLING") === false) {
                                    //sampling info
                                    $str = "Sampling Time : ".$opts['sampling'];
                                    system("sed -i '1i\\#".$str."' '".$filename."'");
                                    }
   }
  }
}
else
{
 //header in separate file
 $header = fopen("header.txt","w");
 if ($opts['structure'] != '2')
 {
 
  //all in one file- add sampling info
   fprintf($header,"#Sampling Time : ".$opts['sampling'].PHP_EOL);
 }
 //time info
  $str = "#Time Format : ".$opts['timeformat'];
  
  if (strcmp($opts['milli'],'1') === 0)
  {
    if (strcmp($opts['timeformat'],'YYYY-MM-DDThh:mm:ss') === 0)
     $str .= ".mls";
   else
                                $str .= " mls";  
                        }
  
                        //fprintf($header,$str.PHP_EOL);
                        foreach ($params as $param)
                        {
                            //param info
                            $infos = $infoMgr->GetParamInfo($param);
                            $str = $infoMgr->ParamInfosToString($infos);
                            fprintf($header,"#".$str.PHP_EOL);
                        }
                    }
        }
  

        public function compressDownloadResult($id,$newName,$opts)
        {
                if ($opts['downloadSrc'] == '2')
                    $ext = "fits";
                else
                {
                    if (strcmp($opts['fileformat'],'vot') === 0)
                        $ext = "xml";
                    else
                        $ext = "txt";
                }
                    
                if (strncmp($opts['compression'],'zip',3) === 0)
                {
                    system("zip -Dj ".$id." *.".$ext." 1> /dev/null 2> /dev/null");
                    if (strcmp($newname,$id) != 0)
                        rename($id.'.zip',$newName.'.zip');
                }
                else 
                {
                    exec("tar -czf ".$id.".tar.gz  *.".$ext);
                 //   exec("gzip ".$id.".tar");

                    if (strcmp($newname,$id) != 0)
                        rename($id.'.tar.gz', $newName.'.tar.gz');
                }
                                
                foreach (glob("*.".$ext) as $file) 
                    unlink($file);
        }

 
        public function generateVOTableFromDownloadResult($id,$newName,$inputCompressed = true,$canBeAlreadyVOTable = false)
        {
                $resultDir = USERWORKINGDIR.$id.'_/';
                $opts = $this->getPrintOptions($resultDir);
                
                $votMgr = new BuildVOTable();
                        return $votMgr->downloadResultToVOTable($id,$newName,$opts,$inputCompressed,$canBeAlreadyVOTable);
        }
 
        /*
         *      Renaming and zipping of PDF/PS
        */
        public function postProcessing($id, $newName) {

                switch ($this->type) {
                    case 'download' :
                            $resultDir = USERWORKINGDIR.$id.'_/';
                            
                            $opts = $this->getPrintOptions($resultDir);
                            
                            if ((strcmp($opts['downloadSrc'],'2') !== 0) && (strcmp($opts['fileformat'],'vot') !== 0))
                            {
                                //add header
                                $this->addHeaderInDownloadResult($opts);
                            }
                            
                            //generate votable if necessary
                            if ((strcmp($opts['fileformat'],'vot') === 0))
                                $this->generateVOTableFromDownloadResult($id,$newName,false,false);
                                
                            //compression
                            $this->compressDownloadResult($id,$newName,$opts);
                                
                    break;
                case 'condition' :   
                                break;
                case 'request' :
                            $resultDir = USERWORKINGDIR.$id.'_/';
                            switch ($this->obj->format) {                            
                                case 'PS' :
                                    if (file_exists($resultDir.'idl.ps')) {
                                        rename($resultDir.'idl.ps',$resultDir.$newName.'.ps');
                                        exec('gzip '.$resultDir.$newName.'.ps'); 
                                    }
                                break;
                                case 'PDF' : 
                                    if (file_exists($resultDir.'idl.ps'))  
                                                exec('ps2pdf -sPAPERSIZE=a4 '.$resultDir.'idl.ps');
                                    unlink($resultDir.'idl.ps');
                                    rename($resultDir.'idl.pdf',$resultDir.$newName.'.pdf');
                                break;
                                default : 
                            } 
                        break;

                default :
                }
            }

        /*
        * Get real IDL plot settings : !x.window & !y.window for each panel
        */
        protected function getPlotSettings(){

            if (!file_exists('plotSettings')) return null;
            $settings = file('plotSettings');
            $plotSetting = new stdClass();
                    
            for ($i = 0; $i < count($settings)/2; $i++) {
                $xArr = explode(' ',trim($settings[$i*2]));
                $yArr = explode(' ',trim($settings[$i*2+1]));
                $plotSetting->xmin =  $xArr[0];
                $plotSetting->xmax =  $xArr[count($xArr)-1];
                $plotSetting->ymin =  $yArr[0];
                $plotSetting->ymax =  $yArr[count($yArr)-1];
                $plotSettings[$i] = $plotSetting;
            }
            return $plotSettings;
        }

/******************************************************************************
*  Start:  Print specific functions
******************************************************************************/ 

        protected function makePrintRequest($dir) 
        {
            $ff = fopen($dir.'print.res','w');
            foreach ($this->obj->list as $param) {
                if ((strncmp($param, "impex___", 8) === 0) || (strncmp($param, "spase___", 8) === 0)){
                    $argumentsByParam = $this->cutSimuArgs($param);
                            foreach ($argumentsByParam as $key => $value) $param = $key;
                }
                fwrite($ff, $this->param2dd_print($param).' ');
            }
            if ($this->obj->structure == '2') {
                fwrite($ff, PHP_EOL.'multi -1'.PHP_EOL);
            }
            else {
                fwrite($ff, PHP_EOL.'uniq '.$this->obj->sampling.PHP_EOL);
            }
            fwrite($ff,'none'.PHP_EOL);
            $timeFormatNumber = $this->obj->milli ? 
                                $this->timeFormat[$this->obj->timeformat] + 4 : $this->timeFormat[$this->obj->timeformat];
            fwrite($ff, $timeFormatNumber.PHP_EOL);
            fclose($ff);
        }
      
        protected function createPrintRequestTime($dir) 
        {
            $ff = fopen($dir.'print.list','w');
            fwrite($ff,$this->getDdTime($this->obj->startDate).PHP_EOL);
            fwrite($ff,$this->getDdInterval().PHP_EOL);

            fclose($ff);
        }

        protected function createPrintPostOptions($dir) 
        {
            $ff = fopen($dir.'print.opt','w');
            fwrite($ff,$this->obj->compression.PHP_EOL);
            fwrite($ff,$this->obj->fileformat.PHP_EOL);
            fwrite($ff,$this->obj->header.PHP_EOL);
            fwrite($ff,$this->obj->structure.PHP_EOL);
            foreach ($this->obj->list as $param)
            {
 
              if ((strncmp($param, "impex___", 8) === 0) || (strncmp($param, "spase___", 8) === 0)){
		$argumentsByParam = $this->cutSimuArgs($param);
		foreach ($argumentsByParam as $key => $value) $param = $key;
	    }
 
                    if ($this->obj->downloadSrc == '2')
                        fwrite($ff, $param->url.' ');
                    else
                        fwrite($ff, $param.' '); //data
            }
            fwrite($ff,PHP_EOL.$this->obj->sampling.PHP_EOL);
            fwrite($ff,$this->obj->timeformat.PHP_EOL);
            if ($this->obj->milli)
                fwrite($ff,'1'.PHP_EOL);
            else
                fwrite($ff,'0'.PHP_EOL);
            fwrite($ff,$this->obj->downloadSrc.PHP_EOL);
            fclose($ff);
        }

        protected function getDateArray()
        {
            if ($this->obj->startDate){
                $matches=array();
                $tmpArr = explode("T", $this->obj->startDate);
                $dateArr = explode("-", $tmpArr[0]);
                $timeArr = explode(":", $tmpArr[1]);
                preg_match("/([0-9]+)/", $timeArr[2], $matches);

                return array("success" => true, 
                            "year"  => ($dateArr[0]),
                            "month" => ($dateArr[1]),
                            "day"   => ($dateArr[2]),
                            "hour"  => ($timeArr[0]),
                            "min"   => ($timeArr[1]),
                            "sec"   => ($matches[1])
                );
            }
            else
                return array('success' => false);    
        }

        protected function getStopDate()
        {
            $date = $this->getDateArray ();
            return gmdate("Y-m-d\TH:i:s\Z", mktime($date['hour'] + intval($this->obj->durationHour), $date['min']+ intval($this->obj->durationMin), $date['sec']+ intval($this->obj->durationSec), $date['month'], $date['day']+ intval($this->obj->durationDay), $date['year'])); 
        }


/******************************************************************************
 *  End:  Print specific functions
*******************************************************************************/  

/*****************************************************************
*                           PUBLIC FUNCTIONS
*****************************************************************/

        public function getPrintOptions($dir) 
        {
                $postOptions = file($dir.'print.opt');
                return array('compression'  => trim($postOptions[0]),
                            'fileformat'   => trim($postOptions[1]),
                            'header'       => trim($postOptions[2]),
                            'structure'    => trim($postOptions[3]),
                            'params'       => trim($postOptions[4]),
                            'sampling'     => trim($postOptions[5]),
                            'timeformat'   => trim($postOptions[6]),
                            'milli'        => trim($postOptions[7]),
                            'downloadSrc' => trim($postOptions[8]));
        }

        public function updatePrintRequestTime($dir, $interval) 
        {
                $ff = fopen($dir.'print.list','w');
                fwrite($ff,$this->getDdTime($interval['start']).PHP_EOL);
                fwrite($ff,$this->calculateTimeInt($interval).PHP_EOL);

                fclose($ff);
        }
        
        public function updatePrintSampling($dir, $sampling) 
        {
                $ff = file($dir.'print.res');
                $newSampling = explode(' ',$ff[1]);
                $ff[1] = $newSampling[0].' '.$sampling.PHP_EOL;

                file_put_contents($dir.'print.res',$ff);
        }

        public function setZoomStart($interval)
        {
            if (!$interval) {
                $time = strtotime($this->obj->startDate);
                $dt = $this->obj->durationDay*86400 +
                                    $this->obj->durationHour*3600 +
                                    $this->obj->durationMin*60 + $this->obj->durationSec;
        
                $stopTime = gmdate("Y-m-d\TH:i:s",$time+$dt); 
                $interval['start'] = $this->obj->startDate;
                $interval['stop'] = $stopTime;
            }
            $ff = fopen('zoom_intervals','w');
            fwrite($ff, json_encode($interval).PHP_EOL);
            fclose($ff);  
        }

        /*
        * Launch process in bkgr; return PID
        */
        public function background($Command)
        {
            $PID = exec("$Command 1> /dev/null 2> /dev/null & echo $!");
            if ($PID != null)  return $PID;

            return false;
        }

        /* Stop Time from StartTime and Interval*/ 
        public function convertTime($obj)
        {

                $time = strtotime($obj->startDate);

                $interval = $obj->durationDay*86400 +
                            $obj->durationHour*3600 +
                            $obj->durationMin*60 + $obj->durationSec;
                $stopTime = gmdate("Y-m-d\TH:i:s", $time+$interval);
                $obj->stopDate = $stopTime;

                return $obj;
        }

        /*
        * Update Time in request 
        */
        public function updateTime($requestName, $interval) 
        {
            $requestFile = file($requestName); 
            $request = fopen($requestName,'w');

            $nObjects = 1 + $requestFile[0]; 

            for ($k = 0; $k < $nObjects; $k++) fwrite($request,$requestFile[$k]);
            
            fwrite($request,$this->getDdTime($interval['start']).PHP_EOL);
            fwrite($request,$this->calculateTimeInt($interval).PHP_EOL);

            fclose($request);          
        }

        //From Start Time and Stop Time 
        public function createSearchRequestTime2($interval) 
        {
                $this->request = fopen(USERWORKINGDIR.'search.list','w');

                fwrite($this->request,$this->getDdTime($interval['start']).PHP_EOL);
                fwrite($this->request,$this->calculateTimeInt($interval).PHP_EOL);

                fclose($this->request);
        }

        //TODO 
        public function markAsUndefined($paramId)
        {
            $n_requests = 0;

            return $n_requests;
        }

        /*
        *   Get Object JSON!!! (request or condition) into Edit
        */ 
        public function getObject($id) 
        {
                    if (!file_exists(USERREQDIR.$id)) return array('error' => NO_OBJECT_FILE);
                
                    if (!($objToGet = $this->contentDom->getElementById($id))) return array('error' => NO_SUCH_ID);
                    $obj = json_decode(file_get_contents(USERREQDIR.$id));
                    //if alias exists, replace parameter name by alias name        
                    if (file_exists(USERWSDIR.'Alias.xml')) {
                        if ($this->type == 'condition') {
                                $obj->expression =  $this->setAlias($obj->expression); 
                        }
                        else if ($this->type == 'request') {
                                for ($i=0; $i < count($obj->children); $i++) {
                                        for ($j=0; $j < count($obj->children[$i]->children); $j++) {
                                                $obj->children[$i]->children[$j]->name =  $this->setAlias($obj->children[$i]->children[$j]->name);
                                        }
                                }
                                //TODO Ajout des SCATTER
                                // if $obj->children[$i]->plotType == "SCATTER" 
                                //$obj->children[$i]->scatterParam->data->name pour 1 panel (bug si 2 panels devient $obj->children[$i]->scatterParam->data->data->name)
                            }    
                    }      
                    //if Start Time - Stop Time
                    if (!$obj->timeTables) $obj =  $this->convertTime($obj);    
                return  $obj;
        }

        public function cachekiller()
        {
                $date = getdate();
                $cachekiller = $date['mday'].$date['hours'].$date['minutes'].$date['seconds'];

            return $cachekiller;
        }

        public function killPlot($tabId)
        {
                $tmpname =  'Plot'.$tabId;
                
                $resDirPng = USERWORKINGDIR.$tmpname.'_';
                
                if (!is_dir($resDirPng))
                    return array('success' => false, 'message' => 'Cannot find workind directory');
                    
                touch($resDirPng."/cancelplot");
        
            return array('success' => true);
        }
      
        public function killMultiPlot($tabIds)
        {              
            if (!is_dir(USERWORKINGDIR."CANCELPLOT")) 
                                mkdir(USERWORKINGDIR."CANCELPLOT");

            foreach ($tabIds as $tabId)    
                    touch(USERWORKINGDIR."CANCELPLOT/".$tabId);
        
            return array('success' => true);
        }


        public function initResDir($tmpname)
        {
                $resDir = USERWORKINGDIR.$tmpname.'_/';

                if (!is_dir($resDir)) {
                        if (!mkdir($resDir, 0775)) 
                            return array('success' => false, 'error' => 'can\'t create directory'); 
                    }

                if (!chdir($resDir)){
                        return array('success' => false, 'error' => 'can\'t change directory');
                    }

            return array('success' => true, 'resdir' => $resDir);
        }

        /*
        *  Try to estimate File Size from param size, time int and sampling
        */
        public function estimateOutputFileSize($obj, $ttInterval)
        {
            $timeConvert = array("s" => 1, "m" => 60, "h" => 3600);

            if (!$obj) $obj = $this->obj;

            $interval = $ttInterval ? $ttInterval : $obj->durationDay*86400 +
                                                    $obj->durationHour*3600 +
                                                    $obj->durationMin*60 + $obj->durationSec;

            $infoMgr = new ParamsInfoMgr();

            $multi = $obj->structure == 2;

            $timeLength = $obj->milli ? 25 : 20;

            $fileSize = $multi ? 0 : $timeLength;
            $sampling_virtual = 60.0;
            $size_virtual = 1;

            foreach ($obj->list as $param) {

                    $info = $infoMgr->GetParamInfo($param);

                    if (!$info['success']) {
                        $size = $size_virtual;
                        $sampling = $sampling_virtual;
                    } 
                    else {
                        // derived parameter
                        if (strncmp(strtolower($param), 'ws_', 3) == 0) { 
                            $size = 1;                                  
                            if ($multi) {                                                                                
                                    $sampling = $info['infos']['timestep']; 
                                }                 
                        }  
                        // my data parameter
                        else if (strncmp(strtolower($param), 'wsd_', 4) == 0) {                                 
                            $size = $info['infos']['size'];
                            $sampling = $info['infos']['minsampling'];                          
                        }
                        else {                                                                                     
                            $codeinfo = $info['codeinfos'];
                            $ddinfo = $info['ddinfos'];
                            if ($codeinfo) {
                                $size = $codeinfo['size'];
                                $sampling = $codeinfo['minsampling']; 
                            }
                            else {
                                $size = $ddinfo['parameter']['size'];
                                $sampling = substr($ddinfo['dataset']['minsampling'], 0, -1);  
                                $sampling *= $timeConvert[substr($ddinfo['dataset']['minsampling'], -1)];
                            }
                            // if component
                            if (sscanf($param,"%[^'('](%d)",$par,$cstart) == 2) $size = 1;
                        }
                    }

                    if ($multi) {
                        $fileSize += $interval / $sampling * ($size * 13 + $timeLength); 
                    }
                    else {
                        $fileSize += $size * 13;
                    }                                   
            }

            if (!$multi) {
                $fileSize *= $interval / $obj->sampling;
            }
        
            if ($obj->fileformat === 'vot')
                $fileSize *= 1.8;

            return  $fileSize;
        }
      
        /*
        *   THE MAIN EXECUTE PART
        */
        public function execute($obj) 
        {
            $this -> setObject($obj);
        
            //TODO define user in AmdaAction constructor : unique SESSION_ID   
            if (isset($obj->username) && isset($obj->password) && isset($obj->sessionID))
            {
                $dd = new WSUserMgr();
                $dd->init($obj->username,$obj->password,$obj->sessionID);
            }
            else
                $dd = new UserMgr();

            //TODO error handling 
            if (($res = $dd -> ddCheckUser()) != 0) {
                if ($res == 156) 
                    return array('error' => 'Your AMDA session is expired.<br/> Login please!');

                return array('error' => 'ddLogin error: '.$res);
                }

            if ($dd->user == 'impex') {
                if ($dd->getWsSize() > DISK_QUOTA * 100)
                    error_log('Natacha! It is time to CLEAN UP IMPEX WS!',1,'nbourrel@irap.omp.eu');
            }
            else {
                // check disk space
                if ($dd->getWsSize() > DISK_QUOTA)
                    return array('error' => 'Please clean up your workspace.<br/>No more space is available');
            }

            $isMulti =  $this->obj->timeTables ? true: false; 

            //  AMDA Statistics
            $amdaStat = new AmdaStats($dd->user);
        
            chdir(USERWORKINGDIR);
                    
            // temp name for output    
            $cachekiller = $this->cachekiller();
            $text = 'result';
            if ($this->obj->name) $text = $this->obj->name;
            if ($this->obj->output) $text = $this->obj->output;
            if ($this->obj->outputName) $text = $this->obj->outputName;
                
            $newName = $text.'_'.$cachekiller;

            // temp name for output
            $tmpname = $this->getRandomName();
            $isPNG = false;

            if ($this->obj->format && $this->obj->format == 'PNG') 
            {
                        $isPNG = true;
                        $tmpname =  'Plot'.$this->obj->tabId;
            }
            
            //TODO organize better : functions, classes? 
            switch ($this->type) 
            {
                    // DD Search
                    case 'condition':
                        $tmpname =  $newName;
                        //if alias exists, replace alias name by parameter name
                        if (file_exists(USERWSDIR.'Alias.xml')) 
                        {
                            $obj->expression = $this->resetAlias($obj->expression);
                        }
                        $realVars = $this -> makeSearchParams(); 
                    
                        if ($amdaStat->success) 
                            $amdaStat->addTask('mining', $dd->user, $realVars);

                        $this -> createSearchRequest($realVars, $tmpname);
                        
                        if ($this->paramsWithoutCode) 
                            $this->makeLocalParams($realVars);
                
                        if ($isMulti) {      
                            $cmd = 'php '.CLASSPATH.'../MultiRequestMgr.php \''.json_encode($this->obj).'\' \''.$tmpname.'\' \''.$dd->user.'\' \''.$dd->IP.'\''; 
                        }
                        else {
                            $this -> createSearchRequestTime();            
                            $cmd = DDBIN."DD_Search ".$dd->user." ".$dd->IP." ".DDPROJECT." ".DDPROJLIB;
                        }
                        break;
                    // DD Print
                    case 'download':

                        if ($this->obj->downloadSrc == 0) {
                            if (file_exists(USERWSDIR.'Alias.xml')) {
                                    foreach($this->obj->list as &$param)
                                        $param = $this->resetAlias($param);
                            } 
                            $isSimu = false;
                            foreach ($this->impex_prefix as $impex_prefix) if (strpos($param, $impex_prefix) !== false) $isSimu = true;
                            
                            if ((!$isMulti) || (!$isSimu)) {
                                $outputFileSize = $this->estimateOutputFileSize();
                                if ( $outputFileSize > DISK_QUOTA ) { //DISK_QUOTA
                                    $outputFileSize /= 1024*1024;
                                    return array('error' => "Sorry! Requested file is too large: ".$outputFileSize."MB 
                                                        <br/>Decrease requested time interval" );
                                }
                            }
                        }

                        $res = $this->initResDir($tmpname);
                        if (!$res['success'])
                                return $res;

                        $resDir = $res['resdir'];
                    
                        switch ($this->obj->downloadSrc)
                        {
                            case '2' : //fits images

                                $this->createPrintPostOptions($resDir);
                                $cmd = '';
                                foreach ($this->obj->list as $file) {
                                    if ($cmd != '')
                                        $cmd .= "|";
                                    $cmd .= "wget -O ".$file->name." \"".$file->url."\"";
                                }
                                break;

                            case '0' : //data

                                if ($amdaStat->success)                        
                                    $amdaStat->addTask('print', $dd->user, $obj->list);
                                
                                if ($this->paramsWithoutCode) 
                                        $this->makeLocalParams($obj->list);
                                if ($this->spectraParams) 
                                        $this->makeSpectraParams($obj->list);
                                if ($this->dataBases) 
                                        $this->makeRemoteParams($obj->list); 
                                    
                                $this->makeWsParams($obj->list);

                                $wsdVars = $this->getWsdVars($obj->list);
                                if ($wsdVars) $this->makeWsdParams($wsdVars);
                                
                                 // if 'impex' in $realVars upload simulation data 
                                $impexVars = $this->getImpexVars($obj->list);
                                $imp = array('realVars'=> $impexVars, 'fromWS' => true);
                                if ($impexVars) $this->makeWsrParams($imp);
                                
                                $this->makePrintRequest($resDir);  
                                $this->createPrintPostOptions($resDir);

                                if ($isMulti) {     
                                    $cmd = 'php '.CLASSPATH.'../MultiRequestMgr.php \''.json_encode($this->obj).'\' \''.$tmpname.'\' \''.$dd->user.'\' \''.$dd->IP.'\' \''.$newName.'\''; 
                                }
                                else
                                {                            
                                    $this->createPrintRequestTime($resDir); 
                                    $cmd = DDBIN.'DD_Print '.$dd->user.' '.$dd->IP.' '.DDPROJECT.' '.DDPROJLIB; 
                                }
                               break;
                        }
                        break;
                    // DD Plot / DD PS
                    case 'request':
                    //if alias exists, replace alias name by parameter name
                        if (file_exists(USERWSDIR.'Alias.xml')) 
                        {
                            for ($i=0; $i < count($obj->children); $i++) 
                            {
                                    for ($j=0; $j < count($obj->children[$i]->children); $j++) 
                                    {
                                        $obj->children[$i]->children[$j]->name =  $this->resetAlias($obj->children[$i]->children[$j]->name);
                                    }
                            }
                        }

                        // For PNG, PS, PDF  
                        $res = $this->initResDir($tmpname);
                        if (!$res['success'])
                                    return $res;
                        $resDirPng = $res['resdir'];

                        if (file_exists($resDirPng."/cancelplot"))
                                    unlink($resDirPng."/cancelplot");

                        // general Plot settings : DD_request.res
                        $this -> setPlot();
 
                        // amda statistics 
                        if ($amdaStat->success) {
                            $varArray = array();
                            foreach ($this->obj->children as $panel)  
                                foreach ($panel->children as $plotVar)                           
                                                $varArray[] = $plotVar->text;                     
                            $amdaStat->addTask('plot', $dd->user, $varArray);   
                        }

                        // panels definitions  with/without time
                        $realVars = $this->setPlotObjects($this->obj->children, $tmpname);                               
                        if ($this->paramsWithoutCode) $this->makeLocalParams($realVars);
                       
                        $this->makeWsParams($realVars);

                        $wsdVars = $this->getWsdVars($realVars);
                        if ($wsdVars) $this->makeWsdParams($wsdVars);

                 //       if 'impex' in $realVars upload simulation data
                        $impexVars = $this->getImpexVars($realVars); 
                        $imp = array('realVars'=> $impexVars, 'fromWS' => false);
                        if ($impexVars) $this->makeWsrParams($imp);
                   
                        //Interactive session : create special folder
                        if ($this->obj->format == 'PNG') 
                        {                       
                            // Time table plot
                            if ($isMulti) 
                            {
                                $interval = $this->prepareTimeTablePlot($resDirPng);
                                $this->updateTime('./'.$tmpname, $interval); //update/add time
                                $this->setZoomStart($interval);  
                            }
                            else 
                                $this->setZoomStart();
                                $cmd = DDBIN."DD_Plot ".$tmpname." ".$dd->user." ".$dd->IP." ".DDPROJECT." ".DDPROJLIB;
                        }
                        else 
                        { 
                            if ($isMulti) {   
                                $cmd = 'php '.CLASSPATH.'../MultiRequestMgr.php \''.json_encode($this->obj).'\' \''.$tmpname.'\' \''.$dd->user.'\' \''.$dd->IP.'\' \''.$newName.'\'';  
                            }
                            else {                         
                                $cmd = DDBIN."DD_PS ".$tmpname." ".$dd->user." ".$dd->IP." ".DDPROJECT." ".DDPROJLIB;  
                            } 
                        }  
                        break;

                    default :
                        return array('error' => $this->type." NOT IMPLEMENTED YET");
                }
                $pid =  $this->background($cmd);    
                //TODO KILL method for real TIMEOUT
                $jobMgr = new JobsMgr();
                $cyclesNumber = $isPNG  ? PLOT_CYCLES_NUMBER: JOB_CYCLES_NUMBER;  
            
                $reqStart = time();
            
                //TODO return ERRORS also
                for ($cycle = 0; $cycle < $cyclesNumber; $cycle++) 
                {
                        sleep(JOBTIMEOUT); 
                        
                        $reqTime = time() - $reqStart;
                        
                        if ($reqTime > $cyclesNumber*JOBTIMEOUT)
                        break;

                        if ( $isPNG && is_dir(USERWORKINGDIR."CANCELPLOT") ) {
                        if (file_exists(USERWORKINGDIR."CANCELPLOT/".$this->obj->tabId))
                                        rename(USERWORKINGDIR."CANCELPLOT/".$this->obj->tabId,$resDirPng."/cancelplot");

                        if (count(scandir(USERWORKINGDIR."CANCELPLOT")) == 2) rmdir(USERWORKINGDIR."CANCELPLOT");

                        }
                        if ( $isPNG && file_exists($resDirPng."/cancelplot"))
                        {
                            if (!$jobMgr->isFinished($pid))
                            { 
                                $cmd = 'kill -9 '.$pid;
                                exec($cmd);
                            }

                            foreach (glob($resDirPng.'/*') as $filename)
                                unlink($filename);

                            rmdir($resDirPng);
                        
                        return array('error' => "Plot canceled!");
                        }

                        if ($jobMgr->isFinished($pid))
                        {
                            if (!$isPNG) $newId = $jobMgr->addJob($this->obj, 0, $tmpname, $newName);

                            if ($tmpname !== $newName) $this->postProcessing($tmpname, $newName);
                            $arrayMain = array('pid' => '0', 'name' => $newName, 'id' => $tmpname);
                                        
                            if ($isPNG) 
                            { 
                                $outputName = $this->obj->outputName? $this->obj->outputName : $tmpname;  
                                rename($tmpname.'.png', $outputName.'_'.$cachekiller.'.png');
                                $arrayMain['name'] = $outputName.'_'.$cachekiller;
                            
                                $plotSettings = $this->getPlotSettings();
                                $arrayMain['children'] = $plotSettings; 
                                $arrayMain['tabId']  =  $this->obj->tabId; 
                                // PNG plotting of time tables
                                if ($isMulti) 
                                {
                                    $arrayTable = array('startDate' => $interval['start'],
                                                        'stopDate' => $interval['stop'], 
                                                        'intervalN' =>  $this->currentInt, 
                                                        'totalN' => $this->totalInt,
                                                        'tableName' => $this->ttName);      
                                    return array_merge($arrayMain, $arrayTable);
                                }
                            }
                        return $arrayMain;  
                        }
                } 

                // Add Job in BATCH MODE        
                $newId = $jobMgr->addJob($this->obj, $pid, $tmpname);

                return array('pid' => $pid, 'id' => $newId, 'rawname' => $tmpname);                
        }
}
?>