require 'rubygems'
require 'inline'

class SfsResize
  SUPPORTED_FORMATS = %w(jpg jpeg png gif)
  attr_accessor :filename
  
  def initialize(filename_in)
    @filename = filename_in
  end
  
  def resize_image(filename_in, filename_out, box_w, box_h, image_type, jpeg_quality); end
  
  def resize_and_write_to_file(filename_out, box_w, box_h, options={})
    options.merge!({
      :cropped => false,
      :jpeg_quality => -1
    })
    
    ext = @filename.match(/\.(\w+)$/).to_a.last
    raise "#{ext} extension not recognised. We only support #{SUPPORTED_FORMATS.join(", ")}" unless SUPPORTED_FORMATS.include?(ext)
    resize_image(@filename, filename_out, box_w, box_h, SUPPORTED_FORMATS.index(ext), options[:jpeg_quality])
  end

  inline do |builder|
    builder.include '"gd.h"'
    builder.add_link_flags "-lgd"
    
    builder.c <<-"END"
      void resize_image(char *filename_in, char *filename_out, int box_w, int box_h, int image_type, int jpeg_quality) {
        gdImagePtr im_in;
        gdImagePtr im_out;
        int x, y;
        float r;
        FILE *in;
        FILE *out;
        
        /* Load original file */
        in = fopen(filename_in, "rb");
        
        /* Support diff image types: jpg jpeg png gif */
        switch(image_type) {
          case 0:
          case 1: im_in = gdImageCreateFromJpeg(in);
                  break;
          case 2: im_in = gdImageCreateFromPng(in);
                  break;
          case 3: im_in = gdImageCreateFromGif(in);
                  break;
          default: puts("Image type not recognised");
        }
        
        fclose(in);
        
        /* New image size */
        if(im_in->sx > im_in->sy) {
          r = (float)im_in->sy / (float)im_in->sx;
          x = box_w;
          y = floor(box_h * r);
        } else {
          r = (float)im_in->sx / (float)im_in->sy;
          x = floor(box_w * r);
          y = box_h;
        }
        
        /* Make the output image four times as small on both axes. Use
          a true color image so that we can interpolate colors. */
        im_out = gdImageCreateTrueColor(x,y);
        /* Now copy the large image, but four times smaller */
        gdImageCopyResampled(im_out, im_in, 0, 0, 0, 0,
          im_out->sx, im_out->sy,
          im_in->sx, im_in->sy);
        out = fopen(filename_out, "wb");
        
        /* TODO: support diff image types */
        /* Support diff image types: jpg jpeg png gif */
        switch(image_type) {
          case 0:
          case 1: gdImageJpeg(im_out, out, jpeg_quality);
                  break;
          case 2: gdImagePng(im_out, out);
                  break;
          case 3: gdImageGif(im_out, out);
                  break;
          default: puts("Image type not recognised");
        }
        
        fclose(out);
        gdImageDestroy(im_in);
        gdImageDestroy(im_out);
      }
    END
  end
end

