'use strict';

/**
 * crop image according to user arguments and its position on screen and save it
 */

var gm = require('gm'),
    async = require('async'),
    request = require('request'),
    exclude = require('./exclude.js');

module.exports = function(res, done) {

    var that = this,
        excludeRect = res.excludeRect,
        shot = gm(this.screenshot).quality(100),
        cropDim;

    if (this.currentArgs.x && this.currentArgs.y && this.currentArgs.width && this.currentArgs.height) {

        /**
         * crop image with given arguments
         */
        cropDim = {
            x: this.currentArgs.x - res.scrollPos.x,
            y: this.currentArgs.y - res.scrollPos.y,
            width: this.currentArgs.width,
            height: this.currentArgs.height
        };

        exclude(shot, excludeRect);
        shot.crop(cropDim.width, cropDim.height, cropDim.x, cropDim.y);

    } else if (res && res.elemBounding) {

        /**
         * or use boundary of specific CSS element
         */
        cropDim = {
            x: res.elemBounding.left + (res.elemBounding.width / 2),
            y: res.elemBounding.top + (res.elemBounding.height / 2),
            width: typeof this.currentArgs.width !== 'undefined' ? this.currentArgs.width : res.elemBounding.width,
            height: typeof this.currentArgs.height !== 'undefined' ? this.currentArgs.height : res.elemBounding.height
        };

        exclude(shot, excludeRect);
        shot.crop(cropDim.width, cropDim.height, cropDim.x - (cropDim.width / 2), cropDim.y - (cropDim.height / 2));

    } else {
        exclude(shot, excludeRect);
    }

    async.waterfall([
        /**
         * save image to fs
         */
        function(cb) {
            if(!that.self.saveImages) {
                return cb();
            }

            return shot.write(that.filename || that.baselinePath, cb);
        },
        /**
         * generate image buffer
         */
        function() {
            var cb = arguments[arguments.length - 1];
            return shot.toBuffer('PNG', cb);
        },
        /**
         * upload image to applitools
         */
        function(buffer) {
            var cb = arguments[arguments.length - 1];
            if (!that.self.usesApplitools) {
                return cb();
            }
            request({
                qs: {apiKey: that.applitools.apiKey},
                url: that.self.host + '/api/sessions/running/' + that.self.sessionId,
                method: 'POST',
                headers: that.self.headers,
                timeout: that.self.reqTimeout,
                json: {
                    'appOutput': {
                        'title': res.title,
                        'screenshot64': new Buffer(buffer).toString('base64')
                    },
                    'tag': that.currentArgs.tag || '',
                    'ignoreMismatch': that.currentArgs.ignoreMismatch || false
                }
            }, cb);
        }
    ], done);

};

@@ -397,19 +397,32 @@
 m;%0A%0A    
-if 
+var x = parseInt
 (this.cu
@@ -436,83 +436,237 @@
 gs.x
- && this.currentArgs.y && this.currentArgs.width && this.currentArgs.height
+, 10);%0A    var y = parseInt(this.currentArgs.y, 10);%0A    var width = parseInt(this.currentArgs.width, 10);%0A    var height = parseInt(this.currentArgs.height, 10);%0A%0A    if (!isNaN(x) && !isNaN(y) && !isNaN(width) && !isNaN(height)
 ) %7B%0A
@@ -768,33 +768,16 @@
      x: 
-this.currentArgs.
 x - res.
@@ -804,33 +804,16 @@
      y: 
-this.currentArgs.
 y - res.
@@ -844,33 +844,16 @@
  width: 
-this.currentArgs.
 width,%0A 
@@ -871,33 +871,16 @@
 height: 
-this.currentArgs.
 height%0A 
@@ -1298,80 +1298,22 @@
 th: 
-typeof this.currentArgs.width !== 'undefined' ? this.currentArgs.width :
+isNaN(width) ?
  res
@@ -1327,24 +1327,32 @@
 unding.width
+ : width
 ,%0A          
@@ -1365,82 +1365,23 @@
 ht: 
-typeof this.currentArgs.height !== 'undefined' ? this.currentArgs.height :
+isNaN(height) ?
  res
@@ -1396,24 +1396,33 @@
 nding.height
+ : height
 %0A        %7D;%0A

Replace falsy check of coordinates with proper numeric check