(function($)
{
	$.fn.monthPicker = function (options)
	{
		var defaults =
		{
			prevClass			: 'prev',
			prevDisabledClass	: 'prevDisabled',
			nextClass			: 'next',
			nextDisabledClass	: 'nextDisabled',
			yearClass			: 'year',
			monthClass			: 'month',
			monthDisabledClass	: 'monthDisabled',
			monthSelectedClass	: 'monthSelected',
			from				: null,
			to					: null,
			currentFromYear		: null,
			currentFromMonth	: null,
			currentToYear		: null,
			currentToMonth		: null,
			parentClass			: null
		};

		function selectMonth (event)
		{
			var element	= $(this);
			var parent	= $(element.parents('.' + options.parentClass).get(0));
			var year	= getInt(parent.find('.' + options.yearClass).html());
			var month	= getInt(element.data('month'));
			var type	= getType(parent.attr('id'));
			var to		= type == 'To';
			var date	= getDate(!to);
			var date2	= year + '' + (month > 9 ? month : '0' + month);
			var result	= to ? date <= date2 : date2 <= date;

			if (!element.hasClass(options.monthDisabledClass) && result)
			{
				parent.find('.' + options.monthSelectedClass).removeClass(options.monthSelectedClass);
				element.addClass(options.monthSelectedClass);

				options['current' + type + 'Year']	= year;
				options['current' + type + 'Month']	= month;
			}
			
			event.preventDefault();
		}

		function gotoYear ()
		{
			var element		= $(this);
			var parent		= $(element.parents('.' + options.parentClass).get(0));
			var yearElement	= parent.find('.' + options.yearClass);
			var year		= getInt(yearElement.html());
			var okay		= false;

			if (element.hasClass(options.prevClass) && !element.hasClass(options.prevDisabledClass))
			{
				year = year - 1;
				okay = true;
			}
			else if (element.hasClass(options.nextClass) && !element.hasClass(options.nextDisabledClass))
			{
				okay = true;
				year = year + 1;
			}

			if (okay == true)
			{
				if (between(year, options.fromYear, options.toYear))
				{
					var type	= getType(parent.attr('id'));
					var month	= parent.find('.' + options.monthSelectedClass);

					yearElement.html(year);
					setDisabledMonths(parent, year);

					month.removeClass(options.monthSelectedClass);

					if (options['current' + type + 'Year'] == year)
					{
						$(parent.find('.' + options.monthClass).get(getInt(options['current' + type + 'Month']) - 1)).addClass(options.monthSelectedClass);
					}
				}
			}
		}

		function setMonthData (index)
		{
			$(this).data('month', index + 1);
		}

		function setDisabledMonths (parent, year)
		{
			var months	= parent.find('.' + options.monthClass);
			var prev	= parent.find('.' + options.prevClass);
			var next	= parent.find('.' + options.nextClass);
			
			months.removeClass(options.monthDisabledClass);
			prev.removeClass(options.prevDisabledClass);
			next.removeClass(options.nextDisabledClass);

			if (year == options.fromYear)
			{
				months.slice(0, options.fromMonth - 1).addClass(options.monthDisabledClass);
				prev.addClass(options.prevDisabledClass);
			}
			else if (year == options.toYear)
			{
				months.slice(options.toMonth).addClass(options.monthDisabledClass);
				next.addClass(options.nextDisabledClass);
			}
		}

		function between (val, min, max)
		{
			if (max < min)
			{
				return between(val, max, min);
			}

			return (val >= min && val <= max);
		}

		function getInt (num, radix)
		{
			var radix	= radix | 10;

			if (typeof num != 'number' || radix != 10)
			{
				var num		= parseInt(num.replace(/^(0+)/, ''), radix);
			}

			return num;
		}

		function getType (parentId)
		{
			return parentId.replace(options.parentClass + '_', '').replace(/\w+/g, function(a)
			{
				return a.charAt(0).toUpperCase() + a.substr(1).toLowerCase();
			});
		}

		function getDate (to)
		{
			if (to)
			{
				return (100 * getInt(options.currentToYear)) + getInt(options.currentToMonth);
			}
			else
			{
				return (100 * getInt(options.currentFromYear)) + getInt(options.currentFromMonth);
			}
		}

		options = $.extend(defaults, options);

		var date			= new Date();
		var currentDate		= [date.getFullYear(), ('0' + (date.getMonth() + 1)).substr(-2)];

		var from			= options.from ? options.from.split('-') : currentDate;
		options.fromYear	= from[0];
		options.fromMonth	= from[1];

		var to				= options.to ? options.to.split('-') : currentDate;
		options.toYear		= to[0];
		options.toMonth		= to[1];

		options.currentFromYear		= options.currentFromYear	|| options.fromYear;
		options.currentFromMonth	= options.currentFromMonth	|| options.fromMonth;
		options.currentToYear		= options.currentToYear		|| options.toYear;
		options.currentToMonth		= options.currentToMonth	|| options.toMonth;

		this.each(function()
		{
			if ($(this).data('monthPicker') == true)
			{
				return false;
			}

			$(this).data('monthPicker', true);
		
			options.parentClass = $(this).attr('id');

			var elementFrom		= $('#' + options.parentClass + '_from');
			var elementFromYear	= $(elementFrom.find('.' + options.yearClass)).html(options.fromYear);

			var elementTo		= $('#' + options.parentClass + '_to');
			var elementToYear	= $(elementTo.find('.' + options.yearClass)).html(options.toYear);

			elementFrom.find('.' + options.prevClass).addClass(options.prevDisabledClass);
			var fromMonths		= elementFrom.find('.' + options.monthClass);
			fromMonths.each(setMonthData);
			fromMonths.click(selectMonth);
			fromMonths.slice(0, options.fromMonth - 1).addClass(options.monthDisabledClass);
			$(fromMonths[options.currentFromMonth - 1]).addClass(options.monthSelectedClass);

			elementTo.find('.' + options.nextClass).addClass(options.nextDisabledClass);
			var toMonths		= elementTo.find('.' + options.monthClass);
			toMonths.each(setMonthData);
			toMonths.click(selectMonth);
			toMonths.slice(options.toMonth).addClass(options.monthDisabledClass);
			$(toMonths[options.currentToMonth - 1]).addClass(options.monthSelectedClass);

			if (options.fromYear == options.toYear)
			{
				elementFrom.find('.' + options.nextClass).addClass(options.nextDisabledClass);
				elementTo.find('.' + options.prevClass).addClass(options.prevDisabledClass);

				fromMonths.slice(options.toMonth).addClass(options.monthDisabledClass);
				toMonths.slice(0, options.fromMonth - 1).addClass(options.monthDisabledClass);
			}

			$('.' + options.parentClass + ' .' + options.prevClass + ', .' + options.parentClass + ' .' + options.nextClass).click(gotoYear);
		});
		
		$.monthPicker =
		{
			getDate : function ()
			{
				var object =
				{
					from :
					{
						year 	: getInt(options.currentFromYear),
						month	: getInt(options.currentFromMonth)
					},
					to :
					{
						year	: getInt(options.currentToYear),
						month	: getInt(options.currentToMonth)
					}
				};

				return object;
			}
		};

		return this;
	};
})(jQuery);