Ext.namespace('Ext.ux.form');

/**
  * Ext.ux.form.DateTime Extension Class for Ext 2.x Library
  *
  * @author    Ing. Jozef Sakalos
  * @copyright (c) 2008, Ing. Jozef Sakalos
  * @version $Id: Ext.ux.form.DateTime.js 645 2008-01-27 21:53:01Z jozo $
  *
  * @class Ext.ux.form.DateTime
  * @extends Ext.form.Field
  *
  * @history
  * 2008-1-31 Jack Slocum
  * Updated for reformatting and code edits
  */

Ext.ux.form.DateTime = Ext.extend(Ext.form.Field, {
        defaultAutoCreate
: {
                tag
: 'input',
                type
: 'hidden'
       
},
        dateWidth
: 135,
        timeWidth
: 100,
        dtSeparator
: ' ',
        hiddenFormat
: 'Y-m-d H:i:s',
        otherToNow
: true,
        timePosition
: 'right',
       
        initComponent
: function(){
               
// call parent initComponent
               
Ext.ux.form.DateTime.superclass.initComponent.call(this);
               
               
// create DateField
               
var dateConfig = Ext.apply({}, {
                        id
: this.id + '-date',
                        format
: this.dateFormat,
                        width
: this.dateWidth,
                        listeners
: {
                                blur
: {
                                        scope
: this,
                                        fn
: this.onBlur
                               
},
                                focus
: {
                                        scope
: this,
                                        fn
: this.onFocus
                               
}
                       
}
               
}, this.dateConfig);
               
this.df = new Ext.form.DateField(dateConfig);
               
delete (this.dateFormat);
               
               
// create TimeField
               
var timeConfig = Ext.apply({}, {
                        id
: this.id + '-time',
                        format
: this.timeFormat,
                        width
: this.timeWidth,
                        listeners
: {
                                blur
: {
                                        scope
: this,
                                        fn
: this.onBlur
                               
},
                                focus
: {
                                        scope
: this,
                                        fn
: this.onFocus
                               
}
                       
}
               
}, this.timeConfig);
               
this.tf = new Ext.form.TimeField(timeConfig);
               
delete (this.timeFormat);
               
               
// relay events
               
this.relayEvents(this.df, ['focus', 'specialkey', 'invalid', 'valid']);
               
this.relayEvents(this.tf, ['focus', 'specialkey', 'invalid', 'valid']);
               
       
},
        onRender
: function(ct, position){
               
if (this.isRendered) {
                       
return;
               
}
               
               
// render underlying field
               
Ext.ux.form.DateTime.superclass.onRender.call(this, ct, position);
               
               
// render DateField and TimeField
               
// create bounding table
               
if ('below' === this.timePosition) {
                       
var t = Ext.DomHelper.append(ct, {
                                tag
: 'table',
                                style
: 'border-collapse:collapse',
                                children
: [{
                                        tag
: 'tr',
                                        children
: [{
                                                tag
: 'td',
                                                style
: 'padding-bottom:1px',
                                                cls
: 'ux-datetime-date'
                                       
}]
                               
}, {
                                        tag
: 'tr',
                                        children
: [{
                                                tag
: 'td',
                                                cls
: 'ux-datetime-time'
                                       
}]
                               
}]
                       
}, true);
               
}
               
else {
                       
var t = Ext.DomHelper.append(ct, {
                                tag
: 'table',
                                style
: 'border-collapse:collapse',
                                children
: [{
                                        tag
: 'tr',
                                        children
: [{
                                                tag
: 'td',
                                                style
: 'padding-right:4px',
                                                cls
: 'ux-datetime-date'
                                       
}, {
                                                tag
: 'td',
                                                cls
: 'ux-datetime-time'
                                       
}]
                               
}]
                       
}, true);
               
}
               
               
this.tableEl = t;
               
this.wrap = t.wrap({
                        cls
: 'x-form-field-wrap'
               
});
               
this.wrap.on("mousedown", this.onMouseDown, this, {
                        delay
: 10
               
});
               
               
// render DateField & TimeField
               
this.df.render(t.child('td.ux-datetime-date'));
               
this.tf.render(t.child('td.ux-datetime-time'));
               
               
if (Ext.isIE && Ext.isStrict) {
                        t
.select('input').applyStyles({
                                top
: 0
                       
});
               
}
               
               
this.on('specialkey', this.onSpecialKey, this);
               
               
this.df.el.swallowEvent(['keydown', 'keypress']);
               
this.tf.el.swallowEvent(['keydown', 'keypress']);
               
               
// create errorIcon for side invalid
               
if ('side' === this.msgTarget) {
                       
var elp = this.el.findParent('.x-form-element', 10, true);
                       
this.errorIcon = elp.createChild({
                                cls
: 'x-form-invalid-icon'
                       
});
                       
                       
this.df.errorIcon = this.errorIcon;
                       
this.tf.errorIcon = this.errorIcon;
               
}
               
               
this.isRendered = true;
               
       
},
        getPositionEl
: function(){
               
return this.wrap;
       
},
        getResizeEl
: function(){
               
return this.wrap;
       
},
       
        adjustSize
: Ext.BoxComponent.prototype.adjustSize,
       
        alignErrorIcon
: function(){
               
this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
       
},
       
        onSpecialKey
: function(t, e){
               
if (e.getKey() == e.TAB) {
                       
if (t === this.df && !e.shiftKey) {
                                e
.stopEvent();
                               
this.tf.focus();
                       
}
                       
if (t === this.tf && e.shiftKey) {
                                e
.stopEvent();
                               
this.df.focus();
                       
}
               
}
       
},
       
        setSize
: function(w, h){
               
if (!w) {
                       
return;
               
}
               
if ('below' == this.timePosition) {
                       
this.df.setSize(w, h);
                       
this.tf.setSize(w, h)
                       
if (Ext.isIE) {
                               
this.df.el.up('td').setWidth(w);
                               
this.tf.el.up('td').setWidth(w);
                       
}
               
}
               
else {
                       
this.df.setSize(w - this.timeWidth - 4, h);
                       
this.tf.setSize(this.timeWidth, h);
                       
                       
if (Ext.isIE) {
                               
this.df.el.up('td').setWidth(w - this.timeWidth - 4);
                               
this.tf.el.up('td').setWidth(this.timeWidth);
                       
}
               
}
               
       
},
       
        setValue
: function(val){
               
if (!val) {
                       
this.setDate('');
                       
this.setTime('');
                       
this.updateValue();
                       
return;
               
}
               
// clear cross frame AIR nonsense
                val
= new Date(val.getTime());
               
var da, time;
               
if (Ext.isDate(val)) {
                       
this.setDate(val);
                       
this.setTime(val);
                       
this.dateValue = new Date(val);
               
}
               
else {
                        da
= val.split(this.dtSeparator);
                       
this.setDate(da[0]);
                       
if (da[1]) {
                               
this.setTime(da[1]);
                       
}
               
}
               
this.updateValue();
       
},
       
        getValue
: function(){
               
// create new instance of date
               
return this.dateValue ? new Date(this.dateValue) : '';
       
},
       
        onMouseDown
: function(e){
               
// just to prevent blur event when clicked in the middle of fields
               
this.wrapClick = 'td' === e.target.nodeName.toLowerCase();
       
},
       
        onFocus
: function(){
               
if (!this.hasFocus) {
                       
this.hasFocus = true;
                       
this.startValue = this.getValue();
                       
this.fireEvent("focus", this);
               
}
       
},
       
        onBlur
: function(f){
               
// called by both DateField and TimeField blur events
               
               
// revert focus to previous field if clicked in between
               
if (this.wrapClick) {
                        f
.focus();
                       
this.wrapClick = false;
               
}
               
               
// update underlying value
               
if (f === this.df) {
                       
this.updateDate();
               
}
               
else {
                       
this.updateTime();
               
}
               
this.updateHidden();
               
               
// fire events later
               
(function(){
                       
if (!this.df.hasFocus && !this.tf.hasFocus) {
                               
var v = this.getValue();
                               
if (String(v) !== String(this.startValue)) {
                                       
this.fireEvent("change", this, v, this.startValue);
                               
}
                               
this.hasFocus = false;
                               
this.fireEvent('blur', this);
                       
}
               
}).defer(100, this);
               
       
},
        updateDate
: function(){
       
               
var d = this.df.getValue();
               
if (d) {
                       
if (!Ext.isDate(this.dateValue)) {
                               
this.initDateValue();
                               
if (!this.tf.getValue()) {
                                       
this.setTime(this.dateValue);
                               
}
                       
}
                       
this.dateValue.setFullYear(d.getFullYear());
                       
this.dateValue.setMonth(d.getMonth());
                       
this.dateValue.setDate(d.getDate());
               
}
               
else {
                       
this.dateValue = '';
                       
this.setTime('');
               
}
       
},
        updateTime
: function(){
               
var t = this.tf.getValue();
               
if (t && !Ext.isDate(t)) {
                        t
= Date.parseDate(t, this.tf.format);
               
}
               
if (t && !this.df.getValue()) {
                       
this.initDateValue();
                       
this.setDate(this.dateValue);
               
}
               
if (Ext.isDate(this.dateValue)) {
                       
if (t) {
                               
this.dateValue.setHours(t.getHours());
                               
this.dateValue.setMinutes(t.getMinutes());
                               
this.dateValue.setSeconds(t.getSeconds());
                       
}
                       
else {
                               
this.dateValue.setHours(0);
                               
this.dateValue.setMinutes(0);
                               
this.dateValue.setSeconds(0);
                       
}
               
}
       
},
        initDateValue
: function(){
               
this.dateValue = this.otherToNow ? new Date() : new Date(1970, 0, 1, 0, 0, 0);
       
},
        updateHidden
: function(){
               
if (this.isRendered) {
                       
var value = Ext.isDate(this.dateValue) ? this.dateValue.format(this.hiddenFormat) : '';
                       
this.el.dom.value = value;
               
}
       
},
        updateValue
: function(){
       
               
this.updateDate();
               
this.updateTime();
               
this.updateHidden();
               
               
return;
               
       
},
        setDate
: function(date){
               
this.df.setValue(date);
       
},
        setTime
: function(date){
               
this.tf.setValue(date);
       
},
        isValid
: function(){
               
return this.df.isValid() && this.tf.isValid();
       
},
        validate
: function(){
               
return this.df.validate() && this.tf.validate();
       
},
        focus
: function(){
               
this.df.focus();
       
},
       
        onDisable
: function(){
               
if(this.rendered){
                       
this.df.disable();
                       
this.tf.disable();
               
}
       
},
       
        onEnable
: function(){
               
if(this.rendered){
                       
this.df.enable();
                       
this.tf.enable();
               
}
       
}
});

// register xtype
Ext.reg('xdatetime', Ext.ux.form.DateTime);