function plDynamicGrid(configs) {
    this.data = configs.data;
    this.gridContainer = configs.gridContainer;
    this.gridId = configs.gridId
    this.addRowSelector = configs.addRowSelector;
    this.newRowClass = configs.newRowClass;
    this.prototypeRowClass = configs.prototypeRowClass;
    
    if (configs.beforeAddRowCallback === undefined) {
        this.beforeAddRowCallback = function () {};
    } else {
        this.beforeAddRowCallback = configs.beforeAddRowCallback;
    }
    
    if (configs.addRowCallback === undefined) {
        this.addRowCallback = function () {};
    } else {
        this.addRowCallback = configs.addRowCallback;
    }
    
    if (configs.afterAddRowCallback === undefined) {
        this.afterAddRowCallback = function () {};
    } else {
        this.afterAddRowCallback = configs.afterAddRowCallback;
    }

    if (configs.beforeRemoveCallback === undefined) {
        this.beforeRemoveCallback = function () {};
    } else {
        this.beforeRemoveCallback = configs.beforeRemoveCallback;
    }
    
    if (configs.removeRowCallback === undefined) {
        this.removeRowCallback = function () {};
    } else {
        this.removeRowCallback = configs.removeRowCallback;
    }
    
    if (configs.afterRemoveCallback === undefined) {
        this.afterRemoveCallback = function () {};
    } else {
        this.afterRemoveCallback = configs.afterRemoveCallback;
    }
    
    this.initAddRow = function() {
        
        var index = $(this.gridId + ' tbody').find('.icon-trash').length;
        var firstRule = $(this.gridId + ' tbody tr').first();
        var newRowClass = this.newRowClass;
        var prototypeRowClass = this.prototypeRowClass;
        var gridId = this.gridId;
        var beforeAddRowCallback =this.beforeAddRowCallback;
        var addRowCallback = this.addRowCallback;
        var afterAddRowCallback = this.afterAddRowCallback;
        var data = this.data;
        
        $(this.gridContainer).on("click",this.addRowSelector, function (){
            
            
            beforeAddRowCallback(this,data);
            
            $(gridId + ' > table').append(firstRule.clone().addClass(newRowClass));
            $(gridId + ' tbody tr:last-child').removeClass(prototypeRowClass);

            $(gridId + ' tbody tr:last-child input').each(function (i, e) {

                e.value = '';
                e.name = e.name.replace('0', index);
                e.id = e.id.replace('0', index);

                addRowCallback(e, index, data);

            });
            var scrolled = $('.modal-body').scrollTop();
            var scroll = scrolled + $(gridId + ' > table > tbody > tr:last-child').height();

            $('.modal-body').animate({scrollTop: scroll}, 300);
            index = index + 1;
            afterAddRowCallback(data);
        });
    }

    this.initRemoveRow = function initRemoveRow() {
        var beforeRemoveCallback = this.beforeRemoveCallback;
        var removeRowCallback = this.removeRowCallback;
        var afterRemoveCallback = this.afterRemoveCallback;
        var data = this.data;
        
        
        $(this.gridContainer).on("click",this.removeRowSelector, function () {
            beforeRemoveCallback(data);
            removeRowCallback(data);
            afterRemoveCallback(data);
        });
        
    }
    
    this.init = function() {
        this.initAddRow();
        this.initRemoveRow();
    }
    this.init();
    //this.initRemoveRow();
}