<?php
abstract class PageBase{
  private $meta;
  private $basedir;
  private $name;
  private $c_header;
  private $c_body;
  private $c_footer;

  function __construct($name,$conf) {
    $this->name=$name;
    $this->basedir="content/pages/$name/";
    $this->meta=Conjuro::loadJson(self::filePath("page.json"));
    if(!isset($this->meta["title"]))
      $this->meta["title"]=$conf["site-title"];
    if(!isset($this->meta["layout"]))
      $this->meta["layout"]=$conf["default-layout"];
    // Sections
    if (isset($this->meta["sections"])){
      $this->c_header=$this->meta["sections"]["header"];
      $this->c_body=$this->meta["sections"]["body"];
      $this->c_footer=$this->meta["sections"]["footer"];
    }
    if ($this->c_header===NULL)
      $this->c_header=[$conf["default-header"]];
    if ($this->c_body==NULL)
      $this->c_body=[];
    if ($this->c_footer===NULL)
      $this->c_footer=[$conf["default-footer"]];
  }

  // Renders an entire section
  private function showSection($secc){
    foreach($secc as $i => $v){
      $this->showFragment($v);
    }
  }

  // META:TITLE
  protected function getTitle(){
    return $this->meta["title"];
  }
  // META:LAYOUT
  protected function getLayoutFile(){
    return "content/layout/".$this->meta["layout"].".php";
  }
  // META:NAME
  protected function getName(){
    return $this->name;
  }

  // Renders a fragmet (but in child class context)
  abstract protected function showFragment($name);

  // Returns the path of a file relative to page
  protected function filePath($file){
    if ($file=="")
      return "";
    if ($file[0]=="#"){
      $fl=substr($file,1);
      return "content/common/$fl";
    }
    return $this->basedir.$file;
  }
  
  // Renders the header
  protected function renderHeader(){
    self::showSection($this->c_header);
  }

  // Renders the body
  protected function renderBody(){
    self::showSection($this->c_body);
  }

  // Renders the footer
  protected function renderFooter(){
    self::showSection($this->c_footer);
  }

  public function needSession(){
    return isset($this->meta["auth"]);
  }

  public function auth(){

  }
}

class Page extends PageBase{

  // Renders the page
  public function showPage(){
    include(self::getLayoutFile());
  }

  // Renders a fragment
  protected function showFragment($name){
    include self::filePath($name.".php");
  }

}

return new class($conf) extends Module{

  private $pages=[];
  private $page="";

  // Render current page
  public function showPage(){
    $this->processRequest();
    $page=$this->getPage($this->currentPage());
    if ($page->needSession() && !$_SESSION['user']){
      $page=$this->getPage($this->conf["login-page"]);
    }
    $page->showPage();
  }

  //Loads page meta from page name (id)
  private function getPage($name){
    if (!isset($this->pages[$name]))
      $this->pages[$name]=new Page($name,$this->conf);
    return $this->pages[$name];
  }

  private function processRequest(){
    // Current page
    if (isset($_GET["page"]))
      $this->page=$_GET["page"];
    else if (isset($_SESSION["page"]))
      $this->page=$_SESSION["page"];
    else
      $this->page=$this->conf["index-page"];
    $_SESSION["page"]=$this->page;
    // Session
    if ($_POST['user'])
      $_SESSION['user']=$this->doLogin($_POST['user'],$_POST['pwd']);
    else if ($_SESSION['user']) // refresh user data
      $_SESSION['user']=$this->db->selectOne('users',null,'where user=?','s',$_SESSION['user']['user']);
    if ($_GET['logout']=='yes')
      session_reset();
  }

  private function doLogin($user,$access){
    return $this->db->selectOne("users",null,'where user=? and pass=sha1(?)','ss',$user,$access);
  }
  
  // Get current selected page
  private function currentPage(){
    return $this->page;      
  }

  public function init(){
    $this->register("showPage",function(){
      $this->showPage();
    });
  }
}
?>