Ext.onReady(function(){
	Ext.namespace('Ext.ux');

	/**
	 * @class Ext.ux.MonthPicker
	 * @extends Ext.Component
	 * A picker that allows you to select a month and year
	 * @constructor
	 * @param {Object} config Configuration options
	 * @author Joseph Kralicky
	 * @version 0.1
	 */




	Ext.ux.MonthPicker = Ext.extend(Ext.Component, {

	    format : "M, Y",
	    okText : Ext.MessageBox.buttonText.ok, 
	    cancelText : Ext.MessageBox.buttonText.cancel,
	    constrainToViewport : true,
	    monthNames : Date.monthNames,
	    value : 0,
	    noPastYears : true, // only use the current year and future years
	    useDayDate : null, // set to a number between 1-31 to use this day when creating the resulting date object (or null to use todays date or keep existing)

	    initComponent: function(){
		Ext.ux.MonthPicker.superclass.initComponent.call(this);

		this.value = this.value ?
		    this.value.clearTime() : new Date().clearTime();

		this.addEvents(
		    'select'
		);

		if(this.handler){
		    this.on("select", this.handler,  this.scope || this);
		}
	    },

	    focus : function(){
		if(this.el){
		    this.update(this.activeDate);
		}
	    },

	    onRender : function(container, position){
		var m = [ '<div style="width: 175px; height:175px;"></div>' ]
		m[m.length] = '<div class="x-date-mp"></div>';

		var el = document.createElement("div");
		el.className = "x-date-picker";
		el.innerHTML = m.join("");

		container.dom.insertBefore(el, position);

		this.el = Ext.get(el);
		this.monthPicker = this.el.down('div.x-date-mp');
		this.monthPicker.enableDisplayMode('block');

		this.el.unselectable();

		this.showMonthPicker();

		if(Ext.isIE){
		    this.el.repaint();
		}

		this.update(this.value);

	    },

	    createMonthPicker : function(){
		if(!this.monthPicker.dom.firstChild){
		    var buf = ['<table border="0" cellspacing="0">'];
		    for(var i = 0; i < 6; i++){
			buf.push(
			    '<tr><td class="x-date-mp-month"><a href="#">', this.monthNames[i].substr(0, 3), '</a></td>',
			    '<td class="x-date-mp-month x-date-mp-sep"><a href="#">', this.monthNames[i+6].substr(0, 3), '</a></td>',
			    i == 0 ?
			    '<td class="x-date-mp-ybtn" align="center"><a class="x-date-mp-prev"></a></td><td class="x-date-mp-ybtn" align="center"><a class="x-date-mp-next"></a></td></tr>' :
			    '<td class="x-date-mp-year"><a href="#"></a></td><td class="x-date-mp-year"><a href="#"></a></td></tr>'
			);
		    }
		    buf.push(
			'<tr class="x-date-mp-btns"><td colspan="4"><button type="button" class="x-date-mp-ok">',
			    this.okText,
			    '</button><button type="button" class="x-date-mp-cancel">',
			    this.cancelText,
			    '</button></td></tr>',
			'</table>'
		    );
		    this.monthPicker.update(buf.join(''));
		    this.monthPicker.on('click', this.onMonthClick, this);
		    this.monthPicker.on('dblclick', this.onMonthDblClick, this);

		    this.mpMonths = this.monthPicker.select('td.x-date-mp-month');
		    this.mpYears = this.monthPicker.select('td.x-date-mp-year');

		    this.mpMonths.each(function(m, a, i){
			i += 1;
			if((i%2) == 0){
			    m.dom.xmonth = 5 + Math.round(i * .5);
			}else{
			    m.dom.xmonth = Math.round((i-1) * .5);
			}
		    });
		}
	    },

	    showMonthPicker : function(){
		this.createMonthPicker();
		var size = this.el.getSize();
		this.monthPicker.setSize(size);
		this.monthPicker.child('table').setSize(size);

		this.mpSelMonth = (this.activeDate || this.value).getMonth();
		this.updateMPMonth(this.mpSelMonth);
		this.mpSelYear = (this.activeDate || this.value).getFullYear();
		this.updateMPYear(this.mpSelYear);

		this.monthPicker.show();
		//this.monthPicker.slideIn('t', {duration:.2});
	    },

	    updateMPYear : function(y){

		if ( this.noPastYears ) {
		    var minYear = new Date().getFullYear();
		    if ( y < (minYear+4) ) {
			y = minYear+4;
		    }
		}

		this.mpyear = y;
		var ys = this.mpYears.elements;
		for(var i = 1; i <= 10; i++){
		    var td = ys[i-1], y2;
		    if((i%2) == 0){
			y2 = y + Math.round(i * .5);
			td.firstChild.innerHTML = y2;
			td.xyear = y2;
		    }else{
			y2 = y - (5-Math.round(i * .5));
			td.firstChild.innerHTML = y2;
			td.xyear = y2;
		    }
		    this.mpYears.item(i-1)[y2 == this.mpSelYear ? 'addClass' : 'removeClass']('x-date-mp-sel');
		}
	    },

	    updateMPMonth : function(sm){
		this.mpMonths.each(function(m, a, i){
		    m[m.dom.xmonth == sm ? 'addClass' : 'removeClass']('x-date-mp-sel');
		});
	    },

	    selectMPMonth: function(m){

	    },

	    getAdjustedDate : function (year,month){
		return new Date(
		    year,
		    month,
		    this.useDayDate ? // use a specific day date?
		    (Math.min(this.useDayDate, (new Date(year, month, 1)).getDaysInMonth())) // yes, cap it to month max
		    :
		    (this.activeDate || this.value).getDate() // keep existing
		);
	    },

	    onMonthClick : function(e, t){
		e.stopEvent();
		var el = new Ext.Element(t), pn;
		if(el.is('button.x-date-mp-cancel')){
		    this.hideMonthPicker();
		    //this.fireEvent("select", this, this.value);
		}
		else if(el.is('button.x-date-mp-ok')){
		    this.update(this.getAdjustedDate(this.mpSelYear, this.mpSelMonth));
		    //this.hideMonthPicker();
		    this.fireEvent("select", this, this.value);
		}
		else if(pn = el.up('td.x-date-mp-month', 2)){
		    this.mpMonths.removeClass('x-date-mp-sel');
		    pn.addClass('x-date-mp-sel');
		    this.mpSelMonth = pn.dom.xmonth;
		}
		else if(pn = el.up('td.x-date-mp-year', 2)){
		    this.mpYears.removeClass('x-date-mp-sel');
		    pn.addClass('x-date-mp-sel');
		    this.mpSelYear = pn.dom.xyear;
		}
		else if(el.is('a.x-date-mp-prev')){
		    this.updateMPYear(this.mpyear-10);
		}
		else if(el.is('a.x-date-mp-next')){
		    this.updateMPYear(this.mpyear+10);
		}
	    },

	    onMonthDblClick : function(e, t){
		e.stopEvent();
		var el = new Ext.Element(t), pn;
		if(pn = el.up('td.x-date-mp-month', 2)){
		    this.update(this.getAdjustedDate(this.mpSelYear, pn.dom.xmonth));
		    //this.hideMonthPicker();
		    this.fireEvent("select", this, this.value);
		}
		else if(pn = el.up('td.x-date-mp-year', 2)){
		    this.update(this.getAdjustedDate(pn.dom.xyear, this.mpSelMonth));
		    //this.hideMonthPicker();
		    this.fireEvent("select", this, this.value);
		}
	    },

	    hideMonthPicker : function(disableAnim){
		Ext.menu.MenuMgr.hideAll();
	    },


	    showPrevMonth : function(e){
	       this.update(this.activeDate.add("mo", -1));
	    },


	    showNextMonth : function(e){
		this.update(this.activeDate.add("mo", 1));
	    },


	    showPrevYear : function(){
		this.update(this.activeDate.add("y", -1));
	    },


	    showNextYear : function(){
		this.update(this.activeDate.add("y", 1));
	    },

	    update : function( date ) {
		this.activeDate = date;
		this.value = date;

		if(!this.internalRender){
		    var main = this.el.dom.firstChild;
		    var w = main.offsetWidth;
		    this.el.setWidth(w + this.el.getBorderWidth("lr"));
		    Ext.fly(main).setWidth(w);
		    this.internalRender = true;

		    if(Ext.isOpera && !this.secondPass){
			main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + "px";
			this.secondPass = true;
			this.update.defer(10, this, [date]);
		    }
		}
	    },

	    setValue : function( date ) {
		this.activeDate = date;
		this.value = date;
	    }

	});

	Ext.reg('monthpicker', Ext.ux.MonthPicker);	

	Ext.ux.MonthItem = function(config){
	    Ext.ux.MonthItem.superclass.constructor.call(this, new Ext.ux.MonthPicker(config), config);

	    this.picker = this.component;
	    this.addEvents('select');

	    this.picker.on("render", function(picker){
		picker.getEl().swallowEvent("click");
		picker.container.addClass("x-menu-date-item");
	    });

	    this.picker.on("select", this.onSelect, this);
	};

	Ext.extend(Ext.ux.MonthItem, Ext.menu.Adapter, {
	    onSelect : function(picker, date){
		this.fireEvent("select", this, date, picker);
		Ext.ux.MonthItem.superclass.handleClick.call(this);
	    }
	});

	Ext.ux.MonthMenu = function(config){
	    Ext.ux.MonthMenu.superclass.constructor.call(this, config);
	    this.plain = true;
	    var mi = new Ext.ux.MonthItem(config);
	    this.add(mi);

	    this.picker = mi.picker;

	    this.relayEvents(mi, ["select"]);
	};

	Ext.extend(Ext.ux.MonthMenu, Ext.menu.Menu, {
	    cls:'x-date-menu'
	});

	Ext.ux.MonthField = function(config){
	    Ext.ux.MonthField.superclass.constructor.call(this, config);
	}

	Ext.extend(Ext.ux.MonthField, Ext.form.DateField, {
	    format : Ext.ux.MonthPicker.prototype.format,
	    noPastYears: Ext.ux.MonthPicker.prototype.noPastYears,
	    useDayDate: Ext.ux.MonthPicker.prototype.useDayDate,
	    onTriggerClick : function(){
		if(this.disabled){
		    return;
		}
		if(this.menu == null){
		    this.menu = new Ext.ux.MonthMenu();
		}
		Ext.apply(this.menu.picker, {
		    format : this.format,
		    noPastYears : this.noPastYears,
		    useDayDate : this.useDayDate
		});
		this.menu.on(Ext.apply({}, this.menuListeners, {
		    scope:this
		}));
		this.menu.picker.setValue(this.getValue() || new Date());
		this.menu.show(this.el, "tl-bl?");
	    }
	});
	
	//Ext.reg('monthfield', Ext.ux.MonthField);
});