<?php
# start a session
session_start();

# we set the PHP error handler to use this function
set_error_handler("page_errors");
# only care about errors normally
error_reporting(E_ERROR | E_USER_ERROR);
#error_reporting(E_ALL);

# set the include path so that our templates can always include
# relative to the root template folder
$DOCROOT = str_replace($_SERVER['SCRIPT_NAME'],'',$_SERVER['SCRIPT_FILENAME']) . '/disciplingthenations';
$templates_path = $DOCROOT.'/site';
$php_path = $DOCROOT.'/php';
set_include_path(get_include_path() . PATH_SEPARATOR . $templates_path . PATH_SEPARATOR . $php_path);

# include configuration options
include_once 'includes/config.php';
# require the user class to handle users
require_once 'classes/user.php';

class Page
{
	################################################################################
	# PRIVATE DATA
	private $title,$pageName, $lang;
	private $cssFiles = array(),$jsFiles = array();
	private $header, $footer, $content, $menu;
	private $display,$data;
	private $absPath,$absURL,$site,$templates,$js,$css,$graphics;
	private $messages = array(),$errors = array();
	private $user;
	
	################################################################################
	# PUBLIC FUNCTIONS
	# constructor
	public function __construct()
	{
		# set our paths
		$this->absPath = str_replace($_SERVER['SCRIPT_NAME'],'',$_SERVER['SCRIPT_FILENAME']).'/disciplingthenations/';
		$this->absURL = preg_replace('/^(.*)\/\w+\.php$/','$1',$_SERVER['SCRIPT_NAME']).'/';
		$this->site = 'site/';
		$this->templates = $this->absPath.$this->site;
		$this->js = '/'.$this->site . 'javascript/';
		$this->css = '/'.$this->site . 'css/';
		$this->graphics = '/'.$this->site . 'graphics/';
		
		# the page language is automatically pulled from a language
		# cookie names 'lang'
		if(isset($_GET['lang']))
		{
		  $this->lang = $_GET['lang'];
			setcookie('lang',$_GET['lang'],time() + 60*60*24*365);
			
			# if the lang parameter is empty, we want to get rid of the cookie
			if(empty($_GET['lang']))
			  unset($_COOKIE['lang']);
		}
		else if(isset($_COOKIE['lang']) && !empty($_COOKIE['lang']))
			$this->lang = $_COOKIE['lang'];
		else
			$this->lang = 'en';
			
		$this->templates .= $this->lang .'/';
		$this->graphics .= $this->lang .'/';
		
		# default values for title and pageName
		$this->title = 'Welcome!';
		$this->pageName = preg_replace('/^.*\/(\w+)\.php$/','$1',$_SERVER['SCRIPT_NAME']);
		
		# elements of our page
		$this->header = $this->templates . 'header.php';
		$this->footer = $this->templates . 'footer.php';
		$this->content = $this->templates . 'home.php';
		$this->menu = $this->templates . 'menu.php';
		
		# by default, the header, footer and content are all displayed
		$this->display = array(
			'header' => true,
			'footer' => true,
			'content' => true,
			'menu' => true
		);
		
		# load default css and js files
		array_push($this->cssFiles,$this->css . 'default.css');
		array_push($this->jsFiles,$this->js . 'default.js');
	}
	# automatically load all css files from folder
	public function autoloadCSS()
	{
		# find all CSS files in css folder
		$this->cssFiles = preg_grep('/\.css$/',scandir($this->absPath . $this->css));
		
		# make each path relative to absURL
		foreach($this->cssFiles as $key => $value)
			$this->cssFiles[$key] = $this->css . $value;
	}
	# automatically load all javascript files from folder
	public function autoloadJS()
	{
		# find all js files in javascript folder
		$this->jsFiles = preg_grep('/\.js$/',scandir($this->absPath . $this->js));
		
		# make each path relative to absURL
		foreach($this->jsFiles as $key => $value)
			$this->jsFiles[$key] = $this->js . $value;
	}
	# processes all or part of the page
	public function process($part = NULL)
	{
		# it is possible to process the header or footer by
		# itself or just the content, or the entire page
		if($part == 'header')
			$this->_processHeader();
		else if($part == 'footer')
			$this->_processFooter();
		else if($part == 'content')
			$this->_processContent();
		else
			$this->_processPage();
	}
	# adds a js file to ones already pulled from standard
	# folder
	public function addJSFile($new_file)
	{
		# a list of files can be passed to add several js files at once
		if(func_num_args() > 1)
		{
			$files = func_get_args();
			foreach($files as $js_file)
			{
				array_push($this->jsFiles, $this->js . $js_file);
			}
		}
		# add single file with relative path
		else
		{
			array_push($this->jsFiles, $this->js . $new_file);
		}
	}
	# replaces all other js files with this one
	public function useJSFile($new_file)
	{
		$this->jsFiles = array($this->js . $new_file);
	}
	# adds a css file to ones already pulled from standard folder
	public function addCSSFile($new_file)
	{
		# a list of files can be passed to add several CSS files at once
		if(func_num_args() > 1)
		{
			$files = func_get_args();
			foreach($files as $css_file)
			{
				array_push($this->cssFiles, $this->css . $css_file);
			}
		}
		# add file with relative path
		else
		{
			array_push($this->cssFiles, $this->css . $new_file);
		}
	}
	# replaces all other css files with this one
	public function useCSSFile($new_file)
	{
		$this->cssFiles = array($this->css . $new_file);
	}
	# adds an error message to the array
	public function addError($err)
	{
		array_push($this->errors,$err);
	}
	# adds non-error message to the array
	public function addMessage($msg)
	{
		array_push($this->messages,$msg);
	}
	################################################################################
	# SETTERS/GETTERS
	# return the user object
	public function init_user()
	{
		$this->user = new User($this->absPath.$this->site);
	}
	public function user()
	{
		if(empty($this->user))
			$this->init_user();
			
		return $this->user;
	}
	# you can pass data to the template via this variable
	public function data($key,&$value = NULL)
	{
		if(!is_null($value))
			$this->data[$key] = $value;
		else
			return($this->data[$key]);			
	}
	# you can turn off parts of the page by setting it's 
	# corresponding display element to false
	public function display($page_element,$value = NULL)
	{
		if(!is_null($value))
			$this->display[$page_element] = $value;
		else
			return($this->display[$page_element]);
	}
	# setter/getter for header file
	public function header($new_header = NULL)
	{
		if(!is_null($new_header))
			$this->header = $this->templates . $new_header;
		else
			return $this->header;
	}
	
	# setter/getter for footer file
	public function footer($new_footer = NULL)
	{
		if(!is_null($new_footer))
			$this->footer = $this->templates . $new_footer;
		else
			return $this->footer;
	}
	
	# setter/getter for content file
	public function content($new_content = NULL)
	{
		if(!is_null($new_content))
			$this->content = $this->templates . $new_content;
		else
			return $this->content;
	}

	# setter/getter for menu file
	public function menu($new_menu = NULL)
	{
		if(!is_null($new_menu))
			$this->menu = $this->templates . $new_menu;
		else
			return $this->menu;
	}
	
	# accessor/modifier for page attributes
	public function attr($attr,$value = NULL)
	{
		# the case when we are setting an attribute
		if(!is_null($value))
		{
			switch($attr)
			{
				case 'lang':
					$this->lang	= $value;
					$this->templates = $this->site;
          $this->templates .= $this->lang .'/';
       		$this->graphics .= $this->lang .'/';
       		$this->header = $this->templates . 'header.php';
       		$this->footer = $this->templates . 'footer.php';
       		$this->content = $this->templates . 'home.php';
					break;
				case 'title':
					$this->title = $value;
					break;
				default:
					break;
			}
		}
		# the case when we are getting an attribute
		else
		{
			switch($attr)
			{
				case 'lang':
					return $this->lang;
					break;
				case 'title':
					return $this->title;
					break;
				default:
					break;
			}
		}	
	}
	################################################################################
	# PRIVATE FUNCTIONS
	private function _processPage()
	{
		include $this->absPath . $this->site . 'layout/html.php';
	}
	private function _processHeader()
	{
		include $this->header;
	}
	private function _processFooter()
	{
		include $this->footer;
	}
	private function _processContent()
	{
		include $this->content;
	}
}

################################################################## page_errors #
function page_errors($errno, $errstr, $errfile, $errline, $errcontext)
{
	global $page;
	
	# don't do anything with the message if error_reporting
	# is too low for this type of error
	if(!(error_reporting() & $errno))
		return true;
	
	switch($errno)
	{
		case E_USER_ERROR:
			$page->addError($errstr);
			break;
		case E_NOTICE:
		case E_WARNING:
		case E_USER_WARNING:
		case E_USER_NOTICE:
			$page->addMessage($errstr.$errno.$errfile.$errline);
			break;
		default:
			$page->addError("$errno: $errstr on $errline in $errfile");
			break;
	}
	
	return true;
}

?>