define([
  'app',
'modules/base/base',
],
function (app, Base) {

    var Main = {
        Models: {},
        Collections: {},
    };

    (function () {
        var superRef, superProto, classRef;

        superRef = Base.Models.Base;
        superProto = superRef.prototype;

        Main.Models.Process = classRef = superRef.extend({
            defaults: {
                id: null,

                comments: null,
                crewId: null,
                gradeId: 0,
                gradeName: null,
                isCurrentProcess: null,
                ladleId: 0,
                ladleName: null,
                heatId: null,
                heatName: null,
                heatStatusCode: null,
                heatStatusName: null,
                initialGradeId: 0,
                initialGradeName: null,
                productionDate: null,

                manualVariables: null,
            },

            procedures: _.extend(superProto.procedures, {
                getNext: null,
                removeManualVariable: null,
            }),

            getNextProcess: function (options) {
                var that = this,
                    opt = _.extend(
                        { error: function () { }, success: function () { }, params: {}, },
                        options
                    ),
                    qp = new QueryParameters();

                qp.Add('id', 'INT', this.get('id'));

                for (var pname in opt.params)
                    qp.Add(pname, 'VARCHAR', opt.params[pname]);

                Core.Json.CallProcedure(
                    that.procedures.getNext,
                    qp,
                    {
                        onSuccess: function (resp) {
                            try {
                                if ((resp) && (resp.Table) && (resp.Table.length > 0)) {
                                    opt.success(that, that.parse(resp.Table[0]));
                                }
                                else {
                                    var msg = (resp.Message) ? resp.Message : 'SERVER_RESPONSE_NOT_VALID';

                                    opt.error(that, msg);
                                    console.error(new Error(msg).stack);
                                }
                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                        },
                        onError: function (msg) {
                            try {
                                opt.error(msg);
                                console.error(new Error(msg).stack);
                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                        },
                        Async: opt.async,
                        Secured: true,
                    },
                    that.connectionString
                );

                return this;
            },
            parse: function (obj, objArray) {
                return {
                    id: obj.Id,

                    comments: obj.Comments,
                    crewId: obj.CrewId,
                    gradeId: obj.GradeId,
                    gradeName: obj.GradeName,
                    isCurrentProcess: obj.IsCurrentProcess,
                    ladleId: obj.LadleId,
                    ladleName: obj.LadleName,
                    heatId: obj.HeatId,
                    heatName: obj.HeatName,
                    heatStatusCode: obj.HeatStatusCode,
                    heatStatusName: obj.HeatStatusName,
                    initialGradeId: obj.InitialGradeId,
                    initialGradeName: obj.InitialGradeName,
                    productionDate: obj.ProductionDateString,

                    //Use method from prototype to not link this method with an instance of this class.
                    manualVariables: classRef.prototype.parseManualVariables(objArray),
                };
            },
            parseResponse: function (resp, opt) {
                if ((resp) && (resp.Table)) {
                    if (resp.Table.length > 0) {
                        this.set(
                            this.parse(resp.Table[0], resp.Table1),
                            _.extend({}, opt, { from: 'fetch' })
                        );
                    }

                    return true;
                }

                return false;
            },
            parseManualVariables: function (objs) {
                if (objs) {
                    return _.map(objs, function (obj) {
                        return {
                            id: obj.Id,
                            module: $.trim(obj.Module).toUpperCase(),
                            name: $.trim(obj.Name).toUpperCase(),
                            value: obj.Value,
                        };
                    });
                }
                else {
                    return [];
                }
            },
            removeManualVariable: function (options) {
                var that = this,
                    qp = new QueryParameters(),
                    opt = _.extend(
                        {
                            params: {},
                            async: true,
                        },
                        options
                    );

                qp.Add('processId', 'INT', this.get('id'));
                qp.Add('variableId', 'INT', _.findWhere(this.get('manualVariables'), { name: opt.params.variableName, }).id);

                Core.Json.CallProcedure(
                    that.procedures.removeManualVariable,
                    qp,
                    {
                        onSuccess: function (resp) {
                            if ((resp) && (resp.Table) && (resp.Table.length > 0)) {
                                var obj = that.parse(resp.Table[0], resp.Table1);

                                that.set(obj, { from: 'fetch', })
                                    .trigger('fetch', that, resp, opt);

                                opt.success(that, resp, opt);
                            }
                            else {
                                var msg = (resp.Message) ? resp.Message : 'SERVER_RESPONSE_NOT_VALID';

                                opt.error(that, msg);
                                console.error(new Error(msg).stack);
                            }
                        },
                        onError: function (msg) {
                            try {
                                opt.error(msg);
                                console.error(new Error(msg).stack);
                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                        },
                        Async: opt.async,
                        Secured: true,
                    },
                    app.ConnectionStrings.app
                );
            },
            setRawManualVariables: function (obj) {
                return this.set('manualVariables', this.parseManualVariables(obj), { from: 'fetch', });
            },
            ship: function (options) {
                var that = this,
                    qp = new QueryParameters(),
                    opt = _.extend(
                        { async: true, error: function () { }, success: function () { }, params: {}, },
                        options
                    );

                qp.Add('id', 'INT', this.get('id'));

                Core.Json.CallProcedure(
                    that.procedures.ship,
                    qp,
                    {
                        onSuccess: function (resp) {
                            if (that.parseResponse(resp, opt) == true) {
                                that.trigger('fetch', that, resp, options);

                                opt.success(that, resp, options);
                            }
                            else {
                                var msg = (resp.Message) ? resp.Message : 'SERVER_RESPONSE_NOT_VALID';

                                opt.error(that, msg);
                                console.error(new Error(msg).stack);
                            }
                        },
                        onError: function (msg) {
                            try {
                                opt.error(msg);
                                console.error(new Error(msg).stack);
                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                        },
                        Async: opt.async,
                        Secured: true,
                    },
                    that.connectionString
                );
            },
        });
    })();

    (function () {
        var superRef, superProto, classRef;

        superRef = Base.Collections.Base;
        superProto = superRef.prototype;

        Main.Collections.Processes = classRef = superRef.extend({
            model: Main.Models.Process,
        });
    })();

    // Required, return the module for AMD compliance.
    return Main;

});