<?php 




function CheckData($data){
	return new apiCheck($data);
}

class apiCheck{
	var $data = [];
	var $checkList = [];
	function __construct(&$data){
		$this->data = $data;
	}
	function __call($name,$args){
		if (preg_match("/^is(?<name>[\s\S]+)/i", $name, $match)) {
			return new apiCheckValue($args[0],$this,strtolower($match["name"]));
		}else{
			return new apiCheckValue($args[0],$this,strtolower($name));
		}
	}
	function ok(&$rep = []){
		return !$this->errors($rep);
	}
	function errors(&$rep = []){
		$allOk = true;
		foreach ($this->checkList as $check) {
			if (!$check->check($rep)) {
				$allOk = false;
			}
		}
		$rep["success"] = $allOk;
		return !$allOk;
	}
	function err(&$rep = []){
		return $this->errors($rep);
	}
	function rep(){
		if ($this->ok($rr)) {
			return [
				"success" => false,
				"error"   => true,
				"ctrl"    => $rr,
				"data"    => $this->data
			];
		}else{
			return [
				"success" => true,
				"error"   => false,
				"ctrl"    => $rr,
				"data"    => $this->data
			];
		}
	}
}

class apiCheckValue{
	var $name = "";
	var $type = "string";
	var $parent = null;
	function __construct($name,$parent,$type = "string"){
		$this->name = $name;
		$this->type = strtolower(trim($type));
		$this->parent = $parent;
		if($this->parent){
			$this->parent->checkList[$this->name] = $this;
		}
	}

	var $_required = false;
	var $_required_msg = "";
	function required($message = "Ce champe est obligatoir"){
		$this->_required = true;
		$this->_required_msg = $message;
		return $this;
	}

	var $_unique = false;
	var $_unique_msg = "";
	function unique($message = "Existe déja"){
		$this->_unique = true;
		$this->_unique_msg = $message;
		return $this;
	}


	var $_uniqueIn = false;
	var $_uniqueIn_msg = "Existe déja";
	var $_uniqueIn_idCol = "id";
	function uniqueIn($sql,$message = "Existe déja",$idCol = "id"){
		$this->_uniqueIn = true;
		$this->_uniqueIn_SQL = $sql;
		$this->_uniqueIn_msg = $message;
		$this->_uniqueIn_idCol = $idCol;
		return $this;
	}


	var $_min = null;
	var $_min_msg = "";
	function min($val,$message = null){
		if(is_null($message)) $message = "Minimum $val";
		$this->_min = $val;
		$this->_min_msg = $message;
		return $this;
	}

	var $_max = null;
	var $_max_msg = "";
	function max($val,$message = null){
		if(is_null($message)) $message = "Maximum $val";
		$this->_max = $val;
		$this->_max_msg = $message;
		return $this;
	}

	var $_minLength = null;
	var $_minLength_msg = "";
	function minLength($val,$message = null){
		if(is_null($message)) $message = "Minimum $val Chars";
		$this->_minLength = $val;
		$this->_minLength_msg = $message;
		return $this;
	}

	var $_maxLength = null;
	var $_maxLength_msg = "";
	function maxLength($val,$message = null){
		if(is_null($message)) $message = "Maximum $val Chars";
		$this->_maxLength = $val;
		$this->_maxLength_msg = $message;
		return $this;
	}

	var $_default = null;
	function default($val){
		$this->_default = $val;
		return $this;
	}
	var $_inList = null;
	var $_inList_msg = "";
	function inList($val,$message = "Valeur incorrect"){
		$this->_inList = $val;
		$this->_inList_msg = $message;
		return $this;
	}

	var $_successMessage = null;
	function successMessage($message){
		$this->_successMessage = $message;
		return $this;
	}

	var $_valid = [];
	function valid($callback){
		$this->_valid[] = $callback;
		return $this;
	}
	var $_then = [];
	function then($callback){
		$this->_then[] = $callback;
		return $this;
	}

	function check(&$rep = []){
		$val = null;
		if (array_key_exists($this->name, $this->parent->data)) {
			$val = $this->parent->data[$this->name];
		}
		if ($this->_required && empty($val) && api::$action != "update") {
			$rep[$this->name] = [
				"error"   => $this->_required_msg
			];
			return false;
		}
		if(empty($val)){
			unset($this->parent->data[$this->name]);
			foreach ($this->_then as $thencallabck) {
				$thencallabck();
			}
		}else{
			switch ($this->type) {
				case 'string':
				case 'text':
				case 'texte':
					if (!is_null($this->_minLength)) {
						if (strlen($val)<floatval($this->_minLength)) {
							$rep[$this->name] = [
								"error"   => $this->_minLength_msg
							];
							return false;
						}
					}
					if (!is_null($this->_maxLength)) {
						if (strlen($val)>floatval($this->_maxLength)) {
							$rep[$this->name] = [
								"error"   => $this->_maxLength_msg
							];
							return false;
						}
					}
				break;
				case "email":
					if (!filter_var($val, FILTER_VALIDATE_EMAIL)) {
						$rep[$this->name] = [
							"error"   => "Email invalid!"
						];
						return false;
					}
				break;
				case "number":
				case "int":
				case "double":
				case "float":
				case "integer":
					if (!is_null($this->_min)) {
						if (floatval($val)<floatval($this->_min)) {
							$rep[$this->name] = [
								"error"   => $this->_min_msg
							];
							return false;
						}
					}
					if (!is_null($this->_max)) {
						if (floatval($val)>floatval($this->_max)) {
							$rep[$this->name] = [
								"error"   => $this->_max_msg
							];
							return false;
						}
					}

				break;
			}


			if (!is_null($this->_inList) && is_array($this->_inList)) {
				if(!in_array($val, $this->_inList)){
					$rep[$this->name] = [
						"error"   => $this->_inList_msg
					];
					return false;
				}
			}

			if ($this->_unique) {
				$self = api::$current;
				$id = 0;
				if (isset($this->parent->data[$self->idCol])) {
					$id = $this->parent->data[$self->idCol];
				}
				if($row = db::row("SELECT $self->idCol FROM $self->tableName where $this->name=:val and $self->idCol<>:id",[
					":val" => $val,
					":id"  => $id
				])){
					$rep[$this->name] = [
						"error"   => $this->_unique_msg
					];
					return false;
				}
			}
			if ($this->_uniqueIn) {
				$id = 0;
				if (isset($this->parent->data[$this->_uniqueIn_idCol])) {
					$id = $this->parent->data[$this->_uniqueIn_idCol];
				}
				if($row = db::row("SELECT $this->name FROM ($this->_uniqueIn_SQL) t where $this->name=:val and $this->_uniqueIn_idCol<>:id",[
					":val" => $val,
					":id"  => $id
				])){
					$rep[$this->name] = [
						"error"   => $this->_uniqueIn_msg
					];
					return false;
				}
			}

			$rep[$this->name] = [
				"success" => true
			];
		}
		foreach ($this->_valid as $callback) {
			$v = $callback($val);
			if($v === false){
				$rep[$this->name] = [
					"error"   => true
				];
				return false;
			}elseif(!empty($v) && is_string($v)){
				$rep[$this->name] = [
					"error"   => $v
				];
				return false;
			}elseif ($v === true) {
				$rep[$this->name] = [
					"success" => true
				];
			}
		}
		foreach ($this->_then as $thencallabck) {
			$thencallabck();
		}
		return true;
	}
}