<?php

class MfCurl {

	const COOKIE = 'cookie.dat';

	private $headers;
	private $userAgent;
	private $cookieFile;
	private $proxy;
	private $userName;
	private $password;

	private $options;

	private $lastRequest;
	private $lastRequestMethod;
	private $lastResponse;

	public function __construct($cookies=false,$proxy='',$timeout=30) {
		$this->headers[] = 'Connection: Keep-Alive';
		$this->headers[] = 'Content-type: application/x-www-form-urlencoded;charset=UTF-8';
		$this->userAgent = 'MFFramework MFCurl';

		$this->options = array();

		$this->proxy = $proxy;

		if (is_string($cookies)) {
			$this->cookieFile = $cookies;
			$cookies = true;
		}

		if ($cookies === true) {
			$this->cookies = true;
			$this->SetCookie($this->cookieFile);
		} else {
			$this->cookies = false;
		}

		$this->ch = curl_init();

		$options = array(
//				CURLOPT_HTTPHEADER => $this->headers,
				CURLOPT_USERAGENT => $this->userAgent,
				CURLOPT_HEADER => false,
				CURLOPT_RETURNTRANSFER => true,
				CURLOPT_FOLLOWLOCATION => true
				);

		if ($this->getUserName() != '' && $this->getPassword() != '') {
			$options[CURLOPT_USERPWD] = $this->getUserName() . ":" . $this->getPassword();
		}

		if ($timeout) {
			$options[CURLOPT_TIMEOUT] = $timeout;
		}

		if ($this->cookies == true) {
			$options[CURLOPT_COOKIEFILE] = $this->cookieFile;
			$options[CURLOPT_COOKIEJAR] = $this->cookieFile;
		}

		if ($this->proxy && is_array($this->proxy)) {
			$options[CURLOPT_PROXY] = $this->proxy['ip'] . ':' . $this->proxy['port'];
		}

		$this->SetOption($options);
	}

	public function  __destruct() {
		curl_close($this->ch);
	}

	public function SetUrl($url) {
		$this->SetOption(CURLOPT_URL, $url);
	}

	/**
	 * Ustawia opcje. Aby ustawić więcej niż 1 opcje należy do name
	 * podać tablice indexowaną nazwami opcji (definicjami) o wartościach jakie
	 * chcemy ustawić.
	 *
	 * @param <string/array> $name
	 * @param <mixed> $value
	 */
	public function SetOption($name, $value = null) {
		if (is_array($name)) {
			foreach ($name as $k => $v) {
				$this->options[$k] = $v;
			}
		} else {
			$this->options[$name] = $value;
		}
	}

	public function GetOption($name) {
		if (array_key_exists($name, $this->options)) {
			return $this->options[$name];
		} else {
			return null;
		}
	}

	public function DelOption($name) {
		if (array_key_exists($name, $this->options)) {
			unset($this->options[$name]);
		}
	}

	public function GetInfo($name) {
		return curl_getinfo($this->ch, $name);
	}

	public function GetLastRequest() {
		return $this->lastRequest;
	}

	public function GetLastRequestMethod() {
		return $this->lastRequestMethod;
	}

	public function GetLastResponse() {
		return $this->lastResponse;
	}

	public function GetUserName() {
	    return $this->userName;
	}

	public function SetUserName($userName) {
	    $this->userName = $userName;
	}

	public function GetPassword() {
	    return $this->password;
	}

	public function SetPassword($password) {
	    $this->password = $password;
	}

	public function SetCookie($cookieFile) {
		if (file_exists($cookieFile)) {
			$this->cookieFile=$cookieFile;
		} else {
			$fh = fopen($cookieFile,'w') or $this->RaiseError('The cookie file could not be opened. Make sure this directory has the correct permissions');
			$this->cookieFile=$cookieFile;
			fclose($fh);
		}
	}

	public function Exec($url, $method, $data = null) {
		$method = strtolower($method);

		$this->SetUrl($url);

		$this->lastRequest = $url;
		$this->lastRequestMethod = $method;

		if (ereg("^(https)", $url)) {
		    $this->SetOption(CURLOPT_SSL_VERIFYPEER, false);
		}

		if($this->getUserName()!='' && $this->getPassword()!='') {
		    $this->SetOption(CURLOPT_USERPWD, $this->getUserName() . ":" . $this->getPassword());
		}

		switch ($method) {
			case 'get':
				$header = false;
				break;
			case 'post':
				$this->SetOption(CURLOPT_POST, true);
				$header = true;
				break;
			default:
				$this->SetOption(CURLOPT_CUSTOMREQUEST, $method);
				$header = true;
				break;
		}

		if (!array_key_exists(CURLOPT_HEADER, $this->options)) {
			$this->SetOption(CURLOPT_HEADER, $header);
		}

		if ($data !== null) {
			$this->SetOption(CURLOPT_POSTFIELDS, $data);
		}

		curl_setopt_array($this->ch, $this->options);

		$response =  curl_exec($this->ch);
		$this->lastResponse = $response;

		if (!$response) {
			throw new MfCurl_Exception('No response', 500);
		}

		if ($this->GetOption(CURLOPT_HEADER)) {

			$headerSize = $this->GetInfo(CURLINFO_HEADER_SIZE);

			$headers     = substr($response, 0, $headerSize -4);
			$body        = substr($response, $headerSize);

			$statusCode = array();

			preg_match_all('/(HTTP(.*) ([1-5][0-9]{2}) ([^\n\r]*)){1,10}/', $headers, $ret);

			$responseCode = (int)$ret[3][sizeof($ret[3])-1];
			$responseMsg = $ret[4][sizeof($ret[4])-1];

			if ($responseCode >= 100 && $responseCode < 300) {
				return new MfCurl_Response($body, $responseCode, $responseMsg);
			} else {
				throw new MfCurl_Exception($responseMsg, $responseCode);
			}
		} else {
			return MfCurl_Response($response);
		}
	}

	public function Get($url) {
		return $this->Exec($url, 'get');
	}

	public function Post($url, $data) {
		return $this->Exec($url, 'post', $data);
	}


	public function RaiseError($error) {
		throw new ApiException($error);
	}
}


?>