Browse Source

Tools directory for ticket #1

DavidWyand-GG 13 năm trước cách đây
mục cha
commit
8337cad7ee
100 tập tin đã thay đổi với 14884 bổ sung0 xóa
  1. 85 0
      Tools/dae2dts/buildFiles/VisualStudio 2005/projects/Torque.rc
  2. BIN
      Tools/dae2dts/buildFiles/VisualStudio 2005/projects/torque.ico
  3. 85 0
      Tools/dae2dts/buildFiles/VisualStudio 2008/projects/Torque.rc
  4. BIN
      Tools/dae2dts/buildFiles/VisualStudio 2008/projects/torque.ico
  5. 13 0
      Tools/dae2dts/buildFiles/config/project.conf
  6. 12 0
      Tools/dae2dts/buildFiles/config/projectCode.conf
  7. 1 0
      Tools/dae2dts/game/readme.txt
  8. 13 0
      Tools/dae2dts/generateProjects.bat
  9. 226 0
      Tools/dae2dts/source/main.cpp
  10. 214 0
      Tools/dae2dts/source/torqueConfig.h
  11. BIN
      Tools/map2dif/map2dif_plus_tgea.exe
  12. 4 0
      Tools/projectGenerator/.gitignore
  13. 217 0
      Tools/projectGenerator/btargets/targets.inc
  14. 180 0
      Tools/projectGenerator/classes/ActiveXWebPlugin.php
  15. 208 0
      Tools/projectGenerator/classes/BuildTarget.php
  16. 133 0
      Tools/projectGenerator/classes/FileUtil.php
  17. 612 0
      Tools/projectGenerator/classes/Generator.php
  18. 182 0
      Tools/projectGenerator/classes/NPWebPlugin.php
  19. 614 0
      Tools/projectGenerator/classes/Project.php
  20. 111 0
      Tools/projectGenerator/classes/SafariWebPlugin.php
  21. 159 0
      Tools/projectGenerator/classes/Solution.php
  22. 267 0
      Tools/projectGenerator/classes/Torque3D.php
  23. 85 0
      Tools/projectGenerator/classes/WebPlugin.php
  24. 453 0
      Tools/projectGenerator/classes/WindowsRegistry.php
  25. 895 0
      Tools/projectGenerator/classes/plist/CFBinaryPropertyList.php
  26. 524 0
      Tools/projectGenerator/classes/plist/CFPropertyList.php
  27. 661 0
      Tools/projectGenerator/classes/plist/CFType.php
  28. 99 0
      Tools/projectGenerator/classes/plist/IOException.php
  29. 22 0
      Tools/projectGenerator/classes/plist/LICENSE
  30. 22 0
      Tools/projectGenerator/classes/plist/PListException.php
  31. 277 0
      Tools/projectGenerator/libs/Torque3D.conf
  32. 77 0
      Tools/projectGenerator/libs/WebDeploy.conf
  33. 50 0
      Tools/projectGenerator/libs/collada_dom.conf
  34. 43 0
      Tools/projectGenerator/libs/convexDecomp.conf
  35. 30 0
      Tools/projectGenerator/libs/d3dx8dll.conf
  36. 30 0
      Tools/projectGenerator/libs/jpeg.conf
  37. 58 0
      Tools/projectGenerator/libs/libbullet.conf
  38. 30 0
      Tools/projectGenerator/libs/libogg.conf
  39. 30 0
      Tools/projectGenerator/libs/libtheora.conf
  40. 30 0
      Tools/projectGenerator/libs/libvorbis.conf
  41. 33 0
      Tools/projectGenerator/libs/mng.conf
  42. 30 0
      Tools/projectGenerator/libs/nxCharacter.conf
  43. 30 0
      Tools/projectGenerator/libs/nxuStream.conf
  44. 34 0
      Tools/projectGenerator/libs/opcode.conf
  45. 38 0
      Tools/projectGenerator/libs/pcre.conf
  46. 30 0
      Tools/projectGenerator/libs/png.conf
  47. 30 0
      Tools/projectGenerator/libs/squish.conf
  48. 30 0
      Tools/projectGenerator/libs/tinyxml.conf
  49. 32 0
      Tools/projectGenerator/libs/ungif.conf
  50. 30 0
      Tools/projectGenerator/libs/zlib.conf
  51. 92 0
      Tools/projectGenerator/modules/T3D.inc
  52. 30 0
      Tools/projectGenerator/modules/Torque3D.inc
  53. 46 0
      Tools/projectGenerator/modules/advancedLighting.inc
  54. 33 0
      Tools/projectGenerator/modules/basicLighting.inc
  55. 44 0
      Tools/projectGenerator/modules/bullet.inc
  56. 39 0
      Tools/projectGenerator/modules/collada.inc
  57. 199 0
      Tools/projectGenerator/modules/core.inc
  58. 41 0
      Tools/projectGenerator/modules/d3dx8dll.inc
  59. 37 0
      Tools/projectGenerator/modules/dsound.inc
  60. 77 0
      Tools/projectGenerator/modules/fmod.inc
  61. 37 0
      Tools/projectGenerator/modules/jpeg.inc
  62. 36 0
      Tools/projectGenerator/modules/libode.inc
  63. 29 0
      Tools/projectGenerator/modules/libogg.inc
  64. 58 0
      Tools/projectGenerator/modules/libtheora.inc
  65. 48 0
      Tools/projectGenerator/modules/libvorbis.inc
  66. 35 0
      Tools/projectGenerator/modules/mng.inc
  67. 45 0
      Tools/projectGenerator/modules/nxCharacter.inc
  68. 43 0
      Tools/projectGenerator/modules/nxuStream.inc
  69. 39 0
      Tools/projectGenerator/modules/opcode.inc
  70. 32 0
      Tools/projectGenerator/modules/openal.inc
  71. 30 0
      Tools/projectGenerator/modules/pestTimer.inc
  72. 107 0
      Tools/projectGenerator/modules/physX.inc
  73. 37 0
      Tools/projectGenerator/modules/png.inc
  74. 34 0
      Tools/projectGenerator/modules/squish.inc
  75. 31 0
      Tools/projectGenerator/modules/theora.inc
  76. 28 0
      Tools/projectGenerator/modules/tinyxml.inc
  77. 39 0
      Tools/projectGenerator/modules/tools.inc
  78. 33 0
      Tools/projectGenerator/modules/ungif.inc
  79. 26 0
      Tools/projectGenerator/modules/vorbis.inc
  80. 30 0
      Tools/projectGenerator/modules/webDeploy.inc
  81. 28 0
      Tools/projectGenerator/modules/xaudio.inc
  82. 34 0
      Tools/projectGenerator/modules/zlib.inc
  83. 216 0
      Tools/projectGenerator/newProject.php
  84. 490 0
      Tools/projectGenerator/projectGenUtils.inc
  85. 92 0
      Tools/projectGenerator/projectGenerator.php
  86. 389 0
      Tools/projectGenerator/smarty/Config_File.class.php
  87. 1944 0
      Tools/projectGenerator/smarty/Smarty.class.php
  88. 2328 0
      Tools/projectGenerator/smarty/Smarty_Compiler.class.php
  89. 157 0
      Tools/projectGenerator/smarty/debug.tpl
  90. 67 0
      Tools/projectGenerator/smarty/internals/core.assemble_plugin_filepath.php
  91. 43 0
      Tools/projectGenerator/smarty/internals/core.assign_smarty_interface.php
  92. 79 0
      Tools/projectGenerator/smarty/internals/core.create_dir_structure.php
  93. 61 0
      Tools/projectGenerator/smarty/internals/core.display_debug_console.php
  94. 44 0
      Tools/projectGenerator/smarty/internals/core.get_include_path.php
  95. 23 0
      Tools/projectGenerator/smarty/internals/core.get_microtime.php
  96. 80 0
      Tools/projectGenerator/smarty/internals/core.get_php_resource.php
  97. 59 0
      Tools/projectGenerator/smarty/internals/core.is_secure.php
  98. 47 0
      Tools/projectGenerator/smarty/internals/core.is_trusted.php
  99. 125 0
      Tools/projectGenerator/smarty/internals/core.load_plugins.php
  100. 74 0
      Tools/projectGenerator/smarty/internals/core.load_resource_plugin.php

+ 85 - 0
Tools/dae2dts/buildFiles/VisualStudio 2005/projects/Torque.rc

@@ -0,0 +1,85 @@
+//Microsoft Developer Studio generated resource script.
+//
+#define IDI_ICON1                       103
+#define IDI_ICON2                       107
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        108
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1000
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "windows.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1               ICON    DISCARDABLE     "torque.ico"
+IDI_ICON2               ICON    DISCARDABLE     "torque.ico"
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "#include ""windows.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+

BIN
Tools/dae2dts/buildFiles/VisualStudio 2005/projects/torque.ico


+ 85 - 0
Tools/dae2dts/buildFiles/VisualStudio 2008/projects/Torque.rc

@@ -0,0 +1,85 @@
+//Microsoft Developer Studio generated resource script.
+//
+#define IDI_ICON1                       103
+#define IDI_ICON2                       107
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        108
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1000
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "windows.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1               ICON    DISCARDABLE     "torque.ico"
+IDI_ICON2               ICON    DISCARDABLE     "torque.ico"
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "#include ""windows.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+

BIN
Tools/dae2dts/buildFiles/VisualStudio 2008/projects/torque.ico


+ 13 - 0
Tools/dae2dts/buildFiles/config/project.conf

@@ -0,0 +1,13 @@
+<?php
+
+// Configure tool
+Torque3D::$sharedConfig = false;
+
+Torque3D::beginConfig( "win32", "dae2dts" );
+
+addProjectDefine("DAE2DTS_TOOL");
+setProjectSubSystem(1);			// console app
+
+Torque3D::endConfig();
+
+?>

+ 12 - 0
Tools/dae2dts/buildFiles/config/projectCode.conf

@@ -0,0 +1,12 @@
+<?php
+
+   // This file is used to add your project specific code to the Torque 3D Game Engine
+   
+   // by default we add the project's source folders recursively
+   addSrcDir('../source', true);
+
+   // Here is an example of how to include your project specific code 
+   // In this case all the code in the "custom" folder in your project's source directory would be added
+   // addSrcDir('../source/custom');
+
+?>

+ 1 - 0
Tools/dae2dts/game/readme.txt

@@ -0,0 +1 @@
+Executable directory

+ 13 - 0
Tools/dae2dts/generateProjects.bat

@@ -0,0 +1,13 @@
+@echo off
+
+SET TORQUEDIR=%2
+
+IF NOT DEFINED TORQUEDIR SET TORQUEDIR=..\..
+
+@%TORQUEDIR%\engine\bin\php\php %TORQUEDIR%\Tools\projectGenerator\projectGenerator.php buildFiles/config/project.conf %TORQUEDIR%
+@echo  ...
+@echo  ...
+@echo  ...
+@echo REMEMBER: Restart Visual Studio if you are running it to be sure the new
+@echo           project file(s) are loaded! See docs for more info!
+@IF X%1 == X pause

+ 226 - 0
Tools/dae2dts/source/main.cpp

@@ -0,0 +1,226 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include <stdio.h>
+
+#include "platform/platform.h"
+#include "platform/platformVolume.h"
+#include "app/mainLoop.h"
+#include "T3D/gameFunctions.h"
+#include "core/stream/fileStream.h"
+#include "core/resourceManager.h"
+#include "ts/tsShape.h"
+#include "ts/tsShapeConstruct.h"
+
+#ifdef TORQUE_OS_WIN32
+#include "platformWin32/platformWin32.h"
+#include "platformWin32/winConsole.h"
+#endif
+
+
+extern TSShape* loadColladaShape( const Torque::Path &path );
+
+
+/** Print the usage string */
+void printUsage()
+{
+   Con::printf(
+"DAE-2-DTS Converter v%s (c) GarageGames, LLC.\n\n"
+"dae2dts [options] daeFilename\n\n"
+"--config cfgFilename   Set the conversion configuration filename.\n"
+"--output dtsFilename   Set the output DTS filename.\n"
+"--dsq                  If set, all sequences in the shape will be saved\n"
+"                       to DSQ files instead of being embedded in the DTS\n"
+"                       file.\n"
+"--dsq-only             Same as --dsq, but no DTS file will be saved (handy for\n"
+"                       animation only input files).\n"
+"--compat               If set, write to DTS v24 for compatibility with\n"
+"                       ShowToolPro (no support for vertex colors, 2nd UV\n"
+"                       set, autobillboards etc)\n"
+"--diffuse              If set, the diffuse texture will be used as the\n"
+"                       material name (instead of the COLLADA <material> name)\n"
+"--materials            If set, generate a materials.cs script in the output \n"
+"                       folder to define Materials used in the shape.\n"
+"--verbose              If set, output progress information\n\n"
+"Exits with zero on success, non-zero on failure\n\n",
+      TORQUE_APP_VERSION_STRING );
+}
+
+Torque::Path makeFullPath( const char* path )
+{
+   char tempBuf[1024];
+   Platform::makeFullPathName( path, tempBuf, sizeof(tempBuf), Platform::getCurrentDirectory() );
+   return Torque::Path( String( tempBuf ) );
+}
+
+S32 TorqueMain( S32 argc, const char **argv )
+{
+   S32 failed = 0;
+
+   // Initialize the subsystems.
+   StandardMainLoop::init();
+   Con::setVariable( "Con::Prompt", "" );
+   WindowsConsole->enable( true );
+
+   // install all drives for now until we have everything using the volume stuff
+   Platform::FS::InstallFileSystems();
+   Platform::FS::MountDefaults();
+
+   bool compatMode = false;
+   bool diffuseNames = false;
+   bool verbose = false;
+   bool saveDTS = true;
+   bool saveDSQ = false;
+   bool genMaterials = false;
+   Torque::Path cfgPath, srcPath, destPath;
+
+   // Parse arguments
+   S32 i;
+   for ( i = 1; i < argc-1; i++ )
+   {
+      if ( dStrEqual( argv[i], "--config" ) )
+         cfgPath = makeFullPath( argv[++i] );
+      else if ( dStrEqual( argv[i], "--output" ) )
+         destPath = makeFullPath( argv[++i] );
+      else if ( dStrEqual( argv[i], "--dsq" ) )
+         saveDSQ = true;
+      else if ( dStrEqual( argv[i], "--dsq-only" ) )
+      {
+         saveDTS = false;
+         saveDSQ = true;
+      }
+      else if ( dStrEqual( argv[i], "--compat" ) )
+         compatMode = true;
+      else if ( dStrEqual( argv[i], "--diffuse" ) )
+         diffuseNames = true;
+      else if ( dStrEqual( argv[i], "--materials" ) )
+         genMaterials = true;
+      else if ( dStrEqual( argv[i], "--verbose" ) )
+         verbose = true;
+   }
+
+   if ( ( i >= argc ) || ( !dStrEndsWith(argv[i], ".dae") && !dStrEndsWith(argv[i], ".kmz" ) ) )
+   {
+      Con::errorf( "Error: no DAE file specified.\n" );
+      printUsage();
+      return -1;
+   }
+
+   srcPath = makeFullPath( argv[i] );
+   if ( destPath.isEmpty() )
+   {
+      destPath = srcPath;
+      destPath.setExtension( "dts" );
+   }
+
+   if ( !cfgPath.isEmpty() )
+      Con::printf( "Configuration files not yet supported.\n" );
+
+   // Define script callbacks
+   if ( verbose )
+      Con::evaluate( "function UpdateTSShapeLoadProgress(%progress, %msg) { echo(%msg); }" );
+   else
+      Con::evaluate( "function UpdateTSShapeLoadProgress(%progress, %msg) { }" );
+
+   if ( verbose )
+      Con::printf( "Parsing configuration file...\n" );
+
+   // Set import options
+   ColladaUtils::getOptions().reset();
+   ColladaUtils::getOptions().forceUpdateMaterials = genMaterials;
+   ColladaUtils::getOptions().useDiffuseNames = diffuseNames;
+
+   if ( verbose )
+      Con::printf( "Reading dae file...\n" );
+
+   // Attempt to load the DAE file
+   Resource<TSShape> shape = ResourceManager::get().load( srcPath );
+   if ( !shape )
+   {
+      Con::errorf( "Failed to convert DAE file: %s\n", srcPath.getFullPath() );
+      failed = 1;
+   }
+   else
+   {
+      if ( compatMode && !shape->canWriteOldFormat() )
+      {
+         Con::errorf( "Warning: Attempting to save to DTS v24 but the shape "
+                      "contains v26 features. Resulting DTS file may not be valid." );
+      }
+
+      FileStream outStream;
+
+      if ( saveDSQ )
+      {
+         Torque::Path dsqPath( destPath );
+         dsqPath.setExtension( "dsq" );
+
+         for ( S32 i = 0; i < shape->sequences.size(); i++ )
+         {
+            const String& seqName = shape->getName( shape->sequences[i].nameIndex );
+            if ( verbose )
+               Con::printf( "Writing DSQ file for sequence '%s'...\n", seqName.c_str() );
+
+            dsqPath.setFileName( destPath.getFileName() + "_" + seqName );
+
+            if ( outStream.open( dsqPath, Torque::FS::File::Write ) )
+            {
+               shape->exportSequence( &outStream, shape->sequences[i], compatMode );
+               outStream.close();
+            }
+            else
+            {
+               Con::errorf( "Failed to save sequence to %s\n", dsqPath.getFullPath().c_str() );
+               failed = 1;
+            }
+         }
+      }
+      if ( saveDTS )
+      {
+         if ( verbose )
+            Con::printf( "Writing DTS file...\n" );
+
+         if ( outStream.open( destPath, Torque::FS::File::Write ) )
+         {
+            if ( saveDSQ )
+               shape->sequences.setSize(0);
+
+            shape->write( &outStream, compatMode );
+            outStream.close();
+         }
+         else
+         {
+            Con::errorf( "Failed to save shape to %s\n", destPath.getFullPath().c_str() );
+            failed = 1;
+         }
+      }
+   }
+
+   // Clean everything up.
+   StandardMainLoop::shutdown();
+
+   // Do we need to restart?
+   if( StandardMainLoop::requiresRestart() )
+      Platform::restartInstance();
+
+   return failed;
+}

+ 214 - 0
Tools/dae2dts/source/torqueConfig.h

@@ -0,0 +1,214 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _TORQUECONFIG_H_
+#define _TORQUECONFIG_H_
+
+//-----------------------------------------------------------------------------
+//Hi, and welcome to the Torque Config file.
+//
+//This file is a central reference for the various configuration flags that
+//you'll be using when controlling what sort of a Torque build you have. In
+//general, the information here is global for your entire codebase, applying
+//not only to your game proper, but also to all of your tools.
+
+/// Since we can build different engine "products" out of the same
+/// base engine source we need a way to differentiate which product
+/// this particular game is using.
+///
+/// TGE       0001
+/// TGEA      0002
+/// TGB       0003
+/// TGEA 360  0004
+/// TGE WII   0005
+/// Torque 3D 0006
+///
+#define TORQUE_ENGINE_PRODUCT      0006
+
+/// What's the name of your application? Used in a variety of places.
+#define TORQUE_APP_NAME            "dae2dts"
+
+/// What version of the application specific source code is this?
+///
+/// Version number is major * 1000 + minor * 100 + revision * 10.
+#define TORQUE_APP_VERSION         1000
+
+/// Human readable application version string.
+#define TORQUE_APP_VERSION_STRING  "1.0.0"
+
+/// Define me if you want to enable multithreading support.
+#ifndef TORQUE_MULTITHREAD
+#define TORQUE_MULTITHREAD
+#endif
+
+/// Define me if you want to disable Torque memory manager.
+#ifndef TORQUE_DISABLE_MEMORY_MANAGER
+#define TORQUE_DISABLE_MEMORY_MANAGER
+#endif
+
+/// Define me if you don't want Torque to compile dso's
+#define TORQUE_NO_DSO_GENERATION
+
+// Define me if this build is a tools build
+
+#ifndef TORQUE_PLAYER
+#  define TORQUE_TOOLS
+#else
+#  undef TORQUE_TOOLS
+#endif
+
+/// Define me if you want to enable the profiler.
+///    See also the TORQUE_SHIPPING block below
+//#define TORQUE_ENABLE_PROFILER
+
+/// Define me to enable debug mode; enables a great number of additional
+/// sanity checks, as well as making AssertFatal and AssertWarn do something.
+/// This is usually defined by the build target.
+//#define TORQUE_DEBUG
+
+/// Define me if this is a shipping build; if defined I will instruct Torque
+/// to batten down some hatches and generally be more "final game" oriented.
+/// Notably this disables a liberal resource manager file searching, and
+/// console help strings.
+//#define TORQUE_SHIPPING
+
+/// Define me to enable a variety of network debugging aids.
+///
+///  - NetConnection packet logging.
+///  - DebugChecksum guards to detect mismatched pack/unpacks.
+///  - Detection of invalid destination ghosts.
+///
+//#define TORQUE_DEBUG_NET
+
+/// Define me to enable detailed console logging of net moves.
+//#define TORQUE_DEBUG_NET_MOVES
+
+/// Enable this define to change the default Net::MaxPacketDataSize
+/// Do this at your own risk since it has the potential to cause packets
+/// to be split up by old routers and Torque does not have a mechanism to
+/// stitch split packets back together. Using this define can be very useful
+/// in controlled network hardware environments (like a LAN) or for singleplayer
+/// games (like BArricade and its large paths)
+//#define MAXPACKETSIZE 1500
+
+/// Modify me to enable metric gathering code in the renderers.
+///
+/// 0 does nothing; higher numbers enable higher levels of metric gathering.
+//#define TORQUE_GATHER_METRICS 0
+
+/// Define me if you want to enable debug guards in the memory manager.
+///
+/// Debug guards are known values placed before and after every block of
+/// allocated memory. They are checked periodically by Memory::validate(),
+/// and if they are modified (indicating an access to memory the app doesn't
+/// "own"), an error is flagged (ie, you'll see a crash in the memory
+/// manager's validate code). Using this and a debugger, you can track down
+/// memory corruption issues quickly.
+//#define TORQUE_DEBUG_GUARD
+
+/// Define me if you want to enable instanced-static behavior
+//#define TORQUE_ENABLE_THREAD_STATICS
+
+/// Define me if you want to gather static-usage metrics
+//#define TORQUE_ENABLE_THREAD_STATIC_METRICS
+
+/// Define me if you want to enable debug guards on the FrameAllocator.
+/// 
+/// This is similar to the above memory manager guards, but applies only to the
+/// fast FrameAllocator temporary pool memory allocations. The guards are only
+/// checked when the FrameAllocator frees memory (when it's water mark changes).
+/// This is most useful for detecting buffer overruns when using FrameTemp<> .
+/// A buffer overrun in the FrameAllocator is unlikely to cause a crash, but may
+/// still result in unexpected behavior, if other FrameTemp's are stomped.
+//#define FRAMEALLOCATOR_DEBUG_GUARD
+
+/// This #define is used by the FrameAllocator to set the size of the frame.
+///
+/// It was previously set to 3MB but I've increased it to 16MB due to the
+/// FrameAllocator being used as temporary storage for bitmaps in the D3D9
+/// texture manager.
+#define TORQUE_FRAME_SIZE     16 << 20
+
+// Finally, we define some dependent #defines. This enables some subsidiary
+// functionality to get automatically turned on in certain configurations.
+
+#ifdef TORQUE_DEBUG
+
+   #define TORQUE_GATHER_METRICS 0
+   #define TORQUE_ENABLE_PROFILE_PATH
+   #ifndef TORQUE_DEBUG_GUARD
+      #define TORQUE_DEBUG_GUARD
+   #endif
+   #ifndef TORQUE_NET_STATS
+      #define TORQUE_NET_STATS
+   #endif
+
+   // Enables the C++ assert macros AssertFatal, AssertWarn, etc.
+   #define TORQUE_ENABLE_ASSERTS
+
+#endif
+
+#ifdef TORQUE_RELEASE
+  // If it's not DEBUG, it's a RELEASE build, put appropriate things here.
+#endif
+
+#ifdef TORQUE_SHIPPING
+
+    // TORQUE_SHIPPING flags here.
+
+#else
+
+   // Enable the profiler by default, if we're not doing a shipping build.
+   #define TORQUE_ENABLE_PROFILER
+
+   // Enable the TorqueScript assert() instruction if not shipping.
+   #define TORQUE_ENABLE_SCRIPTASSERTS
+
+   // We also enable GFX debug events for use in Pix and other graphics
+   // debugging tools.
+   #define TORQUE_ENABLE_GFXDEBUGEVENTS
+
+#endif
+
+#ifdef TORQUE_TOOLS
+#  define TORQUE_INSTANCE_EXCLUSION   "TorqueToolsTest"
+#else
+#  define TORQUE_INSTANCE_EXCLUSION   "TorqueTest"
+#endif
+
+// Someday, it might make sense to do some pragma magic here so we error
+// on inconsistent flags.
+
+// The Xbox360 has it's own profiling tools, the Torque Profiler should not be used
+#ifdef TORQUE_OS_XENON
+#  ifdef TORQUE_ENABLE_PROFILER
+#     undef TORQUE_ENABLE_PROFILER
+#  endif
+#
+#  ifdef TORQUE_ENABLE_PROFILE_PATH
+#     undef TORQUE_ENABLE_PROFILE_PATH
+#endif
+#endif
+
+
+#endif // _TORQUECONFIG_H_
+

BIN
Tools/map2dif/map2dif_plus_tgea.exe


+ 4 - 0
Tools/projectGenerator/.gitignore

@@ -0,0 +1,4 @@
+#############
+## Torque
+#############
+templates_c/

+ 217 - 0
Tools/projectGenerator/btargets/targets.inc

@@ -0,0 +1,217 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+///////////////////////////// VS9 Xenon /////////////////////////////
+   
+$c = BuildTarget::add(	'VS9 Xenon',							// Name		         			
+                        'buildFiles/VisualStudio 2008 (XDK)',	// Solution output directory
+                        'projects/',	                        // Project output directory (relative to solution)
+                        '../../source/',				        // Base directory		         	
+                        'vc2k8_360_proj.tpl',				    // App Project Template
+                        'vc2k8_360_proj.tpl',				    // Shared App Project Template
+                        'vc2k8_360_lib_proj.tpl',			    // Lib Project Template	
+                        'vc2k8_360_dll_proj.tpl',			    // Shared Lib Project Template	
+                        '',			                            // ActiveX Project Template	(not supported on 360)
+                        '.vcproj' );					        // File ext to write the project to
+
+// Solution template and extension
+$c->setSolutionInfo( 'vc2k8_360_sln.tpl', '', '.sln' );
+
+$c->setFileExtensions( 'c', 'cc', 'h', 'cpp', 'inl', 'm', 'mm' );
+
+$c->setPlatforms( "360" );
+         
+$c->setDontCompilePatterns( "#/platformPOSIX.*#", "#/platformMac.*#", "#/platformWin32.*#", "#\.mac\.#", "#\.win32\.#", "#/mac/#", "#/win32/#", "#\.mm$#", "#\.m$#" );
+
+///////////////////////////// VS9 PS3 /////////////////////////////
+   
+$c = BuildTarget::add(	'VS9 PS3',							// Name		         			
+                        'buildFiles/VisualStudio 2008 (PS3)',	// Solution output directory
+                        'projects/',	                        // Project output directory (relative to solution)
+                        '../../source/',				        // Base directory		         	
+                        'vc2k8_ps3_proj.tpl',				    // App Project Template
+                        'vc2k8_ps3_proj.tpl',				    // Shared App Project Template
+                        'vc2k8_ps3_lib_proj.tpl',			    // Lib Project Template	
+                        'vc2k8_ps3_dll_proj.tpl',			    // Shared Lib Project Template	
+                        '',			                            // ActiveX Project Template	(not supported on ps3)
+                        '.vcproj' );					        // File ext to write the project to
+
+// Solution template and extension
+$c->setSolutionInfo( 'vc2k8_ps3_sln.tpl', '', '.sln' );
+
+$c->setFileExtensions( 'c', 'cc', 'h', 'cpp', 'inl', 'm', 'mm' );
+
+$c->setPlatforms( "ps3" );
+         
+$c->setDontCompilePatterns( "#/platformXbox.*#", "#/platformWin32.*#", "#\.mac\.#", "#\.win\.#", "#\.win32\.#", "#/mac/#", "#/win32/#", "#\.mm$#", "#\.m$#" );
+
+
+///////////////////////////// VS9 /////////////////////////////
+
+$c = BuildTarget::add(	'VS9',							   // Name
+                        'buildFiles/VisualStudio 2008',	   // Solution output directory
+                        'projects/',	                   // Project output directory (relative to solution)
+                        '../../source/',				   // Base directory         
+                        'vc2k8_proj.tpl',				   // App Project Template
+                        'vc2k8_shared.tpl',				   // Shared App Project Template
+                        'vc2k8_lib_proj.tpl',			   // Lib Project Template
+                        'vc2k8_dll_proj.tpl',			   // Shared Lib Project Template
+                        'vc2k8_activex_proj.tpl',		   // ActiveX Control	
+                        '.vcproj' );				       // File ext to write the project to
+                  
+// Solution template and extension
+$c->setSolutionInfo( 'vc2k8_sln.tpl', 'vc2k8_proj_user.tpl', '.sln' );
+
+$c->setFileExtensions( 'c', 'cc', 'h', 'cpp', 'inl', 'asm', 'rc', 'm', 'mm', 'cs' );
+
+$c->setPlatforms( "win", "win32" );
+
+$c->setDotNetInfo('vc2k8_csproj.tpl');
+
+$c->setDontCompilePatterns( "#/platformPOSIX.*#", "#/platformMac.*#", "#\.mac\.#", "#/mac/#", "#\.mm$#", "#\.m$#" );
+
+
+///////////////////////////// VS2010 /////////////////////////////
+
+$c = BuildTarget::add(	'VS2010',							   // Name
+                        'buildFiles/VisualStudio 2010',	   // Solution output directory
+                        'projects/',	                   // Project output directory (relative to solution)
+                        '../../source/',				   // Base directory         
+                        'vc2010_proj.tpl',				   // App Project Template
+                        'vc2010_shared.tpl',				   // Shared App Project Template
+                        'vc2010_lib_proj.tpl',			   // Lib Project Template
+                        'vc2010_dll_proj.tpl',			   // Shared Lib Project Template
+                        'vc2010_activex_proj.tpl',		   // ActiveX Control	
+                        '.vcxproj' );				       // File ext to write the project to
+                  
+// Solution template and extension
+$c->setSolutionInfo( 'vc2010_sln.tpl', '', '.sln', 'vc2010_filter.tpl' );
+
+$c->setFileExtensions( 'c', 'cc', 'h', 'cpp', 'inl', 'asm', 'rc', 'm', 'mm', 'cs' );
+$c->setSourceFileExtensions( 'c', 'cc', 'cpp' );
+
+$c->setPlatforms( "win", "win32" );
+
+$c->setDotNetInfo('vc2010_csproj.tpl');
+
+$c->setDontCompilePatterns( "#/platformPOSIX.*#", "#/platformMac.*#", "#\.mac\.#", "#/mac/#", "#\.mm$#", "#\.m$#" );
+
+/////////////////////////// XCode /////////////////////////////
+
+$c = BuildTarget::add( 'Xcode',						         // Name
+                      'buildFiles/Xcode',		            // Solution output directory
+                      '',	                              // Project output directory (relative to solution)
+                      '../../source/',				         // Base directory
+                      'xcode.tpl',				            // App Project Template
+                      'xcodeSharedApp.tpl',				   // Shared App Project Template
+                      'xcodeLib.tpl',				         // Lib Project Template
+                      'xcodeSharedLib.tpl',			      // Shared Lib Project Template
+                      'xcodeSafariPlugin.tpl',			   // Safari Plugin
+                      '.xcodeproj/project.pbxproj' );    // File ext to write the project to
+
+$c->setDelimiters( '[', ']' ); 						// What delimeters does this template use?
+         
+$c->setFileExtensions( 'c', 'cc', 'h', 'cpp', 'inl', 'm', 'mm' );
+
+$c->setPlatforms( "mac" );
+       
+$c->setDontCompilePatterns( "*\.h*", "*win32*", "*\.win\.*", "#/platformWin32/#", "/D3D.*/", "*dsound*" );
+
+
+///////////////////////////// Make //////////////////////////////
+
+$c = BuildTarget::add( 'Make',                // Name
+                       'buildFiles/Make',     // Solution Output directory
+		       '',                    // Project Output directory (relative to solution)
+		       '../../source/',       // Base directory
+		       'makeApp.tpl',         // App Project Template
+		       'makeAppShared.tpl',   // Shared App Project Template
+		       'makeLib.tpl',         // Lib Project Template
+		       'makeSo.tpl',          // Shared Lib Project Template
+		       '',                    // NP Plugin
+		       '' );                  // File ext to write the project to
+
+$c->setSolutionInfo( 'makeSolution.tpl', '', '' );
+
+$c->setFileExtensions( 'c', 'cc', 'h', 'cpp', 'inl', 'asm' );
+
+$c->setPlatforms( "linux" );
+
+$c->setDontCompilePatterns( "*\.h*", "*win32*", "*\.win\.*", "/D3D.*/", "*dsound*", "#/mac/#", "#\.mm$#", "#\.m$#", "*\.dedicated\.*" );
+
+
+///////////////////////////// Make Dedicated ////////////////////
+
+$c = BuildTarget::add( 'Make Dedicated',      // Name
+                       'buildFiles/Make_Ded', // Output directory
+		       '',                    // Project Output directory (relative to solution)
+		       '../../source/',       // Base directory
+		       'makeApp.tpl',         // App Project Template
+		       'makeAppShared.tpl',   // Shared App Project Template
+		       'makeLib.tpl',         // Lib Project Template
+		       'makeSo.tpl',          // Shared Lib Project Template
+		       '',                    // NP Plugin
+		       '' );                  // File ext to write the project to
+
+$c->setSolutionInfo( 'makeSolution.tpl', '', '' );
+
+$c->setFileExtensions( 'c', 'cc', 'h', 'cpp', 'inl', 'asm' );
+
+$c->setPlatforms( "linux_dedicated" );
+
+$c->setDontCompilePatterns( "*\.h*", "*win32*", "*\.win\.*", "/D3D.*/", "#/gl/#", "#/mac/#", "#\.mm$#", "#\.m$#", "*\.client\.*" );
+
+
+///////////////////////////// Build /////////////////////////////
+
+// 'buildManifest_'.$name.'_'.Generator::$platform.'.txt',
+
+$c = BuildTarget::add( 'build',						// Name         
+                  'buildFiles',         			// Solution output directory
+                  'projects/',	                  // Project output directory (relative to solution)
+                  '../source/',         			// Base directory
+                  'buildManifest.tpl',         	// App Project Template
+                  'buildManifest.tpl',         	// Shared Project Template
+                  '',         				   // Lib Project Template
+                  '',         				   // Shared Lib Project Template
+                  '',         				   // ActiveX Project Template
+                  '.txt' );
+         
+$c->setFileExtensions( 'c', 'cc', 'h', 'cpp', 'inl', 'asm', 'm', 'mm' );
+
+// NO PLATFORMS - SO ALL OR NONE?
+$c->setPlatforms("");
+
+////////////////////
+
+function generateAppConfigOutputs( $name )
+{
+    return BuildTarget::getInstances();
+}
+
+function generateLibConfigOutputs( $name )
+{
+    return BuildTarget::getInstances();
+}
+
+?>

+ 180 - 0
Tools/projectGenerator/classes/ActiveXWebPlugin.php

@@ -0,0 +1,180 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+class ActiveXWebPlugin
+{
+	// GUID
+	var $REGISTRY_APPID_RESOURCEID = "";
+	var $WEBGAME_UUID = "";
+	var $IWEBGAMECTRL_UUID = "";
+	var $WEBGAMELIB_UUID = "";
+	
+	var $WEBGAME_PLUGINNAME = "";
+	var $WEBGAME_CTRLNAME = "";
+
+    var $PLUGIN_DLL = "";
+    var $PLUGIN_VERSION = "";
+	
+	var $FOLDER = "";	
+	var $GAMEFOLDER = "";
+	
+	function ActiveXWebPlugin()
+	{
+		// Setup our GUID
+		
+	    //$this->REGISTRY_APPID_RESOURCEID = ActiveXWebPlugin::generateUUID();
+		//$this->WEBGAME_UUID = ActiveXWebPlugin::generateUUID();
+		//$this->IWEBGAMECTRL_UUID = ActiveXWebPlugin::generateUUID();
+		//$this->WEBGAMELIB_UUID = ActiveXWebPlugin::generateUUID();
+        
+        $rootPhpBuildDir = getcwd();
+		$this->FOLDER = $rootPhpBuildDir."\\web\\source\\activex\\";
+		$this->GAMEFOLDER = $rootPhpBuildDir."\\game\\";
+
+        $this->PLUGIN_DLL = WebDeploymentWindows::$axPluginName.".dll";
+        $this->PLUGIN_VERSION = WebDeploymentWindows::$version;
+        
+        
+	    $this->REGISTRY_APPID_RESOURCEID = WebDeploymentWindows::$axAppUUID;
+		$this->WEBGAME_UUID = WebDeploymentWindows::$axWebGameUUID;
+		$this->IWEBGAMECTRL_UUID = WebDeploymentWindows::$axWebGameCtrlUUID;
+		$this->WEBGAMELIB_UUID = WebDeploymentWindows::$axWebGameLibUUID;
+        
+		
+		$this->WEBGAME_PLUGINNAME = str_replace(" ", "", WebDeploymentWindows::$axPluginName);
+		$this->WEBGAME_CTRLNAME = "IEWebGameCtrl";//str_replace(" ", "", WebDeploymentWindows::$axPluginName)."Ctrl";		
+	}
+	
+	function process($project)
+	{
+      $html = 'file://'.getcwd().'/game/web/sample.html';
+      $html = str_replace("\\", "/", $html);
+      
+      // if the someone is clever enough to change the default location of IE, they are assumed to be 
+      // clever enough to edit the debug command :)
+      
+      $IEExe = "C:\\Program Files\\Internet Explorer\\iexplore.exe";
+      if (file_exists("C:\\Program Files (x86)\\Internet Explorer\\iexplore.exe"))
+        $IEExe = "C:\\Program Files (x86)\\Internet Explorer\\iexplore.exe";
+      
+      $project->commandRelease = $IEExe;
+      $project->commandDebug = $IEExe;
+      $project->commandOptimized = $IEExe;
+      
+      $project->argsRelease = $html;
+      $project->argsDebug = $html;
+      $project->argsOptimized = $html;
+    
+      $this->processTemplates();
+	}
+	
+	function readTemplate($filename)
+	{
+	    $filename = realpath( dirname( $_SERVER[ 'PHP_SELF' ] ) ). "/templates/web/".$filename;
+		$fh = fopen($filename, 'r');
+		$data = fread($fh, filesize($filename));
+		fclose($fh);
+		return $data;
+	}
+	
+	function writeFile($filename, $data)
+	{
+	    $filename = $this->FOLDER . $filename;
+		$fh = fopen($filename, 'w');
+		fwrite($fh, $data);
+		fclose($fh);
+	}
+
+	function writeGameFile($filename, $data)
+	{
+	    $filename = $this->GAMEFOLDER . $filename;
+		$fh = fopen($filename, 'w');
+		fwrite($fh, $data);
+		fclose($fh);
+	}
+
+	function processTemplates()
+	{
+	    // Make sure these come first so timestamp is oldest (for autogeneration)
+		$gen =  $this->readTemplate("activex_IEWebGamePlugin_i_h.tpl");
+		$this->writeFile("IEWebGamePlugin_i.h", $gen);
+		$gen =  $this->readTemplate("activex_IEWebGamePlugin_i_c.tpl");
+		$this->writeFile("IEWebGamePlugin_i.c", $gen);
+
+		// WebGame.idl
+		$idl =  $this->readTemplate("activex_IEWebGamePlugin_idl.tpl");
+		$idl = str_replace("__WEBGAME_UUID__", $this->WEBGAME_UUID, $idl);
+		$idl = str_replace("__IWEBGAMECTRL_UUID__", $this->IWEBGAMECTRL_UUID, $idl);
+		$idl = str_replace("__WEBGAMELIB_UUID__", $this->WEBGAMELIB_UUID, $idl);
+        $idl = str_replace("__WEBGAME_PLUGINNAME__", $this->WEBGAME_PLUGINNAME, $idl);
+		$this->writeFile("IEWebGamePlugin.idl", $idl);
+
+		// dllmain.h
+		$dllmain =  $this->readTemplate("activex_dllmain_h.tpl");
+        $dllmain = str_replace("__WEBGAME_PLUGINNAME__", $this->WEBGAME_PLUGINNAME, $dllmain);
+		$dllmain = str_replace("__REGISTRY_APPID_RESOURCEID__", $this->REGISTRY_APPID_RESOURCEID, $dllmain);
+		$this->writeFile("dllmain.h", $dllmain);
+		
+		//WebGameCtrl.rgs
+		$regs =  $this->readTemplate("activex_IEWebGameCtrl_rgs.tpl");
+		$regs = str_replace("__WEBGAME_UUID__", $this->WEBGAME_UUID, $regs);
+		$regs = str_replace("__WEBGAMELIB_UUID__", $this->WEBGAMELIB_UUID, $regs);
+		$regs = str_replace("__WEBGAME_PLUGINNAME__", $this->WEBGAME_PLUGINNAME, $regs);
+		$regs = str_replace("__WEBGAME_CTRLNAME__", $this->WEBGAME_CTRLNAME, $regs);
+		$this->writeFile("IEWebGameCtrl.rgs", $regs);
+
+		//WebGamePlugin.rgs
+		$regs =  $this->readTemplate("activex_IEWebGamePlugin_rgs.tpl");
+		$regs = str_replace("__WEBGAME_PLUGINNAME__", $this->WEBGAME_PLUGINNAME, $regs);
+		$regs = str_replace("__WEBGAME_CTRLNAME__", $this->WEBGAME_CTRLNAME, $regs);
+		$this->writeFile("IEWebGamePlugin.rgs", $regs);
+
+		
+		//WebGameCtrl.rc
+		$rc =  $this->readTemplate("activex_IEWebGamePlugin_rc.tpl");
+        $rc = str_replace("__PLUGIN_DLL__", $this->PLUGIN_DLL, $rc);
+        $rc = str_replace("__WEBGAME_PLUGINNAME__", $this->WEBGAME_PLUGINNAME, $rc);
+        
+        //versioning
+        
+        $rc = str_replace("__PLUGIN_VERSION_STRING__", $this->PLUGIN_VERSION, $rc);
+        $cd = str_replace(".", "," , $this->PLUGIN_VERSION);
+        $rc = str_replace("__PLUGIN_VERSION_COMMA_DELIMITED__", $cd, $rc);
+        
+		$this->writeFile("IEWebGamePlugin.rc", $rc);
+
+        // handle the sample HTML (and whatever else) that is shared between plugins
+        WebPlugin::processActiveXPlugin($this);
+
+	}
+	
+	static function generateUUID()
+	{
+		$command = realpath( dirname( $_SERVER[ 'PHP_SELF' ] ) )."\\..\\..\\Engine\\bin\\uuidgen\\uuidgen.exe -c";
+		exec($command, $output);
+		return $output[0];
+	}
+	
+}
+
+?>

+ 208 - 0
Tools/projectGenerator/classes/BuildTarget.php

@@ -0,0 +1,208 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+class BuildTarget
+{
+    private static $instances = array(); 	
+
+    public $name;
+    public $output_dir;
+    public $project_dir;
+    public $project_rel_path;
+    public $base_dir;
+    public $template_app;
+    public $template_shared_app;
+    public $template_lib;
+    public $template_shared_lib;
+    public $template_activex;
+    public $template_sln;
+    public $template_user;
+    public $template_csproj;
+    public $solution_ext;
+    public $output_ext;
+    public $file_exts;
+    public $reject_patternss;
+    public $dont_compile_patterns;
+    public $source_file_exts;
+    public $platforms;
+    public $ldelim;
+    public $rdelim;
+    
+    
+    static function add( $name, $out, $project, $base, $template_app, $template_shared_app, $template_lib, $template_shared_lib, $template_activex, $out_ext )
+    {
+        $c = new BuildTarget( $name, $out, $project, $base, $template_app, $template_shared_app, $template_lib, $template_shared_lib, $template_activex, $out_ext );
+        
+        self::$instances[ $name ] = $c;
+        
+        return $c;
+    }
+    
+    static function getInstances()
+    {
+        return self::$instances;
+    }
+    
+    function BuildTarget( $name, $out, $project, $base, $template_app, $template_shared_app, $template_lib, $template_shared_lib, $template_activex, $out_ext )
+    {
+        $this->name 	  	   = $name;
+        $this->output_dir 	= $out;
+        $this->project_dir   = $project;
+        $this->output_ext	   = $out_ext;
+        $this->base_dir	  	= $base;
+        $this->template_app	= $template_app;
+        $this->template_shared_app	= $template_shared_app;
+        $this->template_lib	= $template_lib;
+        $this->template_shared_lib	= $template_shared_lib;
+        $this->template_activex = $template_activex;
+        $this->template_csproj = "";
+        $this->template_user = "";
+        
+        // The template for a filters file used by VS2010.
+        $this->template_filter = "";
+
+        $p = explode( '/', $project );
+        $o = array();
+
+      for( $i = 0; $i < sizeof( $p ); $i++ )
+      {
+         // Skip meaningless . or empty terms.
+         if( $p[ $i ] == '' || $p[ $i ] == '.' )
+            continue;
+
+         array_push( $o, '..' );
+      }
+
+      $this->project_rel_path = implode( '/', $o );
+      
+      if (strlen($this->project_rel_path) > 0)
+         $this->project_rel_path = $this->project_rel_path . "/";
+    }	
+
+    function setDelimiters( $l, $r )
+    {
+        $this->ldelim = $l;
+        $this->rdelim = $r;
+    }
+
+    function setSolutionInfo( $template_sln, $template_user, $output_ext, $template_filter = "" )
+    {
+        $this->template_sln = $template_sln;
+        $this->solution_ext = $output_ext;
+        $this->template_user = $template_user;
+        $this->template_filter = $template_filter;
+    }
+    
+    function setDotNetInfo($template_csprog)
+    {
+        $this->template_csproj = $template_csprog;
+    }
+
+    function setFileExtensions()
+    {
+        $args  = func_get_args();
+        $count = func_num_args();
+    
+        $this->file_exts = $args;
+    }
+    
+    function setSourceFileExtensions()
+    {
+        $args  = func_get_args();
+        $count = func_num_args();
+    
+        $this->source_file_exts = $args;
+    }
+
+    function setRejectPatterns()
+    {
+        $args = func_get_args();
+        
+        $this->reject_patterns = $args;
+    }
+    
+    function setDontCompilePatterns()
+    {
+        $args = func_get_args();
+        
+        $this->dont_compile_patterns = $args;
+    }
+    
+    function setPlatforms()
+    {
+        $args = func_get_args();
+        
+        $this->platforms = $args;
+    }
+    
+    function supportsPlatform( $platform )
+    {
+        if( isset( $this->platforms ) )
+            foreach( $this->platforms as $rule )
+                if( strcmp( $rule, $platform ) == 0 )
+                    return true;
+                    
+        return false;					
+    }
+    
+    function ruleReject( $file )
+    {
+        if( isset( $this->reject_patterns ) )		
+            foreach( $this->reject_patterns as $rule )			
+                if( preg_match( $rule, $file ) ) 
+                    return true;
+            
+        return false;
+    }
+    
+    function allowedFileExt( $file )
+    {
+        foreach( $this->file_exts as $ext ) 
+        {
+            $ext 			= ".{$ext}";
+            $extLen 		= strlen( $ext );
+            $possibleMatch	= substr( $file, -$extLen, $extLen );
+
+            if( $possibleMatch == $ext )
+                return true; 
+        }
+        
+        return false;
+    }
+
+    function isSourceFile( $file )
+    {
+        foreach( $this->source_file_exts as $ext ) 
+        {
+            $ext 			= ".{$ext}";
+            $extLen 		= strlen( $ext );
+            $possibleMatch	= substr( $file, -$extLen, $extLen );
+            if( $possibleMatch == $ext )
+                return true; 
+        }
+		
+        return false;
+    }
+}
+
+?>

+ 133 - 0
Tools/projectGenerator/classes/FileUtil.php

@@ -0,0 +1,133 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+class FileUtil
+{
+	// Turn foo/../bar/../baz/ into baz/
+	static function collapsePath( $p )
+	{
+	    $p = explode( '/', $p );
+	    $o = array();
+	    
+	    for( $i = 0; $i < sizeof( $p ); $i++ )
+	    {
+	        // Skip meaningless . or empty terms.
+	        if( $p[ $i ] == '' || $p[ $i ] == '.' )
+	           continue;
+	
+	        // Consider if we can pop something off the list.
+	        if( $p[ $i ] == '..' && $i > 0 && $o[ sizeof( $o ) - 1 ] != '..' )
+	        {
+	            array_pop( $o );
+	            
+	            continue;
+	        }
+	        
+	        array_push( $o, $p[ $i ] );
+	    }
+	    
+	    return implode( '/', $o );
+	}
+	
+	// We apply some cleanup to the file list, specifically to remove
+	// any groupings with no siblings.
+	static function trimFileList( &$list )
+	{
+	   // Consider each child...
+	   foreach( $list as $k => $v )
+	   {
+	      // Only consider folders...
+	      if( !is_array( $v ) )
+	         continue;
+	
+	      // If child has only one child, then collapse it
+	      reset( $v );
+	      
+	      if( count( $v ) == 1 && is_array( current( $v ) ) ) 
+	      {
+	         //echo("Trying to collapse $k\n");
+	         
+	         $list[ $k ] = current( $v );
+	
+	         // Reset our walk through the list...
+	         reset( $list );
+	      }
+	   }
+	
+	   // Now recurse on all children.
+	   foreach( $list as $k => $v )
+	   {
+	      // Only consider folders...
+	      if( !is_array( $v ) )
+	         continue;
+	
+	      FileUtil::trimFileList( &$list[ $k ] );
+	   }
+	}
+	
+	static function prepareOutputDir( $outdir )
+	{
+		if( !file_exists( $outdir ) ) 
+		{
+			echo( " Directory " . $outdir . " doesn't exist, attempting to create it.\n" );
+	
+			if( !mkdir_r( $outdir, 0777 ) ) 
+			{
+				echo( " Couldn't create directory.\n" );
+	
+				return false;
+			}
+		}
+	
+		if( !chdir( $outdir ) ) 
+		{
+			echo( "Couldn't change directory\n" );
+	
+			return false;;
+		}
+		
+		return true;
+	}
+
+   static function normalizeSlashes( $path )
+   {
+      return str_replace( '\\', '/', $path );
+   }
+   
+   static function isAbsolutePath( $path )
+   {
+      // This looks complex, but its really fairly simple.
+      //
+      // We're detecting existing absolute paths in the include
+      // by converting it to absolute, normalizing the slashes,
+      // and comparing the results.
+      //
+      // If we get an absolute path we just don't prepend the
+      // project relative path part.
+      //
+      $orgPath = FileUtil::normalizeSlashes( $path );
+      $absPath = FileUtil::normalizeSlashes( realpath( $path ) );
+      return strcasecmp( $orgPath, $absPath ) == 0;
+   }
+}
+?>

+ 612 - 0
Tools/projectGenerator/classes/Generator.php

@@ -0,0 +1,612 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+///
+/// Static Generator class
+///  
+require_once( "FileUtil.php" );
+require_once( "Solution.php" );
+require_once( "Project.php" );
+require_once( "BuildTarget.php" );
+require_once( "Torque3D.php");
+require_once( "WindowsRegistry.php");
+require_once( "WebPlugin.php");
+require_once( "ActiveXWebPlugin.php");
+require_once( "NPWebPlugin.php");
+require_once( "SafariWebPlugin.php");
+
+
+class Generator
+{
+    public static $app_name;
+    public static $paths            = array();
+    public static $prefs            = array();
+    public static $config_projects  = array(); 
+    public static $app_lib_includes = array(); // An accumulative list of includes that are needed by libs and subsequently needed by the application
+    public static $platform         = 'win32';
+    public static $solutions        = array();
+    public static $libGuard         = array(); // protect against libraries included multiple times across modules
+    public static $absPath          = NULL;
+    public static $gameProjectName  = NULL;
+    public static $toolBuild        = true;
+    public static $watermarkBuild   = false;
+    public static $purchaseScnBuild = false;
+    public static $demoBuild        = false;
+    public static $objectLimitBuild = false;
+    public static $timeOutBuild     = false;
+    public static $useDLLRuntime    = false;
+    
+    private static $solution_cur;
+    private static $project_cur;
+    private static $module_cur;
+    
+    static function init( $torqueRoot )
+    {
+        // If the torque root is absolute then store and use it.
+        if ( realpath( $torqueRoot ) == $torqueRoot ||
+             realpath( $torqueRoot ) == str_replace("/", "\\", $torqueRoot) )
+        {
+            self::$absPath = str_replace( "\\", "/", $torqueRoot );
+            $torqueRoot = self::$absPath;
+        }
+       
+        if ( self::$absPath )
+        {
+           self::$paths[ 'engineLib' ] = '../../../Engine/lib/';
+           self::$paths[ 'engineSrc' ] = '../../../Engine/source/';
+           self::$paths[ 'engineBin' ] = '../../../Engine/bin/';
+        }
+        else
+        {
+           self::$paths[ 'engineLib' ] = $torqueRoot . '/../Engine/lib/';
+           self::$paths[ 'engineSrc' ] = $torqueRoot . '/../Engine/source/';
+           self::$paths[ 'engineBin' ] = $torqueRoot . '/../Engine/bin/';
+        }
+
+        self::$paths[ 'modules' ]   = $torqueRoot . '/Tools/projectGenerator/modules/';
+        self::$paths[ 'libs' ]      = $torqueRoot . '/Tools/projectGenerator/libs/';
+        self::$platform             = 'win32';
+    }
+    
+    static function setGameProjectName($name)
+    {
+       self::$gameProjectName = $name;
+    }
+
+    static function getGameProjectName()
+    {
+       return self::$gameProjectName;
+    }
+
+    static function setToolBuild($tb)
+    {
+       self::$toolBuild = $tb;
+    }
+
+    static function getToolBuild()
+    {
+       return self::$toolBuild;
+    }
+
+    static function setWatermarkBuild($wb)
+    {
+       self::$watermarkBuild = $wb;
+    }
+
+    static function getWatermarkBuild()
+    {
+       return self::$watermarkBuild;
+    }
+
+    static function setPurchaseScreenBuild($psb)
+    {
+       self::$purchaseScnBuild = $psb;
+    }
+
+    static function getPurchaseScreenBuild()
+    {
+       return self::$purchaseScnBuild;
+    }
+    
+    static function setDemoBuild($db)
+    {
+       self::$demoBuild = $db;
+    }
+
+    static function getDemoBuild()
+    {
+       return self::$demoBuild;
+    }
+
+    static function setObjectLimitBuild($olb)
+    {
+       self::$objectLimitBuild = $olb;
+    }
+
+    static function getObjectLimitBuild()
+    {
+       return self::$objectLimitBuild;
+    }
+
+    static function setTimeOutBuild($tob)
+    {
+       self::$timeOutBuild = $tob;
+    }
+
+    static function getTimeOutBuild()
+    {
+       return self::$timeOutBuild;
+    }
+	
+    static function isApp()
+    {
+        return self::$project_cur->isApp();
+    }
+
+
+    static function getGeneratorLibsPath()
+    {
+        return self::$paths[ 'libs' ];
+    }
+    
+    static function getGeneratorModulesPath()
+    {
+        return self::$paths['modules'];
+    }
+    
+    static function getEngineSrcDir()
+    {
+        return self::$paths['engineSrc'];
+    }
+    
+    static function getLibSrcDir()
+    {
+        return self::$paths['engineLib'];
+    }
+    
+    static function getEngineBinDir()
+    {
+        return self::$paths['engineBin'];
+    }
+    
+    static function addSrcDirRecursive($basePath, $dirPath)
+    {
+      $ignore = array( '.', '..', '.svn', '_svn', 'CVS' ); 
+      $absPath = realpath($argv[1])."/buildFiles/";
+      
+      array_push( self::$project_cur->dir_list, $basePath.'/'.$dirPath );
+
+      $dirHandle = opendir( $absPath.$basePath.'/'.$dirPath); 
+    
+      while( $file = readdir( $dirHandle ) )
+      { 
+         if( !in_array( $file, $ignore ) ) 
+         {
+            if( is_dir( $absPath.$basePath.'/'.$dirPath.'/'.$file ) )
+               self::addSrcDirRecursive( $basePath, "$dirPath/$file"); 
+         }
+      }
+     
+      closedir( $dirHandle ); 
+ 
+    }
+    
+    static function addSrcDir( $dir, $recurse = false )
+    {   
+        if (!$recurse)
+          array_push( self::$project_cur->dir_list, $dir );
+        else
+        {
+          self::addSrcDirRecursive($dir, "");
+        }
+    }
+    
+    static function addSrcFile( $file )
+    {
+        array_push( self::$project_cur->dir_list, $file );
+    }
+    
+    static function addIncludePath( $path )
+    {
+        array_push( self::$project_cur->includes, $path );
+    }
+    
+    static function addProjectDefine( $d, $v )
+    {
+        if (!$v)
+            array_push( self::$project_cur->defines, $d );
+        else
+            array_push( self::$project_cur->defines, $d."=".$v );
+    }
+    
+    static function disableProjectWarning( $warning )
+    {
+        array_push( self::$project_cur->disabledWarnings, $warning );
+    }
+    
+    static function addProjectDefines( $args_array )
+    {
+        self::$project_cur->defines = array_merge( self::$project_cur->defines, $args_array );
+    }
+    
+    static function addProjectLibDir( $dir )
+    {
+        array_push( self::$project_cur->lib_dirs, $dir );
+    }
+    
+    static function addProjectLibInput( $lib )
+    {
+        array_push( self::$project_cur->libs, $lib );
+    }
+    
+    static function includeLib( $lib )
+    {
+        foreach( self::$libGuard as $libName )
+            if( $libName == $lib )
+                return;
+                
+        array_push( self::$libGuard, $lib );
+        
+        // if currently in a project, delay the include
+        if (Generator::inProjectConfig())
+        {
+            array_push( self::$project_cur->lib_includes, $lib );
+            return;
+        }
+
+        // otherwise include it immediately
+        require( Generator::getGeneratorLibsPath() . $lib . '.conf' );                
+    }
+        
+    static function addProjectDependency( $pd )
+    {
+        array_push( self::$project_cur->dependencies, $pd );
+    }
+    
+    static function removeProjectDependency( $pd )
+    {
+        foreach (self::$project_cur->dependencies as $key => $value)
+        {
+            if ($value == $pd)
+            {
+                unset(self::$project_cur->dependencies[$key]);
+            }
+        }
+        
+        self::$project_cur->dependencies = array_values(self::$project_cur->dependencies);        
+    }
+    
+
+    static function addProjectReference( $refName, $version = "")
+    {
+        self::$project_cur->addReference( $refName, $version );
+    }
+    
+    static function setProjectGUID( $guid )
+    {
+        self::$project_cur->guid = $guid;
+    }
+    
+    static function setProjectModuleDefinitionFile ( $mdef )
+    {
+        self::$project_cur->moduleDefinitionFile = $mdef;
+    }
+    
+    static function beginModule( $name )
+    {
+        if( !self::$module_cur )
+            self::$module_cur = $name;
+        else
+            echo( "Generator::beginModule() - already in module!" );   
+    }
+    
+    static function endModule()
+    {
+        if( self::$module_cur )
+            self::$module_cur = null;
+        else
+            trigger_error( "Generator::endModule() - no active module!", E_USER_ERROR );
+    }
+    
+    static function inProjectConfig()
+    {
+        return self::$project_cur != null;
+    }
+    
+    static function setProjectSubSystem( $subSystem )
+    {
+        self::$project_cur->setSubSystem( $subSystem );
+    }
+    
+    static function beginProjectConfig( $name, $type, $guid, $game_dir, $output_name )
+    {
+        if( !self::$project_cur )
+        {
+            echo( "   - begin project: " . $name . "=" . $guid . "\n" );
+            
+            self::$project_cur = new Project( $name, $type, $guid, $game_dir, $output_name );
+            
+            self::$config_projects[ $name ] = self::$project_cur;
+        }
+        else
+            trigger_error( "Generator::beginProjectConfig() - a project is already open!", E_USER_ERROR );
+    }
+    
+    static function endProjectConfig( $type )
+    {
+        //echo( "PT: " .$type. ":".self::$project_cur->type . "\n");
+    
+        if( self::$project_cur )
+        {
+            if( self::$project_cur->type == $type )   
+            {
+                echo( "      - end project " . self::$project_cur->name . "\n" );    
+
+                // Set project outputs
+                self::$project_cur->outputs = BuildTarget::getInstances();
+
+                // Allow project to optimize and validate state, etc    
+                self::$project_cur->validate();
+                   
+                // Bit of flummery from original code, not sure what it is supposed to do -- neo
+                if( $type == Project::$TYPE_LIB )
+                {
+                    // Merge lib includes to global lib include array
+                    self::$app_lib_includes = array_merge( self::$app_lib_includes, self::$project_cur->includes );
+                }
+                else if ( $type == Project::$TYPE_SHARED_LIB )
+                {
+                    // Merge lib includes into app include list
+                    self::$app_lib_includes = array_merge( self::$app_lib_includes, self::$project_cur->includes );
+                }
+                else if ( $type == Project::$TYPE_ACTIVEX )
+                {
+                    // Merge lib includes into app include list
+                    self::$app_lib_includes = array_merge( self::$app_lib_includes, self::$project_cur->includes );
+                }
+                else if ( $type == Project::$TYPE_SAFARI )
+                {
+                    // Merge lib includes into app include list
+                    self::$app_lib_includes = array_merge( self::$app_lib_includes, self::$project_cur->includes );
+                }
+                else if ( $type == Project::$TYPE_SHARED_APP )
+                {
+                    // Merge lib includes into app include list
+                    self::$app_lib_includes = array_merge( self::$app_lib_includes, self::$project_cur->includes );
+                }
+                else if ( $type == Project::$TYPE_APP )
+                {
+                    // Merge lib includes into app include list
+                    self::$project_cur->addIncludes( self::$app_lib_includes );
+                }
+
+                // Clear out sucker
+                $p = self::$project_cur;
+                self::$project_cur = null;
+                
+                // Now include any libraries included in the modules
+                foreach( $p->lib_includes as $libName )
+                    require( Generator::getGeneratorLibsPath() . $libName . '.conf' );
+                
+            }
+            else
+                trigger_error( "Generator::endProjectConfig() - closing type mismatch!", E_USER_ERROR );
+        }
+        else
+            trigger_error( "Generator::endProjectConfig() - no currently open project!", E_USER_ERROR );	 	   
+    }
+
+    static function beginActiveXConfig( $lib_name, $guid = '', $game_dir = 'game', $output_name = '' )
+    {  
+        self::beginProjectConfig( $lib_name, Project::$TYPE_ACTIVEX, $guid, $game_dir, $output_name );
+        
+        // Handle ActiveX specific setup (including ATL template processing, etc)
+        $activex = new ActiveXWebPlugin();
+        $activex->process(self::$project_cur);
+    }
+
+    static function endActiveXConfig()
+    {
+        self::endProjectConfig( Project::$TYPE_ACTIVEX );
+    }
+
+    static function beginSafariConfig( $lib_name, $guid = '', $game_dir = 'game', $output_name = '' )
+    {  
+        self::beginProjectConfig( $lib_name, Project::$TYPE_SAFARI, $guid, $game_dir, $output_name );
+        
+        // Handle Safari specific setup 
+        $safari = new SafariWebPlugin();
+        $safari->process(self::$project_cur);
+    }
+
+    static function endSafariConfig()
+    {
+        self::endProjectConfig( Project::$TYPE_SAFARI );
+    }
+
+    
+    static function beginNPPluginConfig( $lib_name, $guid = '', $game_dir = 'game', $output_name = '' )
+    {  
+        self::beginProjectConfig( $lib_name, Project::$TYPE_SHARED_LIB, $guid, $game_dir, $output_name );
+        self::$project_cur->setUniformOutputFile();
+
+        // Handle NP specific setup (resource template processing, etc)
+        $NP = new NPWebPlugin();
+        $NP->process(self::$project_cur);
+    }
+
+    static function endNPPluginConfig()
+    {
+        self::endProjectConfig( Project::$TYPE_SHARED_LIB );
+    }
+
+
+    static function beginSharedLibConfig( $lib_name, $guid = '', $game_dir = 'game', $output_name = '' )
+    {  
+        self::beginProjectConfig( $lib_name, Project::$TYPE_SHARED_LIB, $guid, $game_dir, $output_name );
+    }
+
+    static function endSharedLibConfig()
+    {
+        self::endProjectConfig( Project::$TYPE_SHARED_LIB );
+    }
+
+    static function beginCSProjectConfig( $lib_name, $guid = '', $game_dir = 'game', $output_name = '' )
+    {  
+        self::beginProjectConfig( $lib_name, Project::$TYPE_CSPROJECT, $guid, $game_dir, $output_name );
+    }
+
+    static function endCSProjectConfig()
+    {
+        self::endProjectConfig( Project::$TYPE_CSPROJECT );
+    }
+
+
+    static function beginLibConfig( $lib_name, $guid = '', $game_dir = 'game', $output_name = '' )
+    {  
+        self::beginProjectConfig( $lib_name, Project::$TYPE_LIB, $guid, $game_dir, $output_name );
+    }
+    
+    static function endLibConfig()
+    {
+        self::endProjectConfig( Project::$TYPE_LIB );
+    }
+	
+    static function beginSharedAppConfig( $app_name, $guid = '', $game_dir = 'game', $output_name = '' )
+    {
+        self::beginProjectConfig( $app_name, Project::$TYPE_SHARED_APP, $guid, $game_dir, $output_name );
+    }
+    
+    static function endSharedAppConfig()
+    {
+        self::endProjectConfig( Project::$TYPE_SHARED_APP);   
+    }
+
+    
+    static function beginAppConfig( $app_name, $guid = '', $game_dir = 'game', $output_name = '' )
+    {
+        self::beginProjectConfig( $app_name, Project::$TYPE_APP, $guid, $game_dir, $output_name );
+    }
+    
+    static function endAppConfig()
+    {
+        self::endProjectConfig( Project::$TYPE_APP );   
+    }
+    
+    static function lookupProjectByName( $pname )
+    {
+        foreach( self::$config_projects as $projName => $proj )
+            if( $projName == $pname )
+                return $proj;
+                
+        return null;
+    }
+
+    // We encapsulate the meat of the project generator in generateProjects()
+    // so that more complex .config files can generate more than one run of projects
+    // without having to run a second instance of php
+    static function generateProjects( $tpl ) 
+    {
+        // Alright, for each project scan and generate the file list.
+        $projectFiles    = array ();
+        $rootPhpBuildDir = getcwd();
+        
+        foreach( self::$config_projects as $projName => $proj ) 
+        {
+            echo( "   - Processing project '$projName'...\n" );
+
+            $proj->generate( $tpl, self::$platform, $rootPhpBuildDir );
+        }
+    
+        echo( "PROJECTS DONE\n\n" );
+    
+        chdir( $rootPhpBuildDir );
+    }
+    
+    /////////////////////// SOLUTIONS /////////////////////////
+    
+    static function beginSolution( $name, $guid )
+    {
+        if( !self::$solution_cur )
+        {
+            self::$solution_cur       = new Solution( $name, $guid );
+            self::$solutions[ $name ] = self::$solution_cur;
+        }
+        else
+           trigger_error( "Generator::beginSolution() - tried to start $name but already in the ".self::$solution_cur->name." solution!", E_USER_ERROR );
+    }
+    
+    static function addSolutionProjectRef( $pname )
+    {
+        if( isset( self::$solution_cur ) )	
+            self::$solution_cur->addProjectRef( $pname );
+        else
+            trigger_error( "Generator::addSolutionProjectRef(): no such project - " . $pname . "\n", E_USER_ERROR );
+    }
+    
+    static function addSolutionProjectRefExt( $pname, $ppath, $pguid )
+    {
+        if( isset( self::$solution_cur ) )	
+            self::$solution_cur->addSolutionProjectRefExt( $pname, $ppath, $pguid );
+        else
+            trigger_error( "Generator::addSolutionProjectRefExt(): no such project - " . $pname . "\n", E_USER_ERROR );
+    }
+    
+    static function endSolution()
+    {
+        if( isset( self::$solution_cur ) )
+        {
+            self::$solution_cur->setOutputs( BuildTarget::getInstances() );    
+    
+            self::$solution_cur = null;
+        }    
+        else
+            trigger_error( "Generator::endSolution(): no active solution!\n", E_USER_ERROR );
+    }
+    
+    static function generateSolutions( $tpl ) 
+    {
+        echo( "GENERATING SOLUTIONS\n\n" );
+    
+        $rootPhpBuildDir = getcwd();
+    
+        // Process all solutions	
+        foreach( self::$solutions as $sname => $solution )
+        {
+            echo( "   - Generating solution: " . $sname . "\n" );			    
+            
+            chdir( $rootPhpBuildDir );
+            
+            $solution->generate( $tpl, self::$platform, $rootPhpBuildDir );
+        }
+        
+        chdir( $rootPhpBuildDir );
+    }
+    
+    static function setDLLRuntime( $val )
+    {
+        self::$useDLLRuntime = $val;
+    }
+} 
+?>

+ 182 - 0
Tools/projectGenerator/classes/NPWebPlugin.php

@@ -0,0 +1,182 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+class NPWebPlugin
+{
+   var $FOLDER = "";
+   var $GAMEFOLDER = "";
+   var $PLUGINNAME = "";
+   
+   var $COMPANY = "";
+   var $COMPANYKEY = "";
+   var $PLUGIN = "";
+   var $PRODUCTNAME = "";
+   var $VERSION = "";
+   var $MIMETYPE = "";
+   var $DESCRIPTION = "";
+   
+   function NPWebPlugin()
+   {
+      $rootPhpBuildDir = getcwd();
+      
+      $this->FOLDER = $rootPhpBuildDir."\\web\\source\\npplugin\\windows\\";
+      $this->GAMEFOLDER = $rootPhpBuildDir."\\game\\";
+      
+      $this->PLUGINNAME = WebDeploymentWindows::$npPluginName;
+      
+      $this->COMPANY = WebDeploymentWindows::$company;
+      $this->COMPANYKEY = WebDeploymentWindows::$companyKey;
+      $this->PLUGIN = WebDeploymentWindows::$plugin;
+      $this->PRODUCTNAME = WebDeploymentWindows::$productName;
+      $this->VERSION = WebDeploymentWindows::$version;
+      $this->MIMETYPE = WebDeploymentWindows::$mimeType;
+      $this->DESCRIPTION = WebDeploymentWindows::$description." ".$this->VERSION;      
+   }
+   
+   function process($project)
+   {
+      $windowsRegistry = new WindowsRegistry();
+
+      $MozillaVersion = $windowsRegistry->ReadValue('HKEY_LOCAL_MACHINE\\SOFTWARE\\Mozilla\\Mozilla Firefox', 'CurrentVersion', TRUE);
+      $MozillaExe = $windowsRegistry->ReadValue('HKEY_LOCAL_MACHINE\\SOFTWARE\\Mozilla\\Mozilla Firefox\\'.$MozillaVersion.'\\Main', 'PathToExe', TRUE);
+
+      // FireFox registry settings
+      $MozillaKey = 'HKEY_LOCAL_MACHINE\\SOFTWARE\\MozillaPlugins\\@';
+      
+      $html = 'file://'.getcwd().'/game/web/sample.html';
+      $html = str_replace("\\", "/", $html);
+      $html = str_replace(" ", "%20", $html);
+      
+      $project->commandRelease = $MozillaExe;
+      $project->commandDebug = $MozillaExe;
+      $project->commandOptimized = $MozillaExe;
+      
+      $project->argsRelease = $html;
+      $project->argsDebug = $html;
+      $project->argsOptimized = $html;
+
+      //$windowsRegistry->WriteValue($MozillaKey.$this->COMPANYKEY.'/'.$this->PLUGIN, 'Path', $this->GAMEFOLDER.$this->PLUGINNAME.'.dll');
+      //$windowsRegistry->WriteValue($MozillaKey.$this->COMPANYKEY.'/'.$this->PLUGIN, 'ProductName', $this->PRODUCTNAME);
+      //$windowsRegistry->WriteValue($MozillaKey.$this->COMPANYKEY.'/'.$this->PLUGIN, 'Vendor', $this->COMPANY);
+      //$windowsRegistry->WriteValue($MozillaKey.$this->COMPANYKEY.'/'.$this->PLUGIN, 'Version', $this->VERSION);
+      //$windowsRegistry->WriteValue($MozillaKey.$this->COMPANYKEY.'/'.$this->PLUGIN.'\\MimeTypes\\application/'.$this->MIMETYPE, 'Description', $this->DESCRIPTION);
+
+      unset($windowsRegistry);
+      
+      $this->processTemplates();
+      
+      setProjectModuleDefinitionFile('../../../web/source/npplugin/windows/npWebGamePlugin.def');
+      
+      /// Prefs
+      addProjectDefine( 'TORQUE_SHADERGEN' );
+      addProjectDefine( 'TORQUE_SHARED' );
+      addProjectDefine( 'TORQUE_WEBDEPLOY' );
+
+      // Firefox	
+      addProjectDefine( 'FIREFOXPLUGIN_EXPORTS' );
+      addProjectDefine( 'MOZILLA_STRICT_API' );
+      addProjectDefine( 'XP_WIN' );
+      
+      addProjectDefine( 'WIN32' );
+      addProjectDefine( '_WINDOWS' );
+      addProjectDefine( '_USRDLL' );
+      
+      addSrcDir( '../web/source/common' );
+      addSrcDir( '../web/source/npplugin' );
+      addSrcDir( '../web/source/npplugin/windows' );
+            
+      // Additional includes
+      addIncludePath( "../../web/source/npplugin/windows" );
+      
+      addProjectLibDir( getAppLibSrcDir() . 'SDL/win32' );
+      addProjectLibDir( getAppLibSrcDir() . 'unicode' );
+      // addProjectLibDir( getAppLibSrcDir() . 'mozilla/lib' );
+      
+      addProjectLibInput('COMCTL32.LIB');
+      addProjectLibInput('COMDLG32.LIB');
+      addProjectLibInput('USER32.LIB');
+      addProjectLibInput('ADVAPI32.LIB');
+      addProjectLibInput('GDI32.LIB');
+      addProjectLibInput('WINMM.LIB');
+      addProjectLibInput('WSOCK32.LIB');
+      addProjectLibInput('vfw32.lib');
+      addProjectLibInput('Imm32.lib');
+      addProjectLibInput('UnicoWS.lib');
+      addProjectLibInput('opengl32.lib');
+      addProjectLibInput('glu32.lib');
+      addProjectLibInput('ole32.lib');
+      addProjectLibInput('shell32.lib');
+      addProjectLibInput('oleaut32.lib');
+      addProjectLibInput('version.lib');
+
+   }
+   
+   function readTemplate($filename)
+   {
+      $filename = realpath( dirname( $_SERVER[ 'PHP_SELF' ] ) ). "/templates/web/".$filename;
+      $fh = fopen($filename, 'r');
+      $data = fread($fh, filesize($filename));
+      fclose($fh);
+      return $data;
+   }
+   
+   function writeFile($filename, $data)
+   {
+      $filename = $this->FOLDER . $filename;
+      $fh = fopen($filename, 'w');
+      fwrite($fh, $data);
+      fclose($fh);
+   }
+
+   function writeGameFile($filename, $data)
+   {
+       $filename = $this->GAMEFOLDER . $filename;
+      $fh = fopen($filename, 'w');
+      fwrite($fh, $data);
+      fclose($fh);
+   }
+
+   function processTemplates()
+   {
+   
+      $data =  $this->readTemplate("firefox_rc.tpl");
+      $cd = str_replace(".", "," , $this->VERSION);
+      $data = str_replace("__PRODUCTVERSION__", $cd, $data);
+      $data = str_replace("__FILEDESCRIPTION__", $this->DESCRIPTION, $data);
+      $data = str_replace("__INTERNALNAME__", $this->PRODUCTNAME, $data);
+      $data = str_replace("__MIMETYPE__", "application/".$this->MIMETYPE, $data);
+      $data = str_replace("__ORIGINALFILENAME__", $this->PLUGINNAME.'.dll', $data);
+      $data = str_replace("__PRODUCTNAME__", $this->PRODUCTNAME, $data);
+      $data = str_replace("__COMPANY__", $this->COMPANY, $data);
+      $data = str_replace("__COMPANYKEY__", $this->COMPANYKEY, $data);
+      $data = str_replace("__PLUGIN__", $this->PLUGIN, $data);      
+      $this->writeFile('NPWebGamePlugin.rc', $data);
+      
+      // handle the sample HTML (and whatever else) that is shared between plugins
+      WebPlugin::processNPPlugin($this);
+      
+   }
+   
+}
+
+?>

+ 614 - 0
Tools/projectGenerator/classes/Project.php

@@ -0,0 +1,614 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+///
+///    Project info
+///
+class Project
+{
+   public static $TYPE_APP    =     'app';
+   public static $TYPE_SHARED_APP = 'sharedapp';
+   public static $TYPE_LIB    =     'lib';
+   public static $TYPE_SHARED_LIB = 'shared';
+   public static $TYPE_ACTIVEX =    'activex';
+   public static $TYPE_SAFARI =     'safari';
+   public static $TYPE_CSPROJECT =     'csproj';
+   
+   public $name;               // Project name
+   public $guid;               // Project GUID
+   public $type;               // Application or Library?
+   public $dir_list;           // What directories are we checking in?
+   public $outputs;            // List of outputs we want to generate.
+   public $game_dir;           // Base product path
+   public $defines;            // Preprocessor directives
+   public $disabledWarnings;   // Additional warnings to disable
+   public $includes;           // Additional include paths
+   public $libs;               // Additional libraries to link against
+   public $lib_dirs;           // Additional library search paths
+   public $lib_includes;        // libs to include (generated by modules)
+   public $additionalExePath;  // Additional section to inject into executable path
+   public $dependencies;       // Projects this project depends on
+   public $references;         // for managed projects, references to required assemblies
+   public $moduleDefinitionFile;       // definition file to control shared library exports on windows
+   public $projectFileExt;
+   
+   public $commandDebug = "";
+   public $commandOptimized = "";
+   public $commandRelease = "";
+
+   public $argsDebug = "";
+   public $argsOptimized = "";
+   public $argsRelease = "";
+   
+   public $projSubSystem = 2; // support for Windows/Console/Assembly linker subsystem (1 - Console, 2 - Windows, 3 - Assembly)
+
+   private static $xUID = 1; // used for unique file IDs for Xcode projects
+   
+   public $uniformOutputFile = 0; // debug/release builds use same filename (necessary for np plugin)
+
+   // $additionalExePath, $lib_dirs, $libs, all appear to be unused. [pauls 11/9/2007]
+    public function Project( $name, $type, $guid = '', $game_dir = 'game', $output_name = '' )
+    {
+        if (strlen($output_name) == 0)
+           $output_name = $name;
+
+        $this->name         = $name;
+        $this->outputName   = $output_name;
+        $this->guid         = $guid;
+        $this->type         = $type;
+        $this->game_dir     = $game_dir;
+        $this->dir_list     = array();
+        $this->defines      = array();
+        $this->includes     = array();
+        $this->libs         = array();
+        $this->lib_dirs     = array();
+        $this->lib_includes = array();
+        $this->outputs      = array();
+        $this->dependencies = array();
+        $this->disabledWarnings = array();
+        $this->references = array();
+    }
+
+    public function isApp()
+    {
+        return $this->type == self::$TYPE_APP;
+    }
+
+    public function isSharedApp()
+    {
+        return $this->type == self::$TYPE_SHARED_APP;
+    }
+
+    public function isLib()
+    {
+        return $this->type == self::$TYPE_LIB;
+    }
+
+    public function isSharedLib()
+    {
+        return $this->type == self::$TYPE_SHARED_LIB;
+    }
+
+    public function isCSProject()
+    {
+        return $this->type == self::$TYPE_CSPROJECT;
+    }
+
+    public function isActiveX()
+    {
+        return $this->type == self::$TYPE_ACTIVEX;
+    }
+
+    public function isSafari()
+    {
+        return $this->type == self::$TYPE_SAFARI;
+    }
+
+    public function setUniformOutputFile()
+    {
+        return $this->uniformOutputFile = 1;
+    }
+    
+    public function setSubSystem( $subSystem )
+    {
+        $this->projSubSystem = $subSystem;
+    }
+
+    public function validate()
+    {
+        // Sort the path list
+        sort( $this->dir_list );
+
+        // Make sure we don't have any duplicate paths
+        $this->dir_list = array_unique( $this->dir_list );
+    }
+    
+    public function addReference($refName, $version = "")
+    {
+        $this->references[$refName] = $version;
+    }
+
+    public function addIncludes( $includes )
+    {
+        $this->includes = array_merge( $includes, $this->includes );
+    }
+
+    public function validateDependencies()
+    {
+        $pguids = array();
+
+        foreach( $this->dependencies as $pname )
+        {
+            $p = Generator::lookupProjectByName( $pname );
+
+            if( $p )
+                array_push( $pguids, $p->guid );
+            else
+                trigger_error( "Project dependency not found:  " .$pname, E_USER_ERROR );
+        }
+        // todo: change to dependencyGuids
+        $this->dependencies = $pguids;
+    }
+
+    private function generateXUID()
+    {
+        return sprintf( "%023X", Project::$xUID++ );
+    }
+
+    private function createFileEntry( $output, $curPath, $curFile )
+    {
+        // See if we need to reject it based on our rules..
+        if( $output->ruleReject( $curFile ) )
+            return null;
+
+        // Get the extension - is it one of our allowed values?
+        if( !$output->allowedFileExt( $curFile ) )
+            return null;
+
+        // Cool - note in the list!
+        $newEntry       = new stdClass();
+        $newEntry->name = $curFile;
+        $newEntry->path = FileUtil::collapsePath( $curPath . "/" . $curFile );
+        
+        if ( !FileUtil::isAbsolutePath( $newEntry->path ) )
+        {
+           // This could be consolidated into a single OR statement but it is easier to
+           // read as two separate if's
+           if ( !Generator::$absPath )
+              $newEntry->path = $output->project_rel_path . $newEntry->path;
+              
+           if ( Generator::$absPath && !stristr($newEntry->path, Generator::$absPath) )
+              $newEntry->path = $output->project_rel_path . $newEntry->path;
+         }
+         
+        // Store a project-unique ID here for Xcode projects
+        //  It will be appended by a single char in the templates.
+        $newEntry->hash = Project::generateXUID();
+
+        return $newEntry;
+    }
+
+    function generateFileList( &$projectFiles, $outputName, &$output )
+    {
+        $projName                   = $this->name;
+        $projectFiles[ $projName ]  = array();
+
+        foreach( $this->dir_list as $dir )
+        {
+            $dir = FileUtil::normalizeSlashes( $dir );
+            
+            // Build the path.
+            if ( FileUtil::isAbsolutePath( $dir ) )
+               $curPath  = $dir;
+            else
+               $curPath  = FileUtil::collapsePath( $output->base_dir . $dir );
+            $pathWalk = &$projectFiles[ $projName ];
+            
+            if ( Generator::$absPath )
+            {
+               if ( stristr($curPath, getEngineSrcDir()) || stristr($curPath, getLibSrcDir()) )
+                  $curPath = Generator::$absPath . "/". str_replace("../", "", $curPath);
+            }
+
+            // Check if its a file or a directory.
+            // If its a file just add it directly and build a containng filter/folder structure,
+            // for it else if a dir add all files in it.
+            if( is_file( $curPath ) )
+            {
+                // Get the file name
+                $curFile = basename( $curPath );
+                $curPath = dirname( $curPath );
+
+                //echo( "FILE: " . $curFile . " PATH: " . $curPath . "\n" );
+            }
+
+            if( is_dir( $curPath ) )
+            {
+                //echo( "DIR: " . $curPath . "\n" );
+
+                // Get the array we'll be adding things to...
+                $pathParts = explode( '/', FileUtil::collapsePath( $dir ) );
+
+                foreach( $pathParts as $part )
+                {
+                    // Skip parts that are relative paths - only want meaningful directories.
+                    if( $part == '..' )
+                        continue;
+
+                    if( !is_array( $pathWalk[ $part ] ) )
+                        $pathWalk[ $part ] = array();
+
+                    $pathWalk = &$pathWalk[ $part ];
+                }
+
+                // Open directory.
+                //echo( "SCANNING: " . $curPath . "\n");
+
+                $dirHdl = opendir( $curPath );
+
+                if( !$dirHdl )
+                {
+                    echo( "Path " . $curPath . " not found, giving up.\n" );
+
+                    return false;
+                }
+
+                // Iterate over all the files in the path if not a single file spec.
+                if( !$curFile )
+                {
+                    while( $curFile = readdir( $dirHdl ) )
+                    {
+                        // Skip out if it's an uninteresting dir...
+                        if( $curFile == '.' || $curFile == '..' || $curFile == '.svn' || $curFile == 'CVS' )
+                            continue;
+
+                        $newEntry = $this->createFileEntry( $output, $curPath, $curFile );
+
+                        if( $newEntry )
+                            $pathWalk[] = $newEntry;
+                    }
+                }
+                else
+                {
+                    $newEntry = $this->createFileEntry( $output, $curPath, $curFile );
+
+                    if( $newEntry )
+                        $pathWalk = $newEntry;
+
+                    $curFile = '';
+                }
+
+                // Clean up after ourselves!
+                closedir( $dirHdl );
+            }
+        }
+
+        FileUtil::trimFileList( &$projectFiles );
+
+        // Uncomment me to see the structure the file lister is returning.
+        //print_r($projectFiles);
+
+        return true;
+    }
+
+    private function setTemplateParams( $tpl, $output, &$projectFiles )
+    {
+        // Set the template delimiters
+        $tpl->left_delimiter  = $output->ldelim  ? $output->ldelim  : '{';
+        $tpl->right_delimiter = $output->rdelim ? $output->rdelim : '}';
+
+        // Evaluate template into a file.
+        $tpl->assign_by_ref( 'projSettings', $this );
+        $tpl->assign_by_ref( 'projOutput',   $output );
+        $tpl->assign_by_ref( 'fileArray',    $projectFiles );
+        $tpl->assign_by_ref( 'projName',     $this->name );
+        $tpl->assign_by_ref( 'projOutName',  $this->outputName );
+        $tpl->assign_by_ref( 'gameFolder',   $this->game_dir );
+        $tpl->assign_by_ref( 'GUID',         $this->guid );
+        $tpl->assign_by_ref( 'projDefines',  $this->defines );
+        $tpl->assign_by_ref( 'projDisabledWarnings',  $this->disabledWarnings );
+        $tpl->assign_by_ref( 'projIncludes', $this->includes );
+        $tpl->assign_by_ref( 'projLibs',     $this->libs );
+        $tpl->assign_by_ref( 'projLibDirs',  $this->lib_dirs );
+        $tpl->assign_by_ref( 'projDepend',   $this->dependencies );
+        $tpl->assign_by_ref( 'gameProjectName', getGameProjectName() );
+        $tpl->assign_by_ref( 'projModuleDefinitionFile',   $this->moduleDefinitionFile );
+        $tpl->assign_by_ref( 'projSubSystem', $this->projSubSystem );
+        
+        if (Generator::$useDLLRuntime)
+        {
+            // /MD and /MDd
+            $tpl->assign( 'projRuntimeRelease', 2 );
+            $tpl->assign( 'projRuntimeDebug', 3 );
+        }
+        else
+        {
+            // /MT and /MTd
+            $tpl->assign( 'projRuntimeRelease', 0 );
+            $tpl->assign( 'projRuntimeDebug', 1 );       
+        }
+        
+        if (!$this->commandDebug && ( $this->isSharedLib() || $this->isSharedApp() ))
+        {
+        
+            $command = "$(TargetDir)\\".$this->outputName;
+            $tpl->assign( 'commandDebug' , $command."_DEBUG.exe");
+            $tpl->assign( 'commandRelease' , $command.".exe");
+            $tpl->assign( 'commandOptimized' , $command."_OPTIMIZEDDEBUG.exe");
+        }
+        else
+        {
+            $tpl->assign_by_ref( 'commandDebug' , $this->commandDebug);
+            $tpl->assign_by_ref( 'commandRelease' , $this->commandRelease);
+            $tpl->assign_by_ref( 'commandOptimized' , $this->commandOptimized);
+        }
+
+        $tpl->assign_by_ref( 'argsDebug' , $this->argsDebug);
+        $tpl->assign_by_ref( 'argsRelease' , $this->argsRelease);
+        $tpl->assign_by_ref( 'argsOptimized' , $this->argsOptimized);
+                
+        $ptypes = array();
+        $projectDepends = array();
+        
+        foreach ($this->dependencies as $pname)
+        {          
+          $p = Generator::lookupProjectByName( $pname );
+          $projectDepends[$pname] = $p;
+          
+          if ( $p )
+            $ptypes[$pname] = $p->isSharedLib() || $p->isSafari();
+        }
+        
+        $tpl->assign_by_ref( 'projTypes',   $ptypes );
+        $tpl->assign_by_ref( 'projectDepends',   $projectDepends );
+          
+        // Assign some handy paths for the template to reference
+        $tpl->assign( 'projectOffset', $output->project_rel_path );
+        
+        if ( Generator::$absPath )
+           $tpl->assign( 'srcDir', Generator::$absPath . "/". str_replace("../", "", getAppEngineSrcDir()) );
+        else
+           $tpl->assign( 'srcDir', $output->project_rel_path . getAppEngineSrcDir() );
+           
+        if ( Generator::$absPath )
+           $tpl->assign( 'libDir', Generator::$absPath . "/". str_replace("../", "", getAppLibSrcDir()) );
+        else
+           $tpl->assign( 'libDir', $output->project_rel_path . getAppLibSrcDir() );
+        
+        if ( Generator::$absPath )
+           $tpl->assign( 'binDir', Generator::$absPath . "/". str_replace("../", "", getAppEngineBinDir()) );
+        else
+           $tpl->assign( 'binDir', $output->project_rel_path . getAppEngineBinDir() );
+           
+        $tpl->assign( 'uniformOutputFile', $this->uniformOutputFile);                
+    }
+        
+    
+    private function conditionDirectories( $output, &$projectFiles )
+   {
+      foreach ($this->includes as &$include)
+      {
+         if ( !FileUtil::isAbsolutePath( $include ) )
+            $include = $output->project_rel_path . $include;
+      }
+       
+      foreach ($this->lib_dirs as &$libDirs)
+      {
+         if ( !FileUtil::isAbsolutePath( $libDirs ) )
+            $libDirs = $output->project_rel_path . $libDirs;
+      }
+
+       if ( Generator::$absPath )
+       {
+          foreach ($this->includes as &$include)
+          {
+             if ( stristr($include, getEngineSrcDir()) || stristr($include, getLibSrcDir()) )
+               $include = Generator::$absPath . "/". str_replace("../", "", $include);
+          }
+             
+          foreach ($this->lib_dirs as &$libDirs)
+          {
+             if ( stristr($libDirs, getEngineSrcDir()) || stristr($libDirs, getLibSrcDir()) )
+                $libDirs = Generator::$absPath . "/". str_replace("../", "", $libDirs);
+          }
+       }
+    }
+
+    public function generate( $tpl, $platform, $base_dir )
+    {
+        // Alright, for each project scan and generate the file list.
+        $projectFiles    = array ();
+        $rootPhpBuildDir = getcwd();
+
+        // Iterate over this project's outputs.
+        foreach( $this->outputs as $outputName => $output )
+        {
+            $saved_includes = $this->includes;
+            $saved_lib_dirs = $this->lib_dirs;
+            
+            //print_r( $output );
+
+            // Supported platform?
+            if( !$output->supportsPlatform( $platform ) )
+            {
+                //echo( "      # Skipping output: '$outputName'.\n" );
+
+                continue;
+            }
+
+            // Get to the right working directory (first go back to root, then to relative)
+            chdir( $base_dir );
+
+            //echo( "      - Changing CWD to " . $output->output_dir . "\n" );
+            // echo("        (From: " . getcwd() . ")\n");
+
+            if( !FileUtil::prepareOutputDir( $output->output_dir ) )
+                continue;
+
+            //echo( "      - Scanning directory for output  '.$outputName.'...\n" );
+
+            if( !$this->generateFileList( $projectFiles, $outputName, $output ) )
+            {
+                echo( "File list generation failed. Giving up on this project.\n" );
+
+                continue;
+            }
+
+            // Do any special work on the include/lib directories that we need
+            $this->conditionDirectories( $output, $projectFiles[ $this->name ] );
+            
+            $this->projectFileExt = $output->output_ext;
+            
+            if ( $this->isCSProject() )
+              $this->projectFileExt = ".csproj"; // always csproj C# project under VS/MonoDevelop
+
+            $outfile = $output->project_dir . $this->name . $this->projectFileExt;
+
+            echo( "      o Writing project file " . $outfile . "\n" );
+
+            $this->setTemplateParams( $tpl, $output, $projectFiles[ $this->name ] );
+            // To put a bandaid on the tools/player output dir problem
+            // CodeReview: This should be in the template. -- BJG, 3/13/2007
+            // Moved into templates -- neo
+
+            // Write file
+            $outdir = dirname( $outfile );
+
+            if( !file_exists( $outdir ) )
+                mkdir_r( $outdir, 0777 );
+
+            if( $hdl = fopen( $outfile, 'w' ) )
+            {
+                if ($this->isApp())
+                   $template = $output->template_app;
+                else if ($this->isLib())
+                   $template = $output->template_lib;
+                else if ($this->isSharedLib())
+                   $template = $output->template_shared_lib;
+                else if ($this->isSharedApp())
+                   $template = $output->template_shared_app;
+                else if ($this->isActiveX())
+                   $template = $output->template_activex;
+                else if ($this->isSafari())
+                   $template = $output->template_activex; //rename template?
+                else if ($this->isCSProject())
+                  $template = $output->template_csproj;
+
+                fputs( $hdl, $tpl->fetch( $template ) );
+
+                fclose( $hdl );
+            }
+            else
+                trigger_error( "Could not write output file: " . $output->outputFile, E_USER_ERROR );
+                            
+            if ($output->template_user)
+            {
+            
+                $outfile = $output->project_dir . $this->name . $this->projectFileExt .'.'.getenv("COMPUTERNAME").'.'.getenv("USERNAME").'.user';
+                
+                if( !file_exists( $outfile ) )
+                {
+                    if( $hdl = fopen( $outfile, 'w' ) )
+                    {
+                        $template = $output->template_user;
+                        fputs( $hdl, $tpl->fetch( $template ) );
+                        fclose( $hdl );
+                    }
+                    else
+                        trigger_error( "Could not write output file: " . $outfile, E_USER_ERROR );
+                }
+               
+            }
+
+            // Build the .filters file used by VS2010.
+            if ( $output->template_filter )
+            {
+               $filterData = new FilterData();
+               array_walk( $projectFiles[ $this->name ], array($filterData, 'callback'), '' );
+
+               $tpl->assign_by_ref('Folders', $filterData->folders);
+               $tpl->assign_by_ref('SrcFiles', $filterData->srcFiles);
+               $tpl->assign_by_ref('IncFiles', $filterData->incFiles);
+               $tpl->assign_by_ref('OtherFiles', $filterData->otherFiles);
+               $tpl->register_function( 'gen_uuid', 'gen_uuid' );
+
+               $outfile = $output->project_dir . $this->name . $this->projectFileExt . '.filters';
+               if ( $hdl = fopen( $outfile, 'w' ) )
+               {
+                  fputs( $hdl, $tpl->fetch( $output->template_filter ) );
+                  fclose( $hdl );
+               }
+            }
+
+            $this->includes = $saved_includes;
+            $this->lib_dirs = $saved_lib_dirs;
+        }
+    }
+}
+
+
+class FilterData
+{
+   public $folders = array();
+   public $srcFiles = array();
+   public $incFiles = array();
+   public $otherFiles = array();
+
+   public function callback( $value, $key, $dir )
+   {
+      if ( is_array( $value ) )
+      {
+         if ( $dir != '' )
+            $dirpath = $dir . '\\' . $key;
+         else
+            $dirpath = $key;
+
+         array_push( $this->folders, $dirpath );
+         array_walk( $value, array($this, 'callback'), $dirpath );
+         return;
+      }
+
+      $path = str_replace( '/', '\\', $value->path );
+
+      $ext = strrchr( $path, '.' );
+      if ( $ext == FALSE )
+         return;
+
+      if (  strcasecmp( $ext, '.c' ) == 0 ||
+            strcasecmp( $ext, '.cpp' ) == 0 ||
+            strcasecmp( $ext, '.cc' ) == 0 )
+         $this->srcFiles[$path] = $dir;
+
+      else if (   strcasecmp( $ext, '.h' ) == 0 ||
+                  strcasecmp( $ext, '.hpp' ) == 0 ||
+                  strcasecmp( $ext, '.inl' ) == 0 )
+         $this->incFiles[$path] = $dir;
+
+      else
+         $this->otherFiles[$path] = $dir;
+
+   }
+
+} // class FilterData
+
+?>

+ 111 - 0
Tools/projectGenerator/classes/SafariWebPlugin.php

@@ -0,0 +1,111 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+class SafariWebPlugin
+{
+   var $FOLDER = "";
+   var $GAMEFOLDER = "";
+   var $PLUGINNAME = "";
+   var $MIMETYPE = "";
+   var $DESCRIPTION = "";
+   var $IDENTIFIER = "";
+   var $BUNDLE = "";
+   var $VERSION = "";
+   
+   function SafariWebPlugin()
+   {
+      $rootPhpBuildDir = getcwd();
+
+      $this->FOLDER = $rootPhpBuildDir."/web/source/npplugin/mac/";
+      $this->GAMEFOLDER = $rootPhpBuildDir."/game/";
+      
+      $this->PLUGINNAME = WebDeploymentOSX::$safariPluginName;
+      $this->MIMETYPE = WebDeploymentOSX::$mimeType;
+      
+      $this->VERSION = WebDeploymentOSX::$version;
+
+      $this->DESCRIPTION = WebDeploymentOSX::$description." ".$this->VERSION ;      
+
+      $this->BUNDLE = WebDeploymentOSX::$safariPluginName;
+      $this->IDENTIFIER = WebDeploymentOSX::$identifier;
+   }
+   
+   function process($project)
+   {
+      
+      $this->processTemplates();
+      
+
+   }
+   
+   function readTemplate($filename)
+   {
+      $filename = realpath( dirname( $_SERVER[ 'PHP_SELF' ] ) ). "/templates/web/".$filename;
+      $fh = fopen($filename, 'r');
+      $data = fread($fh, filesize($filename));
+      fclose($fh);
+      return $data;
+   }
+   
+   function writeFile($filename, $data)
+   {
+      $filename = $this->FOLDER . $filename;
+
+      echo($filename);
+      
+      $fh = fopen($filename, 'w');
+      fwrite($fh, $data);
+      fclose($fh);
+   }
+
+   function writeGameFile($filename, $data)
+   {
+      $filename = $this->GAMEFOLDER . $filename;
+      $fh = fopen($filename, 'w');
+      fwrite($fh, $data);
+      fclose($fh);
+   }
+
+   function processTemplates()
+   {
+
+      $data =  $this->readTemplate("safari_Info_plist.tpl");
+      $data = str_replace("__CFBundleExecutable__", $this->BUNDLE, $data);
+      $data = str_replace("__CFBundleIdentifier__", $this->IDENTIFIER, $data);
+      $data = str_replace("__WebPluginDescription__", $this->DESCRIPTION, $data);
+      $data = str_replace("__WebPluginMIMEType__", "application/".$this->MIMETYPE, $data);
+      $data = str_replace("__WebPluginName__", $this->PLUGINNAME, $data);      
+
+      $data = str_replace("__GameName__", getGameProjectName(), $data);
+
+      //TODO: handled by Toolbox
+      $data = str_replace("__GameInstallPath__", $this->GAMEFOLDER, $data);
+
+      $this->writeFile('Info.plist', $data);
+      
+      WebPlugin::processNPPlugin($this);
+   }
+   
+}
+
+?>

+ 159 - 0
Tools/projectGenerator/classes/Solution.php

@@ -0,0 +1,159 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+//
+//	Solution info container
+//
+class Solution
+{
+	public $name;
+	public $guid;
+	public $project_refs = array();
+    public $project_extRefs = array();
+	public $outputs		 = array();
+	
+	public function Solution( $name, $guid, $outputs = null )
+	{
+	    $this->name = $name;
+	    $this->guid = $guid;
+	    
+	  	$this->setOutputs( $outputs );
+	}
+	
+	public function addProjectRef( $pname )
+	{
+	    array_push( $this->project_refs, $pname );
+	}
+    
+    public function addSolutionProjectRefExt( $pname, $ppath, $pguid )
+    {
+        $v = array();
+        $v[0] = $ppath;
+        $v[1] = $pguid;
+        // This is the project GUID for a C# project
+        // TODO: Add support for C++ projects if need to add them
+        // as an external project, to date this hasn't been necessary
+        $v[2] = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}";
+        $this->project_extRefs[$pname] = $v;
+    }
+	
+	public function setOutputs( $outputs )
+	{
+	    if( isset( $outputs ) )
+	    	$this->outputs = array_merge( $this->outputs, $outputs );
+	}
+	
+	public function generate( $tpl, $platform, $root_dir )
+	{
+		// Project container for templates
+		$projects = array();
+        $refs = array();
+        
+        // make sure that startup project is the first in the solution
+        
+        if (getGameProjectName())
+            array_push( $refs, getGameProjectName() );
+        
+        foreach( $this->project_refs as $pname )
+        {
+            if (getGameProjectName() && $pname == getGameProjectName())
+                continue;
+               
+            array_push( $refs, $pname );
+        }
+
+		// Look up each project ref and add its info to the list
+		foreach( $refs as $pname ) 
+		{
+			$project = Generator::lookupProjectByName( $pname );
+	
+			if( isset( $project ) )
+			{
+				echo( "      - project ref: " . $pname . " = " . $project->guid . "\n" );    
+			
+				array_push( $projects, $project );
+                
+        // Let the project update any dependencies
+        $project->validateDependencies(); 												
+			}
+			else
+				trigger_error( "Solution::generate() - project ref not found: " . $pname . "\n", E_USER_ERROR );
+		}
+		
+		// No use going forward if there were no projects for this solution is there?
+		// (Would we ever want to generate an empty solution at all?)
+		if( count( $projects ) == 0 )
+		{
+		    echo( "Solution::generate() - no project refs found for solution: " . $this->name . "\n" );
+		    
+		    continue;
+		}
+		
+		// 
+		//sort( $projects );
+		
+		// Set smarty params that dont change during loop once here
+		$tpl->assign_by_ref( "solution_guid",	$this->guid );
+		$tpl->assign_by_ref( "projects", 		$projects );
+        $tpl->assign_by_ref( "projectExtRefs",  $this->project_extRefs );
+		
+		// Generate a solution file for all outputs for this solution
+		foreach( $this->outputs as $output )
+		{
+         // Supported platform?
+         if( !$output->supportsPlatform( $platform ) )
+         {
+             //echo( "      # Skipping output: '$outputName'.\n" );
+
+             continue;
+         }
+      
+		    // Reset to base dir
+		    chdir( $root_dir );
+		    
+		    // Then offset
+		    if( !FileUtil::prepareOutputDir( $output->output_dir ) || !$output->template_sln )
+				continue;
+		    
+			$outfile = $this->name . $output->solution_ext;			    
+		
+			echo( "   - Writing solution file: " . $output->output_dir . "/" . $outfile );    
+		
+			// Project filenames are <projectname>.<outputext> where ext is set per output.
+			// The template builds each project output using the project name and this ext. 			
+			$tpl->assign_by_ref( "project_ext", $output->output_ext );
+					
+			if( $f = fopen( $outfile, 'w' ) ) 
+			{					
+				fputs( $f, $tpl->fetch( $output->template_sln ) );
+
+				fclose( $f );
+				
+				echo( " - success " . "\n" );
+			} 
+			else
+				trigger_error( "\nCould not write output file: " . $outfile, E_USER_ERROR );
+		}
+	}
+}
+?>

+ 267 - 0
Tools/projectGenerator/classes/Torque3D.php

@@ -0,0 +1,267 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+// This class wraps up some project generator specific stuff for the Torque 3D project itself
+// simplifying the per project setup, while still allowing the engine to have modules plugged in
+
+class Torque3D
+{
+    static $sharedConfig = true;
+    static $projectName = "";
+    
+    static function includeDefaultLibs()
+    {
+        // Libs
+        includeLib( 'mng' );
+        includeLib( 'png' );
+        includeLib( 'ungif' );
+        includeLib( 'zlib' );
+        includeLib( 'jpeg' );
+        includeLib( 'tinyxml' );
+        includeLib( 'opcode' );
+        includeLib( 'squish' );
+        includeLib( 'collada_dom' );
+        includeLib( 'pcre' ); 
+        includeLib( 'convexDecomp' ); 
+
+        // Use FMOD on consoles
+        if ( Generator::$platform != "360" && Generator::$platform != "ps3" )
+        {
+           includeLib( 'libvorbis' );
+           includeLib( 'libogg' );
+           includeLib( 'libtheora' );
+        }    
+    }
+    
+    static function beginConfig( $platform, $projectName )
+    {
+        
+        setPlatform( $platform );
+
+        beginProject( $projectName, self::$sharedConfig );
+        
+        self::includeDefaultLibs();
+        
+        $ext = "DLL";
+        if ( Generator::$platform == "mac" )
+            $ext = "Bundle";
+   
+
+        //some platforms will not want a shared config        
+        if ( Generator::$platform == "360" || Generator::$platform == "ps3" )
+            self::$sharedConfig = false;
+
+        //begin either a shared lib config, or a static app config
+        if ( self::$sharedConfig )
+            beginSharedLibConfig( getGameProjectName().' '.$ext, '{C0FCDFF9-E125-412E-87BC-2D89DB971CAB}', 'game', getGameProjectName() );
+        else
+            beginAppConfig( getGameProjectName(), '{C0FCDFF9-E125-412E-87BC-2D89DB971CAB}', 'game', getGameProjectName() );
+        
+        /// Prefs
+        addProjectDefine( 'TORQUE_SHADERGEN' );
+        addProjectDefine( 'TORQUE_UNICODE' );
+        
+        if ( self::$sharedConfig )
+           addProjectDefine( 'TORQUE_SHARED' );    
+
+        /// For OPCODE
+        addProjectDefine( 'BAN_OPCODE_AUTOLINK' );
+        addProjectDefine( 'ICE_NO_DLL' );
+        addProjectDefine( 'TORQUE_OPCODE' );
+
+        // For libTomCrypt
+        addProjectDefine( 'LTC_NO_PROTOTYPES' );
+        
+        // Additional includes
+        addIncludePath( "../../game/shaders" );
+        
+        addLibIncludePath( "lmng" );
+        addLibIncludePath( "lpng" );
+        addLibIncludePath( "ljpeg" );
+        addLibIncludePath( "lungif" );
+        addLibIncludePath( "zlib" );
+        addLibIncludePath( "tinyxml" );
+        addLibIncludePath( "opcode" );
+        addLibIncludePath( "squish" );
+        addLibIncludePath( 'convexDecomp' ); 
+        
+        if ( Generator::$platform != "360" && Generator::$platform != "ps3" )
+        {
+          addLibIncludePath( "libvorbis/include" );
+          addLibIncludePath( "libogg/include" );
+          addLibIncludePath( "libtheora/include" );
+        }
+        
+        // Modules
+        includeModule( 'core' );
+        includeModule( 'dsound' );
+        //includeModule( 'fmod'); // FMOD support removed until made as a 3rd party library
+        includeModule( 'T3D' );
+        includeModule( 'advancedLighting' );
+        includeModule( 'basicLighting' );
+        includeModule( 'collada' );
+        
+        if ( Generator::$platform != "360" && Generator::$platform != "ps3" )
+        {
+          includeModule( 'vorbis' );
+          includeModule( 'theora' );
+        }
+       
+        if(Generator::$platform == "mac" || Generator::$platform == "win32")
+           includeModule( 'openal' );
+
+   
+        // Dependencies
+        
+        addProjectDependency( 'lmng' );
+        addProjectDependency( 'lpng' );
+        addProjectDependency( 'lungif' );
+        addProjectDependency( 'ljpeg' );
+        addProjectDependency( 'zlib' );
+        addProjectDependency( 'tinyxml' );
+        addProjectDependency( 'opcode' );
+        addProjectDependency( 'squish' );
+        addProjectDependency( 'collada_dom' );
+        addProjectDependency( 'pcre' );
+        addProjectDependency( 'convexDecomp' ); 
+        
+        if ( Generator::$platform != "360" && Generator::$platform != "ps3" )
+        {
+          addProjectDependency( 'libvorbis' );
+          addProjectDependency( 'libogg' );
+          addProjectDependency( 'libtheora' );
+        }
+        
+        if ( Generator::$platform == "mac" )
+        {    
+            addProjectDefine( '__MACOSX__' );
+            addProjectDefine( 'LTM_DESC' );
+        }
+
+        if (Generator::$platform == "win32")
+        {
+            setProjectModuleDefinitionFile('../../' . getLibSrcDir() . 'Torque3D/msvc/torque3d.def');
+
+            addProjectDefine( 'UNICODE' );
+            addProjectDefine( 'INITGUID' );
+            addProjectDefine( '_CRT_SECURE_NO_DEPRECATE' );
+            
+
+            addProjectLibInput('COMCTL32.LIB');
+            addProjectLibInput('COMDLG32.LIB');
+            addProjectLibInput('USER32.LIB');
+            addProjectLibInput('ADVAPI32.LIB');
+            addProjectLibInput('GDI32.LIB');
+            addProjectLibInput('WINMM.LIB');
+            addProjectLibInput('WSOCK32.LIB');
+            addProjectLibInput('vfw32.lib');
+            addProjectLibInput('Imm32.lib');
+            addProjectLibInput('d3d9.lib');
+            addProjectLibInput('d3dx9.lib');
+            addProjectLibInput('DxErr.lib');
+            addProjectLibInput('ole32.lib');
+            addProjectLibInput('shell32.lib');
+            addProjectLibInput('oleaut32.lib');
+            addProjectLibInput('version.lib');
+        }
+        
+        // Include project specific sources in the project/buildFiles/config/projectCode.conf
+        $projectCode = realpath($argv[1])."/buildFiles/config/projectCode.conf";
+        echo( "\n   - Loading project code configuration from ".$projectCode."\n");
+        include $projectCode;
+    }
+    
+    static function endConfig()
+    {
+        //end shared/static config
+        if ( self::$sharedConfig )
+           endSharedLibConfig();
+        else
+           endAppConfig();
+
+        //add the shared application only if this is a shared config
+        if ( self::$sharedConfig )
+        {
+            /////// Application Config
+            beginSharedAppConfig( getGameProjectName(), '{CDECDFF9-E125-523F-87BC-2D89DB971CAB}' );
+
+                addProjectDefine( 'TORQUE_SHARED' );
+
+                addEngineSrcDir( 'main' );
+                
+                if (Generator::$platform == "win32")
+                {
+                    addProjectDefine( 'WIN32' );
+                    addProjectDependency( getGameProjectName() . ' DLL' );
+                }
+
+                if (Generator::$platform == "mac")
+                {
+                    addProjectDefine( '__MACOSX__' );
+                    addProjectDependency( getGameProjectName() . ' Bundle' );
+                    addProjectDependency( getGameProjectName() . ' Plugin' );
+                }
+
+            endSharedAppConfig();
+        }
+        
+        // Add solution references for Visual Studio projects
+        if (Generator::$platform == "win32" || Generator::$platform == "360" || Generator::$platform == "ps3")
+        {
+           if ( !self::$sharedConfig )
+              beginSolutionConfig( getGameProjectName(), '{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}' );
+              
+              addSolutionProjectRef( getGameProjectName() );
+              if ( self::$sharedConfig )
+                 addSolutionProjectRef( getGameProjectName() . ' DLL' );
+                 
+              addSolutionProjectRef( 'collada_dom' );
+              addSolutionProjectRef( 'ljpeg' );
+              addSolutionProjectRef( 'lmng' );
+              addSolutionProjectRef( 'lpng' );
+              addSolutionProjectRef( 'lungif' );
+              addSolutionProjectRef( 'opcode' );
+              addSolutionProjectRef( 'pcre' );
+              addSolutionProjectRef( 'squish' );
+              addSolutionProjectRef( 'tinyxml' );
+              addSolutionProjectRef( 'zlib' );
+              addSolutionProjectRef( 'convexDecomp' ); 
+              
+              if (Generator::$platform == "win32")
+              {
+                 addSolutionProjectRef( 'libogg' );
+                 addSolutionProjectRef( 'libvorbis' );
+                 addSolutionProjectRef( 'libtheora' );
+              }
+              
+           if ( !self::$sharedConfig )
+              endSolutionConfig();
+        }
+        
+        endProject(self::$sharedConfig);
+        
+    }
+        
+}
+
+?>

+ 85 - 0
Tools/projectGenerator/classes/WebPlugin.php

@@ -0,0 +1,85 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+// settings/logic shared by plugins
+
+class WebPlugin
+{
+   static $SAMPLE_HTML = "";
+   static $GAME_FOLDER = "";
+   
+   static function readTemplate()
+   {
+      $filename = realpath( dirname( $_SERVER[ 'PHP_SELF' ] ) ). "/templates/web/sample_html.tpl";
+      $fh = fopen($filename, 'r');
+      $data = fread($fh, filesize($filename));
+      fclose($fh);
+      
+      if (!$data)
+        trigger_error( "WebPlugin::readTemplate() - cannot read HTML template!", E_USER_ERROR );
+      
+      self::$SAMPLE_HTML = $data;
+   }
+   
+   static function processNPPlugin($np)
+   {
+   
+      if (!self::$SAMPLE_HTML)
+         self::readTemplate();
+         
+      $rootPhpBuildDir = getcwd();      
+      self::$GAME_FOLDER = $rootPhpBuildDir."/game/";
+
+      self::$SAMPLE_HTML = str_replace("__MIMETYPE__", $np->MIMETYPE, self::$SAMPLE_HTML);
+      
+   }
+
+   static function processActiveXPlugin($ax)
+   {
+      if (!self::$SAMPLE_HTML)
+        self::readTemplate();   
+
+      $rootPhpBuildDir = getcwd();      
+      self::$GAME_FOLDER = $rootPhpBuildDir."/game/";
+      
+      $projID = $ax->WEBGAME_PLUGINNAME.'.'.$ax->WEBGAME_CTRLNAME.'.'.'1';
+      
+      self::$SAMPLE_HTML = str_replace("__PROJID__", $projID, self::$SAMPLE_HTML);
+      self::$SAMPLE_HTML = str_replace("__CLSID__", $ax->WEBGAMELIB_UUID, self::$SAMPLE_HTML);
+      
+    }
+   
+   static function writeSampleHtml()
+   {
+      // no plugins defined
+      if (!self::$SAMPLE_HTML)
+         return;
+         
+      $filename = self::$GAME_FOLDER . "web/sample.html";
+      $fh = fopen($filename, 'w');
+      fwrite($fh, self::$SAMPLE_HTML);
+      fclose($fh);
+   }
+}
+   
+?>

+ 453 - 0
Tools/projectGenerator/classes/WindowsRegistry.php

@@ -0,0 +1,453 @@
+<?php
+/*
+*	b3rtWindowsRegistry 1.0
+*	===========
+*	Class for reading from and writing to the Windows registry
+*
+*	Copyright (c) 2008, H. Poort
+*	All rights reserved.
+*
+*	Redistribution and use in source and binary forms, with or without
+*	modification, are permitted provided that the following conditions are met:
+*	  * 	Redistributions of source code must retain the above copyright
+*		notice, this list of conditions and the following disclaimer.
+*	  *	Redistributions in binary form must reproduce the above copyright
+*		notice, this list of conditions and the following disclaimer in the
+*		documentation and/or other materials provided with the distribution.
+*	  *	The name the copyright holder may not be used to endorse or promote
+*		products derived from this software without specific prior written
+*		permission.
+*
+*	THIS SOFTWARE IS PROVIDED BY H. Poort "AS IS" AND ANY
+*	EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+*	WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+*	DISCLAIMED. IN NO EVENT SHALL H. Poort BE LIABLE FOR ANY
+*	DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+*	(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+*	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+*	ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+*	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+*	SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+class WindowsRegistry 
+{
+	private $RegistryObject;
+
+	const HKEY_CLASSES_ROOT = 0x80000000;
+	const HKEY_CURRENT_USER = 0x80000001;
+	const HKEY_LOCAL_MACHINE = 0x80000002;
+	const HKEY_USERS = 0x80000003;
+	const HKEY_CURRENT_CONFIG = 0x80000005;
+
+	const REG_NONE = 0;
+	const REG_SZ = 1;
+	const REG_EXPAND_SZ = 2;
+	const REG_BINARY = 3;
+	const REG_DWORD = 4;
+	const REG_MULTI_SZ = 7;
+
+	public function __construct()
+	{
+		/*$this->WbemLocator = new COM('WbemScripting.SWbemLocator');
+		$this->WbemServices = $this->WbemLocator->ConnectServer('.', '/root/default');
+		$this->WbemServices->Security_->ImpersonationLevel = 0x3;
+		$this->RegObject = $this->WbemServices->Get('StdRegProv');*/
+
+		// Get the WMI StdRegProv class
+		try
+		{
+			$this->RegistryObject = new COM('WINMGMTS:{impersonationLevel=impersonate}!//./root/default:StdRegProv');
+		}
+		catch (Exception $ex)
+		{
+			$this->RegistryObject = NULL;
+			throw new Exception('Could not get a connection to the registry.');
+		}
+	}
+
+	public function __destruct()
+	{
+		unset($this->RegistryObject);
+	}
+
+	public function ReadValue($keyPath, $valueName, $asString = FALSE)
+	{
+		$hKeyId = 0;
+		$subKey = '';
+		if (!$this->SplitKeyPath($keyPath, $hKeyId, $subKey))
+			return NULL;
+
+		$valueType = $this->GetValueType($hKeyId, $subKey, $valueName);
+		if (-1 == $valueType)
+			return NULL;
+
+		switch ($valueType)
+		{
+			case self::REG_NONE: // No support for REG_NONE
+				return NULL;
+			case self::REG_SZ:
+				return $this->GetStringValue($hKeyId, $subKey, $valueName);
+			case self::REG_EXPAND_SZ:
+				return $this->GetExpandedStringValue($hKeyId, $subKey, $valueName);
+			case self::REG_BINARY:
+				return $this->GetBinaryValue($hKeyId, $subKey, $valueName, $asString);
+			case self::REG_DWORD:
+				return $this->GetDWORDValue($hKeyId, $subKey, $valueName, $asString);
+			case self::REG_MULTI_SZ:
+				return $this->GetMultiStringValue($hKeyId, $subKey, $valueName, $asString);
+		}
+	}
+
+	public function WriteValue($keyPath, $valueName, $valueContents, $forceType = -1)
+	{
+		$hKeyId = 0;
+		$subKey = '';
+		if (!$this->SplitKeyPath($keyPath, $hKeyId, $subKey))
+			return FALSE;
+
+		if (!$this->CreateKey($keyPath))
+			return FALSE;
+
+		if (-1 != $forceType)
+			$valueType = $forceType;
+		else
+			$valueType = $this->GetValueType($hKeyId, $subKey, $valueName);
+
+		if (self::REG_NONE == $valueType) // No support for REG_NONE
+			return FALSE;
+
+		if (-1 == $valueType) // valueType unknown
+		{
+			if (is_string($valueContents))
+				$valueType = self::REG_SZ;
+			else if (is_int($valueContents))
+				$valueType = self::REG_DWORD;
+			else if (is_array($valueContents) && count($valueContents))
+			{
+				if (is_string($valueContents[0]))
+					$valueType = self::REG_MULTI_SZ;
+				else if (is_int($valueContents[0]))
+					$valueType = self::REG_BINARY;
+			}
+		}
+		if (-1 == $valueType) // valueType still unknown, leave
+			return FALSE;
+
+		$result = -1;
+
+		if ((self::REG_SZ == $valueType) || (self::REG_EXPAND_SZ == $valueType))
+		{
+			//if (!is_string($valueContents))
+			//	$valueContents = strval($valueContents);
+				
+			if (self::REG_SZ == $valueType)
+				$result = $this->RegistryObject->SetStringValue($hKeyId, $subKey, $valueName, $valueContents);
+			else
+				$result = $this->RegistryObject->SetExpandedStringValue($hKeyId, $subKey, $valueName, $valueContents);
+		}
+		else if (self::REG_DWORD == $valueType)
+		{
+			//if (!is_int($valueContents))
+			//	$valueContents = intval($valueContents);
+
+			$result = $this->RegistryObject->SetDWORDValue($hKeyId, $subKey, $valueName, $valueContents);
+		}
+		else if (self::REG_MULTI_SZ == $valueType)
+		{
+			if (!is_array($valueContents) || !is_string($valueContents[0]))
+				return FALSE;
+
+			$result = $this->RegistryObject->SetMultiStringValue($hKeyId, $subKey, $valueName, $valueContents);
+		}
+		else if (self::REG_BINARY == $valueType)
+		{
+			if (!is_array($valueContents) || !is_int($valueContents[0]))
+				return FALSE;
+
+			$result = $this->RegistryObject->SetBinaryValue($hKeyId, $subKey, $valueName, $valueContents);
+		}
+
+		return (0 == $result);
+	}
+
+	public function DeleteValue($keyPath, $valueName)
+	{
+		$hKeyId = 0;
+		$subKey = '';
+		if (!$this->SplitKeyPath($keyPath, $hKeyId, $subKey))
+			return FALSE;
+
+		return ($this->RegistryObject->DeleteValue($hKeyId, $subKey, $valueName) == 0);
+	}
+
+	public function GetValueNames($keyPath, $includeTypes = FALSE)
+	{
+		$hKeyId = 0;
+		$subKey = '';
+		if (!$this->SplitKeyPath($keyPath, $hKeyId, $subKey))
+			return FALSE;
+
+		$valueList = array();
+		if (!$this->EnumValues($hKeyId, $subKey, $valueList))
+			return NULL;
+
+		if (!$includeTypes)
+		{
+			$valueNames = array();
+			for ($i = 0, $cnt = count($valueList); $i < $cnt; $i++)
+				$valueNames[] = $valueList[$i][0];
+			return $valueNames;
+		}
+		else
+			return $valueList;
+	}
+
+	public function CreateKey($keyPath)
+	{
+		$hKeyId = 0;
+		$subKey = '';
+		if (!$this->SplitKeyPath($keyPath, $hKeyId, $subKey))
+			return FALSE;
+
+		return ($this->RegistryObject->CreateKey($hKeyId, $subKey) == 0);
+	}
+
+	public function DeleteKey($keyPath, $deleteSubkeys = FALSE)
+	{
+		$hKeyId = 0;
+		$subKey = '';
+		if (!$this->SplitKeyPath($keyPath, $hKeyId, $subKey))
+			return FALSE;
+
+		if (!$deleteSubkeys)
+			return ($this->RegistryObject->DeleteKey($hKeyId, $subKey) == 0);
+		else
+		{
+			if (!function_exists('deleteSubKeysRecursive'))
+			{
+				function deleteSubKeysRecursive(&$thisRef, $hKeyId, $subKey)
+				{
+					$mapHkeysToString = array(
+						WindowsRegistry::HKEY_CLASSES_ROOT => 'HKEY_CLASSES_ROOT',
+						WindowsRegistry::HKEY_CURRENT_USER => 'HKEY_CURRENT_USER',
+						WindowsRegistry::HKEY_LOCAL_MACHINE => 'HKEY_LOCAL_MACHINE',
+						WindowsRegistry::HKEY_USERS => 'HKEY_USERS',
+						WindowsRegistry::HKEY_CURRENT_CONFIG => 'HKEY_CURRENT_CONFIG');
+
+					if (!isset($mapHkeysToString[$hKeyId]))
+						return FALSE;
+
+					$subKeys = $thisRef->GetSubKeys($mapHkeysToString[$hKeyId] . '\\' . $subKey);
+					if ($subKeys)
+					{
+						for ($i = 0, $cnt = count($subKeys); $i < $cnt; $i++)
+						{
+							if (!deleteSubKeysRecursive($thisRef, $hKeyId, $subKey . '\\' . $subKeys[$i]))
+								return FALSE;
+						}
+					}
+
+					return ($thisRef->DeleteKey($mapHkeysToString[$hKeyId] . '\\' . $subKey));
+				}
+			}
+
+			return deleteSubKeysRecursive($this, $hKeyId, $subKey);
+		}
+	}
+
+	public function GetSubKeys($keyPath)
+	{
+		$hKeyId = 0;
+		$subKey = '';
+		if (!$this->SplitKeyPath($keyPath, $hKeyId, $subKey))
+			return FALSE;
+
+		$keyList = array();
+		if (!$this->EnumKeys($hKeyId, $subKey, $keyList))
+			return NULL;
+
+		return $keyList;
+	}
+
+	public function KeyExists($keyPath)
+	{
+		$hKeyId = 0;
+		$subKey = '';
+		if (!$this->SplitKeyPath($keyPath, $hKeyId, $subKey))
+			return FALSE;
+
+		return ($this->RegistryObject->EnumValues($hKeyId, $subKey, new VARIANT(), new VARIANT()) == 0);
+	}
+
+	// PRIVATE FUNCTIONS
+	// ================================
+	private function SplitKeyPath($keyPath, &$hKeyIdResult, &$subKeyResult)
+	{
+		$hKeyIdResult = 0;
+		$subKeyResult = 'foo';
+
+		$splitPath = explode('\\', $keyPath, 2);
+
+		if (FALSE === $splitPath)
+			return FALSE;
+		else if (count($splitPath) == 1)
+			$splitPath[1] = '';
+
+		$subKeyResult = $splitPath[1];
+
+		switch ($splitPath[0])
+		{
+			case 'HKEY_CLASSES_ROOT':
+				$hKeyIdResult = self::HKEY_CLASSES_ROOT;
+				break;
+			case 'HKEY_CURRENT_USER':
+				$hKeyIdResult = self::HKEY_CURRENT_USER;
+				break;
+			case 'HKEY_LOCAL_MACHINE':
+				$hKeyIdResult = self::HKEY_LOCAL_MACHINE;
+				break;
+			case 'HKEY_USERS':
+				$hKeyIdResult = self::HKEY_USERS;
+				break;
+			case 'HKEY_CURRENT_CONFIG':
+				$hKeyIdResult = self::HKEY_CURRENT_CONFIG;
+				break;
+			default:
+				return FALSE;
+		}
+
+		return TRUE;
+	}
+
+	private function EnumKeys($hKeyId, $subKey, &$keyList)
+	{
+		$keyNames = new VARIANT();
+		if ($this->RegistryObject->EnumKey($hKeyId, $subKey, $keyNames) != 0)
+			return FALSE;
+
+		$keyList = array();
+
+		if (variant_get_type($keyNames) == (VT_VARIANT | VT_ARRAY))
+		{
+			for ($i = 0, $cnt = count($keyNames); $i < $cnt; $i++)
+				$keyList[] = strval($keyNames[$i]);
+		}
+
+		return TRUE;
+	}
+
+	private function EnumValues($hKeyId, $subKey, &$valueList)
+	{
+		$valueNames = new VARIANT();
+		$valueTypes = new VARIANT();
+
+		if ($this->RegistryObject->EnumValues($hKeyId, $subKey, $valueNames, $valueTypes) != 0)
+			return FALSE;
+
+		$valueList = array();
+
+		if (variant_get_type($valueNames) == (VT_VARIANT | VT_ARRAY))
+		{
+			for ($i = 0, $cnt = count($valueNames); $i < $cnt; $i++)
+				$valueList[] = array(strval($valueNames[$i]), intval($valueTypes[$i]));
+		}
+		else // Handle a bug in StdRegProv's EnumValues (http://groups.google.com/group/microsoft.public.win32.programmer.wmi/browse_thread/thread/d74c0ca865887e6b)
+		{
+			if ($this->GetStringValue($hKeyId, $subKey, '') != NULL)
+				$valueList[] = array('', self::REG_SZ);
+			else if ($this->GetDWORDValue($hKeyId, $subKey, '') != NULL)
+				$valueList[] = array('', self::REG_DWORD);
+			else if ($this->GetExpandedStringValue($hKeyId, $subKey, '') != NULL)
+				$valueList[] = array('', self::REG_EXPAND_SZ);
+			else if ($this->GetBinaryValue($hKeyId, $subKey, '') != NULL)
+				$valueList[] = array('', self::REG_BINARY);
+			else if ($this->GetMultiStringValue($hKeyId, $subKey, '') != NULL)
+				$valueList[] = array('', self::REG_MULTI_SZ);
+		}
+
+		return TRUE;
+	}
+
+	private function GetValueType($hKeyId, $subKey, $valueName)
+	{
+		$valueList = array();
+		if (!$this->EnumValues($hKeyId, $subKey, $valueList))
+			return -1;
+
+		for ($i = 0, $cnt = count($valueList); $i < $cnt; $i++)
+		{
+			if ($valueList[$i][0] == $valueName)
+				return $valueList[$i][1];
+		}
+
+		return -1;
+	}
+
+	private function GetStringValue($hKeyId, $subKey, $valueName)
+	{
+		$stringValue = new VARIANT();
+		return (($this->RegistryObject->GetStringValue($hKeyId, $subKey, $valueName, $stringValue) == 0) ?
+			strval($stringValue) : NULL);
+	}
+
+	private function GetExpandedStringValue($hKeyId, $subKey, $valueName)
+	{
+		$expandStringValue = new VARIANT();
+		return ((0 == $this->RegistryObject->GetExpandedStringValue($hKeyId, $subKey, $valueName, $expandStringValue)) ?
+			strval($expandStringValue) : NULL);
+	}
+
+	private function GetBinaryValue($hKeyId, $subKey, $valueName, $asString = FALSE)
+	{
+		$binaryValue = new VARIANT();
+		if ($this->RegistryObject->GetBinaryValue($hKeyId, $subKey, $valueName, $binaryValue) != 0)
+			return NULL;
+
+		if ($asString)
+		{
+			$result = '';
+			for ($i = 0, $cnt = count($binaryValue); $i < $cnt; $i++)
+				$result .= dechex($binaryValue[$i]) . ((($cnt - 1) != $i) ? ' ' : '');
+		}
+		else
+		{
+			$result = array();
+			for ($i = 0, $cnt = count($binaryValue); $i < $cnt; $i++)
+				$result .= intval($binaryValue[$i]);
+		}
+
+		return $result;
+	}
+
+	private function GetDWORDValue($hKeyId, $subKey, $valueName, $asString = FALSE)
+	{
+		$dwordValue = new VARIANT();
+		return (($this->RegistryObject->GetDWORDValue($hKeyId, $subKey, $valueName, $dwordValue) == 0) ?
+			($asString ? strval($dwordValue) : intval($dwordValue)) : NULL);
+	}
+
+	private function GetMultiStringValue($hKeyId, $subKey, $valueName, $asString = FALSE)
+	{
+		$multiStringValue = new VARIANT();
+		if ($this->RegistryObject->GetMultiStringValue($hKeyId, $subKey, $valueName, $multiStringValue) != 0)
+			return NULL;
+
+		if ($asString)
+		{
+			$result = '';
+			for ($i = 0, $cnt = count($multiStringValue); $i < $cnt; $i++)
+				$result .= strval($multiStringValue[$i]) . ((($cnt - 1) != $i) ? "\n" : '');
+		}
+		else
+		{
+			$result = array();
+			for ($i = 0, $cnt = count($multiStringValue); $i < $cnt; $i++)
+				$result[] = strval($multiStringValue[$i]);
+		}
+
+		return $result;
+	}
+}
+?>

+ 895 - 0
Tools/projectGenerator/classes/plist/CFBinaryPropertyList.php

@@ -0,0 +1,895 @@
+<?php
+/**
+ * CFPropertyList
+ * {@link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists}
+ * @author Rodney Rehm <[email protected]>
+ * @author Christian Kruse <[email protected]>
+ * @package plist
+ * @version $Id$
+ */
+
+/**
+ * Facility for reading and writing binary PropertyLists. Ported from {@link http://www.opensource.apple.com/source/CF/CF-476.15/CFBinaryPList.c CFBinaryPList.c}.
+ * @author Rodney Rehm <[email protected]>
+ * @author Christian Kruse <[email protected]>
+ * @package plist
+ * @example example-read-02.php Read a Binary PropertyList
+ * @example example-read-03.php Read a PropertyList without knowing the type
+ */
+abstract class CFBinaryPropertyList {
+  /**
+   * Table containing uniqued objects
+   * @var array
+   */
+  protected $uniqueTable = Array();
+
+  /**
+   * Number of objects in file
+   * @var integer
+   */
+  protected $countObjects = 0;
+
+  /**
+   * The length of all strings in the file (byte length, not character length)
+   * @var integer
+   */
+  protected $stringSize = 0;
+
+  /**
+   * The length of all ints in file (byte length)
+   * @var integer
+   */
+  protected $intSize = 0;
+
+  /**
+   * The length of misc objects (i.e. not integer and not string) in file
+   * @var integer
+   */
+  protected $miscSize = 0;
+
+  /**
+   * Number of object references in file (needed to calculate reference byte length)
+   * @var integer
+   */
+  protected $objectRefs = 0;
+
+  /**
+   * Number of objects written during save phase; needed to calculate the size of the object table
+   * @var integer
+   */
+  protected $writtenObjectCount = 0;
+
+  /**
+   * Table containing all objects in the file
+   */
+  protected $objectTable = Array();
+
+  /**
+   * The size of object references
+   */
+  protected $objectRefSize = 0;
+
+  /**
+   * The „offsets” (i.e. the different entries) in the file
+   */
+  protected $offsets = Array();
+
+  /**
+   * Read a „null type” (filler byte, true, false, 0 byte)
+   * @param $length The byte itself
+   * @return the byte value (e.g. CFBoolean(true), CFBoolean(false), 0 or 15)
+   * @throws PListException on encountering an unknown null type
+   */
+  protected function readBinaryNullType($length) {
+    switch($length) {
+      case 0: return 0; // null type
+      case 8: return new CFBoolean(false);
+      case 9: return new CFBoolean(true);
+      case 15: return 15; // fill type
+    }
+
+    throw new PListException("unknown null type: $length");
+  }
+
+  /**
+   * Create an 64 bit integer using bcmath or gmp
+   * @param int $hi The higher word
+   * @param int $lo The lower word
+   * @return mixed The integer (as int if possible, as string if not possible)
+   * @throws PListException if neither gmp nor bc available
+   */
+  protected static function make64Int($hi,$lo) {
+    // on x64, we can just use int
+    if(PHP_INT_SIZE > 4) return (((int)$hi)<<32) | ((int)$lo);
+
+    // lower word has to be unsigned since we don't use bitwise or, we use bcadd/gmp_add
+    $lo = sprintf("%u", $lo);
+
+    // use GMP or bcmath if possible
+    if(function_exists("gmp_mul")) return gmp_strval(gmp_add(gmp_mul($hi, "4294967296"), $lo));
+
+    if(function_exists("bcmul")) return bcadd(bcmul($hi,"4294967296"), $lo);
+
+    throw new PListException("either gmp or bc has to be installed!");
+  }
+
+  /**
+   * Read an integer value
+   * @param string $fname The filename of the file we're reading from
+   * @param ressource $fd The file descriptor we're reading from
+   * @param integer $length The length (in bytes) of the integer value, coded as „set bit $length to 1”
+   * @return CFNumber The integer value
+   * @throws PListException if integer val is invalid
+   * @throws IOException if read error occurs
+   */
+  protected function readBinaryInt($fname,$fd,$length) {
+    if($length > 3) throw new PListException("Integer greater than 8 bytes: $length");
+
+    $nbytes = 1 << $length;
+
+    $val = null;
+    if(strlen($buff = fread($fd, $nbytes)) != $nbytes) throw IOException::readError($fname);
+    switch($length) {
+      case 0:
+        $val = unpack("C", $buff);
+        $val = $val[1];
+        break;
+      case 1:
+        $val = unpack("n", $buff);
+        $val = $val[1];
+        break;
+      case 2:
+        $val = unpack("N", $buff);
+        $val = $val[1];
+        break;
+      case 3:
+        $words = unpack("Nhighword/Nlowword",$buff);
+        //$val = $words['highword'] << 32 | $words['lowword'];
+        $val = self::make64Int($words['highword'],$words['lowword']);
+        break;
+    }
+
+    return new CFNumber($val);
+  }
+
+  /**
+   * Read a real value
+   * @param string $fname The filename of the file we're reading from
+   * @param ressource $fd The file descriptor we're reading from
+   * @param integer $length The length (in bytes) of the integer value, coded as „set bit $length to 1”
+   * @return CFNumber The real value
+   * @throws PListException if real val is invalid
+   * @throws IOException if read error occurs
+   */
+  protected function readBinaryReal($fname,$fd,$length) {
+    if($length > 3) throw new PListException("Real greater than 8 bytes: $length");
+
+    $nbytes = 1 << $length;
+    $val = null;
+    if(strlen($buff = fread($fd, $nbytes)) != $nbytes) throw IOException::readError($fname);
+
+    switch($length) {
+      case 0: // 1 byte float? must be an error
+      case 1: // 2 byte float? must be an error
+        $x = $length + 1;
+        throw new PListException("got {$x} byte float, must be an error!");
+      case 2:
+        $val = unpack("f", strrev($buff));
+        $val = $val[1];
+        break;
+      case 3:
+        $val = unpack("d", strrev($buff));
+        $val = $val[1];
+        break;
+    }
+
+    return new CFNumber($val);
+  }
+
+  /**
+   * Read a date value
+   * @param string $fname The filename of the file we're reading from
+   * @param ressource $fd The file descriptor we're reading from
+   * @param integer $length The length (in bytes) of the integer value, coded as „set bit $length to 1”
+   * @return CFDate The date value
+   * @throws PListException if date val is invalid
+   * @throws IOException if read error occurs
+   */
+  protected function readBinaryDate($fname,$fd,$length) {
+    if($length > 3) throw new PListException("Date greater than 8 bytes: $length");
+
+    $nbytes = 1 << $length;
+    $val = null;
+    if(strlen($buff = fread($fd, $nbytes)) != $nbytes) throw IOException::readError($fname);
+
+    switch($length) {
+      case 0: // 1 byte CFDate is an error
+      case 1: // 2 byte CFDate is an error
+        $x = $length + 1;
+        throw new PListException("{$x} byte CFdate, error");
+
+      case 2:
+        $val = unpack("f", strrev($buff));
+        $val = $val[1];
+        break;
+      case 3:
+        $val = unpack("d", strrev($buff));
+        $val = $val[1];
+        break;
+    }
+
+    return new CFDate($val,CFDate::TIMESTAMP_APPLE);
+  }
+
+  /**
+   * Read a data value
+   * @param string $fname The filename of the file we're reading from
+   * @param ressource $fd The file descriptor we're reading from
+   * @param integer $length The length (in bytes) of the integer value, coded as „set bit $length to 1”
+   * @return CFData The data value
+   * @throws IOException if read error occurs
+   */
+  protected function readBinaryData($fname,$fd,$length) {
+    if(strlen($buff = fread($fd, $length)) != $length) throw IOException::readError($fname);
+    return new CFData($buff,false);
+  }
+
+  /**
+   * Read a string value, usually coded as utf8
+   * @param string $fname The filename of the file we're reading from
+   * @param ressource $fd The file descriptor we're reading from
+   * @param integer $length The length (in bytes) of the string value
+   * @return CFString The string value, utf8 encoded
+   * @throws IOException if read error occurs
+   */
+  protected function readBinaryString($fname,$fd,$length) {
+    if(strlen($buff = fread($fd, $length)) != $length) throw IOException::readError($fname);
+
+    if(!isset($this->uniqueTable[$buff])) $this->uniqueTable[$buff] = true;
+    return new CFString($buff);
+  }
+
+  /**
+   * Convert the given string from one charset to another.
+   * Trying to use MBString, Iconv, Recode - in that particular order.
+   * @param string $string the string to convert
+   * @param string $fromCharset the charset the given string is currently encoded in
+   * @param string $toCharset the charset to convert to, defaults to UTF-8
+   * @return string the converted string
+   * @throws PListException on neither MBString, Iconv, Recode being available
+   */
+  public static function convertCharset($string, $fromCharset, $toCharset='UTF-8') {
+    if(function_exists('mb_convert_encoding')) return mb_convert_encoding($string, $toCharset, $fromCharset);
+    if(function_exists('iconv')) return iconv($fromCharset, $toCharset, $string);
+    if(function_exists('recode_string')) return recode_string($fromCharset .'..'. $toCharset, $string);
+
+    throw new PListException('neither iconv nor mbstring supported. how are we supposed to work on strings here?');
+  }
+
+  /**
+   * Count characters considering character set
+   * Trying to use MBString, Iconv - in that particular order.
+   * @param string $string the string to convert
+   * @param string $charset the charset the given string is currently encoded in
+   * @return integer The number of characters in that string
+   * @throws PListException on neither MBString, Iconv being available
+   */
+  public static function charsetStrlen($string,$charset="UTF-8") {
+    if(function_exists('mb_strlen')) return mb_strlen($string, $charset);
+    if(function_exists('iconv_strlen')) return iconv($string,$charset);
+
+    throw new PListException('neither iconv nor mbstring supported. how are we supposed to work on strings here?');
+  }
+
+  /**
+   * Read a unicode string value, coded as UTF-16BE
+   * @param string $fname The filename of the file we're reading from
+   * @param ressource $fd The file descriptor we're reading from
+   * @param integer $length The length (in bytes) of the string value
+   * @return CFString The string value, utf8 encoded
+   * @throws IOException if read error occurs
+   */
+  protected function readBinaryUnicodeString($fname,$fd,$length) {
+    if(strlen($buff = fread($fd, 2*$length)) != 2*$length) throw IOException::readError($fname);
+
+    if(!isset($this->uniqueTable[$buff])) $this->uniqueTable[$buf] = true;
+    return new CFString(self::convertCharset($buff,"UTF-8", "UTF-16BE"));
+  }
+
+  /**
+   * Read an array value, including contained objects
+   * @param string $fname The filename of the file we're reading from
+   * @param ressource $fd The file descriptor we're reading from
+   * @param integer $length The number of contained objects
+   * @return CFArray The array value, including the objects
+   * @throws IOException if read error occurs
+   */
+  protected function readBinaryArray($fname,$fd,$length) {
+    $ary = new CFArray();
+
+    // first: read object refs
+    if($length != 0) {
+      if(strlen($buff = fread($fd, $length * $this->objectRefSize)) != $length * $this->objectRefSize) throw IOException::readError($fname);
+      $objects = unpack($this->objectRefSize == 1 ? "C*" : "n*", $buff);
+
+      // now: read objects
+      for($i=0;$i<$length;++$i) {
+        $object = $this->readBinaryObjectAt($fname,$fd,$objects[$i+1]+1,$this->objectRefSize);
+        $ary->add($object);
+      }
+    }
+
+    return $ary;
+  }
+
+  /**
+   * Read a dictionary value, including contained objects
+   * @param string $fname The filename of the file we're reading from
+   * @param ressource $fd The file descriptor we're reading from
+   * @param integer $length The number of contained objects
+   * @return CFDictionary The dictionary value, including the objects
+   * @throws IOException if read error occurs
+   */
+  protected function readBinaryDict($fname,$fd,$length) {
+    $dict = new CFDictionary();
+
+    // first: read keys
+    if($length != 0) {
+      if(strlen($buff = fread($fd, $length * $this->objectRefSize)) != $length * $this->objectRefSize) throw IOException::readError($fname);
+      $keys = unpack(($this->objectRefSize == 1 ? "C*" : "n*"), $buff);
+
+      // second: read object refs
+      if(strlen($buff = fread($fd, $length * $this->objectRefSize)) != $length * $this->objectRefSize) throw IOException::readError($fname);
+      $objects = unpack(($this->objectRefSize == 1 ? "C*" : "n*"), $buff);
+
+      // read real keys and objects
+      for($i=0;$i<$length;++$i) {
+        $key = $this->readBinaryObjectAt($fname,$fd,$keys[$i+1]+1);
+        $object = $this->readBinaryObjectAt($fname,$fd,$objects[$i+1]+1);
+        $dict->add($key->getValue(),$object);
+      }
+    }
+
+    return $dict;
+  }
+
+  /**
+   * Read an object type byte, decode it and delegate to the correct reader function
+   * @param string $fname The filename of the file we're reading from
+   * @param ressource $fd The file descriptor we're reading from
+   * @return mixed The value of the delegate reader, so any of the CFType subclasses
+   * @throws IOException if read error occurs
+   */
+  function readBinaryObject($fname,$fd) {
+    // first: read the marker byte
+    if(strlen($buff = fread($fd,1)) != 1) throw IOException::readError($fname);
+
+    $object_length = unpack("C*", $buff);
+    $object_length = $object_length[1]  & 0xF;
+    $buff = unpack("H*", $buff);
+    $buff = $buff[1];
+
+    $object_type = substr($buff, 0, 1);
+    if($object_type != "0" && $object_length == 15) {
+      $object_length = $this->readBinaryObject($fname,$fd,$this->objectRefSize);
+      $object_length = $object_length->getValue();
+    }
+
+    $retval = null;
+    switch($object_type) {
+      case '0': // null, false, true, fillbyte
+        $retval = $this->readBinaryNullType($object_length);
+        break;
+      case '1': // integer
+        $retval = $this->readBinaryInt($fname,$fd,$object_length);
+        break;
+      case '2': // real
+        $retval = $this->readBinaryReal($fname,$fd,$object_length);
+        break;
+      case '3': // date
+        $retval = $this->readBinaryDate($fname,$fd,$object_length);
+        break;
+      case '4': // data
+        $retval = $this->readBinaryData($fname,$fd,$object_length);
+        break;
+      case '5': // byte string, usually utf8 encoded
+        $retval = $this->readBinaryString($fname,$fd,$object_length);
+        break;
+      case '6': // unicode string (utf16be)
+        $retval = $this->readBinaryUnicodeString($fname,$fd,$object_length);
+        break;
+      case 'a': // array
+        $retval = $this->readBinaryArray($fname,$fd,$object_length);
+        break;
+      case 'd': // dictionary
+        $retval = $this->readBinaryDict($fname,$fd,$object_length);
+        break;
+    }
+
+    return $retval;
+  }
+
+  /**
+   * Read an object type byte at position $pos, decode it and delegate to the correct reader function
+   * @param string $fname The filename of the file we're reading from
+   * @param ressource $fd The file descriptor we're reading from
+   * @param integer $pos The table position in the offsets table
+   * @return mixed The value of the delegate reader, so any of the CFType subclasses
+   */
+  function readBinaryObjectAt($fname,$fd,$pos) {
+    $position = $this->offsets[$pos];
+    fseek($fd,$position,SEEK_SET);
+    return $this->readBinaryObject($fname,$fd);
+  }
+
+  /**
+   * Read a binary plist file
+   * @param string $file The file to read
+   * @return void
+   * @throws IOException if read error occurs
+   */
+  function readBinary($file) {
+    $this->uniqueTable = Array();
+    $this->countObjects = 0;
+    $this->stringSize = 0;
+    $this->intSize = 0;
+    $this->miscSize = 0;
+    $this->objectRefs = 0;
+
+    $this->writtenObjectCount = 0;
+    $this->objectTable = Array();
+    $this->objectRefSize = 0;
+
+    $this->offsets = Array();
+
+    $fd = fopen($file,"rb");
+
+    // first, we read the trailer: 32 byte from the end
+    fseek($fd,-32,SEEK_END);
+    $buff = fread($fd,32);
+
+    $infos = unpack("x6/Coffset_size/Cobject_ref_size/x4/Nnumber_of_objects/x4/Ntop_object/x4/Ntable_offset",$buff);
+
+    // after that, get the offset table
+    fseek($fd,$infos['table_offset'], SEEK_SET);
+    $coded_offset_table = fread($fd,$infos['number_of_objects'] * $infos['offset_size']);
+    if(strlen($coded_offset_table) != $infos['number_of_objects'] * $infos['offset_size']) throw IOException::readError($file);
+    $this->countObjects = $infos['number_of_objects'];
+
+    // decode offset table
+    $formats = Array("","C*","n*","(H6)*","N*");
+    $this->offsets = unpack($formats[$infos['offset_size']],$coded_offset_table);
+    if($infos['offset_size'] == 3) {
+      foreach($this->offsets as $k => $v) $this->offsets[$k] = hexdec($v);
+    }
+
+    $this->uniqueTable = Array();
+    $this->objectRefSize = $infos['object_ref_size'];
+
+    $top = $this->readBinaryObjectAt($file,$fd,$infos['top_object']+1);
+    $this->add($top);
+
+    fclose($fd);
+  }
+
+  /**
+   * calculate the bytes needed for a size integer value
+   * @param integer $int The integer value to calculate
+   * @return integer The number of bytes needed
+   */
+  public static function bytesSizeInt($int) {
+    $nbytes = 0;
+
+    if($int > 0xE) $nbytes += 2; // 2 size-bytes
+    if($int > 0xFF) $nbytes += 1; // 3 size-bytes
+    if($int > 0xFFFF) $nbytes += 2; // 5 size-bytes
+
+    return $nbytes;
+  }
+
+  /**
+   * Calculate the byte needed for a „normal” integer value
+   * @param integer $int The integer value
+   * @return integer The number of bytes needed + 1 (because of the „marker byte”)
+   */
+  public static function bytesInt($int) {
+    $nbytes = 1;
+
+    if($int > 0xFF) $nbytes += 1; // 2 byte integer
+    if($int > 0xFFFF) $nbytes += 2; // 4 byte integer
+    if($int > 0xFFFFFFFF) $nbytes += 4; // 8 byte integer
+    if($int < 0) $nbytes += 7; // 8 byte integer (since it is signed)
+
+    return $nbytes + 1; // one „marker” byte
+  }
+
+  /**
+   * „pack” a value (i.e. write the binary representation as big endian to a string) with the specified size
+   * @param integer $nbytes The number of bytes to pack
+   * @param integer $int the integer value to pack
+   * @return string The packed value as string
+   */
+  public static function packItWithSize($nbytes,$int) {
+    $formats = Array("C", "n", "N", "N");
+    $format = $formats[$nbytes-1];
+    $ret = '';
+
+    if($nbytes == 3) return substr(pack($format, $int), -3);
+    return pack($format, $int);
+  }
+
+  /**
+   * Calculate the bytes needed to save the number of objects
+   * @param integer $count_objects The number of objects
+   * @return integer The number of bytes
+   */
+  public static function bytesNeeded($count_objects) {
+    $nbytes = 0;
+
+    while($count_objects >= 1) {
+      $nbytes++;
+      $count_objects /= 256;
+    }
+
+    return $nbytes;
+  }
+
+  /**
+   * Code an integer to byte representation
+   * @param integer $int The integer value
+   * @return string The packed byte value
+   */
+  public static function intBytes($int) {
+    $intbytes = "";
+
+    if($int > 0xFFFF) $intbytes = "\x12".pack("N", $int); // 4 byte integer
+    elseif($int > 0xFF) $intbytes = "\x11".pack("n", $int); // 2 byte integer
+    else $intbytes = "\x10".pack("C", $int); // 8 byte integer
+
+    return $intbytes;
+  }
+
+  /**
+   * Code an type byte, consisting of the type marker and the length of the type
+   * @param string $type The type byte value (i.e. "d" for dictionaries)
+   * @param integer $type_len The length of the type
+   * @return string The packed type byte value
+   */
+  public static function typeBytes($type,$type_len) {
+    $optional_int = "";
+
+    if($type_len < 15) $type .= sprintf("%x", $type_len);
+    else {
+      $type .= "f";
+      $optional_int = self::intBytes($type_len);
+    }
+
+    return pack("H*", $type).$optional_int;
+  }
+
+  /**
+   * Count number of objects and create a unique table for strings
+   * @param $value The value to count and unique
+   * @return void
+   */
+  protected function uniqueAndCountValues($value) {
+    // no uniquing for other types than CFString and CFData
+    if($value instanceof CFNumber) {
+      $val = $value->getValue();
+      if(intval($val) == $val && !is_float($val) && strpos($val,'.') === false) $this->intSize += self::bytesInt($val);
+      else $this->miscSize += 9; // 9 bytes (8 + marker byte) for real
+      $this->countObjects++;
+      return;
+    }
+    elseif($value instanceof CFDate) {
+      $this->miscSize += 9; // since date in plist is real, we need 9 byte (8 + marker byte)
+      $this->countObjects++;
+      return;
+    }
+    elseif($value instanceof CFBoolean) {
+      $this->countObjects++;
+      $this->miscSize += 1;
+      return;
+    }
+    elseif($value instanceof CFArray) {
+      $cnt = 0;
+      foreach($value as $v) {
+        ++$cnt;
+        $this->uniqueAndCountValues($v);
+        $this->objectRefs++; // each array member is a ref
+      }
+
+      $this->countObjects++;
+      $this->intSize += self::bytesSizeInt($cnt);
+      $this->miscSize++; // marker byte for array
+      return;
+    }
+    elseif($value instanceof CFDictionary) {
+      $cnt = 0;
+      foreach($value as $k => $v) {
+        ++$cnt;
+        if(!isset($this->uniqueTable[$k])) {
+          $this->uniqueTable[$k] = 0;
+          $this->stringSize += strlen($k) + 1;
+          $this->intSize += self::bytesSizeInt(strlen($k));
+        }
+
+        $this->objectRefs += 2; // both, key and value, are refs
+        $this->uniqueTable[$k]++;
+        $this->uniqueAndCountValues($v);
+      }
+
+      $this->countObjects++;
+      $this->miscSize++; // marker byte for dict
+      $this->intSize += self::bytesSizeInt($cnt);
+      return;
+    }
+    elseif($value instanceOf CFData) {
+      $val = $value->getValue();
+      $this->intSize += self::bytesSizeInt(strlen($val));
+      $this->miscSize += strlen($val) + 1;
+      $this->countObjects++;
+      return;
+    }
+    else $val = $value->getValue();
+
+    if(!isset($this->uniqueTable[$val])) {
+      $this->uniqueTable[$val] = 0;
+      $this->stringSize += strlen($val) + 1;
+      $this->intSize += self::bytesSizeInt(strlen($val));
+    }
+    $this->uniqueTable[$val]++;
+  }
+
+  /**
+   * Convert CFPropertyList to binary format; since we have to count our objects we simply unique CFDictionary and CFArray
+   * @return string The binary plist content
+   */
+  public function toBinary() {
+    $this->uniqueTable = Array();
+    $this->countObjects = 0;
+    $this->stringSize = 0;
+    $this->intSize = 0;
+    $this->miscSize = 0;
+    $this->objectRefs = 0;
+
+    $this->writtenObjectCount = 0;
+    $this->objectTable = Array();
+    $this->objectRefSize = 0;
+
+    $this->offsets = Array();
+
+    $binary_str = "bplist00";
+    $value = $this->getValue();
+    $this->uniqueAndCountValues($value);
+
+    $this->countObjects += count($this->uniqueTable);
+    $this->objectRefSize = self::bytesNeeded($this->countObjects);
+    $file_size = $this->stringSize + $this->intSize + $this->miscSize + $this->objectRefs * $this->objectRefSize + 40;
+    $offset_size = self::bytesNeeded($file_size);
+    $table_offset = $file_size - 32;
+
+    $this->objectTable = Array();
+    $this->writtenObjectCount = 0;
+    $this->uniqueTable = Array(); // we needed it to calculate several values
+    $this->getValue()->toBinary($this);
+
+    $object_offset = 8;
+    $offsets = Array();
+
+    for($i=0;$i<count($this->objectTable);++$i) {
+      $binary_str .= $this->objectTable[$i];
+      $offsets[$i] = $object_offset;
+      $object_offset += strlen($this->objectTable[$i]);
+    }
+
+    for($i=0;$i<count($offsets);++$i) {
+      $binary_str .= self::packItWithSize($offset_size, $offsets[$i]);
+    }
+
+
+    $binary_str .= pack("x6CC", $offset_size, $this->objectRefSize);
+    $binary_str .= pack("x4N", $this->countObjects);
+    $binary_str .= pack("x4N", 0);
+    $binary_str .= pack("x4N", $table_offset);
+
+    return $binary_str;
+  }
+
+  /**
+   * Uniques and transforms a string value to binary format and adds it to the object table
+   * @param string $val The string value
+   * @return integer The position in the object table
+   */
+  public function stringToBinary($val) {
+    $saved_object_count = -1;
+
+    if(!isset($this->uniqueTable[$val])) {
+      $saved_object_count = $this->writtenObjectCount++;
+      $this->uniqueTable[$val] = $saved_object_count;
+      $utf16 = false;
+
+      for($i=0;$i<strlen($val);++$i) {
+        if(ord($val{$i}) > 128) {
+          $utf16 = true;
+          break;
+        }
+      }
+
+      if($utf16) {
+        $bdata = self::typeBytes("6", mb_strlen($val,'UTF-8')); // 6 is 0110, unicode string (utf16be)
+        $val = self::convertCharset($val, 'UTF-8', 'UTF-16BE');
+        $this->objectTable[$saved_object_count] = $bdata.$val;
+      }
+      else {
+        $bdata = self::typeBytes("5", strlen($val)); // 5 is 0101 which is an ASCII string (seems to be ASCII encoded)
+        $this->objectTable[$saved_object_count] = $bdata.$val;
+      }
+    }
+    else $saved_object_count = $this->uniqueTable[$val];
+
+    return $saved_object_count;
+  }
+
+  /**
+   * Codes an integer to binary format
+   * @param integer $value The integer value
+   * @return string the coded integer
+   */
+  protected function intToBinary($value) {
+    $nbytes = 0;
+    if($value > 0xFF) $nbytes = 1; // 1 byte integer
+    if($value > 0xFFFF) $nbytes += 1; // 4 byte integer
+    if($value > 0xFFFFFFFF) $nbytes += 1; // 8 byte integer
+    if($value < 0) $nbytes = 3; // 8 byte integer, since signed
+
+    $bdata = self::typeBytes("1", $nbytes); // 1 is 0001, type indicator for integer
+    $buff = "";
+
+    if($nbytes < 3) {
+      if($nbytes == 0) $fmt = "C";
+      elseif($nbytes == 1) $fmt = "n";
+      else $fmt = "N";
+
+      $buff = pack($fmt, $value);
+    }
+    else {
+      if(PHP_INT_SIZE > 4) {
+        // 64 bit signed integer; we need the higher and the lower 32 bit of the value
+        $high_word = $value >> 32;
+        $low_word = $value & 0xFFFFFFFF;
+      }
+      else {
+        // since PHP can only handle 32bit signed, we can only get 32bit signed values at this point - values above 0x7FFFFFFF are
+        // floats. So we ignore the existance of 64bit on non-64bit-machines
+        if($value < 0) $high_word = 0xFFFFFFFF;
+        else $high_word = 0;
+        $low_word = $value;
+      }
+      $buff = pack("N", $high_word).pack("N", $low_word);
+    }
+
+    return $bdata.$buff;
+  }
+
+  /**
+   * Codes a real value to binary format
+   * @param float $val The real value
+   * @return string The coded real
+   */
+  protected function realToBinary($val) {
+    $bdata = self::typeBytes("2", 3); // 2 is 0010, type indicator for reals
+    return $bdata.strrev(pack("d", (float)$val));
+  }
+
+  /**
+   * Converts a numeric value to binary and adds it to the object table
+   * @param numeric $value The numeric value
+   * @return integer The position in the object table
+   */
+  public function numToBinary($value) {
+    $saved_object_count = $this->writtenObjectCount++;
+
+    $val = "";
+    if(intval($value) == $value && !is_float($value) && strpos($value,'.') === false) $val = $this->intToBinary($value);
+    else $val = $this->realToBinary($value);
+
+    $this->objectTable[$saved_object_count] = $val;
+    return $saved_object_count;
+  }
+
+  /**
+   * Convert date value (apple format) to binary and adds it to the object table
+   * @param integer $value The date value
+   * @return integer The position of the coded value in the object table
+   */
+  public function dateToBinary($val) {
+    $saved_object_count = $this->writtenObjectCount++;
+
+    $hour = gmdate("H",$val);
+    $min = gmdate("i",$val);
+    $sec = gmdate("s",$val);
+    $mday = gmdate("j",$val);
+    $mon = gmdate("n",$val);
+    $year = gmdate("Y",$val);
+
+    $val = gmmktime($hour,$min,$sec,$mon,$mday,$year) - CFDate::DATE_DIFF_APPLE_UNIX; // CFDate is a real, number of seconds since 01/01/2001 00:00:00 GMT
+
+    $bdata = self::typeBytes("3", 3); // 3 is 0011, type indicator for date
+    $this->objectTable[$saved_object_count] = $bdata.strrev(pack("d", $val));
+
+    return $saved_object_count;
+  }
+
+  /**
+   * Convert a bool value to binary and add it to the object table
+   * @param bool $val The boolean value
+   * @return integer The position in the object table
+   */
+  public function boolToBinary($val) {
+    $saved_object_count = $this->writtenObjectCount++;
+    $this->objectTable[$saved_object_count] = $val ? "\x9" : "\x8"; // 0x9 is 1001, type indicator for true; 0x8 is 1000, type indicator for false
+    return $saved_object_count;
+  }
+
+  /**
+   * Convert data value to binary format and add it to the object table
+   * @param string $val The data value
+   * @return integer The position in the object table
+   */
+  public function dataToBinary($val) {
+    $saved_object_count = $this->writtenObjectCount++;
+
+    $bdata = self::typeBytes("4", strlen($val)); // a is 1000, type indicator for data
+    $this->objectTable[$saved_object_count] = $bdata.$val;
+
+    return $saved_object_count;
+  }
+
+  /**
+   * Convert array to binary format and add it to the object table
+   * @param CFArray $val The array to convert
+   * @return integer The position in the object table
+   */
+  public function arrayToBinary($val) {
+    $saved_object_count = $this->writtenObjectCount++;
+
+    $bdata = self::typeBytes("a", count($val->getValue())); // a is 1010, type indicator for arrays
+
+    foreach($val as $v) {
+      $bval = $v->toBinary($this);
+      $bdata .= self::packItWithSize($this->objectRefSize, $bval);
+    }
+
+    $this->objectTable[$saved_object_count] = $bdata;
+    return $saved_object_count;
+  }
+
+  /**
+   * Convert dictionary to binary format and add it to the object table
+   * @param CFDictionary $val The dict to convert
+   * @return integer The position in the object table
+   */
+  public function dictToBinary($val) {
+    $saved_object_count = $this->writtenObjectCount++;
+    $bdata = self::typeBytes("d", count($val->getValue())); // d=1101, type indicator for dictionary
+
+    foreach($val as $k => $v) {
+      $str = new CFString($k);
+      $key = $str->toBinary($this);
+      $bdata .= self::packItWithSize($this->objectRefSize, $key);
+    }
+
+    foreach($val as $k => $v) {
+      $bval = $v->toBinary($this);
+      $bdata .= self::packItWithSize($this->objectRefSize, $bval);
+    }
+
+    $this->objectTable[$saved_object_count] = $bdata;
+    return $saved_object_count;
+  }
+
+}
+
+
+?>

+ 524 - 0
Tools/projectGenerator/classes/plist/CFPropertyList.php

@@ -0,0 +1,524 @@
+<?php
+/**
+ * CFPropertyList
+ * {@link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists}
+ * @author Rodney Rehm <[email protected]>
+ * @author Christian Kruse <[email protected]>
+ * @package plist
+ * @version $Id$
+ * @example example-read-01.php Read an XML PropertyList
+ * @example example-read-02.php Read a Binary PropertyList
+ * @example example-read-03.php Read a PropertyList without knowing the type
+ * @example example-create-01.php Using the CFPropertyList API
+ * @example example-create-02.php Using CFPropertyList::guess()
+ * @example example-create-03.php Using CFPropertyList::guess() with {@link CFDate} and {@link CFData}
+ */
+
+/**
+ * Require IOException, PListException, CFType and CFBinaryPropertyList
+ */
+$plistDirectory = dirname(__FILE__);
+require_once($plistDirectory.'/IOException.php');
+require_once($plistDirectory.'/PListException.php');
+require_once($plistDirectory.'/CFType.php');
+require_once($plistDirectory.'/CFBinaryPropertyList.php');
+
+/**
+ * Property List
+ * Interface for handling reading, editing and saving Property Lists as defined by Apple.
+ * @author Rodney Rehm <[email protected]>
+ * @author Christian Kruse <[email protected]>
+ * @package plist
+ * @example example-read-01.php Read an XML PropertyList
+ * @example example-read-02.php Read a Binary PropertyList
+ * @example example-read-03.php Read a PropertyList without knowing the type
+ * @example example-create-01.php Using the CFPropertyList API
+ * @example example-create-02.php Using CFPropertyList::guess()
+ * @example example-create-03.php Using CFPropertyList::guess() with {@link CFDate} and {@link CFData}
+ */
+class CFPropertyList extends CFBinaryPropertyList implements Iterator {
+  /**
+   * Format constant for binary format
+   * @var integer
+   */
+  const FORMAT_BINARY = 1;
+
+  /**
+   * Format constant for xml format
+   * @var integer
+   */
+  const FORMAT_XML = 2;
+
+  /**
+   * Format constant for automatic format recognizing
+   * @var integer
+   */
+  const FORMAT_AUTO = 0;
+
+  /**
+   * Path of PropertyList
+   * @var string
+   */
+  protected $file = null;
+
+  /**
+   * Path of PropertyList
+   * @var integer
+   */
+  protected $format = null;
+
+  /**
+   * CFType nodes
+   * @var array
+   */
+  protected $value = array();
+
+  /**
+   * Position of iterator {@link http://php.net/manual/en/class.iterator.php}
+   * @var integer
+   */
+  protected $iteratorPosition = 0;
+
+  /**
+   * List of Keys for numerical iterator access {@link http://php.net/manual/en/class.iterator.php}
+   * @var array
+   */
+  protected $iteratorKeys = null;
+
+  /**
+   * List of NodeNames to ClassNames for resolving plist-files
+   * @var array
+   */
+  protected static $types = array(
+    'string' => 'CFString',
+    'real' => 'CFNumber',
+    'integer' => 'CFNumber',
+    'date' => 'CFDate',
+    'true' => 'CFBoolean',
+    'false' => 'CFBoolean',
+    'data' => 'CFData',
+    'array' => 'CFArray',
+    'dict' => 'CFDictionary'
+ );
+
+
+  /**
+   * Create new CFPropertyList.
+   * If a path to a PropertyList is specified, it is loaded automatically.
+   * @param string $file Path of PropertyList
+   * @param integer $format he format of the property list, see {@link FORMAT_XML}, {@link FORMAT_BINARY} and {@link FORMAT_AUTO}, defaults to {@link FORMAT_AUTO}
+   * @throws IOException if file could not be read by {@link load()}
+   * @uses $file for storing the current file, if specified
+   * @uses load() for loading the plist-file
+   */
+  public function __construct($file=null,$format=self::FORMAT_AUTO) {
+    $this->file = $file;
+    $this->format = $format;
+    if($this->file) $this->load();
+  }
+
+  /**
+   * Load an XML PropertyList.
+   * @param string $file Path of PropertyList, defaults to {@link $file} 
+   * @return void
+   * @throws IOException if file could not be read
+   * @throws DOMException if XML-file could not be read properly
+   * @uses load() to actually load the file
+   */
+  public function loadXML($file=null) {
+    $this->load($file,CFPropertyList::FORMAT_XML);
+  }
+  
+  /**
+   * Load an binary PropertyList.
+   * @param string $file Path of PropertyList, defaults to {@link $file} 
+   * @return void
+   * @throws IOException if file could not be read
+   * @throws PListException if binary plist-file could not be read properly
+   * @uses load() to actually load the file
+   */
+  public function loadBinary($file=null) {
+    $this->load($file,CFPropertyList::FORMAT_BINARY);
+  }
+
+  /**
+   * Load a plist file.
+   * Load and import a plist file.
+   * @param string $file Path of PropertyList, defaults to {@link $file}
+   * @param integer $format The format of the property list, see {@link FORMAT_XML}, {@link FORMAT_BINARY} and {@link FORMAT_AUTO}, defaults to {@link $format}
+   * @return void
+   * @throws PListException if file format version is not 00
+   * @throws IOException if file could not be read
+   * @throws DOMException if plist file could not be parsed properly
+   * @uses $file if argument $file was not specified
+   * @uses $value reset to empty array
+   * @uses import() for importing the values
+   */
+  public function load($file=null,$format=null) {
+    $file = $file ? $file : $this->file;
+    $format = $format !== null ? $format : $this->format;
+    $this->value = array();
+
+    if(!is_readable($file)) throw IOException::notReadable($file);
+
+    switch($format) {
+      case CFPropertyList::FORMAT_BINARY:
+        $this->readBinary($file);
+        break;
+      case CFPropertyList::FORMAT_AUTO: // what we now do is ugly, but neccessary to recognize the file format
+        $fd = fopen($file,"rb");
+        if(($magic_number = fread($fd,8)) === false) throw IOException::notReadable($file);
+        fclose($fd);
+
+        $filetype = substr($magic_number,0,6);
+        $version  = substr($magic_number,-2);
+
+        if($filetype == "bplist") {
+          if($version != "00") throw new PListException("Wrong file format version! Expected 00, got $version!");
+          $this->readBinary($file);
+          break;
+        }
+        // else: xml format, break not neccessary
+      case CFPropertyList::FORMAT_XML:
+        $doc = new DOMDocument();
+        if(!$doc->load($file)) throw new DOMException();
+        $this->import($doc->documentElement, $this);
+        break;
+    }
+
+  }
+
+  /**
+   * Convert a DOMNode into a CFType.
+   * @param DOMNode $node Node to import children of
+   * @param CFDictionary|CFArray|CFPropertyList $parent 
+   * @return void
+   */
+  protected function import(DOMNode $node, $parent) {
+    // abort if there are no children
+    if(!$node->childNodes->length) return;
+
+    foreach($node->childNodes as $n) {
+      // skip if we can't handle the element
+      if(!isset(self::$types[$n->nodeName])) continue;
+
+      $class = self::$types[$n->nodeName];
+      $key = null;
+
+      // find previous <key> if possible
+      $ps = $n->previousSibling;
+      while($ps && $ps->nodeName == '#text' && $ps->previousSibling) $ps = $ps->previousSibling;
+
+      // read <key> if possible
+      if($ps && $ps->nodeName == 'key') $key = $ps->firstChild->nodeValue;
+
+      switch($n->nodeName) {
+        case 'date':
+          $value = new $class(CFDate::dateValue($n->nodeValue));
+          break;
+        case 'data':
+          $value = new $class($n->nodeValue,true);
+          break;
+        case 'string':
+          $value = new $class($n->nodeValue);
+          break;
+
+        case 'real':
+        case 'integer':
+          $value = new $class($n->nodeName == 'real' ? floatval($n->nodeValue) : intval($n->nodeValue));
+          break;
+
+        case 'true':
+        case 'false':
+          $value = new $class($n->nodeName == 'true');
+          break;
+
+        case 'array':
+        case 'dict':
+          $value = new $class();
+          $this->import($n, $value);
+          break;
+      }
+
+      // Dictionaries need a key
+      if($parent instanceof CFDictionary) $parent->add($key, $value);
+      // others don't
+      else $parent->add($value);
+    }
+  }
+
+  /**
+   * Convert CFPropertyList to XML and save to file.
+   * @param string $file Path of PropertyList, defaults to {@link $file} 
+   * @return void
+   * @throws IOException if file could not be read
+   * @uses $file if $file was not specified
+   */
+  public function saveXML($file) {
+    $this->save($file,CFPropertyList::FORMAT_XML);
+  }
+
+  /**
+   * Convert CFPropertyList to binary format (bplist00) and save to file.
+   * @param string $file Path of PropertyList, defaults to {@link $file} 
+   * @return void
+   * @throws IOException if file could not be read
+   * @uses $file if $file was not specified
+   */
+  public function saveBinary($file) {
+    $this->save($file,CFPropertyList::FORMAT_BINARY);
+  }
+
+  /**
+   * Convert CFPropertyList to XML or binary and save to file.
+   * @param string $file Path of PropertyList, defaults to {@link $file} 
+   * @param string $format Format of PropertyList, defaults to {@link $format}
+   * @return void
+   * @throws IOException if file could not be read
+   * @throws PListException if evaluated $format is neither {@link FORMAT_XML} nor {@link FORMAL_BINARY}
+   * @uses $file if $file was not specified
+   * @uses $format if $format was not specified
+   */
+  public function save($file=null,$format=null) {
+    $file = $file ? $file : $this->file;
+    $format = $format ? $format : $this->format;
+
+    if( !in_array( $format, array( self::FORMAT_BINARY, self::FORMAT_XML ) ) )
+      throw new PListException( "format {$format} is not supported, use CFPropertyList::FORMAT_BINARY or CFPropertyList::FORMAT_XML" );
+
+    if(!file_exists($file)) {
+      // dirname("file.xml") == "" and is treated as the current working directory
+      if(!is_writable(dirname($file))) throw IOException::notWritable($file);
+    }
+    else if(!is_writable($file)) throw IOException::notWritable($file);
+
+    $content = $format == self::FORMAT_BINARY ? $this->toBinary() : $this->toXML();
+
+    $fh = fopen($file, 'wb');
+    fwrite($fh,$content);
+    fclose($fh);
+  }
+
+  /**
+   * Convert CFPropertyList to XML
+   * @param bool $formatted Print plist formatted (i.e. with newlines and whitespace indention) if true; defaults to false
+   * @return string The XML content
+   */
+  public function toXML($formatted=false) {
+    $domimpl = new DOMImplementation();
+    // <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+    $dtd = $domimpl->createDocumentType('plist', '-//Apple Computer//DTD PLIST 1.0//EN', 'http://www.apple.com/DTDs/PropertyList-1.0.dtd');
+    $doc = $domimpl->createDocument(null, "plist", $dtd);
+    $doc->encoding = "UTF-8";
+
+    // format output
+    if($formatted) {
+      $doc->formatOutput = true;
+      $doc->preserveWhiteSpace = true;
+    }
+
+    // get documentElement and set attribs
+    $plist = $doc->documentElement;
+    $plist->setAttribute('version', '1.0');
+
+    // add PropertyList's children
+    $plist->appendChild($this->getValue()->toXML($doc));
+
+    return $doc->saveXML();
+  }
+
+
+  /************************************************************************************************
+   *    M A N I P U L A T I O N
+   ************************************************************************************************/
+
+  /**
+   * Add CFType to collection.
+   * @param CFType $value CFType to add to collection
+   * @return void
+   * @uses $value for adding $value
+   */
+  public function add($value) {
+    $this->value[] = $value;
+  }
+
+  /**
+   * Get CFType from collection.
+   * @param integer $key Key of CFType to retrieve from collection
+   * @return CFType CFType found at $key, null else
+   * @uses $value for retrieving CFType of $key
+   */
+  public function get($key) {
+    if(isset($this->value[$key])) return $this->value[$key];
+    return null;
+  }
+  
+  /**
+   * Remove CFType from collection.
+   * @param integer $key Key of CFType to removes from collection
+   * @return CFType removed CFType, null else
+   * @uses $value for removing CFType of $key
+   */
+  public function del($key) {
+    if(isset($this->value[$key])) {
+      $t = $this->value[$key];
+      unset($this->value[$key]);
+      return $t;
+    }
+
+    return null;
+  }
+
+  /**
+   * Get first (and only) child, or complete collection.
+   * @return CFType|array CFType or list of CFTypes known to the PropertyList
+   * @uses $value for retrieving CFTypes
+   */
+  public function getValue() {
+    if(count($this->value) === 1) return $this->value[0];
+    return $this->value;
+  }
+
+  /**
+   * Create CFType-structure from guessing the data-types.
+   * {@link CFArray}, {@link CFDictionary}, {@link CFBoolean}, {@link CFNumber} and {@link CFString} can be created, {@link CFDate} and {@link CFData} cannot.
+   * <br /><b>Note:</b>Distinguishing between {@link CFArray} and {@link CFDictionary} is done by examining the keys. 
+   * Keys must be strictly incrementing integers to evaluate to a {@link CFArray}. 
+   * Since PHP does not offer a function to test for associative arrays, 
+   * this test causes the input array to be walked twice and thus work rather slow on large collections. 
+   * If you work with large arrays and can live with all arrays evaluating to {@link CFDictionary}, 
+   * feel free to set the appropriate flag.
+   * <br /><b>Note:</b> If $value is an instance of CFType it is simply returned.
+   * <br /><b>Note:</b> If $value is neither a CFType, array, numeric, boolean nor string, it is omitted.
+   * @param mixed $value Value to convert to CFType
+   * @param boolean $autoDictionary if true {@link CFArray}-detection is bypassed and arrays will be returned as {@link CFDictionary}.
+   * @return CFType CFType based on guessed type
+   */
+  public static function guess($value, $autoDictionary=false) {
+    switch(true) {
+      case $value instanceof CFType:
+        return $value;
+      break;
+      case is_array($value):
+        // test if $value is simple or associative array
+        if(!$autoDictionary) {
+          $numericKeys = true;
+          $previousKey = null;
+          foreach($value as $key => $v) {
+            if(!is_numeric($key) || ($previousKey !== null && $previousKey != $key-1)) {
+              $numericKeys = false;
+              break;
+            }
+
+            $previousKey = $key;
+          } 
+
+          if($numericKeys) {
+            $t = new CFArray();
+            foreach($value as $v) $t->add(self::guess($v, $autoDictionary));
+            return $t;
+          }
+        }
+
+        $t = new CFDictionary();
+        foreach($value as $k => $v) $t->add($k, self::guess($v, $autoDictionary));
+
+        return $t;
+        break;
+
+      case is_numeric($value):
+        return new CFNumber($value);
+        break;
+
+      case is_bool($value):
+        return new CFBoolean($value);
+        break;
+
+      case is_string($value):
+        return new CFString($value);
+        break;
+    }
+  }
+
+
+  /************************************************************************************************
+   *    S E R I A L I Z I N G
+   ************************************************************************************************/
+
+  /**
+   * Get PropertyList as array.
+   * @return mixed primitive value of first (and only) CFType, or array of primitive values of collection
+   * @uses $value for retrieving CFTypes
+   */
+  public function toArray() {
+    $a = array();
+    foreach($this->value as $value) $a[] = $value->toArray();
+    if(count($a) === 1) return $a[0];
+
+    return $a;
+  }
+
+
+  /************************************************************************************************
+   *    I T E R A T O R   I N T E R F A C E
+   ************************************************************************************************/
+
+  /**
+   * Rewind {@link $iteratorPosition} to first position (being 0)
+   * @link http://php.net/manual/en/iterator.rewind.php
+   * @return void
+   * @uses $iteratorPosition set to 0
+   * @uses $iteratorKeys store keys of {@link $value}
+   */
+  public function rewind() {
+    $this->iteratorPosition = 0;
+    $this->iteratorKeys = array_keys($this->value);
+  }
+
+  /**
+   * Get Iterator's current {@link CFType} identified by {@link $iteratorPosition}
+   * @link http://php.net/manual/en/iterator.current.php
+   * @return CFType current Item
+   * @uses $iteratorPosition identify current key
+   * @uses $iteratorKeys identify current value
+   */
+  public function current() {
+    return $this->value[$this->iteratorKeys[$this->iteratorPosition]];
+  }
+
+  /**
+   * Get Iterator's current key identified by {@link $iteratorPosition}
+   * @link http://php.net/manual/en/iterator.key.php
+   * @return string key of the current Item
+   * @uses $iteratorPosition identify current key
+   * @uses $iteratorKeys identify current value
+   */
+  public function key() {
+    return $this->iteratorKeys[$this->iteratorPosition];
+  }
+
+  /**
+   * Increment {@link $iteratorPosition} to address next {@see CFType}
+   * @link http://php.net/manual/en/iterator.next.php
+   * @return void
+   * @uses $iteratorPosition increment by 1
+   */
+  public function next() {
+    $this->iteratorPosition++;
+  }
+
+  /**
+   * Test if {@link $iteratorPosition} addresses a valid element of {@link $value}
+   * @link http://php.net/manual/en/iterator.valid.php
+   * @return boolean true if current position is valid, false else
+   * @uses $iteratorPosition test if within {@link $iteratorKeys}
+   * @uses $iteratorPosition test if within {@link $value}
+   */
+  public function valid() {
+    return isset($this->iteratorKeys[$this->iteratorPosition]) && isset($this->value[$this->iteratorKeys[$this->iteratorPosition]]);
+  }
+
+}
+
+
+?>

+ 661 - 0
Tools/projectGenerator/classes/plist/CFType.php

@@ -0,0 +1,661 @@
+<?php
+/**
+ * Data-Types for CFPropertyList as defined by Apple.
+ * {@link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists}
+ * @author Rodney Rehm <[email protected]>
+ * @author Christian Kruse <[email protected]>
+ * @package plist
+ * @subpackage plist.types
+ * @version $Id$
+ */
+
+/**
+ * Base-Class of all CFTypes used by CFPropertyList 
+ * @author Rodney Rehm <[email protected]>
+ * @author Christian Kruse <[email protected]>
+ * @package plist
+ * @subpackage plist.types
+ * @version $Id$
+ * @example example-create-01.php Using the CFPropertyList API
+ * @example example-create-02.php Using CFPropertyList::guess()
+ * @example example-create-03.php Using CFPropertyList::guess() with {@link CFDate} and {@link CFData}
+ */
+abstract class CFType {
+  /**
+   * CFType nodes
+   * @var array
+   */
+  protected $value = null;
+
+  /**
+   * Create new CFType.
+   * @param mixed $value Value of CFType
+   */
+  public function __construct($value=null) {
+    $this->setValue($value);
+  }
+
+  /************************************************************************************************
+   *    M A G I C   P R O P E R T I E S
+   ************************************************************************************************/
+  
+  /**
+   * Get the CFType's value
+   * @return mixed CFType's value
+   */
+  public function getValue() {
+    return $this->value;
+  }
+
+  /**
+   * Set the CFType's value
+   * @return void
+   */
+  public function setValue($value) {
+    $this->value = $value;
+  }
+
+  /************************************************************************************************
+   *    S E R I A L I Z I N G
+   ************************************************************************************************/
+
+  /**
+   * Get XML-Node.
+   * @param DOMDocument $doc DOMDocument to create DOMNode in
+   * @param string $nodeName Name of element to create
+   * @return DOMNode Node created based on CType
+   * @uses $value as nodeValue
+   */
+  public function toXML(DOMDocument $doc, $nodeName) {
+    $text = $doc->createTextNode($this->value);
+    $node = $doc->createElement($nodeName);
+    $node->appendChild($text);
+    return $node;
+  }
+
+  /**
+   * convert value to binary representation
+   * @param CFBinaryPropertyList The binary property list object
+   * @return The offset in the object table
+   */
+  public abstract function toBinary(CFBinaryPropertyList &$bplist);
+
+  /**
+   * Get CFType's value.
+   * @return mixed primitive value
+   * @uses $value for retrieving primitive of CFType
+   */
+  public function toArray() {
+    return $this->getValue();
+  }
+
+}
+
+/**
+ * String Type of CFPropertyList
+ * @author Rodney Rehm <[email protected]>
+ * @author Christian Kruse <[email protected]>
+ * @package plist
+ * @subpackage plist.types
+ */
+class CFString extends CFType {
+  /**
+   * Get XML-Node.
+   * @param DOMDocument $doc DOMDocument to create DOMNode in
+   * @return DOMNode &lt;string&gt;-Element
+   */
+  public function toXML(DOMDocument $doc) {
+    return parent::toXML($doc, 'string');
+  }
+
+  /**
+   * convert value to binary representation
+   * @param CFBinaryPropertyList The binary property list object
+   * @return The offset in the object table
+   */
+  public function toBinary(CFBinaryPropertyList &$bplist) {
+    return $bplist->stringToBinary($this->value);
+  }
+}
+
+/**
+ * Number Type of CFPropertyList
+ * @author Rodney Rehm <[email protected]>
+ * @author Christian Kruse <[email protected]>
+ * @package plist
+ * @subpackage plist.types
+ */
+class CFNumber extends CFType {
+  /**
+   * Get XML-Node.
+   * Returns &lt;real&gt; if $value is a float, &lt;integer&gt; if $value is an integer.
+   * @param DOMDocument $doc DOMDocument to create DOMNode in
+   * @return DOMNode &lt;real&gt; or &lt;integer&gt;-Element 
+   */
+  public function toXML(DOMDocument $doc) {
+    $ret = 'real';
+    if(intval($this->value) == $this->value && !is_float($this->value) && strpos($this->value,'.') === false) {
+      $this->value = intval($this->value);
+      $ret = 'integer';
+    }
+    return parent::toXML($doc, $ret);
+  }
+
+  /**
+   * convert value to binary representation
+   * @param CFBinaryPropertyList The binary property list object
+   * @return The offset in the object table
+   */
+  public function toBinary(CFBinaryPropertyList &$bplist) {
+    return $bplist->numToBinary($this->value);
+  }
+}
+
+/**
+ * Date Type of CFPropertyList
+ * Note: CFDate uses Unix timestamp (epoch) to store dates internally
+ * @author Rodney Rehm <[email protected]>
+ * @author Christian Kruse <[email protected]>
+ * @package plist
+ * @subpackage plist.types
+ */
+class CFDate extends CFType {
+  const TIMESTAMP_APPLE = 0;
+  const TIMESTAMP_UNIX  = 1;
+  const DATE_DIFF_APPLE_UNIX = 978307200;
+
+  /**
+   * Create new Date CFType.
+   * @param integer $value timestamp to set
+   * @param integer $format format the timestamp is specified in, use {@link TIMESTAMP_APPLE} or {@link TIMESTAMP_UNIX}, defaults to {@link TIMESTAMP_APPLE}
+   * @uses setValue() to convert the timestamp
+   */
+  function __construct($value,$format=CFDate::TIMESTAMP_UNIX) {
+    $this->setValue($value,$format);
+  }
+
+  /**
+   * Set the Date CFType's value.
+   * @param integer $value timestamp to set
+   * @param integer $format format the timestamp is specified in, use {@link TIMESTAMP_APPLE} or {@link TIMESTAMP_UNIX}, defaults to {@link TIMESTAMP_UNIX}
+   * @return void
+   * @uses TIMESTAMP_APPLE to determine timestamp type
+   * @uses TIMESTAMP_UNIX to determine timestamp type
+   * @uses DATE_DIFF_APPLE_UNIX to convert Apple-timestamp to Unix-timestamp
+   */
+  function setValue($value,$format=CFDate::TIMESTAMP_UNIX) {
+    if($format == CFDate::TIMESTAMP_UNIX) $this->value = $value;
+    else $this->value = $value + CFDate::DATE_DIFF_APPLE_UNIX;
+  }
+  
+  /**
+   * Get the Date CFType's value.
+   * @param integer $format format the timestamp is specified in, use {@link TIMESTAMP_APPLE} or {@link TIMESTAMP_UNIX}, defaults to {@link TIMESTAMP_UNIX}
+   * @return integer Unix timestamp
+   * @uses TIMESTAMP_APPLE to determine timestamp type
+   * @uses TIMESTAMP_UNIX to determine timestamp type
+   * @uses DATE_DIFF_APPLE_UNIX to convert Unix-timestamp to Apple-timestamp
+   */
+  function getValue($format=CFDate::TIMESTAMP_UNIX) {
+    if($format == CFDate::TIMESTAMP_UNIX) return $this->value;
+    else return $this->value - CFDate::DATE_DIFF_APPLE_UNIX;
+  }
+
+  /**
+   * Get XML-Node.
+   * @param DOMDocument $doc DOMDocument to create DOMNode in
+   * @return DOMNode &lt;date&gt;-Element
+   */
+  public function toXML(DOMDocument $doc) {
+    $text = $doc->createTextNode(gmdate("Y-m-d\TH:i:s\Z",$this->getValue()));
+    $node = $doc->createElement("date");
+    $node->appendChild($text);
+    return $node;
+  }
+
+  /**
+   * convert value to binary representation
+   * @param CFBinaryPropertyList The binary property list object
+   * @return The offset in the object table
+   */
+  public function toBinary(CFBinaryPropertyList &$bplist) {
+    return $bplist->dateToBinary($this->value);
+  }
+  
+  /**
+   * Create a UNIX timestamp from a PList date string
+   * @param string $val The date string (e.g. "2009-05-13T20:23:43Z")
+   * @return integer The UNIX timestamp
+   * @throws PListException when encountering an unknown date string format
+   */
+  public static function dateValue($val) {
+    //2009-05-13T20:23:43Z
+    if(!preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z/',$val,$matches)) throw new PListException("Unknown date format: $val");
+    return gmmktime($matches[4],$matches[5],$matches[6],$matches[2],$matches[3],$matches[1]);
+  }
+}
+
+/**
+ * Boolean Type of CFPropertyList
+ * @author Rodney Rehm <[email protected]>
+ * @author Christian Kruse <[email protected]>
+ * @package plist
+ * @subpackage plist.types
+ */
+class CFBoolean extends CFType {
+  /**
+   * Get XML-Node.
+   * Returns &lt;true&gt; if $value is a true, &lt;false&gt; if $value is false.
+   * @param DOMDocument $doc DOMDocument to create DOMNode in
+   * @return DOMNode &lt;true&gt; or &lt;false&gt;-Element 
+   */
+  public function toXML(DOMDocument $doc) {
+    return $doc->createElement($this->value ? 'true' : 'false');
+  }
+
+  /**
+   * convert value to binary representation
+   * @param CFBinaryPropertyList The binary property list object
+   * @return The offset in the object table
+   */
+  public function toBinary(CFBinaryPropertyList &$bplist) {
+    return $bplist->boolToBinary($this->value);
+  }
+
+}
+
+/**
+ * Data Type of CFPropertyList
+ * Note: Binary data is base64-encoded.
+ * @author Rodney Rehm <[email protected]>
+ * @author Christian Kruse <[email protected]>
+ * @package plist
+ * @subpackage plist.types
+ */
+class CFData extends CFType {
+  /**
+   * Create new Data CFType
+   * @param string $value data to be contained by new object
+   * @param boolean $already_coded if true $value will not be base64-encoded, defaults to false
+   */
+  public function __construct($value=null,$already_coded=false) {
+    if($already_coded) $this->value = $value;
+    else $this->setValue($value);
+  }
+
+  /**
+   * Set the CFType's value and base64-encode it.
+   * <b>Note:</b> looks like base64_encode has troubles with UTF-8 encoded strings
+   * @return void
+   */
+  public function setValue($value) {
+    //if(function_exists('mb_check_encoding') && mb_check_encoding($value, 'UTF-8')) $value = utf8_decode($value);
+    $this->value = base64_encode($value);
+  }
+
+  /**
+   * Get base64 encoded data
+   * @return string The base64 encoded data value
+   */
+  public function getCodedValue() {
+    return $this->value;
+  }
+
+  /**
+   * Get the base64-decoded CFType's value.
+   * @return mixed CFType's value
+   */
+  public function getValue() {
+    return base64_decode($this->value);
+  }
+
+  /**
+   * Get XML-Node.
+   * @param DOMDocument $doc DOMDocument to create DOMNode in
+   * @return DOMNode &lt;data&gt;-Element
+   */
+  public function toXML(DOMDocument $doc) {
+    return parent::toXML($doc, 'data');
+  }
+
+  /**
+   * convert value to binary representation
+   * @param CFBinaryPropertyList The binary property list object
+   * @return The offset in the object table
+   */
+  public function toBinary(CFBinaryPropertyList &$bplist) {
+    return $bplist->dataToBinary($this->getValue());
+  }
+}
+
+/**
+ * Array Type of CFPropertyList
+ * @author Rodney Rehm <[email protected]>
+ * @author Christian Kruse <[email protected]>
+ * @package plist
+ * @subpackage plist.types
+ */
+class CFArray extends CFType implements Iterator {
+  /**
+   * Position of iterator {@link http://php.net/manual/en/class.iterator.php}
+   * @var integer
+   */
+  protected $iteratorPosition = 0;
+
+
+  /**
+   * Create new CFType.
+   * @param array $value Value of CFType
+   */
+  public function __construct($value=array()) {
+    $this->value = $value;
+  }
+
+  /**
+   * Set the CFType's value
+   * <b>Note:</b> this dummy does nothing
+   * @return void
+   */
+  public function setValue($value) {
+  }
+
+  /**
+   * Add CFType to collection.
+   * @param CFType $value CFType to add to collection
+   * @return void
+   * @uses $value for adding $value
+   */
+  public function add($value) {
+    $this->value[] = $value;
+  }
+
+  /**
+   * Get CFType from collection.
+   * @param integer $key Key of CFType to retrieve from collection
+   * @return CFType CFType found at $key, null else
+   * @uses $value for retrieving CFType of $key
+   */
+  public function get($key) {
+    if(isset($this->value[$key])) return $this->value[$key];
+    return null;
+  }
+
+  /**
+   * Remove CFType from collection.
+   * @param integer $key Key of CFType to removes from collection
+   * @return CFType removed CFType, null else
+   * @uses $value for removing CFType of $key
+   */
+  public function del($key) {
+    if(isset($this->value[$key])) unset($this->value[$key]);
+  }
+
+
+  /************************************************************************************************
+   *    S E R I A L I Z I N G
+   ************************************************************************************************/
+
+  /**
+   * Get XML-Node.
+   * @param DOMDocument $doc DOMDocument to create DOMNode in
+   * @return DOMNode &lt;array&gt;-Element
+   */
+  public function toXML(DOMDocument $doc) {
+    $node = $doc->createElement('array');
+
+    foreach($this->value as $value) $node->appendChild($value->toXML($doc));
+    return $node;
+  }
+
+  /**
+   * convert value to binary representation
+   * @param CFBinaryPropertyList The binary property list object
+   * @return The offset in the object table
+   */
+  public function toBinary(CFBinaryPropertyList &$bplist) {
+    return $bplist->arrayToBinary($this);
+  }
+
+  /**
+   * Get CFType's value.
+   * @return array primitive value
+   * @uses $value for retrieving primitive of CFType
+   */
+  public function toArray() {
+    $a = array();
+    foreach($this->value as $value) $a[] = $value->toArray();
+    return $a;
+  }
+
+
+  /************************************************************************************************
+   *    I T E R A T O R   I N T E R F A C E
+   ************************************************************************************************/
+
+  /**
+   * Rewind {@link $iteratorPosition} to first position (being 0)
+   * @link http://php.net/manual/en/iterator.rewind.php
+   * @return void
+   * @uses $iteratorPosition set to 0
+   */
+  public function rewind() {
+    $this->iteratorPosition = 0;
+  }
+
+  /**
+   * Get Iterator's current {@link CFType} identified by {@link $iteratorPosition}
+   * @link http://php.net/manual/en/iterator.current.php
+   * @return CFType current Item
+   * @uses $iteratorPosition identify current key
+   */
+  public function current() {
+    return $this->value[$this->iteratorPosition];
+  }
+
+  /**
+   * Get Iterator's current key identified by {@link $iteratorPosition}
+   * @link http://php.net/manual/en/iterator.key.php
+   * @return string key of the current Item
+   * @uses $iteratorPosition identify current key
+   */
+  public function key() {
+    return $this->iteratorPosition;
+  }
+
+  /**
+   * Increment {@link $iteratorPosition} to address next {@see CFType}
+   * @link http://php.net/manual/en/iterator.next.php
+   * @return void
+   * @uses $iteratorPosition increment by 1
+   */
+  public function next() {
+    $this->iteratorPosition++;
+  }
+
+  /**
+   * Test if {@link $iteratorPosition} addresses a valid element of {@link $value}
+   * @link http://php.net/manual/en/iterator.valid.php
+   * @return boolean true if current position is valid, false else
+   * @uses $iteratorPosition test if within {@link $iteratorKeys}
+   * @uses $iteratorPosition test if within {@link $value}
+   */
+  public function valid() {
+    return isset($this->value[$this->iteratorPosition]);
+  }
+
+}
+
+/**
+ * Array Type of CFPropertyList
+ * @author Rodney Rehm <[email protected]>
+ * @author Christian Kruse <[email protected]>
+ * @package plist
+ * @subpackage plist.types
+ */
+class CFDictionary extends CFType implements Iterator {
+  /**
+   * Position of iterator {@link http://php.net/manual/en/class.iterator.php}
+   * @var integer
+   */
+  protected $iteratorPosition = 0;
+
+  /**
+   * List of Keys for numerical iterator access {@link http://php.net/manual/en/class.iterator.php}
+   * @var array
+   */
+  protected $iteratorKeys = null;
+
+
+  /**
+   * Create new CFType.
+   * @param array $value Value of CFType
+   */
+  public function __construct($value=array()) {
+    $this->value = $value;
+  }
+
+  /**
+   * Set the CFType's value
+   * <b>Note:</b> this dummy does nothing
+   * @return void
+   */
+  public function setValue($value) {
+  }
+
+  /**
+   * Add CFType to collection.
+   * @param string $key Key to add to collection
+   * @param CFType $value CFType to add to collection
+   * @return void
+   * @uses $value for adding $key $value pair
+   */
+  public function add($key, $value) {
+    $this->value[$key] = $value;
+  }
+
+  /**
+   * Get CFType from collection.
+   * @param string $key Key of CFType to retrieve from collection
+   * @return CFType CFType found at $key, null else
+   * @uses $value for retrieving CFType of $key
+   */
+  public function get($key) {
+    if(isset($this->value[$key])) return $this->value[$key];
+    return null;
+  }
+
+  /**
+   * Remove CFType from collection.
+   * @param string $key Key of CFType to removes from collection
+   * @return CFType removed CFType, null else
+   * @uses $value for removing CFType of $key
+   */
+  public function del($key) {
+    if(isset($this->value[$key])) unset($this->value[$key]);
+  }
+
+
+  /************************************************************************************************
+   *    S E R I A L I Z I N G
+   ************************************************************************************************/
+
+  /**
+   * Get XML-Node.
+   * @param DOMDocument $doc DOMDocument to create DOMNode in
+   * @return DOMNode &lt;dict&gt;-Element
+   */
+  public function toXML(DOMDocument $doc) {
+    $node = $doc->createElement('dict');
+
+    foreach($this->value as $key => $value) {
+      $node->appendChild($doc->createElement('key', $key));
+      $node->appendChild($value->toXML($doc));
+    }
+
+    return $node;
+  }
+
+  /**
+   * convert value to binary representation
+   * @param CFBinaryPropertyList The binary property list object
+   * @return The offset in the object table
+   */
+  public function toBinary(CFBinaryPropertyList &$bplist) {
+    return $bplist->dictToBinary($this);
+  }
+
+  /**
+   * Get CFType's value.
+   * @return array primitive value
+   * @uses $value for retrieving primitive of CFType
+   */
+  public function toArray() {
+    $a = array();
+
+    foreach($this->value as $key => $value) $a[$key] = $value->toArray();
+    return $a;
+  }
+
+
+  /************************************************************************************************
+   *    I T E R A T O R   I N T E R F A C E
+   ************************************************************************************************/
+
+  /**
+   * Rewind {@link $iteratorPosition} to first position (being 0)
+   * @link http://php.net/manual/en/iterator.rewind.php
+   * @return void
+   * @uses $iteratorPosition set to 0
+   * @uses $iteratorKeys store keys of {@link $value}
+   */
+  public function rewind() {
+    $this->iteratorPosition = 0;
+    $this->iteratorKeys = array_keys($this->value);
+  }
+
+  /**
+   * Get Iterator's current {@link CFType} identified by {@link $iteratorPosition}
+   * @link http://php.net/manual/en/iterator.current.php
+   * @return CFType current Item
+   * @uses $iteratorPosition identify current key
+   * @uses $iteratorKeys identify current value
+   */
+  public function current() {
+    return $this->value[$this->iteratorKeys[$this->iteratorPosition]];
+  }
+
+  /**
+   * Get Iterator's current key identified by {@link $iteratorPosition}
+   * @link http://php.net/manual/en/iterator.key.php
+   * @return string key of the current Item
+   * @uses $iteratorPosition identify current key
+   * @uses $iteratorKeys identify current value
+   */
+  public function key() {
+    return $this->iteratorKeys[$this->iteratorPosition];
+  }
+
+  /**
+   * Increment {@link $iteratorPosition} to address next {@see CFType}
+   * @link http://php.net/manual/en/iterator.next.php
+   * @return void
+   * @uses $iteratorPosition increment by 1
+   */
+  public function next() {
+    $this->iteratorPosition++;
+  }
+
+  /**
+   * Test if {@link $iteratorPosition} addresses a valid element of {@link $value}
+   * @link http://php.net/manual/en/iterator.valid.php
+   * @return boolean true if current position is valid, false else
+   * @uses $iteratorPosition test if within {@link $iteratorKeys}
+   * @uses $iteratorPosition test if within {@link $value}
+   */
+  public function valid() {
+    return isset($this->iteratorKeys[$this->iteratorPosition]) && isset($this->value[$this->iteratorKeys[$this->iteratorPosition]]);
+  }
+
+}
+
+?>

+ 99 - 0
Tools/projectGenerator/classes/plist/IOException.php

@@ -0,0 +1,99 @@
+<?php
+/**
+ * CFPropertyList
+ * {@link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists}
+ * @author Rodney Rehm <[email protected]>
+ * @author Christian Kruse <[email protected]>
+ * @package plist
+ * @version $Id$
+ */
+
+/**
+ * Basic Input / Output Exception
+ * @author Rodney Rehm <[email protected]>
+ * @author Christian Kruse <[email protected]>
+ * @package plist
+ */
+class IOException extends Exception {
+  /**
+   * Flag telling the File could not be found
+   */
+  const NOT_FOUND = 1;
+  
+  /**
+   * Flag telling the File is not readable
+   */
+  const NOT_READABLE = 2;
+  
+  /**
+   * Flag telling the File is not writable
+   */
+  const NOT_WRITABLE = 3;
+
+  /**
+   * Flag telling there was a read error
+   */
+  const READ_ERROR = 4;
+
+  /**
+   * Flag telling there was a read error
+   */
+  const WRITE_ERROR = 5;
+
+  /**
+   * Create new IOException
+   * @param string $path Source of the problem
+   * @param integer $type Type of the problem
+   */
+  public function __construct($path, $type=null) {
+    parent::__construct( $path, $type );
+  }
+  
+  /**
+   * Create new FileNotFound-Exception
+   * @param string $path Source of the problem
+   * @return IOException new FileNotFound-Exception
+   */
+  public static function notFound($path) {
+    return new IOException( $path, self::NOT_FOUND );
+  }
+
+  /**
+   * Create new FileNotReadable-Exception
+   * @param string $path Source of the problem
+   * @return IOException new FileNotReadable-Exception
+   */
+  public static function notReadable($path) {
+    return new IOException( $path, self::NOT_READABLE );
+  }
+
+  /**
+   * Create new FileNotWritable-Exception
+   * @param string $path Source of the problem
+   * @return IOException new FileNotWritable-Exception
+   */
+  public static function notWritable($path) {
+    return new IOException( $path, self::NOT_WRITABLE );
+  }
+
+  /**
+   * Create new ReadError-Exception
+   * @param string $path Source of the problem
+   * @return IOException new ReadError-Exception
+   */
+  public static function readError($path) {
+    return new IOException( $path, self::READ_ERROR );
+  }
+
+  /**
+   * Create new WriteError-Exception
+   * @param string $path Source of the problem
+   * @return IOException new WriteError-Exception
+   */
+  public static function writeError($path) {
+    return new IOException( $path, self::WRITE_ERROR );
+  }
+}
+
+
+?>

+ 22 - 0
Tools/projectGenerator/classes/plist/LICENSE

@@ -0,0 +1,22 @@
+The MIT License
+
+Copyright (c) 2009 Christian Kruse, Rodney Rehm
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+

+ 22 - 0
Tools/projectGenerator/classes/plist/PListException.php

@@ -0,0 +1,22 @@
+<?php
+/**
+ * CFPropertyList
+ * {@link http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html Property Lists}
+ * @author Rodney Rehm <[email protected]>
+ * @author Christian Kruse <[email protected]>
+ * @package plist
+ * @version $Id$
+ */
+
+/**
+ * Exception for errors with the PList format
+ * @author Rodney Rehm <[email protected]>
+ * @author Christian Kruse <[email protected]>
+ * @package plist
+ */
+class PListException extends Exception {
+
+}
+
+
+?>

+ 277 - 0
Tools/projectGenerator/libs/Torque3D.conf

@@ -0,0 +1,277 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+// Libs
+includeLib( 'mng' );
+includeLib( 'png' );
+includeLib( 'ungif' );
+includeLib( 'zlib' );
+includeLib( 'jpeg' );
+includeLib( 'tinyxml' );
+includeLib( 'opcode' );
+includeLib( 'squish' );
+includeLib( 'collada_dom' );
+includeLib( 'pcre' ); 
+includeLib( 'convexDecomp' ); 
+
+// Use FMOD on consoles
+if ( Generator::$platform != "360" && Generator::$platform != "ps3" )
+{
+   includeLib( 'libvorbis' );
+   includeLib( 'libogg' );
+   includeLib( 'libtheora' );
+}
+
+$ext = "DLL";
+if ( Generator::$platform == "mac" )
+   $ext = "Bundle";
+
+// We need to pick the right physics engine to include.
+global $USE_BULLET_PHYSICS;
+global $PHYSX_SDK_PATH;
+
+//some platforms will not want a shared config
+$useSharedConfig = true;
+if ( Generator::$platform == "360" || Generator::$platform == "ps3" )
+   $useSharedConfig = false;
+
+//begin either a shared lib config, or a static app config
+if ( $useSharedConfig )
+   beginSharedLibConfig( getGameProjectName().' '.$ext, '{C0FCDFF9-E125-412E-87BC-2D89DB971CAB}', 'game', getGameProjectName() );
+else
+   beginAppConfig( getGameProjectName(), '{C0FCDFF9-E125-412E-87BC-2D89DB971CAB}', 'game', getGameProjectName() );
+        
+    /// Prefs
+    addProjectDefine( 'TORQUE_SHADERGEN' );
+    addProjectDefine( 'TORQUE_UNICODE' );
+    
+    if ( $useSharedConfig )
+       addProjectDefine( 'TORQUE_SHARED' );    
+
+    /// For OPCODE
+    addProjectDefine( 'BAN_OPCODE_AUTOLINK' );
+    addProjectDefine( 'ICE_NO_DLL' );
+    addProjectDefine( 'TORQUE_OPCODE' );
+
+    // For libTomCrypt
+    addProjectDefine( 'LTC_NO_PROTOTYPES' );
+    
+    // Additional includes
+    addIncludePath( "../../game/shaders" );
+    
+    addLibIncludePath( "lmng" );
+    addLibIncludePath( "lpng" );
+    addLibIncludePath( "ljpeg" );
+    addLibIncludePath( "lungif" );
+    addLibIncludePath( "zlib" );
+    addLibIncludePath( "tinyxml" );
+    addLibIncludePath( "opcode" );
+    addLibIncludePath( "squish" );
+    addLibIncludePath( "convexDecomp" );
+    
+    if ( Generator::$platform != "360" && Generator::$platform != "ps3" )
+    {
+      addLibIncludePath( "libvorbis/include" );
+      addLibIncludePath( "libogg/include" );
+      addLibIncludePath( "libtheora/include" );
+    }
+    
+    // Modules
+    
+    includeModule( 'Torque3D' );
+    includeModule( 'core' );
+    includeModule( 'dsound' );
+    includeModule( 'fmod');
+    includeModule( 'T3D' );
+    includeModule( 'advancedLighting' );
+    includeModule( 'basicLighting' );
+    includeModule( 'collada' );
+    
+    if ( Generator::$platform != "360" && Generator::$platform != "ps3" )
+    {
+      includeModule( 'vorbis' );
+      includeModule( 'theora' );
+    }
+   
+    if(Generator::$platform == "mac" || Generator::$platform == "win32")
+       includeModule( 'openal' );
+
+    // Demo functionality
+    if (getDemoBuild())
+       includeModule( 'demo' );
+    if (getWatermarkBuild())
+       includeModule( 'demoWatermark' );
+    if (getPurchaseScreenBuild())
+       includeModule( 'demoPurchaseScreen' );
+    if (getObjectLimitBuild())
+       includeModule( 'demoObjectLimit' );
+    if (getTimeOutBuild())
+       includeModule( 'demoTimeout' );
+   
+    // Dependencies
+    
+    addProjectDependency( 'lmng' );
+    addProjectDependency( 'lpng' );
+    addProjectDependency( 'lungif' );
+    addProjectDependency( 'ljpeg' );
+    addProjectDependency( 'zlib' );
+    addProjectDependency( 'tinyxml' );   
+    addProjectDependency( 'opcode' );
+    addProjectDependency( 'squish' );
+    addProjectDependency( 'collada_dom' );
+    addProjectDependency( 'pcre' );
+    addProjectDependency( 'convexDecomp' );
+    
+    if ( Generator::$platform != "360" && Generator::$platform != "ps3" )
+    {
+      addProjectDependency( 'libvorbis' );
+      addProjectDependency( 'libogg' );
+      addProjectDependency( 'libtheora' );
+    }
+
+    if ( $USE_BULLET_PHYSICS == true )
+    {
+        includeModule( 'bullet' );
+        addProjectDependency( 'libbullet' );
+    }
+    
+    if ( $PHYSX_SDK_PATH != "" )
+    {
+        includeModule( 'physx' );
+        addProjectDependency( 'nxCharacter' );
+        addProjectDependency( 'nxuStream' );
+    }
+    
+    if ( Generator::$platform == "mac" )
+    {    
+        addProjectDefine( '__MACOSX__' );
+        addProjectDefine( 'LTM_DESC' );
+    }
+
+    if (Generator::$platform == "win32")
+    {
+        setProjectModuleDefinitionFile('../../' . getLibSrcDir() . 'Torque3D/msvc/torque3d.def');
+
+        addProjectDefine( 'UNICODE' );
+        addProjectDefine( 'INITGUID' );
+        addProjectDefine( '_CRT_SECURE_NO_DEPRECATE' );
+        
+
+        addProjectLibInput('COMCTL32.LIB');
+        addProjectLibInput('COMDLG32.LIB');
+        addProjectLibInput('USER32.LIB');
+        addProjectLibInput('ADVAPI32.LIB');
+        addProjectLibInput('GDI32.LIB');
+        addProjectLibInput('WINMM.LIB');
+        addProjectLibInput('WSOCK32.LIB');
+        addProjectLibInput('vfw32.lib');
+        addProjectLibInput('Imm32.lib');
+        addProjectLibInput('d3d9.lib');
+        addProjectLibInput('d3dx9.lib');
+        addProjectLibInput('DxErr.lib');
+        addProjectLibInput('ole32.lib');
+        addProjectLibInput('shell32.lib');
+        addProjectLibInput('oleaut32.lib');
+        addProjectLibInput('version.lib');
+    }
+    
+    // Include project specific sources in the project/buildFiles/config/projectCode.conf
+    $projectCode = realpath($argv[1])."/buildFiles/config/projectCode.conf";
+    echo( "\n   - Loading project code configuration from ".$projectCode."\n");
+    include $projectCode;
+
+//end shared/static config
+if ( $useSharedConfig )
+   endSharedLibConfig();
+else
+   endAppConfig();
+
+//add the shared application only if this is a shared config
+if ( $useSharedConfig )
+{
+/////// Application Config
+beginSharedAppConfig( getGameProjectName(), '{CDECDFF9-E125-523F-87BC-2D89DB971CAB}' );
+
+	addProjectDefine( 'TORQUE_SHARED' );
+
+	addEngineSrcDir( 'main' );
+    
+    if (Generator::$platform == "win32")
+    {
+        addProjectDefine( 'WIN32' );
+        addProjectDependency( getGameProjectName() . ' DLL' );
+    }
+
+    if (Generator::$platform == "mac")
+    {
+        addProjectDefine( '__MACOSX__' );
+        addProjectDependency( getGameProjectName() . ' Bundle' );
+        addProjectDependency( getGameProjectName() . ' Plugin' );
+    }
+
+endSharedAppConfig();
+}
+
+// Add solution references for Visual Studio projects
+if (Generator::$platform == "win32" || Generator::$platform == "360" || Generator::$platform == "ps3")
+{
+if ( !$useSharedConfig )
+   beginSolutionConfig( getGameProjectName(), '{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}' );
+   
+   addSolutionProjectRef( getGameProjectName() );
+   if ( $useSharedConfig )
+      addSolutionProjectRef( getGameProjectName() . ' DLL' );
+   addSolutionProjectRef( 'collada_dom' );
+   addSolutionProjectRef( 'ljpeg' );
+   addSolutionProjectRef( 'lmng' );
+   addSolutionProjectRef( 'lpng' );
+   addSolutionProjectRef( 'lungif' );
+   addSolutionProjectRef( 'opcode' );
+   addSolutionProjectRef( 'pcre' );
+   addSolutionProjectRef( 'squish' );
+   addSolutionProjectRef( 'tinyxml' );
+   addSolutionProjectRef( 'zlib' );
+   addSolutionProjectRef( 'convexDecomp' );
+   
+   if (Generator::$platform == "win32")
+   {
+      addSolutionProjectRef( 'libogg' );
+      addSolutionProjectRef( 'libvorbis' );
+      addSolutionProjectRef( 'libtheora' );
+   }
+   
+   if ( $USE_BULLET_PHYSICS == true )
+      addSolutionProjectRef( 'libbullet' );
+   
+   if ( $PHYSX_SDK_PATH != "" )
+   {
+      // For PhysX support.
+      addSolutionProjectRef( 'nxCharacter' );
+      addSolutionProjectRef( 'nxuStream' );
+   }
+   
+if ( !$useSharedConfig )
+   endSolutionConfig();
+}
+
+?>

+ 77 - 0
Tools/projectGenerator/libs/WebDeploy.conf

@@ -0,0 +1,77 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+if (Generator::$platform == "win32")
+{
+    // Include the web deployment settings
+    $webDeployConf = realpath($argv[1])."/buildFiles/config/webDeploy.conf";
+    echo( "\n   - Loading web deployment configuration from ".$webDeployConf."\n");
+
+    require_once( $webDeployConf);
+
+    // The NP plugin MUST begin with NP for Firefox to recognize it
+    // Also, the plugin uses the filename to locate your game library, so much begin with either "NP " or "IE " and end with " Plugin"
+    // If you want to change this behavior, you can modify the plugin source code in webCommon.cpp
+
+    WebDeploymentWindows::$npPluginName = 'NP ' . getGameProjectName() . ' Plugin';
+    WebDeploymentWindows::$axPluginName = 'IE ' . getGameProjectName() . ' Plugin';
+
+    beginActiveXConfig( WebDeploymentWindows::$axPluginName, '{CDECDFF9-E125-412E-87CD-2D89DB971CAB}' );
+
+        addProjectDependency( getGameProjectName() . ' DLL' );
+
+    endActiveXConfig();
+
+
+    beginNPPluginConfig( WebDeploymentWindows::$npPluginName, '{CDECDFF9-E125-412E-87BC-2D89DB971CAB}' );
+        
+       addProjectDependency( getGameProjectName() . ' DLL' );
+
+    endNPPluginConfig();
+    
+    // If not building for web deploy, these can be removed
+	addSolutionProjectRef(  WebDeploymentWindows::$npPluginName );
+	addSolutionProjectRef(  WebDeploymentWindows::$axPluginName );
+
+}
+
+if (Generator::$platform == "mac")
+{
+    // Include the web deployment settings
+    $webDeployConf = realpath($argv[1])."/buildFiles/config/webDeploy.mac.conf";
+    echo( "\n   - Loading web deployment configuration from ".$webDeployConf."\n");
+
+    require_once( $webDeployConf);
+
+    WebDeploymentOSX::$safariPluginName = getGameProjectName() . ' Plugin';
+
+    beginSafariConfig( getGameProjectName() . ' Plugin', '{CCDEDFF9-E136-412E-87BC-2D89DB971CAB}' );
+	
+        // Dependencies
+        addProjectDependency( getGameProjectName() . ' Bundle' );
+
+    endSafariConfig();
+
+}
+
+?>

+ 50 - 0
Tools/projectGenerator/libs/collada_dom.conf

@@ -0,0 +1,50 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginLibConfig( 'collada_dom', '{25D580F1-2A2C-48EB-89C6-B54CAF4BDC4E}' );
+
+	// Source
+	addLibSrcDir( 'collada/src/1.4/dom' );
+	addLibSrcDir( 'collada/src/dae' );
+	addLibSrcDir( 'collada/src/modules/LIBXMLPlugin' );
+	addLibSrcDir( 'collada/src/modules/stdErrPlugin' );
+	addLibSrcDir( 'collada/src/modules/STLDatabase' );
+
+	// Additional includes
+	addLibIncludePath( 'collada/include' );
+	addLibIncludePath( 'collada/include/1.4' );
+
+	addLibIncludePath( "pcre" );
+	addLibIncludePath( "tinyxml" );
+
+	// Defines
+	addProjectDefine( 'DOM_INCLUDE_TINYXML' );
+	addProjectDefine( 'PCRE_STATIC' );
+
+	// Dependencies
+	addProjectDependency( 'pcre' );
+	addProjectDependency( 'tinyxml' );
+
+endLibConfig();
+
+?>

+ 43 - 0
Tools/projectGenerator/libs/convexDecomp.conf

@@ -0,0 +1,43 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginLibConfig( 'convexDecomp', '{4EF87A4E-16ED-4E64-BF04-841B2675AEE0}' );
+      
+   // Source
+   addLibSrcDir( 'convexDecomp' );
+
+   // Additional includes
+   addLibIncludePath( 'convexDecomp' );
+
+   if ( Generator::$platform == "360" )
+      addProjectDefine( '_XBOX' );  
+   else if ( Generator::$platform == "ps3" )
+      addProjectDefine( '__CELLOS_LV2__' );       
+   else if ( Generator::$platform == "mac" )
+      addProjectDefine( '__APPLE__' );   
+   else if ( Generator::$platform == "win32" )
+      addProjectDefine( 'WIN32' );
+
+endLibConfig();
+
+?>

+ 30 - 0
Tools/projectGenerator/libs/d3dx8dll.conf

@@ -0,0 +1,30 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginLibConfig( 'd3dx8dll', '{38337D6D-B574-4871-9FF1-0B7B4981AA74}' );
+
+    includeModule( 'd3dx8dll' );
+
+endLibConfig();
+
+?>

+ 30 - 0
Tools/projectGenerator/libs/jpeg.conf

@@ -0,0 +1,30 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginLibConfig( 'ljpeg', '{E2A746EC-8AD3-4D45-AFBB-5A81F705E9BE}' );
+
+includeModule( 'jpeg' );
+
+endLibConfig();
+
+?>

+ 58 - 0
Tools/projectGenerator/libs/libbullet.conf

@@ -0,0 +1,58 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginLibConfig( 'libbullet', '{4368B65C-F5EF-4D28-B533-B02A04EBE921}' );
+      
+   // Source
+   addLibSrcDir( 'bullet/src' );
+   addLibSrcDir( 'bullet/src/BulletCollision' );
+   addLibSrcDir( 'bullet/src/BulletCollision/BroadphaseCollision' );
+   addLibSrcDir( 'bullet/src/BulletCollision/CollisionDispatch' );
+   addLibSrcDir( 'bullet/src/BulletCollision/CollisionShapes' );
+   addLibSrcDir( 'bullet/src/BulletCollision/Gimpact' );
+   addLibSrcDir( 'bullet/src/BulletCollision/NarrowPhaseCollision' );
+   addLibSrcDir( 'bullet/src/BulletDynamics' );
+   addLibSrcDir( 'bullet/src/BulletDynamics/Character' );
+   addLibSrcDir( 'bullet/src/BulletDynamics/ConstraintSolver' );
+   addLibSrcDir( 'bullet/src/BulletDynamics/Dynamics' );
+   addLibSrcDir( 'bullet/src/BulletDynamics/Vehicle' );
+   addLibSrcDir( 'bullet/src/LinearMath' );
+   
+   // TODO: Can we do multicore on OSX?
+   if (  Generator::$platform == "win32" ||
+         Generator::$platform == "360" )
+   {
+      addProjectDefine( 'WIN32' );
+
+      addLibSrcDir( 'bullet/src/BulletMultiThreaded' );
+      addLibSrcDir( 'bullet/src/BulletMultiThreaded/MiniCLTask' );
+      addLibSrcDir( 'bullet/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask' );
+      addLibIncludePath( 'bullet/src/BulletMultiThreaded/vectormath/scalar/cpp' );
+   }
+
+   // Additional includes
+   addLibIncludePath( 'bullet/src' );
+   
+endLibConfig();
+
+?>

+ 30 - 0
Tools/projectGenerator/libs/libogg.conf

@@ -0,0 +1,30 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginLibConfig( 'libogg', '{719523DB-7C6B-416B-B68D-B2579477239B}' );
+
+includeModule( 'libogg' );
+
+endLibConfig();
+
+?>

+ 30 - 0
Tools/projectGenerator/libs/libtheora.conf

@@ -0,0 +1,30 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginLibConfig( 'libtheora', '{B0B6B74B-2045-43B0-85BF-A24BF2D25155}' );
+
+includeModule( 'libtheora' );
+
+endLibConfig();
+
+?>

+ 30 - 0
Tools/projectGenerator/libs/libvorbis.conf

@@ -0,0 +1,30 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginLibConfig( 'libvorbis', '{F8240290-BA36-4696-967F-C2611CEE501A}' );
+
+includeModule( 'libvorbis' );
+
+endLibConfig();
+
+?>

+ 33 - 0
Tools/projectGenerator/libs/mng.conf

@@ -0,0 +1,33 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginLibConfig( 'lmng', '{73D9048F-55AA-4EF6-BF33-3A811DC47FCE}' );
+	// Defines
+	addProjectDefine( 'MNG_OPTIMIZE_OBJCLEANUP' );
+
+	// Modules
+	includeModule( 'mng' );
+	
+endLibConfig();
+
+?>

+ 30 - 0
Tools/projectGenerator/libs/nxCharacter.conf

@@ -0,0 +1,30 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginLibConfig( 'nxCharacter', '{CDECDFF9-E125-412E-87CD-2D89DB972DAC}' );
+
+	includeModule( 'nxCharacter' );
+
+endLibConfig();
+
+?>

+ 30 - 0
Tools/projectGenerator/libs/nxuStream.conf

@@ -0,0 +1,30 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginLibConfig( 'nxuStream', '{CDECDFF9-E125-412E-87CD-2E97DB971CAB}' );
+
+	includeModule( 'nxuStream' );
+
+endLibConfig();
+
+?>

+ 34 - 0
Tools/projectGenerator/libs/opcode.conf

@@ -0,0 +1,34 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginLibConfig( 'opcode', '{C0B7BA09-E125-412E-86B0-2D89DB971CAB}' );
+
+   // Defines
+   addProjectDefine( 'TORQUE_OPCODE' );
+	addProjectDefine( 'ICE_NO_DLL' );
+
+	includeModule( 'opcode' );
+
+endLibConfig();
+
+?>

+ 38 - 0
Tools/projectGenerator/libs/pcre.conf

@@ -0,0 +1,38 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginLibConfig( 'pcre', '{910A3F94-E18D-4CB9-87DC-382C75F6B941}' );
+
+	// Source
+	addLibSrcDir( 'pcre' );
+
+	// Additional includes
+	addLibIncludePath( 'pcre' );
+
+	// Defines
+	addProjectDefine( 'PCRE_STATIC' );
+	addProjectDefine( 'HAVE_CONFIG_H' );
+
+endLibConfig();
+
+?>

+ 30 - 0
Tools/projectGenerator/libs/png.conf

@@ -0,0 +1,30 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginLibConfig( 'lpng', '{63D63B58-3DB8-4844-9648-C5AA04B4C1BC}' );
+
+includeModule( 'png' );
+
+endLibConfig();
+
+?>

+ 30 - 0
Tools/projectGenerator/libs/squish.conf

@@ -0,0 +1,30 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginLibConfig( 'squish', '{3FFDBB50-6E27-4E66-B1EC-750663C9D799}' );
+
+includeModule( 'squish' );
+
+endLibConfig();
+
+?>

+ 30 - 0
Tools/projectGenerator/libs/tinyxml.conf

@@ -0,0 +1,30 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginLibConfig( 'tinyxml', '{470600AC-F51E-4F4E-9406-3B517BF112AC}' );
+
+includeModule( 'tinyxml' );
+
+endLibConfig();
+
+?>

+ 32 - 0
Tools/projectGenerator/libs/ungif.conf

@@ -0,0 +1,32 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginLibConfig( 'lungif', '{5C9BE928-8510-451E-B866-5C2ECF3E592F}' );
+
+addProjectDefine( '_GBA_NO_FILEIO' );
+
+includeModule( 'ungif' );
+
+endLibConfig();
+
+?>

+ 30 - 0
Tools/projectGenerator/libs/zlib.conf

@@ -0,0 +1,30 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginLibConfig( 'zlib', '{3FFDBB50-6E27-4E66-B1EC-750663C9D784}' );
+
+includeModule( 'zlib' );
+
+endLibConfig();
+
+?>

+ 92 - 0
Tools/projectGenerator/modules/T3D.inc

@@ -0,0 +1,92 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+// 3D
+addEngineSrcDir('collision');
+addEngineSrcDir('interior');
+addEngineSrcDir('materials');
+addEngineSrcDir('lighting');
+addEngineSrcDir('lighting/common');
+addEngineSrcDir('renderInstance');
+addEngineSrcDir('scene');
+addEngineSrcDir('scene/culling');
+addEngineSrcDir('scene/zones');
+addEngineSrcDir('scene/mixin');
+addEngineSrcDir('shaderGen');
+addEngineSrcDir('terrain');
+addEngineSrcDir('environment');
+
+addEngineSrcDir('forest');
+addEngineSrcDir('forest/ts');
+addEngineSrcDir('forest/editor');
+
+addEngineSrcDir('ts');
+addEngineSrcDir('ts/arch');
+addEngineSrcDir('physics');
+addEngineSrcDir('gui/3d');
+addEngineSrcDir('postFx' );
+
+// 3D game
+addEngineSrcDir('T3D');
+addEngineSrcDir('T3D/examples');
+addEngineSrcDir('T3D/fps');
+addEngineSrcDir('T3D/fx');
+addEngineSrcDir('T3D/vehicles');
+addEngineSrcDir('T3D/physics');
+addEngineSrcDir('T3D/decal');
+addEngineSrcDir('T3D/sfx');
+addEngineSrcDir('T3D/gameBase');
+addEngineSrcDir('T3D/turret');
+
+global $TORQUE_HIFI_NET;
+if ( $TORQUE_HIFI_NET == true )
+{
+   addProjectDefines( 'TORQUE_HIFI_NET' );
+   addEngineSrcDir('T3D/gameBase/hifi');
+}
+else
+	addEngineSrcDir('T3D/gameBase/std');
+
+// Plstform specific stuff.
+switch( Generator::$platform )
+{
+   case "360":
+      addEngineSrcDir('ts/arch/360');
+      // Fall through
+      
+   case "win32":
+      addEngineSrcDir( 'terrain/hlsl' );
+      addEngineSrcDir( 'forest/hlsl' );
+      break;
+
+   case "ps3":
+      addEngineSrcDir('ts/arch/ps3');
+      // Fall through
+      
+   case "mac":
+      addEngineSrcDir( 'terrain/glsl' );
+      addEngineSrcDir( 'forest/glsl' );
+      break;
+}
+
+?>

+ 30 - 0
Tools/projectGenerator/modules/Torque3D.inc

@@ -0,0 +1,30 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+
+beginModule( 'Torque3D' );
+
+
+endModule();
+
+?>

+ 46 - 0
Tools/projectGenerator/modules/advancedLighting.inc

@@ -0,0 +1,46 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginModule( 'advancedLighting' );
+
+    addProjectDefine( 'TORQUE_ADVANCED_LIGHTING' );
+
+	addEngineSrcDir( 'lighting/advanced' );
+	addEngineSrcDir( 'lighting/shadowMap' );
+
+   switch( Generator::$platform )
+   {
+      case "win32":
+         addEngineSrcDir( 'lighting/advanced/hlsl' );
+         break;
+      case "360":
+         addEngineSrcDir( 'lighting/advanced/hlsl' );
+         break;
+      case "mac":
+         addEngineSrcDir( 'lighting/advanced/glsl' );
+         break;
+   }
+
+endModule();
+
+?>

+ 33 - 0
Tools/projectGenerator/modules/basicLighting.inc

@@ -0,0 +1,33 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginModule( 'basicLighting' );
+
+   addProjectDefine( 'TORQUE_BASIC_LIGHTING' );
+
+   addEngineSrcDir( 'lighting/basic' );
+   addEngineSrcDir( 'lighting/shadowMap' );
+
+endModule();
+
+?>

+ 44 - 0
Tools/projectGenerator/modules/bullet.inc

@@ -0,0 +1,44 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginModule( 'bullet' );
+	           
+   addProjectDefine( "TORQUE_PHYSICS_BULLET" );
+   addProjectDefine( "TORQUE_PHYSICS_ENABLED" );
+
+   addEngineSrcDir( "T3D/physics/bullet" );
+
+   includeLib( 'libbullet' );
+   addLibIncludePath( "bullet/src" );
+
+   if (inProjectConfig())
+   {
+      addProjectDependency( 'libbullet' );
+
+      if (Generator::$platform != "mac")
+         addSolutionProjectRef( 'libbullet' );
+   }
+   
+endModule();
+
+?>

+ 39 - 0
Tools/projectGenerator/modules/collada.inc

@@ -0,0 +1,39 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginModule( 'collada' );
+
+	// Collada Loader
+	addProjectDefine( 'TORQUE_COLLADA' );
+	addProjectDefine( 'DOM_INCLUDE_TINYXML' );
+	addProjectDefine( 'PCRE_STATIC' );
+
+	addEngineSrcDir( 'ts/collada' );
+	addEngineSrcDir( 'ts/loader' );
+
+	addLibIncludePath( 'collada/include' );
+	addLibIncludePath( 'collada/include/1.4' );
+
+endModule();
+
+?>

+ 199 - 0
Tools/projectGenerator/modules/core.inc

@@ -0,0 +1,199 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+addEngineSrcDir('sfx/media');
+addEngineSrcDir('sfx/null');
+addEngineSrcDir('sfx');
+
+
+// Components
+addEngineSrcDir('component');
+addEngineSrcDir('component/interfaces');
+
+// Core
+if (Generator::isApp())
+	addSrcDir( '../source' );
+    
+addEngineSrcDir('console');
+addEngineSrcDir('core');
+addEngineSrcDir('core/stream');
+addEngineSrcDir('core/strings');
+addEngineSrcDir('core/util');
+addEngineSrcDir('core/util/test');
+addEngineSrcDir('core/util/journal');
+addEngineSrcDir('core/util/journal/test');
+addEngineSrcDir('core/util/zip');
+addEngineSrcDir('core/util/zip/unitTests');
+addEngineSrcDir('core/util/zip/compressors');
+addEngineSrcDir('i18n');
+addEngineSrcDir('sim');
+addEngineSrcDir('unit/tests');
+addEngineSrcDir('unit');
+addEngineSrcDir('util');
+addEngineSrcDir('windowManager');
+addEngineSrcDir('windowManager/torque');
+addEngineSrcDir('windowManager/test');
+addEngineSrcDir('math');
+addEngineSrcDir('math/util');
+addEngineSrcDir('math/test');
+addEngineSrcDir('platform');
+addEngineSrcDir('cinterface');
+
+switch( Generator::$platform )
+{
+   case "win32":
+   case "mac":
+   case "linux":
+     addEngineSrcDir('platform/nativeDialogs');
+     addEngineSrcDir('platform/menus');
+     addEngineSrcDir('platform/test');
+     break;
+}
+
+addEngineSrcDir('platform/threads');
+addEngineSrcDir('platform/async');
+addEngineSrcDir('app');
+addEngineSrcDir('app/net');
+
+// Moved this here temporarily because PopupMenu uses on it and is currently in core
+addEngineSrcDir('util/messaging');
+
+switch( Generator::$platform )
+{
+   case "win32":
+     addEngineSrcDir('platformWin32');
+     addEngineSrcDir('platformWin32/nativeDialogs');
+     addEngineSrcDir('platformWin32/menus');
+     addEngineSrcDir('platformWin32/threads');
+     addEngineSrcDir('platformWin32/videoInfo');
+     addEngineSrcDir('platformWin32/minidump');
+     addEngineSrcDir('windowManager/win32');
+     
+     break;
+
+   case "mac":
+     addEngineSrcDir('platformMac');
+     addEngineSrcDir('platformMac/menus');
+     addEngineSrcDir('platformPOSIX');
+     addEngineSrcDir('windowManager/mac');
+     break;
+
+   case "360":
+     addEngineSrcDir('platformXbox');
+     addEngineSrcDir('platformXbox/threads');
+     addEngineSrcDir('windowManager/360');
+     break;
+     
+   case "ps3":
+     addEngineSrcDir('platformPS3');
+     addEngineSrcDir('platformPS3/threads');
+     addEngineSrcDir('windowManager/ps3');
+     break;
+
+   case "linux":
+   case "linux_dedicated":
+     addEngineSrcDir('platformX86UNIX');
+     addEngineSrcDir('platformX86UNIX/threads');
+     addEngineSrcDir('platformPOSIX');
+     break;
+}
+
+// GFX
+addEngineSrcDir( 'gfx/Null' );
+addEngineSrcDir( 'gfx/test' );
+addEngineSrcDir( 'gfx/bitmap' );
+addEngineSrcDir( 'gfx/bitmap/loaders' );
+addEngineSrcDir( 'gfx/util' );
+addEngineSrcDir( 'gfx/video' );
+addEngineSrcDir( 'gfx' );
+addEngineSrcDir( 'shaderGen' );
+
+switch( Generator::$platform )
+{
+   case "win32":
+      //addEngineSrcDir( 'gfx/D3D8' );
+      addEngineSrcDir( 'gfx/D3D' );
+      addEngineSrcDir( 'gfx/D3D9' );
+      addEngineSrcDir( 'gfx/D3D9/pc' );
+      addEngineSrcDir( 'shaderGen/hlsl' );
+      break;
+   case "360":
+      addEngineSrcDir( 'gfx/D3D9' );
+      addEngineSrcDir( 'gfx/D3D9/360' );
+      addEngineSrcDir( 'shaderGen/hlsl' );
+      addEngineSrcDir( 'shaderGen/360' );
+      break;
+   case "mac":
+      addEngineSrcDir( 'gfx/gl/ggl/mac' );
+
+      // GFX - GGL
+      addEngineSrcDir( 'gfx/gl' );
+      addEngineSrcDir( 'gfx/gl/ggl' );
+      addEngineSrcDir( 'gfx/gl/ggl/generated' );
+      addEngineSrcDir( 'shaderGen/glsl' );
+      break;
+   case "ps3":
+      addEngineSrcDir( 'gfx/gl/ggl/ps3' );
+
+      // GFX - GGL
+      addEngineSrcDir( 'gfx/gl' );
+      addEngineSrcDir( 'gfx/gl/ggl' );
+      addEngineSrcDir( 'gfx/gl/ggl/generated' );
+      addEngineSrcDir( 'shaderGen/glsl' );
+      break;
+}
+
+// GFX - Sim dependent 
+addEngineSrcDir( 'gfx/sim');
+
+// GUI
+addEngineSrcDir('gui/buttons');
+addEngineSrcDir('gui/containers');
+addEngineSrcDir('gui/controls');
+
+addEngineSrcDir('gui/core');
+addEngineSrcDir('gui/game');
+addEngineSrcDir('gui/shiny');
+addEngineSrcDir('gui/utility');
+addEngineSrcDir('gui');
+
+// Include tools for non-tool builds (or define player if a tool build)
+includeModule( 'tools' );
+
+/////////////////////
+// Additional includes
+addIncludePath( '../../source' );		   // product source (relative to solution output directories)
+addIncludePath( getAppEngineSrcDir() );	// main engine source dir relative to app project file 
+addIncludePath( getAppLibSrcDir() ); 	   // main lib source dir relative to app project file
+
+if ( Generator::$platform == "win32" )
+{
+   addIncludePath( getAppLibSrcDir() . 'directx8' );
+   addIncludePath( getAppLibSrcDir() . 'openal/win32' );
+   
+   addProjectLibDir( getAppLibSrcDir() . 'SDL/win32' );
+   addProjectLibDir( getAppLibSrcDir() . 'unicode' );
+   addProjectLibDir( getAppLibSrcDir() . 'directx8' );
+}
+
+?>

+ 41 - 0
Tools/projectGenerator/modules/d3dx8dll.inc

@@ -0,0 +1,41 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginModule( 'd3dx8dll' );
+
+   // Source
+   addLibSrcDir( 'd3dx8dll' );
+
+   // Additional includes
+   addLibIncludePath( 'd3dxdll' );    
+   addLibIncludePath( 'directx8' );
+
+   // Libs
+   addProjectLibDir( 'directx8' );
+   
+   // Defines
+   addProjectDefines( '_WINDOWS', '_USRDLL', 'D3DX8DLL_EXPORTS' );
+   
+endModule();
+
+?>

+ 37 - 0
Tools/projectGenerator/modules/dsound.inc

@@ -0,0 +1,37 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginModule( 'dsound' );
+
+   if ( Generator::$platform == "win32" )
+   {
+      addEngineSrcDir('sfx/dsound');
+      addEngineSrcDir('sfx/xaudio');
+      addProjectLibInput('x3daudio.lib');
+   }
+   else if ( Generator::$platform == "360" )
+      addEngineSrcDir('sfx/xaudio');
+
+endModule();
+
+?>

+ 77 - 0
Tools/projectGenerator/modules/fmod.inc

@@ -0,0 +1,77 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginModule( 'fmod' );
+  $allgood = true;
+  
+	// Additional includes
+	switch( Generator::$platform )
+   {
+      case "win32":
+      case "mac":
+        addLibIncludePath( 'fmod/inc' );
+        break;
+        
+      case "360":
+        // Assume 32-bit system
+        $FMOD_PATH = "C:/Program Files/FMOD SoundSystem/FMOD Programmers API Xbox 360/";
+        
+        // Ohnoes! Try 64-bit!
+        if (!file_exists($FMOD_PATH))
+          $FMOD_PATH = "C:/Program Files (x86)/FMOD SoundSystem/FMOD Programmers API Xbox 360/";
+        
+        if (!file_exists($FMOD_PATH))
+        {
+           $allgood = false;
+           echo "\n\n FMOD integration failed to find Xbox360 installation!\n";
+           echo "   - FMOD_PATH is set to $FMOD_PATH\n\n"; 
+        }
+        else
+        {
+          echo "\n\nFMOD integration for Torque3D on the Xbox360\n";
+          echo "   - FMOD_PATH is set to $FMOD_PATH\n\n";
+          
+          // Fmod API
+          addIncludePath($FMOD_PATH . 'api/inc');
+          addProjectLibDir($FMOD_PATH . 'api/lib');
+          
+          // Fmod Designer API
+          addIncludePath($FMOD_PATH . 'fmoddesignerapi/api/inc');
+          addProjectLibDir($FMOD_PATH . 'fmoddesignerapi/api/lib');
+          
+          addProjectLibInput('fmodxbox360.lib');
+          
+          addProjectLibInput('xmahal.lib');
+          addProjectLibInput('xmic.lib');
+          
+          // Prior to June 2009 XDK, FMOD requires xaudio.lib
+          //addProjectLibInput('xaudio.lib');
+        }
+        break;
+   }
+   
+  // Source
+  if($allgood)
+	  addEngineSrcDir('sfx/fmod');
+endModule();
+?>

+ 37 - 0
Tools/projectGenerator/modules/jpeg.inc

@@ -0,0 +1,37 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginModule( 'ljpeg' );	
+
+// Source
+addLibSrcDir( 'ljpeg' );
+
+// Additional includes
+addLibIncludePath( 'ljpeg' );
+
+// Defines
+	if ( Generator::$platform == "360" )
+      addProjectDefines( 'NO_GETENV;' );
+
+endModule();
+?>

+ 36 - 0
Tools/projectGenerator/modules/libode.inc

@@ -0,0 +1,36 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginModule( 'libode' );
+	
+  // Source
+  addLibSrcDir( 'ode' );
+
+  // Additional includes
+  addLibIncludePath( 'opcode' );
+  addLibIncludePath( 'ode' );
+  addLibIncludePath( '' );
+
+endModule();
+
+?>

+ 29 - 0
Tools/projectGenerator/modules/libogg.inc

@@ -0,0 +1,29 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+addLibSrcDir( 'libogg/src' );
+addLibSrcDir( 'libogg/include/ogg' );
+
+addLibIncludePath( 'libogg/include' );
+
+?>

+ 58 - 0
Tools/projectGenerator/modules/libtheora.inc

@@ -0,0 +1,58 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginModule( 'libtheora' );
+
+addLibSrcDir( 'libtheora/include/theora' );
+addLibSrcDir( 'libtheora/lib' );
+addLibSrcDir( 'libtheora/lib/dec' );
+
+switch( Generator::$platform )
+{
+   case "win32":
+      addLibSrcDir( 'libtheora/lib/dec/x86_vc' );
+      break;
+      
+   default:
+      addLibSrcDir( 'libtheora/lib/dec/x86' );
+      break;
+}
+
+// As we don't use the encoder, disable this for now.
+addLibSrcDir( 'libtheora/lib/enc' );
+
+switch( Generator::$platform )
+{
+   case "win32":
+      addLibSrcDir( 'libtheora/lib/enc/x86_32_vs' );
+      break;
+   default:
+      addLibSrcDir( 'libtheora/lib/enc/x86_32' );
+      break;
+}
+
+addLibIncludePath( 'libtheora/include' );
+addLibIncludePath( 'libogg/include' );
+
+endModule();
+?>

+ 48 - 0
Tools/projectGenerator/modules/libvorbis.inc

@@ -0,0 +1,48 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+// NOTE:  This all the source in the libvorbis library which
+// according to the README includes libvorbis, libvorbisfile,
+// and libvorbisenc.
+//
+// We really only need libvorbis and libvorbisfile for loading
+// ogg vorbis files, but the source is distrubuted all in one
+// folder and the project generator does not allow excluding 
+// files.
+// 
+// In an effort to make upgrading this library simple the
+// the inclusion of the encoder is acceptable.  It should
+// be filtered out of the build by the linker.
+
+addLibSrcDir( 'libvorbis/lib' );
+addLibSrcDir( 'libvorbis/lib/books/coupled' );
+addLibSrcDir( 'libvorbis/lib/books/floor' );
+addLibSrcDir( 'libvorbis/lib/books/uncoupled' );
+addLibSrcDir( 'libvorbis/lib/modes' );
+addLibSrcDir( 'libvorbis/include/vorbis' );
+
+addLibIncludePath( 'libvorbis/lib' );
+addLibIncludePath( 'libvorbis/include' );
+addLibIncludePath( 'libogg/include' );
+
+?>

+ 35 - 0
Tools/projectGenerator/modules/mng.inc

@@ -0,0 +1,35 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginModule( 'lmng' );
+	// Source files
+	addLibSrcDir( 'lmng' );
+
+	// Additional includes
+	addLibIncludePath( 'lmng' );
+	addLibIncludePath( 'lpng' );
+	addLibIncludePath( 'zlib' );
+	addLibIncludePath( 'ljpeg' );
+endModule();
+
+?>

+ 45 - 0
Tools/projectGenerator/modules/nxCharacter.inc

@@ -0,0 +1,45 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginModule( 'nxCharacter' );
+	
+   global $PHYSX_SDK_PATH;
+
+   // Defines
+   addProjectDefines( 'WIN32' );
+   addProjectDefines( 'NXCHARACTER_STATIC' );
+
+   // Source
+   addSrcDir( $PHYSX_SDK_PATH . '/SDKs/NxCharacter/src' );
+   addSrcDir( $PHYSX_SDK_PATH . '/SDKs/NxCharacter/include' );
+
+   // Additional includes
+   addIncludePath( $PHYSX_SDK_PATH . '/SDKs/NxCharacter/include' );
+   addIncludePath( $PHYSX_SDK_PATH . '/SDKs/Physics/include' );
+   addIncludePath( $PHYSX_SDK_PATH . '/SDKs/Foundation/include' );
+   addIncludePath( $PHYSX_SDK_PATH . '/SDKs/PhysXLoader/include' );
+   addIncludePath( $PHYSX_SDK_PATH . '/SDKs/Cooking/include' );
+   
+endModule();
+
+?>

+ 43 - 0
Tools/projectGenerator/modules/nxuStream.inc

@@ -0,0 +1,43 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginModule( 'nxuStream' );
+	
+   global $PHYSX_SDK_PATH;
+
+   // Defines
+	addProjectDefines( 'WIN32' );
+
+	// Source
+	addSrcDir( $PHYSX_SDK_PATH . '/Tools/NxuStream2' );
+
+	// Additional includes
+	addIncludePath( $PHYSX_SDK_PATH . '/Tools/NxuStream2' );
+	addIncludePath( $PHYSX_SDK_PATH . '/SDKs/Physics/include' );
+	addIncludePath( $PHYSX_SDK_PATH . '/SDKs/Foundation/include' );
+	addIncludePath( $PHYSX_SDK_PATH . '/SDKs/PhysXLoader/include' );
+	addIncludePath( $PHYSX_SDK_PATH . '/SDKs/Cooking/include' );
+
+endModule();
+
+?>

+ 39 - 0
Tools/projectGenerator/modules/opcode.inc

@@ -0,0 +1,39 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginModule( 'opcode' );
+
+   // Defines
+   addProjectDefine( 'TORQUE_OPCODE' );
+	addProjectDefine( 'ICE_NO_DLL' );
+
+	// Source
+	addLibSrcDir( 'opcode' );
+	addLibSrcDir( 'opcode/Ice' );
+
+	// Additional includes
+	addLibIncludePath( 'opcode' );
+
+endModule();
+
+?>

+ 32 - 0
Tools/projectGenerator/modules/openal.inc

@@ -0,0 +1,32 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+// OpenAL
+addEngineSrcDir('sfx/openal');
+addEngineSrcDir('sfx/openal/mac');
+addEngineSrcDir('sfx/openal/win32');
+
+if ( Generator::$platform == "win32" )
+   addIncludePath( getAppLibSrcDir() . 'openal/win32' );
+
+?>

+ 30 - 0
Tools/projectGenerator/modules/pestTimer.inc

@@ -0,0 +1,30 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+   includeModule( 'demo' );
+
+   addProjectDefine( 'TORQUE_DEMO_PESTTIMER' );
+
+   addEngineSrcDir('demo/pestTimer');
+
+?>

+ 107 - 0
Tools/projectGenerator/modules/physX.inc

@@ -0,0 +1,107 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginModule( 'physX' );
+
+   // Look for the optional global from the project.conf.
+   global $PHYSX_SDK_PATH;
+   if (!$PHYSX_SDK_PATH)
+   {
+      // First look for an environment var.
+      $PHYSX_SDK_PATH = getenv( "TORQUE_PHYSX_PATH" );
+
+      if (strlen($PHYSX_SDK_PATH) == 0 || !file_exists($PHYSX_SDK_PATH))
+      {
+         // Sometimes users get confused and use this var.
+         $PHYSX_SDK_PATH = getenv( "PHYSX_SDK_PATH" );
+
+         if (strlen($PHYSX_SDK_PATH) == 0 || !file_exists($PHYSX_SDK_PATH))
+         {
+            // Since neither environment var worked try for 
+            // the default PhysX SDK install location.
+            $PHYSX_SDK_PATH = getenv("ProgramFiles") . "/NVIDIA Corporation/NVIDIA PhysX SDK/v2.8.4_win";
+
+            // Last channce... try the x86 default install path.
+            if (!file_exists($PHYSX_SDK_PATH))
+               $PHYSX_SDK_PATH = getenv("ProgramFiles(x86)") . "/NVIDIA Corporation/NVIDIA PhysX SDK/v2.8.4_win";
+         }
+      }
+
+      // We need forward slashes for paths.
+      $PHYSX_SDK_PATH = str_replace( "\\", "/", $PHYSX_SDK_PATH);
+
+      // Remove trailing slashes.
+      $PHYSX_SDK_PATH = rtrim($PHYSX_SDK_PATH, " /");
+   }
+
+   // If we still don't have the SDK path then let the user know.
+   if (!file_exists($PHYSX_SDK_PATH))
+   {
+      trigger_error( 
+            "\n*******************************************************************".
+            "\n".
+            "\n  We were not able to find a valid path to the PhysX SDK!".
+            "\n".
+            "\n  You must install the latest PhysX SDK and set the path via a".
+            "\n  \$PHYSX_SDK_PATH variable in your buildFiles/project.conf file".
+            "\n  or by setting the TORQUE_PHYSX_PATH system environment variable".
+            "\n  (may require a reboot).".
+            "\n".
+            "\n*******************************************************************".
+            "\n", E_USER_ERROR );
+   }
+
+   addProjectDefine( "TORQUE_PHYSICS_PHYSX" );
+   addProjectDefine( "TORQUE_PHYSICS_ENABLED" );
+
+   // Source
+   addEngineSrcDir( "T3D/physics/physX" );
+
+   // Includes
+   addIncludePath( $PHYSX_SDK_PATH . "/SDKs/Physics/include" );
+   addIncludePath( $PHYSX_SDK_PATH . "/SDKs/Foundation/include" );
+   addIncludePath( $PHYSX_SDK_PATH . "/SDKs/PhysXLoader/include" );
+   addIncludePath( $PHYSX_SDK_PATH . "/SDKs/Cooking/include" );
+   addIncludePath( $PHYSX_SDK_PATH . "/SDKs/NxCharacter/include" );
+   addIncludePath( $PHYSX_SDK_PATH . "/Tools/NxuStream2" );
+
+   // Libs
+   addProjectLibDir( $PHYSX_SDK_PATH . "/SDKs/lib/Win32" );
+   addProjectLibInput( "PhysXCooking.lib" );
+   addProjectLibInput( "PhysXLoader.lib" );
+
+   // For PhysX support.
+   includeLib( 'nxCharacter' );
+   includeLib( 'nxuStream' );
+
+   if (inProjectConfig())
+   {
+      addProjectDependency( 'nxCharacter' );
+      addProjectDependency( 'nxuStream' );
+      addSolutionProjectRef( 'nxCharacter' );
+      addSolutionProjectRef( 'nxuStream' );
+   }
+
+endModule();
+
+?>

+ 37 - 0
Tools/projectGenerator/modules/png.inc

@@ -0,0 +1,37 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginModule( 'lpng' );
+	// Source
+	addLibSrcDir( 'lpng' );
+
+	// Additional includes
+	addLibIncludePath( 'zlib' );
+	addLibIncludePath( 'lpng' );
+	
+	// Defines
+	if ( Generator::$platform == "360" )
+      addProjectDefines( 'PNG_NO_ASSEMBLER_CODE' );
+	
+endModule();
+?>

+ 34 - 0
Tools/projectGenerator/modules/squish.inc

@@ -0,0 +1,34 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginModule( 'squish' );
+	
+	// Source
+	addLibSrcDir( 'squish' );
+
+	// Additional includes
+	addLibIncludePath( 'squish' );
+
+endModule();
+
+?>

+ 31 - 0
Tools/projectGenerator/modules/theora.inc

@@ -0,0 +1,31 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+addProjectDefine( 'TORQUE_OGGTHEORA' );
+addProjectDefine( 'TORQUE_OGGVORIBS' ); // Currently used by Theora video code.
+
+addEngineSrcDir( 'core/ogg' );
+addEngineSrcDir( 'gfx/video' );
+addEngineSrcDir( 'gui/theora' );
+
+?>

+ 28 - 0
Tools/projectGenerator/modules/tinyxml.inc

@@ -0,0 +1,28 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+addLibSrcDir( 'tinyxml' );
+
+addLibIncludePath( 'tinyxml' );
+
+?>

+ 39 - 0
Tools/projectGenerator/modules/tools.inc

@@ -0,0 +1,39 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+    if (!getToolBuild())
+    {
+        addProjectDefine( 'TORQUE_PLAYER' );
+    }
+    else
+    {
+        // 3D Tools
+        addEngineSrcDir('gui/worldEditor');
+        addEngineSrcDir('environment/editors');
+        addEngineSrcDir('forest/editor');
+
+        addEngineSrcDir('gui/editor');
+        addEngineSrcDir('gui/editor/inspector');
+    }
+
+?>

+ 33 - 0
Tools/projectGenerator/modules/ungif.inc

@@ -0,0 +1,33 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginModule( 'lungif' );
+
+	// Source
+	addLibSrcDir( 'lungif' );
+
+	// Additional includes
+	addLibIncludePath( 'lungif' );
+
+endModule();
+?>

+ 26 - 0
Tools/projectGenerator/modules/vorbis.inc

@@ -0,0 +1,26 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+addProjectDefine( 'TORQUE_OGGVORBIS' );
+
+?>

+ 30 - 0
Tools/projectGenerator/modules/webDeploy.inc

@@ -0,0 +1,30 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginModule( 'webDeploy' );
+
+    includeLib( 'WebDeploy');
+
+endModule();
+
+?>

+ 28 - 0
Tools/projectGenerator/modules/xaudio.inc

@@ -0,0 +1,28 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+// XAudio
+addEngineSrcDir('sfx/xaudio');
+addProjectLibInput('x3daudio.lib');
+
+?>

+ 34 - 0
Tools/projectGenerator/modules/zlib.inc

@@ -0,0 +1,34 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+beginModule( 'zlib' );
+	
+	// Source
+	addLibSrcDir( 'zlib' );
+
+	// Additional includes
+	addLibIncludePath( 'zlib' );
+
+endModule();
+
+?>

+ 216 - 0
Tools/projectGenerator/newProject.php

@@ -0,0 +1,216 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+// Yes, I still need to comment most of the stuff in here. I tried to do a quick port over of the stuff from the bat and
+// skipped laying it out
+function copyDir( $source, $target, $exclude = array())
+{
+   if ( is_dir( $source ) )
+   {
+      @mkdir( $target, 0777, true );
+
+      $dirRef = dir( $source );
+
+      while ( FALSE !== ( $entry = $dirRef->read() ) )
+      {
+         // Read through exclude list. If the current directory is on it, skip it
+         $skip = false;
+         foreach($exclude as $exclFile)
+         {
+            if($entry == $exclFile)
+            { 
+               $skip = true;
+               continue;
+            }
+         }
+
+         if ( $entry == '.' || $entry == '..' || $skip )
+            continue;
+
+         $entryFullPath = $source . '/' . $entry;           
+         if ( is_dir( $entryFullPath ) )
+         {
+            copyDir( $entryFullPath, $target . '/' . $entry, $exclude );
+            continue;
+         }
+
+         copy( $entryFullPath, $target . '/' . $entry );
+         echo("Copying " . $entry . " to " . $target . "/\n");
+      }
+
+      $dirRef->close();
+   }
+   else
+      copy( $source, $target );
+}
+
+// Function taken from PHP.net
+function rm_recursive($filepath)
+{
+   if (is_dir($filepath) && !is_link($filepath))
+   {
+      if ($dirRef = opendir($filepath))
+      {
+         while (($curfile = readdir($dirRef)) !== false)
+         {
+            if ($curfile == '.' || $curfile == '..')
+                continue;
+ 
+            if (!rm_recursive($filepath.'/'.$curfile))
+               throw new Exception($filepath.'/'.$curfile.' could not be deleted.');
+         }
+
+         closedir($dirRef);
+      }
+
+      return rmdir($filepath);
+   }
+
+   return unlink($filepath);
+}
+
+// Replaces all instances of the given text string from the given file
+function ReplaceTextInFile($file, $string, $replace)
+{
+   $buf = "";
+   $confg = file($file);
+
+   foreach ($confg as $line)
+   {
+      $line = str_replace($string, $replace, $line);
+      $buf .= $line;
+   }
+
+   $confg = fopen($file, "w"); 
+   fwrite($confg, $buf); 
+   fclose($confg);
+}
+
+// Flag that notes whether a simple (non-fatal) error has occurred
+$withError = false;
+
+// Minimum number of passed arguments is 3
+if($argc < 4)
+   exit("\nError! Invalid number of arguments! Correct format is Project_Name Torque_Root Project_Destination_Path (optional -O overwrite existing files)\n");
+// If there are 5 args and the last one isn't the override flag, it's a fatal error
+else if($argc == 5 && $argv[4] != "-O")
+   exit("\nInvalid argument of $argv[4]! Should be -O (optional overwrite existing files flag)\n");
+
+// Define our main working paths
+$torqueDir = $argv[2];
+$newPath = $argv[3] . "/".$argv[1] . "/";
+$templPath = $torqueDir . "/Templates/Full/";
+
+// Aesthetics...php doesn't care
+$newPath = str_replace("//", "/", $newPath);
+$templPath = str_replace("//", "/", $templPath);
+
+// Check if template path exists (ie user didn't do something wrong)
+if(is_dir($templPath))
+{
+   // If the destination path doesn't exist, make it
+   if(!is_dir($argv[3]))
+      mkdir($argv[3], 0777, true);
+
+   // If the project folder exists, check for -O
+   if(is_dir($newPath))
+   {
+      //If there's no -O, we exit out
+      if($argv[4] != "-O")
+         exit("\nProject folder already exists! Use -O as 4th argument is you wish to overwrite");
+
+      // Otherwise we delete the other .exe and .torsion as they won't otherwise be overwritten
+      else
+      {
+         if(!unlink($newPath . "game/" . $argv[1] . ".exe") ||
+            !unlink($newPath . "game/" . $argv[1] . ".torsion"))
+         {
+            echo("\nError deleting old files " . $argv[1] . ".exe and " . $argv[1] . ".torsion\n");
+            $withError = true;
+         }
+      }
+   }
+
+   // Read directory exclusion list from file (most likely provided by GUI prompt)
+   $exclude = file($templPath . "exclude.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
+
+   // By default exclude .svn, config, and buildFiles
+   if($exclude == false)
+   {
+      $exclude = array(".svn", "Link");
+   }
+
+   else
+   {
+      $exclude[] = ".svn";
+      $exclude[] = "Link";
+   }
+
+   copyDir($templPath, $newPath, $exclude);
+}
+
+// If the given template directory does not exist, we exit
+else{
+   exit("\nTemplate directory does not exist at $templPath!");
+}
+
+//Replace references to template
+ReplaceTextInFile($newPath . "buildFiles/config/project.conf", "Full", $argv[1]);
+ReplaceTextInFile($newPath . "buildFiles/config/project.360.conf", "Full", $argv[1]);
+ReplaceTextInFile($newPath . "buildFiles/config/project.mac.conf", "Full", $argv[1]);
+ReplaceTextInFile($newPath . "game/Template.torsion", "Full", $argv[1]);
+ReplaceTextInFile($newPath . "game/main.cs", "Full", $argv[1]);
+ReplaceTextInFile($newPath . "source/torqueConfig.h", "Full", $argv[1]);
+
+//Rename the executable and the torsion project file
+if(!rename($newPath . "game/Full.exe", $newPath . "game/" . $argv[1] . ".exe"))
+{ 
+   echo("\n\nCould not rename Full.exe! You may need to rename manually\n");
+   $withError = true;
+}
+
+if(!rename($newPath . "game/Full.torsion", $newPath . "game/" . $argv[1] . ".torsion"))
+{ 
+   echo("\n\nCould not rename Full.torsion! You may need to rename manually\n");
+   $withError = true;
+}
+
+chdir($newPath);
+
+// Generate the projects and solutions using the generateProjects.bat
+// We don't hand in the $torqueDir if our output path is in the Torque folders
+// Probably should make this smarter so that it can handle directories that
+// are in the the Torque folder but are not at the same level as GameExamples and Projects
+if (stristr($newPath, $torqueDir))
+   passthru("generateProjects.bat noPause");
+else
+   passthru("generateProjects.bat noPause $torqueDir");
+
+// If there wasn't an error, print happy message
+if(!$withError)
+   echo("\nProject creation complete!\nYou can find your new project at $newPath.");
+// If there was, print ultra mega sad message
+else
+   echo("\nProject creation completed, however there were some errors. Please verify that your new project is correct.\nYou can find your new project at $newPath.");
+
+?>

+ 490 - 0
Tools/projectGenerator/projectGenUtils.inc

@@ -0,0 +1,490 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+//--------------------------------------------------------------------------------
+//
+//	This file is now the 'API' which just wraps all the internal stuff nicely. 
+//
+//--------------------------------------------------------------------------------
+
+function beginProject($name, $sharedConfig)
+{
+    // Set the game project name, this is what your game's exe/dll will be called
+    setGameProjectName($name);
+    
+    if (Generator::$platform == "win32" && $sharedConfig)
+        beginSolutionConfig( $name, '{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}' );
+
+	
+}
+
+function endProject($sharedConfig)
+{
+    if (Generator::$platform == "win32" && $sharedConfig)
+        endSolutionConfig();
+}
+
+function beginSolutionConfig( $name, $guid = '' )
+{
+	Generator::beginSolution( $name, $guid );  
+}
+
+function addSolutionProjectRef( $pname )
+{
+	Generator::addSolutionProjectRef( $pname );		
+}
+
+// Add a reference to an external project, this is used for WPF projects currently
+// as adding all the various designer/xaml/stuff to the project generator is probably overkill
+// However, it is nice to not have to add the project to the solution whenever you run the project generator
+function addSolutionProjectRefExt( $pname, $ppath, $pguid )
+{
+    Generator::addSolutionProjectRefExt( $pname, $ppath, $pguid );		
+}
+
+function endSolutionConfig()
+{
+	Generator::endSolution();		
+}
+
+function setPlatform( $platform )
+{      
+   echo('   - Setting platform to: ' . $platform . "\n");
+   
+   Generator::$platform = $platform;
+}
+
+function includeLib( $libName )
+{
+    //echo( "GLP: " . Generator::getGeneratorLibsPath() . $libName . "\n" );
+    
+    Generator::includeLib( $libName );    
+
+}
+
+function includeModule( $modName )
+{
+   require( Generator::getGeneratorModulesPath() . $modName . '.inc' );
+}
+
+function beginActiveXConfig( $lib_name, $guid = '', $gameDir = 'game', $output_name = '' )
+{    
+	Generator::beginActiveXConfig( $lib_name, $guid, $gameDir, $output_name );
+}
+
+function endActiveXConfig()
+{
+	Generator::endActiveXConfig();
+}
+
+function beginSafariConfig( $lib_name, $guid = '', $gameDir = 'game', $output_name = '' )
+{    
+	Generator::beginSafariConfig( $lib_name, $guid, $gameDir, $output_name );
+}
+
+function endSafariConfig()
+{
+	Generator::endSafariConfig();
+}
+
+function beginSharedLibConfig( $lib_name, $guid = '', $gameDir = 'game', $output_name = '' )
+{    
+	Generator::beginSharedLibConfig( $lib_name, $guid, $gameDir, $output_name );
+}
+
+function endSharedLibConfig()
+{
+	Generator::endSharedLibConfig();
+}
+
+function beginNPPluginConfig( $lib_name, $guid = '', $gameDir = 'game', $output_name = '' )
+{    
+	Generator::beginNPPluginConfig( $lib_name, $guid, $gameDir, $output_name );
+}
+
+function endNPPluginConfig()
+{
+	Generator::endNPPluginConfig();
+}
+
+
+function beginLibConfig( $lib_name, $guid = '', $gameDir = 'game', $output_name = '' )
+{    
+	Generator::beginLibConfig( $lib_name, $guid, $gameDir, $output_name );
+}
+
+function endLibConfig()
+{
+	Generator::endLibConfig();
+}
+
+function beginAppConfig( $app_name, $guid = '', $game_dir = 'game', $output_name = '' )
+{    
+   Generator::beginAppConfig( $app_name, $guid, $game_dir, $output_name );
+}
+
+function endAppConfig()
+{
+	Generator::endAppConfig();
+}
+
+function beginSharedAppConfig( $app_name, $guid = '', $game_dir = 'game', $output_name = '' )
+{    
+   Generator::beginSharedAppConfig( $app_name, $guid, $game_dir, $output_name );
+}
+
+function endSharedAppConfig()
+{
+	Generator::endSharedAppConfig();
+}
+
+
+function beginCSProjectConfig( $app_name, $guid = '', $game_dir = 'game', $output_name = '' )
+{    
+   Generator::beginCSProjectConfig( $app_name, $guid, $game_dir, $output_name );
+}
+
+function endCSProjectConfig()
+{
+	Generator::endCSProjectConfig();
+}
+
+
+
+///////////////////////
+
+function beginModule( $name )
+{
+	Generator::beginModule( $name );
+}
+
+function endModule()
+{
+    Generator::endModule();	
+}
+
+function addSrcDir( $dir, $recurse = false )
+{
+    //echo( "ADD SRC DIR: " . $dir . "\n" );
+
+	Generator::addSrcDir( $dir, $recurse );
+}
+
+function addSrcFile( $file )
+{
+    //echo( "ADD SRC FILE: " . $file . "\n" );
+
+	Generator::addSrcFile( $file );
+}
+
+function addEngineSrcDir( $dir )
+{
+    //echo( "ADD ENGINE SRC DIR: " . getEngineSrcDir() . $dir . "\n" );
+
+ 	addSrcDir( getEngineSrcDir() . $dir );
+}
+
+function addEngineSrcFile( $file )
+{
+    //echo( "ADD SRC FIL: " . getEngineSrcDir() . $file . "\n" );
+
+	addSrcFile( getEngineSrcDir() . $file );
+}
+
+function addLibSrcDir( $dir )
+{
+	addSrcDir( Generator::getLibSrcDir() . $dir );
+}
+
+function addLibSrcFile( $file )
+{
+	addSrcDir( Generator::getLibSrcDir() . $file );
+}
+
+function addLibIncludePath( $path )
+{
+    // We need to make the include paths relative to the project file location!
+	addIncludePath( getAppLibSrcDir() . $path ); 
+}
+
+function getAppLibSrcDir()
+{
+    // We need to make the include paths relative to the project file location!
+    return "../" . getLibSrcDir();
+}
+
+function addAppIncludePath( $path )
+{
+	// We need to make the include paths relative to the project file location!
+	addIncludePath( getAppEngineSrcDir() . $path ); 
+}
+
+function getAppEngineSrcDir()
+{
+    // We need to make the include paths relative to the project file location!
+    return "../" . getEngineSrcDir();
+}
+
+function getAppEngineBinDir()
+{
+    // We need to make the include paths relative to the project file location!
+    return "../" . getEngineBinDir();
+}
+
+function getEngineSrcDir()
+{
+	return Generator::getEngineSrcDir();
+}
+
+function getLibSrcDir()
+{
+	return Generator::getLibSrcDir();
+}
+
+function getEngineBinDir()
+{
+	return Generator::getEngineBinDir();
+}
+
+function addIncludePath( $path )
+{
+	//echo( "ADD INCLUDE: " . $path . "\n" );    
+
+	Generator::addIncludePath( $path );
+}
+/// Add a preprocessor directive/define
+function addProjectDefine( $d, $v = null )
+{	
+	Generator::addProjectDefine( $d, $v );
+}
+/// Add a list of defines in one call
+function addProjectDefines()
+{
+	$args  = func_get_args();
+	$count = func_num_args();
+	
+	if( $count > 0 )
+		Generator::addProjectDefines( $args );
+	else
+		echo( "addProjectDefines() - no arguments passed!" );
+}
+
+function setProjectGUID( $guid )
+{
+	Generator::setProjectGUID( $guid );
+}
+
+function setProjectModuleDefinitionFile( $mdef )
+{
+	Generator::setProjectModuleDefinitionFile( $mdef );
+}
+
+
+function addProjectLibDir( $dir )
+{
+    Generator::addProjectLibDir( $dir );
+}
+
+function addProjectLibInput( $lib_name )
+{
+    Generator::addProjectLibInput( $lib_name );
+}
+
+function addProjectDependency( $pd )
+{
+    Generator::addProjectDependency( $pd );
+}
+
+function removeProjectDependency( $pd )
+{
+    Generator::removeProjectDependency( $pd );
+}
+
+function addProjectReference( $refName, $version = "" )
+{
+    Generator::addProjectReference( $refName, $version );
+}
+
+// disable a specific project compiler warning
+function disableProjectWarning( $warning )
+{	
+	Generator::disableProjectWarning( $warning );
+}
+
+
+function setGameProjectName($name)
+{
+   Generator::setGameProjectName($name);
+}
+
+function getGameProjectName()
+{
+   return Generator::getGameProjectName();
+}
+
+function setToolBuild($tb)
+{
+   Generator::setToolBuild($tb);
+}
+
+function getToolBuild()
+{
+   return Generator::getToolBuild();
+}
+
+function setWatermarkBuild($wb)
+{
+   Generator::setWatermarkBuild($wb);
+}
+
+function getWatermarkBuild()
+{
+   return Generator::getWatermarkBuild();
+}
+
+function setPurchaseScreenBuild($psb)
+{
+   Generator::setPurchaseScreenBuild($psb);
+}
+
+function getPurchaseScreenBuild()
+{
+   return Generator::getPurchaseScreenBuild();
+}
+
+function setDemoBuild($db)
+{
+   Generator::setDemoBuild($db);
+}
+
+function getDemoBuild()
+{
+   return Generator::getDemoBuild();
+}
+
+function setObjectLimitBuild($olb)
+{
+   Generator::setObjectLimitBuild($olb);
+}
+
+function getObjectLimitBuild()
+{
+   return Generator::getObjectLimitBuild();
+}
+
+function setTimeOutBuild($tob)
+{
+   Generator::setTimeOutBuild($tob);
+}
+
+function getTimeOutBuild()
+{
+   return Generator::getTimeOutBuild();
+}
+
+function inProjectConfig()
+{
+   return Generator::inProjectConfig();
+}
+
+// On Windows, 1 - Console, 2 - Windows 
+function setProjectSubSystem( $subSystem )
+{
+    Generator::setProjectSubSystem( $subSystem );
+}
+
+// Sets whether to use /MT or /MD code generation/runtime on Windows
+// /MD plays better with multiple dynamic libraries in a project (and with certain libraries (like Qt)
+// /MD also generates smaller binaries as the runtime isn't included in each module, memory is handled consistently, etc
+// You must include or install via the redistributable package the appropriate VS runtime for end users.  
+function setDLLRuntime ($val)
+{
+    Generator::setDLLRuntime( $val );
+}
+
+//-------------------------------------------------------------------------------- UTIL
+
+// Some versions of PHP4 are unable to recusively create directories.
+// The version of PHP that is distributed with Mac OS 10.4 suffers from this.
+function mkdir_r($path, $mode)
+{
+   if( @mkdir( $path, $mode ) or file_exists( $path ) ) 
+   	return true;
+   	
+   return ( mkdir_r( dirname( $path ), $mode ) and mkdir( $path, $mode ) );
+}
+
+// This is used inside an if statement in the smarty templates
+function dontCompile( $string, $output )
+{
+   // Skip marking header files to be excluded from the 
+   // build.  It confuses VS2010 and it will not put the 
+   // file into the correct filter folder.
+   //
+   if ( preg_match( '#^.*\.(h|hpp|hh|inc)$#i', $string ) )
+      return false;
+
+   if( !is_array( $output->dont_compile_patterns ) )
+        return false;
+   
+   foreach( $output->dont_compile_patterns as $pattern )   
+      if( preg_match( $pattern, $string ) )
+         return true;
+      
+   return false;
+}
+
+
+/// Generates and returns a randomly generated uuid in the form:
+///
+/// {xxxxxxxx-xxxx-4xxx-Yxxx-xxxxxxxxxxxx}
+///
+/// Where Y is either 8, 9, A, or B.  This is known as 
+/// a v4 UUID.  See...
+///
+/// http://en.wikipedia.org/wiki/Universally_Unique_Identifier#Version_4_.28random.29
+///
+function gen_uuid()
+{
+    return sprintf( '{%04x%04x-%04x-%04x-%04x-%04x%04x%04x}', 
+        // 32 bits for "time_low" 
+        mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), 
+ 
+        // 16 bits for "time_mid" 
+        mt_rand( 0, 0xffff ), 
+ 
+        // 16 bits for "time_hi_and_version", 
+        // four most significant bits holds version number 4 
+        mt_rand( 0, 0x0fff ) | 0x4000, 
+ 
+        // 16 bits, 8 bits for "clk_seq_hi_res", 
+        // 8 bits for "clk_seq_low", 
+        // two most significant bits holds zero and one for variant DCE1.1 
+        mt_rand( 0, 0x3fff ) | 0x8000, 
+ 
+        // 48 bits for "node" 
+        mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ) 
+    ); 
+}
+
+?>

+ 92 - 0
Tools/projectGenerator/projectGenerator.php

@@ -0,0 +1,92 @@
+<?php
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+
+//
+// Hello, hello...
+//
+echo( "Welcome to projectGenerator 0.9\n" );
+echo( "Copyright (c) 2012 GarageGames, LLC\n" );
+echo( "Released under a MIT license.\n" );
+echo( "\n" );
+
+//
+//	Configure error logging
+//
+error_reporting( E_ALL & ~E_NOTICE );
+
+//
+// Requires
+//
+require_once( "classes/BuildTarget.php" );
+require_once( "btargets/targets.inc" );
+require_once( "classes/Generator.php" );
+require_once( "projectGenUtils.inc" );
+require_once( "smarty/Smarty.class.php" );
+
+//
+// Initialization
+//
+$g_cwd = realpath( dirname( $_SERVER[ 'PHP_SELF' ] ) );
+
+echo( "   CWD = " . $g_cwd . "\n" );
+
+//
+// Load, instantiate, and configure the smarty template engine.
+//
+echo( "   - Loading Smarty...\n" );
+
+$tpl 				= new Smarty();
+$tpl->template_dir	= $g_cwd . "/templates";
+$tpl->compile_dir	= $g_cwd . "/templates_c";
+
+$tpl->clear_all_cache();
+
+// By default we assume that the root of the Torque SDK
+// is located two folders up from the CWD.  That is unless
+// another path is passed in the command line.
+$torqueRoot = "../..";
+if ( $argc >= 3 )
+    $torqueRoot = str_replace( "\\", "/", $argv[2] );
+
+// Kick off the generator
+Generator::init( $torqueRoot );
+
+// Ready to read our config file.
+echo( "   - Loading config file " . realpath($argv[1])."\n" );
+
+require( $argv[ 1 ] );
+
+// Generate all projects
+Generator::generateProjects( $tpl );
+
+// Now the solutions (if any)
+$tpl->clear_all_cache();
+
+Generator::generateSolutions( $tpl );
+
+// finally write out the sample.html for web deployment (if any)
+WebPlugin::writeSampleHtml();
+
+exit;
+?>

+ 389 - 0
Tools/projectGenerator/smarty/Config_File.class.php

@@ -0,0 +1,389 @@
+<?php
+
+/**
+ * Config_File class.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @link http://smarty.php.net/
+ * @version 2.6.18
+ * @copyright Copyright: 2001-2005 New Digital Group, Inc.
+ * @author Andrei Zmievski <[email protected]>
+ * @access public
+ * @package Smarty
+ */
+
+/* $Id: Config_File.class.php,v 1.88 2007/03/06 10:40:06 messju Exp $ */
+
+/**
+ * Config file reading class
+ * @package Smarty
+ */
+class Config_File {
+    /**#@+
+     * Options
+     * @var boolean
+     */
+    /**
+     * Controls whether variables with the same name overwrite each other.
+     */
+    var $overwrite        =    true;
+
+    /**
+     * Controls whether config values of on/true/yes and off/false/no get
+     * converted to boolean values automatically.
+     */
+    var $booleanize        =    true;
+
+    /**
+     * Controls whether hidden config sections/vars are read from the file.
+     */
+    var $read_hidden     =    true;
+
+    /**
+     * Controls whether or not to fix mac or dos formatted newlines.
+     * If set to true, \r or \r\n will be changed to \n.
+     */
+    var $fix_newlines =    true;
+    /**#@-*/
+
+    /** @access private */
+    var $_config_path    = "";
+    var $_config_data    = array();
+    /**#@-*/
+
+    /**
+     * Constructs a new config file class.
+     *
+     * @param string $config_path (optional) path to the config files
+     */
+    function Config_File($config_path = NULL)
+    {
+        if (isset($config_path))
+            $this->set_path($config_path);
+    }
+
+
+    /**
+     * Set the path where configuration files can be found.
+     *
+     * @param string $config_path path to the config files
+     */
+    function set_path($config_path)
+    {
+        if (!empty($config_path)) {
+            if (!is_string($config_path) || !file_exists($config_path) || !is_dir($config_path)) {
+                $this->_trigger_error_msg("Bad config file path '$config_path'");
+                return;
+            }
+            if(substr($config_path, -1) != DIRECTORY_SEPARATOR) {
+                $config_path .= DIRECTORY_SEPARATOR;
+            }
+
+            $this->_config_path = $config_path;
+        }
+    }
+
+
+    /**
+     * Retrieves config info based on the file, section, and variable name.
+     *
+     * @param string $file_name config file to get info for
+     * @param string $section_name (optional) section to get info for
+     * @param string $var_name (optional) variable to get info for
+     * @return string|array a value or array of values
+     */
+    function get($file_name, $section_name = NULL, $var_name = NULL)
+    {
+        if (empty($file_name)) {
+            $this->_trigger_error_msg('Empty config file name');
+            return;
+        } else {
+            $file_name = $this->_config_path . $file_name;
+            if (!isset($this->_config_data[$file_name]))
+                $this->load_file($file_name, false);
+        }
+
+        if (!empty($var_name)) {
+            if (empty($section_name)) {
+                return $this->_config_data[$file_name]["vars"][$var_name];
+            } else {
+                if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name]))
+                    return $this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name];
+                else
+                    return array();
+            }
+        } else {
+            if (empty($section_name)) {
+                return (array)$this->_config_data[$file_name]["vars"];
+            } else {
+                if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"]))
+                    return (array)$this->_config_data[$file_name]["sections"][$section_name]["vars"];
+                else
+                    return array();
+            }
+        }
+    }
+
+
+    /**
+     * Retrieves config info based on the key.
+     *
+     * @param $file_name string config key (filename/section/var)
+     * @return string|array same as get()
+     * @uses get() retrieves information from config file and returns it
+     */
+    function &get_key($config_key)
+    {
+        list($file_name, $section_name, $var_name) = explode('/', $config_key, 3);
+        $result = &$this->get($file_name, $section_name, $var_name);
+        return $result;
+    }
+
+    /**
+     * Get all loaded config file names.
+     *
+     * @return array an array of loaded config file names
+     */
+    function get_file_names()
+    {
+        return array_keys($this->_config_data);
+    }
+
+
+    /**
+     * Get all section names from a loaded file.
+     *
+     * @param string $file_name config file to get section names from
+     * @return array an array of section names from the specified file
+     */
+    function get_section_names($file_name)
+    {
+        $file_name = $this->_config_path . $file_name;
+        if (!isset($this->_config_data[$file_name])) {
+            $this->_trigger_error_msg("Unknown config file '$file_name'");
+            return;
+        }
+
+        return array_keys($this->_config_data[$file_name]["sections"]);
+    }
+
+
+    /**
+     * Get all global or section variable names.
+     *
+     * @param string $file_name config file to get info for
+     * @param string $section_name (optional) section to get info for
+     * @return array an array of variables names from the specified file/section
+     */
+    function get_var_names($file_name, $section = NULL)
+    {
+        if (empty($file_name)) {
+            $this->_trigger_error_msg('Empty config file name');
+            return;
+        } else if (!isset($this->_config_data[$file_name])) {
+            $this->_trigger_error_msg("Unknown config file '$file_name'");
+            return;
+        }
+
+        if (empty($section))
+            return array_keys($this->_config_data[$file_name]["vars"]);
+        else
+            return array_keys($this->_config_data[$file_name]["sections"][$section]["vars"]);
+    }
+
+
+    /**
+     * Clear loaded config data for a certain file or all files.
+     *
+     * @param string $file_name file to clear config data for
+     */
+    function clear($file_name = NULL)
+    {
+        if ($file_name === NULL)
+            $this->_config_data = array();
+        else if (isset($this->_config_data[$file_name]))
+            $this->_config_data[$file_name] = array();
+    }
+
+
+    /**
+     * Load a configuration file manually.
+     *
+     * @param string $file_name file name to load
+     * @param boolean $prepend_path whether current config path should be
+     *                              prepended to the filename
+     */
+    function load_file($file_name, $prepend_path = true)
+    {
+        if ($prepend_path && $this->_config_path != "")
+            $config_file = $this->_config_path . $file_name;
+        else
+            $config_file = $file_name;
+
+        ini_set('track_errors', true);
+        $fp = @fopen($config_file, "r");
+        if (!is_resource($fp)) {
+            $this->_trigger_error_msg("Could not open config file '$config_file'");
+            return false;
+        }
+
+        $contents = ($size = filesize($config_file)) ? fread($fp, $size) : '';
+        fclose($fp);
+
+        $this->_config_data[$config_file] = $this->parse_contents($contents);
+        return true;
+    }
+
+    /**
+     * Store the contents of a file manually.
+     *
+     * @param string $config_file file name of the related contents
+     * @param string $contents the file-contents to parse
+     */
+    function set_file_contents($config_file, $contents)
+    {
+        $this->_config_data[$config_file] = $this->parse_contents($contents);
+        return true;
+    }
+
+    /**
+     * parse the source of a configuration file manually.
+     *
+     * @param string $contents the file-contents to parse
+     */
+    function parse_contents($contents)
+    {
+        if($this->fix_newlines) {
+            // fix mac/dos formatted newlines
+            $contents = preg_replace('!\r\n?!', "\n", $contents);
+        }
+
+        $config_data = array();
+        $config_data['sections'] = array();
+        $config_data['vars'] = array();
+
+        /* reference to fill with data */
+        $vars =& $config_data['vars'];
+
+        /* parse file line by line */
+        preg_match_all('!^.*\r?\n?!m', $contents, $match);
+        $lines = $match[0];
+        for ($i=0, $count=count($lines); $i<$count; $i++) {
+            $line = $lines[$i];
+            if (empty($line)) continue;
+
+            if ( substr($line, 0, 1) == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) {
+                /* section found */
+                if (substr($match[1], 0, 1) == '.') {
+                    /* hidden section */
+                    if ($this->read_hidden) {
+                        $section_name = substr($match[1], 1);
+                    } else {
+                        /* break reference to $vars to ignore hidden section */
+                        unset($vars);
+                        $vars = array();
+                        continue;
+                    }
+                } else {                    
+                    $section_name = $match[1];
+                }
+                if (!isset($config_data['sections'][$section_name]))
+                    $config_data['sections'][$section_name] = array('vars' => array());
+                $vars =& $config_data['sections'][$section_name]['vars'];
+                continue;
+            }
+
+            if (preg_match('/^\s*(\.?\w+)\s*=\s*(.*)/s', $line, $match)) {
+                /* variable found */
+                $var_name = rtrim($match[1]);
+                if (strpos($match[2], '"""') === 0) {
+                    /* handle multiline-value */
+                    $lines[$i] = substr($match[2], 3);
+                    $var_value = '';
+                    while ($i<$count) {
+                        if (($pos = strpos($lines[$i], '"""')) === false) {
+                            $var_value .= $lines[$i++];
+                        } else {
+                            /* end of multiline-value */
+                            $var_value .= substr($lines[$i], 0, $pos);
+                            break;
+                        }
+                    }
+                    $booleanize = false;
+
+                } else {
+                    /* handle simple value */
+                    $var_value = preg_replace('/^([\'"])(.*)\1$/', '\2', rtrim($match[2]));
+                    $booleanize = $this->booleanize;
+
+                }
+                $this->_set_config_var($vars, $var_name, $var_value, $booleanize);
+            }
+            /* else unparsable line / means it is a comment / means ignore it */
+        }
+        return $config_data;
+    }
+
+    /**#@+ @access private */
+    /**
+     * @param array &$container
+     * @param string $var_name
+     * @param mixed $var_value
+     * @param boolean $booleanize determines whether $var_value is converted to
+     *                            to true/false
+     */
+    function _set_config_var(&$container, $var_name, $var_value, $booleanize)
+    {
+        if (substr($var_name, 0, 1) == '.') {
+            if (!$this->read_hidden)
+                return;
+            else
+                $var_name = substr($var_name, 1);
+        }
+
+        if (!preg_match("/^[a-zA-Z_]\w*$/", $var_name)) {
+            $this->_trigger_error_msg("Bad variable name '$var_name'");
+            return;
+        }
+
+        if ($booleanize) {
+            if (preg_match("/^(on|true|yes)$/i", $var_value))
+                $var_value = true;
+            else if (preg_match("/^(off|false|no)$/i", $var_value))
+                $var_value = false;
+        }
+
+        if (!isset($container[$var_name]) || $this->overwrite)
+            $container[$var_name] = $var_value;
+        else {
+            settype($container[$var_name], 'array');
+            $container[$var_name][] = $var_value;
+        }
+    }
+
+    /**
+     * @uses trigger_error() creates a PHP warning/error
+     * @param string $error_msg
+     * @param integer $error_type one of
+     */
+    function _trigger_error_msg($error_msg, $error_type = E_USER_WARNING)
+    {
+        trigger_error("Config_File error: $error_msg", $error_type);
+    }
+    /**#@-*/
+}
+
+?>

+ 1944 - 0
Tools/projectGenerator/smarty/Smarty.class.php

@@ -0,0 +1,1944 @@
+<?php
+
+/**
+ * Project:     Smarty: the PHP compiling template engine
+ * File:        Smarty.class.php
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For questions, help, comments, discussion, etc., please join the
+ * Smarty mailing list. Send a blank e-mail to
+ * [email protected]
+ *
+ * @link http://smarty.php.net/
+ * @copyright 2001-2005 New Digital Group, Inc.
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Andrei Zmievski <[email protected]>
+ * @package Smarty
+ * @version 2.6.18
+ */
+
+/* $Id: Smarty.class.php,v 1.528 2007/03/06 10:40:06 messju Exp $ */
+
+/**
+ * DIR_SEP isn't used anymore, but third party apps might
+ */
+if(!defined('DIR_SEP')) {
+    define('DIR_SEP', DIRECTORY_SEPARATOR);
+}
+
+/**
+ * set SMARTY_DIR to absolute path to Smarty library files.
+ * if not defined, include_path will be used. Sets SMARTY_DIR only if user
+ * application has not already defined it.
+ */
+
+if (!defined('SMARTY_DIR')) {
+    define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+}
+
+if (!defined('SMARTY_CORE_DIR')) {
+    define('SMARTY_CORE_DIR', SMARTY_DIR . 'internals' . DIRECTORY_SEPARATOR);
+}
+
+define('SMARTY_PHP_PASSTHRU',   0);
+define('SMARTY_PHP_QUOTE',      1);
+define('SMARTY_PHP_REMOVE',     2);
+define('SMARTY_PHP_ALLOW',      3);
+
+/**
+ * @package Smarty
+ */
+class Smarty
+{
+    /**#@+
+     * Smarty Configuration Section
+     */
+
+    /**
+     * The name of the directory where templates are located.
+     *
+     * @var string
+     */
+    var $template_dir    =  'templates';
+
+    /**
+     * The directory where compiled templates are located.
+     *
+     * @var string
+     */
+    var $compile_dir     =  'templates_c';
+
+    /**
+     * The directory where config files are located.
+     *
+     * @var string
+     */
+    var $config_dir      =  'configs';
+
+    /**
+     * An array of directories searched for plugins.
+     *
+     * @var array
+     */
+    var $plugins_dir     =  array('plugins');
+
+    /**
+     * If debugging is enabled, a debug console window will display
+     * when the page loads (make sure your browser allows unrequested
+     * popup windows)
+     *
+     * @var boolean
+     */
+    var $debugging       =  false;
+
+    /**
+     * When set, smarty does uses this value as error_reporting-level.
+     *
+     * @var boolean
+     */
+    var $error_reporting  =  null;
+
+    /**
+     * This is the path to the debug console template. If not set,
+     * the default one will be used.
+     *
+     * @var string
+     */
+    var $debug_tpl       =  '';
+
+    /**
+     * This determines if debugging is enable-able from the browser.
+     * <ul>
+     *  <li>NONE => no debugging control allowed</li>
+     *  <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li>
+     * </ul>
+     * @link http://www.foo.dom/index.php?SMARTY_DEBUG
+     * @var string
+     */
+    var $debugging_ctrl  =  'NONE';
+
+    /**
+     * This tells Smarty whether to check for recompiling or not. Recompiling
+     * does not need to happen unless a template or config file is changed.
+     * Typically you enable this during development, and disable for
+     * production.
+     *
+     * @var boolean
+     */
+    var $compile_check   =  true;
+
+    /**
+     * This forces templates to compile every time. Useful for development
+     * or debugging.
+     *
+     * @var boolean
+     */
+    var $force_compile   =  false;
+
+    /**
+     * This enables template caching.
+     * <ul>
+     *  <li>0 = no caching</li>
+     *  <li>1 = use class cache_lifetime value</li>
+     *  <li>2 = use cache_lifetime in cache file</li>
+     * </ul>
+     * @var integer
+     */
+    var $caching         =  0;
+
+    /**
+     * The name of the directory for cache files.
+     *
+     * @var string
+     */
+    var $cache_dir       =  'cache';
+
+    /**
+     * This is the number of seconds cached content will persist.
+     * <ul>
+     *  <li>0 = always regenerate cache</li>
+     *  <li>-1 = never expires</li>
+     * </ul>
+     *
+     * @var integer
+     */
+    var $cache_lifetime  =  3600;
+
+    /**
+     * Only used when $caching is enabled. If true, then If-Modified-Since headers
+     * are respected with cached content, and appropriate HTTP headers are sent.
+     * This way repeated hits to a cached page do not send the entire page to the
+     * client every time.
+     *
+     * @var boolean
+     */
+    var $cache_modified_check = false;
+
+    /**
+     * This determines how Smarty handles "<?php ... ?>" tags in templates.
+     * possible values:
+     * <ul>
+     *  <li>SMARTY_PHP_PASSTHRU -> print tags as plain text</li>
+     *  <li>SMARTY_PHP_QUOTE    -> escape tags as entities</li>
+     *  <li>SMARTY_PHP_REMOVE   -> remove php tags</li>
+     *  <li>SMARTY_PHP_ALLOW    -> execute php tags</li>
+     * </ul>
+     *
+     * @var integer
+     */
+    var $php_handling    =  SMARTY_PHP_PASSTHRU;
+
+    /**
+     * This enables template security. When enabled, many things are restricted
+     * in the templates that normally would go unchecked. This is useful when
+     * untrusted parties are editing templates and you want a reasonable level
+     * of security. (no direct execution of PHP in templates for example)
+     *
+     * @var boolean
+     */
+    var $security       =   false;
+
+    /**
+     * This is the list of template directories that are considered secure. This
+     * is used only if {@link $security} is enabled. One directory per array
+     * element.  {@link $template_dir} is in this list implicitly.
+     *
+     * @var array
+     */
+    var $secure_dir     =   array();
+
+    /**
+     * These are the security settings for Smarty. They are used only when
+     * {@link $security} is enabled.
+     *
+     * @var array
+     */
+    var $security_settings  = array(
+                                    'PHP_HANDLING'    => false,
+                                    'IF_FUNCS'        => array('array', 'list',
+                                                               'isset', 'empty',
+                                                               'count', 'sizeof',
+                                                               'in_array', 'is_array',
+                                                               'true', 'false', 'null'),
+                                    'INCLUDE_ANY'     => false,
+                                    'PHP_TAGS'        => false,
+                                    'MODIFIER_FUNCS'  => array('count'),
+                                    'ALLOW_CONSTANTS'  => false
+                                   );
+
+    /**
+     * This is an array of directories where trusted php scripts reside.
+     * {@link $security} is disabled during their inclusion/execution.
+     *
+     * @var array
+     */
+    var $trusted_dir        = array();
+
+    /**
+     * The left delimiter used for the template tags.
+     *
+     * @var string
+     */
+    var $left_delimiter  =  '{';
+
+    /**
+     * The right delimiter used for the template tags.
+     *
+     * @var string
+     */
+    var $right_delimiter =  '}';
+
+    /**
+     * The order in which request variables are registered, similar to
+     * variables_order in php.ini E = Environment, G = GET, P = POST,
+     * C = Cookies, S = Server
+     *
+     * @var string
+     */
+    var $request_vars_order    = 'EGPCS';
+
+    /**
+     * Indicates wether $HTTP_*_VARS[] (request_use_auto_globals=false)
+     * are uses as request-vars or $_*[]-vars. note: if
+     * request_use_auto_globals is true, then $request_vars_order has
+     * no effect, but the php-ini-value "gpc_order"
+     *
+     * @var boolean
+     */
+    var $request_use_auto_globals      = true;
+
+    /**
+     * Set this if you want different sets of compiled files for the same
+     * templates. This is useful for things like different languages.
+     * Instead of creating separate sets of templates per language, you
+     * set different compile_ids like 'en' and 'de'.
+     *
+     * @var string
+     */
+    var $compile_id            = null;
+
+    /**
+     * This tells Smarty whether or not to use sub dirs in the cache/ and
+     * templates_c/ directories. sub directories better organized, but
+     * may not work well with PHP safe mode enabled.
+     *
+     * @var boolean
+     *
+     */
+    var $use_sub_dirs          = false;
+
+    /**
+     * This is a list of the modifiers to apply to all template variables.
+     * Put each modifier in a separate array element in the order you want
+     * them applied. example: <code>array('escape:"htmlall"');</code>
+     *
+     * @var array
+     */
+    var $default_modifiers        = array();
+
+    /**
+     * This is the resource type to be used when not specified
+     * at the beginning of the resource path. examples:
+     * $smarty->display('file:index.tpl');
+     * $smarty->display('db:index.tpl');
+     * $smarty->display('index.tpl'); // will use default resource type
+     * {include file="file:index.tpl"}
+     * {include file="db:index.tpl"}
+     * {include file="index.tpl"} {* will use default resource type *}
+     *
+     * @var array
+     */
+    var $default_resource_type    = 'file';
+
+    /**
+     * The function used for cache file handling. If not set, built-in caching is used.
+     *
+     * @var null|string function name
+     */
+    var $cache_handler_func   = null;
+
+    /**
+     * This indicates which filters are automatically loaded into Smarty.
+     *
+     * @var array array of filter names
+     */
+    var $autoload_filters = array();
+
+    /**#@+
+     * @var boolean
+     */
+    /**
+     * This tells if config file vars of the same name overwrite each other or not.
+     * if disabled, same name variables are accumulated in an array.
+     */
+    var $config_overwrite = true;
+
+    /**
+     * This tells whether or not to automatically booleanize config file variables.
+     * If enabled, then the strings "on", "true", and "yes" are treated as boolean
+     * true, and "off", "false" and "no" are treated as boolean false.
+     */
+    var $config_booleanize = true;
+
+    /**
+     * This tells whether hidden sections [.foobar] are readable from the
+     * tempalates or not. Normally you would never allow this since that is
+     * the point behind hidden sections: the application can access them, but
+     * the templates cannot.
+     */
+    var $config_read_hidden = false;
+
+    /**
+     * This tells whether or not automatically fix newlines in config files.
+     * It basically converts \r (mac) or \r\n (dos) to \n
+     */
+    var $config_fix_newlines = true;
+    /**#@-*/
+
+    /**
+     * If a template cannot be found, this PHP function will be executed.
+     * Useful for creating templates on-the-fly or other special action.
+     *
+     * @var string function name
+     */
+    var $default_template_handler_func = '';
+
+    /**
+     * The file that contains the compiler class. This can a full
+     * pathname, or relative to the php_include path.
+     *
+     * @var string
+     */
+    var $compiler_file        =    'Smarty_Compiler.class.php';
+
+    /**
+     * The class used for compiling templates.
+     *
+     * @var string
+     */
+    var $compiler_class        =   'Smarty_Compiler';
+
+    /**
+     * The class used to load config vars.
+     *
+     * @var string
+     */
+    var $config_class          =   'Config_File';
+
+/**#@+
+ * END Smarty Configuration Section
+ * There should be no need to touch anything below this line.
+ * @access private
+ */
+    /**
+     * where assigned template vars are kept
+     *
+     * @var array
+     */
+    var $_tpl_vars             = array();
+
+    /**
+     * stores run-time $smarty.* vars
+     *
+     * @var null|array
+     */
+    var $_smarty_vars          = null;
+
+    /**
+     * keeps track of sections
+     *
+     * @var array
+     */
+    var $_sections             = array();
+
+    /**
+     * keeps track of foreach blocks
+     *
+     * @var array
+     */
+    var $_foreach              = array();
+
+    /**
+     * keeps track of tag hierarchy
+     *
+     * @var array
+     */
+    var $_tag_stack            = array();
+
+    /**
+     * configuration object
+     *
+     * @var Config_file
+     */
+    var $_conf_obj             = null;
+
+    /**
+     * loaded configuration settings
+     *
+     * @var array
+     */
+    var $_config               = array(array('vars'  => array(), 'files' => array()));
+
+    /**
+     * md5 checksum of the string 'Smarty'
+     *
+     * @var string
+     */
+    var $_smarty_md5           = 'f8d698aea36fcbead2b9d5359ffca76f';
+
+    /**
+     * Smarty version number
+     *
+     * @var string
+     */
+    var $_version              = '2.6.18';
+
+    /**
+     * current template inclusion depth
+     *
+     * @var integer
+     */
+    var $_inclusion_depth      = 0;
+
+    /**
+     * for different compiled templates
+     *
+     * @var string
+     */
+    var $_compile_id           = null;
+
+    /**
+     * text in URL to enable debug mode
+     *
+     * @var string
+     */
+    var $_smarty_debug_id      = 'SMARTY_DEBUG';
+
+    /**
+     * debugging information for debug console
+     *
+     * @var array
+     */
+    var $_smarty_debug_info    = array();
+
+    /**
+     * info that makes up a cache file
+     *
+     * @var array
+     */
+    var $_cache_info           = array();
+
+    /**
+     * default file permissions
+     *
+     * @var integer
+     */
+    var $_file_perms           = 0644;
+
+    /**
+     * default dir permissions
+     *
+     * @var integer
+     */
+    var $_dir_perms               = 0771;
+
+    /**
+     * registered objects
+     *
+     * @var array
+     */
+    var $_reg_objects           = array();
+
+    /**
+     * table keeping track of plugins
+     *
+     * @var array
+     */
+    var $_plugins              = array(
+                                       'modifier'      => array(),
+                                       'function'      => array(),
+                                       'block'         => array(),
+                                       'compiler'      => array(),
+                                       'prefilter'     => array(),
+                                       'postfilter'    => array(),
+                                       'outputfilter'  => array(),
+                                       'resource'      => array(),
+                                       'insert'        => array());
+
+
+    /**
+     * cache serials
+     *
+     * @var array
+     */
+    var $_cache_serials = array();
+
+    /**
+     * name of optional cache include file
+     *
+     * @var string
+     */
+    var $_cache_include = null;
+
+    /**
+     * indicate if the current code is used in a compiled
+     * include
+     *
+     * @var string
+     */
+    var $_cache_including = false;
+
+    /**#@-*/
+    /**
+     * The class constructor.
+     */
+    function Smarty()
+    {
+      $this->assign('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME']
+                    : @$GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME']);
+    }
+
+    /**
+     * assigns values to template variables
+     *
+     * @param array|string $tpl_var the template variable name(s)
+     * @param mixed $value the value to assign
+     */
+    function assign($tpl_var, $value = null)
+    {
+        if (is_array($tpl_var)){
+            foreach ($tpl_var as $key => $val) {
+                if ($key != '') {
+                    $this->_tpl_vars[$key] = $val;
+                }
+            }
+        } else {
+            if ($tpl_var != '')
+                $this->_tpl_vars[$tpl_var] = $value;
+        }
+    }
+
+    /**
+     * assigns values to template variables by reference
+     *
+     * @param string $tpl_var the template variable name
+     * @param mixed $value the referenced value to assign
+     */
+    function assign_by_ref($tpl_var, &$value)
+    {
+        if ($tpl_var != '')
+            $this->_tpl_vars[$tpl_var] = &$value;
+    }
+
+    /**
+     * appends values to template variables
+     *
+     * @param array|string $tpl_var the template variable name(s)
+     * @param mixed $value the value to append
+     */
+    function append($tpl_var, $value=null, $merge=false)
+    {
+        if (is_array($tpl_var)) {
+            // $tpl_var is an array, ignore $value
+            foreach ($tpl_var as $_key => $_val) {
+                if ($_key != '') {
+                    if(!@is_array($this->_tpl_vars[$_key])) {
+                        settype($this->_tpl_vars[$_key],'array');
+                    }
+                    if($merge && is_array($_val)) {
+                        foreach($_val as $_mkey => $_mval) {
+                            $this->_tpl_vars[$_key][$_mkey] = $_mval;
+                        }
+                    } else {
+                        $this->_tpl_vars[$_key][] = $_val;
+                    }
+                }
+            }
+        } else {
+            if ($tpl_var != '' && isset($value)) {
+                if(!@is_array($this->_tpl_vars[$tpl_var])) {
+                    settype($this->_tpl_vars[$tpl_var],'array');
+                }
+                if($merge && is_array($value)) {
+                    foreach($value as $_mkey => $_mval) {
+                        $this->_tpl_vars[$tpl_var][$_mkey] = $_mval;
+                    }
+                } else {
+                    $this->_tpl_vars[$tpl_var][] = $value;
+                }
+            }
+        }
+    }
+
+    /**
+     * appends values to template variables by reference
+     *
+     * @param string $tpl_var the template variable name
+     * @param mixed $value the referenced value to append
+     */
+    function append_by_ref($tpl_var, &$value, $merge=false)
+    {
+        if ($tpl_var != '' && isset($value)) {
+            if(!@is_array($this->_tpl_vars[$tpl_var])) {
+             settype($this->_tpl_vars[$tpl_var],'array');
+            }
+            if ($merge && is_array($value)) {
+                foreach($value as $_key => $_val) {
+                    $this->_tpl_vars[$tpl_var][$_key] = &$value[$_key];
+                }
+            } else {
+                $this->_tpl_vars[$tpl_var][] = &$value;
+            }
+        }
+    }
+
+
+    /**
+     * clear the given assigned template variable.
+     *
+     * @param string $tpl_var the template variable to clear
+     */
+    function clear_assign($tpl_var)
+    {
+        if (is_array($tpl_var))
+            foreach ($tpl_var as $curr_var)
+                unset($this->_tpl_vars[$curr_var]);
+        else
+            unset($this->_tpl_vars[$tpl_var]);
+    }
+
+
+    /**
+     * Registers custom function to be used in templates
+     *
+     * @param string $function the name of the template function
+     * @param string $function_impl the name of the PHP function to register
+     */
+    function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null)
+    {
+        $this->_plugins['function'][$function] =
+            array($function_impl, null, null, false, $cacheable, $cache_attrs);
+
+    }
+
+    /**
+     * Unregisters custom function
+     *
+     * @param string $function name of template function
+     */
+    function unregister_function($function)
+    {
+        unset($this->_plugins['function'][$function]);
+    }
+
+    /**
+     * Registers object to be used in templates
+     *
+     * @param string $object name of template object
+     * @param object &$object_impl the referenced PHP object to register
+     * @param null|array $allowed list of allowed methods (empty = all)
+     * @param boolean $smarty_args smarty argument format, else traditional
+     * @param null|array $block_functs list of methods that are block format
+     */
+    function register_object($object, &$object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
+    {
+        settype($allowed, 'array');
+        settype($smarty_args, 'boolean');
+        $this->_reg_objects[$object] =
+            array(&$object_impl, $allowed, $smarty_args, $block_methods);
+    }
+
+    /**
+     * Unregisters object
+     *
+     * @param string $object name of template object
+     */
+    function unregister_object($object)
+    {
+        unset($this->_reg_objects[$object]);
+    }
+
+
+    /**
+     * Registers block function to be used in templates
+     *
+     * @param string $block name of template block
+     * @param string $block_impl PHP function to register
+     */
+    function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null)
+    {
+        $this->_plugins['block'][$block] =
+            array($block_impl, null, null, false, $cacheable, $cache_attrs);
+    }
+
+    /**
+     * Unregisters block function
+     *
+     * @param string $block name of template function
+     */
+    function unregister_block($block)
+    {
+        unset($this->_plugins['block'][$block]);
+    }
+
+    /**
+     * Registers compiler function
+     *
+     * @param string $function name of template function
+     * @param string $function_impl name of PHP function to register
+     */
+    function register_compiler_function($function, $function_impl, $cacheable=true)
+    {
+        $this->_plugins['compiler'][$function] =
+            array($function_impl, null, null, false, $cacheable);
+    }
+
+    /**
+     * Unregisters compiler function
+     *
+     * @param string $function name of template function
+     */
+    function unregister_compiler_function($function)
+    {
+        unset($this->_plugins['compiler'][$function]);
+    }
+
+    /**
+     * Registers modifier to be used in templates
+     *
+     * @param string $modifier name of template modifier
+     * @param string $modifier_impl name of PHP function to register
+     */
+    function register_modifier($modifier, $modifier_impl)
+    {
+        $this->_plugins['modifier'][$modifier] =
+            array($modifier_impl, null, null, false);
+    }
+
+    /**
+     * Unregisters modifier
+     *
+     * @param string $modifier name of template modifier
+     */
+    function unregister_modifier($modifier)
+    {
+        unset($this->_plugins['modifier'][$modifier]);
+    }
+
+    /**
+     * Registers a resource to fetch a template
+     *
+     * @param string $type name of resource
+     * @param array $functions array of functions to handle resource
+     */
+    function register_resource($type, $functions)
+    {
+        if (count($functions)==4) {
+            $this->_plugins['resource'][$type] =
+                array($functions, false);
+
+        } elseif (count($functions)==5) {
+            $this->_plugins['resource'][$type] =
+                array(array(array(&$functions[0], $functions[1])
+                            ,array(&$functions[0], $functions[2])
+                            ,array(&$functions[0], $functions[3])
+                            ,array(&$functions[0], $functions[4]))
+                      ,false);
+
+        } else {
+            $this->trigger_error("malformed function-list for '$type' in register_resource");
+
+        }
+    }
+
+    /**
+     * Unregisters a resource
+     *
+     * @param string $type name of resource
+     */
+    function unregister_resource($type)
+    {
+        unset($this->_plugins['resource'][$type]);
+    }
+
+    /**
+     * Registers a prefilter function to apply
+     * to a template before compiling
+     *
+     * @param string $function name of PHP function to register
+     */
+    function register_prefilter($function)
+    {
+    $_name = (is_array($function)) ? $function[1] : $function;
+        $this->_plugins['prefilter'][$_name]
+            = array($function, null, null, false);
+    }
+
+    /**
+     * Unregisters a prefilter function
+     *
+     * @param string $function name of PHP function
+     */
+    function unregister_prefilter($function)
+    {
+        unset($this->_plugins['prefilter'][$function]);
+    }
+
+    /**
+     * Registers a postfilter function to apply
+     * to a compiled template after compilation
+     *
+     * @param string $function name of PHP function to register
+     */
+    function register_postfilter($function)
+    {
+    $_name = (is_array($function)) ? $function[1] : $function;
+        $this->_plugins['postfilter'][$_name]
+            = array($function, null, null, false);
+    }
+
+    /**
+     * Unregisters a postfilter function
+     *
+     * @param string $function name of PHP function
+     */
+    function unregister_postfilter($function)
+    {
+        unset($this->_plugins['postfilter'][$function]);
+    }
+
+    /**
+     * Registers an output filter function to apply
+     * to a template output
+     *
+     * @param string $function name of PHP function
+     */
+    function register_outputfilter($function)
+    {
+    $_name = (is_array($function)) ? $function[1] : $function;
+        $this->_plugins['outputfilter'][$_name]
+            = array($function, null, null, false);
+    }
+
+    /**
+     * Unregisters an outputfilter function
+     *
+     * @param string $function name of PHP function
+     */
+    function unregister_outputfilter($function)
+    {
+        unset($this->_plugins['outputfilter'][$function]);
+    }
+
+    /**
+     * load a filter of specified type and name
+     *
+     * @param string $type filter type
+     * @param string $name filter name
+     */
+    function load_filter($type, $name)
+    {
+        switch ($type) {
+            case 'output':
+                $_params = array('plugins' => array(array($type . 'filter', $name, null, null, false)));
+                require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
+                smarty_core_load_plugins($_params, $this);
+                break;
+
+            case 'pre':
+            case 'post':
+                if (!isset($this->_plugins[$type . 'filter'][$name]))
+                    $this->_plugins[$type . 'filter'][$name] = false;
+                break;
+        }
+    }
+
+    /**
+     * clear cached content for the given template and cache id
+     *
+     * @param string $tpl_file name of template file
+     * @param string $cache_id name of cache_id
+     * @param string $compile_id name of compile_id
+     * @param string $exp_time expiration time
+     * @return boolean
+     */
+    function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null)
+    {
+
+        if (!isset($compile_id))
+            $compile_id = $this->compile_id;
+
+        if (!isset($tpl_file))
+            $compile_id = null;
+
+        $_auto_id = $this->_get_auto_id($cache_id, $compile_id);
+
+        if (!empty($this->cache_handler_func)) {
+            return call_user_func_array($this->cache_handler_func,
+                                  array('clear', &$this, &$dummy, $tpl_file, $cache_id, $compile_id, $exp_time));
+        } else {
+            $_params = array('auto_base' => $this->cache_dir,
+                            'auto_source' => $tpl_file,
+                            'auto_id' => $_auto_id,
+                            'exp_time' => $exp_time);
+            require_once(SMARTY_CORE_DIR . 'core.rm_auto.php');
+            return smarty_core_rm_auto($_params, $this);
+        }
+
+    }
+
+
+    /**
+     * clear the entire contents of cache (all templates)
+     *
+     * @param string $exp_time expire time
+     * @return boolean results of {@link smarty_core_rm_auto()}
+     */
+    function clear_all_cache($exp_time = null)
+    {
+        return $this->clear_cache(null, null, null, $exp_time);
+    }
+
+
+    /**
+     * test to see if valid cache exists for this template
+     *
+     * @param string $tpl_file name of template file
+     * @param string $cache_id
+     * @param string $compile_id
+     * @return string|false results of {@link _read_cache_file()}
+     */
+    function is_cached($tpl_file, $cache_id = null, $compile_id = null)
+    {
+        if (!$this->caching)
+            return false;
+
+        if (!isset($compile_id))
+            $compile_id = $this->compile_id;
+
+        $_params = array(
+            'tpl_file' => $tpl_file,
+            'cache_id' => $cache_id,
+            'compile_id' => $compile_id
+        );
+        require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
+        return smarty_core_read_cache_file($_params, $this);
+    }
+
+
+    /**
+     * clear all the assigned template variables.
+     *
+     */
+    function clear_all_assign()
+    {
+        $this->_tpl_vars = array();
+    }
+
+    /**
+     * clears compiled version of specified template resource,
+     * or all compiled template files if one is not specified.
+     * This function is for advanced use only, not normally needed.
+     *
+     * @param string $tpl_file
+     * @param string $compile_id
+     * @param string $exp_time
+     * @return boolean results of {@link smarty_core_rm_auto()}
+     */
+    function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null)
+    {
+        if (!isset($compile_id)) {
+            $compile_id = $this->compile_id;
+        }
+        $_params = array('auto_base' => $this->compile_dir,
+                        'auto_source' => $tpl_file,
+                        'auto_id' => $compile_id,
+                        'exp_time' => $exp_time,
+                        'extensions' => array('.inc', '.php'));
+        require_once(SMARTY_CORE_DIR . 'core.rm_auto.php');
+        return smarty_core_rm_auto($_params, $this);
+    }
+
+    /**
+     * Checks whether requested template exists.
+     *
+     * @param string $tpl_file
+     * @return boolean
+     */
+    function template_exists($tpl_file)
+    {
+        $_params = array('resource_name' => $tpl_file, 'quiet'=>true, 'get_source'=>false);
+        return $this->_fetch_resource_info($_params);
+    }
+
+    /**
+     * Returns an array containing template variables
+     *
+     * @param string $name
+     * @param string $type
+     * @return array
+     */
+    function &get_template_vars($name=null)
+    {
+        if(!isset($name)) {
+            return $this->_tpl_vars;
+        } elseif(isset($this->_tpl_vars[$name])) {
+            return $this->_tpl_vars[$name];
+        } else {
+            // var non-existant, return valid reference
+            $_tmp = null;
+            return $_tmp;   
+        }
+    }
+
+    /**
+     * Returns an array containing config variables
+     *
+     * @param string $name
+     * @param string $type
+     * @return array
+     */
+    function &get_config_vars($name=null)
+    {
+        if(!isset($name) && is_array($this->_config[0])) {
+            return $this->_config[0]['vars'];
+        } else if(isset($this->_config[0]['vars'][$name])) {
+            return $this->_config[0]['vars'][$name];
+        } else {
+            // var non-existant, return valid reference
+            $_tmp = null;
+            return $_tmp;
+        }
+    }
+
+    /**
+     * trigger Smarty error
+     *
+     * @param string $error_msg
+     * @param integer $error_type
+     */
+    function trigger_error($error_msg, $error_type = E_USER_WARNING)
+    {
+        trigger_error("Smarty error: $error_msg", $error_type);
+    }
+
+
+    /**
+     * executes & displays the template results
+     *
+     * @param string $resource_name
+     * @param string $cache_id
+     * @param string $compile_id
+     */
+    function display($resource_name, $cache_id = null, $compile_id = null)
+    {
+        $this->fetch($resource_name, $cache_id, $compile_id, true);
+    }
+
+    /**
+     * executes & returns or displays the template results
+     *
+     * @param string $resource_name
+     * @param string $cache_id
+     * @param string $compile_id
+     * @param boolean $display
+     */
+    function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false)
+    {
+        static $_cache_info = array();
+        
+        $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting)
+               ? $this->error_reporting : error_reporting() & ~E_NOTICE);
+
+        if (!$this->debugging && $this->debugging_ctrl == 'URL') {
+            $_query_string = $this->request_use_auto_globals ? $_SERVER['QUERY_STRING'] : $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING'];
+            if (@strstr($_query_string, $this->_smarty_debug_id)) {
+                if (@strstr($_query_string, $this->_smarty_debug_id . '=on')) {
+                    // enable debugging for this browser session
+                    @setcookie('SMARTY_DEBUG', true);
+                    $this->debugging = true;
+                } elseif (@strstr($_query_string, $this->_smarty_debug_id . '=off')) {
+                    // disable debugging for this browser session
+                    @setcookie('SMARTY_DEBUG', false);
+                    $this->debugging = false;
+                } else {
+                    // enable debugging for this page
+                    $this->debugging = true;
+                }
+            } else {
+                $this->debugging = (bool)($this->request_use_auto_globals ? @$_COOKIE['SMARTY_DEBUG'] : @$GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG']);
+            }
+        }
+
+        if ($this->debugging) {
+            // capture time for debugging info
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $_debug_start_time = smarty_core_get_microtime($_params, $this);
+            $this->_smarty_debug_info[] = array('type'      => 'template',
+                                                'filename'  => $resource_name,
+                                                'depth'     => 0);
+            $_included_tpls_idx = count($this->_smarty_debug_info) - 1;
+        }
+
+        if (!isset($compile_id)) {
+            $compile_id = $this->compile_id;
+        }
+
+        $this->_compile_id = $compile_id;
+        $this->_inclusion_depth = 0;
+
+        if ($this->caching) {
+            // save old cache_info, initialize cache_info
+            array_push($_cache_info, $this->_cache_info);
+            $this->_cache_info = array();
+            $_params = array(
+                'tpl_file' => $resource_name,
+                'cache_id' => $cache_id,
+                'compile_id' => $compile_id,
+                'results' => null
+            );
+            require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
+            if (smarty_core_read_cache_file($_params, $this)) {
+                $_smarty_results = $_params['results'];
+                if (!empty($this->_cache_info['insert_tags'])) {
+                    $_params = array('plugins' => $this->_cache_info['insert_tags']);
+                    require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
+                    smarty_core_load_plugins($_params, $this);
+                    $_params = array('results' => $_smarty_results);
+                    require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
+                    $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
+                }
+                if (!empty($this->_cache_info['cache_serials'])) {
+                    $_params = array('results' => $_smarty_results);
+                    require_once(SMARTY_CORE_DIR . 'core.process_compiled_include.php');
+                    $_smarty_results = smarty_core_process_compiled_include($_params, $this);
+                }
+
+
+                if ($display) {
+                    if ($this->debugging)
+                    {
+                        // capture time for debugging info
+                        $_params = array();
+                        require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+                        $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time;
+                        require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
+                        $_smarty_results .= smarty_core_display_debug_console($_params, $this);
+                    }
+                    if ($this->cache_modified_check) {
+                        $_server_vars = ($this->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
+                        $_last_modified_date = @substr($_server_vars['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_server_vars['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3);
+                        $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT';
+                        if (@count($this->_cache_info['insert_tags']) == 0
+                            && !$this->_cache_serials
+                            && $_gmt_mtime == $_last_modified_date) {
+                            if (php_sapi_name()=='cgi')
+                                header('Status: 304 Not Modified');
+                            else
+                                header('HTTP/1.1 304 Not Modified');
+
+                        } else {
+                            header('Last-Modified: '.$_gmt_mtime);
+                            echo $_smarty_results;
+                        }
+                    } else {
+                            echo $_smarty_results;
+                    }
+                    error_reporting($_smarty_old_error_level);
+                    // restore initial cache_info
+                    $this->_cache_info = array_pop($_cache_info);
+                    return true;
+                } else {
+                    error_reporting($_smarty_old_error_level);
+                    // restore initial cache_info
+                    $this->_cache_info = array_pop($_cache_info);
+                    return $_smarty_results;
+                }
+            } else {
+                $this->_cache_info['template'][$resource_name] = true;
+                if ($this->cache_modified_check && $display) {
+                    header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
+                }
+            }
+        }
+
+        // load filters that are marked as autoload
+        if (count($this->autoload_filters)) {
+            foreach ($this->autoload_filters as $_filter_type => $_filters) {
+                foreach ($_filters as $_filter) {
+                    $this->load_filter($_filter_type, $_filter);
+                }
+            }
+        }
+
+        $_smarty_compile_path = $this->_get_compile_path($resource_name);
+
+        // if we just need to display the results, don't perform output
+        // buffering - for speed
+        $_cache_including = $this->_cache_including;
+        $this->_cache_including = false;
+        if ($display && !$this->caching && count($this->_plugins['outputfilter']) == 0) {
+            if ($this->_is_compiled($resource_name, $_smarty_compile_path)
+                    || $this->_compile_resource($resource_name, $_smarty_compile_path))
+            {
+                include($_smarty_compile_path);
+            }
+        } else {
+            ob_start();
+            if ($this->_is_compiled($resource_name, $_smarty_compile_path)
+                    || $this->_compile_resource($resource_name, $_smarty_compile_path))
+            {
+                include($_smarty_compile_path);
+            }
+            $_smarty_results = ob_get_contents();
+            ob_end_clean();
+
+            foreach ((array)$this->_plugins['outputfilter'] as $_output_filter) {
+                $_smarty_results = call_user_func_array($_output_filter[0], array($_smarty_results, &$this));
+            }
+        }
+
+        if ($this->caching) {
+            $_params = array('tpl_file' => $resource_name,
+                        'cache_id' => $cache_id,
+                        'compile_id' => $compile_id,
+                        'results' => $_smarty_results);
+            require_once(SMARTY_CORE_DIR . 'core.write_cache_file.php');
+            smarty_core_write_cache_file($_params, $this);
+            require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
+            $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
+
+            if ($this->_cache_serials) {
+                // strip nocache-tags from output
+                $_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s'
+                                                ,''
+                                                ,$_smarty_results);
+            }
+            // restore initial cache_info
+            $this->_cache_info = array_pop($_cache_info);
+        }
+        $this->_cache_including = $_cache_including;
+
+        if ($display) {
+            if (isset($_smarty_results)) { echo $_smarty_results; }
+            if ($this->debugging) {
+                // capture time for debugging info
+                $_params = array();
+                require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+                $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time);
+                require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
+                echo smarty_core_display_debug_console($_params, $this);
+            }
+            error_reporting($_smarty_old_error_level);
+            return;
+        } else {
+            error_reporting($_smarty_old_error_level);
+            if (isset($_smarty_results)) { return $_smarty_results; }
+        }
+    }
+
+    /**
+     * load configuration values
+     *
+     * @param string $file
+     * @param string $section
+     * @param string $scope
+     */
+    function config_load($file, $section = null, $scope = 'global')
+    {
+        require_once($this->_get_plugin_filepath('function', 'config_load'));
+        smarty_function_config_load(array('file' => $file, 'section' => $section, 'scope' => $scope), $this);
+    }
+
+    /**
+     * return a reference to a registered object
+     *
+     * @param string $name
+     * @return object
+     */
+    function &get_registered_object($name) {
+        if (!isset($this->_reg_objects[$name]))
+        $this->_trigger_fatal_error("'$name' is not a registered object");
+
+        if (!is_object($this->_reg_objects[$name][0]))
+        $this->_trigger_fatal_error("registered '$name' is not an object");
+
+        return $this->_reg_objects[$name][0];
+    }
+
+    /**
+     * clear configuration values
+     *
+     * @param string $var
+     */
+    function clear_config($var = null)
+    {
+        if(!isset($var)) {
+            // clear all values
+            $this->_config = array(array('vars'  => array(),
+                                         'files' => array()));
+        } else {
+            unset($this->_config[0]['vars'][$var]);
+        }
+    }
+
+    /**
+     * get filepath of requested plugin
+     *
+     * @param string $type
+     * @param string $name
+     * @return string|false
+     */
+    function _get_plugin_filepath($type, $name)
+    {
+        $_params = array('type' => $type, 'name' => $name);
+        require_once(SMARTY_CORE_DIR . 'core.assemble_plugin_filepath.php');
+        return smarty_core_assemble_plugin_filepath($_params, $this);
+    }
+
+   /**
+     * test if resource needs compiling
+     *
+     * @param string $resource_name
+     * @param string $compile_path
+     * @return boolean
+     */
+    function _is_compiled($resource_name, $compile_path)
+    {
+        if (!$this->force_compile && file_exists($compile_path)) {
+            if (!$this->compile_check) {
+                // no need to check compiled file
+                return true;
+            } else {
+                // get file source and timestamp
+                $_params = array('resource_name' => $resource_name, 'get_source'=>false);
+                if (!$this->_fetch_resource_info($_params)) {
+                    return false;
+                }
+                if ($_params['resource_timestamp'] <= filemtime($compile_path)) {
+                    // template not expired, no recompile
+                    return true;
+                } else {
+                    // compile template
+                    return false;
+                }
+            }
+        } else {
+            // compiled template does not exist, or forced compile
+            return false;
+        }
+    }
+
+   /**
+     * compile the template
+     *
+     * @param string $resource_name
+     * @param string $compile_path
+     * @return boolean
+     */
+    function _compile_resource($resource_name, $compile_path)
+    {
+
+        $_params = array('resource_name' => $resource_name);
+        if (!$this->_fetch_resource_info($_params)) {
+            return false;
+        }
+
+        $_source_content = $_params['source_content'];
+        $_cache_include    = substr($compile_path, 0, -4).'.inc';
+
+        if ($this->_compile_source($resource_name, $_source_content, $_compiled_content, $_cache_include)) {
+            // if a _cache_serial was set, we also have to write an include-file:
+            if ($this->_cache_include_info) {
+                require_once(SMARTY_CORE_DIR . 'core.write_compiled_include.php');
+                smarty_core_write_compiled_include(array_merge($this->_cache_include_info, array('compiled_content'=>$_compiled_content, 'resource_name'=>$resource_name)),  $this);
+            }
+
+            $_params = array('compile_path'=>$compile_path, 'compiled_content' => $_compiled_content);
+            require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php');
+            smarty_core_write_compiled_resource($_params, $this);
+
+            return true;
+        } else {
+            return false;
+        }
+
+    }
+
+   /**
+     * compile the given source
+     *
+     * @param string $resource_name
+     * @param string $source_content
+     * @param string $compiled_content
+     * @return boolean
+     */
+    function _compile_source($resource_name, &$source_content, &$compiled_content, $cache_include_path=null)
+    {
+        if (file_exists(SMARTY_DIR . $this->compiler_file)) {
+            require_once(SMARTY_DIR . $this->compiler_file);
+        } else {
+            // use include_path
+            require_once($this->compiler_file);
+        }
+
+
+        $smarty_compiler = new $this->compiler_class;
+
+        $smarty_compiler->template_dir      = $this->template_dir;
+        $smarty_compiler->compile_dir       = $this->compile_dir;
+        $smarty_compiler->plugins_dir       = $this->plugins_dir;
+        $smarty_compiler->config_dir        = $this->config_dir;
+        $smarty_compiler->force_compile     = $this->force_compile;
+        $smarty_compiler->caching           = $this->caching;
+        $smarty_compiler->php_handling      = $this->php_handling;
+        $smarty_compiler->left_delimiter    = $this->left_delimiter;
+        $smarty_compiler->right_delimiter   = $this->right_delimiter;
+        $smarty_compiler->_version          = $this->_version;
+        $smarty_compiler->security          = $this->security;
+        $smarty_compiler->secure_dir        = $this->secure_dir;
+        $smarty_compiler->security_settings = $this->security_settings;
+        $smarty_compiler->trusted_dir       = $this->trusted_dir;
+        $smarty_compiler->use_sub_dirs      = $this->use_sub_dirs;
+        $smarty_compiler->_reg_objects      = &$this->_reg_objects;
+        $smarty_compiler->_plugins          = &$this->_plugins;
+        $smarty_compiler->_tpl_vars         = &$this->_tpl_vars;
+        $smarty_compiler->default_modifiers = $this->default_modifiers;
+        $smarty_compiler->compile_id        = $this->_compile_id;
+        $smarty_compiler->_config            = $this->_config;
+        $smarty_compiler->request_use_auto_globals  = $this->request_use_auto_globals;
+
+        if (isset($cache_include_path) && isset($this->_cache_serials[$cache_include_path])) {
+            $smarty_compiler->_cache_serial = $this->_cache_serials[$cache_include_path];
+        }
+        $smarty_compiler->_cache_include = $cache_include_path;
+
+
+        $_results = $smarty_compiler->_compile_file($resource_name, $source_content, $compiled_content);
+
+        if ($smarty_compiler->_cache_serial) {
+            $this->_cache_include_info = array(
+                'cache_serial'=>$smarty_compiler->_cache_serial
+                ,'plugins_code'=>$smarty_compiler->_plugins_code
+                ,'include_file_path' => $cache_include_path);
+
+        } else {
+            $this->_cache_include_info = null;
+
+        }
+
+        return $_results;
+    }
+
+    /**
+     * Get the compile path for this resource
+     *
+     * @param string $resource_name
+     * @return string results of {@link _get_auto_filename()}
+     */
+    function _get_compile_path($resource_name)
+    {
+        return $this->_get_auto_filename($this->compile_dir, $resource_name,
+                                         $this->_compile_id) . '.php';
+    }
+
+    /**
+     * fetch the template info. Gets timestamp, and source
+     * if get_source is true
+     *
+     * sets $source_content to the source of the template, and
+     * $resource_timestamp to its time stamp
+     * @param string $resource_name
+     * @param string $source_content
+     * @param integer $resource_timestamp
+     * @param boolean $get_source
+     * @param boolean $quiet
+     * @return boolean
+     */
+
+    function _fetch_resource_info(&$params)
+    {
+        if(!isset($params['get_source'])) { $params['get_source'] = true; }
+        if(!isset($params['quiet'])) { $params['quiet'] = false; }
+
+        $_return = false;
+        $_params = array('resource_name' => $params['resource_name']) ;
+        if (isset($params['resource_base_path']))
+            $_params['resource_base_path'] = $params['resource_base_path'];
+        else
+            $_params['resource_base_path'] = $this->template_dir;
+
+        if ($this->_parse_resource_name($_params)) {
+            $_resource_type = $_params['resource_type'];
+            $_resource_name = $_params['resource_name'];
+            switch ($_resource_type) {
+                case 'file':
+                    if ($params['get_source']) {
+                        $params['source_content'] = $this->_read_file($_resource_name);
+                    }
+                    $params['resource_timestamp'] = filemtime($_resource_name);
+                    $_return = is_file($_resource_name);
+                    break;
+
+                default:
+                    // call resource functions to fetch the template source and timestamp
+                    if ($params['get_source']) {
+                        $_source_return = isset($this->_plugins['resource'][$_resource_type]) &&
+                            call_user_func_array($this->_plugins['resource'][$_resource_type][0][0],
+                                                 array($_resource_name, &$params['source_content'], &$this));
+                    } else {
+                        $_source_return = true;
+                    }
+
+                    $_timestamp_return = isset($this->_plugins['resource'][$_resource_type]) &&
+                        call_user_func_array($this->_plugins['resource'][$_resource_type][0][1],
+                                             array($_resource_name, &$params['resource_timestamp'], &$this));
+
+                    $_return = $_source_return && $_timestamp_return;
+                    break;
+            }
+        }
+
+        if (!$_return) {
+            // see if we can get a template with the default template handler
+            if (!empty($this->default_template_handler_func)) {
+                if (!is_callable($this->default_template_handler_func)) {
+                    $this->trigger_error("default template handler function \"$this->default_template_handler_func\" doesn't exist.");
+                } else {
+                    $_return = call_user_func_array(
+                        $this->default_template_handler_func,
+                        array($_params['resource_type'], $_params['resource_name'], &$params['source_content'], &$params['resource_timestamp'], &$this));
+                }
+            }
+        }
+
+        if (!$_return) {
+            if (!$params['quiet']) {
+                $this->trigger_error('unable to read resource: "' . $params['resource_name'] . '"');
+            }
+        } else if ($_return && $this->security) {
+            require_once(SMARTY_CORE_DIR . 'core.is_secure.php');
+            if (!smarty_core_is_secure($_params, $this)) {
+                if (!$params['quiet'])
+                    $this->trigger_error('(secure mode) accessing "' . $params['resource_name'] . '" is not allowed');
+                $params['source_content'] = null;
+                $params['resource_timestamp'] = null;
+                return false;
+            }
+        }
+        return $_return;
+    }
+
+
+    /**
+     * parse out the type and name from the resource
+     *
+     * @param string $resource_base_path
+     * @param string $resource_name
+     * @param string $resource_type
+     * @param string $resource_name
+     * @return boolean
+     */
+
+    function _parse_resource_name(&$params)
+    {
+
+        // split tpl_path by the first colon
+        $_resource_name_parts = explode(':', $params['resource_name'], 2);
+
+        if (count($_resource_name_parts) == 1) {
+            // no resource type given
+            $params['resource_type'] = $this->default_resource_type;
+            $params['resource_name'] = $_resource_name_parts[0];
+        } else {
+            if(strlen($_resource_name_parts[0]) == 1) {
+                // 1 char is not resource type, but part of filepath
+                $params['resource_type'] = $this->default_resource_type;
+                $params['resource_name'] = $params['resource_name'];
+            } else {
+                $params['resource_type'] = $_resource_name_parts[0];
+                $params['resource_name'] = $_resource_name_parts[1];
+            }
+        }
+
+        if ($params['resource_type'] == 'file') {
+            if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $params['resource_name'])) {
+                // relative pathname to $params['resource_base_path']
+                // use the first directory where the file is found
+                foreach ((array)$params['resource_base_path'] as $_curr_path) {
+                    $_fullpath = $_curr_path . DIRECTORY_SEPARATOR . $params['resource_name'];
+                    if (file_exists($_fullpath) && is_file($_fullpath)) {
+                        $params['resource_name'] = $_fullpath;
+                        return true;
+                    }
+                    // didn't find the file, try include_path
+                    $_params = array('file_path' => $_fullpath);
+                    require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
+                    if(smarty_core_get_include_path($_params, $this)) {
+                        $params['resource_name'] = $_params['new_file_path'];
+                        return true;
+                    }
+                }
+                return false;
+            } else {
+                /* absolute path */
+                return file_exists($params['resource_name']);
+            }
+        } elseif (empty($this->_plugins['resource'][$params['resource_type']])) {
+            $_params = array('type' => $params['resource_type']);
+            require_once(SMARTY_CORE_DIR . 'core.load_resource_plugin.php');
+            smarty_core_load_resource_plugin($_params, $this);
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Handle modifiers
+     *
+     * @param string|null $modifier_name
+     * @param array|null $map_array
+     * @return string result of modifiers
+     */
+    function _run_mod_handler()
+    {
+        $_args = func_get_args();
+        list($_modifier_name, $_map_array) = array_splice($_args, 0, 2);
+        list($_func_name, $_tpl_file, $_tpl_line) =
+            $this->_plugins['modifier'][$_modifier_name];
+
+        $_var = $_args[0];
+        foreach ($_var as $_key => $_val) {
+            $_args[0] = $_val;
+            $_var[$_key] = call_user_func_array($_func_name, $_args);
+        }
+        return $_var;
+    }
+
+    /**
+     * Remove starting and ending quotes from the string
+     *
+     * @param string $string
+     * @return string
+     */
+    function _dequote($string)
+    {
+        if ((substr($string, 0, 1) == "'" || substr($string, 0, 1) == '"') &&
+            substr($string, -1) == substr($string, 0, 1))
+            return substr($string, 1, -1);
+        else
+            return $string;
+    }
+
+
+    /**
+     * read in a file
+     *
+     * @param string $filename
+     * @return string
+     */
+    function _read_file($filename)
+    {
+        if ( file_exists($filename) && ($fd = @fopen($filename, 'rb')) ) {
+            $contents = '';
+            while (!feof($fd)) {
+                $contents .= fread($fd, 8192);
+            }
+            fclose($fd);
+            return $contents;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * get a concrete filename for automagically created content
+     *
+     * @param string $auto_base
+     * @param string $auto_source
+     * @param string $auto_id
+     * @return string
+     * @staticvar string|null
+     * @staticvar string|null
+     */
+    function _get_auto_filename($auto_base, $auto_source = null, $auto_id = null)
+    {
+        $_compile_dir_sep =  $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^';
+        $_return = $auto_base . DIRECTORY_SEPARATOR;
+
+        if(isset($auto_id)) {
+            // make auto_id safe for directory names
+            $auto_id = str_replace('%7C',$_compile_dir_sep,(urlencode($auto_id)));
+            // split into separate directories
+            $_return .= $auto_id . $_compile_dir_sep;
+        }
+
+        if(isset($auto_source)) {
+            // make source name safe for filename
+            $_filename = urlencode(basename($auto_source));
+            $_crc32 = sprintf('%08X', crc32($auto_source));
+            // prepend %% to avoid name conflicts with
+            // with $params['auto_id'] names
+            $_crc32 = substr($_crc32, 0, 2) . $_compile_dir_sep .
+                      substr($_crc32, 0, 3) . $_compile_dir_sep . $_crc32;
+            $_return .= '%%' . $_crc32 . '%%' . $_filename;
+        }
+
+        return $_return;
+    }
+
+    /**
+     * unlink a file, possibly using expiration time
+     *
+     * @param string $resource
+     * @param integer $exp_time
+     */
+    function _unlink($resource, $exp_time = null)
+    {
+        if(isset($exp_time)) {
+            if(time() - @filemtime($resource) >= $exp_time) {
+                return @unlink($resource);
+            }
+        } else {
+            return @unlink($resource);
+        }
+    }
+
+    /**
+     * returns an auto_id for auto-file-functions
+     *
+     * @param string $cache_id
+     * @param string $compile_id
+     * @return string|null
+     */
+    function _get_auto_id($cache_id=null, $compile_id=null) {
+    if (isset($cache_id))
+        return (isset($compile_id)) ? $cache_id . '|' . $compile_id  : $cache_id;
+    elseif(isset($compile_id))
+        return $compile_id;
+    else
+        return null;
+    }
+
+    /**
+     * trigger Smarty plugin error
+     *
+     * @param string $error_msg
+     * @param string $tpl_file
+     * @param integer $tpl_line
+     * @param string $file
+     * @param integer $line
+     * @param integer $error_type
+     */
+    function _trigger_fatal_error($error_msg, $tpl_file = null, $tpl_line = null,
+            $file = null, $line = null, $error_type = E_USER_ERROR)
+    {
+        if(isset($file) && isset($line)) {
+            $info = ' ('.basename($file).", line $line)";
+        } else {
+            $info = '';
+        }
+        if (isset($tpl_line) && isset($tpl_file)) {
+            $this->trigger_error('[in ' . $tpl_file . ' line ' . $tpl_line . "]: $error_msg$info", $error_type);
+        } else {
+            $this->trigger_error($error_msg . $info, $error_type);
+        }
+    }
+
+
+    /**
+     * callback function for preg_replace, to call a non-cacheable block
+     * @return string
+     */
+    function _process_compiled_include_callback($match) {
+        $_func = '_smarty_tplfunc_'.$match[2].'_'.$match[3];
+        ob_start();
+        $_func($this);
+        $_ret = ob_get_contents();
+        ob_end_clean();
+        return $_ret;
+    }
+
+
+    /**
+     * called for included templates
+     *
+     * @param string $_smarty_include_tpl_file
+     * @param string $_smarty_include_vars
+     */
+
+    // $_smarty_include_tpl_file, $_smarty_include_vars
+
+    function _smarty_include($params)
+    {
+        if ($this->debugging) {
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $debug_start_time = smarty_core_get_microtime($_params, $this);
+            $this->_smarty_debug_info[] = array('type'      => 'template',
+                                                  'filename'  => $params['smarty_include_tpl_file'],
+                                                  'depth'     => ++$this->_inclusion_depth);
+            $included_tpls_idx = count($this->_smarty_debug_info) - 1;
+        }
+
+        $this->_tpl_vars = array_merge($this->_tpl_vars, $params['smarty_include_vars']);
+
+        // config vars are treated as local, so push a copy of the
+        // current ones onto the front of the stack
+        array_unshift($this->_config, $this->_config[0]);
+
+        $_smarty_compile_path = $this->_get_compile_path($params['smarty_include_tpl_file']);
+
+
+        if ($this->_is_compiled($params['smarty_include_tpl_file'], $_smarty_compile_path)
+            || $this->_compile_resource($params['smarty_include_tpl_file'], $_smarty_compile_path))
+        {
+            include($_smarty_compile_path);
+        }
+
+        // pop the local vars off the front of the stack
+        array_shift($this->_config);
+
+        $this->_inclusion_depth--;
+
+        if ($this->debugging) {
+            // capture time for debugging info
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $debug_start_time;
+        }
+
+        if ($this->caching) {
+            $this->_cache_info['template'][$params['smarty_include_tpl_file']] = true;
+        }
+    }
+
+
+    /**
+     * get or set an array of cached attributes for function that is
+     * not cacheable
+     * @return array
+     */
+    function &_smarty_cache_attrs($cache_serial, $count) {
+        $_cache_attrs =& $this->_cache_info['cache_attrs'][$cache_serial][$count];
+
+        if ($this->_cache_including) {
+            /* return next set of cache_attrs */
+            $_return = current($_cache_attrs);
+            next($_cache_attrs);
+            return $_return;
+
+        } else {
+            /* add a reference to a new set of cache_attrs */
+            $_cache_attrs[] = array();
+            return $_cache_attrs[count($_cache_attrs)-1];
+
+        }
+
+    }
+
+
+    /**
+     * wrapper for include() retaining $this
+     * @return mixed
+     */
+    function _include($filename, $once=false, $params=null)
+    {
+        if ($once) {
+            return include_once($filename);
+        } else {
+            return include($filename);
+        }
+    }
+
+
+    /**
+     * wrapper for eval() retaining $this
+     * @return mixed
+     */
+    function _eval($code, $params=null)
+    {
+        return eval($code);
+    }
+    /**#@-*/
+
+}
+
+/* vim: set expandtab: */
+
+?>

+ 2328 - 0
Tools/projectGenerator/smarty/Smarty_Compiler.class.php

@@ -0,0 +1,2328 @@
+<?php
+
+/**
+ * Project:     Smarty: the PHP compiling template engine
+ * File:        Smarty_Compiler.class.php
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @link http://smarty.php.net/
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Andrei Zmievski <[email protected]>
+ * @version 2.6.18
+ * @copyright 2001-2005 New Digital Group, Inc.
+ * @package Smarty
+ */
+
+/* $Id: Smarty_Compiler.class.php,v 1.395 2007/03/06 10:40:06 messju Exp $ */
+
+/**
+ * Template compiling class
+ * @package Smarty
+ */
+class Smarty_Compiler extends Smarty {
+
+    // internal vars
+    /**#@+
+     * @access private
+     */
+    var $_folded_blocks         =   array();    // keeps folded template blocks
+    var $_current_file          =   null;       // the current template being compiled
+    var $_current_line_no       =   1;          // line number for error messages
+    var $_capture_stack         =   array();    // keeps track of nested capture buffers
+    var $_plugin_info           =   array();    // keeps track of plugins to load
+    var $_init_smarty_vars      =   false;
+    var $_permitted_tokens      =   array('true','false','yes','no','on','off','null');
+    var $_db_qstr_regexp        =   null;        // regexps are setup in the constructor
+    var $_si_qstr_regexp        =   null;
+    var $_qstr_regexp           =   null;
+    var $_func_regexp           =   null;
+    var $_reg_obj_regexp        =   null;
+    var $_var_bracket_regexp    =   null;
+    var $_num_const_regexp      =   null;
+    var $_dvar_guts_regexp      =   null;
+    var $_dvar_regexp           =   null;
+    var $_cvar_regexp           =   null;
+    var $_svar_regexp           =   null;
+    var $_avar_regexp           =   null;
+    var $_mod_regexp            =   null;
+    var $_var_regexp            =   null;
+    var $_parenth_param_regexp  =   null;
+    var $_func_call_regexp      =   null;
+    var $_obj_ext_regexp        =   null;
+    var $_obj_start_regexp      =   null;
+    var $_obj_params_regexp     =   null;
+    var $_obj_call_regexp       =   null;
+    var $_cacheable_state       =   0;
+    var $_cache_attrs_count     =   0;
+    var $_nocache_count         =   0;
+    var $_cache_serial          =   null;
+    var $_cache_include         =   null;
+
+    var $_strip_depth           =   0;
+    var $_additional_newline    =   "\n";
+
+    /**#@-*/
+    /**
+     * The class constructor.
+     */
+    function Smarty_Compiler()
+    {
+        // matches double quoted strings:
+        // "foobar"
+        // "foo\"bar"
+        $this->_db_qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"';
+
+        // matches single quoted strings:
+        // 'foobar'
+        // 'foo\'bar'
+        $this->_si_qstr_regexp = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
+
+        // matches single or double quoted strings
+        $this->_qstr_regexp = '(?:' . $this->_db_qstr_regexp . '|' . $this->_si_qstr_regexp . ')';
+
+        // matches bracket portion of vars
+        // [0]
+        // [foo]
+        // [$bar]
+        $this->_var_bracket_regexp = '\[\$?[\w\.]+\]';
+
+        // matches numerical constants
+        // 30
+        // -12
+        // 13.22
+        $this->_num_const_regexp = '(?:\-?\d+(?:\.\d+)?)';
+
+        // matches $ vars (not objects):
+        // $foo
+        // $foo.bar
+        // $foo.bar.foobar
+        // $foo[0]
+        // $foo[$bar]
+        // $foo[5][blah]
+        // $foo[5].bar[$foobar][4]
+        $this->_dvar_math_regexp = '(?:[\+\*\/\%]|(?:-(?!>)))';
+        $this->_dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]';
+        $this->_dvar_guts_regexp = '\w+(?:' . $this->_var_bracket_regexp
+                . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?';
+        $this->_dvar_regexp = '\$' . $this->_dvar_guts_regexp;
+
+        // matches config vars:
+        // #foo#
+        // #foobar123_foo#
+        $this->_cvar_regexp = '\#\w+\#';
+
+        // matches section vars:
+        // %foo.bar%
+        $this->_svar_regexp = '\%\w+\.\w+\%';
+
+        // matches all valid variables (no quotes, no modifiers)
+        $this->_avar_regexp = '(?:' . $this->_dvar_regexp . '|'
+           . $this->_cvar_regexp . '|' . $this->_svar_regexp . ')';
+
+        // matches valid variable syntax:
+        // $foo
+        // $foo
+        // #foo#
+        // #foo#
+        // "text"
+        // "text"
+        $this->_var_regexp = '(?:' . $this->_avar_regexp . '|' . $this->_qstr_regexp . ')';
+
+        // matches valid object call (one level of object nesting allowed in parameters):
+        // $foo->bar
+        // $foo->bar()
+        // $foo->bar("text")
+        // $foo->bar($foo, $bar, "text")
+        // $foo->bar($foo, "foo")
+        // $foo->bar->foo()
+        // $foo->bar->foo->bar()
+        // $foo->bar($foo->bar)
+        // $foo->bar($foo->bar())
+        // $foo->bar($foo->bar($blah,$foo,44,"foo",$foo[0].bar))
+        $this->_obj_ext_regexp = '\->(?:\$?' . $this->_dvar_guts_regexp . ')';
+        $this->_obj_restricted_param_regexp = '(?:'
+                . '(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')(?:' . $this->_obj_ext_regexp . '(?:\((?:(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')'
+                . '(?:\s*,\s*(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . '))*)?\))?)*)';
+        $this->_obj_single_param_regexp = '(?:\w+|' . $this->_obj_restricted_param_regexp . '(?:\s*,\s*(?:(?:\w+|'
+                . $this->_var_regexp . $this->_obj_restricted_param_regexp . ')))*)';
+        $this->_obj_params_regexp = '\((?:' . $this->_obj_single_param_regexp
+                . '(?:\s*,\s*' . $this->_obj_single_param_regexp . ')*)?\)';
+        $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)';
+        $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?)';
+        
+        // matches valid modifier syntax:
+        // |foo
+        // |@foo
+        // |foo:"bar"
+        // |foo:$bar
+        // |foo:"bar":$foobar
+        // |foo|bar
+        // |foo:$foo->bar
+        $this->_mod_regexp = '(?:\|@?\w+(?::(?:\w+|' . $this->_num_const_regexp . '|'
+           . $this->_obj_call_regexp . '|' . $this->_avar_regexp . '|' . $this->_qstr_regexp .'))*)';
+
+        // matches valid function name:
+        // foo123
+        // _foo_bar
+        $this->_func_regexp = '[a-zA-Z_]\w*';
+
+        // matches valid registered object:
+        // foo->bar
+        $this->_reg_obj_regexp = '[a-zA-Z_]\w*->[a-zA-Z_]\w*';
+
+        // matches valid parameter values:
+        // true
+        // $foo
+        // $foo|bar
+        // #foo#
+        // #foo#|bar
+        // "text"
+        // "text"|bar
+        // $foo->bar
+        $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|'
+           . $this->_var_regexp . '|' . $this->_num_const_regexp  . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)';
+
+        // matches valid parenthesised function parameters:
+        //
+        // "text"
+        //    $foo, $bar, "text"
+        // $foo|bar, "foo"|bar, $foo->bar($foo)|bar
+        $this->_parenth_param_regexp = '(?:\((?:\w+|'
+                . $this->_param_regexp . '(?:\s*,\s*(?:(?:\w+|'
+                . $this->_param_regexp . ')))*)?\))';
+
+        // matches valid function call:
+        // foo()
+        // foo_bar($foo)
+        // _foo_bar($foo,"bar")
+        // foo123($foo,$foo->bar(),"foo")
+        $this->_func_call_regexp = '(?:' . $this->_func_regexp . '\s*(?:'
+           . $this->_parenth_param_regexp . '))';
+    }
+
+    /**
+     * compile a resource
+     *
+     * sets $compiled_content to the compiled source
+     * @param string $resource_name
+     * @param string $source_content
+     * @param string $compiled_content
+     * @return true
+     */
+    function _compile_file($resource_name, $source_content, &$compiled_content)
+    {
+
+        if ($this->security) {
+            // do not allow php syntax to be executed unless specified
+            if ($this->php_handling == SMARTY_PHP_ALLOW &&
+                !$this->security_settings['PHP_HANDLING']) {
+                $this->php_handling = SMARTY_PHP_PASSTHRU;
+            }
+        }
+
+        $this->_load_filters();
+
+        $this->_current_file = $resource_name;
+        $this->_current_line_no = 1;
+        $ldq = preg_quote($this->left_delimiter, '~');
+        $rdq = preg_quote($this->right_delimiter, '~');
+
+        // run template source through prefilter functions
+        if (count($this->_plugins['prefilter']) > 0) {
+            foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
+                if ($prefilter === false) continue;
+                if ($prefilter[3] || is_callable($prefilter[0])) {
+                    $source_content = call_user_func_array($prefilter[0],
+                                                            array($source_content, &$this));
+                    $this->_plugins['prefilter'][$filter_name][3] = true;
+                } else {
+                    $this->_trigger_fatal_error("[plugin] prefilter '$filter_name' is not implemented");
+                }
+            }
+        }
+
+        /* fetch all special blocks */
+        $search = "~{$ldq}\*(.*?)\*{$rdq}|{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}|{$ldq}\s*php\s*{$rdq}(.*?){$ldq}\s*/php\s*{$rdq}~s";
+
+        preg_match_all($search, $source_content, $match,  PREG_SET_ORDER);
+        $this->_folded_blocks = $match;
+        reset($this->_folded_blocks);
+
+        /* replace special blocks by "{php}" */
+        $source_content = preg_replace($search.'e', "'"
+                                       . $this->_quote_replace($this->left_delimiter) . 'php'
+                                       . "' . str_repeat(\"\n\", substr_count('\\0', \"\n\")) .'"
+                                       . $this->_quote_replace($this->right_delimiter)
+                                       . "'"
+                                       , $source_content);
+
+        /* Gather all template tags. */
+        preg_match_all("~{$ldq}\s*(.*?)\s*{$rdq}~s", $source_content, $_match);
+        $template_tags = $_match[1];
+        /* Split content by template tags to obtain non-template content. */
+        $text_blocks = preg_split("~{$ldq}.*?{$rdq}~s", $source_content);
+
+        /* loop through text blocks */
+        for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) {
+            /* match anything resembling php tags */
+            if (preg_match_all('~(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?\s*php\s*[\"\']?)~is', $text_blocks[$curr_tb], $sp_match)) {
+                /* replace tags with placeholders to prevent recursive replacements */
+                $sp_match[1] = array_unique($sp_match[1]);
+                usort($sp_match[1], '_smarty_sort_length');
+                for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
+                    $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$text_blocks[$curr_tb]);
+                }
+                /* process each one */
+                for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
+                    if ($this->php_handling == SMARTY_PHP_PASSTHRU) {
+                        /* echo php contents */
+                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '<?php echo \''.str_replace("'", "\'", $sp_match[1][$curr_sp]).'\'; ?>'."\n", $text_blocks[$curr_tb]);
+                    } else if ($this->php_handling == SMARTY_PHP_QUOTE) {
+                        /* quote php tags */
+                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]);
+                    } else if ($this->php_handling == SMARTY_PHP_REMOVE) {
+                        /* remove php tags */
+                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '', $text_blocks[$curr_tb]);
+                    } else {
+                        /* SMARTY_PHP_ALLOW, but echo non php starting tags */
+                        $sp_match[1][$curr_sp] = preg_replace('~(<\?(?!php|=|$))~i', '<?php echo \'\\1\'?>'."\n", $sp_match[1][$curr_sp]);
+                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]);
+                    }
+                }
+            }
+        }
+        
+        /* Compile the template tags into PHP code. */
+        $compiled_tags = array();
+        for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) {
+            $this->_current_line_no += substr_count($text_blocks[$i], "\n");
+            $compiled_tags[] = $this->_compile_tag($template_tags[$i]);
+            $this->_current_line_no += substr_count($template_tags[$i], "\n");
+        }
+        if (count($this->_tag_stack)>0) {
+            list($_open_tag, $_line_no) = end($this->_tag_stack);
+            $this->_syntax_error("unclosed tag \{$_open_tag} (opened line $_line_no).", E_USER_ERROR, __FILE__, __LINE__);
+            return;
+        }
+
+        /* Reformat $text_blocks between 'strip' and '/strip' tags,
+           removing spaces, tabs and newlines. */
+        $strip = false;
+        for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
+            if ($compiled_tags[$i] == '{strip}') {
+                $compiled_tags[$i] = '';
+                $strip = true;
+                /* remove leading whitespaces */
+                $text_blocks[$i + 1] = ltrim($text_blocks[$i + 1]);
+            }
+            if ($strip) {
+                /* strip all $text_blocks before the next '/strip' */
+                for ($j = $i + 1; $j < $for_max; $j++) {
+                    /* remove leading and trailing whitespaces of each line */
+                    $text_blocks[$j] = preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $text_blocks[$j]);
+                    if ($compiled_tags[$j] == '{/strip}') {                       
+                        /* remove trailing whitespaces from the last text_block */
+                        $text_blocks[$j] = rtrim($text_blocks[$j]);
+                    }
+                    $text_blocks[$j] = "<?php echo '" . strtr($text_blocks[$j], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>";
+                    if ($compiled_tags[$j] == '{/strip}') {
+                        $compiled_tags[$j] = "\n"; /* slurped by php, but necessary
+                                    if a newline is following the closing strip-tag */
+                        $strip = false;
+                        $i = $j;
+                        break;
+                    }
+                }
+            }
+        }
+        $compiled_content = '';
+        
+        $tag_guard = '%%%SMARTYOTG' . md5(uniqid(rand(), true)) . '%%%';
+        
+        /* Interleave the compiled contents and text blocks to get the final result. */
+        for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
+            if ($compiled_tags[$i] == '') {
+                // tag result empty, remove first newline from following text block
+                $text_blocks[$i+1] = preg_replace('~^(\r\n|\r|\n)~', '', $text_blocks[$i+1]);
+            }
+            // replace legit PHP tags with placeholder
+            $text_blocks[$i] = str_replace('<?', $tag_guard, $text_blocks[$i]);
+            $compiled_tags[$i] = str_replace('<?', $tag_guard, $compiled_tags[$i]);
+            
+            $compiled_content .= $text_blocks[$i] . $compiled_tags[$i];
+        }
+        $compiled_content .= str_replace('<?', $tag_guard, $text_blocks[$i]);
+
+        // escape php tags created by interleaving
+        $compiled_content = str_replace('<?', "<?php echo '<?' ?>\n", $compiled_content);
+        $compiled_content = preg_replace("~(?<!')language\s*=\s*[\"\']?\s*php\s*[\"\']?~", "<?php echo 'language=php' ?>\n", $compiled_content);
+
+        // recover legit tags
+        $compiled_content = str_replace($tag_guard, '<?', $compiled_content); 
+        
+        // remove \n from the end of the file, if any
+        if (strlen($compiled_content) && (substr($compiled_content, -1) == "\n") ) {
+            $compiled_content = substr($compiled_content, 0, -1);
+        }
+
+        if (!empty($this->_cache_serial)) {
+            $compiled_content = "<?php \$this->_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content;
+        }
+
+        // run compiled template through postfilter functions
+        if (count($this->_plugins['postfilter']) > 0) {
+            foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
+                if ($postfilter === false) continue;
+                if ($postfilter[3] || is_callable($postfilter[0])) {
+                    $compiled_content = call_user_func_array($postfilter[0],
+                                                              array($compiled_content, &$this));
+                    $this->_plugins['postfilter'][$filter_name][3] = true;
+                } else {
+                    $this->_trigger_fatal_error("Smarty plugin error: postfilter '$filter_name' is not implemented");
+                }
+            }
+        }
+
+        // put header at the top of the compiled template
+        date_default_timezone_set('America/Los_Angeles');
+        $template_header = "<?php /* Smarty version ".$this->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";
+        $template_header .= "         compiled from ".strtr(urlencode($resource_name), array('%2F'=>'/', '%3A'=>':'))." */ ?>\n";
+
+        /* Emit code to load needed plugins. */
+        $this->_plugins_code = '';
+        if (count($this->_plugin_info)) {
+            $_plugins_params = "array('plugins' => array(";
+            foreach ($this->_plugin_info as $plugin_type => $plugins) {
+                foreach ($plugins as $plugin_name => $plugin_info) {
+                    $_plugins_params .= "array('$plugin_type', '$plugin_name', '" . strtr($plugin_info[0], array("'" => "\\'", "\\" => "\\\\")) . "', $plugin_info[1], ";
+                    $_plugins_params .= $plugin_info[2] ? 'true),' : 'false),';
+                }
+            }
+            $_plugins_params .= '))';
+            $plugins_code = "<?php require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');\nsmarty_core_load_plugins($_plugins_params, \$this); ?>\n";
+            $template_header .= $plugins_code;
+            $this->_plugin_info = array();
+            $this->_plugins_code = $plugins_code;
+        }
+
+        if ($this->_init_smarty_vars) {
+            $template_header .= "<?php require_once(SMARTY_CORE_DIR . 'core.assign_smarty_interface.php');\nsmarty_core_assign_smarty_interface(null, \$this); ?>\n";
+            $this->_init_smarty_vars = false;
+        }
+
+        $compiled_content = $template_header . $compiled_content;
+        return true;
+    }
+
+    /**
+     * Compile a template tag
+     *
+     * @param string $template_tag
+     * @return string
+     */
+    function _compile_tag($template_tag)
+    {
+        /* Matched comment. */
+        if (substr($template_tag, 0, 1) == '*' && substr($template_tag, -1) == '*')
+            return '';
+        
+        /* Split tag into two three parts: command, command modifiers and the arguments. */
+        if(! preg_match('~^(?:(' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp
+                . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*))
+                      (?:\s+(.*))?$
+                    ~xs', $template_tag, $match)) {
+            $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__);
+        }
+        
+        $tag_command = $match[1];
+        $tag_modifier = isset($match[2]) ? $match[2] : null;
+        $tag_args = isset($match[3]) ? $match[3] : null;
+
+        if (preg_match('~^' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$~', $tag_command)) {
+            /* tag name is a variable or object */
+            $_return = $this->_parse_var_props($tag_command . $tag_modifier);
+            return "<?php echo $_return; ?>" . $this->_additional_newline;
+        }
+
+        /* If the tag name is a registered object, we process it. */
+        if (preg_match('~^\/?' . $this->_reg_obj_regexp . '$~', $tag_command)) {
+            return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier);
+        }
+
+        switch ($tag_command) {
+            case 'include':
+                return $this->_compile_include_tag($tag_args);
+
+            case 'include_php':
+                return $this->_compile_include_php_tag($tag_args);
+
+            case 'if':
+                $this->_push_tag('if');
+                return $this->_compile_if_tag($tag_args);
+
+            case 'else':
+                list($_open_tag) = end($this->_tag_stack);
+                if ($_open_tag != 'if' && $_open_tag != 'elseif')
+                    $this->_syntax_error('unexpected {else}', E_USER_ERROR, __FILE__, __LINE__);
+                else
+                    $this->_push_tag('else');
+                return '<?php else: ?>';
+
+            case 'elseif':
+                list($_open_tag) = end($this->_tag_stack);
+                if ($_open_tag != 'if' && $_open_tag != 'elseif')
+                    $this->_syntax_error('unexpected {elseif}', E_USER_ERROR, __FILE__, __LINE__);
+                if ($_open_tag == 'if')
+                    $this->_push_tag('elseif');
+                return $this->_compile_if_tag($tag_args, true);
+
+            case '/if':
+                $this->_pop_tag('if');
+                return '<?php endif; ?>';
+
+            case 'capture':
+                return $this->_compile_capture_tag(true, $tag_args);
+
+            case '/capture':
+                return $this->_compile_capture_tag(false);
+
+            case 'ldelim':
+                return $this->left_delimiter;
+
+            case 'rdelim':
+                return $this->right_delimiter;
+
+            case 'section':
+                $this->_push_tag('section');
+                return $this->_compile_section_start($tag_args);
+
+            case 'sectionelse':
+                $this->_push_tag('sectionelse');
+                return "<?php endfor; else: ?>";
+                break;
+
+            case '/section':
+                $_open_tag = $this->_pop_tag('section');
+                if ($_open_tag == 'sectionelse')
+                    return "<?php endif; ?>";
+                else
+                    return "<?php endfor; endif; ?>";
+
+            case 'foreach':
+                $this->_push_tag('foreach');
+                return $this->_compile_foreach_start($tag_args);
+                break;
+
+            case 'foreachelse':
+                $this->_push_tag('foreachelse');
+                return "<?php endforeach; else: ?>";
+
+            case '/foreach':
+                $_open_tag = $this->_pop_tag('foreach');
+                if ($_open_tag == 'foreachelse')
+                    return "<?php endif; unset(\$_from); ?>";
+                else
+                    return "<?php endforeach; endif; unset(\$_from); ?>";
+                break;
+
+            case 'strip':
+            case '/strip':
+                if (substr($tag_command, 0, 1)=='/') {
+                    $this->_pop_tag('strip');
+                    if (--$this->_strip_depth==0) { /* outermost closing {/strip} */
+                        $this->_additional_newline = "\n";
+                        return '{' . $tag_command . '}';
+                    }
+                } else {
+                    $this->_push_tag('strip');
+                    if ($this->_strip_depth++==0) { /* outermost opening {strip} */
+                        $this->_additional_newline = "";
+                        return '{' . $tag_command . '}';
+                    }
+                }
+                return '';
+
+            case 'php':
+                /* handle folded tags replaced by {php} */
+                list(, $block) = each($this->_folded_blocks);
+                $this->_current_line_no += substr_count($block[0], "\n");
+                /* the number of matched elements in the regexp in _compile_file()
+                   determins the type of folded tag that was found */
+                switch (count($block)) {
+                    case 2: /* comment */
+                        return '';
+
+                    case 3: /* literal */
+                        return "<?php echo '" . strtr($block[2], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>" . $this->_additional_newline;
+
+                    case 4: /* php */
+                        if ($this->security && !$this->security_settings['PHP_TAGS']) {
+                            $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__);
+                            return;
+                        }
+                        return '<?php ' . $block[3] .' ?>';
+                }
+                break;
+
+            case 'insert':
+                return $this->_compile_insert_tag($tag_args);
+
+            default:
+                if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) {
+                    return $output;
+                } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) {
+                    return $output;
+                } else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) {
+                    return $output;                    
+                } else {
+                    $this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__);
+                }
+
+        }
+    }
+
+
+    /**
+     * compile the custom compiler tag
+     *
+     * sets $output to the compiled custom compiler tag
+     * @param string $tag_command
+     * @param string $tag_args
+     * @param string $output
+     * @return boolean
+     */
+    function _compile_compiler_tag($tag_command, $tag_args, &$output)
+    {
+        $found = false;
+        $have_function = true;
+
+        /*
+         * First we check if the compiler function has already been registered
+         * or loaded from a plugin file.
+         */
+        if (isset($this->_plugins['compiler'][$tag_command])) {
+            $found = true;
+            $plugin_func = $this->_plugins['compiler'][$tag_command][0];
+            if (!is_callable($plugin_func)) {
+                $message = "compiler function '$tag_command' is not implemented";
+                $have_function = false;
+            }
+        }
+        /*
+         * Otherwise we need to load plugin file and look for the function
+         * inside it.
+         */
+        else if ($plugin_file = $this->_get_plugin_filepath('compiler', $tag_command)) {
+            $found = true;
+
+            include_once $plugin_file;
+
+            $plugin_func = 'smarty_compiler_' . $tag_command;
+            if (!is_callable($plugin_func)) {
+                $message = "plugin function $plugin_func() not found in $plugin_file\n";
+                $have_function = false;
+            } else {
+                $this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null, null, true);
+            }
+        }
+
+        /*
+         * True return value means that we either found a plugin or a
+         * dynamically registered function. False means that we didn't and the
+         * compiler should now emit code to load custom function plugin for this
+         * tag.
+         */
+        if ($found) {
+            if ($have_function) {
+                $output = call_user_func_array($plugin_func, array($tag_args, &$this));
+                if($output != '') {
+                $output = '<?php ' . $this->_push_cacheable_state('compiler', $tag_command)
+                                   . $output
+                                   . $this->_pop_cacheable_state('compiler', $tag_command) . ' ?>';
+                }
+            } else {
+                $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+
+    /**
+     * compile block function tag
+     *
+     * sets $output to compiled block function tag
+     * @param string $tag_command
+     * @param string $tag_args
+     * @param string $tag_modifier
+     * @param string $output
+     * @return boolean
+     */
+    function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output)
+    {
+        if (substr($tag_command, 0, 1) == '/') {
+            $start_tag = false;
+            $tag_command = substr($tag_command, 1);
+        } else
+            $start_tag = true;
+
+        $found = false;
+        $have_function = true;
+
+        /*
+         * First we check if the block function has already been registered
+         * or loaded from a plugin file.
+         */
+        if (isset($this->_plugins['block'][$tag_command])) {
+            $found = true;
+            $plugin_func = $this->_plugins['block'][$tag_command][0];
+            if (!is_callable($plugin_func)) {
+                $message = "block function '$tag_command' is not implemented";
+                $have_function = false;
+            }
+        }
+        /*
+         * Otherwise we need to load plugin file and look for the function
+         * inside it.
+         */
+        else if ($plugin_file = $this->_get_plugin_filepath('block', $tag_command)) {
+            $found = true;
+
+            include_once $plugin_file;
+
+            $plugin_func = 'smarty_block_' . $tag_command;
+            if (!function_exists($plugin_func)) {
+                $message = "plugin function $plugin_func() not found in $plugin_file\n";
+                $have_function = false;
+            } else {
+                $this->_plugins['block'][$tag_command] = array($plugin_func, null, null, null, true);
+
+            }
+        }
+
+        if (!$found) {
+            return false;
+        } else if (!$have_function) {
+            $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
+            return true;
+        }
+
+        /*
+         * Even though we've located the plugin function, compilation
+         * happens only once, so the plugin will still need to be loaded
+         * at runtime for future requests.
+         */
+        $this->_add_plugin('block', $tag_command);
+
+        if ($start_tag)
+            $this->_push_tag($tag_command);
+        else
+            $this->_pop_tag($tag_command);
+
+        if ($start_tag) {
+            $output = '<?php ' . $this->_push_cacheable_state('block', $tag_command);
+            $attrs = $this->_parse_attrs($tag_args);
+            $_cache_attrs='';
+            $arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs);
+            $output .= "$_cache_attrs\$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); ';
+            $output .= '$_block_repeat=true;' . $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], null, $this, $_block_repeat);';
+            $output .= 'while ($_block_repeat) { ob_start(); ?>';
+        } else {
+            $output = '<?php $_block_content = ob_get_contents(); ob_end_clean(); ';
+            $_out_tag_text = $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $_block_content, $this, $_block_repeat)';
+            if ($tag_modifier != '') {
+                $this->_parse_modifiers($_out_tag_text, $tag_modifier);
+            }
+            $output .= '$_block_repeat=false;echo ' . $_out_tag_text . '; } ';
+            $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>';
+        }
+
+        return true;
+    }
+
+
+    /**
+     * compile custom function tag
+     *
+     * @param string $tag_command
+     * @param string $tag_args
+     * @param string $tag_modifier
+     * @return string
+     */
+    function _compile_custom_tag($tag_command, $tag_args, $tag_modifier, &$output)
+    {
+        $found = false;
+        $have_function = true;
+
+        /*
+         * First we check if the custom function has already been registered
+         * or loaded from a plugin file.
+         */
+        if (isset($this->_plugins['function'][$tag_command])) {
+            $found = true;
+            $plugin_func = $this->_plugins['function'][$tag_command][0];
+            if (!is_callable($plugin_func)) {
+                $message = "custom function '$tag_command' is not implemented";
+                $have_function = false;
+            }
+        }
+        /*
+         * Otherwise we need to load plugin file and look for the function
+         * inside it.
+         */
+        else if ($plugin_file = $this->_get_plugin_filepath('function', $tag_command)) {
+            $found = true;
+
+            include_once $plugin_file;
+
+            $plugin_func = 'smarty_function_' . $tag_command;
+            if (!function_exists($plugin_func)) {
+                $message = "plugin function $plugin_func() not found in $plugin_file\n";
+                $have_function = false;
+            } else {
+                $this->_plugins['function'][$tag_command] = array($plugin_func, null, null, null, true);
+
+            }
+        }
+
+        if (!$found) {
+            return false;
+        } else if (!$have_function) {
+            $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
+            return true;
+        }
+
+        /* declare plugin to be loaded on display of the template that
+           we compile right now */
+        $this->_add_plugin('function', $tag_command);
+
+        $_cacheable_state = $this->_push_cacheable_state('function', $tag_command);
+        $attrs = $this->_parse_attrs($tag_args);
+        $_cache_attrs = '';
+        $arg_list = $this->_compile_arg_list('function', $tag_command, $attrs, $_cache_attrs);
+
+        $output = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', $arg_list)."), \$this)";
+        if($tag_modifier != '') {
+            $this->_parse_modifiers($output, $tag_modifier);
+        }
+
+        if($output != '') {
+            $output =  '<?php ' . $_cacheable_state . $_cache_attrs . 'echo ' . $output . ';'
+                . $this->_pop_cacheable_state('function', $tag_command) . "?>" . $this->_additional_newline;
+        }
+
+        return true;
+    }
+
+    /**
+     * compile a registered object tag
+     *
+     * @param string $tag_command
+     * @param array $attrs
+     * @param string $tag_modifier
+     * @return string
+     */
+    function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier)
+    {
+        if (substr($tag_command, 0, 1) == '/') {
+            $start_tag = false;
+            $tag_command = substr($tag_command, 1);
+        } else {
+            $start_tag = true;
+        }
+
+        list($object, $obj_comp) = explode('->', $tag_command);
+
+        $arg_list = array();
+        if(count($attrs)) {
+            $_assign_var = false;
+            foreach ($attrs as $arg_name => $arg_value) {
+                if($arg_name == 'assign') {
+                    $_assign_var = $arg_value;
+                    unset($attrs['assign']);
+                    continue;
+                }
+                if (is_bool($arg_value))
+                    $arg_value = $arg_value ? 'true' : 'false';
+                $arg_list[] = "'$arg_name' => $arg_value";
+            }
+        }
+
+        if($this->_reg_objects[$object][2]) {
+            // smarty object argument format
+            $args = "array(".implode(',', (array)$arg_list)."), \$this";
+        } else {
+            // traditional argument format
+            $args = implode(',', array_values($attrs));
+            if (empty($args)) {
+                $args = 'null';
+            }
+        }
+
+        $prefix = '';
+        $postfix = '';
+        $newline = '';
+        if(!is_object($this->_reg_objects[$object][0])) {
+            $this->_trigger_fatal_error("registered '$object' is not an object" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
+        } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) {
+            $this->_trigger_fatal_error("'$obj_comp' is not a registered component of object '$object'", $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
+        } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) {
+            // method
+            if(in_array($obj_comp, $this->_reg_objects[$object][3])) {
+                // block method
+                if ($start_tag) {
+                    $prefix = "\$this->_tag_stack[] = array('$obj_comp', $args); ";
+                    $prefix .= "\$_block_repeat=true; \$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], null, \$this, \$_block_repeat); ";
+                    $prefix .= "while (\$_block_repeat) { ob_start();";
+                    $return = null;
+                    $postfix = '';
+                } else {
+                    $prefix = "\$_obj_block_content = ob_get_contents(); ob_end_clean(); \$_block_repeat=false;";
+                    $return = "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$_obj_block_content, \$this, \$_block_repeat)";
+                    $postfix = "} array_pop(\$this->_tag_stack);";
+                }
+            } else {
+                // non-block method
+                $return = "\$this->_reg_objects['$object'][0]->$obj_comp($args)";
+            }
+        } else {
+            // property
+            $return = "\$this->_reg_objects['$object'][0]->$obj_comp";
+        }
+
+        if($return != null) {
+            if($tag_modifier != '') {
+                $this->_parse_modifiers($return, $tag_modifier);
+            }
+
+            if(!empty($_assign_var)) {
+                $output = "\$this->assign('" . $this->_dequote($_assign_var) ."',  $return);";
+            } else {
+                $output = 'echo ' . $return . ';';
+                $newline = $this->_additional_newline;
+            }
+        } else {
+            $output = '';
+        }
+
+        return '<?php ' . $prefix . $output . $postfix . "?>" . $newline;
+    }
+
+    /**
+     * Compile {insert ...} tag
+     *
+     * @param string $tag_args
+     * @return string
+     */
+    function _compile_insert_tag($tag_args)
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+        $name = $this->_dequote($attrs['name']);
+
+        if (empty($name)) {
+            return $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__);
+        }
+        
+        if (!preg_match('~^\w+$~', $name)) {
+            return $this->_syntax_error("'insert: 'name' must be an insert function name", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        if (!empty($attrs['script'])) {
+            $delayed_loading = true;
+        } else {
+            $delayed_loading = false;
+        }
+
+        foreach ($attrs as $arg_name => $arg_value) {
+            if (is_bool($arg_value))
+                $arg_value = $arg_value ? 'true' : 'false';
+            $arg_list[] = "'$arg_name' => $arg_value";
+        }
+
+        $this->_add_plugin('insert', $name, $delayed_loading);
+
+        $_params = "array('args' => array(".implode(', ', (array)$arg_list)."))";
+
+        return "<?php require_once(SMARTY_CORE_DIR . 'core.run_insert_handler.php');\necho smarty_core_run_insert_handler($_params, \$this); ?>" . $this->_additional_newline;
+    }
+
+    /**
+     * Compile {include ...} tag
+     *
+     * @param string $tag_args
+     * @return string
+     */
+    function _compile_include_tag($tag_args)
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+        $arg_list = array();
+
+        if (empty($attrs['file'])) {
+            $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        foreach ($attrs as $arg_name => $arg_value) {
+            if ($arg_name == 'file') {
+                $include_file = $arg_value;
+                continue;
+            } else if ($arg_name == 'assign') {
+                $assign_var = $arg_value;
+                continue;
+            }
+            if (is_bool($arg_value))
+                $arg_value = $arg_value ? 'true' : 'false';
+            $arg_list[] = "'$arg_name' => $arg_value";
+        }
+
+        $output = '<?php ';
+
+        if (isset($assign_var)) {
+            $output .= "ob_start();\n";
+        }
+
+        $output .=
+            "\$_smarty_tpl_vars = \$this->_tpl_vars;\n";
+
+
+        $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))";
+        $output .= "\$this->_smarty_include($_params);\n" .
+        "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" .
+        "unset(\$_smarty_tpl_vars);\n";
+
+        if (isset($assign_var)) {
+            $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();\n";
+        }
+
+        $output .= ' ?>';
+
+        return $output;
+
+    }
+
+    /**
+     * Compile {include ...} tag
+     *
+     * @param string $tag_args
+     * @return string
+     */
+    function _compile_include_php_tag($tag_args)
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+
+        if (empty($attrs['file'])) {
+            $this->_syntax_error("missing 'file' attribute in include_php tag", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        $assign_var = (empty($attrs['assign'])) ? '' : $this->_dequote($attrs['assign']);
+        $once_var = (empty($attrs['once']) || $attrs['once']=='false') ? 'false' : 'true';
+
+        $arg_list = array();
+        foreach($attrs as $arg_name => $arg_value) {
+            if($arg_name != 'file' AND $arg_name != 'once' AND $arg_name != 'assign') {
+                if(is_bool($arg_value))
+                    $arg_value = $arg_value ? 'true' : 'false';
+                $arg_list[] = "'$arg_name' => $arg_value";
+            }
+        }
+
+        $_params = "array('smarty_file' => " . $attrs['file'] . ", 'smarty_assign' => '$assign_var', 'smarty_once' => $once_var, 'smarty_include_vars' => array(".implode(',', $arg_list)."))";
+
+        return "<?php require_once(SMARTY_CORE_DIR . 'core.smarty_include_php.php');\nsmarty_core_smarty_include_php($_params, \$this); ?>" . $this->_additional_newline;
+    }
+
+
+    /**
+     * Compile {section ...} tag
+     *
+     * @param string $tag_args
+     * @return string
+     */
+    function _compile_section_start($tag_args)
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+        $arg_list = array();
+
+        $output = '<?php ';
+        $section_name = $attrs['name'];
+        if (empty($section_name)) {
+            $this->_syntax_error("missing section name", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        $output .= "unset(\$this->_sections[$section_name]);\n";
+        $section_props = "\$this->_sections[$section_name]";
+
+        foreach ($attrs as $attr_name => $attr_value) {
+            switch ($attr_name) {
+                case 'loop':
+                    $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int)\$_loop); unset(\$_loop);\n";
+                    break;
+
+                case 'show':
+                    if (is_bool($attr_value))
+                        $show_attr_value = $attr_value ? 'true' : 'false';
+                    else
+                        $show_attr_value = "(bool)$attr_value";
+                    $output .= "{$section_props}['show'] = $show_attr_value;\n";
+                    break;
+
+                case 'name':
+                    $output .= "{$section_props}['$attr_name'] = $attr_value;\n";
+                    break;
+
+                case 'max':
+                case 'start':
+                    $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n";
+                    break;
+
+                case 'step':
+                    $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n";
+                    break;
+
+                default:
+                    $this->_syntax_error("unknown section attribute - '$attr_name'", E_USER_ERROR, __FILE__, __LINE__);
+                    break;
+            }
+        }
+
+        if (!isset($attrs['show']))
+            $output .= "{$section_props}['show'] = true;\n";
+
+        if (!isset($attrs['loop']))
+            $output .= "{$section_props}['loop'] = 1;\n";
+
+        if (!isset($attrs['max']))
+            $output .= "{$section_props}['max'] = {$section_props}['loop'];\n";
+        else
+            $output .= "if ({$section_props}['max'] < 0)\n" .
+                       "    {$section_props}['max'] = {$section_props}['loop'];\n";
+
+        if (!isset($attrs['step']))
+            $output .= "{$section_props}['step'] = 1;\n";
+
+        if (!isset($attrs['start']))
+            $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n";
+        else {
+            $output .= "if ({$section_props}['start'] < 0)\n" .
+                       "    {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" .
+                       "else\n" .
+                       "    {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n";
+        }
+
+        $output .= "if ({$section_props}['show']) {\n";
+        if (!isset($attrs['start']) && !isset($attrs['step']) && !isset($attrs['max'])) {
+            $output .= "    {$section_props}['total'] = {$section_props}['loop'];\n";
+        } else {
+            $output .= "    {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n";
+        }
+        $output .= "    if ({$section_props}['total'] == 0)\n" .
+                   "        {$section_props}['show'] = false;\n" .
+                   "} else\n" .
+                   "    {$section_props}['total'] = 0;\n";
+
+        $output .= "if ({$section_props}['show']):\n";
+        $output .= "
+            for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1;
+                 {$section_props}['iteration'] <= {$section_props}['total'];
+                 {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n";
+        $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n";
+        $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n";
+        $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n";
+        $output .= "{$section_props}['first']      = ({$section_props}['iteration'] == 1);\n";
+        $output .= "{$section_props}['last']       = ({$section_props}['iteration'] == {$section_props}['total']);\n";
+
+        $output .= "?>";
+
+        return $output;
+    }
+
+
+    /**
+     * Compile {foreach ...} tag.
+     *
+     * @param string $tag_args
+     * @return string
+     */
+    function _compile_foreach_start($tag_args)
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+        $arg_list = array();
+
+        if (empty($attrs['from'])) {
+            return $this->_syntax_error("foreach: missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__);
+        }
+        $from = $attrs['from'];
+
+        if (empty($attrs['item'])) {
+            return $this->_syntax_error("foreach: missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__);
+        }
+        $item = $this->_dequote($attrs['item']);
+        if (!preg_match('~^\w+$~', $item)) {
+            return $this->_syntax_error("'foreach: 'item' must be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        if (isset($attrs['key'])) {
+            $key  = $this->_dequote($attrs['key']);
+            if (!preg_match('~^\w+$~', $key)) {
+                return $this->_syntax_error("foreach: 'key' must to be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__);
+            }
+            $key_part = "\$this->_tpl_vars['$key'] => ";
+        } else {
+            $key = null;
+            $key_part = '';
+        }
+
+        if (isset($attrs['name'])) {
+            $name = $attrs['name'];
+        } else {
+            $name = null;
+        }
+
+        $output = '<?php ';
+        $output .= "\$_from = $from; if (!is_array(\$_from) && !is_object(\$_from)) { settype(\$_from, 'array'); }";
+        if (isset($name)) {
+            $foreach_props = "\$this->_foreach[$name]";
+            $output .= "{$foreach_props} = array('total' => count(\$_from), 'iteration' => 0);\n";
+            $output .= "if ({$foreach_props}['total'] > 0):\n";
+            $output .= "    foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
+            $output .= "        {$foreach_props}['iteration']++;\n";
+        } else {
+            $output .= "if (count(\$_from)):\n";
+            $output .= "    foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
+        }
+        $output .= '?>';
+
+        return $output;
+    }
+
+
+    /**
+     * Compile {capture} .. {/capture} tags
+     *
+     * @param boolean $start true if this is the {capture} tag
+     * @param string $tag_args
+     * @return string
+     */
+
+    function _compile_capture_tag($start, $tag_args = '')
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+
+        if ($start) {
+            if (isset($attrs['name']))
+                $buffer = $attrs['name'];
+            else
+                $buffer = "'default'";
+
+            if (isset($attrs['assign']))
+                $assign = $attrs['assign'];
+            else
+                $assign = null;
+            $output = "<?php ob_start(); ?>";
+            $this->_capture_stack[] = array($buffer, $assign);
+        } else {
+            list($buffer, $assign) = array_pop($this->_capture_stack);
+            $output = "<?php \$this->_smarty_vars['capture'][$buffer] = ob_get_contents(); ";
+            if (isset($assign)) {
+                $output .= " \$this->assign($assign, ob_get_contents());";
+            }
+            $output .= "ob_end_clean(); ?>";
+        }
+
+        return $output;
+    }
+
+    /**
+     * Compile {if ...} tag
+     *
+     * @param string $tag_args
+     * @param boolean $elseif if true, uses elseif instead of if
+     * @return string
+     */
+    function _compile_if_tag($tag_args, $elseif = false)
+    {
+
+        /* Tokenize args for 'if' tag. */
+        preg_match_all('~(?>
+                ' . $this->_obj_call_regexp . '(?:' . $this->_mod_regexp . '*)? | # valid object call
+                ' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)?    | # var or quoted string
+                \-?0[xX][0-9a-fA-F]+|\-?\d+(?:\.\d+)?|\.\d+|!==|===|==|!=|<>|<<|>>|<=|>=|\&\&|\|\||\(|\)|,|\!|\^|=|\&|\~|<|>|\||\%|\+|\-|\/|\*|\@    | # valid non-word token
+                \b\w+\b                                                        | # valid word token
+                \S+                                                           # anything else
+                )~x', $tag_args, $match);
+
+        $tokens = $match[0];
+
+        if(empty($tokens)) {
+            $_error_msg = $elseif ? "'elseif'" : "'if'";
+            $_error_msg .= ' statement requires arguments'; 
+            $this->_syntax_error($_error_msg, E_USER_ERROR, __FILE__, __LINE__);
+        }
+            
+                
+        // make sure we have balanced parenthesis
+        $token_count = array_count_values($tokens);
+        if(isset($token_count['(']) && $token_count['('] != $token_count[')']) {
+            $this->_syntax_error("unbalanced parenthesis in if statement", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        $is_arg_stack = array();
+
+        for ($i = 0; $i < count($tokens); $i++) {
+
+            $token = &$tokens[$i];
+
+            switch (strtolower($token)) {
+                case '!':
+                case '%':
+                case '!==':
+                case '==':
+                case '===':
+                case '>':
+                case '<':
+                case '!=':
+                case '<>':
+                case '<<':
+                case '>>':
+                case '<=':
+                case '>=':
+                case '&&':
+                case '||':
+                case '|':
+                case '^':
+                case '&':
+                case '~':
+                case ')':
+                case ',':
+                case '+':
+                case '-':
+                case '*':
+                case '/':
+                case '@':
+                    break;
+
+                case 'eq':
+                    $token = '==';
+                    break;
+
+                case 'ne':
+                case 'neq':
+                    $token = '!=';
+                    break;
+
+                case 'lt':
+                    $token = '<';
+                    break;
+
+                case 'le':
+                case 'lte':
+                    $token = '<=';
+                    break;
+
+                case 'gt':
+                    $token = '>';
+                    break;
+
+                case 'ge':
+                case 'gte':
+                    $token = '>=';
+                    break;
+
+                case 'and':
+                    $token = '&&';
+                    break;
+
+                case 'or':
+                    $token = '||';
+                    break;
+
+                case 'not':
+                    $token = '!';
+                    break;
+
+                case 'mod':
+                    $token = '%';
+                    break;
+
+                case '(':
+                    array_push($is_arg_stack, $i);
+                    break;
+
+                case 'is':
+                    /* If last token was a ')', we operate on the parenthesized
+                       expression. The start of the expression is on the stack.
+                       Otherwise, we operate on the last encountered token. */
+                    if ($tokens[$i-1] == ')')
+                        $is_arg_start = array_pop($is_arg_stack);
+                    else
+                        $is_arg_start = $i-1;
+                    /* Construct the argument for 'is' expression, so it knows
+                       what to operate on. */
+                    $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start));
+
+                    /* Pass all tokens from next one until the end to the
+                       'is' expression parsing function. The function will
+                       return modified tokens, where the first one is the result
+                       of the 'is' expression and the rest are the tokens it
+                       didn't touch. */
+                    $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1));
+
+                    /* Replace the old tokens with the new ones. */
+                    array_splice($tokens, $is_arg_start, count($tokens), $new_tokens);
+
+                    /* Adjust argument start so that it won't change from the
+                       current position for the next iteration. */
+                    $i = $is_arg_start;
+                    break;
+
+                default:
+                    if(preg_match('~^' . $this->_func_regexp . '$~', $token) ) {
+                            // function call
+                            if($this->security &&
+                               !in_array($token, $this->security_settings['IF_FUNCS'])) {
+                                $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);
+                            }
+                    } elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && (strpos('+-*/^%&|', substr($token, -1)) === false) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') {
+                        // variable function call
+                        $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);                      
+                    } elseif(preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$~', $token)) {
+                        // object or variable
+                        $token = $this->_parse_var_props($token);
+                    } elseif(is_numeric($token)) {
+                        // number, skip it
+                    } else {
+                        $this->_syntax_error("unidentified token '$token'", E_USER_ERROR, __FILE__, __LINE__);
+                    }
+                    break;
+            }
+        }
+
+        if ($elseif)
+            return '<?php elseif ('.implode(' ', $tokens).'): ?>';
+        else
+            return '<?php if ('.implode(' ', $tokens).'): ?>';
+    }
+
+
+    function _compile_arg_list($type, $name, $attrs, &$cache_code) {
+        $arg_list = array();
+
+        if (isset($type) && isset($name)
+            && isset($this->_plugins[$type])
+            && isset($this->_plugins[$type][$name])
+            && empty($this->_plugins[$type][$name][4])
+            && is_array($this->_plugins[$type][$name][5])
+            ) {
+            /* we have a list of parameters that should be cached */
+            $_cache_attrs = $this->_plugins[$type][$name][5];
+            $_count = $this->_cache_attrs_count++;
+            $cache_code = "\$_cache_attrs =& \$this->_smarty_cache_attrs('$this->_cache_serial','$_count');";
+
+        } else {
+            /* no parameters are cached */
+            $_cache_attrs = null;
+        }
+
+        foreach ($attrs as $arg_name => $arg_value) {
+            if (is_bool($arg_value))
+                $arg_value = $arg_value ? 'true' : 'false';
+            if (is_null($arg_value))
+                $arg_value = 'null';
+            if ($_cache_attrs && in_array($arg_name, $_cache_attrs)) {
+                $arg_list[] = "'$arg_name' => (\$this->_cache_including) ? \$_cache_attrs['$arg_name'] : (\$_cache_attrs['$arg_name']=$arg_value)";
+            } else {
+                $arg_list[] = "'$arg_name' => $arg_value";
+            }
+        }
+        return $arg_list;
+    }
+
+    /**
+     * Parse is expression
+     *
+     * @param string $is_arg
+     * @param array $tokens
+     * @return array
+     */
+    function _parse_is_expr($is_arg, $tokens)
+    {
+        $expr_end = 0;
+        $negate_expr = false;
+
+        if (($first_token = array_shift($tokens)) == 'not') {
+            $negate_expr = true;
+            $expr_type = array_shift($tokens);
+        } else
+            $expr_type = $first_token;
+
+        switch ($expr_type) {
+            case 'even':
+                if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
+                    $expr_end++;
+                    $expr_arg = $tokens[$expr_end++];
+                    $expr = "!(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
+                } else
+                    $expr = "!(1 & $is_arg)";
+                break;
+
+            case 'odd':
+                if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
+                    $expr_end++;
+                    $expr_arg = $tokens[$expr_end++];
+                    $expr = "(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
+                } else
+                    $expr = "(1 & $is_arg)";
+                break;
+
+            case 'div':
+                if (@$tokens[$expr_end] == 'by') {
+                    $expr_end++;
+                    $expr_arg = $tokens[$expr_end++];
+                    $expr = "!($is_arg % " . $this->_parse_var_props($expr_arg) . ")";
+                } else {
+                    $this->_syntax_error("expecting 'by' after 'div'", E_USER_ERROR, __FILE__, __LINE__);
+                }
+                break;
+
+            default:
+                $this->_syntax_error("unknown 'is' expression - '$expr_type'", E_USER_ERROR, __FILE__, __LINE__);
+                break;
+        }
+
+        if ($negate_expr) {
+            $expr = "!($expr)";
+        }
+
+        array_splice($tokens, 0, $expr_end, $expr);
+
+        return $tokens;
+    }
+
+
+    /**
+     * Parse attribute string
+     *
+     * @param string $tag_args
+     * @return array
+     */
+    function _parse_attrs($tag_args)
+    {
+
+        /* Tokenize tag attributes. */
+        preg_match_all('~(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+)
+                         )+ |
+                         [=]
+                        ~x', $tag_args, $match);
+        $tokens       = $match[0];
+
+        $attrs = array();
+        /* Parse state:
+            0 - expecting attribute name
+            1 - expecting '='
+            2 - expecting attribute value (not '=') */
+        $state = 0;
+
+        foreach ($tokens as $token) {
+            switch ($state) {
+                case 0:
+                    /* If the token is a valid identifier, we set attribute name
+                       and go to state 1. */
+                    if (preg_match('~^\w+$~', $token)) {
+                        $attr_name = $token;
+                        $state = 1;
+                    } else
+                        $this->_syntax_error("invalid attribute name: '$token'", E_USER_ERROR, __FILE__, __LINE__);
+                    break;
+
+                case 1:
+                    /* If the token is '=', then we go to state 2. */
+                    if ($token == '=') {
+                        $state = 2;
+                    } else
+                        $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
+                    break;
+
+                case 2:
+                    /* If token is not '=', we set the attribute value and go to
+                       state 0. */
+                    if ($token != '=') {
+                        /* We booleanize the token if it's a non-quoted possible
+                           boolean value. */
+                        if (preg_match('~^(on|yes|true)$~', $token)) {
+                            $token = 'true';
+                        } else if (preg_match('~^(off|no|false)$~', $token)) {
+                            $token = 'false';
+                        } else if ($token == 'null') {
+                            $token = 'null';
+                        } else if (preg_match('~^' . $this->_num_const_regexp . '|0[xX][0-9a-fA-F]+$~', $token)) {
+                            /* treat integer literally */
+                        } else if (!preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$~', $token)) {
+                            /* treat as a string, double-quote it escaping quotes */
+                            $token = '"'.addslashes($token).'"';
+                        }
+
+                        $attrs[$attr_name] = $token;
+                        $state = 0;
+                    } else
+                        $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__);
+                    break;
+            }
+            $last_token = $token;
+        }
+
+        if($state != 0) {
+            if($state == 1) {
+                $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
+            } else {
+                $this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__);
+            }
+        }
+
+        $this->_parse_vars_props($attrs);
+
+        return $attrs;
+    }
+
+    /**
+     * compile multiple variables and section properties tokens into
+     * PHP code
+     *
+     * @param array $tokens
+     */
+    function _parse_vars_props(&$tokens)
+    {
+        foreach($tokens as $key => $val) {
+            $tokens[$key] = $this->_parse_var_props($val);
+        }
+    }
+
+    /**
+     * compile single variable and section properties token into
+     * PHP code
+     *
+     * @param string $val
+     * @param string $tag_attrs
+     * @return string
+     */
+    function _parse_var_props($val)
+    {
+        $val = trim($val);
+
+        if(preg_match('~^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(' . $this->_mod_regexp . '*)$~', $val, $match)) {
+            // $ variable or object
+            $return = $this->_parse_var($match[1]);
+            $modifiers = $match[2];
+            if (!empty($this->default_modifiers) && !preg_match('~(^|\|)smarty:nodefaults($|\|)~',$modifiers)) {
+                $_default_mod_string = implode('|',(array)$this->default_modifiers);
+                $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . '|' . $modifiers;
+            }
+            $this->_parse_modifiers($return, $modifiers);
+            return $return;
+        } elseif (preg_match('~^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+                // double quoted text
+                preg_match('~^(' . $this->_db_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
+                $return = $this->_expand_quoted_text($match[1]);
+                if($match[2] != '') {
+                    $this->_parse_modifiers($return, $match[2]);
+                }
+                return $return;
+            }
+        elseif(preg_match('~^' . $this->_num_const_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+                // numerical constant
+                preg_match('~^(' . $this->_num_const_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
+                if($match[2] != '') {
+                    $this->_parse_modifiers($match[1], $match[2]);
+                    return $match[1];
+                }
+            }
+        elseif(preg_match('~^' . $this->_si_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+                // single quoted text
+                preg_match('~^(' . $this->_si_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
+                if($match[2] != '') {
+                    $this->_parse_modifiers($match[1], $match[2]);
+                    return $match[1];
+                }
+            }
+        elseif(preg_match('~^' . $this->_cvar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+                // config var
+                return $this->_parse_conf_var($val);
+            }
+        elseif(preg_match('~^' . $this->_svar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+                // section var
+                return $this->_parse_section_prop($val);
+            }
+        elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) {
+            // literal string
+            return $this->_expand_quoted_text('"' . strtr($val, array('\\' => '\\\\', '"' => '\\"')) .'"');
+        }
+        return $val;
+    }
+
+    /**
+     * expand quoted text with embedded variables
+     *
+     * @param string $var_expr
+     * @return string
+     */
+    function _expand_quoted_text($var_expr)
+    {
+        // if contains unescaped $, expand it
+        if(preg_match_all('~(?:\`(?<!\\\\)\$' . $this->_dvar_guts_regexp . '(?:' . $this->_obj_ext_regexp . ')*\`)|(?:(?<!\\\\)\$\w+(\[[a-zA-Z0-9]+\])*)~', $var_expr, $_match)) {
+            $_match = $_match[0];
+            $_replace = array();
+            foreach($_match as $_var) {
+                $_replace[$_var] = '".(' . $this->_parse_var(str_replace('`','',$_var)) . ')."';
+            }
+            $var_expr = strtr($var_expr, $_replace);
+            $_return = preg_replace('~\.""|(?<!\\\\)""\.~', '', $var_expr);
+        } else {
+            $_return = $var_expr;
+        }
+        // replace double quoted literal string with single quotes
+        $_return = preg_replace('~^"([\s\w]+)"$~',"'\\1'",$_return);
+        return $_return;
+    }
+
+    /**
+     * parse variable expression into PHP code
+     *
+     * @param string $var_expr
+     * @param string $output
+     * @return string
+     */
+    function _parse_var($var_expr)
+    {
+        $_has_math = false;
+        $_math_vars = preg_split('~('.$this->_dvar_math_regexp.'|'.$this->_qstr_regexp.')~', $var_expr, -1, PREG_SPLIT_DELIM_CAPTURE);
+
+        if(count($_math_vars) > 1) {
+            $_first_var = "";
+            $_complete_var = "";
+            $_output = "";
+            // simple check if there is any math, to stop recursion (due to modifiers with "xx % yy" as parameter)
+            foreach($_math_vars as $_k => $_math_var) {
+                $_math_var = $_math_vars[$_k];
+
+                if(!empty($_math_var) || is_numeric($_math_var)) {
+                    // hit a math operator, so process the stuff which came before it
+                    if(preg_match('~^' . $this->_dvar_math_regexp . '$~', $_math_var)) {
+                        $_has_math = true;
+                        if(!empty($_complete_var) || is_numeric($_complete_var)) {
+                            $_output .= $this->_parse_var($_complete_var);
+                        }
+
+                        // just output the math operator to php
+                        $_output .= $_math_var;
+
+                        if(empty($_first_var))
+                            $_first_var = $_complete_var;
+
+                        $_complete_var = "";
+                    } else {
+                        $_complete_var .= $_math_var;
+                    }
+                }
+            }
+            if($_has_math) {
+                if(!empty($_complete_var) || is_numeric($_complete_var))
+                    $_output .= $this->_parse_var($_complete_var);
+
+                // get the modifiers working (only the last var from math + modifier is left)
+                $var_expr = $_complete_var;
+            }
+        }
+
+        // prevent cutting of first digit in the number (we _definitly_ got a number if the first char is a digit)
+        if(is_numeric(substr($var_expr, 0, 1)))
+            $_var_ref = $var_expr;
+        else
+            $_var_ref = substr($var_expr, 1);
+        
+        if(!$_has_math) {
+            
+            // get [foo] and .foo and ->foo and (...) pieces
+            preg_match_all('~(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+~', $_var_ref, $match);
+                        
+            $_indexes = $match[0];
+            $_var_name = array_shift($_indexes);
+
+            /* Handle $smarty.* variable references as a special case. */
+            if ($_var_name == 'smarty') {
+                /*
+                 * If the reference could be compiled, use the compiled output;
+                 * otherwise, fall back on the $smarty variable generated at
+                 * run-time.
+                 */
+                if (($smarty_ref = $this->_compile_smarty_ref($_indexes)) !== null) {
+                    $_output = $smarty_ref;
+                } else {
+                    $_var_name = substr(array_shift($_indexes), 1);
+                    $_output = "\$this->_smarty_vars['$_var_name']";
+                }
+            } elseif(is_numeric($_var_name) && is_numeric(substr($var_expr, 0, 1))) {
+                // because . is the operator for accessing arrays thru inidizes we need to put it together again for floating point numbers
+                if(count($_indexes) > 0)
+                {
+                    $_var_name .= implode("", $_indexes);
+                    $_indexes = array();
+                }
+                $_output = $_var_name;
+            } else {
+                $_output = "\$this->_tpl_vars['$_var_name']";
+            }
+
+            foreach ($_indexes as $_index) {
+                if (substr($_index, 0, 1) == '[') {
+                    $_index = substr($_index, 1, -1);
+                    if (is_numeric($_index)) {
+                        $_output .= "[$_index]";
+                    } elseif (substr($_index, 0, 1) == '$') {
+                        if (strpos($_index, '.') !== false) {
+                            $_output .= '[' . $this->_parse_var($_index) . ']';
+                        } else {
+                            $_output .= "[\$this->_tpl_vars['" . substr($_index, 1) . "']]";
+                        }
+                    } else {
+                        $_var_parts = explode('.', $_index);
+                        $_var_section = $_var_parts[0];
+                        $_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index';
+                        $_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]";
+                    }
+                } else if (substr($_index, 0, 1) == '.') {
+                    if (substr($_index, 1, 1) == '$')
+                        $_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]";
+                    else
+                        $_output .= "['" . substr($_index, 1) . "']";
+                } else if (substr($_index,0,2) == '->') {
+                    if(substr($_index,2,2) == '__') {
+                        $this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__);
+                    } elseif($this->security && substr($_index, 2, 1) == '_') {
+                        $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
+                    } elseif (substr($_index, 2, 1) == '$') {
+                        if ($this->security) {
+                            $this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
+                        } else {
+                            $_output .= '->{(($_var=$this->_tpl_vars[\''.substr($_index,3).'\']) && substr($_var,0,2)!=\'__\') ? $_var : $this->trigger_error("cannot access property \\"$_var\\"")}';
+                        }
+                    } else {
+                        $_output .= $_index;
+                    }
+                } elseif (substr($_index, 0, 1) == '(') {
+                    $_index = $this->_parse_parenth_args($_index);
+                    $_output .= $_index;
+                } else {
+                    $_output .= $_index;
+                }
+            }
+        }
+
+        return $_output;
+    }
+
+    /**
+     * parse arguments in function call parenthesis
+     *
+     * @param string $parenth_args
+     * @return string
+     */
+    function _parse_parenth_args($parenth_args)
+    {
+        preg_match_all('~' . $this->_param_regexp . '~',$parenth_args, $match);
+        $orig_vals = $match = $match[0];
+        $this->_parse_vars_props($match);
+        $replace = array();
+        for ($i = 0, $count = count($match); $i < $count; $i++) {
+            $replace[$orig_vals[$i]] = $match[$i];
+        }
+        return strtr($parenth_args, $replace);
+    }
+
+    /**
+     * parse configuration variable expression into PHP code
+     *
+     * @param string $conf_var_expr
+     */
+    function _parse_conf_var($conf_var_expr)
+    {
+        $parts = explode('|', $conf_var_expr, 2);
+        $var_ref = $parts[0];
+        $modifiers = isset($parts[1]) ? $parts[1] : '';
+
+        $var_name = substr($var_ref, 1, -1);
+
+        $output = "\$this->_config[0]['vars']['$var_name']";
+
+        $this->_parse_modifiers($output, $modifiers);
+
+        return $output;
+    }
+
+    /**
+     * parse section property expression into PHP code
+     *
+     * @param string $section_prop_expr
+     * @return string
+     */
+    function _parse_section_prop($section_prop_expr)
+    {
+        $parts = explode('|', $section_prop_expr, 2);
+        $var_ref = $parts[0];
+        $modifiers = isset($parts[1]) ? $parts[1] : '';
+
+        preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match);
+        $section_name = $match[1];
+        $prop_name = $match[2];
+
+        $output = "\$this->_sections['$section_name']['$prop_name']";
+
+        $this->_parse_modifiers($output, $modifiers);
+
+        return $output;
+    }
+
+
+    /**
+     * parse modifier chain into PHP code
+     *
+     * sets $output to parsed modified chain
+     * @param string $output
+     * @param string $modifier_string
+     */
+    function _parse_modifiers(&$output, $modifier_string)
+    {
+        preg_match_all('~\|(@?\w+)((?>:(?:'. $this->_qstr_regexp . '|[^|]+))*)~', '|' . $modifier_string, $_match);
+        list(, $_modifiers, $modifier_arg_strings) = $_match;
+
+        for ($_i = 0, $_for_max = count($_modifiers); $_i < $_for_max; $_i++) {
+            $_modifier_name = $_modifiers[$_i];
+
+            if($_modifier_name == 'smarty') {
+                // skip smarty modifier
+                continue;
+            }
+
+            preg_match_all('~:(' . $this->_qstr_regexp . '|[^:]+)~', $modifier_arg_strings[$_i], $_match);
+            $_modifier_args = $_match[1];
+
+            if (substr($_modifier_name, 0, 1) == '@') {
+                $_map_array = false;
+                $_modifier_name = substr($_modifier_name, 1);
+            } else {
+                $_map_array = true;
+            }
+
+            if (empty($this->_plugins['modifier'][$_modifier_name])
+                && !$this->_get_plugin_filepath('modifier', $_modifier_name)
+                && function_exists($_modifier_name)) {
+                if ($this->security && !in_array($_modifier_name, $this->security_settings['MODIFIER_FUNCS'])) {
+                    $this->_trigger_fatal_error("[plugin] (secure mode) modifier '$_modifier_name' is not allowed" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
+                } else {
+                    $this->_plugins['modifier'][$_modifier_name] = array($_modifier_name,  null, null, false);
+                }
+            }
+            $this->_add_plugin('modifier', $_modifier_name);
+
+            $this->_parse_vars_props($_modifier_args);
+
+            if($_modifier_name == 'default') {
+                // supress notifications of default modifier vars and args
+                if(substr($output, 0, 1) == '$') {
+                    $output = '@' . $output;
+                }
+                if(isset($_modifier_args[0]) && substr($_modifier_args[0], 0, 1) == '$') {
+                    $_modifier_args[0] = '@' . $_modifier_args[0];
+                }
+            }
+            if (count($_modifier_args) > 0)
+                $_modifier_args = ', '.implode(', ', $_modifier_args);
+            else
+                $_modifier_args = '';
+
+            if ($_map_array) {
+                $output = "((is_array(\$_tmp=$output)) ? \$this->_run_mod_handler('$_modifier_name', true, \$_tmp$_modifier_args) : " . $this->_compile_plugin_call('modifier', $_modifier_name) . "(\$_tmp$_modifier_args))";
+
+            } else {
+
+                $output = $this->_compile_plugin_call('modifier', $_modifier_name)."($output$_modifier_args)";
+
+            }
+        }
+    }
+
+
+    /**
+     * add plugin
+     *
+     * @param string $type
+     * @param string $name
+     * @param boolean? $delayed_loading
+     */
+    function _add_plugin($type, $name, $delayed_loading = null)
+    {
+        if (!isset($this->_plugin_info[$type])) {
+            $this->_plugin_info[$type] = array();
+        }
+        if (!isset($this->_plugin_info[$type][$name])) {
+            $this->_plugin_info[$type][$name] = array($this->_current_file,
+                                                      $this->_current_line_no,
+                                                      $delayed_loading);
+        }
+    }
+
+
+    /**
+     * Compiles references of type $smarty.foo
+     *
+     * @param string $indexes
+     * @return string
+     */
+    function _compile_smarty_ref(&$indexes)
+    {
+        /* Extract the reference name. */
+        $_ref = substr($indexes[0], 1);
+        foreach($indexes as $_index_no=>$_index) {
+            if (substr($_index, 0, 1) != '.' && $_index_no<2 || !preg_match('~^(\.|\[|->)~', $_index)) {
+                $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
+            }
+        }
+
+        switch ($_ref) {
+            case 'now':
+                $compiled_ref = 'time()';
+                $_max_index = 1;
+                break;
+
+            case 'foreach':
+                array_shift($indexes);
+                $_var = $this->_parse_var_props(substr($indexes[0], 1));
+                $_propname = substr($indexes[1], 1);
+                $_max_index = 1;
+                switch ($_propname) {
+                    case 'index':
+                        array_shift($indexes);
+                        $compiled_ref = "(\$this->_foreach[$_var]['iteration']-1)";
+                        break;
+                        
+                    case 'first':
+                        array_shift($indexes);
+                        $compiled_ref = "(\$this->_foreach[$_var]['iteration'] <= 1)";
+                        break;
+
+                    case 'last':
+                        array_shift($indexes);
+                        $compiled_ref = "(\$this->_foreach[$_var]['iteration'] == \$this->_foreach[$_var]['total'])";
+                        break;
+                        
+                    case 'show':
+                        array_shift($indexes);
+                        $compiled_ref = "(\$this->_foreach[$_var]['total'] > 0)";
+                        break;
+                        
+                    default:
+                        unset($_max_index);
+                        $compiled_ref = "\$this->_foreach[$_var]";
+                }
+                break;
+
+            case 'section':
+                array_shift($indexes);
+                $_var = $this->_parse_var_props(substr($indexes[0], 1));
+                $compiled_ref = "\$this->_sections[$_var]";
+                break;
+
+            case 'get':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_GET' : "\$GLOBALS['HTTP_GET_VARS']";
+                break;
+
+            case 'post':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_POST' : "\$GLOBALS['HTTP_POST_VARS']";
+                break;
+
+            case 'cookies':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_COOKIE' : "\$GLOBALS['HTTP_COOKIE_VARS']";
+                break;
+
+            case 'env':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_ENV' : "\$GLOBALS['HTTP_ENV_VARS']";
+                break;
+
+            case 'server':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_SERVER' : "\$GLOBALS['HTTP_SERVER_VARS']";
+                break;
+
+            case 'session':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_SESSION' : "\$GLOBALS['HTTP_SESSION_VARS']";
+                break;
+
+            /*
+             * These cases are handled either at run-time or elsewhere in the
+             * compiler.
+             */
+            case 'request':
+                if ($this->request_use_auto_globals) {
+                    $compiled_ref = '$_REQUEST';
+                    break;
+                } else {
+                    $this->_init_smarty_vars = true;
+                }
+                return null;
+
+            case 'capture':
+                return null;
+
+            case 'template':
+                $compiled_ref = "'$this->_current_file'";
+                $_max_index = 1;
+                break;
+
+            case 'version':
+                $compiled_ref = "'$this->_version'";
+                $_max_index = 1;
+                break;
+
+            case 'const':
+                if ($this->security && !$this->security_settings['ALLOW_CONSTANTS']) {
+                    $this->_syntax_error("(secure mode) constants not permitted",
+                                         E_USER_WARNING, __FILE__, __LINE__);
+                    return;
+                }
+                array_shift($indexes);
+                if (preg_match('!^\.\w+$!', $indexes[0])) {
+                    $compiled_ref = '@' . substr($indexes[0], 1);
+                } else {
+                    $_val = $this->_parse_var_props(substr($indexes[0], 1));
+                    $compiled_ref = '@constant(' . $_val . ')';
+                }
+                $_max_index = 1;
+                break;
+
+            case 'config':
+                $compiled_ref = "\$this->_config[0]['vars']";
+                $_max_index = 3;
+                break;
+
+            case 'ldelim':
+                $compiled_ref = "'$this->left_delimiter'";
+                break;
+
+            case 'rdelim':
+                $compiled_ref = "'$this->right_delimiter'";
+                break;
+                
+            default:
+                $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__);
+                break;
+        }
+
+        if (isset($_max_index) && count($indexes) > $_max_index) {
+            $this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        array_shift($indexes);
+        return $compiled_ref;
+    }
+
+    /**
+     * compiles call to plugin of type $type with name $name
+     * returns a string containing the function-name or method call
+     * without the paramter-list that would have follow to make the
+     * call valid php-syntax
+     *
+     * @param string $type
+     * @param string $name
+     * @return string
+     */
+    function _compile_plugin_call($type, $name) {
+        if (isset($this->_plugins[$type][$name])) {
+            /* plugin loaded */
+            if (is_array($this->_plugins[$type][$name][0])) {
+                return ((is_object($this->_plugins[$type][$name][0][0])) ?
+                        "\$this->_plugins['$type']['$name'][0][0]->"    /* method callback */
+                        : (string)($this->_plugins[$type][$name][0][0]).'::'    /* class callback */
+                       ). $this->_plugins[$type][$name][0][1];
+
+            } else {
+                /* function callback */
+                return $this->_plugins[$type][$name][0];
+
+            }
+        } else {
+            /* plugin not loaded -> auto-loadable-plugin */
+            return 'smarty_'.$type.'_'.$name;
+
+        }
+    }
+
+    /**
+     * load pre- and post-filters
+     */
+    function _load_filters()
+    {
+        if (count($this->_plugins['prefilter']) > 0) {
+            foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
+                if ($prefilter === false) {
+                    unset($this->_plugins['prefilter'][$filter_name]);
+                    $_params = array('plugins' => array(array('prefilter', $filter_name, null, null, false)));
+                    require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
+                    smarty_core_load_plugins($_params, $this);
+                }
+            }
+        }
+        if (count($this->_plugins['postfilter']) > 0) {
+            foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
+                if ($postfilter === false) {
+                    unset($this->_plugins['postfilter'][$filter_name]);
+                    $_params = array('plugins' => array(array('postfilter', $filter_name, null, null, false)));
+                    require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
+                    smarty_core_load_plugins($_params, $this);
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Quote subpattern references
+     *
+     * @param string $string
+     * @return string
+     */
+    function _quote_replace($string)
+    {
+        return strtr($string, array('\\' => '\\\\', '$' => '\\$'));
+    }
+
+    /**
+     * display Smarty syntax error
+     *
+     * @param string $error_msg
+     * @param integer $error_type
+     * @param string $file
+     * @param integer $line
+     */
+    function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null)
+    {
+        $this->_trigger_fatal_error("syntax error: $error_msg", $this->_current_file, $this->_current_line_no, $file, $line, $error_type);
+    }
+
+
+    /**
+     * check if the compilation changes from cacheable to
+     * non-cacheable state with the beginning of the current
+     * plugin. return php-code to reflect the transition.
+     * @return string
+     */
+    function _push_cacheable_state($type, $name) {
+        $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
+        if ($_cacheable
+            || 0<$this->_cacheable_state++) return '';
+        if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty'));
+        $_ret = 'if ($this->caching && !$this->_cache_including): echo \'{nocache:'
+            . $this->_cache_serial . '#' . $this->_nocache_count
+            . '}\'; endif;';
+        return $_ret;
+    }
+
+
+    /**
+     * check if the compilation changes from non-cacheable to
+     * cacheable state with the end of the current plugin return
+     * php-code to reflect the transition.
+     * @return string
+     */
+    function _pop_cacheable_state($type, $name) {
+        $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
+        if ($_cacheable
+            || --$this->_cacheable_state>0) return '';
+        return 'if ($this->caching && !$this->_cache_including): echo \'{/nocache:'
+            . $this->_cache_serial . '#' . ($this->_nocache_count++)
+            . '}\'; endif;';
+    }
+
+
+    /**
+     * push opening tag-name, file-name and line-number on the tag-stack
+     * @param string the opening tag's name
+     */
+    function _push_tag($open_tag)
+    {
+        array_push($this->_tag_stack, array($open_tag, $this->_current_line_no));
+    }
+
+    /**
+     * pop closing tag-name
+     * raise an error if this stack-top doesn't match with the closing tag
+     * @param string the closing tag's name
+     * @return string the opening tag's name
+     */
+    function _pop_tag($close_tag)
+    {
+        $message = '';
+        if (count($this->_tag_stack)>0) {
+            list($_open_tag, $_line_no) = array_pop($this->_tag_stack);
+            if ($close_tag == $_open_tag) {
+                return $_open_tag;
+            }
+            if ($close_tag == 'if' && ($_open_tag == 'else' || $_open_tag == 'elseif' )) {
+                return $this->_pop_tag($close_tag);
+            }
+            if ($close_tag == 'section' && $_open_tag == 'sectionelse') {
+                $this->_pop_tag($close_tag);
+                return $_open_tag;
+            }
+            if ($close_tag == 'foreach' && $_open_tag == 'foreachelse') {
+                $this->_pop_tag($close_tag);
+                return $_open_tag;
+            }
+            if ($_open_tag == 'else' || $_open_tag == 'elseif') {
+                $_open_tag = 'if';
+            } elseif ($_open_tag == 'sectionelse') {
+                $_open_tag = 'section';
+            } elseif ($_open_tag == 'foreachelse') {
+                $_open_tag = 'foreach';
+            }
+            $message = " expected {/$_open_tag} (opened line $_line_no).";
+        }
+        $this->_syntax_error("mismatched tag {/$close_tag}.$message",
+                             E_USER_ERROR, __FILE__, __LINE__);
+    }
+
+}
+
+/**
+ * compare to values by their string length
+ *
+ * @access private
+ * @param string $a
+ * @param string $b
+ * @return 0|-1|1
+ */
+function _smarty_sort_length($a, $b)
+{
+    if($a == $b)
+        return 0;
+
+    if(strlen($a) == strlen($b))
+        return ($a > $b) ? -1 : 1;
+
+    return (strlen($a) > strlen($b)) ? -1 : 1;
+}
+
+
+/* vim: set et: */
+
+?>

+ 157 - 0
Tools/projectGenerator/smarty/debug.tpl

@@ -0,0 +1,157 @@
+{* Smarty *}
+{* debug.tpl, last updated version 2.1.0 *}
+{assign_debug_info}
+{capture assign=debug_output}
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+    <title>Smarty Debug Console</title>
+{literal}
+<style type="text/css">
+/* <![CDATA[ */
+body, h1, h2, td, th, p {
+    font-family: sans-serif;
+    font-weight: normal;
+    font-size: 0.9em;
+    margin: 1px;
+    padding: 0;
+}
+
+h1 {
+    margin: 0;
+    text-align: left;
+    padding: 2px;
+    background-color: #f0c040;
+    color:  black;
+    font-weight: bold;
+    font-size: 1.2em;
+ }
+
+h2 {
+    background-color: #9B410E;
+    color: white;
+    text-align: left;
+    font-weight: bold;
+    padding: 2px;
+    border-top: 1px solid black;
+}
+
+body {
+    background: black; 
+}
+
+p, table, div {
+    background: #f0ead8;
+} 
+
+p {
+    margin: 0;
+    font-style: italic;
+    text-align: center;
+}
+
+table {
+    width: 100%;
+}
+
+th, td {
+    font-family: monospace;
+    vertical-align: top;
+    text-align: left;
+    width: 50%;
+}
+
+td {
+    color: green;
+}
+
+.odd {
+    background-color: #eeeeee;
+}
+
+.even {
+    background-color: #fafafa;
+}
+
+.exectime {
+    font-size: 0.8em;
+    font-style: italic;
+}
+
+#table_assigned_vars th {
+    color: blue;
+}
+
+#table_config_vars th {
+    color: maroon;
+}
+/* ]]> */
+</style>
+{/literal}
+</head>
+<body>
+
+<h1>Smarty Debug Console</h1>
+
+<h2>included templates &amp; config files (load time in seconds)</h2>
+
+<div>
+{section name=templates loop=$_debug_tpls}
+    {section name=indent loop=$_debug_tpls[templates].depth}&nbsp;&nbsp;&nbsp;{/section}
+    <font color={if $_debug_tpls[templates].type eq "template"}brown{elseif $_debug_tpls[templates].type eq "insert"}black{else}green{/if}>
+        {$_debug_tpls[templates].filename|escape:html}</font>
+    {if isset($_debug_tpls[templates].exec_time)}
+        <span class="exectime">
+        ({$_debug_tpls[templates].exec_time|string_format:"%.5f"})
+        {if %templates.index% eq 0}(total){/if}
+        </span>
+    {/if}
+    <br />
+{sectionelse}
+    <p>no templates included</p>
+{/section}
+</div>
+
+<h2>assigned template variables</h2>
+
+<table id="table_assigned_vars">
+    {section name=vars loop=$_debug_keys}
+        <tr class="{cycle values="odd,even"}">
+            <th>{ldelim}${$_debug_keys[vars]|escape:'html'}{rdelim}</th>
+            <td>{$_debug_vals[vars]|@debug_print_var}</td></tr>
+    {sectionelse}
+        <tr><td><p>no template variables assigned</p></td></tr>
+    {/section}
+</table>
+
+<h2>assigned config file variables (outer template scope)</h2>
+
+<table id="table_config_vars">
+    {section name=config_vars loop=$_debug_config_keys}
+        <tr class="{cycle values="odd,even"}">
+            <th>{ldelim}#{$_debug_config_keys[config_vars]|escape:'html'}#{rdelim}</th>
+            <td>{$_debug_config_vals[config_vars]|@debug_print_var}</td></tr>
+    {sectionelse}
+        <tr><td><p>no config vars assigned</p></td></tr>
+    {/section}
+</table>
+</body>
+</html>
+{/capture}
+{if isset($_smarty_debug_output) and $_smarty_debug_output eq "html"}
+    {$debug_output}
+{else}
+<script type="text/javascript">
+// <![CDATA[
+    if ( self.name == '' ) {ldelim}
+       var title = 'Console';
+    {rdelim}
+    else {ldelim}
+       var title = 'Console_' + self.name;
+    {rdelim}
+    _smarty_console = window.open("",title.value,"width=680,height=600,resizable,scrollbars=yes");
+    _smarty_console.document.write('{$debug_output|escape:'javascript'}');
+    _smarty_console.document.close();
+// ]]>
+</script>
+{/if}

+ 67 - 0
Tools/projectGenerator/smarty/internals/core.assemble_plugin_filepath.php

@@ -0,0 +1,67 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * assemble filepath of requested plugin
+ *
+ * @param string $type
+ * @param string $name
+ * @return string|false
+ */
+function smarty_core_assemble_plugin_filepath($params, &$smarty)
+{
+    static $_filepaths_cache = array();
+
+    $_plugin_filename = $params['type'] . '.' . $params['name'] . '.php';
+    if (isset($_filepaths_cache[$_plugin_filename])) {
+        return $_filepaths_cache[$_plugin_filename];
+    }
+    $_return = false;
+
+    foreach ((array)$smarty->plugins_dir as $_plugin_dir) {
+
+        $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename;
+
+        // see if path is relative
+        if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $_plugin_dir)) {
+            $_relative_paths[] = $_plugin_dir;
+            // relative path, see if it is in the SMARTY_DIR
+            if (@is_readable(SMARTY_DIR . $_plugin_filepath)) {
+                $_return = SMARTY_DIR . $_plugin_filepath;
+                break;
+            }
+        }
+        // try relative to cwd (or absolute)
+        if (@is_readable($_plugin_filepath)) {
+            $_return = $_plugin_filepath;
+            break;
+        }
+    }
+
+    if($_return === false) {
+        // still not found, try PHP include_path
+        if(isset($_relative_paths)) {
+            foreach ((array)$_relative_paths as $_plugin_dir) {
+
+                $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename;
+
+                $_params = array('file_path' => $_plugin_filepath);
+                require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
+                if(smarty_core_get_include_path($_params, $smarty)) {
+                    $_return = $_params['new_file_path'];
+                    break;
+                }
+            }
+        }
+    }
+    $_filepaths_cache[$_plugin_filename] = $_return;
+    return $_return;
+}
+
+/* vim: set expandtab: */
+
+?>

+ 43 - 0
Tools/projectGenerator/smarty/internals/core.assign_smarty_interface.php

@@ -0,0 +1,43 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty assign_smarty_interface core plugin
+ *
+ * Type:     core<br>
+ * Name:     assign_smarty_interface<br>
+ * Purpose:  assign the $smarty interface variable
+ * @param array Format: null
+ * @param Smarty
+ */
+function smarty_core_assign_smarty_interface($params, &$smarty)
+{
+        if (isset($smarty->_smarty_vars) && isset($smarty->_smarty_vars['request'])) {
+            return;
+        }
+
+        $_globals_map = array('g'  => 'HTTP_GET_VARS',
+                             'p'  => 'HTTP_POST_VARS',
+                             'c'  => 'HTTP_COOKIE_VARS',
+                             's'  => 'HTTP_SERVER_VARS',
+                             'e'  => 'HTTP_ENV_VARS');
+
+        $_smarty_vars_request  = array();
+
+        foreach (preg_split('!!', strtolower($smarty->request_vars_order)) as $_c) {
+            if (isset($_globals_map[$_c])) {
+                $_smarty_vars_request = array_merge($_smarty_vars_request, $GLOBALS[$_globals_map[$_c]]);
+            }
+        }
+        $_smarty_vars_request = @array_merge($_smarty_vars_request, $GLOBALS['HTTP_SESSION_VARS']);
+
+        $smarty->_smarty_vars['request'] = $_smarty_vars_request;
+}
+
+/* vim: set expandtab: */
+
+?>

+ 79 - 0
Tools/projectGenerator/smarty/internals/core.create_dir_structure.php

@@ -0,0 +1,79 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * create full directory structure
+ *
+ * @param string $dir
+ */
+
+// $dir
+
+function smarty_core_create_dir_structure($params, &$smarty)
+{
+    if (!file_exists($params['dir'])) {
+        $_open_basedir_ini = ini_get('open_basedir');
+
+        if (DIRECTORY_SEPARATOR=='/') {
+            /* unix-style paths */
+            $_dir = $params['dir'];
+            $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY);
+            $_new_dir = (substr($_dir, 0, 1)=='/') ? '/' : getcwd().'/';
+            if($_use_open_basedir = !empty($_open_basedir_ini)) {
+                $_open_basedirs = explode(':', $_open_basedir_ini);
+            }
+
+        } else {
+            /* other-style paths */
+            $_dir = str_replace('\\','/', $params['dir']);
+            $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY);
+            if (preg_match('!^((//)|([a-zA-Z]:/))!', $_dir, $_root_dir)) {
+                /* leading "//" for network volume, or "[letter]:/" for full path */
+                $_new_dir = $_root_dir[1];
+                /* remove drive-letter from _dir_parts */
+                if (isset($_root_dir[3])) array_shift($_dir_parts);
+
+            } else {
+                $_new_dir = str_replace('\\', '/', getcwd()).'/';
+
+            }
+
+            if($_use_open_basedir = !empty($_open_basedir_ini)) {
+                $_open_basedirs = explode(';', str_replace('\\', '/', $_open_basedir_ini));
+            }
+
+        }
+
+        /* all paths use "/" only from here */
+        foreach ($_dir_parts as $_dir_part) {
+            $_new_dir .= $_dir_part;
+
+            if ($_use_open_basedir) {
+                // do not attempt to test or make directories outside of open_basedir
+                $_make_new_dir = false;
+                foreach ($_open_basedirs as $_open_basedir) {
+                    if (substr($_new_dir, 0, strlen($_open_basedir)) == $_open_basedir) {
+                        $_make_new_dir = true;
+                        break;
+                    }
+                }
+            } else {
+                $_make_new_dir = true;
+            }
+
+            if ($_make_new_dir && !file_exists($_new_dir) && !@mkdir($_new_dir, $smarty->_dir_perms) && !is_dir($_new_dir)) {
+                $smarty->trigger_error("problem creating directory '" . $_new_dir . "'");
+                return false;
+            }
+            $_new_dir .= '/';
+        }
+    }
+}
+
+/* vim: set expandtab: */
+
+?>

+ 61 - 0
Tools/projectGenerator/smarty/internals/core.display_debug_console.php

@@ -0,0 +1,61 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty debug_console function plugin
+ *
+ * Type:     core<br>
+ * Name:     display_debug_console<br>
+ * Purpose:  display the javascript debug console window
+ * @param array Format: null
+ * @param Smarty
+ */
+function smarty_core_display_debug_console($params, &$smarty)
+{
+    // we must force compile the debug template in case the environment
+    // changed between separate applications.
+
+    if(empty($smarty->debug_tpl)) {
+        // set path to debug template from SMARTY_DIR
+        $smarty->debug_tpl = SMARTY_DIR . 'debug.tpl';
+        if($smarty->security && is_file($smarty->debug_tpl)) {
+            $smarty->secure_dir[] = realpath($smarty->debug_tpl);
+        }
+        $smarty->debug_tpl = 'file:' . SMARTY_DIR . 'debug.tpl';
+    }
+
+    $_ldelim_orig = $smarty->left_delimiter;
+    $_rdelim_orig = $smarty->right_delimiter;
+
+    $smarty->left_delimiter = '{';
+    $smarty->right_delimiter = '}';
+
+    $_compile_id_orig = $smarty->_compile_id;
+    $smarty->_compile_id = null;
+
+    $_compile_path = $smarty->_get_compile_path($smarty->debug_tpl);
+    if ($smarty->_compile_resource($smarty->debug_tpl, $_compile_path))
+    {
+        ob_start();
+        $smarty->_include($_compile_path);
+        $_results = ob_get_contents();
+        ob_end_clean();
+    } else {
+        $_results = '';
+    }
+
+    $smarty->_compile_id = $_compile_id_orig;
+
+    $smarty->left_delimiter = $_ldelim_orig;
+    $smarty->right_delimiter = $_rdelim_orig;
+
+    return $_results;
+}
+
+/* vim: set expandtab: */
+
+?>

+ 44 - 0
Tools/projectGenerator/smarty/internals/core.get_include_path.php

@@ -0,0 +1,44 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Get path to file from include_path
+ *
+ * @param string $file_path
+ * @param string $new_file_path
+ * @return boolean
+ * @staticvar array|null
+ */
+
+//  $file_path, &$new_file_path
+
+function smarty_core_get_include_path(&$params, &$smarty)
+{
+    static $_path_array = null;
+
+    if(!isset($_path_array)) {
+        $_ini_include_path = ini_get('include_path');
+
+        if(strstr($_ini_include_path,';')) {
+            // windows pathnames
+            $_path_array = explode(';',$_ini_include_path);
+        } else {
+            $_path_array = explode(':',$_ini_include_path);
+        }
+    }
+    foreach ($_path_array as $_include_path) {
+        if (@is_readable($_include_path . DIRECTORY_SEPARATOR . $params['file_path'])) {
+               $params['new_file_path'] = $_include_path . DIRECTORY_SEPARATOR . $params['file_path'];
+            return true;
+        }
+    }
+    return false;
+}
+
+/* vim: set expandtab: */
+
+?>

+ 23 - 0
Tools/projectGenerator/smarty/internals/core.get_microtime.php

@@ -0,0 +1,23 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Get seconds and microseconds
+ * @return double
+ */
+function smarty_core_get_microtime($params, &$smarty)
+{
+    $mtime = microtime();
+    $mtime = explode(" ", $mtime);
+    $mtime = (double)($mtime[1]) + (double)($mtime[0]);
+    return ($mtime);
+}
+
+
+/* vim: set expandtab: */
+
+?>

+ 80 - 0
Tools/projectGenerator/smarty/internals/core.get_php_resource.php

@@ -0,0 +1,80 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Retrieves PHP script resource
+ *
+ * sets $php_resource to the returned resource
+ * @param string $resource
+ * @param string $resource_type
+ * @param  $php_resource
+ * @return boolean
+ */
+
+function smarty_core_get_php_resource(&$params, &$smarty)
+{
+
+    $params['resource_base_path'] = $smarty->trusted_dir;
+    $smarty->_parse_resource_name($params, $smarty);
+
+    /*
+     * Find out if the resource exists.
+     */
+
+    if ($params['resource_type'] == 'file') {
+        $_readable = false;
+        if(file_exists($params['resource_name']) && is_readable($params['resource_name'])) {
+            $_readable = true;
+        } else {
+            // test for file in include_path
+            $_params = array('file_path' => $params['resource_name']);
+            require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
+            if(smarty_core_get_include_path($_params, $smarty)) {
+                $_include_path = $_params['new_file_path'];
+                $_readable = true;
+            }
+        }
+    } else if ($params['resource_type'] != 'file') {
+        $_template_source = null;
+        $_readable = is_callable($smarty->_plugins['resource'][$params['resource_type']][0][0])
+            && call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][0],
+                                    array($params['resource_name'], &$_template_source, &$smarty));
+    }
+
+    /*
+     * Set the error function, depending on which class calls us.
+     */
+    if (method_exists($smarty, '_syntax_error')) {
+        $_error_funcc = '_syntax_error';
+    } else {
+        $_error_funcc = 'trigger_error';
+    }
+
+    if ($_readable) {
+        if ($smarty->security) {
+            require_once(SMARTY_CORE_DIR . 'core.is_trusted.php');
+            if (!smarty_core_is_trusted($params, $smarty)) {
+                $smarty->$_error_funcc('(secure mode) ' . $params['resource_type'] . ':' . $params['resource_name'] . ' is not trusted');
+                return false;
+            }
+        }
+    } else {
+        $smarty->$_error_funcc($params['resource_type'] . ':' . $params['resource_name'] . ' is not readable');
+        return false;
+    }
+
+    if ($params['resource_type'] == 'file') {
+        $params['php_resource'] = $params['resource_name'];
+    } else {
+        $params['php_resource'] = $_template_source;
+    }
+    return true;
+}
+
+/* vim: set expandtab: */
+
+?>

+ 59 - 0
Tools/projectGenerator/smarty/internals/core.is_secure.php

@@ -0,0 +1,59 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * determines if a resource is secure or not.
+ *
+ * @param string $resource_type
+ * @param string $resource_name
+ * @return boolean
+ */
+
+//  $resource_type, $resource_name
+
+function smarty_core_is_secure($params, &$smarty)
+{
+    if (!$smarty->security || $smarty->security_settings['INCLUDE_ANY']) {
+        return true;
+    }
+
+    if ($params['resource_type'] == 'file') {
+        $_rp = realpath($params['resource_name']);
+        if (isset($params['resource_base_path'])) {
+            foreach ((array)$params['resource_base_path'] as $curr_dir) {
+                if ( ($_cd = realpath($curr_dir)) !== false &&
+                     strncmp($_rp, $_cd, strlen($_cd)) == 0 &&
+                     substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) {
+                    return true;
+                }
+            }
+        }
+        if (!empty($smarty->secure_dir)) {
+            foreach ((array)$smarty->secure_dir as $curr_dir) {
+                if ( ($_cd = realpath($curr_dir)) !== false) {
+                    if($_cd == $_rp) {
+                        return true;
+                    } elseif (strncmp($_rp, $_cd, strlen($_cd)) == 0 &&
+                        substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR) {
+                        return true;
+                    }
+                }
+            }
+        }
+    } else {
+        // resource is not on local file system
+        return call_user_func_array(
+            $smarty->_plugins['resource'][$params['resource_type']][0][2],
+            array($params['resource_name'], &$smarty));
+    }
+
+    return false;
+}
+
+/* vim: set expandtab: */
+
+?>

+ 47 - 0
Tools/projectGenerator/smarty/internals/core.is_trusted.php

@@ -0,0 +1,47 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * determines if a resource is trusted or not
+ *
+ * @param string $resource_type
+ * @param string $resource_name
+ * @return boolean
+ */
+
+ // $resource_type, $resource_name
+
+function smarty_core_is_trusted($params, &$smarty)
+{
+    $_smarty_trusted = false;
+    if ($params['resource_type'] == 'file') {
+        if (!empty($smarty->trusted_dir)) {
+            $_rp = realpath($params['resource_name']);
+            foreach ((array)$smarty->trusted_dir as $curr_dir) {
+                if (!empty($curr_dir) && is_readable ($curr_dir)) {
+                    $_cd = realpath($curr_dir);
+                    if (strncmp($_rp, $_cd, strlen($_cd)) == 0
+                        && substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) {
+                        $_smarty_trusted = true;
+                        break;
+                    }
+                }
+            }
+        }
+
+    } else {
+        // resource is not on local file system
+        $_smarty_trusted = call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][3],
+                                                array($params['resource_name'], $smarty));
+    }
+
+    return $_smarty_trusted;
+}
+
+/* vim: set expandtab: */
+
+?>

+ 125 - 0
Tools/projectGenerator/smarty/internals/core.load_plugins.php

@@ -0,0 +1,125 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Load requested plugins
+ *
+ * @param array $plugins
+ */
+
+// $plugins
+
+function smarty_core_load_plugins($params, &$smarty)
+{
+
+    foreach ($params['plugins'] as $_plugin_info) {
+        list($_type, $_name, $_tpl_file, $_tpl_line, $_delayed_loading) = $_plugin_info;
+        $_plugin = &$smarty->_plugins[$_type][$_name];
+
+        /*
+         * We do not load plugin more than once for each instance of Smarty.
+         * The following code checks for that. The plugin can also be
+         * registered dynamically at runtime, in which case template file
+         * and line number will be unknown, so we fill them in.
+         *
+         * The final element of the info array is a flag that indicates
+         * whether the dynamically registered plugin function has been
+         * checked for existence yet or not.
+         */
+        if (isset($_plugin)) {
+            if (empty($_plugin[3])) {
+                if (!is_callable($_plugin[0])) {
+                    $smarty->_trigger_fatal_error("[plugin] $_type '$_name' is not implemented", $_tpl_file, $_tpl_line, __FILE__, __LINE__);
+                } else {
+                    $_plugin[1] = $_tpl_file;
+                    $_plugin[2] = $_tpl_line;
+                    $_plugin[3] = true;
+                    if (!isset($_plugin[4])) $_plugin[4] = true; /* cacheable */
+                }
+            }
+            continue;
+        } else if ($_type == 'insert') {
+            /*
+             * For backwards compatibility, we check for insert functions in
+             * the symbol table before trying to load them as a plugin.
+             */
+            $_plugin_func = 'insert_' . $_name;
+            if (function_exists($_plugin_func)) {
+                $_plugin = array($_plugin_func, $_tpl_file, $_tpl_line, true, false);
+                continue;
+            }
+        }
+
+        $_plugin_file = $smarty->_get_plugin_filepath($_type, $_name);
+
+        if (! $_found = ($_plugin_file != false)) {
+            $_message = "could not load plugin file '$_type.$_name.php'\n";
+        }
+
+        /*
+         * If plugin file is found, it -must- provide the properly named
+         * plugin function. In case it doesn't, simply output the error and
+         * do not fall back on any other method.
+         */
+        if ($_found) {
+            include_once $_plugin_file;
+
+            $_plugin_func = 'smarty_' . $_type . '_' . $_name;
+            if (!function_exists($_plugin_func)) {
+                $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", $_tpl_file, $_tpl_line, __FILE__, __LINE__);
+                continue;
+            }
+        }
+        /*
+         * In case of insert plugins, their code may be loaded later via
+         * 'script' attribute.
+         */
+        else if ($_type == 'insert' && $_delayed_loading) {
+            $_plugin_func = 'smarty_' . $_type . '_' . $_name;
+            $_found = true;
+        }
+
+        /*
+         * Plugin specific processing and error checking.
+         */
+        if (!$_found) {
+            if ($_type == 'modifier') {
+                /*
+                 * In case modifier falls back on using PHP functions
+                 * directly, we only allow those specified in the security
+                 * context.
+                 */
+                if ($smarty->security && !in_array($_name, $smarty->security_settings['MODIFIER_FUNCS'])) {
+                    $_message = "(secure mode) modifier '$_name' is not allowed";
+                } else {
+                    if (!function_exists($_name)) {
+                        $_message = "modifier '$_name' is not implemented";
+                    } else {
+                        $_plugin_func = $_name;
+                        $_found = true;
+                    }
+                }
+            } else if ($_type == 'function') {
+                /*
+                 * This is a catch-all situation.
+                 */
+                $_message = "unknown tag - '$_name'";
+            }
+        }
+
+        if ($_found) {
+            $smarty->_plugins[$_type][$_name] = array($_plugin_func, $_tpl_file, $_tpl_line, true, true);
+        } else {
+            // output error
+            $smarty->_trigger_fatal_error('[plugin] ' . $_message, $_tpl_file, $_tpl_line, __FILE__, __LINE__);
+        }
+    }
+}
+
+/* vim: set expandtab: */
+
+?>

+ 74 - 0
Tools/projectGenerator/smarty/internals/core.load_resource_plugin.php

@@ -0,0 +1,74 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * load a resource plugin
+ *
+ * @param string $type
+ */
+
+// $type
+
+function smarty_core_load_resource_plugin($params, &$smarty)
+{
+    /*
+     * Resource plugins are not quite like the other ones, so they are
+     * handled differently. The first element of plugin info is the array of
+     * functions provided by the plugin, the second one indicates whether
+     * all of them exist or not.
+     */
+
+    $_plugin = &$smarty->_plugins['resource'][$params['type']];
+    if (isset($_plugin)) {
+        if (!$_plugin[1] && count($_plugin[0])) {
+            $_plugin[1] = true;
+            foreach ($_plugin[0] as $_plugin_func) {
+                if (!is_callable($_plugin_func)) {
+                    $_plugin[1] = false;
+                    break;
+                }
+            }
+        }
+
+        if (!$_plugin[1]) {
+            $smarty->_trigger_fatal_error("[plugin] resource '" . $params['type'] . "' is not implemented", null, null, __FILE__, __LINE__);
+        }
+
+        return;
+    }
+
+    $_plugin_file = $smarty->_get_plugin_filepath('resource', $params['type']);
+    $_found = ($_plugin_file != false);
+
+    if ($_found) {            /*
+         * If the plugin file is found, it -must- provide the properly named
+         * plugin functions.
+         */
+        include_once($_plugin_file);
+
+        /*
+         * Locate functions that we require the plugin to provide.
+         */
+        $_resource_ops = array('source', 'timestamp', 'secure', 'trusted');
+        $_resource_funcs = array();
+        foreach ($_resource_ops as $_op) {
+            $_plugin_func = 'smarty_resource_' . $params['type'] . '_' . $_op;
+            if (!function_exists($_plugin_func)) {
+                $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", null, null, __FILE__, __LINE__);
+                return;
+            } else {
+                $_resource_funcs[] = $_plugin_func;
+            }
+        }
+
+        $smarty->_plugins['resource'][$params['type']] = array($_resource_funcs, true);
+    }
+}
+
+/* vim: set expandtab: */
+
+?>

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác