<?php


function GRAPH_VIEW_PROCES() {
	$id_proces = V::get('id_proces', '', $_REQUEST, 'int');
	if ($id_proces <= 0) {
		echo'<p class="err box box-red">'."Wrong ID".'</p>';
		return;
	}

	$db = DB::getDB();
	$proces = $db->get_by_id('CRM_PROCES', $id_proces);
	if (!$proces) {
		echo'<p class="err box box-red">'."Process {$id_proces} not exists".'</p>';
		return;
	}

	$ajaxTask = V::get('ajaxTask', '', $_REQUEST);
	if ($ajaxTask == 'getInfo') {
		$id = V::get('id', 0, $_REQUEST, 'int');
		if ($id > 0) {
			$step = $db->get_by_id('CRM_PROCES', $id);
			//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;"> (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($step);echo'</pre>';
			?>
			<p><code><?php echo $step->ID; ?></code> <?php echo $step->DESC; ?></p>
			<p><?php echo $step->OPIS; ?></p>
			<?php
		}
		exit;
	}

	$graph = new stdClass();
	$graph->htmlID = 'graph_proces_id_' . $id_proces;
	$graph->procesTreeFlat = array();
	$graph->procesTreeGoto = array();
	$graph->treeItems = array();

	$graph->elements = new stdClass();
	$graph->elements->nodes = array();
	$graph->elements->edges = array();
	/*	elements: {
				nodes: [
					{ data: { id: 'j', name: 'Jerry' } },
					{ data: { id: 'e', name: 'Elaine' } },
					{ data: { id: 'k', name: 'Kramer' } },
					{ data: { id: 'g', name: 'George' } }
				],
				edges: [
					{ data: { source: 'j', target: 'e' } },
					{ data: { source: 'j', target: 'k' } },
					{ data: { source: 'j', target: 'g' } },
					{ data: { source: 'e', target: 'j' } },
					{ data: { source: 'e', target: 'k' } },
					{ data: { source: 'k', target: 'j' } },
					{ data: { source: 'k', target: 'e' } },
					{ data: { source: 'k', target: 'g' } },
					{ data: { source: 'g', target: 'j' } }
				]
			},
	 */


	function graph__addNodeID($id, &$graph,$name=null,&$path,$parent=null,$type) {
		if (!array_key_exists($id, $graph->treeItems)) {
			$graph->treeItems[$id]= true;
			if(empty($name)) $name=$id;
			if(!empty($path))  { $name=$name." ".implode(',', $path);// $path=array(); 
			}
			//DEBUG_S(-3,'added id,name,path,parent',array($id,$name,$path,$parent),__FILE__,__FUNCTION__,__LINE__);

			if($type=='PROCES_INIT') $type_init='procesInit'; else $type_init=null;
			//echo $type_init.$id;
			$graph->elements->nodes[] = array('data'=>array('id'=>"".$id."", 'name'=>$name , 'type'=>$type_init));
			
			if(!empty($parent)) $graph->elements->edges[] = array('data'=>array('source'=>$parent, 'target'=>$id  ));
			//echo "<br> w AddNode:";
		}
	}
	
	 
	 
class crm_proces_paser {

  // var $this->get_proces_init=array();

 // [proces_init]  - A
 //    [step]      - flat 0
 //    [step]      - flat 3 , tree 2 , cut
 //     [step]     - flat 0 , tree 0
 //     [step]     - flat 1 , tree 1
 //       [step]   - flat 1 , tree 1
 //         [step] - flat 0 , tree 0
 //     [step]     - flat 1 , tree 1
 //       [step]   - flat 0 , tree 0
 


   function TestIfHasDeep($id_proces_step) {
		 $sql="select `ID`,`IF_TRUE_GOTO` from `CRM_PROCES` where `PARENT_ID`=$id_proces_step and  `A_STATUS` in ('WAITING','NORMAL') ";
		 $res=DB::query($sql);
		 while($h=DB::fetch($res)) {
			 $ret[$h->ID]='PARENT_ID';
		 }
		 
		 $sql="select `ID`,`IF_TRUE_GOTO`,`IF_TRUE_GOTO_FLAG` from `CRM_PROCES` where `ID`=$id_proces_step and `IF_TRUE_GOTO`>0 and  `A_STATUS` in ('WAITING','NORMAL') ";
		  $res=DB::query($sql);
		  	while($h=DB::fetch($res)) {
			 $ret[$h->IF_TRUE_GOTO]=$h->IF_TRUE_GOTO_FLAG;
			 }
		 return $ret;
	 }
   //funckcja do szukania proces_init
   function get_proces_init() {
	$sql= "select p.`ID`,`DESC` from `CRM_PROCES` as p where  p.`A_STATUS` in('WAITING','NORMAL') and p.`TYPE`='PROCES_INIT' and ID=994 limit 1";
	echo $sql;
	$res=DB::query($sql);
		while($h=DB::fetch($res)) {
			$this->get_proces_init[]=$h->ID;
		}
		return $this->get_proces_init;
	
   }

   function build_proces_init_tree($id_proces) {
	  // $tree->Childs[$id_proces]=true;
	   $tree->Childs[$id_proces]->PARENT=0;
	   $tree->Parents[0]->CHILD[$id_proces]=$id_proces;
	   $obj=DB::get_by_id('CRM_PROCES',$id_proces);
	   $tree->Childs[$id_proces]->TYPE=$obj->TYPE;
	   self::build_tree_for_proces($tree,$id_proces);
	   return $tree;
   }
   
      function build_tree_for_proces(&$tree,$cursor) {
	      	   $sql="select `ID`,`IF_TRUE_GOTO`,`IF_TRUE_GOTO_FLAG` , `TYPE` from `CRM_PROCES` where PARENT_ID={$cursor} and  `A_STATUS` in ('WAITING','NORMAL')";
		  	  // echo "<br>sql: ".$sql;
	      	   $res=DB::query($sql);
	      	   	      	   while ($h=DB::fetch($res)) {
	      	   	   $tree->Childs[$h->ID]->PARENT=$cursor;
	      	   	   $tree->Parents[$cursor]->CHILD[$h->ID]=$h->ID;
		  	   	   $tree->Childs[$h->ID]->TYPE=$h->TYPE;
	      	   	   if($h->IF_TRUE_GOTO>0) { 
	      	   	      $tree->Childs[$h->ID]->GOTO_FLAG=$h->IF_TRUE_GOTO_FLAG;
	      	   	      $tree->Childs[$h->ID]->IF_TRUE_GOTO=$h->IF_TRUE_GOTO;
	      	   	   }
		      	   self::build_tree_for_proces($tree,$h->ID);
	      	   }
      }

      function build_tree_flat_info(&$tree,$flat) {
		  /* >> zbudowanie ile ma dzieci <<
			  $tree->Childs[3208] => stdClass Object
			  (
            [PARENT] => 3123
            [CHILD] => Array
                (
             >>       [3219] => 1 <<
             >>       [3237] => 0 <<
             >>       [3209] => 0 <<
                 
			 */
	      foreach($tree->Childs as $id=>$obj) {
			  //sprawdzmy czy nasz parent wymaga wyswietlenia osobnego podkroku w widoku szczegolowego procesu
		      foreach($tree->Parents[$id]->CHILD as $child) {
			      $tree->Childs[$id]->CHILD[$child]=count($tree->Parents[$child]->CHILD);     
		      }
	      }    
      }
      
      
      function detect_tree_where_to_detail_cut(&$tree) {
	       foreach($tree->Childs as $id=>$obj) {
			  //sprawdzmy czy nasz parent wymaga wyswietlenia osobnego podkroku w widoku szczegolowego procesu
			  $control=0;
		      foreach($obj->CHILD as $child) {
			      if($child>0) $control++;   
		      }
		      if($control>1) $tree->Childs[$id]->TO_DETAIL_CUT_FLAG=true;
	      }       
      }
      function search_parent_ids_till_cut($tree,$init,&$find) {
	      if(!isset($tree->Childs[$init]->TO_DETAIL_CUT_FLAG)) {
	      		  $find[]=$init;
//		  		  self::zoom_process_links($tree,$init);
		      foreach($tree->Childs[$init]->CHILD as $id=>$count) {
			      self::search_parent_ids_till_cut($tree,$id,$find);
		      }
	      }
      }
      
      function zoom_process_links($tree,$id,$root_id) {
	      
	      if(isset($tree->Childs[$id]->GOTO_FLAG)) {
					  	if(isset( $tree->Childs[$tree->Childs[$id]->IF_TRUE_GOTO])) {
						  	//adding internal link to the same process
						  	$tree->Viev_Zpc[$id]->INTERNAL_LINK[$tree->Childs[$id]->IF_TRUE_GOTO]=$tree->Childs[$id]->IF_TRUE_GOTO;

						  	
					  	} else { echo "<br>Links zewnetrzny do ".$id." - ".$tree->Childs[$id]->IF_TRUE_GOTO;
					  		$tree->Viev_Zpc[$id]->EXTERNAL_LINK[$tree->Childs[$id]->IF_TRUE_GOTO]=$tree->Childs[$id]->IF_TRUE_GOTO;
					  	}
				  	} 

	      
      }
      
      function build_path_zoom_proces_cut(&$tree,$init,$path_zpc=array()) {
	      //funkcja do pokazania procesow wyplaszczonych, z wypunktowanymi rozgalezieniami - buduje drzewo w sposob inteligentny
		  //szukam rekordow z gory do pierwszego CUT
		  foreach($tree->Childs as $id=>$obj) {
		  		if(!isset($tree->Viev_Zpc_found[$id])) {
			  		//echo "<br>szukam parentow dla ".$id;
				  	self::search_parent_ids_till_cut($tree,$id,$find);
				  	//echo "<br>find:";print_r($find);
				  	foreach($find as $find_id) {
				  		$tree->Viev_Zpc_found[$find_id]=$find[0];
				  	}
				  	$tree->Viev_Zpc[$id]->PATH=$find;
				  					  	unset($find);
			  	}
		  	
		  }
		  
		  	      
      }
      
      
}	 
	 
	 
	 

	 
	 
	 
	 
	 $cp=new crm_proces_paser;
	$PROC_GET=1349;
		$PROC_GET=$id_proces;
	 $init=$cp->get_proces_init();
	 $tree=$cp->build_proces_init_tree($PROC_GET);
	 $cp->build_tree_flat_info($tree,null);
     $cp->detect_tree_where_to_detail_cut($tree);
	 $cp->build_path_zoom_proces_cut($tree,$PROC_GET);
	 DEBUG_S(-3,'get_proces_init',$init);
	 DEBUG_S(-3,'tree->childs',$tree->Childs);
	 DEBUG_S(-3,'tree->Parents',$tree->Parents);
	 DEBUG_S(-3,'tree->Viev_Zpc',$tree->Viev_Zpc);

	 	  graph__addNodeID(0, &$graph,$name=null,$path,null);
	 foreach($tree->Viev_Zpc as $id=>$obj) {
		  graph__addNodeID($id, &$graph,$name=null,$obj->PATH,$tree->Childs[$id]->PARENT,$tree->Childs[$id]->TYPE);
		  foreach($obj->INTERNAL_LINK as $link) graph__addNodeID($id, &$graph,$name=null,$obj->PATH,$link,null);
	 }
	 
	 
	 
	 
/*
	$db = DB::getDB();
	
	$sql= "select p.`ID`,`DESC` from `CRM_PROCES` as p where  p.`A_STATUS` in('WAITING','NORMAL') and p.`TYPE`='PROCES_INIT' and ID=994 limit 1";
	$res=DB::query($sql);
	while($h=DB::fetch($res)) {
		SearchParentsWithExits($h->ID,$h->ID,$graph,'Proces '.$h->ID,0);
		//graph__addNodeID($h->ID, $graph);
		graph__addNodeID('1', $graph,'1');

	//	graph__addNodeID($h->ID, $graph,$h->ID);
//		graph__addNodeID('100', $graph,'100');
		//$graph->treeItems[$h->ID] = true;
		//$graph->treeItems[101] = true;

//		$graph->elements->nodes[] = array('data'=>array('id'=>$h->ID, 'name'=>$h->ID , 'type'=>'procesInit'));
//		$graph->elements->nodes[] = array('data'=>array('id'=>101, 'name'=>101 , 'type'=>'procesInit'));
//		$graph->elements->edges[] = array('data'=>array('source'=>994, 'target'=>101));


	}
*/
	foreach($graph->elements->nodes as $var) {
	//	echo "<br>\n NODE".$var[data][id];
		$nodes[$var[data][id]]=$var[data][id];
	}
	foreach($graph->elements->edges as $var) {
		echo "<br>\n".$var[data][source]." ".$var[data][target]." ";
		if(isset($nodes[$var[data][source]])) echo "OK1"; else echo "FAIL1";
		if(isset($nodes[$var[data][target]])) echo "OK2"; else echo "FAIL2";
	}

	DEBUG_S(-3,'nodes',$graph->elements->nodes);
	DEBUG_S(-3,'edges',$graph->elements->edges);
/*		
	$sql = "select p.`ID`, p.`PARENT_ID`
			from `CRM_PROCES` as p
			where p.`A_STATUS` in('WAITING','NORMAL')
	";
	$res = $db->query($sql);
	while ($r = $db->fetch($res)) {
		$graph->procesTreeFlat[$r->PARENT_ID] []= $r->ID;
	}

	$sql = "select p.`IF_TRUE_GOTO` as ID, p.`ID` as PARENT_ID
			from `CRM_PROCES` as p
			where p.`A_STATUS` in('WAITING','NORMAL')
				and p.IF_TRUE_GOTO>0
		--		and p.IF_TRUE_GOTO_FLAG='GOTO_AND_RETURN'
	";
	
	$res = $db->query($sql);
	while ($r = $db->fetch($res)) {
		$graph->procesTreeGoto[$r->PARENT_ID] []= $r->ID;
	}


	function createGraphRec($id, $tree, &$graph, $lvl = 0) {
		$graph->treeItems[$id] = true;
		settype($id, 'string');
		if ($id == 3122) {
			$graph->elements->nodes[] = array('data'=>array('id'=>$id, 'name'=>$id, 'type'=>'procesInit', 'lvl'=>$lvl));
		} else {
			$graph->elements->nodes[] = array('data'=>array('id'=>$id, 'name'=>$id, 'lvl'=>$lvl));
		}

		if ($lvl > 1) {
		//	return;
		}

		if (!empty($tree[$id])) {
			foreach ($tree[$id] as $vChildID) {
				$graph->elements->edges[] = array('data'=>array('source'=>$id, 'target'=>$vChildID));
				createGraphRec($vChildID, $tree, $graph, $lvl + 1);
			}
		}
	}

	createGraphRec($id_proces, $graph->procesTreeFlat, $graph);

*/
/*
	// addGraphGoto
	foreach ($graph->procesTreeGoto as $kID => $vGotoIds) {
		//$graph->treeItems[$id] = true;
		if (array_key_exists($kID, $graph->treeItems)) {
			foreach ($vGotoIds as $vGotoID) {
				graph__addNodeID($vGotoID, $graph);
				$graph->elements->edges[] = array('data'=>array('source'=>$kID, 'target'=>$vGotoID, 'type'=>'GOTO'));
			}
		} else {
			foreach ($vGotoIds as $vGotoID) {
				if (array_key_exists($vGotoID, $graph->treeItems)) {
//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;"> (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r("TODO: add node ($kID); add edge from $kID to $vGotoID");echo'</pre>';
					graph__addNodeID($kID, $graph);
					//$graph->elements->edges[] = array('data'=>array('source'=>$kID, 'target'=>$vGotoID, 'type'=>'GOTO'));
				}
			}
		}
	}
*/
?>
<style type="text/css">
#<?php echo $graph->htmlID; ?>_wrap {
	position:relative;
	width:1100px;
	margin:0 auto;
	border:1px solid #ccc;
}
#<?php echo $graph->htmlID; ?> {
	height:560px;
	border-bottom:1px solid #ccc;
}
#<?php echo $graph->htmlID; ?>_info {
	padding:3px;
}
#<?php echo $graph->htmlID; ?>_wrap .actions { position:absolute; top:20px; left:-40px; margin:0; padding:0; list-style:none; }
#<?php echo $graph->htmlID; ?>_wrap .actions button { border-radius:0; background:#fff; border:1px solid #ccc; }
</style>

<script src="./stuff/cytoscape.js/arbor.js"></script>
<script src="./stuff/cytoscape.js/cytoscape.js"></script>
<script>
jQuery(loadInfo = function(nodeID){
	$.ajax({
		url: 'index.php?MENU_INIT=GRAPH_VIEW_PROCES&id_proces=<?php echo $id_proces; ?>&ajaxTask=getInfo&id=' + nodeID + '&HEADER_NOT_INIT=YES',
		type: 'GET',
		dataType: 'text',
		data: '',
		async: true,
		success: function (data) {
			jQuery('#<?php echo $graph->htmlID; ?>_info').html(data);
		},
		error: function (err) {
			console.log('err');
		}
	});
});
jQuery(loadCy = function(){
	jQuery('#<?php echo $graph->htmlID; ?>').cytoscape({
		layout: {
			name: 'arbor'
		},
		style: cytoscape.stylesheet()
			.selector('node')
				.css({
					'shape': 'rectangle',
					'width': '46px', 'height': '26px',
					'font-size': '10px',
					'content': 'data(name)',
					'text-valign': 'center',
					'color': 'white',
					'text-outline-width': 2,
					'text-outline-color': '#888'
				})
			.selector('edge')
				.css({
					'target-arrow-shape': 'triangle'
				})
			.selector(':selected')
				.css({
					'background-color': 'black',
					'line-color': 'black',
					'target-arrow-color': 'black',
					'source-arrow-color': 'black'
				})
			.selector('.faded')
				.css({
					'opacity': 0.25,
					'text-opacity': 0
				})
			.selector('edge.neighborhood')
				.css({
					'background-color': 'blue',
					'color': 'orange'
				})
			.selector('node.procesInit')
				.css({
					'background-color': 'red',
					'text-outline-color': 'red',
					'font-weight': 'bold'
				}),

		elements: <?php echo json_encode($graph->elements); ?>,

		ready: function(){
			var cy = this;
			window.cy_<?php echo $graph->htmlID; ?> = this;

			cy.elements("node[type = 'procesInit']").addClass('procesInit');
			cy.elements("node[lvl > 1]").hide();

			cy.elements().unselectify();

			cy.on('tap', 'node', function(e){
				//console.log('on tap node', e)
				var node = e.cyTarget;
				var neighborhood = node.neighborhood().add(node);

				var nodeID = node.id();
				loadInfo(nodeID);

				cy.elements().addClass('faded').unselect();
				neighborhood.removeClass('faded');
				node.select();

				cy.edges().removeClass('neighborhood');
				node.connectedEdges().addClass('neighborhood');

				neighborhood.show();

				cy.center(neighborhood);
			});

			cy.on('tap', function(e){
				if (e.cyTarget === cy){
					cy.elements().removeClass('faded');
				}
			});
		},
		showOverlay: false
	});
});

jQuery(document).ready(function(){
	loadCy();

	var parent = $('#<?php echo $graph->htmlID; ?>')
		.parent()
	parent.find('.actions .cy-refresh')
		.on('mousedown touchstart', function(){
			loadCy();

			cy.attr('style', '');
		});
	parent.find('.actions .cy-zoom-plus')
		.on('mousedown touchstart', function(){
			window.cy_<?php echo $graph->htmlID; ?>.zoom(window.cy_<?php echo $graph->htmlID; ?>.zoom() + 0.1);
		});
  parent.find('.actions .cy-zoom-minus')
		.on('mousedown touchstart', function(){
			window.cy_<?php echo $graph->htmlID; ?>.zoom(window.cy_<?php echo $graph->htmlID; ?>.zoom() - 0.1);
		});
});
</script>

<div id="<?php echo $graph->htmlID; ?>_wrap">
	<div id="<?php echo $graph->htmlID; ?>"></div>
	<div id="<?php echo $graph->htmlID; ?>_info"></div>
	<ul class="actions">
		<li><button class="btn cy-refresh"><i title="Refresh" class="ico-refresh"></i></button></li>
		<li><button class="btn cy-zoom-plus"><i title="Zoom +" class="ico-plus"></i></button></li>
		<li><button class="btn cy-zoom-minus"><i title="Zoom -" class="ico-minus"></i></button></li>
	</ul>
</div>

<?php
}
