<?php


Class Filter {


var $args;
var $args_default;
var $filters;
var $labels;
var $callbacks;
var $_key;
var $_storage;// enum('session', 'cookie')
var $_trash_filtr;// Tree trash


/**
 * @param $args - args table: $_GET, $_POST, $_REQUEST, etc
 * @param $key - kay to store values in @storage, if not set then args not saved
 * @param $storage - where to store state - cookie or session, default is cookie
 */
function __construct( $args, $key = null, $storage = 'cookie' ) {
	$this->args = $args;
	$this->args_default = array();
	$this->filters = array();
	$this->labels = array();
	$this->callbacks = array();
	$this->_key = 'filter-'.$key;
	$this->_storage = $storage;
	$this->_init_args();
	$this->_trash_filtr = null;
}


function get_arg( $name ) {
	// try load from @storage and save
	if (array_key_exists($name, $this->args)) {
		return $this->args[ $name ];
	} else if (array_key_exists($name, $this->args_default)) {
		return $this->args_default[ $name ];
	}
	return null;
}


function _init_args() {
	if (array_key_exists('filtr_clear', $this->args) && $this->args['filtr_clear'] == 1) {
		$this->args = array();
	} else {
		$this->_read_args();
	}
}


function add_filter( $name, $values, $default, $label = '', $callback = null ) {
	$this->filters[ $name ] = $values;
	$this->labels[ $name ] = ($label)? $label : $name;
	$this->args_default[ $name ] = $default;
	if ($callback) $this->callbacks[ $name ] = $callback;
}


function _save_args() {
	if (!$this->_key) { return; }
	if ($this->_storage == 'cookie') {
		$this->_save_args_in_cookie();
	} else {
		$this->_save_args_in_session();
	}
}


function _save_args_in_session() {
	if (!$this->_key) { return; }

	$save_args = array();
	foreach ($this->filters as $name => $options) {
		$arg = (isset($this->args[$name]))? $this->args[$name] : '';
		if (count($options) == 1 && reset($options) == 'search') {
			if ($arg != $this->args_default[$name]) {
				$option = $arg;
				$save_args []= ''.urlencode($name).'='.urlencode($option);
			}
		} else {
			foreach($options as $option => $field_name) {
				if (isset($this->args[$name]) && $this->args[$name] == $option) {
					$save_args []= ''.urlencode($name).'='.urlencode($option);
				}
			}
		}
	}

	$save_args = implode(',', $save_args);
	$_SESSION[ $this->_key ] = $save_args;
}


function _save_args_in_cookie() {
	if (!$this->_key) { return; }

	$save_args = array();
	foreach ($this->filters as $name => $options) {
		$arg = (isset($this->args[$name]))? $this->args[$name] : '';
		if (count($options) == 1 && reset($options) == 'search') {
			if ($arg != $this->args_default[$name]) {
				$option = $arg;
				$save_args []= ''.urlencode($name).'='.urlencode($option);
			}
		} else {
			foreach($options as $option => $field_name) {
				if (isset($this->args[$name]) && $this->args[$name] == $option) {
					$save_args []= ''.urlencode($name).'='.urlencode($option);
				}
			}
		}
	}
//	if ($save_args) {
		$save_args = implode(',', $save_args);
		echo'<script type="text/javascript">';echo"
			(function(){
				var exdate=new Date()
					, exdays = 14
					, c_name='".$this->_key."'
					, value='".$save_args."'
				;
				exdate.setDate(exdate.getDate() + exdays);
				var c_value=escape(value) + ((exdays==null) ? '' : '; expires='+exdate.toUTCString());
				document.cookie=c_name + '=' + c_value;
			})();
		";echo'</script>';
//	}
}


function _read_args($force = false) {
	if (!$this->_key) { return; }
	if ($this->_storage == 'cookie') {
		$this->_read_args_from_cookie($force);
	} else {
		$this->_read_args_from_session($force);
	}
}


function _read_args_from_session($force = false) {
	if (!$this->_key) { return; }
	if (!array_key_exists($this->_key, $_SESSION)) { return; }
	$c_args = explode(',', $_SESSION[$this->_key]);
//echo'<p>read from session c_args: '.$_SESSION[$this->_key].'</p>';
	foreach ($c_args as $c_val) {
		$c_val = explode('=', $c_val);
		if (count($c_val) != 2) continue;
		$name = urldecode($c_val[0]);
		$option = urldecode($c_val[1]);
		if ($force || !array_key_exists($name, $this->args)) {
//echo'<p>read from session: '.$name.' / '.$this->args[ $name ].' / set '.$option.'</p>';
			$this->args[ $name ] = $option;
		}
	}//end foreach
}


/**
 * Read args from cookie.
 */
function _read_args_from_cookie($force = false) {
	if (!$this->_key) { return; }
	if (!array_key_exists($this->_key, $_COOKIE)) { return; }
	$c_args = explode(',', $_COOKIE[$this->_key]);
	foreach ($c_args as $c_val) {
		$c_val = explode('=', $c_val);
		if (count($c_val) != 2) continue;
		$name = urldecode($c_val[0]);
		$option = urldecode($c_val[1]);
		if ($force || !array_key_exists($name, $this->args)) {
			$this->args[ $name ] = $option;
		}
	}//end foreach
}


/**
 * Print form fields. Must be inside <form> tag.
 */
function show_filters() {
	// read args from cookie if exists
	$selected_defaults = true;

	// bug fix in browser, run onclick action on first submit/image/button element in html code
	echo'<nobr style="float:right;margin:-9999px 0 0 -9999px;">';
		echo'<input type="submit" value="'."submit".'" />';
	echo'</nobr>';

	// show trash if exists
	echo $this->show_trash();

	// show filters
	foreach ($this->filters as $name => $options) {
		$out = new stdClass();
		$out->cls = '';// class
		$out->cnt = '';// content

		$selected_option = (isset($this->args[$name]))? $this->args[$name] : $this->args_default[$name];
		if (count($options) == 1 && reset($options) == 'search') {
			$size = strlen($selected_option); $size = ($size < 4)? 4 : $size + 2;// size min 4
			$out->cnt .= '<input type="text" name="'.$name.'" value="'.$selected_option.'" class="i" size="'.$size.'" />';
			if ($selected_option != $this->args_default[$name]) {
				$selected_defaults = false;
				$out->cls = 'active';
				//echo' <input type="submit" value="'."x".'" onclick="'."this.form.".$name.".value='';".'" title="'."Usuń".'" />';
				// po kliknięciu ENTER w polu wymuszało usuwanie zawartości pola - 1st submit btn in form
				$out->cnt .= '<input type="button" value="'."x".'" onclick="'."this.form.".$name.".value='';this.form.submit();".'" title="'."Usuń".'" />';
			}
			//$out->cnt .= '<input type="submit" value="'."Szukaj".'" />';
			$out->cnt .= '<input type="image" src="' . "icon/search.png" . '" ale="'."Szukaj".'" title="'."Szukaj".'" />';
		}
		else if (count($options) == 2) {// 2 opcje do wyboru to button
			$selected_button = $selected_option;
			if (!array_key_exists($selected_button, $options)) {
				$selected_button = $this->args_default[$name];
			}
			if ($selected_button != $this->args_default[$name]) {
				$selected_defaults = false;
				$out->cls = 'active';
			}
			foreach ($options as $option => $val) {
				if ($selected_button != $option) {
					$out->cnt .= '<input type="submit" name="'.$name.'" value="'.$option.'" />';
				}
			}
		}
		else {// ponad 2 opcje to select
			$out->cnt .= '<select name="'.$name.'" onchange="this.form.submit();">';
			if ($selected_option != $this->args_default[$name]) {
				$selected_defaults = false;
				$out->cls = 'active';
			}
			foreach ($options as $option => $field_name) {
				$sel = ($selected_option == $option)? 'selected' : '';
				$out->cnt .= '<option value="'.$option.'" '.$sel.'>'.$option.'</option>';
			}
			$out->cnt .= '</select>';
		}

		echo' <nobr'.(($out->cls)? ' class="'.$out->cls.'"' : '').'>';
			echo $this->labels[$name];
			echo $out->cnt;
		echo'</nobr>';
		echo $this->separator();
		unset($out);
	}

	if (!$selected_defaults) {
		echo'<nobr>';
		echo'<input type="hidden" name="filtr_clear" value="0" />';
		echo' <input type="button" value="'."Wyczyść filtr".'" onclick="this.form.filtr_clear.value=1;this.form.submit()" /> ';
		echo'</nobr>';
	}
	$this->_save_args();
}


function set_trash( $filtr_key = '', $value = 0 ) {
	$this->_trash_filtr = array('filtr_key'=>$filtr_key, 'value'=>$value);
}


function is_trash() {
	if ($this->_trash_filtr === null) {
		return false;
	}

	$trash_filtr_key = $this->_trash_filtr['filtr_key'];
	$trash_filtr_value = $this->_trash_filtr['value'];
	$filtr_value = $this->get_arg($trash_filtr_key);
	if ($filtr_value === null) {
		return false;
	}
	if ($filtr_value == $trash_filtr_value) {
		return true;
	}
	return false;
}


function show_trash() {
	$out = '';
	if ($this->_trash_filtr === null) {
		return $out;
	}

	$trash_filtr_key = $this->_trash_filtr['filtr_key'];
	$trash_filtr_value = $this->_trash_filtr['value'];
	$filtr_value = $this->get_arg($trash_filtr_key);
	if ($filtr_value === null) {// filtr not exists, TODO: throw error?
		return $out;
	}
	$out .= '<nobr>';
		if ($this->is_trash()) {
			//echo App::link("Drzewo", array('task'=>App::get_task()), array('ico'=>'trash_out.gif', 'title'=>'Wroc do drzewa'));
			$trash_ico = 'icon/trash_out.gif';
			$onclick = ' onclick="'."this.form.".$trash_filtr_key.".value='';this.form.submit();".'"';
			$out .= '<input type="image" src="'.$trash_ico.'" value="'."Drzewo".'" class="i"'.$onclick.' title="'."Wroc do drzewa".'" />';
		} else {
			//echo App::link("Kosz", array('task'=>App::get_task(), 'filtr_id'=>"-1"), array('ico'=>'trash.gif', 'title'=>'Kosz'));
			$trash_ico = 'icon/trash.gif';
			$onclick = ' onclick="'."this.form.".$trash_filtr_key.".value='".$trash_filtr_value."';this.form.submit();".'"';
			$out .= '<input type="image" src="'.$trash_ico.'" value="'."Kosz".'" class="i"'.$onclick.' title="'."Kosz".'" />';
		}
	$out .= '</nobr>';
	$out .= $this->separator();

	return $out;
}


function separator() {
	return '<div class="btnseparator"></div>';// separator
}


}
