{% import 'closure/model/macro.jinja' as model %}
/**
 * Automatically generated by pride
 */
goog.provide('{{namespace}}.{{name}}');

goog.require('{{project}}');

goog.require('goog.json');

goog.require('prestans.types.Model');
goog.require('prestans.types.Model.AttributeChangedEvent');
goog.require('prestans.types.Model.EventType');

goog.require('{{filter_namespace}}.{{name}}');
{% for dependency in dependencies %}
goog.require('{{dependency}}');
{% endfor %}

/**
 * @constructor
 * @param {?Object=} opt_json
 * @param {!boolean=} opt_minified
 * @param {!boolean=} opt_raiseValidateException
 *
 * @extends {prestans.types.Model}
 */
{{namespace}}.{{name}} = function(opt_json, opt_minified, opt_raiseValidateException) {

    //Setup base model
    prestans.types.Model.call(this);

    if(!goog.isDef(opt_raiseValidateException))
        opt_raiseValidateException = true;

    if(goog.isDef(opt_minified) && goog.isBoolean(opt_minified) && opt_minified && goog.isDefAndNotNull(opt_json)) {
{% for attribute in attributes %}{{model.minifiedAttributeWithJson(namespace, name, attribute)}}{% endfor %}
    }
    else if(goog.isDefAndNotNull(opt_json)) {
{% for attribute in attributes %}{{model.attributeWithJson(namespace, name, attribute)}}{% endfor %}
    }
    else {
{% for attribute in attributes %}{{model.attribute(namespace, name, attribute)}}{% endfor %}
    }

    //listen for array events
    {% for attribute in attributes %}{% if attribute.blueprint_type == "array" %}
this.eventHandler_.listen(this.{{attribute.ccif}}_, prestans.types.Array.EventType.ARRAY_CHANGED, function(event) {
        this.dispatchAttributeChangedEvent_("{{attribute.ccif}}", null, this.{{attribute.ccif}}_);
    });
    {% endif %}{% endfor %}

};
goog.inherits({{namespace}}.{{name}}, prestans.types.Model);

{{namespace}}.{{name}}.Meta = {
{% for attribute in attributes %}
{% if attribute.blueprint_type == "string" %}
    {{attribute.cc}}: {
        REQUIRED: {{attribute.required}},
        DEFAULT: {{attribute.default}},
        MAX_LENGTH: {{attribute.max_length}},
        MIN_LENGTH: {{attribute.min_length}},
        FORMAT: {{attribute.format}},
        CHOICES: {{attribute.choices}}
{% if loop.last %}
    }
{% else %}
    },
{% endif %}
{% endif %}
{% if attribute.blueprint_type == "boolean" %}
    {{attribute.cc}}: {
        REQUIRED: {{attribute.required}},
        DEFAULT: {{attribute.default}}
{% if loop.last %}
    }
{% else %}
    },
{% endif %}
{% endif %}
{% if attribute.blueprint_type == "integer" %}
    {{attribute.cc}}: {
        REQUIRED: {{attribute.required}},
        DEFAULT: {{attribute.default}},
        MAXIMUM: {{attribute.maximum}},
        MININUM: {{attribute.minimum}},
        CHOICES: {{attribute.choices}}
{% if loop.last %}
    }
{% else %}
    },
{% endif %}
{% endif %}
{% if attribute.blueprint_type == "float" %}
    {{attribute.cc}}: {
        REQUIRED: {{attribute.required}},
        DEFAULT: {{attribute.default}},
        MAXIMUM: {{attribute.maximum}},
        MININUM: {{attribute.minimum}},
        CHOICES: {{attribute.choices}}
{% if loop.last %}
    }
{% else %}
    },
{% endif %}
{% endif %}
{% if attribute.blueprint_type == "datetime" %}
    {{attribute.cc}}: {
        REQUIRED: {{attribute.required}},
        DEFAULT: {{attribute.default}},
        TIMEZONE: {{attribute.timezone}},
        UTC: {{attribute.utc}}
{% if loop.last %}
    }
{% else %}
    },
{% endif %}
{% endif %}
{% if attribute.blueprint_type == "date" %}
    {{attribute.cc}}: {
        REQUIRED: {{attribute.required}},
        DEFAULT: {{attribute.default}}
{% if loop.last %}
    }
{% else %}
    },
{% endif %}
{% endif %}
{% if attribute.blueprint_type == "time" %}
    {{attribute.cc}}: {
        REQUIRED: {{attribute.required}},
        DEFAULT: {{attribute.default}}
{% if loop.last %}
    }
{% else %}
    },
{% endif %}
{% endif %}
{% if attribute.blueprint_type == "data_url_file" %}
    {{attribute.cc}}: {
        REQUIRED: {{attribute.required}},
        ALLOWED_MIME_TYPES: {{attribute.default}}
{% if loop.last %}
    }
{% else %}
    },
{% endif %}
{% endif %}
{% if attribute.blueprint_type == "model" %}
    {{attribute.cc}}: {
        REQUIRED: {{attribute.required}}
{% if loop.last %}
    }
{% else %}
    },
{% endif %}
{% endif %}
{% if attribute.blueprint_type == "array" %}
    {{attribute.cc}}: {
        REQUIRED: {{attribute.required}}
{% if loop.last %}
    }
{% else %}
    },
{% endif %}
{% endif %}
{% endfor %}
};

/**
 * @enum {!string}
 */
{{namespace}}.{{name}}.REWRITE_MAP = {
{% for attribute in attributes %}
{% if loop.last %}
    "{{attribute.name}}": "{{attribute.map_name}}"
{% else %}
    "{{attribute.name}}": "{{attribute.map_name}}",
{% endif %}
{% endfor %}
};

/**
 * @enum {!string}
 */
{{namespace}}.{{name}}.REVERSE_REWRITE_MAP = {
{% for attribute in attributes %}
{% if loop.last %}
    "{{attribute.map_name}}": "{{attribute.name}}"
{% else %}
    "{{attribute.map_name}}": "{{attribute.name}}",
{% endif %}
{% endfor %}
};

{% for attribute in attributes %}
{{model.getMethod(namespace, name, attribute)}}

{% endfor %}

{% for attribute in attributes %}
{{model.setMethod(namespace, name, attribute)}}

{% endfor %}

/**
 * @param {!string} key
 * @param value
 */
{{namespace}}.{{name}}.prototype.setValueForKey = function(key, value) {

    var returnVal_ = null;

    switch(key)
    {
{% for attribute in attributes %}
        case "{{attribute.ccif}}":
            returnVal_ = this.set{{attribute.cc}}(value);
            break;
{% endfor %}
        default:
            throw "Key: "+key+" not found in model";
    }

    return returnVal_;
};

/**
 * @param {!string} key
 */
{{namespace}}.{{name}}.prototype.getValueForKey = function(key) {

    var returnVal_ = null;

    switch(key)
    {
{% for attribute in attributes %}
        case "{{attribute.ccif}}":
            returnVal_ = this.get{{attribute.cc}}();
            break;
{% endfor %}
        default:
            throw "Key: "+key+" not found in model";
    }

    return returnVal_;
};

/**
 * @param {!{{filter_namespace}}.{{name}}=} opt_filter
 *
 * @return {!{{namespace}}.{{name}}}
 */
{{namespace}}.{{name}}.prototype.clone = function(opt_filter) {
    var json_ = this.getJSONObject(true, opt_filter);
    return new {{namespace}}.{{name}}(json_, true, false);
};

/**
 * @param {!boolean} minified
 * @param {!{{filter_namespace}}.{{name}}=} opt_filter
 *
 * @return {!Object}
 */
{{namespace}}.{{name}}.prototype.getJSONObject = function(minified, opt_filter) {

    {% if filter_namespace != None %}//check that filter is of correct type
    if(goog.isDefAndNotNull(opt_filter) && !(opt_filter instanceof {{filter_namespace}}.{{name}}))
        throw "Incorrect filter for this model";
    {% endif %}

    var jsonifiedObject_ = {};
    
    if(goog.isDef(minified) && goog.isBoolean(minified) && minified) {
    {% for attribute in attributes %}
    {% if attribute.blueprint_type == 'model' %}
        if(goog.isDef(opt_filter) && opt_filter.get{{attribute.cc}}().anyFieldsEnabled()) {
            if(this.get{{attribute.cc}}() == null)
                jsonifiedObject_[{{namespace}}.{{name}}.REWRITE_MAP["{{attribute.name}}"]] = null;
            else
                jsonifiedObject_[{{namespace}}.{{name}}.REWRITE_MAP["{{attribute.name}}"]] = this.get{{attribute.cc}}().getJSONObject(true, opt_filter.get{{attribute.cc}}());
        }
        else if(!goog.isDef(opt_filter)) {
            if(this.get{{attribute.cc}}() == null)
                jsonifiedObject_[{{namespace}}.{{name}}.REWRITE_MAP["{{attribute.name}}"]] = null;
            else
                jsonifiedObject_[{{namespace}}.{{name}}.REWRITE_MAP["{{attribute.name}}"]] = this.get{{attribute.cc}}().getJSONObject(true);
        }
    {% elif attribute.blueprint_type == 'array' %}
    {% if attribute.element_template_is_model %}
        if(goog.isDef(opt_filter) && opt_filter.get{{attribute.cc}}().anyFieldsEnabled())
            jsonifiedObject_[{{namespace}}.{{name}}.REWRITE_MAP["{{attribute.name}}"]] = this.get{{attribute.cc}}().getJSONObject(true, opt_filter.get{{attribute.cc}}());
        else if(!goog.isDef(opt_filter))
            jsonifiedObject_[{{namespace}}.{{name}}.REWRITE_MAP["{{attribute.name}}"]] = this.get{{attribute.cc}}().getJSONObject(true);
    {% else %}
        if(goog.isDef(opt_filter) && opt_filter.get{{attribute.cc}}())
            jsonifiedObject_[{{namespace}}.{{name}}.REWRITE_MAP["{{attribute.name}}"]] = this.get{{attribute.cc}}().getJSONObject(true);
        else if(!goog.isDef(opt_filter))
            jsonifiedObject_[{{namespace}}.{{name}}.REWRITE_MAP["{{attribute.name}}"]] = this.get{{attribute.cc}}().getJSONObject(true);
    {% endif %}
    {% elif attribute.blueprint_type == 'datetime' or attribute.blueprint_type == 'date' or attribute.blueprint_type == 'time' %}
        if(goog.isDef(opt_filter) && opt_filter.get{{attribute.cc}}())
            jsonifiedObject_[{{namespace}}.{{name}}.REWRITE_MAP["{{attribute.name}}"]] = this.{{attribute.ccif}}_.getJSONObject();
        else if(!goog.isDef(opt_filter))
            jsonifiedObject_[{{namespace}}.{{name}}.REWRITE_MAP["{{attribute.name}}"]] = this.{{attribute.ccif}}_.getJSONObject();
    {% else %}
        if(goog.isDef(opt_filter) && opt_filter.get{{attribute.cc}}())
            jsonifiedObject_[{{namespace}}.{{name}}.REWRITE_MAP["{{attribute.name}}"]] = this.get{{attribute.cc}}()
        else if(!goog.isDef(opt_filter))
            jsonifiedObject_[{{namespace}}.{{name}}.REWRITE_MAP["{{attribute.name}}"]] = this.get{{attribute.cc}}()
    {% endif %}
    {% endfor %}
    }
    else {
    {% for attribute in attributes %}
    {% if attribute.blueprint_type == 'model' %}
        if(goog.isDef(opt_filter) && opt_filter.get{{attribute.cc}}().anyFieldsEnabled()) {
            if(this.get{{attribute.cc}}() == null)
                jsonifiedObject_["{{attribute.name}}"] = null;
            else
                jsonifiedObject_["{{attribute.name}}"] = this.get{{attribute.cc}}().getJSONObject(false, opt_filter.get{{attribute.cc}}());
        }
        else if(!goog.isDef(opt_filter)) {
            if(this.get{{attribute.cc}}() == null)
                jsonifiedObject_["{{attribute.name}}"] = null;
            else
                jsonifiedObject_["{{attribute.name}}"] = this.get{{attribute.cc}}().getJSONObject(false);
        }
    {% elif attribute.blueprint_type == 'array' %}
    {% if attribute.element_template_is_model %}
        if(goog.isDef(opt_filter) && opt_filter.get{{attribute.cc}}().anyFieldsEnabled())
            jsonifiedObject_["{{attribute.name}}"] = this.get{{attribute.cc}}().getJSONObject(false, opt_filter.get{{attribute.cc}}());
        else if(!goog.isDef(opt_filter))
            jsonifiedObject_["{{attribute.name}}"] = this.get{{attribute.cc}}().getJSONObject(false);
    {% else %}
        if(goog.isDef(opt_filter) && opt_filter.get{{attribute.cc}}())
            jsonifiedObject_["{{attribute.name}}"] = this.get{{attribute.cc}}().getJSONObject(false);
        else if(!goog.isDef(opt_filter))
            jsonifiedObject_["{{attribute.name}}"] = this.get{{attribute.cc}}().getJSONObject(false);
    {% endif %}
    {% elif attribute.blueprint_type == 'datetime' or attribute.blueprint_type == 'date' or attribute.blueprint_type == 'time' %}
        if(goog.isDef(opt_filter) && opt_filter.get{{attribute.cc}}())
            jsonifiedObject_["{{attribute.name}}"] = this.{{attribute.ccif}}_.getJSONObject();
        else if(!goog.isDef(opt_filter))
            jsonifiedObject_["{{attribute.name}}"] = this.{{attribute.ccif}}_.getJSONObject();
    {% else %}
        if(goog.isDef(opt_filter) && opt_filter.get{{attribute.cc}}())
            jsonifiedObject_["{{attribute.name}}"] = this.get{{attribute.cc}}()
        else if(!goog.isDef(opt_filter))
            jsonifiedObject_["{{attribute.name}}"] = this.get{{attribute.cc}}()
    {% endif %}
    {% endfor %}
    }

    return jsonifiedObject_;
};

/**
 * @final
 * @param {!boolean} minified
 * @param {!{{filter_namespace}}.{{name}}=} opt_filter
 *
 * @return {!string}
 */
{{namespace}}.{{name}}.prototype.getJSONString = function(minified, opt_filter) {
    return goog.json.serialize(this.getJSONObject(minified, opt_filter));
};