text: (function() {
  
     var lang = YAHOO.lang, Event = YAHOO.util.Event, Dom = YAHOO.util.Dom;
  
  /**
   * A DatePicker Field.
   * @class inputEx.DatePickerField
   * @extends inputEx.DateField
   * @constructor
   * @param {Object} options No added option for this field (same as DateField)
   * <ul>
   *   <li>calendar: yui calendar configuration object</li>
   * </ul>
   */
  inputEx.DatePickerField = function(options) {
     inputEx.DatePickerField.superclass.constructor.call(this,options);
  };
  
  lang.extend(inputEx.DatePickerField, inputEx.DateField, {
     /**
      * Set the default date picker CSS classes
      * @param {Object} options Options object (inputEx inputParams) as passed to the constructor
      */
     setOptions: function(options) {
        inputEx.DatePickerField.superclass.setOptions.call(this, options);
        
        // Overwrite options
        this.options.className = options.className ? options.className : 'inputEx-Field inputEx-DateField inputEx-PickerField inputEx-DatePickerField';
        this.options.readonly = true;
        
        // Added options
        this.options.calendar = options.calendar || inputEx.messages.defautCalendarOpts;
     },
     
     /**
      * Render the input field and the minical container
      */
     renderComponent: function() {
        
        inputEx.DatePickerField.superclass.renderComponent.call(this);
        
        
        // Create overlay
        this.oOverlay = new YAHOO.widget.Overlay(Dom.generateId(), { visible: false });
        this.oOverlay.setBody(" ");
        this.oOverlay.body.id = Dom.generateId();
        
        // Create button
        this.button = new YAHOO.widget.Button({ type: "menu", menu: this.oOverlay, label: "&nbsp;&nbsp;&nbsp;&nbsp;" });       
        this.button.appendTo(this.wrapEl);
              
        // Render the overlay
        this.oOverlay.render(this.wrapEl);
        // HACK: Set position absolute to the overlay
        Dom.setStyle(this.oOverlay.body.parentNode, "position", "absolute");
        
        
        Event.addListener(this.el,'click',function(){
           // calendar may not have been rendered yet
           this.renderCalendar();
           
           if (!this.oOverlay.justHidden) {
              this.button._showMenu();
           }
        },this,true);
        
        this.oOverlay.hideEvent.subscribe(function() {
           this.oOverlay.justHidden = true;
           YAHOO.lang.later(250,this,function(){this.oOverlay.justHidden=false;});
        },this,true);
        
        
        // Subscribe to the first click
        this.button.on('click', this.renderCalendar, this, true);
     },
  
     
     /**
      * Called ONCE to render the calendar lazily
      */
     renderCalendar: function() {
        // if already rendered, ignore call
        if (!!this.calendarRendered) return;
        
        // Render the calendar
        var calendarId = Dom.generateId();
        this.calendar = new YAHOO.widget.Calendar(calendarId,this.oOverlay.body.id, this.options.calendar );
        
        
        /*
        this.calendar.cfg.setProperty("DATE_FIELD_DELIMITER", "/");
        this.calendar.cfg.setProperty("MDY_DAY_POSITION", 1);
        this.calendar.cfg.setProperty("MDY_MONTH_POSITION", 2);
        this.calendar.cfg.setProperty("MDY_YEAR_POSITION", 3);
        this.calendar.cfg.setProperty("MD_DAY_POSITION", 1);
        this.calendar.cfg.setProperty("MD_MONTH_POSITION", 2);*/
  
        // localization
        if(inputEx.messages.shortMonths) this.calendar.cfg.setProperty("MONTHS_SHORT", inputEx.messages.shortMonths);
        if(inputEx.messages.months) this.calendar.cfg.setProperty("MONTHS_LONG", inputEx.messages.months);
        if(inputEx.messages.weekdays1char) this.calendar.cfg.setProperty("WEEKDAYS_1CHAR", inputEx.messages.weekdays1char);
        if(inputEx.messages.shortWeekdays) this.calendar.cfg.setProperty("WEEKDAYS_SHORT", inputEx.messages.shortWeekdays);
        
        // HACK to keep focus on calendar/overlay 
        // so overlay is not hidden when changing page in calendar
        // (inspired by YUI examples)
        var focusDay = function () {
  
           var oCalendarTBody = Dom.get(calendarId).tBodies[0],
              aElements = oCalendarTBody.getElementsByTagName("a"),
              oAnchor;
  
           if (aElements.length > 0) {
           
              Dom.batch(aElements, function (element) {
                 if (Dom.hasClass(element.parentNode, "today")) {
                    oAnchor = element;
                 }
              });
              
              if (!oAnchor) {
                 oAnchor = aElements[0];
              }
  
              // Focus the anchor element using a timer since Calendar will try 
              // to set focus to its next button by default
              
              lang.later(0, oAnchor, function () {
                 try {
                    oAnchor.focus();
                 }
                 catch(e) {}
              });
           
           }
           
        };
  
        // Set focus to either the current day, or first day of the month in 
        // the Calendar when the month changes (renderEvent is fired)
        this.calendar.renderEvent.subscribe(focusDay, this.calendar, true);
        
        // Open minical on correct date / month if field contains a value
        this.oOverlay.beforeShowEvent.subscribe(this.beforeShowOverlay, this, true);
        
        // Render the calendar on the right page !
        //    ->  this.calendar.render(); is not enough...
        this.beforeShowOverlay();
        
        this.calendar.selectEvent.subscribe(function (type,args,obj) {
           // HACK: stop here if called from beforeShowOverlay
           if (!!this.ignoreBeforeShowOverlayCall) { return; }
           
           this.oOverlay.hide();
           var date = args[0][0];
           var year = date[0], month = date[1], day = date[2];
           
           // set value (updatedEvt fired by setValue)
           this.setValue(new Date(year,month-1, day) );
           
        }, this, true);
        
        // Unsubscribe the event so this function is called only once
        this.button.unsubscribe("click", this.renderCalendar); 
        
        this.calendarRendered = true;
     },
     
     // Select the right date and display the right page on calendar, when the field has a value
     beforeShowOverlay: function() {
        var date = this.getValue(true);
        if (!!this.calendar) {
           
  			if(!!date) {
           	// HACK: don't fire Field updatedEvt when selecting date
           	this.ignoreBeforeShowOverlayCall = true;
           	// select the previous date in calendar
          		this.calendar.select(date);
  				this.ignoreBeforeShowOverlayCall = false;
           	this.calendar.cfg.setProperty("pagedate",(date.getMonth()+1)+"/"+date.getFullYear());
  			}
  
           this.calendar.render(); // refresh calendar
        }
     }
     
  });
  
  inputEx.messages.defautCalendarOpts = { navigator: true };
  
  // Register this class as "datepicker" type
  inputEx.registerType("datepicker", inputEx.DatePickerField);
  
  })();