'use strict';

var sharp = require('sharp');
var map   = require('map-stream');
var env   = require('../config/environment_vars');
var dims  = require('../lib/dimensions');


module.exports = function () {

  return map( function(image, callback) {

    // do nothing if there is an error on the image object
    if (image.isError()){
      return callback(null, image);
    }

    // let this pass through if we are requesting the metadata as JSON
    if (image.modifiers.action === 'json'){
      image.log.log('resize: json metadata call');
      return callback(null, image);
    }

    if (image.modifiers.action === 'original' && env.RESIZE_PROCESS_ORIGINAL === false){
      image.log.log('resize: original no resize');
      return callback(null, image);
    }

    image.log.time('resize');

    var resizeResponse = function (err, buffer) {
      if (err) {
        image.log.error('resize error', err);
        image.error = new Error(err);
      }
      else {
        image.contents = buffer;
      }

      image.log.timeEnd('resize');
      callback(null, image);
    };

    var r = sharp(image.contents);

    // never enlarge an image beyond its original size, unless we're padding
    // the image, as even though this can count as an "enlargement" the padded
    // result can be reasonably generated in most cases.
    if (image.modifiers.action !== 'crop' && image.modifiers.crop !== 'pad') {
      r.withoutEnlargement();
    }

    // if allowed auto rotate images, very helpful for photos off of an iphone
    // which are landscape by default and the metadata tells them what to show.
    if (env.AUTO_ORIENT) {
      r.rotate();
    }

    // by default we remove the metadata from resized images, setting the env
    // var to false can retain it.
    if (!env.REMOVE_METADATA) {
      r.withMetadata();
    }

    var d, wd, ht;

    switch(image.modifiers.action){
    case 'original' :
      r.toBuffer(resizeResponse);
      break;

    case 'resize':
      r.resize(image.modifiers.width, image.modifiers.height);
      r.max();
      r.toBuffer(resizeResponse);
      break;

    case 'square':
      r.metadata(function(err, metadata){
        if (err){
          image.error = new Error(err);
          callback(null, image);
          return;
        }

        d = dims.cropFill(image.modifiers, metadata);

        // resize then crop the image
        r.resize(
            d.resize.width,
            d.resize.height
          ).extract(
            d.crop.y,
            d.crop.x,
            d.crop.width,
            d.crop.height
          );

        r.toBuffer(resizeResponse);
      });

      break;

    case 'crop':
      r.metadata(function(err, size){
        if (err){
          image.error = new Error(err);
          callback(null, image);
          return;
        }

        switch(image.modifiers.crop){
        case 'fit':
          r.resize(image.modifiers.width, image.modifiers.height);
          r.max();
          break;
        case 'fill':
          d = dims.cropFill(image.modifiers, size);

          r.resize(
              d.resize.width,
              d.resize.height
            ).extract(
              d.crop.y,
              d.crop.x,
              d.crop.width,
              d.crop.height
            );
          break;
        case 'cut':
          wd = image.modifiers.width || image.modifiers.height;
          ht = image.modifiers.height || image.modifiers.width;

          d = dims.gravity(
            image.modifiers.gravity,
            size.width,
            size.height,
            wd,
            ht
          );
          r.extract(d.y, d.x, wd, ht);
          break;
        case 'scale':
          // TODO: deal with scale
          r.resize(image.modifiers.width, image.modifiers.height);
          break;
        case 'pad':
          r.resize(
            image.modifiers.width,
            image.modifiers.height
          ).background(env.IMAGE_PADDING_COLOR || 'white').embed();
        }

        r.toBuffer(resizeResponse);
      });

      break;
    }
  });

};

@@ -2463,32 +2463,33 @@
       ).extract(
+%7B
 %0A            d.c
@@ -2480,32 +2480,38 @@
 %0A           
+ left:
  d.crop.
 y,%0A         
@@ -2490,33 +2490,33 @@
    left: d.crop.
-y
+x
 ,%0A            d.
@@ -2508,32 +2508,37 @@
 %0A           
+ top:
  d.crop.
 x,%0A         
@@ -2517,33 +2517,33 @@
     top: d.crop.
-x
+y
 ,%0A            d.
@@ -2531,32 +2531,39 @@
 p.y,%0A           
+ width:
  d.crop.width,%0A 
@@ -2564,32 +2564,40 @@
 dth,%0A           
+ height:
  d.crop.height%0A 
@@ -2605,16 +2605,17 @@
         
+%7D
 );%0A%0A    
@@ -3183,16 +3183,17 @@
 extract(
+%7B
 %0A       
@@ -3198,24 +3198,30 @@
         
+ left:
  d.crop.
 y,%0A     
@@ -3204,33 +3204,33 @@
    left: d.crop.
-y
+x
 ,%0A              
@@ -3228,24 +3228,29 @@
         
+ top:
  d.crop.
 x,%0A     
@@ -3233,33 +3233,33 @@
     top: d.crop.
-x
+y
 ,%0A              
@@ -3249,32 +3249,39 @@
 y,%0A             
+ width:
  d.crop.width,%0A 
@@ -3292,16 +3292,24 @@
         
+ height:
  d.crop.
@@ -3319,32 +3319,33 @@
 ght%0A            
+%7D
 );%0A          bre
@@ -3679,24 +3679,112 @@
 act(
-d.y, d.x, wd, ht
+%7B%0A            left: d.x,%0A            top: d.y,%0A            width: wd,%0A            height: ht%0A          %7D
 );%0A 

fix extract calls