<?php
    class Database {
        public function __construct() {
            try {
				$this->conn = new \PDO("mysql:host=" . DB_HOST . ";port=" . DB_PORT . ";dbname=" . DB_NAME, DB_USER, DB_PASS, array(\PDO::ATTR_PERSISTENT => true));
			} catch(\PDOException $e) {
				throw new \Exception('Failed to connect to database. Reason: \'' . $e->getMessage() . '\'');
			}

			$this->conn->exec("SET NAMES 'utf8'");
			$this->conn->exec("SET CHARACTER SET " . DB_CHARSET);
			$this->conn->exec("SET CHARACTER_SET_CONNECTION=" . DB_CHARSET);
			$this->conn->exec("SET SQL_MODE = ''");
            $this->prefix = DB_PREFIX;
        }

        public function prepare($sql) {
			$this->statement = $this->conn->prepare($sql);
		}

		public function bindParam($parameter, $variable, $data_type = \PDO::PARAM_STR, $length = 0) {
			if ($length) {
				$this->statement->bindParam($parameter, $variable, $data_type, $length);
			} else {
				$this->statement->bindParam($parameter, $variable, $data_type);
			}
		}

		public function execute() {
			try {
				if ($this->statement && $this->statement->execute()) {
					$data = array();

					while ($row = $this->statement->fetch(\PDO::FETCH_ASSOC)) {
						$data[] = $row;
					}

					$result = new \stdClass();
					$result->row = (isset($data[0])) ? $data[0] : array();
					$result->rows = $data;
					$result->num_rows = $this->statement->rowCount();
				}
			} catch(\PDOException $e) {
				throw new \Exception('Error: ' . $e->getMessage() . ' Error Code : ' . $e->getCode());
			}
		}

		public function query($sql, $params = array()) {
            //$this->conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
			$this->statement = $this->conn->prepare($sql);
			
			$result = false;
            $error_info = false;

			try {
				if ($this->statement && $this->statement->execute($params)) {
					$data = array();

					while ($row = $this->statement->fetch(\PDO::FETCH_ASSOC)) {
						$data[] = $row;
					}

					$result = new \stdClass();
					$result->row = (isset($data[0]) ? $data[0] : array());
					$result->rows = $data;
					$result->num_rows = $this->statement->rowCount();
                    $result->error = false;
				}
			} catch (\PDOException $e) {
				//throw new \Exception('Error: ' . $e->getMessage() . ' Error Code : ' . $e->getCode() . ' <br />' . $sql);
                $error_info['message'] = $e->getMessage();
                $error_info['code'] = $e->getCode();
			}

			if ($result) {
				return $result;
			} else {
				$result = new \stdClass();
				$result->row = array();
				$result->rows = array();
				$result->num_rows = 0;
                if($error_info) {
                    $result->error = true;
                    $result->error_info = $error_info;
                }else{
                    $result->error = false;
                }
				
				return $result;
			}
		}

		public function escape($value) {
			return str_replace(array("\\", "\0", "\n", "\r", "\x1a", "'", '"'), array("\\\\", "\\0", "\\n", "\\r", "\Z", "\'", '\"'), $value);
		}

		public function countAffected() {
			if ($this->statement) {
				return $this->statement->rowCount();
			} else {
				return 0;
			}
		}

		public function getLastId() {
			return $this->conn->lastInsertId();
		}
		
		public function isConnected() {
			if ($this->conn) {
				return true;
			} else {
				return false;
			}
		}
		
		public function __destruct() {
			$this->conn = null;
		}
    }