/**
 * Naptár komponens
 * 
 */
var CmooTranszferCalendar = new Class ({
	// 2009.jan.1 csüt.
	/**
	 * 
	 * @var function 
	 */
	onPickDate : null,
	/**
	 * Az aktuális év
	 * @var int
	 */
	year : 2009,
	/**
	 * Az aktuális hónap
	 * @var int 
	 */
	month : 1,
	/**
	 * Az aktuális nap
	 * @var
	 */
	day: 1,
	/**
	 * A minimum év amit a naptár felvehet
	 * @var
	 */
	minYear : 1900,
	/**
	 * A minimum évben felvehető minimum hónap.
	 * @var int
	 */
	minMonth : 1,
	/**
	 * A minimum hónapban felvehető minimum nap
	 * @var int
	 */
	minDay : 1,
	/**
	 * A maximun év amit a naptár felvehet
	 * @var int
	 */
	maxYear : 2100,
	/**
	 * A maximális hónap a mit a naptár a maximum évben felvehet.
	 * @var int
	 */
	maxMonth : 12,
	/**
	 * A maximum hónapban felvehető maximum nap.
	 * @var int
	 */
	maxDay : 31,
	/**
	 * A naptárt tartalmazó konténer
	 * @var Element
	 */
	oContainer : null,
	/**
	 * Maga a naptár 
	 * @var Element
	 */
	oCalContainer : null,
	/**
	 * A honapok neveit tartalmazó tömb
	 * @var Array
	 */
	months : ['január','február','március','április','május','június','július','augusztus','szeptember','október','november','december'],
	/**
	 * A napok neveit tartalmazó tömb
	 * @var Array
	 */
	days : ['H','K','Sze','Cs','P','Szo','V'],
	/**
	 * A vasárnapi nap indexe
	 * @var int
	 */
	sunday : 6,
	/**
	 * Az egyes hónapok napjainak száma
	 * @var Array 
	 */
	mDays : [31,28,31,30,31,30,31,31,30,31,30,31],
	/**
	 * Megadja, hogy 2009 jan. 1. melyik nap indexnek felel meg.
	 * Ehhez viszonyítva jeleníti meg a napokat.
	 */
	dIndex : 3,
	/**
	 * Konstruktor
	 * @param string id
	 * @param Element oContainer A naptár szülő konténere
	 * @param int year Az aktuális év
	 * @param int month Az aktuális hónap (1-12)
	 * @param int day Az aktuális nap (1-31)
	 * @param function onPickDate Visszahívó függvény ami akkor hívódik meg, ha változik a naptár aktuális dátuma.
	 * 	A függvénynek 3 paraméterrel kell rendelkeznie. sorban: év,hó,nap
	 * @param array minDate A legkisebb dátum, amit a naptárral ki lehet választani
	 * @param array maxDate A legnagyobb dátum, amit a naptárral ki lehet választani												 
	 */
	initialize : function (id, oContainer, year, month, day, onPickDate) {
		
		
		this.id = id;
		this.oContainer = oContainer;
		this.setDate(year, month, day);
		
		
		if ($type(arguments[5] == 'function')) {
			this.onPickDate = arguments[5];
		}
		if ($type(arguments[6]) == 'array' && arguments[6].length == 3) {
			
			//  alert(this.year+'set'+arguments[6][0]);
			if (this.year!=1900)
			{
			this.setMinDate(arguments[6][0],arguments[6][1],arguments[6][2]);
			}
		}
		if ($type(arguments[7]) == 'array' && arguments[7].length == 3) {
			this.setMaxDate(arguments[7][0],arguments[7][1],arguments[7][2]);
		}
		this.createCalendar(false);
		this.hide();
	},
	/**
	 * Legyártja a naptárat, és beilleszti a szülő konténerbe.
	 * @param boolean show Megadja, hogy megjelenítse-e a naptárat.
	 */
	createCalendar : function (show) {
		this.oCalContainer = new Element ('div',{'id':this.id,'class':'ccalendar'});
		this.oCalContainer.setStyle('position','absolute');
		this.createTable(this.year, this.month);
		if (show) {
			this.show();
		}
		else {
			this.hide();
		}
		this.oCalContainer.inject(this.oContainer);
	},
	/**
	 * Összeállítja a naptár táblázatot. 
	 */
	createTable : function (year,month) {
		// lapozó sáv
		var t = new Element ('div',{'class':'tcalendar select-free', 'html':'<!--[if lte IE 6.5]><iframe></iframe><![endif]-->'});
		var nLine = new Element ('div',{'class':'navi','html':'<div class="calendar_year">'+ year +'</div><div class="calendar_month">' +this.months[month-1] + '</div>'});
		nLine.inject(t);
		var oDiv = new Element('div',{'class':'larrow','html':'&laquo;','events':{'click':function(oEvent){oEvent.stop();this.stepMonth(-1)}.bind(this)}});
		oDiv.inject (nLine,'top');
		oDiv = new Element('div',{'class':'rarrow','html':'&raquo;','events':{'click':function(oEvent){oEvent.stop();this.stepMonth(1)}.bind(this)}});
		oDiv.inject (nLine);
		// naptár
		var tr = new Element ('div',{'class':'trow day_row'});
		tr.inject(t);
		for (var i= 0; i < 7; i++) {
			new Element ('div',{'class':'th','html':this.days[i]}).inject(tr);
		}
		this.mDays[1] = this.isLeap(year) ? 29 : 28;
		var fDay = this.getFirstDay(year, month);
	
		tr = new Element ('div',{'class':'trow'});
		var befMDay = this.mDays[(month > 1 ? month-2 : 11)];
		for (i = fDay-1; i >= 0; i--) {
			new Element ('div',{'html':'&nbsp;','class':'td empty'}).inject(tr);
			
		}
		var d = 1;
		var limit;
		if (this.minYear == year && this.minMonth == month) {
			limit = 'min';
		}
		else if (this.maxYear == year && this.maxMonth == month) {
			limit = 'max';
		}
		else {
			limit = null;
		}
		i = fDay;
		tr.inject(t);
		var notd = false;
		while (d <= this.mDays[month-1]) {
			while (i < 7 && d <= this.mDays[month-1]) {
				notd = (limit == 'min' && d < this.minDay) || (limit == 'max' && d > this.maxDay);
				td = new Element ('div',{'html':d,'class':'td'+(notd ? ' no_td' : '' ),'events': (!notd ? {'click':function(oEvent){this.pickDate(oEvent);}.bind(this),'mouseover':function (){this.addClass('over');},'mouseout':function(){this.removeClass('over');}} : null)});
				td.setStyle('cursor','default');
				if (d == this.day) {
					td.addClass ('current');
				}
				if (i == this.sunday) {
					td.addClass('sunday');
				}
				td.inject(tr);
				++d;
				++i;
			}
			if (i < 7) {
				while (i++ < 7) {
					new Element ('div',{'html':'&nbsp;','class':'td empty'}).inject(tr);
				}
			}
			else {
				i = 0;
				if (d <= this.mDays[month-1]) {
					tr = new Element ('div',{'class':'trow'});
					tr.inject(t);
				}
			}	
			
		}
		tr.addClass('last_row');
		t.inject(this.oCalContainer);
		
	},
	/**
	 * Beállítja az aktuális dátumot.
	 * @param int year Az aktuális év
	 * @param int month Az aktuális hónap (1-12)
	 * @param int day Az aktuális nap (1-31)
	 */
	setDate : function (year,month,day) {
		
		day=parseInt(day);
		
		
		
	
		
		
		
		
		
		
		
		if (year < this.minYear || (this.minYear == year && (month < this.minMonth || (this.minMonth == month && day < this.minDay)))) {
	
			year = this.minYear;
			month = this.minMonth;
			day = this.minDay;
		}
		else if (year > this.maxYear || (this.maxYear == year && (month > this.maxMonth || (this.maxMonth == month && day > this.maxDay)))) {
			
			year = this.maxYear;
			month = this.maxMonth;
			day = this.maxDay;
		}
		
		this.year = year;
		this.month = month;
		this.day = day;
		if ($chk(this.oCalContainer)) {
			this.refresh();
		}	
	},
	/**
	 * Megmondja az adott évről, hogy az szökőév-e.
	 * @param int y A vizsgált év
	 */
	isLeap : function (y) {
		if (y % 400 == 0) {
			return true;
		}
		else if (y % 100 == 0) {
			return false;
		}
		else if (y % 4 == 0) {
			return true
		}
		return false;
	},
	/**
	 * Megadja, hogy az adott év adott hónapja milyen nappal kezdődik
	 * (0 : hétfő, 6: vasárnap)
	 * @param int year Az adott év
	 * @param int month Az adott hónap (1-12)
	 * @return int A nap indexe.  
	 */
	getFirstDay : function (year,month) {
		var mDays = [31,28,31,30,31,30,31,31,30,31,30,31]; 
		var days = 0;
		var index = 0
		var result = 0;
		if (year >= 2009) {
			for(var y = 2009; y < year; y++) {
				days += this.isLeap(y) ? 366 : 365;
			}
			mDays[1] = this.isLeap(year) ? 29 : 28;
			for (var m = 0; m < month-1; m++) {
				days += mDays[m];
			}
			++ days;
			index = days % 7;
			result = index + this.dIndex -1;
		}
		else {
			for (y = 2008; y > year; --y) {
				days += this.isLeap(y) ? 366 : 365;
			}
			mDays[1] = this.isLeap(y) ? 29 : 28;
			for (m = 11; m >= month-1; --m) {
				days += mDays[m];
			}
			index = days % 7;
			result = 7-index + this.dIndex ;
		}
		return result >= 7 ? result-7 : result;
	},
	/**
	 * A dátum kiválasztás eseménykezelője.
	 * @param Event oEvent Az esemény objektum.
	 */
	pickDate : function (oEvent) {
		var oDiv = oEvent.target;
		if ($chk(oDiv)) {
			var day = oDiv.get('html');
			  
			if ((this.year == this.minYear && this.month == this.minMonth && day < this.minDay) || (this.year == this.maxYear && this.month == this.maxMonth && day > this.maxDay)) {
				return;
			}
			this.day = day;
			this.refresh();
			if ($type(this.onPickDate) == 'function' && $type(oDiv) == 'element') {
				this.onPickDate(this.year,this.month,this.day);
				this.hide();
			}
		}	
	},
	/**
	 * Frissíti a naptárat.
	 */
	refresh : function () {
		var show = this.oCalContainer.get('display') == 'block';
		this.oCalContainer.destroy();
		this.createCalendar(show);
	},
	/**
	 * Elrejti a naptárat.
	 */
	hide : function () {
		this.oCalContainer.setStyle('display','none');
		valendar_open=false;
	},
	/**
	 * Megjeleníti a naptárat.
	 */
	show : function () {
		//alert('show');
		// minden naptar bezarasa
		$each($$('div[class=ccalendar]'), function(cal){
			cal.setStyle('display','none');
		});
		this.oCalContainer.setStyle('display','block');
		// pozicionálás
		var a = null;
		if ($chk(a = this.oContainer.getElement('a'))) {
			var aC = a.getCoordinates();
			this.oCalContainer.setStyles({
				'left' : aC.right - this.oCalContainer.getSize().x,
				'top' : aC.bottom
			});
		}

	},
	/**
	 * Ki-Be kapcsolja a naptár megjelenítését. 
	 */
	toggle : function () {
		if (this.oCalContainer.getStyle('display') == 'none') {
			this.show();
		}
		else {
			this.hide();
		}
		//this.oCalContainer.setStyle('display',(this.oCalContainer.getStyle('display') == 'none' ? 'block' : 'none'));
	},
	/**
	 * Lépteti a hónapot. Ha alul illetve felül csordul, akkor átlép az előző, illetve következő évre.
	 * @param int s Ha negatív akkor visszafelé léptet, egyébként előre.
	 */
	stepMonth : function (s) {
		var ds = false;
		if (s < 0 && (this.year > this.minYear || (this.year == this.minYear && this.month > this.minMonth))) {
			if (this.month > 1) {
				--this.month;
			}
			else {
				--this.year;
				this.month = 12;
			}
			ds = true;
		}
		else if (s > 0 && (this.year < this.maxYear || (this.year == this.maxYear && this.month < this.maxMonth))) {
			
			if (this.month < 12) {
				++this.month;
			}
			else {
				++this.year;
				this.month = 1;
			}
			ds = true;
		}
		if (ds) {
			this.mDays[1] = this.isLeap(this.year) ? 29 : 28;
			if (this.mDays[this.month-1] < this.day) {
				this.day = this.mDays[this.month-1];
			}
			if ($type(this.onPickDate) == 'function') {
				this.onPickDate(this.year,this.month,this.day);
			}
			this.refresh();
		}	
		this.show();
	},

	/**
	 * Beállítja a naptár alsó korlátját.
	 * @param int year
	 * @param int month
	 * @param int day
	 */
	setMinDate : function (year,month,day) {
		
		
		this.minYear = year;
		this.minMonth = month;
		this.minDay = day;
		if ( this.year < year || (this.year == year && (this.month < month || (this.month == month && (this.day < day )  )))) {
			this.setDate(year, month, day);
			if ($type(this.onPickDate) == 'function') {
				this.onPickDate(this.year,this.month,this.day);
			}
		}
		
	},
	/**
	 * Beállítja a naptár felső korlátját.
	 * @param int year
	 * @param int month
	 * @param int day
	 */
	setMaxDate : function (year,month,day) {
		// alert("set max "+year+"|"+month+"|"+day);
		this.maxYear = year;
		this.maxMonth = month;
		this.maxDay = day;
		if (this.year > year || (this.year == year && (this.month > month || (this.month == month && this.day > day)))) {
			this.setDate(year, month, day);
			if ($type(this.onPickDate) == 'function') {
				this.onPickDate(this.year,this.month,this.day);
			}
		}
	},
	/**
	 * Összehasonlítja a paraméterül kapott naptárral a dátumot
	 * @return int Ha megegyeznak akkor 0, ha ez korábbi akkor negatív, ha a paraméter korábbi akkor pozitív.
	 */
	cmp : function (oCalendar) {
		var res = 0;
		if ((res = this.year - oCalendar.year) == 0) {
			if ((res = this.month - oCalendar.month) == 0) {
				res = this.day - oCalendar.day;	
			}
		}
		return res;
	}
	
});
