    /**
     * @class Ext.ensible.cal.EventEditForm
     * @extends Ext.form.FormPanel
     * A custom form used for detailed editing of events.
     * This is pretty much a standard form that is simply pre-configured for the options needed by the
     * calendar components. It is also configured to automatically bind records of type {@link Ext.ensible.cal.EventRecord}
     * to and from the form.
     * This form also provides custom events specific to the calendar so that other calendar components can be easily
     * notified when an event has been edited via this component.
     * The default configs are as follows:
    labelWidth: 65,
    labelWidthRightCol: 65,
    colWidthLeft: .6,
    colWidthRight: .4,
    title: 'Event Form',
    titleTextAdd: 'Add Event',
    titleTextEdit: 'Edit Event',
    titleLabelText: 'Title',
    datesLabelText: 'When',
    reminderLabelText: 'Reminder',
    notesLabelText: 'Notes',
    locationLabelText: 'Location',
    webLinkLabelText: 'Web Link',
    calendarLabelText: 'Calendar',
    repeatsLabelText: 'Repeats',
    saveButtonText: 'Save',
    deleteButtonText: 'Delete',
    cancelButtonText: 'Cancel',
    bodyStyle: 'padding:20px 20px 10px;',
    border: false,
    buttonAlign: 'center',
    autoHeight: true // to allow for the notes field to autogrow

     * @constructor
     * @param {Object} config The config object
     */
    Ext.ensible.cal.EventEditForm = Ext.extend(Ext.form.FormPanel, {
        labelWidth: 65,
        labelWidthRightCol: 65,
        colWidthLeft: .6,
        colWidthRight: .4,
        title: 'Event Form',
        titleTextAdd: 'Add Event',
        titleTextEdit: 'Edit Event',
        titleLabelText: 'Title',
        datesLabelText: 'When',
        reminderLabelText: 'Reminder',
        notesLabelText: 'Notes',
        locationLabelText: 'Location',
        webLinkLabelText: 'Web Link',
        calendarLabelText: 'Calendar',
        repeatsLabelText: 'Repeats',
        saveButtonText: 'Save',
        deleteButtonText: 'Delete',
        cancelButtonText: 'Cancel',
        bodyStyle: 'padding:20px 20px 10px;',
        border: false,
        buttonAlign: 'center',
        autoHeight: true, // to allow for the notes field to autogrow

        /* // not currently supported
         * @cfg {Boolean} enableRecurrence
         * True to show the recurrence field, false to hide it (default). Note that recurrence requires
         * something on the server-side that can parse the iCal RRULE format in order to generate the
         * instances of recurring events to display on the calendar, so this field should only be enabled
         * if the server supports it.
         */
        enableRecurrence: false,

        // private properties:
        layout: 'column',
        cls: 'ext-evt-edit-form',

        // private
        initComponent: function(){

            this.addEvents({
                /**
                 * @event eventadd
                 * Fires after a new event is added
                 * @param {Ext.ensible.cal.EventEditForm} this
                 * @param {Ext.ensible.cal.EventRecord} rec The new {@link Ext.ensible.cal.EventRecord record} that was added
                 */
                eventadd: true,
                /**
                 * @event eventupdate
                 * Fires after an existing event is updated
                 * @param {Ext.ensible.cal.EventEditForm} this
                 * @param {Ext.ensible.cal.EventRecord} rec The new {@link Ext.ensible.cal.EventRecord record} that was updated
                 */
                eventupdate: true,
                /**
                 * @event eventdelete
                 * Fires after an event is deleted
                 * @param {Ext.ensible.cal.EventEditForm} this
                 * @param {Ext.ensible.cal.EventRecord} rec The new {@link Ext.ensible.cal.EventRecord record} that was deleted
                 */
                eventdelete: true,
                /**
                 * @event eventcancel
                 * Fires after an event add/edit operation is canceled by the user and no store update took place
                 * @param {Ext.ensible.cal.EventEditForm} this
                 * @param {Ext.ensible.cal.EventRecord} rec The new {@link Ext.ensible.cal.EventRecord record} that was canceled
                 */
                eventcancel: true
            });

            this.titleField = new Ext.form.TextField({
                fieldLabel: this.titleLabelText,
                name: Ext.ensible.cal.EventMappings.Title.name,
                anchor: '90%'
            });
            this.dateRangeField = new Ext.ensible.cal.DateRangeField({
                fieldLabel: this.datesLabelText,
                singleLine: false,
                anchor: '90%',
                listeners: {
                    'change': this.onDateChange.createDelegate(this)
                }
            });
            this.reminderField = new Ext.ensible.cal.ReminderField({
                name: Ext.ensible.cal.EventMappings.Reminder.name,
                fieldLabel: this.reminderLabelText
            });
            this.notesField = new Ext.form.TextArea({
                fieldLabel: this.notesLabelText,
                name: Ext.ensible.cal.EventMappings.Notes.name,
                grow: true,
                growMax: 150,
                anchor: '100%'
            });
            this.locationField = new Ext.form.TextField({
                fieldLabel: this.locationLabelText,
                name: Ext.ensible.cal.EventMappings.Location.name,
                anchor: '100%'
            });
            this.urlField = new Ext.form.TextField({
                fieldLabel: this.webLinkLabelText,
                name: Ext.ensible.cal.EventMappings.Url.name,
                anchor: '100%'
            });

            var leftFields = [this.titleField, this.dateRangeField, this.reminderField],
                rightFields = [this.notesField, this.locationField, this.urlField];

            if(this.enableRecurrence){
                this.recurrenceField = new Ext.ensible.cal.RecurrenceField({
                    name: Ext.ensible.cal.EventMappings.RRule.name,
                    fieldLabel: this.repeatsLabelText,
                    anchor: '100%'
                });
                leftFields.splice(2, 0, this.recurrenceField);
            }

            if(this.calendarStore){
                this.calendarField = new Ext.ensible.cal.CalendarCombo({
                    store: this.calendarStore,
                    fieldLabel: this.calendarLabelText,
                    name: Ext.ensible.cal.EventMappings.CalendarId.name
                });
                leftFields.splice(2, 0, this.calendarField);
            };

            this.items = [{
                id: this.id+'-left-col',
                columnWidth: this.colWidthLeft,
                layout: 'form',
                border: false,
                items: leftFields
            },{
                id: this.id+'-right-col',
                columnWidth: this.colWidthRight,
                layout: 'form',
                labelWidth: this.labelWidthRightCol || this.labelWidth,
                border: false,
                items: rightFields
            }];

            this.fbar = [{
                text:this.saveButtonText, scope: this, handler: this.onSave
            },{
                cls:'ext-del-btn', text:this.deleteButtonText, scope:this, handler:this.onDelete
            },{
                text:this.cancelButtonText, scope: this, handler: this.onCancel
            }];

            Ext.ensible.cal.EventEditForm.superclass.initComponent.call(this);
        },

        // private
        onDateChange: function(dateRangeField, val){
            if(this.recurrenceField){
                this.recurrenceField.setStartDate(val[0]);
            }
        },

        // inherited docs
        loadRecord: function(rec){
            this.form.reset().loadRecord.apply(this.form, arguments);
            this.activeRecord = rec;
            this.dateRangeField.setValue(rec.data);

            if(this.recurrenceField){
                this.recurrenceField.setStartDate(rec.data[Ext.ensible.cal.EventMappings.StartDate.name]);
            }
            if(this.calendarStore){
                this.form.setValues({'calendar': rec.data[Ext.ensible.cal.EventMappings.CalendarId.name]});
            }

            //this.isAdd = !!rec.data[Ext.ensible.cal.EventMappings.IsNew.name];
            if(rec.phantom){
                //rec.markDirty();
                this.setTitle(this.titleTextAdd);
                Ext.select('.ext-del-btn').setDisplayed(false);
            }
            else {
                this.setTitle(this.titleTextEdit);
                Ext.select('.ext-del-btn').setDisplayed(true);
            }
            this.titleField.focus();
        },

        // inherited docs
        updateRecord: function(){
            var dates = this.dateRangeField.getValue(),
                M = Ext.ensible.cal.EventMappings,
                rec = this.activeRecord,
                fs = rec.fields,
                dirty = false;

            rec.beginEdit();

            //TODO: This block is copied directly from BasicForm.updateRecord.
            // Unfortunately since that method internally calls begin/endEdit all
            // updates happen and the record dirty status is reset internally to
            // that call. We need the dirty status, plus currently the DateRangeField
            // does not map directly to the record values, so for now we'll duplicate
            // the setter logic here (we need to be able to pick up any custom-added
            // fields generically). Need to revisit this later and come up with a better solution.
            fs.each(function(f){
                var field = this.form.findField(f.name);
                if(field){
                    var value = field.getValue();
                    if (value.getGroupValue) {
                        value = value.getGroupValue();
                    }
                    else if (field.eachItem) {
                        value = [];
                        field.eachItem(function(item){
                            value.push(item.getValue());
                        });
                    }
                    rec.set(f.name, value);
                }
            }, this);

            rec.set(M.StartDate.name, dates[0]);
            rec.set(M.EndDate.name, dates[1]);
            rec.set(M.IsAllDay.name, dates[2]);

            dirty = rec.dirty;
            //delete rec.store; // make sure the record does not try to autosave
            rec.endEdit();

            return dirty;
        },

        // private
        onCancel: function(){
            this.cleanup(true);
            this.fireEvent('eventcancel', this, this.activeRecord);
        },

        // private
        cleanup: function(hide){
            if(this.activeRecord){
                this.activeRecord.reject();
            }
            delete this.activeRecord;

            if(this.form.isDirty()){
                this.form.reset();
            }
        },

        // private
        onSave: function(){
            if(!this.form.isValid()){
                return;
            }
            if(!this.updateRecord()){
                this.onCancel();
                return;
            }
            this.fireEvent(this.activeRecord.phantom ? 'eventadd' : 'eventupdate', this, this.activeRecord);
        },

        // private
        onDelete: function(){
            this.fireEvent('eventdelete', this, this.activeRecord);
        }
    });

    Ext.reg('extensible.eventeditform', Ext.ensible.cal.EventEditForm);