/*
  backgrid-calendar-cell 1.0.0
*/
(function (root, factory) {

  if (typeof define === 'function' && define.amd) {
    // AMD
    define(["underscore", "backgrid", "moment"], factory);
  } else if (typeof exports === 'object') {
    // CommonJS
    module.exports = factory(require("underscore"), require("backgrid"),
                             require("moment"));
  } else {
    // Browser globals
    factory(root._, root.Backgrid, root.moment);
  }

}(this, function (_, Backgrid, moment) {

    //Fix require config issue with Underscore.
    if (!_)
        _ = this._;

    Backgrid.Extension.CalendarCellEditor = Backgrid.InputCellEditor.extend({
        showOn: "focus",
        showOtherMonths: true,
        selectOtherMonths: true,
        dateFormat: "yy-mm-dd",
        momentFormat: "YYYY-MM-DD",
        events: {
            //"blur": "saveOrCancel",
            "keydown": "input_keyDown",
        },
        render: function () {
            var that = this; 
            var model = this.model;

            //Get picker options
            var pickerOpt = {
                beforeShow: _.bind(this.datepicker_onBeforeShow, this),
                onClose: _.bind(this.datepicker_onClose, this),
                onSelect: _.bind(this.datepicker_onSelect, this),
            };

            _.each($.datepicker._defaults, function (value, key) { if (typeof(that[key]) != 'undefined') pickerOpt[key] = that[key]; });

            this.$el.datepicker(pickerOpt);
                            
            var cm = moment(this.formatter.fromRaw(model.get(this.column.get("name")), model), this.momentFormat);

            if (cm.isValid())
                this.$el.datepicker("setDate", cm.format(this.momentFormat));

            //this.$el.val(this.formatter.fromRaw(model.get(this.column.get("name")), model));

            return this;
        },
        save: function(e){
            var formatter = this.formatter;
            var model = this.model;
            var column = this.column;

            var command = new Backgrid.Command(e);
            var blurred = e.type === "blur";

            e.preventDefault();
            e.stopPropagation();

            var val = moment(this.$el.datepicker("getDate")).format(this.momentFormat);

            var newValue = formatter.toRaw(val, model);

            if (_.isUndefined(newValue)) {
                model.trigger("backgrid:error", model, column, val);
            }
            else {
                model.set(column.get("name"), newValue);
                //model.trigger("backgrid:edited", model, column, command);
            }
        },
        edited: function (e) {
            var model = this.model;
            var column = this.column;

            var command = new Backgrid.Command(e);

            // undo
            e.stopPropagation();
            model.trigger("backgrid:edited", model, column, command);
        },

        datepicker_onBeforeShow: function () {},
        datepicker_onClose: function () {
            try {
                this.edited($.Event("keydown", { keyCode: 27 }));
            }
            catch (Error) { console.error(Error.stack); }
        },
        datepicker_onSelect: function () {
            try {
                this.save($.Event("keydown", { keyCode: 13 }));
            }
            catch (Error) { console.error(Error.stack); }
        },
        input_keyDown: function (e) {
            try {
                var keyCode = e.which || e.keyCode;

                if (keyCode == 13)
                    this.save($.Event("keydown", { keyCode: 13 }));
            }
            catch (Error) { console.error(Error.stack); }
        },
    });

    Backgrid.Extension.DatetimeToDateFormatter = DatetimeToDateFormatter = function (options) {};
    DatetimeToDateFormatter.prototype = new Backgrid.CellFormatter;
    _.extend(DatetimeToDateFormatter.prototype, {
        columnName: null,
        displayFormat: 'YYYY-MM-DD',
        modelDateFormat: 'YYYY-MM-DD',
        modelTimeFormat: 'HH:mm:ss.SSS',
        modelFormat: 'YYYY-MM-DD HH:mm:ss.SSS',

        fromRaw: function (rawData) {
            if (!rawData) return '';

            var m = new moment(rawData, this.modelFormat);

            if (m.isValid())
                return m.format(this.displayFormat);
            else
                return '';
        },
        toRaw: function (formattedData, model) {
            var dateObj = new moment(formattedData, this.displayFormat);

            if (dateObj.isValid()) {
                var value = model.get(this.columnName),
                    time;

                time = (value)
                        ? new moment(value, this.modelFormat).format(this.modelTimeFormat)
                        : new moment().format(this.modelTimeFormat);

                return dateObj.format(this.modelDateFormat) + ' ' + time;
            }
            else {
                return null;
            }
        },
    });
    DatetimeToDateFormatter.extend = Backbone.Model.extend;
}));
