{{>licenseInfo}}
{{#models}}{{#model}}

#include "{{classname}}.h"

{{#modelNamespaceDeclarations}}
namespace {{this}} {
{{/modelNamespaceDeclarations}}

{{classname}}::{{classname}}()
{
    {{#vars}}{{#isNotContainer}}{{#isPrimitiveType}}m_{{name}} = {{{defaultValue}}};
    {{/isPrimitiveType}}{{^isPrimitiveType}}{{#isString}}m_{{name}} = {{{defaultValue}}};
    {{/isString}}{{#isDateTime}}m_{{name}} = {{{defaultValue}}};
    {{/isDateTime}}{{/isPrimitiveType}}{{/isNotContainer}}{{^required}}m_{{name}}IsSet = false;
    {{/required}}{{/vars}}
}

{{classname}}::~{{classname}}()
{
}

void {{classname}}::validate()
{
    // TODO: implement validation
}

nlohmann::json {{classname}}::toJson() const
{
    nlohmann::json val = nlohmann::json::object();

    {{#vars}}{{#isPrimitiveType}}{{^isListContainer}}{{^required}}if(m_{{name}}IsSet)
    {
        val["{{baseName}}"] = m_{{name}};
    }
    {{/required}}{{#required}}val["{{baseName}}"] = m_{{name}};
    {{/required}}{{/isListContainer}}{{/isPrimitiveType}}{{#isListContainer}}{
        nlohmann::json jsonArray;
        for( auto& item : m_{{name}} )
        {
            jsonArray.push_back(ModelBase::toJson(item));
        }
        {{#required}}val["{{baseName}}"] = jsonArray;
        {{/required}}{{^required}}
        if(jsonArray.size() > 0)
        {
            val["{{baseName}}"] = jsonArray;
        }
        {{/required}}
    }
    {{/isListContainer}}{{^isListContainer}}{{^isPrimitiveType}}{{^required}}if(m_{{name}}IsSet)
    {
        val["{{baseName}}"] = ModelBase::toJson(m_{{name}});
    }
    {{/required}}{{#required}}val["{{baseName}}"] = ModelBase::toJson(m_{{name}});
    {{/required}}{{/isPrimitiveType}}{{/isListContainer}}{{/vars}}

    return val;
}

void {{classname}}::fromJson(nlohmann::json& val)
{
    {{#vars}}{{#isPrimitiveType}}{{^isListContainer}}{{^required}}if(val.find("{{baseName}}") != val.end())
    {
        {{setter}}(val.at("{{baseName}}"));
    }
    {{/required}}{{#required}}{{setter}}(val.at("{{baseName}}"));
    {{/required}}{{/isListContainer}}{{/isPrimitiveType}}{{#isListContainer}}{
        m_{{name}}.clear();
        nlohmann::json jsonArray;
        {{^required}}if(val.find("{{baseName}}") != val.end())
        {
        {{/required}}
        for( auto& item : val["{{baseName}}"] )
        {
            {{#isPrimitiveType}}m_{{name}}.push_back(item);
            {{/isPrimitiveType}}{{^isPrimitiveType}}{{#items.isString}}m_{{name}}.push_back(item);
            {{/items.isString}}{{^items.isString}}{{#items.isDateTime}}m_{{name}}.push_back(item);
            {{/items.isDateTime}}{{^items.isDateTime}}
            if(item.is_null())
            {
                m_{{name}}.push_back( {{{items.datatype}}}(nullptr) );
            }
            else
            {
                {{{items.datatype}}} newItem({{{items.defaultValue}}});
                newItem->fromJson(item);
                m_{{name}}.push_back( newItem );
            }
            {{/items.isDateTime}}{{/items.isString}}{{/isPrimitiveType}}
        }
        {{^required}}
        }
        {{/required}}
    }
    {{/isListContainer}}{{^isListContainer}}{{^isPrimitiveType}}{{^required}}if(val.find("{{baseName}}") != val.end())
    {
        {{#isString}}{{setter}}(val.at("{{baseName}}"));
        {{/isString}}{{^isString}}{{#isDateTime}}{{setter}}(val.at("{{baseName}}"));
        {{/isDateTime}}{{^isDateTime}}if(!val["{{baseName}}"].is_null())
        {
            {{{datatype}}} newItem({{{defaultValue}}});
            newItem->fromJson(val["{{baseName}}"]);
            {{setter}}( newItem );
        }
        {{/isDateTime}}{{/isString}}
    }
    {{/required}}{{#required}}{{#isString}}{{setter}}(val.at("{{baseName}}"));
    {{/isString}}{{^isString}}{{#isDateTime}}{{setter}}(val.at("{{baseName}}"));
    {{/isDateTime}}{{/isString}}{{/required}}{{/isPrimitiveType}}{{/isListContainer}}{{/vars}}
}


{{#vars}}{{^isNotContainer}}{{{datatype}}}& {{classname}}::{{getter}}()
{
    return m_{{name}};
}
{{/isNotContainer}}{{#isNotContainer}}{{{datatype}}} {{classname}}::{{getter}}() const
{
    return m_{{name}};
}
void {{classname}}::{{setter}}({{{datatype}}} value)
{
    m_{{name}} = value;
    {{^required}}m_{{name}}IsSet = true;{{/required}}
}
{{/isNotContainer}}
{{^required}}bool {{classname}}::{{nameInCamelCase}}IsSet() const
{
    return m_{{name}}IsSet;
}
void {{classname}}::unset{{name}}()
{
    m_{{name}}IsSet = false;
}
{{/required}}
{{/vars}}

{{#modelNamespaceDeclarations}}
}
{{/modelNamespaceDeclarations}}

{{/model}}
{{/models}}
