<%--

  // Params
  Images:            directory holding images (non-abs path is attempted to be resolved to the pics gallery folder)
  Thumbnails:        
  Viewer:             url to viwer, with params: .../elements/PhotoViewer.jsp?f=${Images}&i=${AbsPath}
  ViewerWindow:       java script to open view window, takes one param ${URL} as spec'ed by Viewer
  Target: 
  Columns:           default = 0
  Rows:              default = 0
  ThumbnailPrefix:   ""
  ThumbnailSuffix:   ""
  ThumbnailSize:     default = 128
  EnforceSize:       false (default), true, square

  // Props
  Images:            required
  Thumbnails:        required (if this is not an absolute path, then it defaults to either a folder with the given name
                     inside the images folder or a folder with the image folder + _ + given name parallel to the image folder. 
                     E.g. Images=/foo/bar and Thumbnails=thumbs, will either evaluate to /foo/bar/thumbs or /foo/bar_thumbs,
                     if neither of these exists an exception will be thrown (if both exists the former takes precedence.)
  Columns:
  Rows:
  ThumbnailPrefix:
  ThumbnailSuffix:
  ThumbnailSize:    if making thumbs this should be set for safety
  EnforceSize:
  MakeThumbnails:
  DefaultThumbnail: system/modules/com.codedroids.templatebuilder/resources/missing_thumb.gif;  

--%><%@ 
page session="false" %><%@ 
page import="java.lang.*,java.util.*,java.io.*,java.awt.image.*,java.awt.*,java.awt.geom.*,java.awt.font.*" %><%@ 
page import="com.opencms.flex.jsp.*,com.opencms.file.*,com.opencms.template.*,com.opencms.flex.util.CmsMessages,com.opencms.core.*" %><%@
page import="com.codedroids.oc5.*" 
%><%!
  BufferedImage thumbnailFromImage(BufferedImage image, int width, int height)
  {
    //ColorModel cm = image.getColorModel();
    int h = image.getHeight();
    int w = image.getWidth();
    int t = image.getType(); // This is typically TYPE_3BYTE_BGR (5)
    int th_h = height;
    int th_w = width;
    if(h > w)
      th_w = (th_w * w) / h;
    else if (w > h)
      th_h = (th_h * h) / w;
    BufferedImage thumb = new BufferedImage(th_w, th_h, t);
    Graphics2D g2d = thumb.createGraphics();
    g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
    //g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.drawImage(image, 0, 0, th_w, th_h, 0, 0, w, h, null);
    return thumb;
  }

  BufferedImage blankImage(int width, int height, Color color)
  {
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);

    Graphics2D g2d = image.createGraphics();
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
    path.moveTo(0.0f,0.0f);
    path.lineTo(0.0f,width);
    path.lineTo(height,0.0f);
    path.lineTo(0.0f,-width);
    path.closePath();

    if(color==null)
      color = Color.GRAY;

    g2d.setColor(color);
    g2d.fill(path);

    return image;
  }

  BufferedImage writeOnImage(BufferedImage image, String text, String anchor, float xoffset, float yoffset, Font font, Color color)
  {    
    int h = image.getHeight();
    int w = image.getWidth();
    int t = image.getType();
    float xoz, yoz;

    if(font==null)
      font = new Font("TimesRoman", Font.BOLD, 20);
    if(color==null)
      color = Color.GRAY;

    Graphics2D g2d = image.createGraphics();
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    
    FontRenderContext frc = g2d.getFontRenderContext();
    TextLayout layout = new TextLayout(text, font, frc);

    Rectangle2D bounds = layout.getBounds();
    
    if("tl".equals(anchor)) {
      // top left
      xoz = xoffset + 1.0f;
      yoz = yoffset + (float)bounds.getHeight() + 1.5f;      
    }
    else if("tc".equals(anchor)) {
      // top center
      xoz = (w - (float)bounds.getWidth()) / 2.0f + xoffset;
      yoz = yoffset + (float)bounds.getHeight() + 1.5f;      
    }
    else if("tr".equals(anchor)) {
      // top right
      xoz = w - (float)bounds.getWidth() - xoffset;
      yoz = yoffset + (float)bounds.getHeight() + 1.5f;      
    }
    else if("ml".equals(anchor)) {
      // middle left
      xoz = xoffset + 1.0f;
      yoz = (h + (float)bounds.getHeight())/2.0f + yoffset;      
    }
    else if("mc".equals(anchor)) {
      // middle center
      xoz = (w - (float)bounds.getWidth()) / 2.0f + xoffset;
      yoz = (h + (float)bounds.getHeight())/2.0f + yoffset;      
    }
    else if("mr".equals(anchor)) {
      // middle right
      xoz = w - (float)bounds.getWidth() - xoffset;
      yoz = (h + (float)bounds.getHeight())/2.0f + yoffset;      
    }
    else if("br".equals(anchor)) {
      // bottom right
      xoz = w - (float)bounds.getWidth() - xoffset;
      yoz = h - yoffset;      
    }
    else if("bc".equals(anchor)) {
      // bottom center
      xoz = (w - (float)bounds.getWidth()) / 2.0f + xoffset;
      yoz = h - yoffset;      
    }
    else { // "bl" is default
      // bottom left 
      xoz = xoffset + 1.0f;
      yoz = h - yoffset;      
    }

    g2d.setFont(font);
    g2d.setColor(color);
    g2d.drawString(text, xoz, yoz);

    return image;
  }

%><%
  CmsJspActionElement cms = new CmsJspActionElement(pageContext, request, response);
  CmsObject cmso = cms.getCmsObject();
  String meme = cms.link(cmso.getRequestContext().getUri());

  int currentPg = 1;
  String pg = request.getParameter("tb:pg");
  if(pg != null) {
    try {
      currentPg = Integer.parseInt(pg);
    } catch (Exception e) {
      currentPg = 1;
    }
  }
  if(currentPg < 1)
    currentPg = 1;

  // Params
  //String code = StringUtils.s4n(request.getParameter("Code"), "list");
  String imageDir = request.getParameter("Images"); 
  String thumbDir = request.getParameter("Thumbnails");
  String targetView = request.getParameter("Viewer");
  String viewerWindow = request.getParameter("ViewerWindow");
  String target = request.getParameter("Target");
  String columnStr = StringUtils.s4n(request.getParameter("Columns"), "4");
  String rowStr = StringUtils.s4n(request.getParameter("Rows"), "0");
  String thumbPrefix = StringUtils.s4n(request.getParameter("ThumbnailPrefix"), "");
  String thumbSuffix = StringUtils.s4n(request.getParameter("ThumbnailSuffix"), "");
  String thumbSize = StringUtils.s4n(request.getParameter("ThumbnailSize"), "128");
  String enforceSize = StringUtils.s4n(request.getParameter("EnforceSize"), "false");

  // Props
  imageDir = cms.property("Images", null, imageDir);
  if(imageDir == null)
    throw new Exception("The \"Images\" property must be set");
  else if(!imageDir.startsWith("/"))
    imageDir = "/system/galleries/pics/" + imageDir;
  imageDir = PathUtils.patchDir(imageDir);
 
  thumbDir = cms.property("Thumbnails", null, thumbDir);
  if(thumbDir == null)
    throw new Exception("The \"Thumbnails\" property must be set");
  else
    thumbDir = PathUtils.patchDir(thumbDir);
  if(thumbDir.equals(imageDir))
    throw new Exception("The \"Images\" and \"Thumbnails\" can not be set to the same folder");
  // Test if the thumbdir exists in case it is not an absolute path
  if(!thumbDir.startsWith("/")) {
    String s = imageDir + thumbDir;
    boolean x = OCUtils.fileExists(cmso, s);
    if(!x) {
      String b = PathUtils.removeTrailing(imageDir, "/");
      s = PathUtils.folderFromPath(b) + PathUtils.filenameFromPath(b) + "_" + thumbDir;
      x = OCUtils.fileExists(cmso, s);
    }
    if(!x) {
      throw new Exception("The expansion of relative \"Thumbnails\" directory fails to locate absolute path-" +s);
    } else {
      thumbDir = s;
    }
  }

  columnStr = cms.property("Columns", null, columnStr);
  rowStr = cms.property("Rows", null, rowStr);
  targetView = cms.property("Viewer", null, targetView );
  viewerWindow = cms.property("ViewerWindow", null, viewerWindow);
  target = cms.property("Target", null, target);
  thumbPrefix = cms.property("ThumbnailPrefix", null, thumbPrefix);
  thumbSuffix = cms.property("ThumbnailSuffix", null, thumbSuffix);
  thumbSize = cms.property("ThumbnailSize", null, thumbSize); // if making thumbs this should be set for safety
  enforceSize = cms.property("EnforceSize", null, enforceSize);
  String makeThumbs = cms.property("MakeThumbnails", null, "false"); // not settable by params thank you...
  String defaultThumb = cms.property("DefaultThumbnail", null, "/system/modules/com.codedroids.templatebuilder/resources/missing_thumb.gif");  

  int cols = 0, rows = 0, index = 0, th_max_w = 0, th_max_h = 0;
  boolean generateThumbs = makeThumbs.toLowerCase().equals("true");
  boolean beSquare = enforceSize.toLowerCase().equals("square");
  boolean forceThumbSize = (beSquare || enforceSize.toLowerCase().equals("true"));
  if(columnStr != null)
    cols = Integer.parseInt(columnStr);
  if(rowStr != null)
    rows = Integer.parseInt(rowStr);
  th_max_w = th_max_h = Integer.parseInt(thumbSize);
  int offset = 0;
  int max = 0;
  // since the number of images is open-ended only one of these should be set at the time
  // columns take precedence, if rows is set the number of columns is determined from the
  // actual amount of images. If neither is set it defaults to 4 cols
  if(cols > 0 && rows > 0)
    max = cols * rows;
  else if(cols <= 0 && rows <= 0)
    cols = 4;

  java.util.Vector images = new Vector();
  images = cmso.getResourcesInFolder(imageDir); 
  // If thumbs are ...
  int pages = (max > 0 ? ( images.size() / max + ((images.size() % max > 0) ? 1 : 0 ) ) : 0 );
  if(currentPg > pages)
    currentPg = pages;
  offset = max * (currentPg-1);

  java.util.Vector thumbs = null;
  thumbs = cmso.getResourcesInFolder(thumbDir);

  final String IMAGE = "img";
  final String THUMB = "th";
  final String CMS = "cms";

  // build list of maps, generate thumbnails if needed and requested
  CmsResource def_th = null;
  ArrayList list = new ArrayList();
  int first = offset;
  int last = (max > 0 ? max : images.size());
  for(int i = first; list.size() < last && i < images.size(); i++) {
    CmsResource im = (CmsResource)images.elementAt(i);
    if(im.isFolder())
      continue; // skip folders, we won't traverse filesystem.
    String ifn = im.getName();
    int ifndx = ifn.lastIndexOf('.');
    if(ifndx > 0)
      ifn = ifn.substring(0, ifndx);
    CmsResource th = null;
    // look for thumbnail
    for(int j = 0; j<thumbs.size(); j++) {
      CmsResource tmp = (CmsResource)thumbs.elementAt(j);
      String tfn = tmp.getName();
      int tfndx = tfn.lastIndexOf('.');
      if(tfndx > 0)
        tfn = tfn.substring(0, tfndx);
      if(tfn.equals(thumbPrefix + ifn + thumbSuffix)) {
        th = tmp;
        break;
      }
    }
    if(th == null && generateThumbs) {
      // attempt to generate thumb if requested (default)
      CmsFile f = cmso.readFile(im.getAbsolutePath());
      byte[] bytes = f.getContents();
      String ext = f.getExtension().substring(1); // need it without the dot
      String filename = thumbPrefix + ifn + thumbSuffix + "." + ext;

      ByteArrayInputStream is = new ByteArrayInputStream(bytes);
      BufferedImage orig = javax.imageio.ImageIO.read(is);
      BufferedImage img = thumbnailFromImage(orig, th_max_w, th_max_h);

      ByteArrayOutputStream os = new ByteArrayOutputStream();
      javax.imageio.ImageIO.write(img, ext, os);

      Map props = new HashMap();
      props.put("Width", ""+img.getWidth());
      props.put("Height", ""+img.getHeight());
      // title and desc from image???
      CmsResource r = cmso.createResource(thumbDir, filename, "image", props, os.toByteArray());    
      th = r;
    }
    HashMap map = new HashMap(3);
    if(th != null) {
      map.put(IMAGE, im);
      map.put(CMS, cms);
      map.put(THUMB, th);
      list.add(map);
    } else {
      if(def_th == null)
        def_th = cmso.readFileHeader(defaultThumb);
      map.put(IMAGE, im);
      map.put(CMS, cms);
      map.put(THUMB, def_th); 
      list.add(map);
    }
  }

  // Sort the list
  Comparator CmsResourceCmp = new Comparator() {
    public int compare(Object o1, Object o2) {
      CmsResource r1 = (CmsResource)((HashMap)o1).get(IMAGE);
      CmsResource r2 = (CmsResource)((HashMap)o2).get(IMAGE);
      CmsJspActionElement c = (CmsJspActionElement)((HashMap)o1).get(CMS);
      String p1 = r1.getAbsolutePath();
      String p2 = r2.getAbsolutePath();
      double f1 = Double.parseDouble(c.property(I_CmsConstants.C_PROPERTY_NAVPOS, p1, "0.0"));
      double f2 = Double.parseDouble(c.property(I_CmsConstants.C_PROPERTY_NAVPOS, p2, "0.0"));
      double f = f1 - f2;
      if(f < 0.0)
        return -1;
      else if(f > 0.0)
        return 1;
      else
        return p1.compareToIgnoreCase(p2);
    }
  }; 
  Collections.sort(list, CmsResourceCmp);

  int imageCnt = list.size();
  if(cols <= 0)
    cols = (imageCnt / rows) + (imageCnt % rows > 0 ? 1 : 0);
  
  String preTable = "<table class=\"PhotoAlbum\" cellspan=\"0\" cellpadding=\"0\" border=\"0\">";
  String postTable = "</table>";
  String prePagerRow = "<tr class=\"PhotoAlbumPager\">";
  String preRowEven = "<tr class=\"PhotoAlbumRow PhotoAlbumEven\">";
  String preRowOdd = "<tr class=\"PhotoAlbumRow PhotoAlbumOdd\">";
  String postRow = "</tr>";
  String preCellEven = "<td class=\"PhotoAlbumThumbnail PhotoAlbumEven\">";
  String preCellOdd = "<td class=\"PhotoAlbumThumbnail PhotoAlbumOdd\">";
  String postCell = "</td>";
  String preImage = "<div class=\"PhotoAlbumThumbnailImage\">";
  String postImage = "</div>";
  String preText = "<div class=\"PhotoAlbumThumbnailText\">";
  String postText = "</div>";

  CmsResource image = null;
  CmsResource thumb = null;
  int rowcnt = 0;

  out.println(preTable);
  if(pages > 1) {
    out.println(prePagerRow);
    out.println("<td class=\"PhotoAlbumPager\" colspan=\"" + cols + "\">");
    out.println("<table cellspan=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%\"><tr>");
    if(currentPg > 1)
      out.println("<td align=\"center\"><a href=\""+meme+"?tb:pg="+(currentPg-1)+"\">&lt;&lt;</a></td>");
    else
      out.println("<td align=\"center\">&lt;&lt;</td>");
    out.println("<td align=\"center\">");
    for(int i=1; i<=pages; i++) {
      if(i==currentPg)
        out.println("<b>"+i+"</b>");
      else
        out.println("<a href=\""+meme+"?tb:pg="+i+"\">"+i+"</a>");
    }
    out.println("<td>");
    if(currentPg < pages)
      out.println("<td align=\"center\"><a href=\""+meme+"?tb:pg="+(currentPg+1)+"\">&gt;&gt;</a></td>");
    else
      out.println("<td align=\"center\">&gt;&gt;</td>");
    out.println("</tr></table>");
    out.println("</td>");
    out.println(postRow);
  }
  for(int i=0; i<imageCnt; i++) {
    if(i % cols == 0) {
      if(i > 0)
        out.println(postRow);
      if(rowcnt % 2 == 0)
        out.println(preRowEven);
      else
        out.println(preRowOdd);
      rowcnt++;
    }
    if(i % 2 == 0)
      out.println(preCellEven);
    else
      out.println(preCellOdd);

    image = (CmsResource)((HashMap)(list.get(i))).get(IMAGE);
    thumb = (CmsResource)((HashMap)(list.get(i))).get(THUMB);
    String thumb_path = thumb.getAbsolutePath();
    String thumb_src = cms.link(thumb_path);
    String thumb_title = cms.property(I_CmsConstants.C_PROPERTY_TITLE, thumb_path);
    String thumb_desc = cms.property(I_CmsConstants.C_PROPERTY_DESCRIPTION, thumb_path);
    String thumb_w = cms.property("Width", thumb_path);
    String thumb_h = cms.property("Height", thumb_path);
    int th_w = 0;
    int th_h = 0;
    if(beSquare || (thumb_w == null && thumb_h == null && forceThumbSize)) {
      th_w = th_max_w;
      th_h = th_max_h;
    }
    else {
      if(thumb_w != null)
        th_w = Integer.parseInt(thumb_w);
      if(thumb_h != null)
        th_h = Integer.parseInt(thumb_h);
    }
    if(forceThumbSize && (th_w > th_max_w || th_h > th_max_h)) {
      // let browser scale it but keep proportions
      if(th_w > th_h) {
        th_w = th_max_w;
        th_h = 0;
      } else {
        th_h = th_max_h;
        th_w = 0;
      }
    }

    String image_src = null;
    if(targetView == null) {
      image_src = cms.link(image.getAbsolutePath());
    } else {
      Map pars = new HashMap();
      pars.put("Images", imageDir);
      pars.put("Path", image.getAbsolutePath());
      pars.put("File", PathUtils.filenameFromPath(image.getAbsolutePath()));
      image_src = cms.link(StringUtils.replaceStrings(targetView, pars, "${", "}"));
    }
    if(viewerWindow != null) {
      Map pars = new HashMap();
      pars.put("URL", image_src);
      image_src = StringUtils.replaceStrings(viewerWindow, pars, "${", "}");
    }
    out.print(preImage);
    out.print("<a href=\"" + image_src + "\" alt=\"" + thumb.getName() + "\"" +(target == null ? "" : "target=\"" + target +"\"")+ ">");
    out.print("<img src=\"" + thumb_src + "\" alt=\"" + thumb.getName() + "\"");
    if(th_w > 0)
      out.print(" width=\""+th_w+"\"");
    if(th_h > 0)
      out.print(" height=\""+th_h+"\"");
    out.print(">");
    out.print("</a>");
    out.print(postImage);
    out.print(preText);
    if(thumb_title != null) {
      out.println("<h1>" + thumb_title + "</h1>");
    }
    if(thumb_desc != null) {
      out.println("<p>" + thumb_desc + "</p>");
    }
    out.print(postText);
    out.println(postCell);
  }
  out.println(postRow);
  out.println(postTable);
%>

