<?php if (!defined('PmWiki')) exit();
#ini_set('display_errors', 'On');
#error_reporting(E_ALL | E_STRICT);

/*
******************************************************************************************
*                                                                                        *
*    Yet Another Gallery tool v2.0 - Create image galleries in PmWiki                    *
*    Copyright (C) Jul 04, 2012  Subhrajit Bhattacharya                                  *
*                                                                                        *
*    This program is free software: you can redistribute it and/or modify                *
*    it under the terms of the GNU General Public License as published by                *
*    the Free Software Foundation, either version 3 of the License, or                   *
*    (at your option) any later version.                                                 *
*                                                                                        *
*    This program is distributed in the hope that it will be useful,                     *
*    but WITHOUT ANY WARRANTY; without even the implied warranty of                      *
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                       *
*    GNU General Public License for more details <http://www.gnu.org/licenses/>.         *
*                                                                                        *
*                                                                                        *
*    Contact: subhrajit@gmail.com, http://www.subhrajit.net/                             *
*                                                                                        *
*                                                                                        *
******************************************************************************************
*/

/* Syntax:
       YAG [option1=o1, option2=o2, ...] { url_or_path | caption  &&  url_or_path | caption  &&  ... }
       
   See http://www.pmwiki.org/wiki/Cookbook/YAG for more details
   
*/

Markup(
    'YAG',
    '<fulltext',
    "/YAG\\s*\\[(.*?)\\]\\s*\\{(.*?)\\}/esi",
    "Keep(YetAnotherGalleryHTML(PSS('$1'),PSS('$2'),\$pagename))" );

// Folder options
SDV($YetAnotherGallery->cache, $FarmD.'/pub/YetAnotherGalleryCache/' );
$AlansPubDirUrl='http://'.$_SERVER['HTTP_HOST'].'/wiki/pub';
SDV($YetAnotherGallery->cacheURL, $PubDirUrl.'/YetAnotherGalleryCache/' );
  
// Advanced path and folder options
#Original SDV($YetAnotherGallery->fetchLocalFileLocally, true ); // If an image file appears to be local, try to fetch it as a local file instead of a URL.
SDV($YetAnotherGallery->fetchLocalFileLocally, true ); // If an image file appears to be local, try to fetch it as a local file instead of a URL.
SDV($YetAnotherGallery->ShellPWD, trim(shell_exec("pwd")) );

// Default values
SDV($YetAnotherGallery->cols, 4);
SDV($YetAnotherGallery->maxrows, 5);
SDV($YetAnotherGallery->imgmaxwidth, 150);
SDV($YetAnotherGallery->imgmaxheight, 250);
SDV($YetAnotherGallery->convertoptions, "-resize {imgmaxwidth}x{imgmaxheight}" );
SDV($YetAnotherGallery->thumbtype, "jpg" );
SDV($YetAnotherGallery->containerwidth, 500 ); // Effective only for 'popup' and 'div'
SDV($YetAnotherGallery->containerheight, 600 ); // Effective only for 'popup' and 'div'
SDV($YetAnotherGallery->style, "hiddencaption,popup" ); // Do not use 'default' in this list

SDV($YetAnotherGallery->captiontype, 'linked,basichtml'); // Allowed values: 'linked'/'free' & 'nohtml'/'wiki'/'basichtml'/'fullhtml'
SDV($YetAnotherGallery->allowUserCaptiontype, true);

SDV($YetAnotherGallery->allowCustomPHPhandler, false); // Allow use of custom. WARNING: Potential hazzard if enabled.
SDV($YetAnotherGallery->allowRefreshCacheInGETparam, false); // Allows passing of per-page GET parameter 'YAGrefresh=yes' to refresh cache for the page

// ---------------------------------------------
// CSS styles
SDVA($YetAnotherGallery->cellStyle, array(
                        'default' => "border: solid 2px #cccccc;"
                         ) );
SDVA($YetAnotherGallery->imgDivStyle, array(
                        'default' => "text-align: center; vertical-align: middle; margin: 0; padding: 0; 
                                      cursor:hand; cursor:pointer; ",
                        'rightcaption' => "text-align: center; vertical-align: middle; margin: 0; padding: 0; display:inline" 
                         ) );
SDVA($YetAnotherGallery->imgStyle, array(
                        'default' =>      "border: 1px solid; border-color: #aaaabb #bbbbcc #bbbbcc #aaaabb; ",
                        'rightcaption' => "border: 1px solid; border-color: #aaaabb #bbbbcc #bbbbcc #aaaabb; float:left;"
                         ) );
SDVA($YetAnotherGallery->captionDiv, array(
                        'default' =>       "",
                        'hiddencaption' => "<div style='position:relative; width:100%;'>
                                                <div style='width:100%; position:absolute; width:100%; display:none; 
                                                            padding: 5px; left: -6px; top: -5px; border: 1px solid; 
                                                            border-color: #ccc #888 #888 #ccc; color: #eeeeff; background-color: #333338;'>
                                                                <b>\$Caption</b>
                                                </div></div>",
                        'rightcaption' => "<div style='margin: 0px 10px; text-align:left; float:left;'>\$Caption</div>" 
                         ) );
// On-page Javascripts
SDVA($YetAnotherGallery->imgMouseOverJavascript, array(
                        'default' =>       "void(0);",
                        'hiddencaption' =>  "this.getElementsByTagName('img')[0].style.opacity=0.6;
                                            this.getElementsByTagName('img')[0].style.filter='alpha(opacity=60)';
                                            this.getElementsByTagName('div')[0].getElementsByTagName('div')[0].style.display='block';" 
                         ) );
SDVA($YetAnotherGallery->imgMouseOutJavascript, array(
                        'default' =>       "void(0);",
                        'hiddencaption' => "this.getElementsByTagName('img')[0].style.opacity=1.0;
                                           this.getElementsByTagName('img')[0].style.filter='alpha(opacity=100)';
                                           this.getElementsByTagName('div')[0].getElementsByTagName('div')[0].style.display='none';" 
                         ) );
// Header and footer of gallery
SDVA($YetAnotherGallery->GalleryDivContainerFmt, array(
                         'default' => "",
                         'div' =>     "<center><div style='margin:0;padding:0;overflow:hidden;position:relative;'
                                      id='YAGdivContainer_\$GalleryName'>
                                      <img id='YAGdivContainerImg_\$GalleryName' height=\$containerheight style = 'border: 5px solid #ddddee;' />
                                      <div id='YAGdivContainerCaption_\$GalleryName' style='font-weight:bold;'></div>
                                      <hr style='border:1px solid #bbb;background-color:#eee;height:5px;'/>
                                      </div></center>",
                         'lfloat'=>   "<div style='float:left;margin:5px;padding:0;overflow:hidden;position:relative;'
                                      id='YAGdivContainer_\$GalleryName'><center>
                                      <div id='YAGdivContainerCaption_\$GalleryName' style='font-weight:bold;margin:5px;'></div>
                                      <img id='YAGdivContainerImg_\$GalleryName' width=\$containerwidth style = 'border: 5px solid #ddddee;' />
                                      </center></div>"
                          ) );
SDVA($YetAnotherGallery->GalleryHeaderFmt, array(
                        'default' =>      "<div style='font-weight: bold; color:#999999; padding: 5px;'>Displaying page \$PageNo of 
                                           <a href='#YAGlink_\$GalleryName'>\$PagesCount</a></div>",
                        'nohead' =>       "" 
                         ) );
SDVA($YetAnotherGallery->GalleryFooterFmt, array(
                        'default' =>          array('start'=>"<a name='YAGlink_\$GalleryName'></a>&nbsp;<br/>Pages: ",
                                                    'page-prefix'=>"&nbsp;", 'page-suffix'=>"&nbsp;",
                                                    'current-page-prefix'=>"<b>&nbsp;", 'current-page-suffix'=>"&nbsp;</b>",
                                                    'end'=>""),
                         'nofoot' =>          array('start'=>"<div style='display:none;'>",
                                                    'page-prefix'=>"", 'page-suffix'=>"",
                                                    'current-page-prefix'=>"", 'current-page-suffix'=>"",
                                                    'end'=>"</div>")
                         ) );


// Constants
SDVA($YetAnotherGallery->URLcharacters, 
     array('!', '*', "'", "(", ")", ";", "@", "&", "=", "+", "$", ",", "?", "%", "#", "[", "]", "<", ">") );
SDVA($YetAnotherGallery->URLcodes, 
     array('%21', '%2A', '%27', '%28', '%29', '%3B', '%40', '%26', '%3D', '%2B', '%24', '%2C', '%3F', '%25', '%23', '%5B', '%5D', '%3C', '%3E') );

// ==============================================
// JavaScripts for handling the gallery show

SDVA($YetAnotherGallery->HandleClick_FunctionContent, array ( // variables: url, caption, num, GalleryName
            'default' => " window.location = url; ",
            'popup' =>   " var thepop = window.open(url,'YAGwindow', ".
                         "    'top=0,left=0,width=\$containerwidth,height=\$containerheight,".
                         "     location=1,menubar=0,resizable=1,scrollbars=1,status=1,toolbar=0' ); ".
                         " thepop.focus(); " ,
            'self' =>    " window.location = url; ",
            'div' =>     " var containerImg = document.getElementById('YAGdivContainerImg_'+GalleryName); ".
                         " var containerCaption = document.getElementById('YAGdivContainerCaption_'+GalleryName); ".
                         "     containerImg.style.opacity=0.4; containerImg.style.filter='alpha(opacity=40)'; ".
                         "     containerCaption.innerHTML='<font color=\\'#888\\'>Loading image...</font>'; ".
                         "     var pic = new Image(); pic.src = url;".
                         "     if(pic.complete) donePic(); else pic.onload= donePic;".
                         "     function donePic() { containerImg.src = pic.src; ".
                         "          containerImg.style.opacity=1.0; containerImg.style.filter='alpha(opacity=100)'; ".
                         "          containerCaption.innerHTML = caption; } ",
            'lfloat' =>  " var containerImg = document.getElementById('YAGdivContainerImg_'+GalleryName); ".
                         " var containerCaption = document.getElementById('YAGdivContainerCaption_'+GalleryName); ".
                         "     containerImg.style.opacity=0.4; containerImg.style.filter='alpha(opacity=40)'; ".
                         "     containerCaption.innerHTML='<font color=\\'#888\\'>Loading image...</font>'; ".
                         "     var pic = new Image(); pic.src = url;".
                         "     if(pic.complete) donePic(); else pic.onload= donePic;".
                         "     function donePic() { containerImg.src = pic.src; ".
                         "          containerImg.style.opacity=1.0; containerImg.style.filter='alpha(opacity=100)'; ".
                         "          containerCaption.innerHTML = caption; } "
            ) );

// ==============================================

function YetAnotherGalleryHTML($optionString, $imagesString, $pagename)
{
    global $YetAnotherGallery, $_GET, $ScriptUrl, $UploadDir, $UploadPrefixFmt;
    SDV($YetAnotherGallery->PmwikiUrl, dirname($ScriptUrl) );
    
    // -------------------------------------------------
    // Parse the markup
    
    $YAGoptions = array('cols'=>''.$YetAnotherGallery->cols,
                        'maxrows'=>''.$YetAnotherGallery->maxrows,
                        'imgmaxwidth'=>''.$YetAnotherGallery->imgmaxwidth,
                        'imgmaxheight'=>''.$YetAnotherGallery->imgmaxheight,
                        'convertoptions'=>$YetAnotherGallery->convertoptions,
                        'style'=>$YetAnotherGallery->style,
                        'containerwidth'=>$YetAnotherGallery->containerwidth,
                        'containerheight'=>$YetAnotherGallery->containerheight,
                        'captiontype'=>$YetAnotherGallery->captiontype,
                        'urlbase'=>'',
                        'refreshcache'=>'yes'  );
#			'refreshcache'=>'no'  );

    $optionsarray = ParseArgs_YAG($optionString);
    foreach ($optionsarray as $k=>$v) $YAGoptions[$k] = $v;
    // Version compatibility:
        if( isset($optionsarray['container']) && !isset($optionsarray['style']) )
            $YAGoptions['style'] = $YAGoptions['style'] . $optionsarray['container'];
    
    // security checks
    $YAGoptions['cols'] = "".intval($YAGoptions['cols']);
    $YAGoptions['maxrows'] = "".intval($YAGoptions['maxrows']);
    $YAGoptions['imgmaxwidth'] = "".intval($YAGoptions['imgmaxwidth']);
    $YAGoptions['imgmaxheight'] = "".intval($YAGoptions['imgmaxheight']);
    $YAGoptions['convertoptions'] = str_replace(';','',$YAGoptions['convertoptions']);
    $YAGoptions['containerwidth'] = "".intval($YAGoptions['containerwidth']);
    $YAGoptions['containerheight'] = "".intval($YAGoptions['containerheight']);
    $YAGoptions['refreshcache'] = str_replace(';','',$YAGoptions['refreshcache']);
    if ( !$YetAnotherGallery->allowUserCaptiontype ) 
        $YAGoptions['captiontype']=$YetAnotherGallery->captiontype;
    
    $YAGoptions['convertoptionsFull'] = str_replace( array("{imgmaxwidth}","{imgmaxheight}"), 
                                                     array($YAGoptions['imgmaxwidth'],$YAGoptions['imgmaxheight']),
                                                     $YAGoptions['convertoptions'] );

    if ( !isset($YAGoptions['name']) )
        $YAGoptions['name'] = "";
    
    if ( isset($_GET["YAGpage_".$YAGoptions['name']]) )
        $YAGpageno = $_GET["YAGpage_".$YAGoptions['name']];
    else
        $YAGpageno = 1;
    
    $PageNo = $YAGpageno;
    $GalleryName = $YAGoptions['name'];
    $containerheight = $YAGoptions['containerheight'];
    $containerwidth = $YAGoptions['containerwidth'];

    // Check and set styles
    $YAGoptions['style'] = $YAGoptions['style'];
    foreach(array("cellStyle", "imgDivStyle", "imgStyle", "captionDiv", "imgMouseOverJavascript", 
                  "imgMouseOutJavascript", "GalleryDivContainerFmt", 
                  "GalleryHeaderFmt", "GalleryFooterFmt", "HandleClick_FunctionContent") as $p) {
        $YAGstyleVars->{$p} = $YetAnotherGallery->{$p}['default'];
        foreach($YetAnotherGallery->{$p} as $k=>$v) 
            if (strrpos($YAGoptions['style'], $k)!==false)
                $YAGstyleVars->{$p} = $v;
    }

    
    $containerHTML = $YAGstyleVars->GalleryDivContainerFmt;
    
    $YAGcols = intval($YAGoptions['cols']);
    $YAGmaxrows = intval($YAGoptions['maxrows']);
    if ($YAGmaxrows <=0 )
        $YAGmatrixCount = 10000000;
    else
        $YAGmatrixCount = $YAGcols * $YAGmaxrows;
    $YAGcolwidth = 100 / $YAGcols;
    
    // -------------------------------------------------
    // Initiate the JavaScript
    $outJS = "\n<script type=\"text/javascript\">";
    
    // The HandleYAGclick function
    $outJS .= "function HandleYAGclick_".$GalleryName."(url,caption,num) { var GalleryName='".$GalleryName."';";
    $outJS .= str_replace(array("\$containerwidth","\$containerheight"),array($containerwidth,$containerheight),
                           $YAGstyleVars->HandleClick_FunctionContent );
    $outJS .= "}";
    
    // ---------------------------------------------
    
    $StartImage = $YAGmatrixCount*($YAGpageno-1);
    $EndImage = $YAGmatrixCount*$YAGpageno - 1;
    
    $YAGimages = array();
    $imagesString = str_replace("<:vspace>", "\n", $imagesString);
    
    $imagesarray = explode("&&", htmlspecialchars_decode($imagesString));
    
    $imgParsedNo = -1;
    foreach ($imagesarray as $thisImage)
    {
        $thisImage = trim($thisImage);
        if (empty($thisImage))
            continue;
    
        list($imageURL,$imageCaption) = explode('|', $thisImage, 2);
        
        $imageURL = trim($imageURL);
        if (substr($imageURL,0,2) == "--")
            $imageURL = trim(substr($imageURL,2));
        else
            $imageURL = trim($YAGoptions['urlbase']).$imageURL;
          
        $subs = array();
        $urls = array();
        $paths = array();
        if (preg_match("/\\[(.*)]/i",$imageURL,$matches) > 0)
        {
            $matchParts0 = explode("<<", $matches[1]);
            
            if (count($matchParts0) > 1) // regular substitution wildcard
            {
                $sprintfString = $matchParts0[0];
                $matchParts = explode(";", $matchParts0[1]);
                foreach ($matchParts as $vv)

                {
                    $thisSubs = ParseWildcard_YAG($sprintfString,$vv);
                    $subs = array_merge($subs, $thisSubs);
                    
                    foreach ($thisSubs as $thisSub)
                    {
                        $theurl = trim(str_replace($matches[0], $thisSub, $imageURL));
                        $theurl = MakeLink($pagename, str_replace($YetAnotherGallery->URLcharacters, $YetAnotherGallery->URLcodes, $theurl),
                                            "","","\$LinkUrl");
                        $theurl = str_replace("%25", "%", $theurl);
                        $urls[] = $theurl;
                        $paths[] = GetAbsShellPathFromURL_YAG($theurl, true);
                    }
                }
            }
            else // attempt local folder search glob
            {
                $imageURLsubs = trim(str_replace($matches[0],$matches[1],$imageURL));
                if (substr($imageURLsubs,0,7) == "Attach:")
                {
                    $imageURLsubs = substr($imageURLsubs,7); // remove leading "Attach:"
                    $thispatparts = pathinfo($imageURLsubs);
                    $thispagename = $thispatparts['dirname'];
                    $uploaddir = FmtPageName("$UploadDir$UploadPrefixFmt", $thispagename);
                    
                    $stringtoglob = $YetAnotherGallery->ShellPWD."/".$uploaddir."/".$thispatparts['basename'];
                }
                else if ( ($globstr=GetAbsShellPathFromURL_YAG($imageURLsubs,false)) )
                    $stringtoglob = $globstr;

                else
                    $stringtoglob = $imageURLsubs;
                
                $thisPaths = glob($stringtoglob);
                $paths = array_merge($paths, $thisPaths);
                foreach ($thisPaths as $thisPath)
                {
                    $theurl = GetURLfromShellPath_YAG($thisPath);
		    
                    $urls[] = $theurl;
                    
                    $pathparts = explode($matches[1], $stringtoglob);
                    $thissubs = $thisPath;
                    $thissubs = (substr($thissubs,0,strlen($pathparts[0]))==$pathparts[0]) ? substr($thissubs,strlen($pathparts[0])) : $thissubs;
                    $thissubs = (substr($thissubs,-strlen($pathparts[1]))==$pathparts[1]) ? substr($thissubs,0,-strlen($pathparts[1])) : $thissubs;
                    $subs[] = $thissubs;
                }
            }
        }
       else
        {
	    $subs[] = "";
	     $theurl = 'http://'.$_SERVER['HTTP_HOST'];

		$alanslimit=1;
		$alans3=preg_split('/www/',$imageURL,-1,PREG_SPLIT_OFFSET_CAPTURE);

		$theurl=$theurl.$alans3[1][0];

            $theurl = str_replace("%25", "%", $theurl);
            $urls[] = $theurl;
            
            $paths[] = GetAbsShellPathFromURL_YAG($theurl, true);

        }

	$subsC = array();
        if ( ( strpos($YAGoptions['captiontype'],'wiki')!==false && preg_match("/[^[]\\[([^[].*[^\\]])][^\\]]/i",$imageCaption,$matchesC) > 0 ) || 
                ( strpos($YAGoptions['captiontype'],'wiki')===false && preg_match("/\\[(.*)]/i",$imageCaption,$matchesC) > 0) )
        {
            if ($matchesC[1]=="*")
                $subsC = $subs;
            else
            {
                $matchPartsC0 = explode("<<", $matchesC[1]);
                $sprintfStringC = $matchPartsC0[0];
                $matchPartsC = explode(";", $matchPartsC0[1]);
                foreach ($matchPartsC as $vvC)
                {
                    $vvC = trim($vvC);
                    if (preg_match("/\\*(\d?)/i",$vvC,$matchesStarC)>0)
                    {
                        $startInd = count($subsC);
                        if (isset($matchesStarC[1]) && !empty($matchesStarC[1]))
                            $endInd = $startInd+intval($matchesStarC[1])-1;
                        else
                            $endInd = count($subs)-1;
                        for ($cc=$startInd; $cc<=min($endInd,count($subs)-1); $cc++)
                            $subsC[$cc] = str_replace($matchesStarC[0],$subs[$cc],$vvC);
                    }
                    elseif (preg_match("/^\\.(\d?)/i",$vvC,$matchesStarC)>0)
                    {
                        $startInd = count($subsC);
                        if (isset($matchesStarC[1]) && !empty($matchesStarC[1]))
                            $endInd = $startInd+intval($matchesStarC[1])-1;
                        else
                            $endInd = count($subs)-1;
                        for ($cc=$startInd; $cc<=min($endInd,count($subs)-1); $cc++)
                            $subsC[$cc] = str_replace($matchesStarC[0],"",$vvC);
                    }
                    else
                        $subsC = array_merge($subsC, ParseWildcard_YAG($sprintfStringC,$vvC));
                        
                    if (count($subsC) >= count($subs))
                    {
                        $subsC = array_slice($subsC,0,count($subs));
                        break;
                    }
                }
            }
        }
        $subsC = array_pad($subsC, count($subs)-count($subsC), "");
            
        foreach ($subs as $kk=>$thisSub)
        {
            $imgParsedNo++;
            if ($imgParsedNo<$StartImage || $imgParsedNo>$EndImage)
            {
                $YAGimages[] = false;
                continue;
            }
            $ThisImageArray->URL = $urls[$kk];
    
            if ($YetAnotherGallery->fetchLocalFileLocally && $paths[$kk])
                $ThisImageArray->path = $paths[$kk];
	
	    else
                $ThisImageArray->path = $ThisImageArray->URL;
                $ThisImageArray->Caption = str_replace($matchesC[0],$subsC[$kk],$imageCaption);
            if (strpos($YAGoptions['captiontype'],'nohtml')!==false) 
                $ThisImageArray->Caption = trim(str_replace(array("\\n","\\r"),"<br/>", strip_tags($ThisImageArray->Caption) ));
            elseif (strpos($YAGoptions['captiontype'],'wiki')!==false) 
                $ThisImageArray->Caption = MarkupToHTML($pagename, trim(str_replace(array("\\n","\\r"),"[[<<]]", $ThisImageArray->Caption)) );
            elseif (strpos($YAGoptions['captiontype'],'basichtml')!==false) 
                $ThisImageArray->Caption = trim(str_replace(array("\\n","\\r"),"<br/>", strip_tags($ThisImageArray->Caption, 
                                                      "<br/><br><b><big><em><i><font><small><strong><sup><sub><ins><del><code><pre>") ));
            $ThisImageArray->Caption = str_replace(array("\n","\r"), "", $ThisImageArray->Caption);
            $YAGimages[] = clone($ThisImageArray);
        }
    }
        
    $TotalCount = count($YAGimages);
    $EndImage = min($YAGmatrixCount*$YAGpageno, $TotalCount) - 1;
    $PagesCount = floor(($TotalCount-1)/$YAGmatrixCount) + 1;
    $ThisPageRowCount = floor(($EndImage-$StartImage) / $YAGcols) + 1;
    
    // -------------------------------------------------
    // Check the cache

    if (!file_exists($YetAnotherGallery->cache))
        mkdir($YetAnotherGallery->cache);
    chmod($YetAnotherGallery->cache, 0777);
    #chmod($YetAnotherGallery->cache, 0755);    

    // -------------------------------------------------
    // Create the HTML
    
    $outHTML = "<a name=\"YAGstart_".$GalleryName."\"></a>";

    // Only if it's a 'div' container, add the required HTML and Javascript
    if (!empty($containerHTML))
    {
        eval("\$containerString = \"".$containerHTML."\";");
        $outHTML .= $containerString;
        $outJS .= "\nwindow.onload = HandleYAGclick_".$GalleryName."('".$YAGimages[$StartImage]->URL."','".$YAGimages[$StartImage]->Caption."',".$StartImage."); ";
    }
    
    $outHTML .= "\n<table class='YAGtable' cellspacing=2 cellpadding=2 style='display:inline !important; width:auto !important;'>";


    if ($YAGmaxrows > 0)
    {
        eval("\$headerString = \"".$YAGstyleVars->GalleryHeaderFmt."\";");
        $outHTML .= "<tr><td align=left colspan=".$YAGcols.">".$headerString."</td></tr>";
    }

    $imgNum = $StartImage;

    for ($r=1; $r<=$ThisPageRowCount; $r++)
    {
        $outHTML .= "<tr>";
        for ($c=1; $c<=$YAGcols; $c++)
        {
            $outHTML .= "<td valign=bottom style='".$YAGstyleVars->cellStyle."; ".
                        "text-align: center; vertical-align: middle;' width='".$YAGcolwidth."%' align='center' valign='middle'>";
            if ($imgNum <= $EndImage)
            {
                $ImgThumbURL = YetAnotherGalleryReadCache($YAGimages[$imgNum]->path, $YAGoptions);

	        if (substr($ImgThumbURL,0,7)=="ERROR: " && $YAGimages[$imgNum]->path!=$YAGimages[$imgNum]->URL)
                    $ImgThumbURL = YetAnotherGalleryReadCache($YAGimages[$imgNum]->URL, $YAGoptions);
                
                $YAGimages[$imgNum]->thumbURL = $ImgThumbURL;
		
		
		
                if (substr($ImgThumbURL,0,7)=="ERROR: ")
                    $ImgTag = "<div style='".$YAGstyleVars->imgStyle."; font-size:10pt'>".str_replace("\n","<br />",htmlspecialchars($ImgThumbURL))."</div>";
                else
                    $ImgTag = "<img style='".$YAGstyleVars->imgStyle."' src=\"".$ImgThumbURL."\" />";
                $outHTML .= "<div id='YAG_".$YAGoptions['name']."_".$imgNum."' style='".$YAGstyleVars->imgDivStyle."' 
                              onMouseOver=\"javascript: ".$YAGstyleVars->imgMouseOverJavascript."\"
                              onMouseOut=\"javascript: ".$YAGstyleVars->imgMouseOutJavascript."\" >".
                                "<a href='javascript:void(0);' onClick=\"javascript: HandleYAGclick_".$GalleryName.
                                             "('".$YAGimages[$imgNum]->URL."','".str_replace(array("'","\""),array("\\'","\\'"),$YAGimages[$imgNum]->Caption)."',".$imgNum.");\">".
                                  $ImgTag.
                                  ((strpos($YAGoptions['captiontype'],'linked')!==false)?"":"</a>").
                                  str_replace("\$Caption",$YAGimages[$imgNum]->Caption,$YAGstyleVars->captionDiv).
                                  ((strpos($YAGoptions['captiontype'],'linked')!==false)?"</a>":"").
                            "</div>";

            }
            else
                $outHTML .= "&nbsp;";
            $outHTML .= "</td>";
            $imgNum++;
        }
        $outHTML .= "</tr>";
    }
    if ($YAGmaxrows > 0)
    {
        eval("\$evalStr = \"".$YAGstyleVars->GalleryFooterFmt['start']."\";");
        $outHTML .= "<tr><td align=center colspan=".$YAGcols.">".$evalStr;
        $YAGlist_GET = $_GET;
        unset($YAGlist_GET["YAGpage_".$YAGoptions['name']]);
        for ($p=1; $p<=$PagesCount; $p++)
        {
            $YAGlist_GET["YAGpage_".$YAGoptions['name']] = $p;
            $getString = "";
            foreach ($YAGlist_GET as $k=>$v)
                $getString .= $k."=".$v."&";
            $getString = substr($getString,0,-1);
            if ($p==$YAGpageno)
                $outHTML .= "<a href='?".$getString."#YAGstart_".$GalleryName."'>".
                            $YAGstyleVars->GalleryFooterFmt['current-page-prefix'].$p.
                            $YAGstyleVars->GalleryFooterFmt['current-page-suffix']."</a>";
            else
                $outHTML .= "<a href='?".$getString."#YAGstart_".$GalleryName."'>".
                            $YAGstyleVars->GalleryFooterFmt['page-prefix'].$p.
                            $YAGstyleVars->GalleryFooterFmt['page-suffix']."</a>";
        }
        $outHTML .= $YAGstyleVars->GalleryFooterFmt['end']."</td></tr>";
    }
    $outHTML .= "</table>";
    
    $outJS .= "</script>\n";
    
    // ---------------------------------------------------------------------------------------
    if ( $YetAnotherGallery->allowCustomPHPhandler && isset($YAGoptions['customPHPhandler']) )
    {
        // $YAGoptions['customPHPhandler'] is a function name of the form:  fun( &$images, &$options )
        //      $images is an array of objects with keys 'URL', 'Caption' and 'thumbURL'
        return ( $YAGoptions['customPHPhandler']($YAGimages, $YAGoptions) );
    }
    else
        return $outHTML.$outJS;
}

function YetAnotherGalleryReadCache($RawURL, &$YAGoptions) // Can be used as an independent function!
{
    global $YetAnotherGallery;
    
    $RawURLmd5 = md5($RawURL.$YAGoptions['name']);

    $CacheFileName = $RawURLmd5.'.'.$YetAnotherGallery->thumbtype;
    
    if ($YAGoptions['refreshcache']=='yes' || (array_key_exists('YAGrefresh',$_GET) && $_GET['YAGrefresh']="yes"))
        $ForceRefresh = true;
    else
        $ForceRefresh = false;
    
    if ($ForceRefresh && file_exists($YetAnotherGallery->cache.$CacheFileName))
        @unlink($YetAnotherGallery->cache.$CacheFileName);
    
    if ($ForceRefresh || !file_exists($YetAnotherGallery->cache.$CacheFileName))
    {
        $sysCommand = "convert ".$RawURL." ".
                      $YAGoptions['convertoptionsFull'].
                      " ".$YetAnotherGallery->cache.$CacheFileName.
                      " 2>&1";
        $shellOut = shell_exec($sysCommand);
   	
    }
    
    if (file_exists($YetAnotherGallery->cache.$CacheFileName))
        return ($YetAnotherGallery->cacheURL.$CacheFileName);
    else
        return "ERROR: ".$shellOut;
}

// ==================================

function ParseArgs_YAG($x,
                       $optpat = "(?>(\\w+)\\s*[:=]\\s*)",
                       $valpat = "(\"[^\"]*\"|'[^']*'|[^,;]+|\\S+)",
                       $stripquotepat = "/^\\s*(['\"])?(.*)\\1\\s*[,;]?\\s*$/"  )
{
    $z = array();
    preg_match_all("/($optpat|[-+])$valpat/", $x, $terms, PREG_SET_ORDER);
    foreach($terms as $t)
    {
        $v = preg_replace($stripquotepat, '$2', $t[3]);
        if ($t[2]) { $z['#'][] = $t[2]; $z[$t[2]] = $v; }
        else { $z['#'][] = $t[1]; $z[$t[1]][] = $v; }
        $z['#'][] = $v;
    }
    return $z;
}

// ==================================

function ParseWildcard_YAG($sprintfStr, $CardStr)
{
    $CardParts = explode(":", $CardStr);
    $params = explode(",", $CardParts[1]);
    foreach ($params as $k=>$v)
    {
        $params[$k] = trim($params[$k]);
        if (is_numeric($params[$k]))
            eval("\$params[".$k."] = ".$params[$k].";");
    }
    
    $arr = array();
    switch (strtolower(trim($CardParts[0])))
    {
        case "range": // range: start, end, step
            if (count($params) >= 3)
                $arr = range($params[0],$params[1],$params[2]);
            else
                $arr = range($params[0],$params[1]);
            break;
        case "list": // list: item1, item2, item3, ...
            foreach ($params as $v) $arr[]=$v;
            break;
    }
    
    $outArr = array();
    foreach ($arr as $a)
        $outArr[] = sprintf($sprintfStr, $a);
    
    return ($outArr);
}

// ==================================

function GetAbsShellPathFromURL_YAG($RawURL, $check_exist=false)
{
    global $YetAnotherGallery;
    $RawURL = trim(urldecode($RawURL));
    if ( substr($RawURL,0,strlen($YetAnotherGallery->PmwikiUrl)) == $YetAnotherGallery->PmwikiUrl )
        $LocalPath = $YetAnotherGallery->ShellPWD . substr($RawURL, strlen($YetAnotherGallery->PmwikiUrl));
    else
        $LocalPath = false;
    if ($check_exist && !file_exists($LocalPath))
        $LocalPath = false;
    return $LocalPath;
}

function GetURLfromShellPath_YAG($RawPath)
{
    global $YetAnotherGallery, $EnableDirectDownload, $UploadUrlFmt, $UploadPrefixFmt;
    
    if ( substr($RawPath,0,strlen($YetAnotherGallery->ShellPWD)) == $YetAnotherGallery->ShellPWD )
        $RawPath = substr($RawPath,strlen($YetAnotherGallery->ShellPWD));
    $RawPath = trim($RawPath, "/\\");
    
    $downURL = $YetAnotherGallery->PmwikiUrl ."/". $RawPath;
    $downURLparts = pathinfo($downURL);
    
    // Test if this is the upload folder
    if ( substr($downURLparts['dirname'],0,strlen("$UploadUrlFmt/"))=="$UploadUrlFmt/" )
        $returl = FmtPageName(
                        IsEnabled($EnableDirectDownload, 1)? "$UploadUrlFmt$UploadPrefixFmt/": "\$PageUrl?action=download&amp;upname=", 
                            substr($downURLparts['dirname'],strlen("$UploadUrlFmt/")) ) . $downURLparts['basename'];
    else
        $returl = $downURL;
        
    return $returl;
}

?>