<?php
/**
 * Code Generator class of PHPGEN system. This is the core of PHPGEN system!.
 *
 * PHPGEN is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * PHPGEN is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with PHPGEN; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * @copyright   EasySoft R&D Team (C) 2006
 * @author      Chunsheng Wang <wwccss@263.net>
 * @link        http://www.phpgen.com
 * @package     Generator
 * @version     $Id: Generator.class.php,v 1.5 2006/08/16 16:53:06 wangcs Exp $
 */
class Generator
{
   /**
    * Using smarty to parse code.
    * @var Object
    */
    var $Parser;

   /**
    * Page params.
    * @var array
    */
    var $Page;

   /**
    * The home dir of plugin.
    * @var string
    */
    var $PluginHome;

   /**
    * The Templates files.
    * @var array
    */
    var $Templates   = array();

   /**
    * The codes generatored.
    * @var array
    */
    var $Codes = array();

   /**
    * The code style.
    * @var string
    */
    var $CodeStyle;

   /**
    * Structor.
    *
    * @param object  $Parse     The smarty object.
    * @param array   $CFG       The generator config.
    * @param array   $Page      The defination of Page.
    */
    function generator($Parser, $CFG, $Page, $CodeStyle)
    {
        $this->setParser($Parser);
        $this->setPage($Page);
        $this->setCodeStyle($CodeStyle);
        $this->setTemplateHome($CFG["TemplateHome"]);
        $this->setPluginHome($CFG["PluginHome"]);
        $this->setEmptyLine($CFG["EmptyLine"]);
    }

   /**
    * Set parser.
    *
    * @param object  $Parse     The smarty object.
    */
    function setParser($Parser)
    {
        $this->Parser = $Parser;
        $this->Parser->left_delimiter  = "{{";
        $this->Parser->right_delimiter = "}}";
    }

   /**
    * Set the template files dir of smarty.
    *
    * @param string   $TemplateHome
    */
    function setTemplateHome($TemplateHome)
    {
        $this->Parser->template_dir = $TemplateHome . $this->CodeStyle . "/";
    }

   /**
    * Set the home dir of plugins.
    *
    * @param string   $PluginHome
    */
    function setPluginHome($PluginHome)
    {
        $this->PluginHome = $PluginHome;
    }

   /**
    * Set the code style.
    *
    * @param string   $CodeStyle
    */
    function setCodeStyle($CodeStyle)
    {
        $this->CodeStyle = $CodeStyle;
    }

   /**
    * Set empty line sign.
    *
    * @param string   $EmptyLine
    */
    function setEmptyLine($EmptyLine)
    {
        $this->EmptyLine = $EmptyLine;
    }

   /**
    * Add template files.
    *
    * @param string   $TemplateType     HTML|PHP
    * @param string   $TemplateFile     The Template file name.
    */
    function addTemplate($TemplateType, $TemplateFile)
    {
        $this->Templates[strtoupper($TemplateType)] = $TemplateFile;
    }

   /**
    * Append parsed codes.
    *
    * @param string   $CodeType     HTML|PHP
    * @param string   $Code         the code lines.
    */
    function addCode($CodeType, $Code)
    {
        $this->Codes[$CodeType] = $this->_stripEmptyLine($Code);
    }

   /**
    * Set page params.
    *
    * @param array   $Page;
    */
    function setPage($Page)
    {
        empty($Page["Type"]) ? die("Can't find the page type.") : "";
        $this->Page = $Page;
    }

   /**
    * Import tools lib.
    *
    * @param array   $Page;
    */
    function importToolsLib()
    {
        include_once($this->PluginHome . "Tools.php");
    }

   /**
    * Using the plugin to set template files, assign php vars and then use smarty's fetch method to get the parsed code.
    *
    * @param string   $PluginName       the name of the plugin to be loaded.
    * @param array    $Params           the params passwd to plugin program.
    */
    function parse($Page = "")
    {
        !empty($Page) ? $this->setPage($Page) : "";
        $this->_setIncludePath();
        $this->_setTplFile();
        $this->_setFieldsNumber();
        $this->_setFieldsString();
        $this->_setCreatedTime();
        $this->_setPackageName();
        $this->_setPackageLabel();
        $this->_setAuthor();
        $this->_loadPlugin();
        foreach($this->Templates as $TemplateType => $TemplateFile)
        {
            $this->addCode($TemplateType, $this->Parser->fetch($TemplateFile));
        }
        return $this->Codes;
    }

    /* Save PHP. */
    function savePHP()
    {
        $this->_initDir("PHP");
        $FileID = fopen($this->Page["CodeHome"] . $this->Page["PhpFile"], "w+");
        fwrite($FileID, $this->Codes["PHP"]);
        fclose($FileID);
    }

    /* Save HTML. */
    function saveHTML()
    {
        $this->_initDir("HTML");
        $FileID = fopen($this->Page["CodeHome"] . "Templates/" . $this->Page["TplFile"], "w+");
        fwrite($FileID, $this->Codes["HTML"]);
        fclose($FileID);
    }

    /* Save Language. */
    function saveLang()
    {
        $this->_initDir("Lang");
        if($this->Page["Type"] == "FrontCommon")
        {
            $FileID = fopen($this->Page["CodeHome"] . "Languages/" . $_SESSION["UserLang"] . "/" . $this->Page["PhpFile"], "w+");            
        }
        else
        {
            $FileID = fopen($this->Page["CodeHome"] . "Languages/" . $this->Page["PhpFile"], "w+");            
        }
        fwrite($FileID, $this->Codes["LANG"]);
        fclose($FileID);
    }

    /* Save php and html. */
    function saveAll()
    {
        $this->savePHP();
        $this->saveHTML();
        $this->saveLang();
    }

    /* Set the user's project code home. */
    function _setCodeHome()
    {
        $this->Page["CodeHome"] = codeGetHome($_SESSION["UserName"], $_SESSION["ProjectID"]);
    }

    /* Set the include path used for every php file to include Init.php. */
    function _setIncludePath()
    {
        $this->Page["IncludePath"] = str_repeat("../", substr_count($this->Page["PhpFile"], "/"));
    }

    /* According to the PhpFile var, get the tpl file name. */
    function _setTplFile()
    {
        $this->Page["TplFile"] = str_replace(".php", ".htm", $this->Page["PhpFile"]);
    }

    /* Set number of fields. */
    function _setFieldsNumber()
    {
        $this->Page["FieldsNumber"] = count($this->Page["Fields"]) + 1;    // The fields number used to colspan of table.
    }

    /* Set the query string of fields. */
    function _setFieldsString()
    {
        $this->Page["FieldsString"] = join(",", array_keys($this->Page["Fields"]));
    }

    /* Set the created date. */
    function _setCreatedTime()
    {
        $this->Page["CreatedTime"] = date("Y-m-d H:i:s");
    }

    /* Set project name. */
    function _setPackageName()
    {
        $this->Page["PackageName"] = $_SESSION["Projects"][$_SESSION["ProjectID"]]["Name"];
    }

    /* Set project label. */
    function _setPackageLabel()
    {
        $this->Page["PackageLabel"] = $_SESSION["Projects"][$_SESSION["ProjectID"]]["Label"];
    }
    /* Set author. */
    function _setAuthor()
    {
        $this->Page["Author"] = $_SESSION["UserName"];
    }

   /**
    * Load plugin. The plugin is a php file named by $PluginName.php which defined a function to do some dity works for parsing.
    *
    * @param string   $PluginName       the name of the plugin to be loaded.
    * @param array    $Params           the params passwd to plugin program.
    */
    function _loadPlugin()
    {
        require_once($this->PluginHome . $this->Page["Type"] . ".php");
        $FuncName = "create" . $this->Page["Type"];
        $FuncName(&$this);
    }

    /* Mkdir dirs to store php, tpl and language files. */
    function _initDir($Dirs)
    {
        $this->_setCodeHome();
        if(eregi("PHP", $Dirs))
        {
            $PhpPath  = dirname($this->Page["CodeHome"] . $this->Page["PhpFile"]);
            !file_exists($PhpPath)  ? sysMkdir($PhpPath)  : "";
        }
        if(eregi("HTML", $Dirs))
        {
            $TplPath  = dirname($this->Page["CodeHome"] . "Templates/" . $this->Page["PhpFile"]);
            !file_exists($TplPath)  ? sysMkdir($TplPath)  : "";
        }
        if(eregi("Lang", $Dirs))
        {
            $LangPath = dirname($this->Page["CodeHome"] . "Languages/" . $this->Page["PhpFile"]);
            !file_exists($LangPath) ? sysMkdir($LangPath) : "";
        }
    }

    /* Strip empty lines from Code. */
    function _stripEmptyLine($Code)
    {
        $Code = explode("\n", $Code);
        for($I = 0; $I < count($Code); $I ++)
        {
            if(eregi($this->EmptyLine, $Code[$I]))
            {
                unset($Code[$I]);
            }
        }
        return join("\n", $Code);
    }
}
?>