<?php
   class v3_factory
   {
      private static $inc_path = null;

      function __construct()
         { throw new Exception(__CLASS__ . ': we don\'t need no stinkin\' instances!'); }
      function __clone()
         { throw new Exception(__CLASS__ . ': we don\'t need no stinkin\' clones!'); }


      public static function load_module($name)
      {
         if(self::$inc_path === null) {
            self::$inc_path = V3_ROOT . '/includes';
         }

         $path = self::$inc_path . '/v3_' . $name . '.inc';

         if(@include_once($path)) {
            return true;
         } else {
            throw new Exception(__CLASS__ . ": '$name' not found!");
         }
      }

      public static function new_instance(/* $name, ... */)
      {
         if(func_num_args() == 0)
            throw new Exception(__METHOD__ . ' expects at least one argument!');

         $args = func_get_args();
         $name = array_shift($args);

         if(self::load_module($name)) {
            $cl = 'v3_' . $name;

            if(count($args))
               return eval("return new $cl(". self::_parse_args($args) .');');
            else 
               return new $cl;
         }
      }

      # Yes, this is hackish as all hell, but it does work.
      private static function _parse_arg($a)
      {
         if(is_string($a))
            return "'". str_replace("'", "\\'", $a) . "'";
         else if(is_bool($a))
            return $a ? 'true' : 'false';
         else if(is_array($a))
            return 'array(' . self::_parse_arr($a) . ')';
         else if(is_scalar($a))
            return $a;
         else
            return 'null';
      }
      private static function _parse_arr($arr)
      {
         $out = '';
         $i   = count($arr);

         foreach($arr as $k => $v)
            $out .= sprintf('%s => %s%s', self::_parse_arg($k), self::_parse_arg($v), --$i ? ',' : '');

         return $out;
      }
      private static function _parse_args($args)
      {
         return join(', ', array_map(array(self, '_parse_arg'), $args));
      }
   }
?>