define([], function(){

    restCollectionFactory.$inject = ['$http', 'getUrl', 'primaryKey', 'restSortFunction', 'valueAttribute'];
    function restCollectionFactory($http, getUrl, primaryKey, restSortFunction, valueAttribute){
        return new RestCollection($http, getUrl, primaryKey, restSortFunction, valueAttribute);
    }

    function RestCollection($http, getUrl, primaryKey, restSortFunction, valueAttribute)
    {
        this.$http = $http;
        this.getUrl = getUrl;
        this.primaryKey = primaryKey;
        this.items = [];
        this.callbacks = [];
        this.sorter = restSortFunction;
        this.valueAttribute = valueAttribute || "value";
    }

    RestCollection.prototype.getAll = function()
    {
        var that = this;
        return this.$http.get(this.getUrl).then(function (response) {
            if(Array.isArray(response.data.data))
                that.items = response.data.data;
            else
                that.items = [];
            that.items.sort(that.sorter);
        });
    };

    RestCollection.prototype.get = function($key)
    {
        return this.$http.get(this.getUrl + '/' + $key);
    };

    RestCollection.prototype.post = function(item)
    {
        return this.$http.post(this.getUrl + '/' + item[this.primaryKey], {value: item[this.valueAttribute]}, {headers: {'Content-Type': 'application/json'}});
    };

    RestCollection.prototype.delete = function(item)
    {
        var key = item;
        if(item instanceof Object)
            key = item[this.primaryKey];
        return this.$http.delete(this.getUrl + '/' + key);
    };

    RestCollection.prototype.save = function(obj)
    {
        var that = this;
        var index = this.items.findIndex(function(item){
            return item[that.primaryKey] === obj[that.primaryKey];
        });
        if(index >= 0)
        {
            this.items[index] = obj;
            for(var i in this.callbacks)
                if(this.callbacks.hasOwnProperty(i))
                    this.callbacks[i]();
            return this.post(obj);
        }else
        {
            return null;
        }
    };

    RestCollection.prototype.saveAll = function(arr)
    {
        if(arr !== undefined)
            this.items = arr;
        this.items = this.items.filter(function(elem){
            return elem.marked_for_death !== true;
        });
        for(var i in this.callbacks)
            if(this.callbacks.hasOwnProperty(i))
                this.callbacks[i]();
        var that = this;
        var promise = this.$http.post(this.getUrl, {value: this.items}, {headers: {'Content-Type': 'application/json'}});
        promise.then(function (response) {
            if(Array.isArray(response.data.data))
                that.items = response.data.data;
            else
                that.items = [];
            that.items.sort(that.sorter);
        });
        return promise;
    };

    RestCollection.prototype.registerCallback = function(callback)
    {
        this.callbacks.push(callback);
    };

    return function(app)
    {
        app.factory('restCollection', restCollectionFactory);
    };

    function RestCollectionPromise(collectionIn, httpPromise)
    {
        var collection = collectionIn;
        var promise = httpPromise;
        // var that = this;
        this.then = function(callback)
        {
            promise.then(function($response){
                callback(collection, $response);
            })
        }
    }
});