--- image_filter.module.orig	Tue Apr 26 17:55:39 2005
+++ image_filter.module	Thu May  5 12:54:29 2005
@@ -1,6 +1,15 @@
 <?php
 // $Id: image_filter.module,v 1.7 2004/12/13 22:38:47 mrowe Exp $
  
+define("IMAGE_FILTER_SHORT_TIP",
+'You may link to images on this site <a href="%explanation-url">using a special syntax</a>');
+
+define("IMAGE_FILTER_LONG_TIP",
+'<p>You may quickly link to image nodes using a special syntax. Each image code will be replaced by a thumbnail linked to the full size image node. Syntax:<blockquote><code>[image:<em>node_id</em> (left|right|top|middle|bottom|absmiddle|texttop|baseline|align=<em>alignment</em>) size=<em>label</em> width=<em>n</em> height=<em>n</em> nolink=(0|1) hspace=<em>n</em> vspace=<em>n</em> border=<em>n</em> class=<em>name</em>]</code></blockquote> Every parameter except <code><em>node_id</em></code> is <em>optional</em>.</p>
+<p>Typically, you will specify one of <code>size</code>, <code>width</code>, or <code>height</code>. If you use <code>size=<em>label</em></code>, where <em>label</em> with one of the image size labels defined on the image settings page, the image size for that label will be used. If you use <code>width=<em>n</em></code> or <code>height=<em>n</em></code>, the image will be scaled to fit the specified width or height. If you specify none of these, a thumbnail image will be used.</p>
+<p>If you specify <code>nolink=1</code>, no link will be created to the image node. The default is to create a link.</p>
+<p>The <code>hspace</code>, <code>vspace</code>, <code>border</code>, and <code>class</code> arguments set the corresponding attributes in the generated <code>img</code> tag.</p>');
+
 function image_filter_help($section = 'admin/help#image_filter') {
   global $base_url;
 
@@ -11,15 +20,15 @@ function image_filter_help($section = 'a
   $output = '';
   switch ($section) {
     case 'admin/help#image_filter':
-      $output  = t('<p>Sometimes, you want to add an image to another node like a blog entry or a story. You may do this by creating an image node in Drupal for the target image, and then referencing that image in your story, blog, etc. To enable this feature and learn the proper syntax, visit the <a href="%filters">filters configuration screen</a>.</p>', array('%filters' => url('admin/filters')));
+      $output = t('<p>Sometimes, you want to add an image to another node like a blog entry or a story. You may do this by creating an image node in Drupal for the target image, and then referencing that image in your story, blog, etc. To enable this feature and learn the proper syntax, visit the <a href="%filters">filters configuration screen</a>.</p>', array('%filters' => url('admin/filters')));
       break;
     case 'admin/modules#description':
       $output = t("Allow users to reference images from other nodes.");
       break;
     case 'filter#short-tip':
-      return t('You may link to images on this site <a href="%explanation-url">using a special syntax</a>', array('%explanation-url' => url('filter/tips', NULL, 'image')));
+      return t(IMAGE_FILTER_SHORT_TIP, array('%explanation-url' => url('filter/tips', NULL, 'image')));
     case 'filter#long-tip':
-      return t('<p>You may quickly link to image nodes using a special syntax. The image code(s) will be replaced by thumbnail linked to full size image node. Syntax: <code>[image:node_id (left|right|top|middle|bottom|absmiddle|texttop|baseline) hspace=n vspace=n border=n width=n height=n]</code>. Every parameter except node_id is <em>optional</em>.</p>');
+      return t(IMAGE_FILTER_LONG_TIP);
   }
 
   return $output;
@@ -46,10 +55,10 @@ function image_filter_filter($op, $delta
  */
 function image_filter_filter_tips($delta = 0, $format = -1, $long = false) {
   if ($long) {
-    return t('<p>You may quickly link to image nodes using a special syntax. The image code(s) will be replaced by thumbnail linked to full size image node. Syntax: <code>[image:node_id (left|right|top|middle|bottom|absmiddle|texttop|baseline) hspace=n vspace=n border=n width=n height=n]</code>. Every parameter except node_id is <em>optional</em>.</p>');
+    return t(IMAGE_FILTER_LONG_TIP);
   }
   else {
-    return t('You may link to images on this site <a href="%explanation-url">using a special syntax</a>', array('%explanation-url' => url('filter/tips', NULL, 'image')));
+    return t(IMAGE_FILTER_SHORT_TIP, array('%explanation-url' => url('filter/tips', NULL, 'image')));
   }
 }
 
@@ -58,87 +67,92 @@ function image_filter_filter_tips($delta
  */
 function image_filter_process($text) {
 
-  // *** Original syntax: [image:NID,(left|center|right)] ***
-  // First we find every tag.
-
-  if (preg_match_all("/\[image:(\d+)(,(left|right|top|middle|bottom|absmiddle|texttop|baseline))?(,(\d+))?(,(\d+))?(,(\d+))?\]/i", $text, $match)) {
-
-    // Then we make the html.
-
-    foreach ($match[1] as $key => $value) {
-      $map[$value] = $key;
-    }
-
-    $result = db_query("SELECT n.nid, n.teaser, i.thumb_path FROM {image} i, {node} n WHERE n.status = 1 AND i.nid = n.nid AND n.nid IN ('" . implode("','", array_map('db_escape_string', $match[1])) . "')");
-
-    while ($img = db_fetch_object($result)) {
-      $n = $map[$img->nid];
-      $img->align = $match[3][$n];
-      $img->hspace = $match[5][$n];
-      $img->vspace = $match[7][$n];
-      $img->border = $match[9][$n];
-      $match[10][$n] = theme("image_inline_img", $img);
-    }
-
-    // PHP (4.3.2) str_replace appears to use some internal order
-    // rather than array index when finding replace elements
-    // corresponding to search elements.  To make sure that the
-    // order of the arrays correspond, we make new copies here.
-
-    foreach ($match[1] as $key => $value) {
-      $mtch[] = $match[0][$key];
-      $repl[] = $match[10][$key];
-    }
-
-    $text = str_replace($mtch, $repl, $text);
-
-  }
-
-  // *** New syntax: [image:node_id (left|right|top|middle|bottom|absmiddle|texttop|baseline) hspace=n vspace=n border=n width=n height=n class=x]
-
-  if (preg_match_all('/\[image:(\d+)\w?(.*?)?\]/i', $text, $match)) {
-
-    // Then we make the html.
-
-    foreach ($match[1] as $key => $value) {
-      $map[$value] = $key;
-    }
-
-    $result = db_query("SELECT n.nid, n.title, i.thumb_path FROM {image} i, {node} n WHERE n.status = 1 AND i.nid = n.nid AND n.nid IN ('" . implode("','", array_map("db_escape_string", $match[1])) . "')");
-
+  // Loop over image tags.
+  preg_match_all("/\[image:(\d+)(\s*,\s*)?([^\[\]]*)\]/i", $text, $matches, PREG_SET_ORDER);
+//  $matches = array_unique($matches); // This doesn't work correctly; need to unique on $matches[][0].
+  foreach ($matches as $match) {
+
+    $args = array();
+    $args['link'] = 1;
+    if (strlen($match[2]) > 0) {
+      // *** Original syntax: [image:NID,align,hspace,vspace,border] ***
+      $a = preg_replace('/\W/', '', preg_split("/\s*,\s*/", $match[3]));
+      $args['align']  = $a[0];
+      $args['hspace'] = $a[1];
+      $args['vspace'] = $a[2];
+      $args['border'] = $a[3];
+    }
+    else {
+      // *** New syntax: [image:node_id (left|right|top|middle|bottom|absmiddle|texttop|baseline|align=alignment) hspace=n vspace=n border=n size=label width=n height=n nolink=(0|1) class=name]
+      if (preg_match("/\b(left|right|top|middle|bottom|absmiddle|texttop|baseline)\b/i", $match[3], $m)) {
+        $args['align'] = $m[1];
+      }
+      $a = preg_split("/\s+/", $match[3]);
+      foreach ($a as $arg) {
+        $pos = strpos($arg, '=');
+        if ($pos) {
+          $name = strtolower(substr($arg, 0, $pos));
+          $value = preg_replace('/\W/', '', substr($arg, $pos + 1));
+          $args[$name] = $value;
+        }
+      }
+    }
+
+    // Loop over the sizes found for this image node and select the best match.
+    $width = $args['width'];
+    $height = $args['height'];
+    $size = $args['size'];
+    if ($size == 'original') { $size = '_original'; }
+    if (!$width && !$height && strlen($size) == 0) { $size = 'thumbnail'; }
+    $best_img = NULL;
+    $result = db_query(db_rewrite_sql("SELECT n.nid, n.title, f.filename, f.filepath FROM {files} f, {node} n WHERE n.status = 1 AND f.nid = n.nid AND n.nid = %d" . ($size ? " AND f.filename LIKE \"" . db_escape_string($size) . "\"" : '')), $match[1]);
     while ($img = db_fetch_object($result)) {
+      $img->filepath = file_create_path($img->filepath);
+      $img->size = getimagesize($img->filepath);
+      if (! $best_img) {
+        $best_img = $img;
+      }
+      if ($width && $img->size[0] >= $width && $img->size[1] >= $height) {
+        if ($img->size[0] < $best_img->size[0] || $best_img->size[0] < $width) {
+          $best_img = $img;
+        }
+      }
+      if ($height && $img->size[1] >= $height && $img->size[0] >= $width) {
+        if ($img->size[1] < $best_img->size[1] || $best_img->size[1] < $height) {
+	  $best_img = $img;
+        }
+      }
+    }
+
+    // If we found a matching image, replace the image code with an <img> tag.
+    if ($best_img) {
+      if (! $width && ! $height) {
+        $best_img->width = $best_img->size[0];
+        $best_img->height = $best_img->size[1];
+      }
+      else if ($width && ! $height) {
+        $best_img->width = $width;
+	$best_img->height = round($best_img->size[1] * $width / $best_img->size[0]);
+      }
+      else if ($height && ! $width) {
+        $best_img->height = $height;
+        $best_img->width = round($best_img->size[0] * $height / $best->img->size[1]);
+      }
+      else {
+        $best_img->width = $width;
+        $best_img->height = $height;
+      }
+
+      $best_img->align = $args['align'];
+      $best_img->hspace = $args['hspace'];
+      $best_img->vspace = $args['vspace'];
+      $best_img->border = $args['border'];
+      $best_img->class = $args['class'];
+      $best_img->link = ($args['nolink'] ? NULL : "node/$best_img->nid");
 
-      $n = $map[$img->nid];
-      preg_match("/(left|right|top|middle|bottom|absmiddle|texttop|baseline)/i", $match[2][$n], $m);
-      $img->align = $m[1];
-      preg_match("/hspace=\"?(\d+)\"?/i", $match[2][$n], $m);
-      $img->hspace = $m[1];
-      preg_match("/vspace=\"?(\d+)\"?/i", $match[2][$n], $m);
-      $img->vspace = $m[1];
-      preg_match("/border=\"?(\d+)\"?/i", $match[2][$n], $m);
-      $img->border = $m[1];
-      preg_match("/width=\"?(\d+)\"?/i", $match[2][$n], $m);
-      $img->width = $m[1];
-      preg_match("/height=\"?(\d+)\"?/i", $match[2][$n], $m);
-      $img->height = $m[1];
-      preg_match("/class=\"?(\w+)\"?/i", $match[2][$n], $m);
-      $img->class = $m[1];
-      $match[10][$n] = theme("image_inline_img", $img);
-
-    }
-
-    // PHP (4.3.2) str_replace appears to use some internal order
-    // rather than array index when finding replace elements
-    // corresponding to search elements.  To make sure that the
-    // order of the arrays correspond, we make new copies here.
-
-    foreach ($match[1] as $key => $value) {
-      $mtch[] = $match[0][$key];
-      $repl[] = $match[10][$key];
+      $image_tag = theme("image_inline_img", $best_img);
+      $text = str_replace($match[0], $image_tag, $text);
     }
-
-    $text = str_replace($mtch, $repl, $text);
-
   }
 
   return $text;
@@ -149,8 +163,10 @@ function image_filter_process($text) {
  * Displays a thumbnail with a link to the image.
  */
 function theme_image_inline_img($img) {
-  global $base_url;
-  return l('<img src="' . ($img->width || $img->height ? url("image/view/$img->nid", 'res=' . $img->width . "x$img->height") : "$base_url/$img->thumb_path") . '"' . ($img->width ? " width=\"$img->width\"" : '') . ($img->height ? " height=\"$img->height\"" : NULL) . ($img->align ? " align=\"$img->align\"" : '') . ($img->border ? " border=\"$img->border\"" : '') . ($img->hspace ? " hspace=\"$img->hspace\"" : '') . ($img->vspace ? " vspace=\"$img->vspace\"" : '') . " alt=\"$img->title\"" . ($img->class ? " class=\"$img->class\"" : '') . " />", "node/$img->nid");
+  $imgtag = '<img src="' . $img->filepath . '"' . ($img->width ? " width=\"$img->width\"" : '') . ($img->height ? " height=\"$img->height\"" : NULL) . ($img->align ? " align=\"$img->align\"" : '') . ($img->border ? " border=\"$img->border\"" : '') . ($img->hspace ? " hspace=\"$img->hspace\"" : '') . ($img->vspace ? " vspace=\"$img->vspace\"" : '') . " alt=\"$img->title\"" . ($img->class ? " class=\"$img->class\"" : '') . " />";
+  return ($img->link
+    ? l($imgtag, $img->link, array(), NULL, NULL, FALSE, TRUE)
+    : $imgtag);
 }
 
 ?>
