<?php 

/**
 * 
 */
class filter
{
	
	private $query;
	private $sorting;

	public function __construct() {
		$this->query = new query;
		$this->sorting = new sorting;
	}

	public function add_filter($filter, $cb, $priority = 1) {
		$filter = strtolower($filter);
		$cb = strtolower($cb);
		$existing_filter = $this->filter_exists($filter, $cb);
		if($existing_filter) {
			$existing_filter = array_shift($existing_filter);
			if($existing_filter['priority'] != $priority) {
				$this->drop_filter($filter, $cb);
				$this->add_filter($filter, $cb, $priority);
			}
			return;
		}
		return $this->query->insert('filters', array('filter_name', 'filter_cb', 'priority'), array($filter, $cb, $priority));
	}

	public function apply_filters($filter, $subject, ...$args) {
		$filter = strtolower($filter);
		$filters = $this->query->query_to_array($this->query->select('filters', array('filter_name' => $filter)));

		if(_count($filters) > 0) {
			$filters = $this->sorting->sort_by_meta_value($filters, 'priority', 'asc');
			foreach ($filters as $key => $value) {
				if(function_exists($value['filter_cb'])) {
					if(_count($args)) {
						$subject = $value['filter_cb']($subject, $args);
					} else {
						$subject = $value['filter_cb']($subject);
					}
					
				} else {
					// $this->drop_filter($filter, $value['filter_cb']);
				}
			}

		} 
		return $subject;
	}

	public function filter_exists($filter, $cb = false) {
		$filter = strtolower($filter);
		$where = array('filter_name' => $filter);
		if($cb) {
			$cb = strtolower($cb);
			$where['filter_cb'] = $cb;
		}
		return $this->query->query_to_array($this->query->select('filters', $where));
	}

	public function drop_filter($filter, $cb = false) {
		$existing_filter = $this->filter_exists($filter, $cb);
		if($existing_filter && _count($existing_filter)) {
			foreach ($existing_filter as $key => $value) {
				$this->query->delete( 'filters', ['id' => $value['id']]);
			}
		}
		return false;
	}
}