<?php 
include_once ("_dirinfo.php");

include_once (PATH_TO_ROOT."init.php");
include (PATH_TO_ROOT."webcati/init.php");
//recursive function to get all XML elements!

class DesignerPanelXMLManipulator {
	/**
	 * the sm
	 *
	 * @var SimpleXMLElement
	 */
	public $xml;
	
	public $parentId;
	public $panelType;
	public $panelId;
	function __construct($db,$xml) 
	{
		$this->db = $db;
		$this->xml = $xml;
		$this->parentId = $_POST['parent'];
		$this->panelType = $_POST['type'];
		$this->panelId = $_POST['id'];
		
	}
	
	private function getIcon($type)
	{
		$sql = "SELECT node_img FROM ".WC_DESIGNER_ELEMENTS." WHERE type = ".$type;
		if(!$rs = $this->db->SQLexecute($sql)) return '{success:false,error:"'.$this->db->GetError().'", STATEMENT: "'.$sql.'"}';
			if ($row = $this->db->fetchArray($rs))
			{
				return $row[0];
			}
	}
	
	private function getLabel($type,$idTemplate)
	{
		if($type)
		{
		$sql = "SELECT idLab FROM ".WC_DESIGNER_ELEMENTS." WHERE type = ".$type;
		if($idTemplate)
		{
			$sql.= " AND id_template = ".$idTemplate;
		}
		if(!$rs = $this->db->SQLexecute($sql)) return '{success:false,error:"'.$this->db->GetError().'", STATEMENT: "'.$sql.'"}';
			if ($row = $this->db->fetchArray($rs))
			{
				return $row[0];
			}
		}
		return 'Panel';
		
	}
	/**
	 * function recursively finds children in an XML object
	 *
	 * @param unknown_type $xmlObj
	 * @param unknown_type $id
	 * @return SimpleXMLElement
	 */
	private function findChildrenById($xmlObj,$id) {
		$attr = $xmlObj->attributes();
	  	if($attr['id'] == $id )
	  	{
	  		return $xmlObj;
	  	}
	  foreach($xmlObj->children() as $child) {
	    if($res = $this->findChildrenById($child,$id))
	    	return $res;
	  }
	  return false;
	}
	
	
	/**
	 * 
	 * function inserts a Panel to the Designer panel (Objects, Overview)
	 * @author RMplus
	 * 
	 */
	public function insertPanelAction()
	{
		
			/*foreach ($xml as $key => $val) {
				echo $key;
				print_r($val);
			}*/
			$attr = array();
		/*	$attr['height'] = 20;
			$attr['width'] = 20;
			$attr['position'] = 'relative';*/
			if(is_array( $_POST['attr'] ))
				$attr = $_POST['attr']; 	
			
			//let's fetch all the default values for this type
			$sql =	"SELECT properties_name,`default_value` FROM _DesignerProperties a "
				  . "INNER JOIN _DesignerElemPropLink b ON a.id = b.id_property "
				  . "WHERE object_type = $this->panelType AND default_value != ''";
				  
			if(!$rs = $this->db->SQLexecute($sql)) return $this->db->JsonError();
			while ($row = $this->db->fetchAssoc($rs))
			{
				if(!isset($attr[$row['properties_name']]))
					$attr[$row['properties_name']] = $row['default_value'];
			}
			
			switch ($this->panelType) {
				//horizontal panel
				case 1:
					$type = 'DIV';
				
				break;
				case 2:
					$type = 'DIV';
					
				break;
				case 3:
					$type = 'QUESTION';
				break;
				case 4:
					$type = 'INSTRUCTION';
				break;
				case 5:
					$type = 'WINDOW';
					break;
				case 6:
					$type = 'ANSWER';
				break;
				case 7:
					$type = 'VARIABLE';
				break;
				case 8:
					$type = 'IMAGE';
				break;
				case 9:
					$type = 'VIDEO';
				break;
				case 10:
					$type = 'SUBMIT';
				break;
				case 35:
				case 36:
				case 37:
					$type = 'DIV';
					//template type is dialers
					$templateType = ", type = 1";
				break;
				//this object is created from a template!
				case 47:
					$type = 'TEMPLATE';
					$attr['id_template'] = $_POST['objectTemplate'];
				break;
				default:
					$type = "DIV";
				break;
			}
			 
			$par = $this->findChildrenById($this->xml,$this->parentId);
			if($par)
			{
				$itemIndex = $_POST['itemIndex'];
				if($itemIndex || $itemIndex === '0')
				{
					//$parDom = dom_import_simplexml($par);
					$ind = 0;
					foreach ($par->children() as $chr) {
						$ind++;
						if($ind > $itemIndex) // all those nodes need to be deleted and reAdded :)
							$tmp[] = $chr;
						
					}
					if($tmp)
					foreach ($tmp as $chr) {
						$dom = dom_import_simplexml( $chr );
						$dom->parentNode->removeChild($dom);
					}
					
					
				}
				$new = $par->addChild($type);
				if($tmp)
				{
					$parDom = dom_import_simplexml($par);
					foreach ($tmp as $chr) {
							$parDom->appendChild( dom_import_simplexml ($chr ) );
						}
				}
				$new->addAttribute('id',$this->panelId);
				$new->addAttribute('type',$this->panelType);
				foreach ($attr as $name => $val) {
					$new->addAttribute($name,$val);
				}
				if($this->panelType == 6)
				{
					//for answers we add the 3 rows each with 3 objects!
					$curId = $this->panelId+1;
					$legR = $new->addChild('DIV'); $legR->addAttribute('id', $curId++);$legR->addAttribute('type', 1); $legR->addAttribute('position', 'relative');  $legR->addAttribute('name', 'Legend row');$legR->addAttribute('height', 33.33);
					$legR->addAttribute('subType',1);
					
					$tmp = $legR->addChild('DIV'); $tmp->addAttribute('id', $curId++); $tmp->addAttribute('type', '20');  $tmp->addAttribute('width', 33.33); $tmp->addAttribute('position', 'relative');
					$tmp = $legR->addChild('DIV'); $tmp->addAttribute('id', $curId++); $tmp->addAttribute('type', '21');  $tmp->addAttribute('width', 33.33);$tmp->addAttribute('position', 'relative');
					$tmp = $legR->addChild('DIV'); $tmp->addAttribute('id', $curId++); $tmp->addAttribute('type', '22');  $tmp->addAttribute('width', 33.33);$tmp->addAttribute('position', 'relative');
					
					$oddR = $new->addChild('DIV'); $oddR->addAttribute('id', $curId++);$oddR->addAttribute('type', 1); $oddR->addAttribute('name', 'Odd rows');  $oddR->addAttribute('height', 33.33);$oddR->addAttribute('position', 'relative');
					$oddR->addAttribute('subType',2);
					
					$tmp = $oddR->addChild('DIV'); $tmp->addAttribute('id', $curId++); $tmp->addAttribute('type', '20');  $tmp->addAttribute('width', 33.33); $tmp->addAttribute('position', 'relative');
					$tmp = $oddR->addChild('DIV'); $tmp->addAttribute('id', $curId++); $tmp->addAttribute('type', '21');  $tmp->addAttribute('width', 33.33); $tmp->addAttribute('position', 'relative');
					$tmp = $oddR->addChild('DIV'); $tmp->addAttribute('id', $curId++); $tmp->addAttribute('type', '22');  $tmp->addAttribute('width', 33.33); $tmp->addAttribute('position', 'relative');
					
					$evenR = $new->addChild('DIV');$evenR->addAttribute('id', $curId++);$evenR->addAttribute('type', 1); $evenR->addAttribute('name', 'Even rows');$evenR->addAttribute('height', 33.33);$evenR->addAttribute('position', 'relative');
					$evenR->addAttribute('subType',3);
					
					$tmp = $evenR->addChild('DIV'); $tmp->addAttribute('id', $curId++); $tmp->addAttribute('type', '20');  $tmp->addAttribute('width', 33.33); $tmp->addAttribute('position', 'relative');
					$tmp = $evenR->addChild('DIV'); $tmp->addAttribute('id', $curId++); $tmp->addAttribute('type', '21');  $tmp->addAttribute('width', 33.33); $tmp->addAttribute('position', 'relative');
					$tmp = $evenR->addChild('DIV'); $tmp->addAttribute('id', $curId++); $tmp->addAttribute('type', '22');  $tmp->addAttribute('width', 33.33); $tmp->addAttribute('position', 'relative');
					
				}
				
				$curXML = $this->xml->asXML();
				$sql = "UPDATE ".WC_DESIGNER_TEMPLATES." SET template_xml = '$curXML' $templateType WHERE id = " . $_POST['templateId'];
				if(!$this->db->SQLexecute($sql)) return '{success:false,error:"'.$this->db->GetError().'", STATEMENT: "'.$sql.'"}';
				
				return "{success:true}";
			}
			else {
				return "{success:false, error:'Warning! $this->parentId not found in ".$this->xml->asXML()."'}" ;
			}
	}
	
	public function movePanelAction()
	{
		$target = $this->findChildrenById($this->xml,$this->panelId);
		
		$par = $this->findChildrenById($this->xml,$_POST['newParent']);
		$itemIndex = $_POST['itemIndex'];
		
		if($itemIndex || $itemIndex === '0')
		{
					$ind = 0;
					foreach ($par->children() as $chr) {
						$ind++;
						$attr = $chr->attributes();
						if($ind > $itemIndex && $attr['id'] != $this->panelId) // all those nodes need to be deleted and reAdded :)
							$tmp[] = $chr;
						
					}
					if($tmp)
					foreach ($tmp as $chr) {
						$dom = dom_import_simplexml( $chr );
						$dom->parentNode->removeChild($dom);
					}
		}
		//we remove the clild
		$this->removeAction();
		//we add the child
		$parDom = dom_import_simplexml($par);
		$parDom->appendChild( dom_import_simplexml( $target));
		
		if($tmp)
		{
			
			foreach ($tmp as $chr) {
					$parDom->appendChild( dom_import_simplexml ($chr ) );
				}
		}
		
		$curXML = $this->xml->asXML();
		$sql = "UPDATE ".WC_DESIGNER_TEMPLATES." SET template_xml = '$curXML' $templateType WHERE id = " . $_POST['templateId'];
		if(!$this->db->SQLexecute($sql)) return '{success:false,error:"'.$this->db->GetError().'", STATEMENT: "'.$sql.'"}';
		
		
		return '{"success":true}';
	}
	
	public function removeAction()
	{
		$par = $this->findChildrenById($this->xml,$this->parentId);
		if($par)
		{
			foreach($par->children() as $seg)
			{
			    if($seg['id'] == $this->panelId) {
			        $dom=dom_import_simplexml($seg);
			        $dom->parentNode->removeChild($dom);
			    }
			}
		}
		else
		{
			return "{success:false, error:'Warning! $this->parentId not found in ".$this->xml->asXML()."'}" ;
		}
		$curXML = $this->xml->asXML();
			$sql = "UPDATE ".WC_DESIGNER_TEMPLATES." SET template_xml = '$curXML' WHERE id = " . $_POST['templateId'];
			if(!$this->db->SQLexecute($sql)) return '{success:false,error:"'.$this->db->GetError().'", STATEMENT: "'.$sql.'"}';
			
			return "{success:true}";
	}
	
	public function modifyAttributesAction()
	{
		$xml = $this->findChildrenById($this->xml,$this->panelId);
		if($xml)
		{
			foreach ($_POST['attr'] as $name => $value) {
				$xml[$name] = $value;
			}
			
		}
		else
		{
			return "{success:false, error:'Warning! $this->parentId not found in ".$this->xml->asXML()."'}" ;
		}
		$curXML = $this->xml->asXML();
			$sql = "UPDATE ".WC_DESIGNER_TEMPLATES." SET template_xml = '$curXML' WHERE id = " . $_POST['templateId'];
			if(!$this->db->SQLexecute($sql)) return '{success:false,error:"'.$this->db->GetError().'", STATEMENT: "'.$sql.'"}';
			
			//return "{success:true}";
			$_POST['RMcomp'] = 'propGrid';
			return $this->selectAction();
	}
	/**
	 * Adding class to elements
	 * We add comma separted id values of classes in property RMcls
	 *
	 */
	public function addClassAction()
	{
		$xml = $this->findChildrenById($this->xml,$this->panelId);
		$rmClass = $_POST['specStyle'] ? 'RMcls_'.$_POST['specStyle'] : 'RMclass';
	if($xml)
		{
			if($xml[$rmClass])
			{
				$clsArr = explode(',',$xml[$rmClass]);
				{
					if(!in_array($_POST['classId'],$clsArr ) )
						$xml[$rmClass] .= ','.$_POST['classId'];
				}
			}
			else 
				$xml[$rmClass] = $_POST['classId'];
			
		}
		else{return "{success:false, error:'Warning! $this->parentId not found in ".$this->xml->asXML()."'}" ;}
		$curXML = $this->xml->asXML();
		$sql = "UPDATE ".WC_DESIGNER_TEMPLATES." SET template_xml = '$curXML' WHERE id = " . $_POST['templateId'];
		if(!$this->db->SQLexecute($sql)) return '{success:false,error:"'.$this->db->GetError().'", STATEMENT: "'.$sql.'"}';
		
		return "{success:true}";
	}
	public function removeClassAction()
	{
		$clsId = $_POST['classId'];
		$specId = explode('_',$clsId);
		if(count($specId) > 1 )
		{
			$clsId = $specId[1];
			$RMcls = 'RMcls_'.$specId[0];
		}
		else 
			$RMcls = 'RMclass';
		$xml = $this->findChildrenById($this->xml,$this->panelId);
		if($xml)
		{
			if($xml[$RMcls])
			{
				$clsArr = explode(',',$xml[$RMcls]);
				foreach ($clsArr as $key => $val)
				{
					if($val == $clsId)
						unset($clsArr[$key] );
				}
				if(count($clsArr) > 0)
					$xml[$RMcls] = implode(',',$clsArr);
				else 
					unset($xml[$RMcls]);
			}
			
		}
		else{return "{success:false, error:'Warning! $this->parentId not found in ".$this->xml->asXML()."'}" ;}
		$curXML = $this->xml->asXML();
		$sql = "UPDATE ".WC_DESIGNER_TEMPLATES." SET template_xml = '$curXML' WHERE id = " . $_POST['templateId'];
		if(!$this->db->SQLexecute($sql)) return '{success:false,error:"'.$this->db->GetError().'", STATEMENT: "'.$sql.'"}';
		
		return "{success:true}";
	}
	
	private function countTemplateQuestions($xmlObj)
	{
		$count = 0;
		foreach ($xmlObj->attributes() as $attr => $value) {
			if( substr($attr,0,12) == 'question_num')
			{
				 if( (int)$value > $count )
				 	$count = (int)$value;
			}
		}
		foreach($xmlObj->children() as $child) {
		    $cC =$this->countTemplateQuestions($child);
		    if($cC > $count)
		    	$count = $cC;
		  }
		return $count;
	}
	
	private function buildJsonTree($xmlObj) {
		foreach ($xmlObj->attributes() as $attr => $value) {
			$prop[$attr] = "$value";
		}
	  	$prop['text'] = $this->getLabel($prop['type'],$prop['id_template'] ).' '.$prop['id'];
	  	if($prop['type'])
	  		$prop['iconCls'] = $this->getIcon( $prop['type'] );
	  	
	  $prop['children'] = array();
	  foreach($xmlObj->children() as $child) {
	    $prop['children'][] =$this->buildJsonTree($child);
	  }
	  return $prop;
	}
	
	/**
	 * 
	 * function is called when an object in the Designer is selected, to update the view and hierarchy tree
	 */
	
	public function selectAction()
	{
		if($_POST['RMcomp'] == 'tree')
			return '['.json_encode( $this->buildJsonTree($this->xml) ).']';
		else if ($_POST['RMcomp'] == 'propGrid')
		{
			if($this->panelType == 47) //for template objects, let's find out how many questions they support
			{
				$tmpId = $this->findChildrenById($this->xml,$this->panelId);
				$tmpAttr = $tmpId->attributes();
				$sql = "SELECT template_xml FROM ".WC_DESIGNER_TEMPLATES." WHERE id = ".$tmpAttr['id_template']; //load template_xml from database
				$rs = $this->db->SQLexecute($sql);
				$row = $this->db->fetchArray($rs);
				$curXML = $row[0];
				$templCount = 0;	
				if($curXML)
				{
					$curXML = simplexml_load_string($curXML);
					foreach($curXML->children() as $child) {
					    $cC =$this->countTemplateQuestions($child);
					    if($cC > $templCount)
					    	$templCount = $cC;
					  }
				}
				for($i=1;$i<=$templCount;$i++)	
					$attr[] = array('question_num_'.$i);
			}
			
			$sql = "SELECT properties_name,properties_value FROM ".WC_DESIGNER_PROPERTIES." a INNER JOIN ".WC_ELEM_PROP_LINK." b ON a.id = b.id_property WHERE object_type = $this->panelType OR object_type = 0";
			if(!$rs = $this->db->SQLexecute($sql)) return '{success:false,error:"'.$this->db->GetError().'", STATEMENT: "'.$sql.'"}';
			while ($row = $this->db->fetchRow($rs))
			{
				$attr[] = $row;
			} 
			//we create an object for the property grid!!!
			$rows = array();
			if($this->panelId)
			{
				$xml = $this->findChildrenById($this->xml,$this->panelId);
				$panAtr = $xml->attributes();
				foreach ($attr as $name) {
				//	$r['name'] = $name;
					//because value is actualy a simpleXmlElement we convert it to string
					$value = $panAtr[$name[0]];
					$rows[$name[0]] = "$value";
				//	$rows[] = $r ;
					if($name[1])
					{//we set up a combobox
						if(is_array($propValues = explode(',',$name[1])  ) )
							$editors[] = $name[0].":new Ext.grid.GridEditor (new Ext.form.ComboBox({store:['".implode("','",$propValues)."'],triggerAction:'all',editable:false}))"; 
						//$editors[$name[0]] = "new Ext.grid.GridEditor (new Ext.form.DateField())";
					}
				}
				if($_POST['parentType'] == 1 ) // Horizontal panel
				{
					unset($rows['height']);
				}
				else if($_POST['parentType'] == 2) // Vertical panel
				{
					unset($rows['width']);
				}
			}
				
				return "{success:true,object:".json_encode($rows).",editors:{".implode(',',$editors)."}}";
			
		}
		else if($_POST['RMcomp'] == 'grid')
		{
			$this->arr = array();
			if($this->panelId)
			{
			$xml = $this->findChildrenById($this->xml,$this->panelId);
			if($xml)
				{
					if($xml['RMclass'])
					{
						$sql = "SELECT c.id as clsId,c.idLab,a.name,b.prop_value FROM ".WC_DESIGNER_CSS_PROPERTIES." a INNER JOIN ".WC_DESIGNER_CLS_PROP_LINK." b ON a.id = b.id_property INNER JOIN ".WC_DESIGNER_CSS." c ON c.id = b.id_class WHERE c.id IN (".$xml['RMclass'].") ORDER BY c.id";
						If (!$this->rs = $this->db->SQLexecute($sql)) {	return '{success:false,error:"'.$this->db->GetError().'", STATEMENT: "'.$sql.'"}';}
						while($obj = $this->db->fetchAssoc($this->rs)){
							$this->arr[] = $obj;
						}
						
					}
					if($xml['RMcls_input'])
					{
					$sql = "SELECT c.id as clsId,c.idLab,a.name,b.prop_value FROM ".WC_DESIGNER_CSS_PROPERTIES." a INNER JOIN ".WC_DESIGNER_CLS_PROP_LINK." b ON a.id = b.id_property INNER JOIN ".WC_DESIGNER_CSS." c ON c.id = b.id_class WHERE c.id IN (".$xml['RMcls_input'].") ORDER BY c.id";
						If (!$this->rs = $this->db->SQLexecute($sql)) {	return '{success:false,error:"'.$this->db->GetError().'", STATEMENT: "'.$sql.'"}';}
						while($obj = $this->db->fetchAssoc($this->rs)){
							$obj['clsId'] = 'input_'.$obj['clsId'];
							$this->arr[] = $obj;
						}
					}
					if($xml['RMcls_text'])
					{
					$sql = "SELECT c.id as clsId,c.idLab,a.name,b.prop_value FROM ".WC_DESIGNER_CSS_PROPERTIES." a INNER JOIN ".WC_DESIGNER_CLS_PROP_LINK." b ON a.id = b.id_property INNER JOIN ".WC_DESIGNER_CSS." c ON c.id = b.id_class WHERE c.id IN (".$xml['RMcls_text'].") ORDER BY c.id";
						If (!$this->rs = $this->db->SQLexecute($sql)) {	return '{success:false,error:"'.$this->db->GetError().'", STATEMENT: "'.$sql.'"}';}
						while($obj = $this->db->fetchAssoc($this->rs)){
							$obj['clsId'] = 'text_'.$obj['clsId'];
							$this->arr[] = $obj;
						}
					}
							
					$echo = '{success:true';
					
						$echo.= ', STATEMENT: "'.$sql.'",rows: '.json_encode($this->arr);
						$echo.='}';
						return $echo;
					
				}
			}
			return "{success:true,rows:[] }";
			
		}
	}
	public function createObjectAction()
	{
		
		$id_template = $_POST['templateId'];
		$sql = "SELECT * FROM _DesignerElements WHERE id_template = $id_template";
		//if template is already in, we just update text...whatever 8)
		if($this->db->fetchRow($this->db->SQLexecute($sql)))
		{
			$sql = "UPDATE _DesignerElements SET idLab = '{$_POST['text']}' WHERE id_template = $id_template";
			$this->db->SQLexecute($sql);
		}
		else
		{
			$sql = "SELECT orderBy from _DesignerElements WHERE id_sup = 52 ORDER BY orderBy DESC LIMIT 1";
			$ord = $this->db->fetchRow($this->db->SQLexecute($sql));
			$ord = $ord[0]+1;
			$sql = "INSERT INTO _DesignerElements (id_sup,type,idLab,orderBy,id_template) VALUES(52,47,'{$_POST['text']}',$ord,{$_POST['templateId']})";
			$this->db->SQLexecute($sql);
		}
		return "{success:true }";
	}
	
}
	

	/**
	 * this runs every time
	 */


	/**
	 * get the xml of the template from the database
	 */

	$db->ChangeDatabase(DB_WARPIT_WEBCATI_BASE);
	$sql = "SELECT template_xml FROM ".WC_DESIGNER_TEMPLATES." WHERE id = ".$_POST['templateId'];
	$rs = $db->SQLexecute($sql);
	$row = $db->fetchArray($rs);
	$curXML = $row[0];
	if($curXML)
		$xml = simplexml_load_string( $curXML );
	else 
	{
		/*$xml = new SimpleXMLElement("<DIV></DIV>");
		//$xml->addChild('DIV');
		$xml->addAttribute('id',$parentId);*/
		/**
		 * 
		 * failsafe - load empty template
		 */
		$xml = simplexml_load_string('<DIV id="0"></DIV>');
	}
	
	// run some action of DesignerPanelXMLManipulator class
	$manipulator = new DesignerPanelXMLManipulator( $db,$xml );
	$comm = $_POST['action'].'Action';
	if(method_exists($manipulator,$comm)) //if the action exists
		echo $manipulator->$comm(); //output JSON result
	else 
		echo '{success:false,error:"Unknown action!"}';	//fail with JSON error
	

?>