define([], function () {

    /**
     * Field model
     * @constructor
     * @property {String} symName - field symbolic name
     * @property {String} label - field label
     * @property {Number} postiton - field postition
     */
    var Field = function(field) {"use strict";
        this.model = new Field.Model(field);
        this.view = new Field.View();
        this.model.setView(this.view);
        this.view.setModel(this.model);
    };

    Field.Model = function(field) {"use strict";
        this.view = null;
        /**
         * Field symbolic name
         * @private
         * @type {String}
         */
        this.symName = null;

        /**
         * Field label
         * @private
         * @type {String}
         */
        this.label = null;

        /**
         * Field postion
         * @private
         * @type {Number}
         */
        this.position = null;

        this.init(field);
    };

    Field.Model.prototype = (function() {"use strict";

        var setView = function(view) {
            this.view = view;
        };

        var setData = function(data) {
            setSymName.call(this, data.sym_name);
            setLabel.call(this, data.label);
            setPostiton.call(this, data.position);
        };

        var setSymName = function(symName) {
            this.symName = symName;
        };

        var getSymName = function() {
            if (_.isString(this.symName)) {
                return this.symName;
            } else {
                return '';
            }
        };

        var setLabel = function(label) {
            this.label = label;
        };

        var getLabel = function() {
            if (_.isString(this.label)) {
                return this.label;
            } else {
                return '';
            }
        };

        var setPostiton = function(position) {
            this.position = position;
        };

        var getPosition = function() {
            if (_.isNumber(this.position)) {
                return parseInt(this.position, 10);
            } else {
                return NaN;
            }
        };

        return {
            setView : setView,

            init : setData,

            symName : getSymName,

            label : getLabel,

            position : getPosition
        };
    })();

    Field.View = function() {"use strict";
        this.model = null;
    };

    Field.View.prototype = (function() {"use strict";
        var setModel = function(model) {
            this.model = model;
        };

        /**
         * Print the field label
         * @private
         * @memberOf Field.View
         * @returns {Object}
         */
        var render = function() {
            return _.template($('#field-tmpl').html())(this.model);
        };

        return {
            setModel : setModel,

            render : render
        };
    })();

    return Field;
});
