Index: trunk/include/config_default.inc.php
===================================================================
--- trunk/include/config_default.inc.php	(revision 8008)
+++ trunk/include/config_default.inc.php	(revision 8012)
@@ -480,4 +480,7 @@
 // production environment.
 $conf['template_force_compile'] = false;
+
+// activate merging of javascript / css files
+$conf['template_combine_files'] = true;
 
 // this permit to show the php errors reporting (see INI 'error_reporting'
Index: trunk/include/template.class.php
===================================================================
--- trunk/include/template.class.php	(revision 8008)
+++ trunk/include/template.class.php	(revision 8012)
@@ -397,5 +397,5 @@
           $scripts = $this->scriptLoader->get_head_scripts();
           $content = array();
-          foreach ($scripts as $id => $script)
+          foreach ($scripts as $script)
           {
               $content[]=
@@ -412,23 +412,37 @@
     {
       ksort($this->css_by_priority);
-      $combiner = new FileCombiner('css');
-      foreach ($this->css_by_priority as $files)
-      {
-        foreach ($files as $file_ver)
-        {
-          $combiner->add( $file_ver[0], $file_ver[1] );
-        }
-      }
-      if ( $combiner->combine( $out_file, $out_version) )
-      {
-        $href = get_root_url() . $out_file;
-        if ($out_version !== false)
-          $href .= '?v' . ($out_version ? $out_version : PHPWG_VERSION);
+
+			global $conf;
+			$css = array();
+			if ($conf['template_combine_files'])
+			{
+				$combiner = new FileCombiner('css');
+				foreach ($this->css_by_priority as $files)
+				{
+					foreach ($files as $file_ver)
+						$combiner->add( $file_ver[0], $file_ver[1] );
+				}
+				if ( $combiner->combine( $out_file, $out_version) )
+					$css[] = array($out_file, $out_version);
+			}
+			else
+			{
+				foreach ($this->css_by_priority as $files)
+					$css = array_merge($css, $files);
+			}
+			
+			$content = array();
+      foreach( $css as $file_ver )
+      {
+        $href = get_root_url() . $file_ver[0];
+        if ($file_ver[1] !== false)
+          $href .= '?v' . ($file_ver[1] ? $file_ver[1] : PHPWG_VERSION);
         // trigger the event for eventual use of a cdn
-        $href = trigger_event('combined_css', $href, $out_file, $out_version);
-        $this->output = str_replace(self::COMBINED_CSS_TAG,
-          '<link rel="stylesheet" type="text/css" href="'.$href.'">',
+        $href = trigger_event('combined_css', $href, $file_ver[0], $file_ver[1]);
+				$content[] = '<link rel="stylesheet" type="text/css" href="'.$href.'">';
+      }
+      $this->output = str_replace(self::COMBINED_CSS_TAG,
+          implode( "\n", $content ),
           $this->output );
-      }
     }
 
@@ -569,12 +583,10 @@
     else
     {
-      if (!$this->scriptLoader->did_head())
-        fatal_error('get_combined_scripts didn\'t call header');
       $scripts = $this->scriptLoader->get_footer_scripts();
-      foreach ($scripts[0] as $id => $script)
+      foreach ($scripts[0] as $script)
       {
         $content[]=
           '<script type="text/javascript" src="'
-          . Template::make_script_src($script)
+          . self::make_script_src($script)
           .'"></script>';
       }
@@ -596,5 +608,5 @@
           $content[]=
             's=document.createElement(\'script\'); s.type = \'text/javascript\'; s.async = true; s.src = \''
-            . Template::make_script_src($script)
+            . self::make_script_src($script)
             .'\';';
           $content[]= 'after = after.parentNode.insertBefore(s, after);';
@@ -611,5 +623,5 @@
   {
     $ret = '';
-    if ( url_is_remote($script->path) )
+    if ( $script->is_remote() )
       $ret = $script->path;
     else
@@ -621,4 +633,6 @@
       }
     }
+    // trigger the event for eventual use of a cdn
+    $ret = trigger_event('combined_script', $ret, $script);
     return $ret;
   }
@@ -639,5 +653,4 @@
     $version = isset($params['version']) ? $params['version'] : 0;
     $this->css_by_priority[$order][] = array( $params['path'], $version);
-    //var_export( $this->css_by_priority ); echo "<br>";
   }
 
@@ -830,11 +843,12 @@
   public $extra = array();
 
-  function Script($id, $load_mode, $precedents, $path, $version)
+  function Script($load_mode, $id, $path, $version, $precedents)
   {
     $this->id = $id;
     $this->load_mode = $load_mode;
+    $this->id = $id;
+    $this->set_path($path);
+    $this->version = $version;
     $this->precedents = $precedents;
-    $this->path = $path;
-    $this->version = $version;
   }
 
@@ -844,5 +858,5 @@
       $this->path = $path;
   }
-  
+
   function is_remote()
   {
@@ -902,5 +916,5 @@
     if (! isset( $this->registered_scripts[$id] ) )
     {
-      $script = new Script($id, $load_mode, $require, $path, $version);
+      $script = new Script($load_mode, $id, $path, $version, $require);
       self::fill_well_known($id, $script);
       $this->registered_scripts[$id] = $script;
@@ -946,14 +960,13 @@
     }
     $this->did_head = true;
-    return $this->head_done_scripts;
+    return self::do_combine($this->head_done_scripts, 0);
   }
 
   function get_footer_scripts()
   {
-    if (!$this->did_head)
+    /*if (!$this->did_head)
     {
       trigger_error("Attempt to write footer scripts without header scripts", E_USER_ERROR );
-    }
-    
+    }*/
     $todo = array();
     foreach( $this->registered_scripts as $id => $script)
@@ -971,5 +984,4 @@
     uasort($todo, array('ScriptLoader', 'cmp_by_mode_and_order'));
 
-    
     $result = array( array(), array() );
     foreach( $todo as $id => $script)
@@ -977,9 +989,29 @@
       $result[$script->load_mode-1][$id] = $script;
     }
-    return $result;
-  }
-
+    return array( self::do_combine($result[0],1), self::do_combine($result[1],2) );
+  }
+
+	private static function do_combine($scripts, $load_mode)
+	{
+		global $conf;
+		if (count($scripts)<2 or !$conf['template_combine_files'])
+			return $scripts;
+		$combiner = new FileCombiner('js');
+		foreach ($scripts as $script)
+		{
+			if ($script->is_remote()) fatal_error("NOT IMPLEMENTED");// TODO - we cannot combine remote scripts
+			$combiner->add( $script->path, $script->version );
+		}
+		if ( $combiner->combine( $out_file, $out_version) )
+		{
+			return array( 'combi' => new Script($load_mode, 'combi', $out_file, $out_version, array() ) );
+		}
+		return null;
+	}
+	
+	// checks that if B depends on A, then B->load_mode >= A->load_mode in order to respect execution order
   private static function check_load_dep($scripts)
   {
+		global $conf;
     do
     {
@@ -999,5 +1031,5 @@
             $changed = true;
           }
-          if ($load==2 && $scripts[$precedent]->load_mode==2 && $script->is_remote() )
+          if ($load==2 && $scripts[$precedent]->load_mode==2 && ($script->is_remote() or !$conf['template_combine_files']) )
           {// we are async -> a predecessor cannot be async unlesss it can be merged; otherwise script execution order is not guaranteed
             $scripts[$precedent]->load_mode = 1;
@@ -1009,6 +1041,6 @@
     while ($changed);
   }
-  
-  
+
+
   private static function fill_well_known($id, $script)
   {
@@ -1049,8 +1081,8 @@
     $ret = $s1->load_mode - $s2->load_mode;
     if ($ret) return $ret;
-    
+
     $ret = $s1->extra['order'] - $s2->extra['order'];
     if ($ret) return $ret;
-    
+
     if ($s1->extra['order']==0 and ($s1->is_remote() xor $s2->is_remote()) )
     {
@@ -1074,5 +1106,5 @@
     $this->type = $type;
   }
-  
+
   static function clear_combined_files()
   {
@@ -1100,5 +1132,4 @@
   function combine(&$out_file, &$out_version)
   {
-    //var_export($this);
     if (count($this->files) == 0)
     {
@@ -1140,9 +1171,7 @@
       $output .= "/* BEGIN $input_file */\n";
       if ($this->type == "css")
-      {
-        $output .= $this->process_css($input_file);
-      }
+        $output .= self::process_css($input_file);
       else
-        $output .= file_get_contents(PHPWG_ROOT_PATH . $input_file);
+				$output .= self::process_js($input_file);
       $output .= "\n";
     }
@@ -1155,5 +1184,15 @@
   }
 
-  private function process_css($file)
+	private static function process_js($file)
+	{
+		$js = file_get_contents(PHPWG_ROOT_PATH . $file);
+		if (strpos($file, '.min')===false and strpos($file, '.packed')===false )
+		{
+			//TODO minify javascript with some php lib from www...
+		}
+		return $js;
+	}
+	
+  private static function process_css($file)
   {
     static $PATTERN = "#url\(\s*['|\"]{0,1}(.*?)['|\"]{0,1}\s*\)#";
@@ -1181,5 +1220,5 @@
       {
         $search[] = $match[0];
-        $replace[] = $this->process_css(dirname($file) . "/$match[1]");
+        $replace[] = self::process_css(dirname($file) . "/$match[1]");
       }
       $css = str_replace($search, $replace, $css);
