
<?php
/**
 * Class for generating columns and assignin propertis
 * This class is generated through the addColumn method in MakeGrid.
 * It is then returned so that properties can be assigned through methods!
 *
 */
class MakeColumn
{
	
	/**
	 * some basic properties...for what do I know what...
	 *
	 * @var unknown_type
	 */
	public $properties;
	/**
	 * array of properties that affect the column in the grid
	 *
	 * @var unknown_type
	 */
	public $colProperties;
	/**
	 * array of properties that are required for the data store model!
	 * note: currently not in use!
	 * @var unknown_type
	 */
	public $storeProperties;
	
	function __construct($props=null)
	{
		if (isset($props))
		{
			foreach ($props as $key => $val) {
				
				if(method_exists($this,$key))
				{
					$this->$key($val);
				}
				else 
				{
					$this->setProperty($key,$val);
				}
			}
			
		}
	}/**
	 * Set Data index
	 *
	 * @param unknown_type $text
	 * @return MakeColumn
	 */
	public function dataIndex($text)
	{
		$this->properties['dataIndex'] = $text;
		$this->colProperties['dataIndex'] = "'$text'";
		$this->storeProperties['name'] = $text;
		return $this;
	}
	/**
	 * SET the header as to appear in the grid
	 * If this is not set the column will not be included in the grid!
	 *
	 * @param unknown_type $text
	 * @return MakeColumn
	 */
	public function header($text)
	{
		$this->properties['header'] = $text;
		$this->colProperties['header'] = "'$text'";
		return $this;
	}
	/**
	 * The type of the value
	 * Types that MakeGrid treats specialy:
	 * 		date - sets formater to the default set
	 * 		combo - sets a combobox for editor (needs comboTable,comboValue,comboDisplay opt. comboDatabase)
	 * 		checkColumn - sets up a special column, with editable checkbox (doesn't requre doubleclick to be editable)
	 *		more to come...
	 * @param unknown_type $type
	 * @return MakeColumn
	 */
	public function type($text)
	{
		$this->properties['type'] = $text;
		$this->storeProperties['type'] = $text;
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $type
	 * @return MakeColumn
	 */
	public function editor($text)
	{
		$this->properties['editor'] = $text;
		$this->colProperties['editor'] = $text;
		return $this;
	}
	/**
	 * The table this field belongs to, in case of editing!
	 *
	 * @param unknown_type $text
	 * @return MakeColumn
	 */
	public function table($text)
	{
		$this->properties['table'] = $text;
		$this->colProperties['RMtable'] = "'$text'";
		return $this;
	}
	/**
	 * Which field to use as ID when editing this field ?
	 *
	 * @param unknown_type $type
	 * @return MakeColumn
	 */
	public function idField($text)
	{
		$this->properties['idField'] = $text;
		$this->colProperties['idField'] = "'$text'";
		return $this;
	}
	/**
	 * Used when defining a combo type. 
	 * From which table to set up the combobox
	 *
	 * @param unknown_type $text
	 * @return MakeColumn
	 */
	public function comboTable($text)
	{
		$this->properties['comboTable'] = $text;
		return $this;
	}
	/**
	 * Used when defining a combo type. 
	 * Which field to use as value in combobox
	 *
	 * @param unknown_type $text
	 * @return MakeColumn
	 */
	public function comboValue($text)
	{
		$this->properties['comboValue'] = $text;
		return $this;
	}
	/**
	 * Used when defining a combo type. 
	 * Which field to use as display field in combobox
	 *
	 * @param unknown_type $type
	 * @return MakeColumn
	 */
	public function comboDisplay($text,$useSearch = false)
	{
		$this->properties['comboDisplay'] = $text;
		if($useSearch)
			$this->colProperties['comboDisplay'] = "'$text'";
		return $this;
	}
	/**
	 * Used if special SQL for combobox is requered!
	 *
	 * @param unknown_type $text
	 * @return MakeColumn
	 */
	public function comboSQL($text)
	{
		$this->properties['comboSQL'] = $text;
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @return MakeColumn
	 */
	public function renderer($text)
	{
		$this->properties['renderer'] = $text;
		$this->colProperties['renderer'] = $text;
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @return MakeColumn
	 */
	public function width($num)
	{
		$this->properties['width'] = $num;
		$this->colProperties['width'] = $num;
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $type
	 * @return MakeColumn
	 */
	public function hidden($bool)
	{
		$this->properties['hidden'] = $bool;
		$this->colProperties['hidden'] = $bool;
		return $this;
	}
/**
	 * Enter description here...
	 *
	 * @param unknown_type $type
	 * @return MakeColumn
	 */
	public function defaultValue($val)
	{
		$this->properties['defaultValue'] = $val;
		return $this;
	}
	/**
	 * Set a basic property
	 * WARNING: is string you have to manually set the paranthesis!
	 *
	 * @param unknown_type $key
	 * @param unknown_type $val
	 * @return MakeColumn
	 */
	public function setProperty($key,$val)
	{
		$this->colProperties[$key] = $val;
		return $this;
	}
}

class MakeGrid
{
	
	public $reqUrl = '_ajaxManipulators/gridDataManipulator.php';
	protected $newLine = "\n";
	
	protected $rndID;
	
	/*
	 * If the source is a database table we need to configure this properties
	 */
	public $table;
	protected $database;
	public $mainKey = 'id';
	public $selectSQL = false;
	
	/*
	 * If the source is a local array, we need to configure this properties
	 */
	public $dataArray;
	
	/*
	 * If the source is in a XML format, we need to configure this properties
	 */
	public $dataXML;

	
	/*
	 * the array which holds the properties for all the columns
	 * deprecated...$columns is now used to hold MakeColumn class
	 */
	protected $properties = array();
	/**
	 * array that holds the columns
	 *
	 * @var MakeColumn array
	 */
	protected $columns = array();
	
	/*
	 * Properties for paging
	 */
	protected $paging = false;
	protected $pagingLimit;
	
	
	/**
	 * if set to true CreateGrid will automaticly create the store! 
	 * Set to false if you want to define your own store.
	 *
	 * @var boolean
	 */
	public $autoCreateStore = true;
	
	//if we have checkselect or expandor row, then we must start editing the next row upon add
	protected $firstEditableColumn = 0;
	
	/*
	 * The formats for the dates
	 */
	protected $dateInput = 'Y-m-d';
	protected $dateOutput = 'd.m.Y';
	
	/*
	 * Properties for grouping
	 */
	protected $groupCol;
	
	//if filtering is set
	protected $filtering;
	
	//search field instead of filtering
	protected $searchField;
	/**
	 * Variable to hold the template, for the row expander
	 */
	protected $expanderTemplate;
	
	protected $checkBoxSelection;
	
	protected $addTBar = false;
	
	protected $addButton = false;
	protected $removeButton = false;
	protected $buttonSendSelected;
	protected $exportButton;
	
	protected $isNameRandom = false;
	protected $gridName;
	
	/**
	 * Array that holds default values
	 *  field is key, value is value!
	 * Can be set through addColumn, setDefaultValue(field,value) or directly in this var
	 * @var array
	 */
	public $defaultValues=array();
	/**
	 * Holds the special types, like checkColumn,comboBox
	 * Can create stores or other vars by default
	 *
	 * @var unknown_type
	 */
	public $specialTypes=array();
	 
	
	function __construct()
	{
		$this->rndID = mt_rand();
		$this->gridName = 'grid'.$this->rndID;
	}
	/**
	 * Adds a column to the grid
	 *
	 * @param unknown_type $props
	 * if array it sets the properties otherwise it is the dataIndex
	 * current properties :
	 * 		dataIndex : the field name in the table
	 * 		header : what name to use in header. if it is not passed this column will not be displayed!
	 * 		name : the field to update when edited. Defaults to dataIndex!
	 * 		renderer : the renderer to be used (e.g new Ext.form.TextField)
	 * 		editor : the editor to be used
	 * 		width : the width of the column
	 * 		table : in which table to update this field. Defaults to mainTable
	 * 		type : the type of the field. Defaults to text...I think
	 * 		idField : which field to use as the ID when updating.
	 * 		relaod : if true, it reloads the grid after editing
	 * @param unknown_type $header
	 * @param unknown_type $editType
	 * 
	 * @return MakeColumn - returns the created columns, so that properties can be set!
	 */
	function addColumn( $props,$header = null,$editType = null,$type = null)
	{
	/*	*/
		if( is_array($props)  )
		{
			//$this->properties[ $props['dataIndex']  ] = $props;
			return $this->columns[ $props['dataIndex']  ] = new MakeColumn($props);
		}
		else 
		{
			$tmp['dataIndex'] = $props;
			if($header)
				$tmp['header'] = $header;
			
			if ($editType)
				$tmp['editor'] = $editType;
				
			if($type)
			{
				$tmp['type'] = $type;
			}
			
			//$this->properties[$props] = $tmp;
			return $this->columns[$props] = new MakeColumn( $tmp);
		}
		
		return $this->columns[] = new MakeColumn();
		
	
	}
	/**
	 * creates all the special column types which are defined in the $specialTypes array
	 * Special types like combobox renderer, checkColumn etc.
	 *
	 * @return string - the javascript for the created types
	 */
	protected function createSpecialColumnData()
	{
	foreach ($this->specialTypes as $key => $spType) {
			
			$tmp .= $this->newLine."//CREATING A SPECIAL COLUMN TYPE".$this->newLine;
			switch ($spType) {
				case 'checkColumn':
					
					//for the checkColumn we must create an Ext.grid.CheckColumn
					//the name contains the dataIndex and the grid random id, so we don't mix up more columns
					$tmp.= 'var SpecCol'.$key.$this->rndID.' = new Ext.grid.CheckColumn(';
					
					//we assign properties to these columns as we would to normal columns
					$tmp.= $this->assignProperties($this->columns[$key]->properties);
					$tmp.=');'.$this->newLine;
					//since this column is included in the columns from grid as a variable, we set up a special flag
					$this->columns[$key]->properties['SpecCol'] = true;
					//and because this needs to be added as a plug in we set up another flag
					$this->columns[$key]->properties['specPlugin'] = true;
					
				break;
				case 'combo':
					/*3 things are neccesery if we want a ComboBox as a renderer AND editor
					1. the json store...the parameters for the store are passed in as
					comboTable, comboValue, comboDisplay (optional comboDatabase)
					*/ 
					$storeName = 'SpecStore'.$key.$this->rndID;
					$props = $this->columns[$key]->properties;
					$tmp .= 'var '.$storeName.' = new Ext.data.JsonStore({';
					$tmp .= 'url:"'.$this->reqUrl.'",';
					$tmp .= 'baseParams:{action:"select",database:"'.( isset($props['comboDatabase']) ? $props['comboDatabase'] : $this->database) .'",';
					$tmp .= 'table:"'.$props['comboTable'].'"';
					if (isset( $props['comboSQL']  ) )
						$tmp .= ',SQL:"'.$props['comboSQL'].'"';
					
					$tmp .=	'},root:"rows",';
					$tmp .= 'fields:["'.$props['comboValue'].'","'.$props['comboDisplay'].'"]});';
					$tmp .= $storeName.'.load();'.$this->newLine;
					//2. Create the comboBox form...value field and display field should be passed!
		
					$tmp.= 'var SpecCol'.$key.$this->rndID.' = new Ext.form.ComboBox({';
					$tmp.= "store:$storeName,";
					$tmp.= 'displayField:"'.$props['comboDisplay'].'",valueField:"'.$props['comboValue'].'",mode:"local",triggerAction:"all"';
					$tmp.= '});';
					//3rd Create the renderer to aply, so that it mathces to the editor!
					$tmp.= "var comboToRenderer = function(combo) { return function(value) {var idx = combo.store.find(combo.valueField, value);if(idx==-1)return 'Select';var rec = combo.store.getAt(idx);return rec.get(combo.displayField);};} ".$this->newLine;
					break;
				default:
					;
				break;
			}
			
		}
		
		return $tmp;
	}
	/**
	 * Function that creates the store and currently all the additional features of the grid (like filters, checkcolumns, exapnders etc.
	 * Depending on the data provided (table, array, xml) it creates the appropriate store
	 *
	 * @return string - the script for the store
	 */
	function createStore()
	{
		//if this function is manually called, then it shall not be called again from createGrid()
		$this->autoCreateStore = false;
		
		
		$tmp = $this->newLine.$this->newLine."//CREATING DATA STORE MODEL".$this->newLine;
		$tmp .= 'var ds_model'.$this->rndID.' = Ext.data.Record.create('.$this->newLine;
		
		foreach ($this->columns as $col) {
			//for each column we set up a name and opt. a type in the data model
			$field = $col->properties;
			$strField = '{ name:"'.$field['dataIndex'].'" ';
			if(isset($field['type']))
			{
				//we check for some special data types for special handling
				//the special types(like checkColumn, combo) are save in the specialTypes array, so we can handle them later
				switch ($field['type']) {
					case 'date':
					$strField .= ',dateFormat:"'.$this->dateInput.'" ';
					break;
					case 'checkColumn':
						$this->specialTypes[$field['dataIndex']] = 'checkColumn';
						//we change the type to bool, so that we don't TOTALY MESS UP the program!
						$field['type'] = 'bool';
						break;
					case 'combobox':
					case 'combo':
					case 'comboBox':
						$this->specialTypes[$field['dataIndex'] ] = 'combo';
						$field['type'] = 'int';
						
						break;
					default:
						;
					break;
					
				}
				$strField .= ',type: "'.$field['type'].'"';
			}
			
			$fields[] = $strField.'}';
		}
		
		$tmp .= '['.implode(',',$fields).']);'.$this->newLine;
		
		//lets create ALL the special columns variables our application will use.
		$tmp .= $this->createSpecialColumnData();
		
		//create the filters!!!
		if($this->filtering)
		{
			
			$tmp .= $this->newLine.'//CREATE FILTERING'.$this->newLine;
			$tmp .= 'var filters'.$this->rndID. '= new Ext.ux.grid.GridFilters({'.$this->newLine;
			$tmp .= 'filters:['.$this->newLine;
			
			foreach ($this->columns as $col )
			{
				$property = $col->properties;
				$filtTmp ='{dataIndex: "'.$property['dataIndex'].'",' ;
				if(isset($property['type']))
				{
					switch ($property['type']) {
						case 'combo':	
							$filtTmp.='type:"list",store:SpecStore'.$property['dataIndex'].$this->rndID.',
							phpMode:true,idField:"'.$property['comboValue'].'", labelField:"'.$property['comboDisplay'].'"' ;
						break;
						case 'bool':
							$filtTmp .= 'type:"boolean"';
							break;
						case 'int':
							$filtTmp .= 'type:"numeric"';
							break;
						case 'checkColumn':
							$filtTmp.='type:"boolean"';
							break;
						default:
							$filtTmp .= 'type:"'.$property['type'].'"';
						break;
					}
				}
				else 
				{
					$filtTmp .= 'type:"string"';
				}
				
				
				$filtTmp.='}'.$this->newLine;
				$filtesrTmp[] = $filtTmp;
			
			}
			$tmp.= implode(',',$filtesrTmp);
			$tmp.= ']});'.$this->newLine;
		//	$tmp .= '*/';
		}
		$tmp.= $this->newLine.'//CREATE THE DATA STORE READER'.$this->newLine;
		//depending of the type of data (http, array, xml...) we create a reader
		if(isset($this->table ))
		{
					$tmp .= 'var Reader'.$this->rndID.' = new Ext.data.JsonReader({'.$this->newLine;
					$tmp.=		'root:\'rows\'';
					if($this->paging)
					{
						$tmp.=',totalProperty : "results",idProperty:"id"';
					}
					$tmp.='},'.$this->newLine;
					
					//we assign properties that are required only for this specific reader
					$readerSpecific = "url:'$this->reqUrl',".$this->newLine;
					$readerSpecific .= 'remoteSort:true,remoteGroup:true,';
					$readerSpecific.= $this->newLine.'//ADDING BASE PARAMS TO STORE'.$this->newLine;
					$readerSpecific.= 'baseParams: {database:\''.$this->database.'\', action : \'select\',table : \''.$this->table.'\'  '.$this->newLine;
					if($this->selectSQL)
					{
						$readerSpecific.=', SQL : "'.$this->selectSQL.'" ';
					}
					if($this->paging)
					{
						$readerSpecific.=', start: 0,limit : '.$this->pagingLimit;
					}
					$readerSpecific.='},';
					
					//we set the specific load for the reader
					$loadSpecific = 'Store'.$this->rndID.'.load()'.$this->newLine;
					
		}
		elseif (isset( $this->dataArray))
		{
			$tmp .= "var myData$this->rndID = ".json_encode($this->dataArray).';'.$this->newLine;
			
			
			$tmp .= 'var Reader'.$this->rndID.' = new Ext.data.ArrayReader({},';
			
			$loadSpecific = 'Store'.$this->rndID.'.loadData(myData'.$this->rndID.')'.$this->newLine;
		}
		//the reader requires the data model, so it knows what kind of data it gets
		$tmp.='ds_model'.$this->rndID.$this->newLine;
		$tmp.=')'.$this->newLine;
		
		$tmp.= $this->newLine.'//CREATE THE DATA STORE'.$this->newLine;
		$tmp.= 'var Store'.$this->rndID. ' = new';
		if($this->groupCol)
		{
			$tmp.= " Ext.data.GroupingStore({ groupField : '$this->groupCol',";
			
			if(!isset($this->sortBy))
			{
				$tmp.= "sortInfo: { field: '$this->groupCol',direction: 'ASC'},";
			}
		}
		else 
		{
			$tmp .=' Ext.data.Store({'.$this->newLine;
		}
		
		if(isset($this->sortBy))
			{
				$tmp.= "sortInfo: { field: '$this->sortBy',direction: '$this->sortDir'},";
			}
		//we add the specific data, that the differend readers need (like json requers url...)
		$tmp.= $readerSpecific;
		$tmp.= $this->newLine.'//DEFINING THE READER'.$this->newLine;
		if(isset($this->exportButton ))
		{
			//if the export button is set, we set up a listener the load function, so that we can store all send parameters
			$tmp.= 'listeners:{ load : function(a,b,o){'.$this->gridName.'.lastOptions = o.params; }';
			$tmp.= '},';
		}
		
		$tmp.='reader: Reader'.$this->rndID.$this->newLine;
		$tmp.='});'.$this->newLine;
		//differend readers requere differnt load command...
		$tmp.= $loadSpecific;
		
		
		
		return $tmp;
	}
	/**
	 * creates a config object with all properties assigned for the column
	 * also checks for special types and assigns default values
	 *
	 * @param unknown_type $property
	 * @return unknown
	 */
	protected function assignProperties($property)
	{
			$col = '{sortable:true,name:"'.$property['dataIndex'].'",id:"'.$property['dataIndex'].'"';
				foreach ($this->columns[ $property['dataIndex'] ]->colProperties as $key => $val) {
					$col.= ','.$key.' : '.$val.' ';
				}
				if( isset($property['type']) )
				{
					switch ($property['type']) {
						case 'date':
						$col.= ',renderer: Ext.util.Format.dateRenderer("'.$this->dateOutput.'")';
						break;
						case 'combo':
							$col.=',editor: SpecCol'.$property['dataIndex'].$this->rndID;
							$col.=',renderer:comboToRenderer(SpecCol'.$property['dataIndex'].$this->rndID.')';
						break;
						default:
							;
						break;
					}
					
				}
				//if the required info for update and insert are not assigned the defaults are used
				if (!isset($property['table']) && isset($this->table))
				{	
					$col .= ',RMtable : "'.$this->table.'"';
				}
				if( !isset($property['idField']))
				{
					$col.= ',idField : "'.$this->mainKey.'" ';
				}
				//default values are stored in a special array, so that they may be used in the insert function
				if( isset($property['defaultValue']))
				{
					$this->defaultValues[$property['dataIndex'] ] = $property['defaultValue'];
				}
				
			/*	$col .= 'header:"'.$property['header'].'", dataIndex: "'.$property['dataIndex'].'",sortable:true'.', id: "'.$property['dataIndex'].'"';
				if(isset($property['editor']) )
				{
					$col .= ',editor : '.$property['editor'];
				}
				if(isset($property['name']))
				{
					$col .= ', name : "'.$property['name'].'"';
				}
				else 
				{
					$col .= ', name : "'.$property['dataIndex'].'"';
				}
				
				if(isset($property['renderer']))
				{
					$col .= ',renderer : '.$property['renderer'];
				}
				if(isset($property['width']))
				{
					$col .= ',width : '.$property['width'];
				}
				if (isset($property['table']))
				{
					$col .= ',RMtable : "'.$property['table'].'"';
				}
				elseif (isset($this->table) )
				{
					$col .= ',RMtable : "'.$this->table.'"';
				}
				
				
				if(isset($property['hidden'] ))
				{
					$col.= ',hidden:'.$property['hidden'];
				}
				if( isset($property['idField']))
				{
					$col.= ',idField : "' . $property['idField'].'"';
				}
				else 
				{
					$col.= ',idField : "'.$this->mainKey.'" ';
				}
				if( isset($property['reload']) )
				{
					$col.= ',reload : true';
				}
				
			/*	if( isset($this->specialTypes[$property['dataIndex']] ) )
				{
					switch ($this->specialTypes[$property['dataIndex']]) {
						case 'combo':
							$col.=',editor: SpecCol'.$property['dataIndex'].$this->rndID;
							$col.=',renderer:comboToRenderer(SpecCol'.$property['dataIndex'].$this->rndID.')';
						break;
						
						default:
							;
						break;
					}
				
				}*/
				
				$col .= '}'.$this->newLine;
				return $col;
	}
	/**
	 * Deprecated
	 * Function previously used for seperatly loading store. Store is now loaded automaticly after creation
	 * Please delete!
	 *
	 */
	public function loadStore()
	{
		
	}
	function createGrid()
	{
		$tmp = '';
		if($this->autoCreateStore)
		{
			$tmp .= $this->createStore();			
		}
		
		
		//adding the Expander
		//here we define the expander! we add it in the columns at the begging and in the $plugins field!
	
		if(isset($this->expanderTemplate) )
		{
			$tmp.= $this->newLine.'//CREATE THE EXPANDER'.$this->newLine;
			$tmp.= 'var expander'.$this->rndID.' = new Ext.grid.RowExpander({'.$this->newLine;
			$tmp.= 'tpl: new Ext.Template(\''.$this->expanderTemplate."')});".$this->newLine;
			$this->firstEditableColumn++;
			
			$col = 'expander'.$this->rndID;
			$columns[] = $col;
			$plugins[] = $col;
		}
		
		if( $this->checkBoxSelection )
		{
			$tmp.= $this->newLine.'//CREATE THE CHECKBOX SELECTION MODEL'.$this->newLine;
			$tmp .= 'var checkBoxsm'.$this->rndID.' = new Ext.grid.CheckboxSelectionModel();'.$this->newLine;
			$this->firstEditableColumn++;
			
			$col = 'checkBoxsm'.$this->rndID;
			$columns[] = $col;
		}
		if(isset($this->searchField))
		{
			//ce prav razumem primer, to pokne sam v plugin
			{
				$plugins[] = "new Ext.ux.grid.Search({minChars:3,position:'$this->searchFieldPos',paramNames:{fields:'srcfields', query:'srcquery'} })";
			}
		}
		if(isset($this->rowAction))
		{
			$tmp.='var rowActions'.$this->rndID.' = new Ext.ux.grid.RowActions({';
			$tmp.='actions:[{iconCls:\'icon-minus\',qtip:"Delete Record"},{ iconCls:\'icon-edit-record\' ,qtip:\'Edit Record\' }],id:"actions",getEditor:Ext.emptyFn';
			$tmp.=',listeners:{action:function(grid, record, action, row, col){testRecordForm.show(record,'.$this->getGridName().'.getView().getCell(row,col)  ); } } });';
			$columns[] = 'rowActions'.$this->rndID;
			$plugins[] = 'rowActions'.$this->rndID;
			$plugins[] = 'testRecordForm';
			$tmp.='testRecordForm.afterUpdateRecord = function(rec){console.log(rec);}';
			
		}
		
		$tmp.= $this->newLine.'//CREATE THE GRID ITSELF!!!'.$this->newLine;
		$tmp .= 'var '.$this->gridName.' = new Ext.grid.EditorGridPanel({'.$this->newLine;
		//$tmp .= 'renderTo:"'.$this->table.'Div" ,'.$this->newLine;
		$tmp .= 'store: Store'.$this->rndID.','.$this->newLine;
		$tmp .= 'closable: true,';
	//	$tmp .= 'lastOptions : {a:"lala"},';
		$tmp .= 'id: "'.$this->gridName.'",'.$this->newLine;
		if(isset($this->title))
		{
			$tmp .= 'title: "'.$this->title.'",'.$this->newLine;
		}
		
		
		$tmp .= 'columns: ['.$this->newLine;
		
		if($this->filtering)
		{
			$plugins[] = 'filters'.$this->rndID;
		}
		
		//$plugins[]='expander';
		$tmp.= $this->newLine.'//DEFINING THE COLUMNS FOR THE GRID'.$this->newLine;
		foreach ($this->columns as $field )
		{
			$property = $field->properties;
		
			if( isset($property['header'] ) )
			{
				//if the column has a specific setting like CheckColumn or a special combobox!
				if( $property['SpecCol'] )
				{
					$col = 'SpecCol'.$property['dataIndex'].$this->rndID;
					$columns[] = $col;
					if($property['specPlugin'])
						$plugins[] = $col;
				}
				else 
				{
					$columns[] = $this->assignProperties($property);
				}
				//$columns[].= '{ header:"'.$property['header'].'", dataIndex:"'.$this->fields[$i].'", id:"'.$this->fields[$i].'",editor: new '.$this->editType[$i].'}'.$this->newLine;
			}
		}
		$tmp .= implode(',',$columns);
		//testno checkColumn
		$tmp .= '],'.$this->newLine;
		if(isset($plugins) )
		{
			$tmp.='plugins :['.implode(',',$plugins).'],';
		}
	//	$tmp .= 'autoHeight:true,'.$this->newLine;
		$tmp .= 'clicksToEdit:1,'.$this->newLine;
		if(isset($this->autoExpand))
		{
			$tmp.= 'autoExpandColumn :\''.$this->autoExpand."',";
		}
		
		if($this->addTBar  ||$this->searchFieldPos == 'top')
		{
			$tmp .= 'tbar:[';
			$tbar = array();
			if($this->addButton)
			{
				$tbarTmp = $this->newLine.'//ADDING THE ADD BUTTON'.$this->newLine;
				$tbarTmp .= "{text:'$this->addButton', ";
				$tbarTmp.= 'handler : function(){ var conn = new Ext.data.Connection();'.$this->newLine;
				$tbarTmp.= 'conn.request({';
				$tbarTmp.= "url: '$this->reqUrl', params: {";
				$tbarTmp .= "database:'$this->database',action: 'insert',table:'$this->table'";
				
				//if we have any default values set, we include the values statement
				foreach ($this->defaultValues as $fl => $df) {
					$fldsSQL[] = $fl;
					$valSQL[] = $df;
				}
				
				
			
				if(is_array($fldsSQL) )
				{
					$tbarTmp .= ',defaultFields : "'.implode(',',$fldsSQL).'",defaultValues :"\''.implode("','",$valSQL).'\'"';
				}
				$tbarTmp .= '},success: function(resp,opt){';
				$tbarTmp .= 'var insert_id = Ext.util.JSON.decode(resp.responseText).insert_id;'.$this->newLine;
				$tbarTmp .= 'var lastRow = Store'.$this->rndID.'.getCount();';
				$tbarTmp .= $this->gridName.'.getStore().insert(lastRow,new ds_model'.$this->rndID.'({id:insert_id ';
				foreach ($this->defaultValues as $fl => $df) {
					
					if ($this->columns[$fl]->properties['type'] == 'date' ) 
					{
						$tbarTmp .= ', '.$fl .':  Date.parseDate("'.$df.'","Y-m-d")';
					}
					
					else $tbarTmp .= ', '.$fl .': "'.$df.'"';
				}
				$tbarTmp .=	'}));'.$this->newLine;
				$tbarTmp .= $this->gridName.'.startEditing(lastRow,'.$this->firstEditableColumn.');';
				$tbarTmp .= '}';
				$tbarTmp .= '}); }}'.$this->newLine;
				
				
				$tbar[] = $tbarTmp;
			}
			if($this->removeButton)
			{
				$tbarTmp= $this->newLine.'//ADDING THE REMOVE BUTTON'.$this->newLine;
				$tbarTmp.= "{text:'$this->removeButton', ";
				$tbarTmp.= 'handler:function(){'.$this->newLine;
				$tbarTmp.= 'var sm = '.$this->gridName.'.getSelectionModel();';
				$tbarTmp.= 'if(sm.hasSelection()){'.$this->newLine;
				$tbarTmp.= 'var sel = sm.getSelections();'.$this->newLine;
				$tbarTmp.= "Ext.Msg.show({ title:'Remove record',buttons: Ext.MessageBox.YESNO,msg:'Are you sure?',";
				$tbarTmp.= "fn: function(btn){if(btn == 'yes'){";
				$tbarTmp.='var conn = new Ext.data.Connection();';
				$tbarTmp.='var x; for(x=0; x<sel.length ;x++){';
				$tbarTmp.="conn.request({ url:'$this->reqUrl', params: {";
				$tbarTmp.="database:'$this->database',action:'delete',id:sel[x].data.id,table:'$this->table',x:x }, ";
				$tbarTmp.='success:function(res,opt){ '.$this->gridName.'.getStore().remove(sel[opt.params.x]);}';
			//	$tbarTmp.='success: HUDICJEBENI';				
				$tbarTmp .= ' }); }    }} }); } }}'.$this->newLine;
				
				$tbar[] = $tbarTmp;
			}
			if (isset($this->buttonSendSelected ))
			{
				$tbarTmp = $this->newLine.'//ADDING THE SEND SELECTED BUTTON'.$this->newLine;
				$tbarTmp .= "{text: '$this->buttonSendSelected',";
				$tbarTmp.= 'handler:function(){'.$this->newLine;
				$tbarTmp.= 'var sm = '.$this->gridName.'.getSelectionModel();';
				$tbarTmp.= 'if(sm.hasSelection()){'.$this->newLine;
				$tbarTmp.= 'var sel = sm.getSelections();'.$this->newLine;
				
				$tbarTmp.='var conn = new Ext.data.Connection();var fld = [];';
				$tbarTmp.='var x; for(x=0; x<sel.length ;x++){ fld.push(sel[x].data.'.$this->buttonSendField.')}';
				$tbarTmp.="conn.request({ url:'$this->buttonSendReqUrl', params: {";
				$tbarTmp.="data: Ext.encode(fld) },callback:$this->buttonSendCallback }); } } } ".$this->newLine;
				
				//buttonSendReqUrl
				$tbar[] = $tbarTmp;
			}
			if(isset($this->exportButton))
			{
				$tbarTmp = $this->newLine.'//ADDING THE EXPORT BUTTON'.$this->newLine;
				$tbarTmp .= "{text: '$this->exportButton',";
				$tbarTmp.="menu:[";
				$tbarTmp.="{text:'Excel',";
			
				$tbarTmp.= 'handler:function(){'.$this->newLine;
					//this works only for remote options, since the export is done on the server
					//lets break the reference, so we don't mess the original load options!!!
				$tbarTmp.= "var expParams =  Ext.decode(Ext.encode($this->gridName.lastOptions)); var cm = $this->gridName.getColumnModel();var str='';".$this->newLine;
				$tbarTmp.= "var cols = [];var heads=[]; for(var x=0;x<cm.getColumnCount();x++){var col = cm.config[x]; if( !cm.isHidden(x) && col.dataIndex != ''){ cols[x] = col.comboDisplay ? col.comboDisplay : col.dataIndex;heads[x]=col.header;}  } expParams.cols = Ext.encode(cols);expParams.heads = Ext.encode(heads);".$this->newLine;
				$tbarTmp.= "expParams.action='export';expParams.RMexport = 'excel';".$this->newLine;
				$tbarTmp.='var conn = new Ext.data.Connection();'.$this->newLine;
				$tbarTmp.="report.load({ url:'$this->reqUrl', params: expParams });}}".$this->newLine;
					
				
				
			
				$tbarTmp.="	,{text:'CSV',";
				$tbarTmp.= 'handler:function(){'.$this->newLine;
					//this works only for remote options, since the export is done on the server
					//lets break the reference, so we don't mess the original load options!!!
				$tbarTmp.= "var expParams =  Ext.decode(Ext.encode($this->gridName.lastOptions)); var cm = $this->gridName.getColumnModel();var str='';".$this->newLine;
				$tbarTmp.= "var cols = [];var heads=[]; for(var x=0;x<cm.getColumnCount();x++){col = cm.config[x]; if( !cm.isHidden(x) && col.dataIndex != ''){ cols[x] = col.comboDisplay ? col.comboDisplay : col.dataIndex;heads[x]=col.header;}  } expParams.cols = Ext.encode(cols);expParams.heads = Ext.encode(heads); ".$this->newLine;
				$tbarTmp.= "expParams.action='export';expParams.RMexport = 'csv';".$this->newLine;
				$tbarTmp.='var conn = new Ext.data.Connection();'.$this->newLine;
				$tbarTmp.="report.load({ url:'$this->reqUrl', params: expParams });}}".$this->newLine;
				
				$tbarTmp.="	,{text:'XML',";
				$tbarTmp.= 'handler:function(){'.$this->newLine;
					//this works only for remote options, since the export is done on the server
					//lets break the reference, so we don't mess the original load options!!!
				$tbarTmp.= "var expParams =  Ext.decode(Ext.encode($this->gridName.lastOptions)); var cm = $this->gridName.getColumnModel();var str='';".$this->newLine;
				$tbarTmp.= "var cols = [];var heads=[]; for(var x=0;x<cm.getColumnCount();x++){col = cm.config[x]; if( !cm.isHidden(x) && col.dataIndex != ''){ cols[x] = col.comboDisplay ? col.comboDisplay : col.dataIndex;heads[x]=col.header;}  } expParams.cols = Ext.encode(cols);expParams.heads = Ext.encode(heads); ".$this->newLine;
				$tbarTmp.= "expParams.action='export';expParams.RMexport = 'xml';".$this->newLine;
				$tbarTmp.='var conn = new Ext.data.Connection();'.$this->newLine;
				$tbarTmp.="report.load({ url:'$this->reqUrl', params: expParams });}}".$this->newLine;
				
			
				$tbarTmp.="	]} ".$this->newLine;
					
				//buttonSendReqUrl
				$tbar[] = $tbarTmp;
			}
			$tmp .= implode(',',$tbar);
			
			$tmp .= '],';
		}
		//we add paging
		if($this->paging)
		{
			$tmp.= $this->newLine.'//ADDING THE PAGING'.$this->newLine;
			$tmp .= 'bbar: new Ext.PagingToolbar({';
			$tmp .= 'pageSize:'.$this->pagingLimit.', store: Store'.$this->rndID;
			$tmp .= ',displayInfo : true, displayMsg : "Showing {0} - {1} from {2}"';
			$tmp .= '}),';
		}
		elseif ($this->searchFieldPos == 'bottom')
		{
			$tmp.='bbar:[],';
		}
		//add grouping
		if($this->groupCol)
		{
			$tmp.= $this->newLine.'//ADDING THE GROUP VIEW'.$this->newLine;
			$tmp .= 'view : new Ext.grid.GroupingView(),';
		}
		//we add listeners 
		$tmp .= 'listeners: {'.$this->newLine;
		$tmp.= $this->newLine.'//ADDING THE AFTER EDIT LISTENER'.$this->newLine;
		$tmp .= 'afteredit : function(e) {';
		if(isset($this->table))
		{
			$tmp .= 'var conn = new Ext.data.Connection();';
			$tmp .= 'conn.request({';
			$tmp .=		"url: '$this->reqUrl', params: {";
			$tmp .= "database:'$this->database',action: 'update', id: e.record.get( e.grid.getColumnModel().config[e.column].idField ),idField : e.grid.getColumnModel().config[e.column].idField ,field: e.grid.getColumnModel().config[e.column].name ,value : Ext.isDate(e.value) ? Ext.util.Format.date(e.value, 'Y-m-d') : e.value ,table: e.grid.getColumnModel().config[e.column].RMtable},";
			$tmp .= "success : function(resp,opt){if(Ext.decode(resp.responseText).success){ e.record.commit(); if(e.grid.getColumnModel().config[e.column].reload){ Store".$this->rndID.".reload();} } else {e.record.reject();}},";
			$tmp .= "failure: function(){e.record.reject();}});";
		}
		elseif (isset($this->dataArray))
		{
			$tmp .= 'e.record.commit();';
		}
		$tmp .= " }},".$this->newLine;
		
		if ($this->checkBoxSelection )
		{
			$tmp.= 'sm : checkBoxsm'.$this->rndID.'';
			
		}
		else 
		{
			$tmp .= 'sm: new Ext.grid.RowSelectionModel({singleSelect : true}) ';
		}
				
		$tmp .= '});'.$this->newLine;
		
		return $tmp;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $b
	 * @return MakeGrid
	 */
	function activateAdd($b)
	{
		$this->addButton = $b;
		$this->addTBar = true;
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $b
	 * @return MakeGrid
	 */
	function activateRemove($b)
	{
		$this->removeButton = $b;
		$this->addTBar = true;
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @param unknown_type $file
	 * @param unknown_type $callback
	 * @param unknown_type $sendField
	 * @return MakeGrid
	 */
	function addButtonSendSelected($text,$file,$callback = 'function(){}',$sendField = 'id')
	{
		$this->buttonSendSelected = $text;
		$this->buttonSendReqUrl = $file;
		$this->buttonSendField = $sendField;
		$this->buttonSendCallback = $callback;
		
		$this->addTBar = true;
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @return MakeGrid
	 */
	function addExportButton($text)
	{
		$this->exportButton = $text;
		$this->addTBar = true;
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $table
	 * @param unknown_type $database
	 * @param unknown_type $key
	 * @param unknown_type $sortBy
	 * @param unknown_type $sortDir
	 * @return MakeGrid
	 */
	function setMainTable($table,$database = null, $key = 'id',$sortBy=null,$sortDir = 'asc')
	{
		$this->table = $table;
		$this->mainKey = $key;
		if($database)
			$this->database = $database;
		if($sortBy)
		{
		/*	$this->sortBy = $sortBy;
			$this->sortDir = $sortDir;*/
			$this->setSort($sortBy,$sortDir);
		}
		return $this;
	}
	function setReqUrl($url)
	{
		$this->reqUrl = $url;
		if(!isset($this->table) )
		{
			$this->table = true;
		}
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $limit
	 * @return MakeGrid
	 */
	function setPaging($limit)
	{
		$this->paging = true;
		$this->pagingLimit = $limit;
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $groupColumn
	 * @return MakeGrid
	 */
	function setGrouping($groupColumn)
	{
		$this->groupCol = $groupColumn;
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $columnId
	 * @return MakeGrid
	 */
	function setAutoExpand($columnId)
	{
		$this->autoExpand = $columnId;
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $title
	 * @return MakeGrid
	 */
	function setTitle($title)
	{
		$this->title = $title;
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $database
	 * @return MakeGrid
	 */
	function setDatabase($database)
	{
		$this->database = $database;
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $template
	 * @return MakeGrid
	 */
	function setExpander($template)
	{
		//$this->expanderTemplate = $template;
		$this->expanderTemplate = str_replace("'","\\'",$template);
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $bool
	 * @return MakeGrid
	 */
	function setCheckBoxSelectionModel($bool)
	{
		$this->checkBoxSelection = true;
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $bool
	 * @return MakeGrid
	 */
	function setFiltering($bool)
	{
		$this->filtering = true;
		return $this;
	}
	/*function setNameRandom($bool)
	{
		$this->isNameRandom = true;
	}*/
	/**
	 * Enter description here...
	 *
	 * @return string
	 */
	function getGridName()
	{
		return $this->gridName;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $name
	 * @return MakeGrid bla
	 */
	function setGridName($name)
	{
		
		$this->gridName = $name;
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $sortBy
	 * @param unknown_type $dir
	 * @return MakeGrid
	 */
	function setSort($sortBy,$dir='ASC')
	{
		$this->sortBy = $sortBy;
		$this->sortDir = $dir;
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $sortBy
	 * @param unknown_type $dir
	 * @return MakeGrid
	 */
	function setSearchField($text,$position = 'top')
	{
		$this->searchField = $text;
		$this->searchFieldPos = $position;
		return $this;
	}
	function setRowAction()
	{
		$this->rowAction = true;
	}
	function setRecordForm()
	{
		$this->recordForm = true;
	}
}
?> 
