<?php

include_once("_dirinfo.php");

include_once (PATH_TO_ROOT."_class/class.Extjs.php");

class MakeTree extends MakeComponent 
{
	
	protected $reqUrl = '_ajaxManipulators/treeDataManipulator.php';
	protected $TreeName;
	public $rootId = 0;
	
	//is set to true if any context menu is added
	protected $addContext = false;
	
	protected $contDelete;
	/**
	 * Adds a context menu item for deleting the node
	 *
	 * @param unknown_type $text
	 * @return MakeTree
	 */
	public function setContDelete($text = 'Delete',$hidden = 'node.hasChildNodes()',$iconCls = 'icon_red_delete',$button = 2)
	{
		
		$context = "function(item) {
				 if(item)
							n = item.parentMenu.contextNode;
						else
							{
								//to be compatable with the...yes!
								
								n = $this.getSelectionModel().getSelectedNode();
								if(!n)
									return;
								var node = n
								if($hidden) return;
							}
				Ext.Msg.confirm('Delete node','Are you sure?',function(btn){
				if(btn == 'yes')
				{
				$this->compName.RMconn.request({params:{action:'delete',nodeId:n.id} 
				,success:function(resp){if(Ext.decode(resp.responseText).success){
				if (n.parentNode) {
				 n.remove();
				}} else{alert('failed');}},
				failure:function(){alert('failed');}	});
				}});						
	}
				 ";
			        
		$this->addContItem($text,$context,$hidden,$iconCls,$button );
		$this->contDelete = $text;
		
		return $this;
	}
	private $contAdd;
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * 
	 * 
	 * @return MakeTree
	 */
	
	public function setContRename($text = 'Rename',$hidden = 'false',$iconCls = 'RMicon_edit_record',$button = 2)
	{
		$this->setEditable();
		return $this->addContItem($text,"function(item){ if(item)
			n = item.parentMenu.contextNode;
		else
			{
				n = $this.getSelectionModel().getSelectedNode();
				if(!n)
					return;
				var node = n
						if($hidden) return;
			}
			$this.treeEditor.triggerEdit(n);
			}",'false','RMicon_edit_record',2);
		
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * 
	 * @param useForm a url to an form item used to input elements to this tree NOTE: the form must take care of adding the child!
	 * @return MakeTree
	 */
	
	public function setContAddItem($text = 'Add item',$hidden = 'false',$iconCls = 'icon-add-record',$useForm = null,$button = 2)
	{
		
		$context = "function(item) {
				 if(item)
						n = item.parentMenu.contextNode;
					else
						{
							n = $this.getSelectionModel().getSelectedNode();
							if(!n)
								n = $this.getRootNode();
							var node = n
								if($hidden) return;
						}
						
					var par;
					//if we clicked on a question or a closed group we add it to its parent one position lower otherwise to the clicked group
					var closed = !n.isExpanded();
					if(n.attributes.leaf==true || closed)
					{par = n.parentNode; }
					 else {par = n;}
					";
					
				if($useForm)
					$context .= "CallScript('$useForm',{ parId:par.id, closed:closed,
			                       nodeId:n.id, tree:'$this->compName'
									, isLeaf:n.attributes.leaf ? 1 : 0 , addLeaf:true
									});";
				else 
		$context.= "//we open a window to ask for the name (later we can add the window as parameter with multi choise options)
				var promptNameTF = new Ext.form.TextField({id:'RMtreeAddPrompt' , fieldLabel:'Name',width: 140,allowBlank:false});
				new Ext.Window({title:'$text',modal:true,width:'280px',
					items:{
						xtype:'form', buttonAlign:'center',
						frame:true,
						items: [ promptNameTF
							//textfield for inserting the items name
							
						],
						keys: [{
				               key: [Ext.EventObject.ENTER], fn: function(){
				                   Ext.getCmp('promptOKBtn').fireEvent('click');
				               }
					      		 }],
							buttons:[{text:'Ok',id:'promptOKBtn',listeners:{
							click: function(){
							var text = promptNameTF.getValue();
							
							if(promptNameTF.isValid()   )
							{	
								
								 //we make a server requst to handle insertItem
								 //we send the parent node ID and the text
			                       $this->compName.RMconn.request({params:{action:'insertItem',
			                       parId:par.id, closed:closed,
			                       nodeId:n.id,nodeText:text
									, isLeaf:n.attributes.leaf ? 1 : 0 , addLeaf:true
									} 
								,success:function(resp){
											var r = Ext.decode(resp.responseText);
											
											if(r.success){
												//if adding was succesful we refresh the parent and open the location
												//NOTE: all other groups get closed
												
												var p = par.getPath()+'/'+r.insertId;
												$this->compName.getLoader().load(par,function(){ $this->compName.selectPath(p); 
												$this->afterAddItem
											} );
												promptNameTF.findParentByType('window').close();
											} else{//else we display a warning and focus on the name field
											Ext.Msg.alert('Warning!',Ext.decode(resp.responseText).error );
											promptNameTF.focus()}},
									failure:function(){alert('failed');}	});
					}}
					}},{
		text:'Cancel',handler:function(){ 
		
		this.findParentByType('window').close();
	
		 }}
					
					] //eo buttons 
				},
	defaultButton:'RMtreeAddPrompt'
				}).show(n);//eo window
				";
	
	$context .= " }";
		
		$this->contAdd = $text;
		$this->addContItem($text,$context,$hidden,$iconCls,$button);
		return $this;
	}
	private $contAddMain;
	
	//force tree to be one level
	//automaticly give folder to 
	public function setOneLevel()
	{
		$this->oneLevel = true;
		$this->addConfig('RMoneLevel','true');
		return $this;
	}
	
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @return MakeTree
	 */
	public function setContAddGroup($text = 'Add folder',$hidden = 'false',$iconCls = 'icon-add-folder',$button = 2)
	{
		
		$context = " function(item) {
					Ext.Msg.prompt('$text','Name:',function(btn,text){ if(btn == 'ok' ){

					 if(item)
							n = item.parentMenu.contextNode;
						else
							{
								n = $this.getSelectionModel().getSelectedNode();
								if(!n)
									n = $this.getRootNode();
								var node = n
								if($hidden) return;
							}
					var par;
						//the group gets added after the clicked node
						var closed = $this.RMoneLevel || !n.isExpanded();
						if($this.RMoneLevel)
							par = $this.getRootNode();
						else if(n.attributes.leaf == true || closed )
							{par = n.parentNode; } 
						else{ par = n;   }
                       $this->compName.RMconn.request({params:{action:'insertItem',
                       nodeId:n.id,nodeText:text,parId:par.id,closed:closed,isLeaf:n.attributes.leaf ? 1 : 0,
                       addLeaf:false
						} 
					,success:function(resp){
					if(Ext.decode(resp.responseText).success){
							//if adding was succesful we refresh the parent and open the location
							//NOTE: all other groups get closed
							var nId = Ext.decode(resp.responseText).insertId;
							var p = par.getPath()+'/'+nId;
							var l = $this->compName.getLoader();
							l.load(par,function(){ 
								$this->compName.selectPath(p,'id',
									function(suc,selNode) { if (selNode != undefined) selNode.expand();  }
								);
							});
					} else{alert('failed');}},
						failure:function(){alert('failed');}	});}});
						}";
			      
		$this->contAddMain = $text;
		$this->addContItem($text,$context,$hidden,$iconCls,$button);
		return $this;
	}
	
	
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @return MakeTree
	 */
	public function addButton($text,$function){parent::addButton($text,$function);return $this;}
	
	//an array holding all the context menu items
	private $contextItems = array();
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @return MakeTree
	 */
	public function addContItem($text,$function,$hidden = 'false',$iconCls = false,$addButton = false )
	{
		$this->addContext = true;
			$fncName = 'contextHandler_'.count($this->contextItems);
			$this->addConfig($fncName,$function);
			$this->contextItems[$text]['function'] = 'this.'.$fncName;
		if($addButton)
		{
			$btn = "{ handler: function(){ $this.$fncName(); } ";
			if($addButton == 1) $btn .=	", text:'$text'";
			else $btn .=",tooltip:'$text'";
			if($iconCls) $btn .= ", iconCls:'$iconCls'";
			$btn .= '}';
			$this->addtBarItem($btn);
		}
	//	else
	//		$this->contextItems[$text]['function'] = $function;
		$this->contextItems[$text]['hidden'] = $hidden;
		$this->contextItems[$text]['iconCls'] = $iconCls;
		
		return $this;
	}
	public function addContSeparator($toolBarSep = false)
	{
		$this->contextItems[] = '-';
		if($toolBarSep) $this->addtBarItem("'-'");
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $url
	 * @return MakeTree
	 */
	function setReqUrl($url){ parent::setReqUrl($url); return $this; }
	
	
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $url
	 * @return MakeTree
	 */
	function setSearchField($text,$position = 'top',$width = null)
	{
		$this->searchField = $text;
		$this->searchFieldPos = $position;
		if($text != '')
			$this->addtBarItem("{text:'$text'  }");
		$this->addtBarItem("new Ext.form.TwinTriggerField({trigger2Class:'x-form-clear-trigger'".
		($width ? ",width:$width" :"").	" 
			,trigger1Class:'x-form-search-trigger',
			onTrigger1Click:function(){
			 var l = $this->compName.getLoader();
			 l.baseParams.filter =this.getValue();
			l.load( $this->compName.getRootNode(),function(){
			var animate = $this->compName.animate;
			$this->compName.animate = false;
			$this->compName.expandAll(); 
			$this->compName.animate = animate;
			}  ); 
			},
			onTrigger2Click:function(){
			 var l = $this->compName.getLoader();
			delete l.baseParams.filter;
			 this.setValue('');
			l.load( $this->compName.getRootNode(),function(){ $this->compName.getRootNode().expand() } ); 
			},
			listeners: {
                specialkey: function(field, e){
                    // e.HOME, e.END, e.PAGE_UP, e.PAGE_DOWN,
                    // e.TAB, e.ESC, arrow keys: e.LEFT, e.RIGHT, e.UP, e.DOWN
                    if (e.getKey() == e.ENTER) {
                       field.onTrigger1Click();
                    }
                }
            }
		})");
		return $this;
	}
	
	private $dragDrop;
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @return MakeTree
	 */
	public function activateDD($treeGroup = null,$dropConfig = null,$beforeDropListener = null)
	{
		if($treeGroup)
		{
			$this->addConfig('ddGroup',"'$treeGroup'");
		}
		if($beforeDropListener)
			$this->listeners[] = "beforenodedrop:".$beforeDropListener;
		else 
		$this->listeners[] = "beforenodedrop:function(e){
		if(!e.dropNode)
		{
			return true;
		}
		if(e.target.ownerTree !== e.dropNode.ownerTree)
		{
			alert('Move only inside this tree, please');
			e.cancel = true;
			return;
		}
		if(!e.target.isLeaf()) e.target.expand();
		var nodeId = e.dropNode.attributes.id;
		var targetId = e.target.attributes.id;
		this.RMconn.request({params:{action:'moveNode',nodeId: nodeId,targetId:targetId,movePoint:e.point}});}";
		$this->configs['enableDD'] = "true".$this->newLine;
		$this->addConfig('dropConfig','{expandDelay:"500"'. ($treeGroup ? ",ddGroup :'$treeGroup'" : '') .($dropConfig ? ",$dropConfig" : '').   '}');
		$this->dragDrop = true;
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @return MakeTree
	 */
	public function setBoldRoots()
	{
		$this->boldRoots = true;
		return $this;
	}
/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @return MakeTree
	 */
	public function multiSelect($b = true)
	{
		$this->multiSelect = $b;
		return $this;
	}
	/**
	 * Add config options! 
	 * WARNING: the options should have quote marks if neccesery!
	 *
	 * @param unknown_type $conf
	 * @param unknown_type $opt
	 * @return MakeTree
	 */
	public function addConfig($conf,$opt)
	{ parent::addConfig($conf,$opt); return $this; }
	
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @return MakeTree
	 */
	public function setLinesVisible($bool = false)
	{
		if ($bool)
			$this->addConfig('lines','true'); else  $this->addConfig('lines','false');
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @return MakeTree
	 */
	public function setTextPadding($value)
	{
		
		$this->styleClasses .=	".treeFontPadding_$value .x-tree-node-anchor {padding-left:".$value.';}';
		$this->addConfig('cls','treeFontPadding_'.$value);
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @return MakeTree
	 */
	public function setFontMedium()
	{
		$this->styleClasses .=	".treeFontMedium .x-tree-node{ font-size: 12px; }";
		$this->addConfig('cls',"treeFontMedium");
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @return MakeTree
	 */
	public function setFontLarge()
	{
		$this->addConfig('cls',"treeFontLarge");
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @return MakeTree
	 */
	public function setFontExtraLarge()
	{
		$this->styleClasses .=	".treeFontExtraLarge .x-tree-node{ font-size: 14px;}";
		$this->addConfig('cls',"treeFontExtraLarge");
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @return MakeTree
	 */
	public function setFontSmall()
	{
		$this->addConfig('cls',"treeFontSmall");
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @return MakeTree
	 */
	public function setFontHuge()
	{
		$this->addConfig('cls',"treeFontHuge");
		return $this;
	}
	
/**
	 * Sets if items of components are editable (currently used for tree items and grid items)
	 *
	 * @param unknown_type $text
	 * @return MakeComponent
	 */
	public function setEditable($fieldConfig = '{}',$editorConfig = '')
	{
		if($editorConfig) $this->editorConfig = ','.$editorConfig;
		$this->editable = true;
		$this->editFieldConfig = $fieldConfig;
		return $this;
	}
	
	//function __construct($treeName) { $this->compName = $treeName;}
	
	/**
	 * Deprecated..
	 *
	 * @param unknown_type $text
	 * @return MakeTree
	 */
	function SetTable($Table,$dataBase=null,$mainKey = 'id_sup') {
		return parent::setMainTable($Table,$dataBase,$mainKey);
	}
			
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @return MakeTree
	 */
	function SetRootVisible($visible = "true",$root = 'Root',$config = null) { 
		$this->RootVisible = $visible; 
		$this->RootLabel = $root;
		$this->rootConfig = $config;
		return $this;
	}
	
	function GetRootVisible() { 
		return $this->RootVisible; 
	}
	
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @return MakeTree
	 */
	function SetRootLabel($lab = "Root") { $this->RootLabel = $lab; 
		return $this;}
	function GetRootLabel() { return $this->RootLabel; }

	function setSort($Order)
	{
		$this->order = $Order;
		return $this;
	}
	
	function CreateTree() {
			
		if ( isset($this->table ) )
		{
			$this->configRMconn('tree');
		}
		
		if (isset($this->styleClasses))
		{
			$tmp.= "setClassStyle(\"$this->styleClasses\");";
		}
		
		
		$tmp .= " var ".$this->compName." = new Ext.tree.TreePanel({ ".$this->newLine;
		$tmp .= " 	collapsible      : false,".$this->newLine;
		$tmp .= " 	id               : '$this->compName',".$this->newLine;
		$tmp .= " 	autoScroll       : true,".$this->newLine;
		$tmp .= " 	animate          : true,".$this->newLine;
		
		$tmp .= " loader : new Ext.tree.TreeLoader({".$this->newLine;
		$tmp .= " dataUrl   	:'$this->reqUrl',".$this->newLine;;
		$tmp .= " baseParams	: {RMtable:'$this->table',database:'$this->database',action:'select',RMcomp:'tree', table: '$this->table', compName: '$this->compName'";
		if (isset($this->order))
		{
			$tmp .= ", RMorder: '$this->order'";
		}
		if($this->selectSQL)
					{
						$tmp.=', SQL : "'.$this->selectSQL.'" ';
					}
		if ($this->boldRoots)
		{
			$tmp.=', boldRoots : true';
		}
		if(isset($this->baseParams))
		{
			$tmp.=','.$this->baseParams;	
		}
		
		$tmp .=	"} ".$this->newLine;
		$tmp .= ",listeners: { load : function(a,b,resp){ var r = Ext.decode(resp.responseText); if(r!= null && r.success === false){
		//tree load error
		if(r.error == 'sessionTimeout')
		{
			CallScript( '_forms/window.sessionTimeout.php',{ loginSessionType:'ajaxRequest',
				loginSessionTodo:'Ext.getCmp(\'$this->compName\').getRootNode().findChild(\'id\','+b.id+',true).reload(); '  });
		}
		else
			alert('Tree load error: '+r.error,'Error'); 
	}  } }";
		if( $this->loaderConfig )
		{
			$tmp .= ','.$this->loaderConfig;
		}
		$tmp .= " }), ".$this->newLine.$this->newLine;
	
		
		if($this->dragDrop)
		{
			//
		
		}
		$tmp .= " 	ddScroll	     : true".$this->newLine;
		if($this->GetRootVisible() != 'true')
			$tmp .= " 	,rootVisible		 : false".$this->newLine;
		//$tmp .= " 	border			 : false".$this->newLine;
		
		$tmp .= ", root : new Ext.tree.AsyncTreeNode({ ".$this->newLine;
	    $tmp .= "   text		: '".$this->GetRootLabel()."',  ".$this->newLine;
	    if($this->rootConfig)
	    {
	    	$tmp .= $this->rootConfig.",";
	    }
	    $tmp .= "   draggable	: false,editable:false, ".$this->newLine;
	    $tmp .= "   id		    : '$this->rootId'     ".$this->newLine;
	    $tmp .= " })  ".$this->newLine;	
		if($this->addContext)
		{
			
			
			foreach ($this->contextItems as $text => $func) {
				if($func === '-')
					$contTmp = "'-'";
				else
				{
					$contTmp = "{text: '$text',handler:{$func['function']},hidden:{$func['hidden']}";
					if($func['iconCls'])
					{
						$contTmp .= ",iconCls:'{$func['iconCls']}'";
					}
					$contTmp .= "}";
				}
				$contextArr[] = $contTmp;
			}
			//if a context item has been added, we create the context menu and add a listener for the context menu
			//we then write down all the context menu items and their handlers
			 $this->listeners[] =  "   contextmenu: function(node, e) {
			 			if(!node.isSelected())
			            	node.select();
			            var hasItem;
			            var contItems = [".implode(',',$contextArr). "];
			            for(var i=0;i<contItems.length;i++)
			            {
			            	if(contItems[i])
			            	{
			            		hasItem = true;
			            		break;
			            	}
			            }
			            if(hasItem)
			    		{
			            var c = new Ext.menu.Menu({
			        		items: contItems
			    				});
			    		
			    		
			    		
				            c.contextNode = node;
				            c.showAt(e.getXY());
			            }
			        }";
			 
			 
			$contextArr = array();
			
			
			
		/*	$tmp .= " ,contextMenu: new Ext.menu.Menu({
			        items: [".implode(',',$contextArr). "]
			        
			    })";*/
		}
		/*	 $tmp .=" ,listeners: {";
			 //adding the context menu if there is any
			 $listeners = array();
			 if($this->addContext)
			 {
			 
			 }
			 if($this->dragDrop)
			 {
			 	
			 }
			 
			 $tmp.=  implode(',',$this->listeners). "}";*/
	if($this->addTBar )
		{
			 $tmp .= ',tbar:[' . implode(',',$this->tBarItems).']';
		}
		if($this->multiSelect)
		{
			$tmp .= ",selModel: new Ext.tree.MultiSelectionModel()";	 
		}
		if($this->GetRootVisible())
		{
			 $this->listeners[] = "afterrender : function(t){ t.getRootNode().expand();}";
		}	 
		  
		 $tmp .= $this->createConfigs();
		 $tmp .= " });".$this->newLine.$this->newLine; 	
		 	 
		if($this->editable )
		{	//we
			 $tmp .= "  $this.treeEditor = new Ext.tree.TreeEditor(".$this->compName.",$this->editFieldConfig,{".$this->newLine;
	   		 $tmp .= " ignoreNoChange: true $this->editorConfig ,listeners:{ beforecomplete : function(editor, newValue, originalValue)".$this->newLine; 
			 $tmp .= "	{".$this->newLine;
			 $tmp .= "		Nodeid = editor.editNode;
			 				$this->compName.RMconn.request({params:{nodeId:Nodeid.id,action:'edit',newValue:newValue,oldValue:originalValue},
							success:function(resp){
								var r = Ext.decode(resp.responseText);
								if(!r.success) {
									Nodeid.setText(originalValue);
									Ext.Msg.alert('Error!',r.error);
								}
							}
		});".$this->newLine; 
			 //$tmp .= "		manipulate('nodeId='+Nodeid.id+'&action=edit&newValue='+newValue+'&RMtable=".$this->GetTable()."');".$this->newLine;
			 $tmp .= "	}  } }); ".$this->newLine;
		}
		//let's add the custom check behavore
		if(!$this->spCheck)
		$tmp .= " $this.on('click',function(node,e){
			if(node.attributes.checked != null)
			{
				
				if(!e.ctrlKey)
				{
				//dissable all other checks!
					$this.getRootNode().cascade( function(cnode){
							cnode.getUI().toggleCheck(false);
					});
				}
				node.getUI().toggleCheck(true);
			}
		}); ";
		
	  	return $tmp;
	}
}



?>
