﻿var AsyncExecutioner = Class.create({
    initialize: function(data, userConfig) {
        var timer = false, self = this, config = {}, lambda = function() { }, index = 0, dataLength;

        function getDefaultConfig() {
            return {
                onStart: lambda,
                onExecution: lambda,
                onStop: lambda,
                deferTime: 5,
                chunkSize: 1
            }
        }
        function buildConfig(cfg) {
            config = Object.extend(getDefaultConfig(), userConfig);
        }
        function handleExecution() {
            for (var len = index + config.chunkSize; index < len; index++)
                config.onExecution(data[index]);

            if (index >= dataLength) {
                self.stop();
            }
            else
                start();
        }

        function start() {
            timer = setTimeout(handleExecution, config.deferTime);
        }
        this.add = function(item) {
            data.push(item);
            dataLength++;
        };
        this.merge = function(arr) {
            data = data.concat(arr);
            dataLength = data.length;
        };
        this.start = function() {
            if (this.isProcessing())
                return false;
            config.onStart(this);
            start();
        };
        this.stop = function() {
            clearTimeout(timer);
            timer = false
            config.onStop(this);
        };
        this.isProcessing = function() {
            return !!timer;
        }
        buildConfig();
    }
});
