"use strict";

App.module("DataModule", function(DataModule, App, Backbone, Marionette, $, _, Logger) {
    DataModule.addInitializer(function(){
        //var logger = Logger.get("DataModule.DynamicDefinition");

        DataModule.DynamicDefinitionProvider = Marionette.Object.extend({
            
            options: {
                DynamicDefinition:                  undefined,
                apiMethod:                          undefined,
                customAttributesWhenNotApplicable: undefined,
                customAttributesWhileBeingUpdated: undefined,
                customAttributesWhenIsFaulty:      undefined,
            },
            
            // These methods are defined in children prototypes
            definitionIsFaulty: function(definition) {},
            definitionIsBeingUpdated: function(definition) {},
            configParametersToRequestParameters: function(config) {},
            apiResponseToDynamicDefinitionAttributes: function(data, query) {},

            initialize: function() {
                //this.options = options;
                this._dynamicDefinitionsByEntityConfigClientId = {};
                this._requestHashesByParameterHash = {};
                this._requestParametersByRequestHash = {};
                this._cachedAttributesByRequestHash = {};
            },
            
            get: function(entityConfig) {
                var clientId = entityConfig.getClientId();
                var definition = this._dynamicDefinitionsByEntityConfigClientId[clientId];
                
                if (!definition) {
                    definition = new this.options.DynamicDefinition({}, {
                        entityConfig: entityConfig,
                        provider: this,
                    });
                    this._dynamicDefinitionsByEntityConfigClientId[clientId] = definition;
                }
                
                return definition;
            },
            
            retire: function (entityConfigClientId) {
                var definitionToRetire = this._dynamicDefinitionsByEntityConfigClientId[entityConfigClientId];
                definitionToRetire.destroy();
                delete this._dynamicDefinitionsByEntityConfigClientId[entityConfigClientId];
            },
            
            updateResponseForRequestHash: function(requestHash) {
                var requestParameters = this._requestParametersByRequestHash[requestHash];
                
                if (requestParameters === null) {
                    this._cachedAttributesByRequestHash[requestHash] = _.clone(this.options.customAttributesWhenNotApplicable);
                    this.trigger("change:" + requestHash);
                    return;
                }
                
                this._cachedAttributesByRequestHash[requestHash] = _.clone(this.options.customAttributesWhileBeingUpdated);
                this.trigger("change:" + requestHash);
                
                var provider = this;
                App.DataModule.CliopatriaAPI.request(this.options.apiMethod, requestParameters, function(data, query){
                    var attributes = provider.apiResponseToAttributes(data, query);
                    provider._cachedAttributesByRequestHash[requestHash] = attributes;
                    provider.trigger("change:" + requestHash);
                });
            }
        });
    });
    
}, Logger);
