function CalNav (vars) {

	for (par in vars) this[par] = vars[par]

	this.initalized =	false
	this.controls =		null
	this.days =		null
	this.loader =		null
	var obj =		this
	this.curDate =		new Date(this.active)
	this.from =		new Date(this.from.setDate(this.from.getDate()-1))
	this.to =		new Date(this.to.setDate(this.to.getDate()+1))

	this.init =		function () {
					with (obj) {
						controls = cn('div')
						with (controls) {
							className = 'controls'
							appendChild(crControls('month'))
							appendChild(crControls('year'))
						}

						validateControls()

						days = cn('div')
						days.className = 'days'
						loader = cn('div')
						loader.className = 'loader'
						loader.style.display = 'block'
						loader.style.backgroundImage = 'url("../i/cal_loader.gif")'
						loader.style.width = element.parentNode.offsetWidth -2 + 'px'

						$.getJSON(
							'/common/cal/' + obj.cal_type + '/' + obj.cal_id + '/',
							{ y: obj.active.getFullYear(), m: obj.active.getMonth()+1, ajax: 1 },
							function (response) {
								obj.createDays(obj.active, response)
								element.appendChild(days)
							}
						)

						with (element) {
							appendChild(controls)
							appendChild(loader)
							onselectstart = function () { return false }
						}

						initalized = true
						show()
					}
				}

	this.crControls =	function (cls) {
					var ctr = cls.substring(0,1).toUpperCase()

					obj[ctr] = {}
					var t = obj[ctr]

					t.par = cn('span'); t.par.className = cls
						t.prew = cn('a'); nohref(t.prew); t.prew.innerHTML = '&larr;'; t.prew.hideFocus = true
						t.cur = cn('a');  nohref(t.cur);  t.cur.className = 'cur'; t.cur.hideFocus = true
						t.next = cn('a'); nohref(t.next); t.next.innerHTML = '&rarr;'; t.next.hideFocus = true

					t.cur.innerHTML = (ctr == 'M') ? obj.cMonth(obj.active) : obj.active.getFullYear()
					if (ctr == 'M') t.cur.setAttribute('rel', obj.active.getMonth())
					var step = (ctr == 'M') ? 1 : 12

					t.prew.onclick = function () { obj.list( - step, ctr) }
					t.next.onclick = function () { obj.list(step, ctr) }

					with(t.par) {
						appendChild(t.prew)
						appendChild(t.cur)
						appendChild(t.next)
					}

					return obj[ctr].par
				}

	this.createDays =	function (date, posts) {
					obj.days.innerHTML = ''
					var date = new Date(date)

					var days = date.lastDay()
					var month = date.getMonth()+1; month = (month < 10) ? '0'+month : month
					var lnkDate = '?date=' + date.getFullYear() +'-'+ month + '-'

					for (var day=1; day <= days; day++) {
						date.setDate(day)
						var cls = ''
						if (date.isHoliday()) cls = 'h'
						if (isEq(date, obj.active)) cls += ' active'
						if (!isBetween(obj.from, date, obj.to) || !posts[day]) cls += ' disabled'
						var a = cn('a')
						a.className = cls
						a.hideFocus = true
						a.href = (posts[day]) ? lnkDate + day : 'javascript: void(0)'
						a.title = (posts[day]) ? posts[day] : 'В этот день небыло написано ни одного поста'
						a.appendChild(document.createTextNode(day))
						obj.days.appendChild(a)
					}
					obj.loader.style.display = 'block'
					obj.loader.style.backgroundImage = 'url("../i/cal_loader.gif")'
					$(obj.days).fadeIn(200)

				}

	this.list = 		function (dir, ctr) { with (obj) {

					if (	obj[ctr].prew.className == 'disabled' && dir < 0
					     || obj[ctr].next.className == 'disabled' && dir > 0  ) return false

					curDate.changeMonth(dir)

					if (Math.abs(dir) > 1) {
						if (curDate < from) curDate = new Date(from)
						if (curDate > to)   curDate = new Date(to)
					}

					$(days).fadeOut(150, function () {
						$.getJSON(
							'/common/cal/' + obj.cal_type + '/' + obj.cal_id + '/',
							{ y: obj.curDate.getFullYear(), m: obj.curDate.getMonth()+1, ajax: 1 },
							function (response) {
								obj.createDays(obj.curDate, response)
							}
						)
					})

					M.cur.setAttribute('rel', curDate.getMonth())
					M.cur.innerHTML = cMonth(obj.curDate)
					Y.cur.innerHTML = curDate.getFullYear()

					validateControls()
				} }

	this.validateControls =	function () { with (obj) {
					var cur = new Date(curDate);	cur.setDate(1)
					var prew = new Date(cur);	prew.changeMonth(-1); prew.setDate(prew.lastDay())
					var next = new Date(cur);	next.changeMonth(1)
					M.prew.className = (prew < from) ? 'disabled' : ''
					M.next.className = (next > to)   ? 'disabled' : ''
					Y.prew.className = (curDate.getFullYear() <= from.getFullYear()) ? 'disabled' : ''
					Y.next.className = (curDate.getFullYear() >= to.getFullYear()) ? 'disabled' : ''
				} }

	this.cMonth = 		function (date) { return obj.customMonths[date.getMonth()] }

	this.show =		function (callback) {
					if (!obj.initalized) { obj.init(); return false }
					if (!callback) callback = function () {}
					$(obj.element).show(250, callback)
				}

	this.hide =		function () { $(obj.element).hide(250) }

	this.control.onclick =	function () {
					if (this.className != 'open') {
						this.className = 'open'; obj.show(function () { obj.loader.style.display = 'block' }) }
					else {
						this.className = ''; obj.loader.style.display = 'none'; obj.hide() }
				}
}

function cn (n){
	return document.createElement(n) }

function nohref(lnk) {
	lnk.href = 'javascript: void(0)' }

function isBetween (min, cur, max) {
	return (cur < max && cur > min ) }

function isEq (a, b) {
	return !((a > b) || (a < b)) }

Date.prototype.isHoliday = function () {
	return (!isBetween(0, this.getDay(), 6)) }

Date.prototype.lastDay = function () {
	var date = new Date(this)
	date.setDate(1)
	date.setMonth(date.getMonth() + 1 )
	date.setDate(0)
	return date.getDate()
}

Date.prototype.changeMonth = function (dir) {
	this.setMonth(this.getMonth() + dir) }
