/**
 * @author morettip
 * paolo.moretti@valueteam.com
 */
var AgendaClosing = false;
var Agenda = {
	
	defaultOptions: {
		months			: {
			it	: new Array('GENNAIO', 'FEBBRAIO', 'MARZO', 'APRILE', 'MAGGIO', 'GIUGNO', 'LUGLIO', 'AGOSTO', 'SETTEMBRE', 'OTTOBRE', 'NOVEMBRE', 'DICEMBRE'),
			en	: new Array('JANUARY', 'FEBRUARY', 'MARCH', 'APRIL', 'MAY', 'JUNE', 'JULY', 'AUGUST', 'SEPTEMBER', 'OCTOBER', 'NOVEMBER', 'DECEMBER')
		},
		weekDaysName		: {
			it	: new Array('Lun', 'Mar', 'Mer', 'Gio', 'Ven', 'Sab', 'Dom'),
			en	: new Array('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')
		},
		monthsDaycount		: new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31),
		xmlFile			: false,
		id			: 'AppCalendar',
		returnDayOnClick	: true, 
		initDateReference	: true,
		returnField		: false,
		opener			: null,
		dateFormat		: new Template('#{day}#{sep}#{month}#{sep}#{year}'),
		dateFormatIndexer	: new Array('day', 'month', 'year'),
		dateSeparator		: '/',
		vposition		: 'bottom',
		hposition		: 'left',
		closeOnReturn		: true,
		skin			: 'invisible',
		view			: 'normal',
		locale			: 'it'
	},
	settings: {		
		dayContents		: new Array(),
		today			: new Date(),
		year			: new Date().getFullYear(),
		filters			: new Array(),
		eventsList		: new Array(),
		xmlParamsObj		: {
			year	: new Date().getFullYear(),
			month	: new Date().getMonth()+1
		}
	},
	UI: {
		app			: $('AppCalendar'),
		monthLabel		: $('monthLabel'),
		monthDaysContainer	: $('monthDays'),						// Contenitore dei giorni
		nextMonthBtn		: $('nextMonthBtn'),					// Pulsante per il mese successivo
		prevMonthBtn		: $('prevMonthBtn'),					// Pulsante per il mese precedente
		getMonthDayHolder	: function(){return new Element('li').insert(new Element('a').insert(new Element('span')))},	
		eventsDetail		: $('eventDetail'),
		getFocusTitle		: function(){ return new Element('h1') },
		focusLink		: function(){ return new Element('a').addClassName('listLink') },
		focusContainer		: function(){ return new Element('div', {id: 'singleEvent'} )},
		focusEventBox		: function(){ return new Element('div', {id: 'singleEvent'}).insert(new Element('h1').addClassName('listLink')) },
		agendaRows		: $('agenda_table_rows')
	},
	LBL: {
		Today			: 'Oggi, ',
		AddFileTip		: 'Seleziona i formati che ti interessano cliccando il tipo di file'
	},
	
	init: function(userOptions) {
		// Anni bisestili
		this.checkLead();
		// Integro le opzioni di default con quelle definite dall'utente
		this.options = Object.clone(this.defaultOptions);
		Object.extend(this.options, userOptions);
		this.UI.app.style.display = 'block';
		this.checkDateFormat();
		if(this.options.opener != null) {
			this.options.opener.style.cursor = 'pointer';
		}
		if(this.options.xmlFile)
			this.loadXML(this.options.xmlFile);
		else 
			this.buildNewAgenda();
	},
	
	checkDateFormat: function() 
	{
		if(this.options.locale == 'en') {	// Risetto il formato a mese/giorno/anno
			this.options.dateFormat = new Template('#{month}#{sep}#{day}#{sep}#{year}');
			this.options.dateFormatIndexer = new Array('month', 'day', 'year');
		} else {
			this.options.dateFormat = new Template('#{day}#{sep}#{month}#{sep}#{year}');
			this.options.dateFormatIndexer = new Array('day', 'month', 'year');
		}
	},
	
	unload: function()
	{
		this.UI.app.hide();
	},
	
	getXmlParams: function()
	{
		return "?" + Object.toQueryString(this.settings.xmlParamsObj);
	},
	
	checkLead: function()
	{
		var isLeap = new Date(this.settings.today.getFullYear(),1,29).getDate() == 29;
		if(isLeap) 
			this.defaultOptions.monthsDaycount[1] = 29;
	},
	
	loadXML: function(xmlFile) {
		AgendaBaloon.init();
		if(document.all) {
			var http = new ActiveXObject("Microsoft.XMLHTTP");
			http.open("GET", xmlFile + this.getXmlParams(), false);
			http.send(null);
			this.xmlDoc = http.responseXML;
			this.eventsList = this.xmlDoc.getElementsByTagName('item');
			// Inizializzo il primo
			this.buildNewAgenda();
		} else {
			new Ajax.Request(xmlFile + this.getXmlParams(), {method: 'get', onFailure: Agenda.handlerERROR, onSuccess: function(ajax){ Agenda.handlerXML(ajax); }});
		}
		
	},
	
	handlerXML: function(ajax) {
		if(document.all) 
			this.xmlDoc = ajax.responseText;
		else 
			this.xmlDoc = ajax.responseXML

		this.eventsList = this.xmlDoc.getElementsByTagName('item');
		// Inizializzo il primo
		this.buildNewAgenda();
	},
	
	buildNewAgenda: function(m) {
		if(this.options.view == 'mini') 
			this.UI.app.addClassName('mini');
		if(m) {
			this.settings.today = new Date(this.settings.today.getFullYear(),(this.settings.today.getMonth()+m), this.settings.today.getDate());
			
			if(this.settings.today.getFullYear() != this.settings.year) {
				// E' cambiato l'anno, devo richiedere un nuovo XML
				this.settings.year = this.settings.today.getFullYear();
				this.settings.xmlParamsObj.year = this.settings.today.getFullYear();
				this.settings.xmlParamsObj.month = this.doubbleCharDateObj(this.settings.today.getMonth() + 1);
				
			} else 
				this.settings.xmlParamsObj.month = this.doubbleCharDateObj(this.settings.today.getMonth() + 1);
			// Check id leap year
			if(this.options.xmlFile)
				this.loadXML(this.options.xmlFile);
			else 
				this.buildAgenda();
			
		} else {
			// Check id leap year
			var isLeap = new Date(this.settings.today.getFullYear(),1,29).getDate() == 29;
			if(isLeap) 
				this.options.monthsDaycount[1] = 29;
			
			this.buildAgenda(true);
		}
	},
	
	handlerERROR: function(ajax) {
		 alert('Error ' + ajax.status + ' -- ' + ajax.statusText);
	},
		
	buildAgenda: function(first) {
		if(this.options.initDateReference && first) {
			// Guardo la data del campo di riferimento e costruisco il calendario in base a quella
			var refDate = this.getDateObjFromString($(this.options.returnField).value);
			if (refDate) {
				this.settings.today.setDate(refDate.day);
				this.settings.today.setMonth(refDate.month - 1);
				this.settings.today.setFullYear(refDate.year);
			} else 
				this.settings.today = new Date();
		}

		// Setto mese e giorno
		this.UI.monthLabel.update(this.options.months[this.options.locale][this.settings.today.getMonth()] + ' ' + this.settings.today.getFullYear());
		this.options.currentMonth = this.settings.today.getMonth();
		
		// Costruisco il calendario
		var firstDay = new Date(this.settings.today.getTime() - ((this.settings.today.getDate()-1) * 24 * 60 * 60 * 1000));
		var dayOfWeek = firstDay.getDay();
		if(dayOfWeek == 0) 
			dayOfWeek = 7;

		this.UI.monthDaysContainer.update();
		var dayBuildingStarted = false;
		var actDay = 1;
		
		// Creazione calendario....
		// Creazione nomi dei giorni della settimana
		$('weekDaysHeader').update('');
		$('weekDaysHeader').insert(new Element('ul'));
		this.options.weekDaysName[this.options.locale].each(function(e, ind) {
			var wdn = new Element('li').insert(new Element('strong').update(e));
			if(ind == 5 || ind == 6)
				wdn.addClassName('fest');
			$('weekDaysHeader').down('ul').insert(wdn);
		});
		$('weekDaysHeader').insert(new Element('br').setStyle({clear: 'both'}));
		var skipBuild = false;
		
		// Inserimento giorni del mese
		for(var i=0; i<42; i++) {
			var dayHolder = this.UI.getMonthDayHolder();
			if(dayOfWeek == (i+1) || dayBuildingStarted == true && actDay <= this.options.monthsDaycount[this.options.currentMonth]) {
				dayBuildingStarted = true;
				dayHolder.id = 'agenda_day_'+actDay;
				dayHolder.down('span').update(actDay);
				dayHolder.writeAttribute('returnDate', actDay);
				var t = new Date();
				t.setMonth(this.options.currentMonth);
				t.setFullYear(this.settings.year);
				t.setDate(actDay);
				dayHolder.writeAttribute('weekday', (t.getDay() == 0 ? 6 : (t.getDay() - 1)));
				if(t.getDay() == 0 || t.getDay() == 6)
					dayHolder.addClassName('festDay');
				actDay++;
			} else {
				if (i%7==0 && dayBuildingStarted ==true) {
					skipBuild = true;
					dayHolder.down('span').update('&nbsp;');
				}
			}
			if (this.options.returnDayOnClick) {
				dayHolder.down('span').setStyle({cursor: 'pointer'});
				dayHolder.down('a').onclick = function(){
					var date = {
						day	: this.up().readAttribute('returnDate'),
						month	: ++Agenda.options.currentMonth,
						year	: Agenda.settings.year,
						sep	: Agenda.options.dateSeparator
					}
					date = Agenda.doubbleCharDateObj(date);
					$(Agenda.options.returnField).value = Agenda.options.dateFormat.evaluate(date);
					if(Agenda.options.closeOnReturn)
						Agenda.unload();
					if($(Agenda.options.returnField).updateDatagrid) 
						$(Agenda.options.returnField).updateDatagrid();
				}
			}
			if(!skipBuild) {
				this.UI.monthDaysContainer.appendChild(dayHolder);
				if(this.options.xmlFile)
					this.setDayProperties(actDay-1);
			}
		}
		// Posiziono il calendario
		if (this.options.opener) {
			var voffset = Element.getHeight(this.options.opener);
			var hoffset = Element.getWidth(this.options.opener);
			var fix = this.options.opener.viewportOffset().top;
			if (this.options.vposition == 'top') 
				voffset = -this.UI.app.getHeight();
			if (this.options.hposition == 'left') 
				hoffset = -this.UI.app.getWidth();
			this.UI.app.setStyle({
				position: 'absolute',
				zIndex: 99999999,
				background: '#fff',
				left: this.options.opener.viewportOffset().left + this.options.opener.cumulativeScrollOffset().left + hoffset + 'px',
				top: this.options.opener.viewportOffset().top + this.options.opener.cumulativeScrollOffset().top + voffset + 'px'
			}).setStyle({
				top: this.options.opener.viewportOffset().top + this.options.opener.cumulativeScrollOffset().top + voffset + 'px'
			});
		}
		// Valorizzo i bottoni
		this.UI.prevMonthBtn.onclick = function(){Agenda.buildNewAgenda(-1);}
		this.UI.nextMonthBtn.onclick = function(){Agenda.buildNewAgenda(1);}
		
		// Evento close
		if (this.options.skin == 'invisible') {
			// Se sono in configurazione invisibile, faccio chiudere il calendario al blur
			Event.observe(document.body, 'click', function(e){
				if (Event.element(e) != Agenda.UI.app &&
				Event.element(e).ancestors().indexOf(Agenda.UI.app) == -1 &&
				Event.element(e).ancestors().indexOf(Agenda.options.opener) == -1) 
					Agenda.unload();
			});
		} else 
			this.UI.app.setStyle({display: 'block'});
		if ($$('.Legenda').length > 0) 
			$$('.Legenda')[0].style.marginTop = (this.UI.monthDaysContainer.offsetHeight - 204) + 'px';
	},
	
	emailChecker: function(mail) {
		
		return mail.match(/\b(^(\S+@).+((\.com)|(\.net)|(\.edu)|(\.mil)|(\.gov)|(\.org)|(\.tv)|(\..{2,2}))$)\b/gi);
		
	},
	
	setDayProperties: function(d) {
		var dayEvents = Agenda.searchEventsByDay(d);
		if(dayEvents.length > 0 && d > 0) {
			var types = new Array();
			dayEvents.each(function(e) {
				if(e.getAttribute('type') == 4)
					var eventTypeSrc = 'event_type_4.gif';
				else if(e.getAttribute('type') == 1 || e.getAttribute('type') == 3)
					var eventTypeSrc = 'event_type_13.gif';
				else
					var eventTypeSrc = 'event_type_025.gif';
				if (Agenda.options.view == 'mini')
					eventTypeSrc = 'm_' + eventTypeSrc;
				if(types.indexOf(eventTypeSrc) == -1) {
					types.push(eventTypeSrc);
					var c = new Element('img', {src: '/shared/i/' + eventTypeSrc});
					c.setStyle({
						position	: 'absolute',
						right		: '3px',
						bottom		: (11 * (types.length-1) + 4) + 'px'
					});
					$('agenda_day_'+d).appendChild(c);
				}
			});
			$('agenda_day_'+d).observe('mousemove', function(){
				AgendaBaloon.showBaloon(this);
			});
			$('agenda_day_'+d).observe('mouseout', function(){
				AgendaBaloon.hideBaloon(this);
			});
		}
	},
	
	searchEventsByDay: function(d) {
		var eventsOnDay = new Array();
		for(var i=0; i<this.eventsList.length; i++) {
			var date = this.eventsList[i].getAttribute('date').split("-");
			if(Number(date[2]) == d) { // && parseInt(date[1]) == (this.options.currentMonth+1)
				// Evento nel giorno "d"
				eventsOnDay.push(this.eventsList[i]);
			}
		}
		return eventsOnDay;
	},
	
	searchEventsByDate: function(date) {
		var searchDate = (parseInt(date.getMonth())+1) + "-" + parseInt(date.getDate());
		var eventsOnDay = new Array();
		
		for(var i=0; i<this.eventsList.length; i++) {
			var eventDate = this.eventsList[i].getAttribute('date').split("-");
			var eventDate = parseInt(eventDate[this.options.dateFormatIndexer.indexOf('month')]) + "-" + parseInt(eventDate[this.options.dateFormatIndexer.indexOf('year')]);
			if(eventDate == searchDate) {
				// Evento nel giorno "d"
				eventsOnDay.push(this.eventsList[i]);
			}
		}
		return eventsOnDay;
	},
	
	getDateObjFromString: function(str)
	{
		if(str != '' && str != null && str != undefined) {
			var ret = str.split(this.options.dateSeparator);
			var date = {
				day	: ret[this.options.dateFormatIndexer.indexOf('day')],
				month	: ret[this.options.dateFormatIndexer.indexOf('month')],
				year	: ret[this.options.dateFormatIndexer.indexOf('year')],
				sep	: this.options.dateSeparator
			}
			return date;
		} else 
			return false;
	},
	
	doubbleCharDateObj: function(Obj)
	{
		Object.keys(Obj).each(function(k) {
			if(Number(Obj[k]) < 10) 
				Obj[k] = String('0' + Obj[k]);
		});
		return Obj;
	},
	
	doubbleCharNumber: function(n)
	{
		if(Number(n) < 10) 
			n = String('0' + n);
		return n;
	}
	
}

var AgendaBaloon = {
	
	offset_x: 66,
	offset_y: 12,
	
	init: function() {
		this.setBaloonPosition();
		$('popup_agenda').onmousemove = function() {
			AgendaBaloon.show();
			this.itemOver = false;
		}
		$('popup_agenda').onmouseout = function() {
			AgendaClosing = true;
			AgendaBaloon.hide();
		}
	},
	
	createBaloon: function()
	{
		var b = new Element('div', {id: 'popup_agenda'});
		var bc = new Element('div', {id: 'popup_agenda_content'});
		bc.insert(new Element('div', {id: 'popup_agenda_day'}));
		bc.insert(new Element('div', {id: 'popup_agenda_weekday'}));
		bc.insert(new Element('ul', {id: 'popup_agenda_list'}));
		b.insert(bc);
		b.insert(new Element('img', {width: '257', height: '29', id: 'popup_agenda_closer', src: '/shared/i/agenda_baloon_b.png'}));
		document.body.appendChild(b);
	},
	
	setBaloonPosition: function() 
	{
		//document.body.appendChild($('popup_agenda'));
	},
	
	show: function() {
		if(AgendaClosing) 
			AgendaClosing = false
		if (this.prevItemOver != this.itemOver) {
			this.populateBaloon();
			$('popup_agenda').showing = true;
			this.showing = true;
			if(Agenda.options.view != 'mini') {
				$('popup_agenda').setStyle({
					position	: 'absolute',
					left		: this.itemOver.viewportOffset().left + this.offset_x - $('popup_agenda').getDimensions().width + 'px',
					top		: this.itemOver.viewportOffset().top + this.offset_y + this.itemOver.cumulativeScrollOffset().top - $('popup_agenda').getDimensions().height + 'px',
					zIndex		: 5000,
					display		: 'block'
				});
			} else {
				$('popup_agenda').setStyle({
					position	: 'absolute',
					left		: this.itemOver.offsetLeft + this.offset_x - $('popup_agenda').offsetWidth + 'px',
					top		: this.itemOver.offsetTop + this.offset_y - $('popup_agenda').offsetHeight + 'px',
					zIndex		: 5000,
					display		: 'block'
				});
			}
		}
	},
	
	hide: function() {
		setTimeout(function(){
			if(AgendaClosing === true) {
				AgendaBaloon.prevItemOver = '##';
				this.prevItemOver = '##';
				AgendaBaloon.showing = false;
				$('popup_agenda').setStyle({
					position	: 'absolute',
					zIndex		: 5,
					top		: '-2000px'
				});
			}
		}, 100);
	},
	
	populateBaloon: function() {
		$('popup_agenda_list').update();
		$('popup_agenda_day').update(Agenda.doubbleCharNumber(this.itemOver.down('span').innerHTML));
		$('popup_agenda_weekday').update(Agenda.options.weekDaysName[Agenda.options.locale][this.itemOver.getAttribute('weekday')]);
		var events = Agenda.searchEventsByDay(this.itemOver.readAttribute('returnDate'));
		events.each(function(ev) {
			var link = new Element('li').addClassName("type" + ev.getAttribute('type'));
			link.appendChild(new Element('a', {href: ev.getElementsByTagName('link')[0].getAttribute('href')}).update(ev.getElementsByTagName('link')[0].firstChild.nodeValue))
			if(ev.getAttribute('reminder') == 'true') {
				link.setAttribute('reminderUrl', '/' + Agenda.options.locale + '/tools/alert/sendalertsingle_form.jsp?url=' + ev.getElementsByTagName('link')[0].getAttribute('href'));
				link.insert(new Element('a').addClassName('set_reminder').update('> SET REMINDER').setStyle({position: 'relative'})).observe('click', function() {
					window.location = this.getAttribute('reminderUrl');
				});
			}
			$('popup_agenda_list').appendChild(link);
		});
		$('popup_agenda_list').relativize();
		$('popup_agenda_content').setStyle({paddingBottom: '20px'});		
	},

	showBaloon: function(elem) {
		AgendaClosing = false;
		this.prevItemOver = this.itemOver;
		this.showing = true;
		this.itemOver = elem;
		this.show();
	},
	
	hideBaloon: function(elem) {
		AgendaClosing = true;
		if(this.showing === true) 
			this.hide();
	}
}