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.BucketDetails = classRef = superRef.extend({
            defaults: _.extend(
                {},
                superProto.defaults,
                {
                    id: null,

                    heatId: null,
                    heatName: null,

                    comments: null,
                    gradeId: null,
                    gradeName: null,
                    sampleIdCode: null,
                    timestamp: null,
                    typeCode: null,
                }
            ),
            procedures: {
                create: app.DatabaseNames.MES + '.LAB.CreateChemistrySampleManual',
                get: app.DatabaseNames.MES + '.LAB.GetChemistrySamples',
                update: app.DatabaseNames.MES + '.LAB.UpdateChemistrySampleManual',
                remove: app.DatabaseNames.MES + '.LAB.RemoveChemistrySample',
            },

            parse: function (obj, objSpecs) {
                var ret = {};

                if (objSpecs) {
                    _.each(app.chemistryElements, function (el) {
                        ret[el] = obj[el];

                        _.each(objSpecs, function (objSpec) {
                            ret[objSpec.SpecTypeCode.toLowerCase() + el] = objSpec[el];
                        });
                    });
                }
                else {
                    _.each(app.chemistryElements, function (el) {
                        ret[el] = obj[el];
                    });
                }


                _.each(app.chemistryCalculatedElements, function (el) {
                    ret[el] = obj[el];
                });


                return _.extend(
                    ret,
                    {
                        id: obj.Id,

                        heatId: obj.HeatId,
                        heatName: obj.HeatName,

                        comments: obj.Comments,
                        gradeId: obj.GradeId,
                        gradeName: obj.GradeName,
                        sampleIdCode: obj.SampleIdCode,
                        timestamp: obj.TimestampString,
                        typeCode: obj.TypeCode,
                    }
                );
            },
            parseResponse: function (resp, opt) {
                if ((resp) && (resp.Table) && (resp.Table1)) {
                    this.set(
                        this.parse(resp.Table[0], resp.Table1),
                        _.extend({}, opt, { from: 'fetch' })
                    );

                    return true;
                }

                return false;
            },
        });
    })();

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

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

        Main.Collections.BucketsDetails = classRef = superRef.extend({
            model: Main.Models.BucketDetails,
            comparator: 'timestamp',

            parseResponse: function (resp, opt) {
                if ((resp) && (resp.Table) && (resp.Table1)) {
                    var that = this,
                        newColl;

                    newColl = _.map(resp.Table, function (obj) {
                            return that.model.prototype.parse(
                                obj,
                                _.where(resp.Table1, { GradeVersionId: obj.GradeVersionId, })
                            );
                        });

                    var method = ((opt.refresh) || ((opt.reset))) ? 'set' : 'add';

                    var editingItems = _.where(this.toJSON(), { isNew: true });
                    [].push.apply(newColl, editingItems);

                    this[method](newColl, { from: 'fetch' });

                    return true;
                }

                return false;
            },
        });
    })();

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

});