"use strict";

App.module("DataModule", function(DataModule, App, Backbone, Marionette, $, _, Logger) {

    DataModule.addInitializer(function(options){
        
        DataModule.ModelWithHashableAttributes = Backbone.Model.extend({
            defaultOptions: {
                attributesToExcludeFromHash: null,
                customHashSuffixGenerator: null // function(attributes)
            },
            
            initialize: function(attributes, options) {
                this.listenTo(this, "change", this.dropCachedHash);
                this.options = _.defaults(options || {}, this.defaultOptions);
            },
            
            dropCachedHash: function() {
                this._cachedHash = undefined;
            },

            getHash: function() {
                if (!this._cachedHash) {
                    var mixOfAttributesAndAttributeHashes = {};
                    for (var attributeName in this.attributes) {
                        if (this.options.attributesToExcludeFromHash && _.contains(this.options.attributesToExcludeFromHash, attributeName)) {
                            continue;
                        }
                        if (this.attributes.hasOwnProperty(attributeName)) {
                            var attribute = this.attributes[attributeName];
                            if (attribute && attribute.getHash) {
                                mixOfAttributesAndAttributeHashes[attributeName] = attribute.getHash();
                            } else {
                                mixOfAttributesAndAttributeHashes[attributeName] = attribute;
                            }
                        }
                    }
                    var newHash = JSON.stringify(mixOfAttributesAndAttributeHashes);
                    if (this.options.customHashSuffixGenerator && _.isFunction(this.options.customHashSuffixGenerator)) {
                        newHash += this.options.customHashSuffixGenerator(this.attributes);
                    }
                    this._cachedHash = newHash;
                }
                return this._cachedHash;
            }
        });
    });
}, Logger);
