$(function(){
	
	$.fn.jsdate = function(c) {
		
		var elm = $(this); // DOM element of function REQUIRED
		var obj = this; // this class REQUIRED
		
		var dom = {};
		var events = {};
		var eventDate;
		var eventFilters = '';
		
		__construct = function() {
			c.dict				= (c.dict!==undefined) ? c.dict : {} ;
			c.dict.days			= (c.dict.days!==undefined) ? c.dict.days : ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'] ;
			c.dict.months		= (c.dict.months!==undefined) ? c.dict.months : ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'septembre', 'oktobre', 'novembre', 'decembre'] ;
			c.activeDate		= (c.activeDate!==undefined) ? c.activeDate : date('Y-m-d') ;
			c.startDate			= (c.startDate!==undefined) ? c.startDate : false ;
			c.endDate			= (c.endDate!==undefined) ? c.endDate : false ;
			c.type				= (c.type!==undefined) ? c.type : 'input' ;
			c.eventsUrl			= (c.eventsUrl!==undefined) ? c.eventsUrl : false ;
			c.name 				= elm.attr('name');
			
			switch (c.type) {
				case 'canvas': 
					obj.open();
				break;
				default: 
					elm.focus( function() {
						obj.open();
					});
				break;
			}
			
			eventDate = c.activeDate;
		};
		
		
		obj.open = function() {
			c.activeDate			= (dom.output!==undefined && dom.output.val().length>0) ? dom.output.val() : c.activeDate ;
			
			html('setup');
			
			if (c.eventsUrl===false) {
				obj.buildcalender(c.activeDate);
			} else {
				obj.loadevents(c.activeDate);
			}
			
			elm.attr({ name: c.name + '_dummy' });
			if (dom.output===undefined) html('output');
			
			actions();
		};
		
		obj.close = function(object) {
			if (!object) object = dom.wrapper;
			object.find('*').each( function(){
				$(this).unbind();
				$(this).remove();
			});
			
			object.remove();
		};
		
		obj.loadevents = function(date, filter) {
			if ($('#jsdate-wrapper').length>0) cleandays();
			if (!date) date = eventDate;
			
			/*
			if (!filter) filter = eventFilters;
			
			eventFilters = filter; // store filter
			$.getJSON(c.eventsUrl + '&date=' + date + '&filter=' + rawurlencode(filter), function(data){
			*/
			$.getJSON(c.eventsUrl + '&date=' + date + '&filter=', function(data){
				events = data;
				//alert(date);
				obj.buildcalender(date);
			});
		};
		
		var cleandays = function() {
			dom.days.find('*:not(.jsdate-days-day.head)').each( function(){
				$(this).unbind();
				$(this).remove();
			});
		};
		
		var html = function(action, attr) {
			var object; 
			if (!attr) attr = {};
			
			switch (action) {
				case 'setup':
					if ($('#jsdate-wrapper').length>0) obj.close($('#jsdate-wrapper'));
					
					switch (c.type) {
						case 'canvas': 
							dom.wrapper = $('<div id="jsdate-wrapper"/>').appendTo(elm);
						break;
						default: 
							dom.wrapper = $('<div id="jsdate-wrapper"/>').appendTo('body');
					
							dom.wrapper.css({
								position: 'absolute',
								zIndex: 999,
								top: (elm.offset().top) + 'px',
								left: (elm.offset().left + elm.width() + 10) + 'px'
							});
						break;
					}
					
					
					dom.menu = $('<div class="jsdate-menu"/>').appendTo(dom.wrapper);
					dom.prev = $('<a class="jsdate-menu-prev"/>').appendTo(dom.menu);
					dom.title = $('<input type="text" class="jsdate-menu-title"/>').appendTo(dom.menu);
					
					dom.next = $('<a class="jsdate-menu-next"/>').appendTo(dom.menu);
					
					dom.days = $('<div class="jsdate-days"/>').appendTo(dom.wrapper);
					
					html('head');
				break;
				case 'day':
					object = $('<a class="jsdate-days-day ' + attr + '"/>').appendTo(dom.days);
				break;
				case 'head':
					$('<a class="jsdate-days-day head">' + c.dict.days[0].substr(0,2) + '</a>').appendTo(dom.days);
					$('<a class="jsdate-days-day head">' + c.dict.days[1].substr(0,2) + '</a>').appendTo(dom.days);
					$('<a class="jsdate-days-day head">' + c.dict.days[2].substr(0,2) + '</a>').appendTo(dom.days);
					$('<a class="jsdate-days-day head">' + c.dict.days[3].substr(0,2) + '</a>').appendTo(dom.days);
					$('<a class="jsdate-days-day head">' + c.dict.days[4].substr(0,2) + '</a>').appendTo(dom.days);
					$('<a class="jsdate-days-day head">' + c.dict.days[5].substr(0,2) + '</a>').appendTo(dom.days);
					$('<a class="jsdate-days-day head">' + c.dict.days[6].substr(0,2) + '</a>').appendTo(dom.days);
				break;
				case 'output':
					dom.output = $('<input type="hidden" name="' + c.name + '" value=""/>').appendTo(elm.parent());
				break;
			}
			
			return object;
		};
		
		
		obj.buildcalender = function(curDate) {
			var days = [];
			
			eventDate = curDate;
			
			current = curDate.split('-');
			curMonth = current[1];
			curYear = parseInt(current[0]);
			dom.title.val(curMonth + '-' + curYear);
			
			for (var i=1;i<32;i++) {
				var day = (i<10) ? '0' + i : i ;
				
				if (date('m', strtotime(curYear + '-' + curMonth + '-' + day))==curMonth) {
					days.push({
						dayOfWeek: date('N', strtotime(curYear + '-' + curMonth + '-' + day)),
						day: day,
						dayName: c.dict.days[i-1],
						month: curMonth,
						monthName: c.dict.months[parseInt(curMonth)-1],
						year: curYear
					});
				}
			}
			
			var endday = days[days.length-1].dayOfWeek;
			
			for (var i=0;i<days[0].dayOfWeek-1;i++) html('day', 'inactive');
			
			$.each(days, function(j, day){
				
				if (
					(c.startDate===false || strtotime(c.startDate)<=strtotime(day.year + '-' + day.month + '-' + day.day)) && 
					(c.endDate===false || strtotime(c.endDate)>=strtotime(day.year + '-' + day.month + '-' + day.day))
				) {
					var object = html('day');
					object.text(day.day);
					object.attr({
						rel: day.year + '-' + day.month + '-' + day.day,
						title: day.day + '-' + day.month + '-' + day.year
					});
					
					actions('day', object);
				} else {
					object = html('day', 'inactive');
					object.text(day.day);
				}
				
				if (strtotime(c.activeDate)==strtotime(day.year + '-' + day.month + '-' + day.day)) object.addClass('active');
				
				if (events!==undefined && typeof(events)=='object' &&  events[day.year + '-' + day.month + '-' + day.day]!==undefined) {
					var eventsToday = events[day.year + '-' + day.month + '-' + day.day];
					var width = Math.floor(object.width()/eventsToday.length);
					
					var thisEvent = eventsToday[0];
					var a = $('<a/>').appendTo(object);
					a.css({ width: (object.width()-2), opacity:0.5, left: '2px' });
					a.addClass('eventType_1');
					a.attr({ 'ziggobox': 'ziggobox' });
					a.attr({ href: '/module/ext/nl/eventsday/?day=' + day.year + '-' + day.month + '-' + day.day + '&inline=true' });
					
					/*
					$.each(eventsToday, function(x, thisEvent){
						var a = $('<a/>').appendTo(object);
						a.css({ width: (width-2), opacity:0.5, left: ((x * width) + 2) + 'px' });
						a.addClass('eventType_' + thisEvent.type);
						a.attr({ href: thisEvent.url });
					});
					*/
				}
			});
			
			for (var i=1;i<(8-days[days.length-1].dayOfWeek);i++) html('day', 'inactive');
			
			if (curMonth.indexOf('0')==0) curMonth = parseInt(curMonth.substr(1,2));
			
			if (parseInt(curMonth)-1<1) { // setup previous month
				prevMonth = '12';
				prevYear = curYear-1;
			} else {
				prevMonth = (parseInt(curMonth)-1<10) ? '0' + (parseInt(curMonth)-1) : parseInt(curMonth)-1 ;
				prevYear = curYear;
			}
			
			if (parseInt(curMonth)+1>12) { // setup next month
				nextMonth = '01';
				nextYear = curYear+1;
			} else {
				nextMonth = (parseInt(curMonth)+1<10) ? '0' + (parseInt(curMonth)+1) : parseInt(curMonth)+1 ;
				nextYear = curYear;
			}
			
			dom.days.attr({
				rel: prevYear + '-' + prevMonth + '_' + nextYear + '-' + nextMonth
			});
		};
		
		
		var actions = function(action, domobj) {
			if (!action) action = false;
			if (!domobj) domobj = false;
			
			switch (action) {
			case 'day':
				domobj.click( function(e){
					switch (c.type) {
						case 'canvas': 
							if (domobj.children('a').length<1) e.preventDefault();
							//console.log('day');
						break;
						default: 
							e.preventDefault();
							
							var display = $(this).attr('title');
							var format = $(this).attr('rel');
							
							elm.val(display);
							dom.output.val(format);
							
							obj.close();
						break;
					}
				});
			break;
			default: 
				dom.prev.click( function(e){
					e.preventDefault();
					var gotodate = dom.days.attr('rel').split('_');
					
					cleandays();
					if (c.eventsUrl===false) {
						obj.buildcalender(gotodate[0]);
					} else {
						obj.loadevents(gotodate[0]);
					}
				});
				
				dom.next.click( function(e){
					e.preventDefault();
					var gotodate = dom.days.attr('rel').split('_');
					
					cleandays();
					if (c.eventsUrl===false) {
						obj.buildcalender(gotodate[1]);
					} else {
						obj.loadevents(gotodate[1]);
					}
				});
				
				dom.title.click( function() {
					$(this).addClass('active');
				}).blur( function(){
					var gotoval = $(this).val().split('-');
					$(this).removeClass('active');
					
					var month = trim(gotoval[0]);
					var year = trim(gotoval[1]);
					
					cleandays();
					if (c.eventsUrl===false) {
						obj.buildcalender(year + '-' + month);
					} else {
						obj.loadevents(year + '-' + month);
					}
				}).keydown( function(e){
					if (e.keyCode==13) {
						var gotoval = $(this).val().split('-');
						$(this).removeClass('active');
						
						var month = trim(gotoval[0]);
						var year = trim(gotoval[1]);
						
						cleandays();
						if (c.eventsUrl===false) {
							obj.buildcalender(year + '-' + month);
						} else {
							obj.loadevents(year + '-' + month);
						}
					} else {
						return;
					}
				});
				
				elm.blur( function() {
					//obj.close();
				});
			break;
			}
		};
		
		__construct();
		return obj;
	};
	
});
