<?php

include_once("_dirinfo.php");

include_once (PATH_TO_ROOT."_class/class.Extjs.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
{

	/**
	 * The grid containing this column
	 *
	 * @var MakeGrid
	 */
	private $gridParent;
	/**
	 * 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!
	 * @var unknown_type
	 */
	public $storeProperties;

	/**
	 * array of cell actions!
	 * @var unknown_type
	 */
	public $cellActions;

	function __construct($props=null,$grid = null)
	{
		if (isset($props))
		{
			foreach ($props as $key => $val) {

				if(method_exists($this,$key))
				{
					$this->$key($val);
				}
				else
				{
					$this->setProperty($key,$val);
				}
			}

		}

		$this->gridParent = $grid;
	}/**
	 * 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->colProperties['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,$nameAs = '')
	{
		$this->properties['table'] = $text;
		$this->colProperties['RMtable'] = "'$text'";
		$this->properties['tableAs'] = $nameAs ? $nameAs : $text;
		if($nameAs)
			$this->colProperties['tableAs'] = "'$nameAs'";

		return $this;
	}

	public function tableAs($text)
	{
		$this->properties['tableAs'] = $text;
		$this->colProperties['tableAs'] = "'$text'";

		return $this;
	}

	/**
	 * If left join is used tell the filter to convert NULL into zeros! (currently only used with filter)
	 *
	 * @param unknown_type $text
	 * @return MakeColumn
	 */
	public function convertNull()
	{
		$this->properties['convertNull'] = 'true';
		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,$mode = 'local')
	{
		$this->properties['comboTable'] = $text;
		$this->properties['mode'] = $mode;
		return $this;
	}
	/**
	 * Used when defining a combo type.
	 * From which table to set up the combobox
	 *
	 * @param unknown_type $text
	 * @return MakeColumn
	 */
	public function comboDatabase($text)
	{
		$this->properties['comboDatabase'] = $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,$useRenderer = true)
	{
		$this->properties['comboValue'] = $text;
		$this->properties['useComboRenderer'] = $useRenderer;
		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 when defining a combo type.
	 * Which field to use as renderer to showing in grid (only if it's different than display!)
	 *
	 * @param unknown_type $type
	 * @return MakeColumn
	 */
	public function comboRender($text)
	{
		$this->properties['comboRender'] = $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;
	}
	/**
	 * Used if special WHERE for combobox is requered!
	 *
	 * @param unknown_type $text
	 * @return MakeColumn
	 */
	public function comboWhere($text)
	{
		$this->properties['comboWhere'] = $text;
		return $this;
	}
/**
	 * Used if special SQL for combobox is requered!
	 *
	 * @param unknown_type $text
	 * @return MakeColumn
	 */
	public function comboProperties($text)
	{
		$this->properties['comboProperties'] = $text;
		return $this;
	}
	/**
	 * Used if special SQL for combobox is requered!
	 *
	 * @param unknown_type $text
	 * @return MakeColumn
	 */
	public function comboListeners($text)
	{
		$this->properties['comboListeners'] = $text;
		return $this;
	}
/**
	 * Used if a predefined store is used for combobox (anything that combobox accepts as store!
	 *
	 * @param unknown_type $text
	 * @return MakeColumn
	 */
	public function comboStore($text,$data=false)
	{
		if(is_array($text))
			$text = json_encode($text);
		$this->properties['comboStore'] = $text;
		if($data)
			$this->properties['comboStoreData'] = $data;
		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 groupRenderer($text)
	{
		$this->colProperties['groupRenderer'] = $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;
	}
	/**
	 * A function that is called after this field is editer
	 * Function is called with parameter e
	 *
	 * @param unknown_type $val
	 * @return MakeColumn
	 */

	public function afterEditHandler($function)
	{
		$this->setProperty('aftereditHandler',$function);
		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;
	}
	/**
	 * Add a icon cell action (plugin by Saki)
	 *
	 * @param unknown_type $key
	 * @param unknown_type $val
	 * @return MakeColumn
	 */
	public function addIconAction($icon,$listener)
	{
		$this->cellActions[] = "{iconCls:'$icon' }";
		$this->colProperties['cellActions'] = "[".implode(',',$this->cellActions). "]";

		$this->gridParent->cellActionListeners[ $this->properties['dataIndex'] ][$icon] = $listener;
		/* $this->gridParent->plugins[] = "new Ext.ux.grid.CellActions({listeners:{
                action:$listener }})";*/


		return $this;
	}


    //TODO docs
    public function addSummaryType($text)
    {
        $this->properties['summaryType'] = "'" . $text . "'";
        $this->colProperties['summaryType'] = "'" . $text . "'";
        return $this;
    }


    public function addSummaryRenderer($text)
    {
        $this->colProperties['summaryRenderer'] = $text;
        return $this;
    }

}

class MakeGrid extends MakeComponent
{

	public $reqUrl = '_ajaxManipulators/gridDataManipulator.php';



	public $mainKey = 'id';


	/*
	 * 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
	public $firstEditableColumn = 0;


	/*
	 * Properties for grouping
	 */
	protected $groupCol;

	//if filtering is set
	protected $filtering;

	//search field instead of filtering
	protected $searchField;
	public $searchFieldTwo;
	/**
	 * Variable to hold the template, for the row expander
	 */
	protected $expanderTemplate;

	protected $checkBoxSelection;

   /**
    * Variable to hold groupSummary options
    */
    protected $groupSummaryConfig;

    protected $groupSummaryEnable = false;


	protected $addButton = false;
	protected $removeButton = false;
	protected $buttonSendSelected;
	protected $exportButton;
	/**
	 * this variable defines whether an afteredit listener is specified!
	 * this does NOT make cells editable! a cell is editable whether it has an editor or not!
	 * If you don't want the record to be commited or canceled after editing call setEditing(false)
	 *
	 * @var boolean
	 */
	protected $editable = true;

	public $cellActionListeners;
	/**
	 * 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($varName = null)
	{
		parent::__construct($varName);


	}

/**
	 * Enter description here...
	 *
	 * @param unknown_type $table
	 * @param unknown_type $database
	 * @param unknown_type $key
	 * @return MakeGrid
	 */
	function setMainTable($table,$database = null, $key = 'id'){ parent::setMainTable($table,$database,$key);return $this;}

	/**
	 * Enter description here...
	 *
	 * @param unknown_type $limit
	 * @return MakeGrid
	 */
	function setPaging($limit = 'auto')
	{

		if($limit == 'auto')
		{
			$this->paging = 'auto';
			$limit = 0;
		}
		else
			$this->paging = true;
		$this->pagingLimit = $limit;
		return $this;
	}
	private $autoLoad = true;
	public function setAutoLoad($bool)
	{
		$this->autoLoad = $bool;
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $groupColumn
	 * @return MakeGrid
	 */
	function setGrouping($groupColumn,$conf = '{hideGroupedColumn: true,enableGroupingMenu:false,enableNoGroups:false}')
	{
		$this->groupCol = $groupColumn;
	/*	$this->configs[] = '//ADDING THE GROUP VIEW'.$this->newLine
			.'view : new Ext.grid.GroupingView()';*/
		$this->addConfig('view',"new Ext.grid.GroupingView( $conf )");
		return $this;
	}
	/**
	 * Defines whether an afteredit listener is aplied
	 * You can also specify an success or failure function in this form:
	 * function(response, optionc) { code  }
	 *
	 * @param boolean $groupColumn
	 * @param string $success - function to call on success
	 * @param string $failure - function to call on fail
	 * !WARNING failure function will be called on server error!!! a returned JSON string having success : false, does not mean a failure!!!
	 * @return MakeGrid
	 */
	function setEditable($bool = true,$success = null,$failure = null)
	{
		$this->afterEditSucces = $success;
		$this->afterEditFailure = $failure;
		$this->editable = $bool;
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $columnId
	 * @return MakeGrid
	 */

	public function addButton($text,$function){parent::addButton($text,$function);return $this;}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @return MakeGrid
	 */
	function setAutoExpand($columnId,$min=50,$max=1000)
	{
		$this->autoExpand = $columnId;
		$this->configs['autoExpandColumn'] = '\''.$this->autoExpand."'";
		$this->configs['autoExpandMin'] = $min;
		$this->configs['autoExpandMax'] = $max;

		return $this;
	}

	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @return MakeGrid
	 */
	function setAutoExpandMax($width)
	{
		$this->configs['autoExpandMax'] = '\''.$width."'";

		return $this;
	}

	/**

	 * @return MakeGrid
	 */
	function setTitle($title,$iconCls = null) { parent::setTitle($title,$iconCls); 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,$expConfig = '')
	{
		//$this->expanderTemplate = $template;
		$this->expanderTemplate = str_replace("'","\\'",$template);
		$this->expanderConfig = $expConfig;
		return $this;
	}
     /**
     * Enter description here...
     *
     * @param unknown_type $template
     * @return MakeGrid
     */
    function addSummaryGroup($config = '')
    {
        $this->groupSummaryEnable = true;
        $this->groupSummaryConfig = $config;
        return $this;
    }
     /**
     * Enter description here...
     *
     * @param unknown_type $template
     * @return MakeGrid
     */
    function addCustomSummaryFunction($text)
    {
        $this->groupSummaryEnable = true;
        $this->groupSummaryConfig = $config;
        return $this;
    }
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $bool
	 * @return MakeGrid
	 */
	function setCheckBoxSelectionModel()
	{
		$this->checkBoxSelection = true;
		return $this;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $bool
	 * @return MakeGrid
	 */
	function setFiltering($bool=true)
	{
		$this->filtering = true;
		return $this;
	}

	/**
	 * Enter description here...
	 *
	 * @return string
	 */
	function getGridName()
	{
		return $this->compName;
	}
/**
	 * Enter description here...
	 *
	 * @return string
	 */
	function getStoreName()
	{
		return 'Store'.$this->rndID;
	}
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $name
	 * @return MakeGrid
	 */
	function setGridName($name)
	{

		$this->compName = $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 = 'Search',$position = 'top',$minChars = 0,$disableArray='[]')
	{
		/*if( is_array($text) )
		{
			foreach ($text as $key => $val) {
				;
			}

		}*/
		$this->searchField = $text;
		$this->searchFieldPos = $position;
		$this->searchMinChars = $minChars;
		$this->searchDisableIndexes = $disableArray;
		$this->searchIndexPos = count($this->tBarItems);
		return $this;
	}
	function setRowAction()
	{
		$this->rowAction = true;
	}
	function setRecordForm()
	{
		$this->recordForm = true;
	}

	protected $storeConfigs = array();
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $sortBy
	 * @param unknown_type $dir
	 * @return MakeGrid
	 */
	function setRemoteSort()
	{

		$this->storeConfigs[] = 'remoteSort : true';
		return $this;
	}
/**
	 * Enter description here...
	 *
	 * @param unknown_type $url
	 * @return MakeGrid
	 */
	function setReqUrl($url){ parent::setReqUrl($url); return $this; }
	/**
	 * Enter description here...
	 *
	 * @param unknown_type $url
	 * @return MakeGrid
	 */
	function setSortable($bool = true){ $this->sortable = $bool; return $this; }



/**
	 * This button must be defined at create time so that all default values are declared, that's why the createAddButton function is called
	 *
	 * @param unknown_type $b
	 * @return MakeGrid
	 */

	function activateAdd($b='Add',$icon = 'icon-add-record',$success='')
	{
		$this->addButton = $b;
		$success = addslashes($success);
		$tbarTmp['function'] = "\$this->createAddButton('$b','$icon','$success');";
		$this->addtBarItem($tbarTmp);
		return $this;
	}
	/**
	 * Enter description here...
	 * @return $this
	 */
	function addSetter($columns)
	{
		if($columns)
		{//create javascript array
			$conf = "columns:[$columns]";
		}
		$this->plugins[] = "new Ext.ux.grid.GridSetter({ $conf })";
		return $this;
	}

	function createAddButton($b,$icon,$success)
	{

				$addFuncTmp = "function(){";
				$addFuncTmp.= "var tmpStore =  $this->compName.getStore(); ";

				if(isset($this->table))
				{

					$addFuncTmp.= $this->compName.'.RMconn.request({';
					$addFuncTmp.= "params: {";
					$addFuncTmp .= "action: 'insert'";

					//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) )
					{
						$addFuncTmp .= ',defaultFields : "'.implode(',',$fldsSQL).'",defaultValues :"\''.implode("','",$valSQL).'\'"';
					}
					$addFuncTmp .= "},success: function(resp,opt){
					var response  = Ext.decode(resp.responseText);
					if(response.success == false)
					{
						alert('Error: '+response.error);
						return;
					}	";

					$addFuncTmp .= 'var insert_id = Ext.util.JSON.decode(resp.responseText).insert_id;'.$this->newLine;
					$addFuncTmp .= 'var lastRow = tmpStore.getCount();';
					$addFuncTmp .= 'tmpStore.insert(lastRow,new ds_model'.$this->rndID.'({id:insert_id ';
					foreach ($this->defaultValues as $fl => $df) {

						if ($this->columns[$fl]->properties['type'] == 'date' )
						{
							$addFuncTmp .= ', '.$fl .':  Date.parseDate("'.$df.'","'.$this->dateSQL.'")';
						}

						else $addFuncTmp .= ', '.$fl .': "'.$df.'"';
					}
					$addFuncTmp .=	'}));'.$this->newLine;
					$addFuncTmp .= $success.';';
					$addFuncTmp .= $this->compName.'.startEditing(lastRow,'.$this->firstEditableColumn.');';
					$addFuncTmp .= '}';
					$addFuncTmp .= '});';
				}
				elseif (isset($this->dataArray))
				{
					$addFuncTmp .= 'var lastRow = tmpStore.getCount();';
					$addFuncTmp .= $this->compName.'.getStore().insert(lastRow,new ds_model'.$this->rndID.'({';
					foreach ($this->defaultValues as $fl => $df) {

						if ($this->columns[$fl]->properties['type'] == 'date' )
						{
							$dfVal[] = $fl .':  Date.parseDate("'.$df.'","'.$this->dateSQL.'")';
						}

						else $dfVal[] = $fl .': "'.$df.'"';
					}
					if (is_array($dfVal))
					{
						$addFuncTmp .= implode(',',$dfVal);
					}
					$addFuncTmp .=	'}));'.$this->newLine;
					$addFuncTmp .= $this->compName.'.startEditing(lastRow,'.$this->firstEditableColumn.');';
				}
				$addFuncTmp .= '}';

		$this->addConfig('RMaddRow',$addFuncTmp);
	//	$this->addConfig('RMaddRow',"function(){alert('hahaha');}");

		$tbarTmp = $this->newLine.'//ADDING THE ADD BUTTON'.$this->newLine;
				$tbarTmp .= "{text:'$this->addButton',iconCls:'$icon', ";
				$tbarTmp.= "handler : function(){ $this->compName.RMaddRow() }".$this->newLine;



				$tbarTmp .= '}'.$this->newLine;

		return $tbarTmp;
	}

	/**
	 * Enter description here...
	 *
	 * @param unknown_type $b
	 * @return MakeGrid
	 */
	function activateRemove($b='Remove',$icon = 'icon-delete-record',$success = '')
	{
				$this->removeButton = $b;

				$tbarTmp= $this->newLine.'//ADDING THE REMOVE BUTTON'.$this->newLine;
				$tbarTmp.= "{text:'$this->removeButton',iconCls:'$icon', ";
				$tbarTmp.= 'handler:function(){'.$this->newLine;
				$tbarTmp.= 'var sm = '.$this->compName.'.getSelectionModel();';
				$tbarTmp.= 'if(sm.hasSelection()){'.$this->newLine;
				$tbarTmp.= 'var sel = sm.getSelections();'.$this->newLine;
				$tbarTmp.= "Ext.Msg.show({ title:'Remove '+sel.length+ ' record'+( sel.length==1 ? '':'s') ,buttons: Ext.MessageBox.YESNO,msg:'Are you sure?',";
				$tbarTmp.= "fn: function(btn){if(btn == 'yes'){
						var ids = new Array();";
				$tbarTmp.='var x; for(x=0; x<sel.length ;x++){';
				if(isset($this->table) && !$this->removeLocal )
				{
					//{ to keep the number of brackets equal!
					$tbarTmp.="ids.push(sel[x].data.id);} ";
					$tbarTmp.="$this->compName.RMconn.request({ params: {";
					$tbarTmp.="action:'delete',ids: ids.join()  }, ";
					$tbarTmp.='success:function(res,opt){
						var r = Ext.decode(res.responseText);

					'.$this->compName.".getStore().reload();
						if(r.success)
						{
							$success
						}
						else
							Ext.Msg.alert('Error',r.error);
						}";
					$tbarTmp .= ' }); ';
				}
				elseif (isset($this->dataArray) || $this->removeLocal )
				{	//{
					$tbarTmp.= $this->compName.'.getStore().remove(sel[x]);}';
				}
				//}
				$tbarTmp .= '    }} }); } }}'.$this->newLine;

				$this->addtBarItem($tbarTmp);



		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', $sendField_extra='')
	{
		$this->buttonSendSelected = $text;
		$this->buttonSendReqUrl = $file;
		$this->buttonSendField = $sendField;
		$this->buttonSendCallback = $callback;

		if($sendField_extra!="")
			$extra=", ".$sendField_extra;
		else
			$extra='';

		$tbarTmp = $this->newLine.'//ADDING THE SEND SELECTED BUTTON'.$this->newLine;
		$tbarTmp .= "{text: '$this->buttonSendSelected',";
		$tbarTmp.= 'handler:function(){'.$this->newLine;
		$tbarTmp.= 'var sm = '.$this->compName.'.getSelectionModel();';
		$tbarTmp.= 'if(sm.hasSelection()){'.$this->newLine;
		$tbarTmp.= 'var sel = sm.getSelections();'.$this->newLine;

		$tbarTmp.='var fld = [];';
		$tbarTmp.='var x; for(x=0; x<sel.length ;x++){ fld.push(sel[x].data.'.$this->buttonSendField.')}';
		$tbarTmp.="$this->compName.RMconn.request({ url:'$this->buttonSendReqUrl', params: {";
		$tbarTmp.="data: Ext.encode(fld)".$extra." },success:$this->buttonSendCallback }); } } } ".$this->newLine;

		//buttonSendReqUrl
		$this->addtBarItem($tbarTmp);


		return $this;
	}

	function addButtonSendSelected2($text, $obj, $sendField = 'id',$iconCls = null,$warning = null)
	{
		$this->buttonSendSelected = $text;
		$this->buttonSendField = $sendField;

		$tbarTmp.= $this->newLine.'//ADDING THE SEND SELECTED BUTTON'.$this->newLine;
		$tbarTmp.= "{text: '$this->buttonSendSelected',";
		if($iconCls)
			$tbarTmp.= "iconCls:'$iconCls',";
		$tbarTmp.= 'handler:function(){'.$this->newLine;
		$tbarTmp.= 'var sm = '.$this->compName.'.getSelectionModel();';
		$tbarTmp.= 'if(sm.hasSelection()){'.$this->newLine;

		if ($warning) {
				$tbarTmp.= "Ext.Msg.show({ title:'Delete defined layer' ,buttons: Ext.MessageBox.YESNO,msg:'Are you sure?', ";
				$tbarTmp.= "fn: function(btn) { if(btn == 'yes') { ";
		}


	    $tbarTmp.= 'var sel = sm.getSelections();'.$this->newLine;
		$tbarTmp.='var fld = [];';
		$tbarTmp.='var x; for(x=0; x<sel.length ;x++){ fld.push(sel[x].data.'.$this->buttonSendField.') }';
		$tbarTmp.='var obj='.$obj.';';
		$tbarTmp.='obj.params.data=Ext.encode(fld);';
		$tbarTmp.="$this->compName.RMconn.request(obj);  ".$this->newLine;


		if ($warning) $tbarTmp .="  } } }); ".$this->newLine;

		$tbarTmp.= " } } } ".$this->newLine;

		//buttonSendReqUrl
		$this->addtBarItem($tbarTmp);


		return $this;
	}


	/**
	 * Enter description here...
	 *
	 * @param unknown_type $text
	 * @return MakeGrid
	 */
	function addExportButton($text = 'Export',$icon = 'RMicon_export',$exportProperties = array(),$bottom = false, $returnCode = false)
	{
		if(!$text) $text = 'Export';
		if(!$icon) $icon = 'RMicon_export';
		$this->exportButton = $text;


				$tbarTmp = $this->newLine.'//ADDING THE EXPORT BUTTON'.$this->newLine;
				$tbarTmp .= "{text: '$this->exportButton', iconCls: '$icon', ";
				$tbarTmp.="menu:[";
				$tbarTmp.="{text:'Excel',";
				if($this->table)
				{
					//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!!!
					//I do this with encode and decode, so that I copy the options and not the reference
					$handler = "var expParams =  Ext.decode(Ext.encode($this->compName.lastOptions));".$this->newLine;

					}
				else if($this->dataArray)
				{
					$handler = "var data = [];
					Ext.each( $this.getStore().data.items , function(item){ data.push(item.data);   });
					var expParams = { data: Ext.encode( data ), arrayExport : true };
					";
				}

				//setting some defualt for excel properties
				if(!isset($exportProperties['title'])) $exportProperties['title'] = 'Izvoz';
					$handler.= " var cm = $this->compName.getColumnModel();var str='';
					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.props = '".json_encode($exportProperties)."'
	  				expParams.heads = Ext.encode(heads);".$this->newLine;
					$handler.= "expParams.action='export';".$this->newLine;



				$tbarTmp.= 'handler:function(){'.$this->newLine;
				$tbarTmp.= $handler;
				$tbarTmp.="expParams.RMexport = 'excel';";
				$tbarTmp.="	Ext.util.FileOps.downloadFile('$this->reqUrl', 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.= $handler;
				$tbarTmp.= "expParams.RMexport = 'csv';".$this->newLine;
				$tbarTmp.="	Ext.util.FileOps.downloadFile('$this->reqUrl', 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.= $handler;
				$tbarTmp.= "expParams.RMexport = 'xml';".$this->newLine;
				$tbarTmp.="	Ext.util.FileOps.downloadFile('$this->reqUrl', expParams );}}".$this->newLine;


				$tbarTmp.="	]} ".$this->newLine;

				//buttonSendReqUrl
				if($returnCode){
					return $tbarTmp;
				}else{
					if($bottom)
						$this->addBottomBarItem($tbarTmp);
					else
						$this->addtBarItem($tbarTmp);
				}

		return $this;
	}


	public function baseParams($text)
	{
		$this->baseParams = $text;
		return $this;

	}


	function addImportButton($text = 'Import')
	{
		$tbarTmp = "{ text: '$text',iconCls:'icon_import_database',
	menu:[{
			text:'CVS',
			handler: function(){
				CallScript('_plugins/windows.fileUpload.php',{
					idComponent: '$this',
					RMtable: '$this->table',
					database: '$this->database'

				});
			}
		},
		{
		text:'Paste',
		handler: function(){
				var win1 = new Ext.Window({
					modal: true,
					title: 'Paste import',
					layout:'anchor',

					width: 800,
					height:600,
					items: [{
						xtype: 'textarea',
						anchor: '100% 100%',
						ref:'pasteArea',
						id: 'importPasteArea'

				}],
				defaultButton: 'importPasteArea',
				buttons: [{
					text: 'Import',


						handler: function(){
						var cm = $this->compName.getColumnModel();
						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;}
			  					}
							$this.RMconn.request({
								params: {
									action: 'pasteImport',
									pasteData: win1.pasteArea.getValue(),
									cols: cols.join()
								},
								success: function(resp){
									var r = Ext.decode(resp.responseText);
									if(r.success)
									{
										$this.store.reload();
										win1.close();
									}
									else
									{
										Ext.Msg.alert('Error!',r.error);
									}
								}
							});
						}

				}]
				}).show();
				}
		 }] }";
		$this->addtBarItem($tbarTmp);
		return $this;
	}

	/**
	 * 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,$this);
		}
		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,$this);
		}



	}
	/**
	 * Function for adding custom prescripted columns
	 *
	 */
	function addRowAction($dataIndex,$column)
	{
		$actionName = 'rowAction'.$dataIndex.$this->rndID;
		//$this->addConfig($actionName,$column);
		$this->echo = $actionName.' = ' .$column.';';

		$this->columns[$dataIndex] = $actionName;
		$this->plugins[] = $actionName;
	}

	/**
	 * 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
					$spName = 'SpecCol'.$key.$this->rndID;
					$this->columns[$key]->properties['SpecCol'] = $spName;
					$this->columns[$key]->colProperties['type'] = "'bool'";
					$tmp.= 'var '.$spName.' = 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

					//and because this needs to be added as a plug in we set up another flag
					//$this->columns[$key]->properties['specPlugin'] = true;
					$this->plugins[] = $spName;

				break;
				case 'combo':
				case 'checkCombo':
					/*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)
					*/
					$props = &$this->columns[$key]->properties;
					if(isset($props['comboStore']))
					{
						$storeName = $props['comboStore'];
						if($props['comboStoreData'])
						$props['RMspecialStoreData'] = 'options:'. $props['comboStoreData'];
					}
					else
					{
						//we have 2 options: either fetch the data and fill comboStore
						//or create a JsonStore that will make a call for the data
						$storeName = 'SpecStore'.$key.$this->rndID;
						$isjsonStore = $props['mode'] != 'local';
						if($isjsonStore) //in case we want to make a jsonStore
						{
							$tmp .= 'var '.$storeName.' = new Ext.data.JsonStore({';
							$tmp .= 'url:"'.$this->reqUrl.'",';
							$tmp .= 'baseParams:{action:"select",database:"'.( isset($props['comboDatabase']) ? $props['comboDatabase'] : $this->database) .'",';
							$tmp .= 'RMtable:"'.$props['comboTable'].'"';
							if (isset( $props['comboSQL']  ) )
								$tmp .= ',SQL:"'.$props['comboSQL'].'"';
							if (isset( $props['comboWhere']  ) )
								$tmp .= ',SQLwhere:"'.$props['comboWhere'].'"';

							if($props['mode'] == 'autoFill')
							{
								$tmp .= ',autoFill:"'.$props['comboDisplay'].'"';
							}
							$tmp .=	'},root:"rows",';
							$props['RMspecialStoreData'] = 'store:'. $storeName;
							//})
						}
						else
						{
							global $db;
							$db->ChangeDatabase($this->database);
							$tmp .= "var $storeName = new Ext.data.ArrayStore({
								data:[";
							if (isset( $props['comboSQL']  ) )
								$cbRes = $db->SQLexecute($props['comboSQL']);
							else
							{
								$sql = "SELECT * FROM ".( isset($props['comboDatabase']) ? $props['comboDatabase'] : $this->database).'.'.$props['comboTable'];
								$cbRes = $db->SQLexecute($sql);
							}
							$data = array();
								while ($cbRow = $db->fetchAssoc($cbRes))
								{
									$dataRow = '"'. $cbRow[ $props['comboValue'] ].'"';
									$dataRow .= ',"'. $cbRow[ $props['comboDisplay'] ].'"';
									if(isset( $props['comboRender']))
										$dataRow .= ',"'. $cbRow[ $props['comboRender'] ].'"';

									$data[] = '['.$dataRow.']';
								}
							 //we save the data in case we want to make a listfilter!
							 $dataStr =  implode(',',$data) .']';
							 $props['RMspecialStoreData'] = 'options: ['.$dataStr ;
							$tmp .= $dataStr;
							$tmp .= ",";
							//)};
						}
						//({
						$tmp .= 'fields:["'.$props['comboValue'].'","'.$props['comboDisplay'].'"';
						if(isset( $props['comboRender']))
							$tmp .= ',"'.$props['comboRender'].'"';
						$tmp .= ']});';
					if($isjsonStore)
						$tmp .= $storeName.'.load();'.$this->newLine;
					}
					//2. Create the comboBox form...value field and display field should be passed!
					$comboFld = $spType == 'combo' ? 'Ext.form.ComboBox' : 'Ext.ux.form.LovCombo';
					$tmp.= 'var SpecCol'.$key.$this->rndID.' = new '.$comboFld.'({';
					$tmp.= "store:$storeName,";
					$tmp.= 'displayField:"'.$props['comboDisplay'].'",valueField:"'.$props['comboValue'].'",';
					if(isset($props['comboProperties']))
					{
						$tmp .= $props['comboProperties'];
					}
					else
					{
						$tmp .= 'triggerAction:"all"';
					}
					if(isset($props['comboListeners']))
					{
						$tmp.= ",listeners:{".$props['comboListeners']." }";
					}
					if($isjsonStore)
					{
						$tmp.= ",mode:'remote',listeners:{ beforequery:function(qe){ delete qe.combo.lastQuery;} }";
					}
					else
					{
						$tmp .= ',mode:"local"';
					}
					$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;
	}
	private function createStoreModel()
	{
		$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) {
			if(!is_a($col,'MakeColumn'))
			{
				continue;
			}
			//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 saved in the specialTypes array, so we can handle them later
				switch ($field['type']) {
					case 'date':
					$strField .= ',dateFormat:"'.$this->dateSQL.'" ';
					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';
						//WARNING...field type from combo is not always int! make a special setting to make it int if neccesery!
						//$field['type'] = 'int';

						break;
					case 'checkCombo':
						$this->specialTypes[$field['dataIndex'] ] = 'checkCombo';
						$field['type'] = 'string';

						break;
					default:
						;
					break;

				}
				$strField .= ',type: "'.$field['type'].'"';
			}

			$fields[] = $strField.'}';
		}

		$tmp .= '['.implode(',',$fields).']);'.$this->newLine;

		return $tmp;
	}

	private function createFiltering()
	{
			$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 )
			{
				if(!is_a($col,'MakeColumn'))
				{
					continue;
				}
				$property = $col->properties;
				$filtTmp ='{dataIndex: "'.$property['dataIndex'].'",RMtable: "'.$property['tableAs'].'",' ;
				if($property['convertNull'])
					$filtTmp .= 'convertNull: true,';
				if(isset($property['type']))
				{
					switch ($property['type']) {
						case 'combo':
							$filtTmp.='type:"list",'.$property['RMspecialStoreData'].',
							phpMode:true';
							if($property['mode'] == 'remote')
								$filtTmp .= ',idField:"'.$property['comboValue'].'"';
							$filtTmp .= ', labelField:"'.$property['comboDisplay'].'"' ;
						break;
						case 'bool':
							$filtTmp .= 'type:"boolean"';
							break;
						case 'int':
							$filtTmp .= 'type:"numeric"';
							break;
						case 'checkColumn':
						case 'checkCombo':
							$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;

			$this->plugins[] = 'filters'.$this->rndID;
			$this->addConfig('gridFilter','filters'.$this->rndID);

			return $tmp;
	}

	private function createDataReader()
	{
		$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 ))
		{
					//all grids should have remote sort...don't they ???
					$this->setRemoteSort();
					$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
					$this->readerSpecific = "url:'$this->reqUrl',".$this->newLine;
					$this->readerSpecific .= 'remoteGroup:true,';
					$this->readerSpecific.= $this->newLine.'//ADDING BASE PARAMS TO STORE'.$this->newLine;
					$this->readerSpecific.= 'baseParams: {database:\''.$this->database.'\', action : \'select\',RMcomp:\'grid\',RMtable : \''.$this->table.'\'  '.$this->newLine;
					if($this->selectSQL)
					{
						$this->readerSpecific.=', SQL : "'.$this->selectSQL.'" ';
					}
					if($this->paging)
					{
						$this->readerSpecific.=', start: 0,limit : '.$this->pagingLimit;
					}
					if($this->baseParams)
					{
						$this->readerSpecific.= ','.$this->baseParams;
					}
					$this->readerSpecific.='},';



		}
		elseif (isset( $this->dataArray))
		{
			$tmp .= "var myData$this->rndID = ".$this->dataArray.';'.$this->newLine;


			$tmp .= 'var Reader'.$this->rndID.' = new Ext.data.ArrayReader({},';

			$this->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;

		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->createStoreModel();

		//lets create ALL the special columns variables our application will use.
		$tmp .= $this->createSpecialColumnData();

		//create the filters!!!
		if($this->filtering)
		{

			$tmp .= $this->createFiltering();
		//	$tmp .= '*/';
		}

		$tmp .= $this->createDataReader();

		$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.= $this->readerSpecific;
		$tmp.="listeners:{exception : function(m,b,j,k,resp){
		var r  = Ext.decode( resp.responseText);
		if(r.error == 'sessionTimeout')
		{
			CallScript( '_forms/window.sessionTimeout.php',{});
		}
		else
			alert('Grid error: '+  r.error  );
	}";
		if(isset($this->exportButton ) && $this->table )
		{
			//if the export button is set, we set up a listener the load function, so that we can store all send parameters
			$tmp.= ',load : function(a,b,o){'.$this->compName.'.lastOptions = o.params; }';
		}
		$tmp.= '},';

		$tmp.='reader: Reader'.$this->rndID.$this->newLine;
		foreach ($this->storeConfigs as $stConfig) {
			$tmp.= ','.$stConfig;
		}


		$tmp.='});'.$this->newLine;
		//differend readers requere differnt load command...
		$tmp.= $this->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 = '{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':
						if(!isset($property['renderer'] ))
							$col.= ',renderer: Ext.util.Format.dateRenderer("'.$this->dateDisplay.'")';
						break;
						case 'combo':
							$col.=',editor: SpecCol'.$property['dataIndex'].$this->rndID;
							if(!isset($property['renderer']) && $property['useComboRenderer'])
							$col.=',renderer:comboToRenderer(SpecCol'.$property['dataIndex'].$this->rndID.')';
						break;
						case 'checkCombo':
							$col.=',editor: 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.'" ';
				}
				if( $this->sortable )
				{
					$col.=',sortable:true';
				}
				//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 .= '}'.$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()
	{
		//let's check if 'id' was inserted becouse it is neccesery!
		if($this->table && ! isset($this->columns['id']))
			$this->addColumn('id');
		//borut hoce da majo vsi gridi export...let him have that :)
	//	if(!$this->exportButton)
	//		$this->addExportButton();


		$tmp = $this->echo;
		if($this->autoCreateStore)
		{
			$tmp .= $this->createStore();
		}
		if(!isset($this->sortable))
		{
			$this->sortable = true;
		}
		$this->configRMconn('grid');

		//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."')";
			if($this->expanderConfig)
			{
				$tmp.= ','.$this->expanderConfig;
			}

			$tmp.= "});".$this->newLine;
			$this->firstEditableColumn++;

			$col = 'expander'.$this->rndID;
			$columns[] = $col;
			$this->plugins[] = $col;
		}

        //add summery group

        if($this->groupSummaryEnable)
        {
            $tmp .= $this->newLine . '//CREATE GROUP SUMMERY' . $this->newLine;
            $tmp .= 'var summery' . $this->rndID . ' = new Ext.ux.grid.GroupSummary();';

            $plugin = "summery" . $this->rndID;
            $this->plugins[] = $plugin;
         }

		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->cellActionListeners))
		{
			$ca = "new Ext.ux.grid.CellActions({listeners:{
                action:function(grid, record, action, value,dataIndex,row,col) {
                	";
               foreach ($this->cellActionListeners as $dataI => $list) {
               	foreach ($list as $ac => $listener) {
               		$ca .= "if(dataIndex ==  '$dataI' && action == '$ac'){ $listener; }".$this->newLine;
               	}
               }
             $ca.=      " }} })";

			$this->plugins[] = $ca;
		}

		if(isset($this->searchField))
		{
			//ce prav razumem primer, to pokne sam v plugin
			{
				$this->plugins[] = "new Ext.ux.grid.Search({searchText:'$this->searchField',  minChars:$this->searchMinChars,position:'$this->searchFieldPos',paramNames:{fields:'srcfields', query:'srcquery'},disableIndexes:$this->searchDisableIndexes,indexPos:$this->searchIndexPos , ref: 'searchField'})";
			}
		}
		if(isset($this->searchFieldTwo))
		{
			//ce prav razumem primer, to pokne sam v plugin
			{
				$this->plugins[] = "new Ext.ux.grid.Search({width:300,searchText:'Find',  minChars:'0',position:'".($this->searchFieldPos+1)."',paramNames:{fields:'srcfields2', query:'srcquery2'},disableIndexes:$this->searchDisableIndexes })";
			}
		}

		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;
			$this->plugins[] = 'rowActions'.$this->rndID;
			$this->plugins[] = 'testRecordForm';
			$tmp.='testRecordForm.afterUpdateRecord = function(rec){}';

		}
		//arrow keys plugin...move editor on grid with arrow keys
		//maybe later put some conditions on this plugin
		if(true)
		{
			$this->addConfig('useCtrl','true');
			$this->plugins[] = "new Ext.ux.grid.ArrowKeys()";
		}

		if($this->dateSQL)
			$this->addConfig('dateSQL',"'$this->dateSQL'");



		$tmp.= $this->newLine.'//CREATE THE GRID ITSELF!!!'.$this->newLine;
		$tmp .= 'var '.$this->compName.' = new Ext.grid.EditorGridPanel({'.$this->newLine;
		//create a spceial custom function to get all selected IDs!
		$tmp .= "getSelectedIds :function(field ){
				if(!field) field = 'id';
				var arr=new Array(),sel = this.selModel.getSelections();

				 for(x=0; x<sel.length ;x++){
				    arr.push( sel[x].data[field] );}
				  return arr;
		}, ";
		//$tmp .= 'renderTo:"'.$this->table.'Div" ,'.$this->newLine;
		$tmp .= 'store: Store'.$this->rndID.$this->newLine;
	//	$tmp .= ',closable: true';
	//	$tmp .= 'lastOptions : {a:"lala"},';
		$tmp .= ',id: "'.$this->compName.'"'.$this->newLine;
		if(isset($this->title))
		{
		//	$tmp .= 'title: "'.$this->title.'",'.$this->newLine;
		}


		$tmp .= ',columns: ['.$this->newLine;

		if($this->filtering)
		{

		}

		//$plugins[]='expander';
		$tmp.= $this->newLine.'//DEFINING THE COLUMNS FOR THE GRID'.$this->newLine;
		foreach ($this->columns as $field )
		{
			if(!is_a($field,'MakeColumn'))
			{

				$columns[] = $field;
				continue;
			}
			$property = $field->properties;

			if( isset($property['header'] ) )
			{
				//if the column has a specific setting like CheckColumn or a special combobox!
				if( $property['SpecCol'] )
				{
					$col = $property['SpecCol'];
					$columns[] = $col;
				/*	if($property['specPlugin'])
						$this->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;
			}
			else
			{
				//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'];
				}
			}
		}
		$tmp .= implode(',',$columns);
		//testno checkColumn
		$tmp .= ']'.$this->newLine;

	//	$tmp .= 'autoHeight:true,'.$this->newLine;



	if(isset($this->plugins) )
		{
			$tmp.=',plugins :['.implode(',',$this->plugins).']';
		}


		$tmp .= ',clicksToEdit:2,loadMask:true'.$this->newLine;

		if($this->addTBar  ||$this->searchFieldPos == 'top')
		{
			$tmp .= ',tbar:[';
			$tbar = array();

			foreach ($this->tBarItems as $barItem) {
				if(is_string($barItem))
				{
					$tbar[] = $barItem;
				}
				elseif (isset($barItem['function']))
				{
					$tbar[] =  eval('return '.$barItem['function']);
				}
			}
			$tmp .= implode(',',$tbar);
			unset($tbar);

			$tmp .= ']';
		}
		//we add paging
		if($this->paging)
		{
			if($this->paging === 'auto')
			{
				$this->listeners[] ="bodyresize: function(panel, width, height) {
				var contentHeight = ".
				($this->groupCol ?  "height-150;" : "height - 24; "  )
				."var rowHeight = 22;
				var maxRowsPerGrid = Math.round(contentHeight/rowHeight);
				if(maxRowsPerGrid <= 0) maxRowsPerGrid = 1;
				var tmp_bbar = $this->compName.getBottomToolbar();
				if( tmp_bbar.pageSize !=  maxRowsPerGrid )
				{
					tmp_bbar.pageSize = maxRowsPerGrid;
					tmp_bbar.doLoad(tmp_bbar.cursor);
				}
					}";
			}

			$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}"';
			if($this->addBBar)
				$tmp .= ",items: [ ".implode(',',$this->bBarItems) ."]";

			$tmp .= '})';
		}
		elseif ($this->searchFieldPos == 'bottom')
		{
			$tmp.=',bbar:[]';
		}
		//we add listeners
	//	$tmp .= ',listeners: {'.$this->newLine;
		$tmp.= $this->newLine.'//ADDING THE AFTER EDIT LISTENER'.$this->newLine;
		if($this->editable)
		{
			$aetmp .= 'afteredit : function(e) {';
			if(isset($this->table))
			{
				if($this->ignoreUpdate)
				{
					//the user can specify a condidion on which the update won't commit!
					//he can use the e in his statemetn e.g e.field == 'noUpdateFld'
					$aetmp .= "if ( $this->ignoreUpdate ) { return; } ";
				}
				$aetmp .= 'this.RMconn.request({';
				$aetmp .=	"url:'$this->reqUrl',params: {";
				$aetmp .= "action: 'update',RMcomp:'grid', id: e.record.get( e.grid.getColumnModel().config[e.column].idField ),
				idField : e.grid.getColumnModel().config[e.column].idField ,
				field: e.field ,
				value : Ext.isDate(e.value) ? Ext.util.Format.date(e.value, '$this->dateSQL') : e.value ,
				'RMtable': e.grid.getColumnModel().config[e.column].RMtable,
				database:'$this->database'";

				if ($this->ExtraAfterEditParameters) $aetmp .= ", ".implode(",",$this->ExtraAfterEditParameters);

				$aetmp .= "}";



				if(isset($this->afterEditSucces ))
					$aetmp .= ",success : $this->afterEditSucces";
				else
					$aetmp .= ",success : function(resp,opt){var r = Ext.decode(resp.responseText); if(r.success)
					{
						 e.record.commit();
						 var colTmp = e.grid.getColumnModel().config[e.column];
						  if(colTmp.reload){ Store".$this->rndID.".reload();}
						  //a custom column function to execute after this column has been edited
						  if(colTmp.aftereditHandler){ colTmp.aftereditHandler(e);}
			} else
			 {e.record.reject(); if(r.error) Ext.Msg.alert('Error',r.error);  }}";
				if(isset($this->afterEditFailure ))
					$aetmp .= ",failure: $this->afterEditFailure";
				else
					$aetmp .= ",failure: function(){e.record.reject();}});";
			}
			elseif (isset($this->dataArray))
			{
				$aetmp .= 'e.record.commit();';
			}
			$aetmp .= " }".$this->newLine;
			$this->listeners[] = $aetmp;
		}

	//	$tmp .= '},';

		if ($this->checkBoxSelection )
		{
			$tmp.= ',sm : checkBoxsm'.$this->rndID.'';

		}
		else
		{
			$tmp .= ',sm: new Ext.grid.RowSelectionModel({singleSelect : true}) ';
		}
		$tmp.= $this->createConfigs();

		$tmp .= '});'.$this->newLine;
	//we set the specific load for the reader
					//if loading is done on resizing (paging == auto, we don't need to manually load the store!!!)
		if(isset($this->table) && $this->autoLoad && !($this->paging === 'auto') )
		{
			//$this->loadSpecific = 'Store'.$this->rndID.'.load()'.$this->newLine;
			$tmp .= "$this.on('render', function(cmp){cmp.getStore().reload(); });";
		}


		return $tmp;
	}


}
?>
