<?php

class Query {

	private $class = "";
	private $table = "";
	private $where = [];
	private $order = [];
	private $limit = "";

	private $query;

	public function __construct($class, $table, $where = []) {
		$this->where = $where;
		$this->table = $table;
		$this->class = $class;
	}

	public function where($where) {
		foreach ($where as $w) {
			$this->where[] = $w;
		}
		return $this;
	}

	public function orderBy($order) {
		$this->order[] = $order;
		return $this;
	}

	public function orderByDesc($order) {
		$this->order[] = "$order desc";
		return $this;
	}

	public function limit($a, $b=null) {
		if ($b == null) {
			$this->limit = $a;
		} else {
			$this->limit = "$a,$b";
		}
		return $this;
	}

	function all() {
		$this->__run();
		$cl = $this->class;

		$out = new Collection;
		while ($r = DB::getInstance()->nextRecord($this->query)) {
			$ob = new $cl($r->id);
			$out->push($ob);
		}
		return $out;
	}

	function first() {
		$this->__run();
		$cl = $this->class;

		$out = new Collection;
		if ($r = DB::getInstance()->nextRecord($this->query)) {
			$ob = new $cl($r->id);
			return $ob;
		}
		return false;
	}

	function next() {
		$cl = $this->class;

		$out = new Collection;
		if ($r = DB::getInstance()->nextRecord($this->query)) {
			$ob = new $cl($r->id);
			return $ob;
		}
		return false;
	}

	// Run the query but don't retrieve anything.
	private function __run() {
		$args = [];
		$ac = 1;
		$q = "select id from `" . $this->table . "`";

		if (count($this->where) > 0) {
			$q .= " where";
			
			$first = true;
			foreach ($this->where as $w) {
				if (!$first) {
					$q .= " and";
				}
				$q .= sprintf(" `%s` %s :arg%d", $w[0], $w[1], $ac);
				$args["arg" . $ac] = $w[2];
				$first = false;
				$ac++;
			}
		}

		if (count($this->order) > 0) {
			$q .= " order by ";
			$q .= implode(",", $this->order);
		}

		if ($this->limit != "") {
			$q .= sprintf(" limit %s", $this->limit);
		}

		$this->query = DB::getInstance()->query($q, $args);
	}
}
