<?php

include_once(dirname(__FILE__).'/../Model.php');

class Module
{
  var $Name;
  var $Version;
  var $License; 
  var $Creator;
  var $Description;
  var $Dependencies;
  var $Models = array();
  var $Database;
  var $Installed;
  var $System;
  
  function __construct($Database, $System)
  {
    $this->Database = &$Database;    
    $this->System = &$System;    
  }
  
  function Install()
  {
    DebugLog('Installing module '.$this->Name.'...');
    foreach($this->Models as $ModelName)
    {
      $Model = new $ModelName($this->Database, $this->System);
      $Model->Install();
      unset($Model);
    }
    $this->Database->query('UPDATE Module SET Installed=1 WHERE Name="'.$this->Name.'"');
  }
  
  function UnInstall()
  {
    DebugLog('Uninstalling module '.$this->Name.'...');
    foreach($this->Models as $ModelName)
    {
      $Model = new $ModelName($this->Database, $this->System);
      $Model->UnInstall();
      unset($Model);
    }
    $this->Database->query('UPDATE Module SET Installed=0 WHERE Name="'.$this->Name.'"');
  }
  
  function Init()
  {
  }
}

class ModularSystem
{
  var $Database;
  var $Modules = array();
  var $Models = array();
  
  function __construct($Database)
  {
    $this->Database = &$Database;
  }
  
  function ModulePresent($Name)
  {
    return(array_key_exists($Name, $this->Modules));
  }

  function Init($Installed = true)
  {
    $Query = 'SELECT Name FROM `Module`';
    if($Installed) $Query .= ' WHERE `Installed`=1';
      else $Query .= ' WHERE `Installed`=0';
    $DbResult = $this->Database->query($Query);
    while($Module = $DbResult->fetch_array())
    {
      include_once(dirname(__FILE__).'/'.$Module['Name'].'/'.$Module['Name'].'.php');
      $ModuleClassName = 'Module'.$Module['Name'];
      $this->Modules[$Module['Name']] = new $ModuleClassName($this->Database, $this);
      $this->Modules[$Module['Name']]->Init();
    }     
  }
  
  function Install()
  {
    //DebugLog('Installing modular system core...');
    $this->Database->query('CREATE TABLE IF NOT EXISTS `Module` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `Name` varchar(255) COLLATE utf8_czech_ci NOT NULL,
  `Creator` varchar(255) COLLATE utf8_czech_ci NOT NULL,
  `Version` varchar(255) COLLATE utf8_czech_ci NOT NULL,
  `License` varchar(255) COLLATE utf8_czech_ci NOT NULL,
  `Installed` int(11) NOT NULL,
  `Description` text COLLATE utf8_czech_ci NOT NULL,
  `Dependecies` varchar(255) COLLATE utf8_czech_ci NOT NULL,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci AUTO_INCREMENT=1;');
    $this->ReloadList();
    $this->Init(false);
    foreach($this->Modules as $Index => $Module)
    {
      $this->Modules[$Index]->Install();
    }
  }
  
  function UnInstall()
  {
    DebugLog('Uninstalling modular system core...');
    foreach($this->Modules as $Index => $Module)
      $this->Modules[$Index]->UnInstall();
    $this->Database->query('DROP TABLE IF EXISTS `Module`');
  }
  
  function ReloadList()
  {
    // Load list of modules from database
    $Modules = array();
    $DbResult = $this->Database->query('SELECT * FROM `Module`');
    while($DbRow = $DbResult->fetch_assoc())
      $Modules[$DbRow['Name']] = $DbRow;
    
    // Load list of modules on disk
    $ModulesOnDisk = array();
    $Files = scandir(dirname(__FILE__)); 
    foreach($Files as $File)
    if(is_dir(dirname(__FILE__).'/'.$File) and ($File != '.') and ($File != '..') and (substr($File, 0, 1) != '.'))
    {
      $ModulesOnDisk[] = $File;
    }   

    // Add new 
    foreach($ModulesOnDisk as $ModuleName)
    if(!array_key_exists($ModuleName, $Modules))
    {
      DebugLog('Adding module '.$ModuleName.' to list');
      include_once(dirname(__FILE__).'/'.$ModuleName.'/'.$ModuleName.'.php');
      $ModuleClassName = 'Module'.$ModuleName;
      if(class_exists($ModuleClassName))
      {
        $Module = new $ModuleClassName($this->Database, $this); 
        $this->Database->insert('Module', array('Name' => $Module->Name, 
          'Version' => $Module->Version, 'Creator' => $Module->Creator, 
          'Description' => $Module->Description, 'License' => $Module->License,
          'Installed' => 0, 'Dependecies' => implode(',', $Module->Dependencies)));
        unset($Module);
      } else throw new Exception('Missing class '.$ModuleClassName.' in module '.$ModuleName);
    }
    
    // Remove missing
    foreach($Modules as $Module)
    if(($Module['Installed'] == 0) and !in_array($Module['Name'], $ModulesOnDisk))
    {
      DebugLog('Removing module '.$Module['Name'].' from list');
      $this->Database->query('DELETE FROM `Module` WHERE `Id` = '.$Module['Id']);
    }
  }
}

?>