;(function(root, factory) {
	'use strict';
	if(typeof exports === 'object') {
        module.exports = factory(require('jquery'), require('./jquery.gridster.js'));
    }
    else if (typeof define === 'function' && define.amd) {
        define(['jquery', 'gridster'], factory);
    } else {
        root.Gridster = factory(root.$ || root.jQuery, root.Gridster);
    }

}(this, function($, Gridster) {
	'use strict';
    var fn = Gridster.prototype;

    fn.widgets_in_col = function(col) {
        if (!this.gridmap[col]) {
            return false;
        }

        for (var i = this.gridmap[col].length - 1; i >= 0; i--) {
            if (this.is_widget(col, i) !== false) {
                return true;
            }
        }

        return false;
    };

    fn.widgets_in_row = function(row) {
        for (var i = this.gridmap.length; i >= 1; i--) {
            if (this.is_widget(i, row) !== false) {
                return true;
            }
        }

        return false;
    };

    fn.get_bottom_most_occupied_cell = function() {
        var row = 0;
        var col = 0;
        this.for_each_cell(function($el, c, r) {
            if ($el && r > row) {
                row = r;
                col = c;
            }
        });

        return {col: col, row: row};
    };


    fn.get_right_most_occupied_cell = function() {
        var row = 0;
        var col = 0;
        this.for_each_cell(function($el, c, r) {
            if ($el) {
                row = r;
                col = c;
                return false;
            }
        });

        return {col: col, row: row};
    };


    fn.for_each_cell = function(callback, gridmap) {
        gridmap || (gridmap = this.gridmap);
        var cols = gridmap.length;
        var rows = gridmap[1].length;

        cols_iter:
        for (var c = cols - 1; c >= 1; c--) {
            for (var r = rows - 1; r >= 1; r--) {
                var $el = gridmap[c] && gridmap[c][r];
                if (callback) {
                    if (callback.call(this, $el, c, r) === false) {
                        break cols_iter;
                    } else { continue; }
                }
            }
        }
    };


    fn.next_position_in_range = function(size_x, size_y) {
        size_x || (size_x = 1);
        size_y || (size_y = 1);
        var ga = this.gridmap;
        var cols_l = ga.length;
        var valid_pos = [];
        var rows_l;

        for (var c = 1; c < cols_l; c++) {
            rows_l = this.options.max_rows || ga[c].length;
            for (var r = 1; r <= rows_l; r++) {
                var can_move_to = this.can_move_to({
                    size_x: size_x,
                    size_y: size_y
                }, c, r);

                if (can_move_to) {
                    valid_pos.push({
                        col: c,
                        row: r,
                        size_y: size_y,
                        size_x: size_x
                    });
                }
            }
        }

        if (valid_pos.length >= 1) {
            return Gridster.sort_by_col_asc(valid_pos)[0];
        }

        return false;
    };


    fn.closest_to_right = function(col, row) {
        if (!this.gridmap[col]) { return false; }
        var cols_l = this.gridmap.length - 1;

        for (var c = col; c <= cols_l; c++) {
            if (this.gridmap[c][row]) {
                return { col: c, row: row };
            }
        }

        return false;
    };


    fn.closest_to_left = function(col, row) {
        if (!this.gridmap[col]) { return false; }

        for (var c = col; c >= 1; c--) {
            if (this.gridmap[c][row]) {
                return { col: c, row: row };
            }
        }

        return false;
    };

    return Gridster;

}));
