<?
/**

fly5 start

a mix of fly3 fly4
pug & vuejs 친화적
자동화 제거, 더욱 단순하게
	
*/

/*
spl_autoload_register(function ($class) use ($srcPath) {
	if (
		strstr($class, 'Pug')  ||
		strstr($class, 'Jade') 
	) {
		error_log("loading $class\n");
		//die();
		include(str_replace("\\", DIRECTORY_SEPARATOR, $class) . '.php');
	}
});	
*/
spl_autoload_register(function ($class) use ($srcPath) {
	if (
		strstr($class, 'Pug') /* new name */ ||
		strstr($class, 'Jade') /* old name */
	) {
		$srcPath = __DIR__ . '/../pug/';
		include($srcPath . str_replace("\\", DIRECTORY_SEPARATOR, $class) . '.php');
	}
});

function __file_not_found($fn)
{
	header("HTTP/1.0 404 Not Found");
	echo "fly4 error : file not found $fn";
	die();
}

function __addincludepath($path)
{
	set_include_path(get_include_path() . PATH_SEPARATOR . $path);
}

function __output_file($filename)
{
	// required for IE, otherwise Content-disposition is ignored
	if(ini_get('zlib.output_compression'))
	  ini_set('zlib.output_compression', 'Off');

	// addition by Jorg Weske
	$file_extension = strtolower(substr(strrchr($filename,"."),1));

	if (! is_file( $filename ) ) 
	{
		//echo $filename;
		return false;
	};
	switch( $file_extension )
	{
	  case "pdf": $ctype="application/pdf"; break;
	  case "exe": $ctype="application/octet-stream"; break;
	  case "zip": $ctype="application/zip"; break;
	  case "doc": $ctype="application/msword"; break;
	  case "xls": $ctype="application/vnd.ms-excel"; break;
	  case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
	  case "gif": $ctype="image/gif"; break;
	  case "png": $ctype="image/png"; break;
	  case "jpeg":
	  case 'html':case "htm": $ctype="text/html"; break;
	  case "js": $ctype="application/javascript"; break;
	  case "css": $ctype="text/css"; break;
	  default: $ctype=mime_content_type($filename);//"text/pug";
	}
	header("Content-Type: $ctype");
	header("Content-Length: ".filesize($filename));
	readfile($filename);
	die();
}


class Fly5
{
	var $args = null;
	var $documentroot = './';
	var $rootpath = '';
	//var $viewpath = './view/';
	var $nousephpview = null;
	var $subpages = array(); // [top=>'top.htm', bottom=>'bottom.htm'] 과 같은 방식으로 지정
	var $pug = null; // pug-php
	
	function initialize()
	{
	}
	
	function execute(&$view, $path, $args)
	{
		$view = 'index.pug';
	}	
}

function ll()
{
	$args = func_get_args();
	echo "===================\n";
	foreach($args as $s) {
		if ($s == null){
			echo "\n";
			continue;
		}
		echo ++$i.": ";
		if (is_array($s) || is_object($s))
			print_r($s);
		else
			echo $s."\n";
	}
}

class FlyApp
{
	/**
	fly5 실행 규칙

		path/foo/a/b/c 경로를 실행할 경우

		documentroot/path/foo/a/b/c 파일 리턴
		documentroot/view/path/foo/a/b/c 파일 리턴
		path->foo(a/b/c) 실행  
		path->execute(foo/a/b/c) 실행
		Index->path(foo/a/b/c) 실행
		Index->execute(path/foo/a/b/c) 실행
		
		아무것도 발견 안됨 -> 에러
	*/
	function applyTemplate($contents) {
		return $contents;
		$tag_start			= "\{\{";
		$tag_end			= "\}\}";

		$pattern[] 		= '/'.$tag_start.'\s*([\x{ac00}-\x{d7af}a-zA-Z0-9_\[\]\'\"\.\(\)\/]+)\s*'.$tag_end.'/u'; /* {{a}} => <? $this->a ?> 로 변환 */
		$replacement[] 	= '<?= $this->\\1 ?>';
		
		$pattern[] 		= '/'.$tag_start.'\$([\x{ac00}-\x{d7af}a-zA-Z0-9_\->\[\]]+)\.([\x{ac00}-\x{d7af}a-zA-Z0-9_]+)'.$tag_end.'/u';  /* {{a.b}} => <?=a[b] ?> 로 변환 */
		$replacement[] 	= '<?= $this->\\1[\\2] ?>';
		
		$contents = preg_replace($pattern, $replacement ,$contents);
		
		return $contents;
	}
	
	function pug()
	{
		if ($this->pug == null)
			$this->pug = new Pug\Pug(array(
				prettyprint=>true
			));			
		return $this->pug;
	}
	
	function loadhtml($fn, $data)
	{
		$fn = iconv('utf-8', 'euc-kr', $fn);

		if (!is_file($fn))
			throw new Exception("file not found ".$fn);
		
		if (pathinfo($fn, PATHINFO_EXTENSION) == 'pug') {
			$pug = $this->pug();
			$html = $pug->render($fn, $data);
		} else {
			$html = file_get_contents($fn);				
		}
		if ($this->nousephpview)
		{
			return $html;
		}
		ob_start();
		
		eval(' ?>'.$this->applyTemplate($html).'<?php ');
		$html = ob_get_contents();
		ob_end_clean();
		return $html;
	}
	
	function render($fn, $data)
	{
		$filename = $this->viewpath.$fn;
		$html = $this->loadhtml($filename, $data);
		echo $html;
		//echo "<!-- fly5->render('$filename') -->";
		echo "<!-- fly5->render('$fn') -->";
	}
	
	function run($cls, $method, $args)
	{
		//ll('cls '.$cls, 'method '.$method, 'args '. $args);
		$dir = $this->dir;
		$path = $dir.$cls.".Class.php";
		if(!is_file($path))
			return false;
		
		require_once($path);
		$fly = new $cls();
		if(!method_exists($fly, $method))
			return false;
		
		//$uripath = explode('?', $args, 9999)[0];
		//$uripath = explode('?', $args, 9999)[0];
		//$uripath = explode('?', $args, 9999)[0];
		$args = explode('?', $args, 9999)[1];
		$uripath = substr($_SERVER[PATH_INFO], 1, 9999);
		if($uripath == '')
			$uripath = 'index';
		
		$fly->initialize($uripath, $args);
		//$fly->$method($args);
		
		$data = $fly->$method($view, $uripath, $args);
		if ($view) {
			$this->render($view, $data);
		}
		return true;
	}
	
	function main()
	{
		//print_r($_SERVER);
		__addincludepath('./fly2'); //fly2 와 project path를 기본 include path로		
		$filepath = substr($_SERVER[SCRIPT_FILENAME], 0, strrpos($_SERVER[SCRIPT_FILENAME], '/')+1); // 실제 파일 dir
		$this->rootpath = $filepath;
		$this->viewpath = $this->rootpath.'view/';
		$purepath = $_SERVER[PATH_INFO];
		$all = explode('/', $purepath);
		array_shift($all);
		
		$cls = explode('?', $all[0])[0];
		$purepath = implode('/', array_slice($all, 1, 9999));
		$args = explode('?', $_SERVER[REQUEST_URI])[1];
					
		//ll($purepath, $all, 'cls - '.$cls);
		$fn = $this->rootpath.$this->viewpath.$purepath;
		//ll('fn 1 - '.$fn);
		if(is_file($fn)) {			
			__output_file($fn);
		}
		$fn = $purepath;
		//ll('fn 2 - '.$fn);
		if(is_file($fn)) {			
			__output_file($fn);
		}
		if (!$this->run($cls, $all[1], implode('/', array_slice($all, 2, 9999)))) {
			if (!$this->run($cls, 'execute', implode('/', array_slice($all, 1, 9999)))) {
				if (!$this->run('Index', $cls, implode('/', array_slice($all, 1, 9999)))) {
					//ll('cls XXXXXX'.$cls, $fn);
					//array_unshift($all, $cls);
					if (!$this->run('Index', 'execute', implode('/', $all))) {
						$fn = $docpath.implode('/', $all);
						//ll('execute', $fn);
						__output_file($fn);
						$fn = $docpath.$_SERVER[REQUEST_URI];
						__output_file($fn);
						__file_not_found($fn);
						return;
					}
				}
			}
		}
	}
	function __construct()
	{
		mb_internal_encoding("UTF-8");
		if (php_sapi_name() == 'cli'){
			$argv = $GLOBALS[argv];
			preg_match('/\?(.+)/', $argv[1], $matches);
			parse_str($matches[1], $_REQUEST);
			
			//print_r($_REQUEST);
			$_SERVER[SCRIPT_FILENAME] = $_SERVER[PWD].'/'.$_SERVER[PHP_SELF];
			$_SERVER[REQUEST_URI] = $argv[1];
			//print_r($_SERVER);
			//$_SERVER[
			//die();
			//die();
			//print_r($_REQUEST);
			//http_parse_params(
			//die();
		} 
		//print_r($_SERVER);
	}
}

$app = new FlyApp();
$app->main();

?>