import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import java.awt.Container;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;

import javax.servlet.*;
import javax.servlet.http.*;

/**
 * @version 	1.0
 * @author
 */
public class ImageAgent extends HttpServlet implements SingleThreadModel {

   	private String image_base_folder = "";

   	public void init(ServletConfig config)
         throws ServletException
   	{
      	super.init(config);

      	try {
         	ResourceBundle props = ResourceBundle.getBundle("ImageAgent");
         	image_base_folder = props.getString("image_base_folder");
         	if (image_base_folder != null) {
            	image_base_folder = image_base_folder.trim();
            	int len = image_base_folder.length();
            	if (len > 0 && image_base_folder.charAt(len-1) != '/')
               		image_base_folder = image_base_folder.concat("/");
         	}
         	else {
            	log("No image_base_folder in ImageAgent.properties file.");
            	image_base_folder = "";
         	}
      	}
      	catch (Exception e) {
         	log(e.getMessage());
      		//throw new ServletException(e.getMessage());
      	}
   	}

	/**
	* @see javax.servlet.http.HttpServlet#void (javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	*/
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
		throws ServletException, IOException {
		doPost(req, resp);
	}

	/**
	* @see javax.servlet.http.HttpServlet#void (javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	*/
	public void doPost(HttpServletRequest req, HttpServletResponse resp)
		throws ServletException, IOException {

      	try {
         	String imgFile = req.getParameter("getImage");
              String widthLmt = "";
         	String heightLmt = "";
        	imgFile = validate(imgFile);

         	ServletContext cntx = getServletContext();
         	String contentType = cntx.getMimeType(imgFile);
         	resp.setContentType(contentType);

         	ServletOutputStream out = resp.getOutputStream();
                if(req.getParameter("widthLimit")==null&&req.getParameter("heightLimit")==null){
                    System.out.println("======This is the old way to invoke without width and height");
                    sendFile(imgFile, out);
                }else{
                    widthLmt = req.getParameter("widthLimit");
                    heightLmt = req.getParameter("heightLimit");
                    System.out.println("The Target sizes are: "+widthLmt+", and "+heightLmt);
                    sendFile(imgFile, out, widthLmt, heightLmt);
                }
      	}
      	catch (FileNotFoundException e) {
         	resp.sendError(resp.SC_NOT_FOUND, e.getMessage());
      	}
      	catch (IOException e) {
         	resp.getOutputStream().println("Failed in sending the file: " + e.getMessage());
      	}
      	catch (Exception e) {
         	resp.getOutputStream().println(e.getMessage());
      	}
	}

   private void sendFile(String filename, OutputStream out)
         throws FileNotFoundException, IOException
   {
      InputStream is = null;
      try {
         is = new FileInputStream(filename);
         byte[] buf = new byte[4 * 1024];
         int bytesRead;
         while ((bytesRead = is.read(buf)) != -1) {
            out.write(buf, 0, bytesRead);
         }
      }
      finally {
         if (is != null) is.close();
      }
   }

   private void sendFile(String filename, OutputStream out, String widthLmt, String heightLmt)
         throws FileNotFoundException, IOException
   {
      InputStream is = null;
      String tempImage = "/userhome/brs90/tempImage.jpg";
      try {
	Toolkit toolkit = Toolkit.getDefaultToolkit();
	Image image = toolkit.getImage(filename);
        MediaTracker mediaTracker = new MediaTracker(new Container());
        mediaTracker.addImage(image, 0);
            try {
                mediaTracker.waitForID(0);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        // determine thumbnail size from WIDTH and HEIGHT
         String width = Integer.toString(image.getWidth(null));
         String height = Integer.toString(image.getHeight(null));

         System.out.println("filename is: "+filename);
         System.out.println("The file size is: "+width+", and "+height);

/*         Toolkit toolkit = Toolkit.getDefaultToolkit();
            System.out.println("The Original image file is: "+filename);
	    Image image = toolkit.createImage(filename);
            String width = Integer.toString(image.getWidth(null));
            String height = Integer.toString(image.getHeight(null));
            System.out.println("The Original sizes are: "+width+", and "+height);
 */
         if((Integer.valueOf(width).intValue()<Integer.valueOf(widthLmt).intValue())&&(Integer.valueOf(height).intValue()<Integer.valueOf(heightLmt).intValue())){
             is = new FileInputStream(filename);
         }else{
	    int thumbWidth = Integer.parseInt(widthLmt);
	    int thumbHeight = Integer.parseInt(heightLmt);
	    double thumbRatio = (double)thumbWidth / (double)thumbHeight;
	    int imageWidth = image.getWidth(null);
	    int imageHeight = image.getHeight(null);
	    double imageRatio = (double)imageWidth / (double)imageHeight;
	    if (thumbRatio < imageRatio) {
	      thumbHeight = (int)(thumbWidth / imageRatio);
	    } else {
	      thumbWidth = (int)(thumbHeight * imageRatio);
	    }
	    // draw original image to thumbnail image object and
	    // scale it to the new size on-the-fly
	    BufferedImage thumbImage = new BufferedImage(thumbWidth, 
	      thumbHeight, BufferedImage.TYPE_INT_RGB);
	    Graphics2D graphics2D = thumbImage.createGraphics();
	    graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
	      RenderingHints.VALUE_INTERPOLATION_BILINEAR);
	    graphics2D.drawImage(image, 0, 0, thumbWidth, thumbHeight, null);
	    // save thumbnail image to OUTFILE
	    BufferedOutputStream outStr = new BufferedOutputStream(new FileOutputStream(tempImage));
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(outStr);
            JPEGEncodeParam param = encoder.
              getDefaultJPEGEncodeParam(thumbImage);
            int quality = 100;
            quality = Math.max(0, Math.min(quality, 100));
            param.setQuality((float)quality / 100.0f, false);
            encoder.setJPEGEncodeParam(param);
            encoder.encode(thumbImage);
	    outStr.close(); 
	    //System.out.println("Done.");
	    //System.exit(0);

         //System.out.println("filename is: "+filename);
         //System.out.println("The file size is: "+width+", and "+height);
         is = new FileInputStream(tempImage);
      }
         byte[] buf = new byte[4 * 1024];
         int bytesRead;
         while ((bytesRead = is.read(buf)) != -1) {
             System.out.println("bytesRead: "+bytesRead);
            out.write(buf, 0, bytesRead);
         }
         File f = new File(tempImage);
         //System.out.println("f.isFile: "+f.isFile());
         f.delete();
      }
      finally {
         if (is != null) is.close();
      }
   }

   private String validate(String filename)
         throws Exception
   {
      if (filename == null || filename.trim().length() == 0) {
         throw new Exception("Error: image file name is missing.");
      }

      filename = filename.trim();

      if (filename.length() != 8 || !isDigits(filename))
         throw new Exception("Error: image file name should be 8 digits.");

	  String fname;
      File f = new File(image_base_folder + filename.substring(0, 3));
      if (!f.isDirectory())
         //throw new Exception("Error: No image sub folder for " + filename);
		 fname = image_base_folder + filename;
	  else
      	 fname = image_base_folder + filename.substring(0, 3) + "/" + filename;

      f = new File(fname + ".JPG");
      if (!f.isFile()) {
         f = new File(fname + ".jpg");
         if (!f.isFile()) {
            f = new File(fname + ".GIF");
            if (!f.isFile()) {
               f = new File(fname + ".gif");
               if (!f.isFile())
                  throw new Exception("No image for " + filename);
            }
         }
      }
      System.out.println("The f.getPath() is: "+f.getPath());

      return f.getPath();
   }

   private boolean isDigits(String st) {
      try {
         Integer.parseInt(st);
      } catch (NumberFormatException e) { return false; }

      return true;
   }

}