ProspectDirector.Web.UI.Queries.Condition = Class.extend({

    //================================
    // FIELDS
    //================================

    _conditions: null,
    _filters: null,
    _parent: null,

    //================================
    // CONSTRCUTOR
    //================================

    init: function (options) {

        options = $.extend(true, {}, {
            data: {
                id: uuid.v4(),
                conditions: [],
                filters: [],
                isEnabled: true,
                operatorName: "AND",
                role: "condition",
                color: ProspectDirector.Web.UI.Utilities.ColorWheel.next()
            }
        }, options);

        ProspectDirector.Web.Structure.mixin(options.data, this);

        this.data("checked", this.data("isEnabled"));

        this._fill();

    },

    //================================
    // CONSTRCUTOR
    //================================

    get_id: function () {
        return this.data("id");
    },

    get_conditions: function () {
        return this._conditions;
    },

    get_filters: function () {
        return this._filters;
    },

    get_isEnabled: function () {
        return this.data("isEnabled");
    },

    get_operator: function () {
        return this.data("operatorName");
    },

    get_role: function () {
        return this.data("role");
    },

    get_parent: function () {
        return this._parent;
    },

    //================================
    // PUBLIC METHODS
    //================================

    add: function (constraint) {

        constraint.remove();

        switch (constraint.get_role()) {
            case "condition":
                this.get_conditions().add(constraint);
                break;
            case "filter":
                this.get_filters().add(constraint);
                break;
        }

    },

    remove: function () {
        if (this.get_parent()) {
            this.get_parent().get_conditions().remove(this);
        }
    },

    update: function (data) {
        this.data().update(data);
    },

    findById: function (id) {

        var result = null;

        result = this.get_filters().findById(id);

        if (!result) {
            result = this.get_conditions().findById(id);
        }

        return result;

    },

    toJSON: function () {

        this.data("conditions", this.get_conditions().toJSON());
        this.data("filters", this.get_filters().toJSON());

        return this.data().toObject();

    },

    hasConstraints: function () {
        return this.get_conditions().count() > 0 && this.get_filters().count();
    },

    getCounts: function () {

        var filters = this.get_filters().count(),
            conditions = this.get_conditions().count();

        this.get_conditions().each(function (index, condition) {
            var counts = condition.getCounts();
            filters += counts.filters;
            conditions += counts.conditions;
        });

        return {
            filters: filters,
            conditions: conditions
        };

    },

    isFirst: function () {
        return this.get_parent() === null
            || this.get_parent().get_conditions().first().get_id() === this.get_id();
    },

    isLast: function () {
        return this.get_parent() === null
            || this.get_parent().get_conditions().last().get_id() === this.get_id();
    },

    //================================
    // PRIVATE METHODS
    //================================

    _fill: function () {

        var that = this,
            fData = new ProspectDirector.Web.List(this.data("filters")),
            cData = new ProspectDirector.Web.List(this.data("conditions"));

        fData = fData.transform(function (data) {
            return new ProspectDirector.Web.UI.Queries.Filter({
                data: data
            });
        });

        cData = cData.transform(function (data) {
            return new ProspectDirector.Web.UI.Queries.Condition({
                data: data
            });
        });

        this._filters = new ProspectDirector.Web.UI.Queries.FilterCollection({
            condition: this,
            data: fData.toArray()
        });

        this._conditions = new ProspectDirector.Web.UI.Queries.ConditionCollection({
            condition: this,
            data: cData.toArray()
        });

    }

});