*              www.linkedin.com/profile/view?id=206267783
 *		https://github.com/Akshay-Hegde
 *
 * @version    	1.0.2 ( update callback fix (28-07-2015 13:17:00), function_renamed (11-08-2015 10:24:00 ) )
 * @copyright  	Copyright (c) 2010 through 2014, John Skoumbourdis
 * @license    	https://github.com/scoumbourdis/grocery-crud/blob/master/license-grocery-crud.txt
 *
 * Thanks
 * John Skoumbourdis, Amit Shah & Victor
 */
class Grocery_CRUD_Multiuploader extends grocery_CRUD
{
	protected $callback_read_field	= array();
	
	protected $multi_upload_function ;  
	/* multiupload css directory */ 
	protected $multiupload_css_path        = 'assets/grocery_crud_multiuploader/styles/';
	/* multiupload js directory */ 
	protected $multiupload_javascript_path = 'assets/grocery_crud_multiuploader/scripts/';
	/* Default upload directory */ 
	protected $path_to_directory           = 'assets/grocery_crud_multiuploader/GC_uploads';
	/* No file text on list/read state */ 
	protected $no_file_text                = '
Empty
';
	
	/* Anchor text */ 
	protected $enable_full_path            = true;
	
	/* download button on read state */ 
	protected $enable_download_button      = true;
	/* download button filetypes read state */ 
	protected $download_allowed            = null;
	/* Table where files saved */
	protected $file_table;
	/* Primary Key of table */
	protected $primary_key;
	/* upload Field */
	protected $upload_field;
	/* Allowed file types */
	protected $allowed_types      = 'gif|jpeg|jpg|png|pdf|doc';
	/* Show allowed types - edit state */
	protected $show_allowed_types = true;	
	/* Upload options */
	protected $hash_fields = array(
					"upload_field",
					"allowed_types",
					"show_allowed_types",
					"path_to_directory",
					"no_file_text",
					"enable_full_path",
					"enable_download_button",
					"download_allowed"
				      );
	/* Temp storage */
	protected $hash = array();
	public $basic_model,$ci;
	
	
	/*
	 * Constructor - Initializes and references CI
	*/
	public function __construct()
	{
		parent::__construct();
		$this->ci = &get_instance();
		$this->ci->load->model('grocery_CRUD_Model');
		$this->basic_model = new grocery_CRUD_Model();
		log_message('debug', "Grocery_CRUD_Multiuploader Class Initialized.");
	}
	
	/*
	/* Callback read field
	/* Thanks Amit shah for hint...
	*/
	public function callback_read_field($field, $callback = null)
	{
		$this->callback_read_field[$field] = $callback;
		return $this;
	}
	
	/*
	*  Nothing much changed added field info 
	*/
	protected function change_list($list,$types)
	{
		$primary_key    = $this->get_primary_key();
		$has_callbacks  = !empty($this->callback_column);
		$output_columns = $this->get_columns();
		foreach($list as $num_row => $row)
		{
			foreach($output_columns as $column)
			{
				$field_name 	= $column->field_name;
				$field_value 	= isset( $row->{"$column->field_name"} ) ? $row->{"$column->field_name"} : null;
				if( $has_callbacks && isset($this->callback_column[$field_name]) )
					$list[$num_row]->$field_name = call_user_func($this->callback_column[$field_name], $field_value, $row,$this->get_field_types()[$column->field_name]);
				elseif(isset($types[$field_name]))
					$list[$num_row]->$field_name = $this->change_list_value($types[$field_name] , $field_value);
				else
					$list[$num_row]->$field_name = $field_value;
			}
		}
		return $list;
	}
	
	/*
	 * _is_image
	 *
	 * @access	public
	 * @param	string
	 * @return      boolean
	 */
	function _is_image($name)
	{
		$imgs = array('.jpg','.png','.jpeg','.gif','.tiff');
		$inp  = array(substr($name, -4),substr($name, -5));		
		return count(array_intersect($imgs, $inp)) > 0;
	}
	
	/*
	 * _reset - used for multiple upload field...
	 * 
	 * @access	public
	 * @param	string
	 * @return      void
	 */
	function _reset($field)
	{	
		foreach($this->hash_fields as $f){
			$this->{"$f"} = $this->hash[$field][$f];
		}
	}
	/*
	 * remote_file_exists 
	 * 
	 * @access	public
	 * @param	string
	 * @return      boolean
	 */
	function remote_file_exists($url)
	{
	  	return(bool)preg_match( '~HTTP/1\.\d\s+200\s+OK~', @current(get_headers($url)) );
	}
	/*
	 * segment_check 
	 * 
	 * @access	public
	 * @param	string
	 * @param	string
	 * @return      void
	 */
	function segment_check($fun, $field)
	{
	   if($this->ci->input->post("field") && $this->ci->input->post("field") === $field)
	   {
		$this->_reset($field);
		$seg = $this->ci->uri->segments;
		if(!empty($seg))	
		{
			if(
				$seg[count($seg)-1] === $fun && 
				in_array($seg[count($seg)],array('uploade','delete_file'))
		  	  )
			  {
				switch ($seg[count($seg)])
				{
					case 'uploade':
						$this->multiupload_file();
						break;
					case 'delete_file':
						$this->delete_multi_file();
						break;
					default:
						break;
				}
	
				die();
			  }
		}
	   }
	}
	
	/*
	 * Callback override fix for callback_before_(insert|update|delete)
	 * 
	 * @access	protected
	 * @return      void
	 */
	protected function pre_render()
	{
		$this->_initialize_variables();
		$this->_initialize_helpers();
		$this->_load_language();
		$this->state_code = $this->getStateCode();
		if($this->basic_model === null)
			$this->set_default_Model();
		$this->set_basic_db_table($this->get_table());
		$this->_load_date_format();
		$this->_set_primary_keys_to_model();
		switch($this->state_code)
		{
			case 4 : // before delete
				 $this->_delete_this_key($this->get_state_info_from_url()->first_parameter);
				 break;
			case 5 : // before insert
				 $_POST = $this->_set_files($_POST);
				 break;
			case 6 : 
				 // before update
				 $_POST = $this->_set_files($_POST,$this->get_state_info_from_url()->first_parameter);
				 break;
		}
	}
	
	/*
	 * set_callbacks 
	 * 
	 * @access	protected
	 * @param	string
	 * @return      void
	 */
	protected function set_callbacks($file_field)
	{
		/* Callback on list state */
		$this->callback_column($file_field,array($this,'_file_url'));
	
		/* Callback on add state */
		$this->callback_add_field($file_field,array($this, 'add_upload_field'));
		
		/* Callback on edit state */
		$this->callback_edit_field($file_field,array($this, 'edit_upload_fied'));
		
		/* Callback on read state */
		// GC < 1.5 we have some issue...	
		$version = explode(".",grocery_CRUD::VERSION);	
		switch($version[1])
		{
		   case   5:
			    $this->callback_read_field($file_field, array($this,'view_upload_field'));
			    break;
		   default : 
			   if($this->getState() == "read")
			   {
				$this->callback_field($file_field, array($this,'view_upload_field'));
			   }else
			   {
				$this->callback_read_field($file_field, array($this,'view_upload_field'));
			   }
		}
	
	}
	/*
	 * new_multi_upload
	 *
	 * @access	public
	 * @param	upload-field
	 * @param	obj/array
	 * @return	void
	 */
	public function new_multi_upload($field=null, $obj=null)
	{
		/* Whether field is null */
		if(is_null($field))
		{
			throw new Exception("field is mandotory");
			die();         
		}
		$this->file_table   = $this->basic_db_table;
		$this->primary_key  = $this->primary_key = $this->basic_model->get_primary_key($this->file_table);
		$this->multi_upload_function = __FUNCTION__;
		$this->upload_field = $field;
		/* Whether field exists in table ? */
		if(!$this->basic_model->field_exists($this->upload_field,$this->file_table))
		{
			throw new Exception("field : ".$this->upload_field." Not Found in table ".$this->file_table);
			die(); 
		}
		/* Override default configuration */
		if (!is_null($obj) && is_array($obj) && !empty($obj) )
		{
             	  foreach ($obj as $k => $v)
		  {
                	if (property_exists($this,$k)) 
			{
				$this->{"$k"} = $v;
                	}else
			{
				log_message('debug', "$k doesn't exists in Grocery_CRUD_Multiuploader.");
			}
             	  }
         	}
		
		/* Upload directory exists ? */		
		if(!file_exists($this->path_to_directory))
		{
			throw new Exception("Directory does not exist : ".$this->path_to_directory);
			die(); 
		}		
		/* Upload directory has write permission ? */	
		if(!is_writable($this->path_to_directory))
		{
			throw new Exception("Not writable : ".$this->path_to_directory."\n Current Permission : ".substr(sprintf('%o', fileperms($this->path_to_directory)), -4));
			die(); 	
		}
		
		/* temp storage */
		foreach($this->hash_fields as $f){
			$this->hash[$field][$f] = $this->{"$f"};
		}
		/* Check whether req is to upload file / delete file */
		$this->segment_check(__FUNCTION__,$field);
		/* Initialize Callbacks */
		$this->set_callbacks($field);
		/* Set Scripts */
		$this->set_scripts();
	}
	
	
	/*
	 * set_scripts
	 * 
	 * @access	protected
	 * @return      void
	 */
	protected function set_scripts()
	{ 
	  $css = array(
			'assets/grocery_crud/css/ui/simple/' . grocery_CRUD::JQUERY_UI_CSS,
			'assets/grocery_crud/css/jquery_plugins/file_upload/file-uploader.css',
			'assets/grocery_crud/css/jquery_plugins/file_upload/jquery.fileupload-ui.css',
			'assets/grocery_crud/css/jquery_plugins/fancybox/jquery.fancybox.css',
			$this->multiupload_css_path.'multi_uploader.css',
		      );
	  $js  = array(
			'assets/grocery_crud/js/' . grocery_CRUD::JQUERY,
			'assets/grocery_crud/js/jquery_plugins/ui/' . grocery_CRUD::JQUERY_UI_JS,
			'assets/grocery_crud/js/jquery_plugins/tmpl.min.js',
			'assets/grocery_crud/js/jquery_plugins/load-image.min.js',
			'assets/grocery_crud/js/jquery_plugins/jquery.iframe-transport.js',
			'assets/grocery_crud/js/jquery_plugins/jquery.fileupload.js',
			'assets/grocery_crud/js/jquery_plugins/config/jquery.fileupload.config.js',
			'assets/grocery_crud/js/jquery_plugins/jquery.fancybox.pack.js',
			'assets/grocery_crud/js/jquery_plugins/jquery.easing-1.3.pack.js',
			'assets/grocery_crud/js/jquery_plugins/config/jquery.fancybox.config.js',
			$this->multiupload_javascript_path.'jquery.mousewheel.js',
		      );
	   foreach($css as $c){
		$this->set_css($c);
	   }
	   foreach($js as $c){
		$this->set_js($c);
	   }
	}
	
	/*
	 * add_upload_field callback
	 * 
	 * @access	public
	 * @return      string
	 */
	function add_upload_field()
	{
		$args = func_get_args();
		$name = $args[2]->name;
		$this->_reset( $name );
	        $html = '
			
				Upload a file
				
			
                       '.( $this->show_allowed_types ? ''.str_replace('|',',',$this->allowed_types).'' : null ) .'
                        
			
		
		
		
		
';
		$html.=$this->JS( $name  );
		return $html;
	}
	function edit_upload_fied($value, $primary_key)
	{
		$args = func_get_args();
		$name = $args[2]->name;
		$this->_reset( $name );
		$result = $this->ci->db->get_where($this->file_table,array($this->primary_key => $primary_key));
		$result = $result->result_array();
				
		if(!empty($result))
		{
			$files = unserialize($result[0][$this->upload_field]);
		}else
		{
			$files = array();
		}
		
		$html = '
			 
			 Upload a file
			 
			 
                         '.( $this->show_allowed_types ? ''.str_replace('|',',',$this->allowed_types).'' : null ) .'
			 
			 
			
';
		$html.= '';
		$html.='';
		if (!empty($files))
		{
			foreach ($files as $items)
			{
			   $thisfile = base_url() . $this->path_to_directory . $items ;
			   if($this->remote_file_exists($thisfile))
			   {			
				if( strpos ($items,"." ) !== false )
				{
				if ($this->_is_image($items) === true)
				{
					$html.= '
';
				}
				else
				{
					$html.='
';
				}
				}
			    }
			}
		}
		$html.='