function class_pjd_calendar(grid_id,days_id,prev_btn_id,next_btn_id,month_display_id){
	/* @ 11:59 2012-01-05 */
	
	if(!pjd.isString(grid_id)||pjd.isEmpty(grid_id))return;
	if(!pjd.isString(days_id)||pjd.isEmpty(days_id))return;
	if(!pjd.isString(prev_btn_id)||pjd.isEmpty(prev_btn_id))return;
	if(!pjd.isString(next_btn_id)||pjd.isEmpty(next_btn_id))return;
	if(!pjd.isString(month_display_id)||pjd.isEmpty(month_display_id))return;

	var _grid,_days,_prev_btn,_next_btn,_month_display;
	var _grid_id=grid_id;
	var _days_id=days_id;
	var _prev_btn_id=prev_btn_id;
	var _next_btn_id=next_btn_id;
	var _month_display_id=month_display_id;

	var _lang=typeof _userSelectedLanguage!='undefined'?_userSelectedLanguage:'fr';
	var _day=new Date().getDate();
	var _month=new Date().getMonth();
	var _year=new Date().getFullYear();
	var _connection,_cache={};
	var _labels={
		days:{fr:'DLMMJVS',en:'SMTWTFS'},
		months:{
			fr:['Janvier','F&eacute;vrier','Mars','Avril','Mai','Juin','Juillet','Ao&ucirc;t','Septembre','Octobre','Novembre','D&eacute;cembre'],
			en:['January','February','March','April','May','June','July','August','September','October','November','December']
		}
	};
	
	this.initialize=function(){
		_grid=pjd.getById(_grid_id);
		_days=pjd.getById(_days_id);
		_prev_btn=pjd.getById(_prev_btn_id);
		_next_btn=pjd.getById(_next_btn_id);
		_month_display=pjd.getById(_month_display_id);
		
		void populate_days();
		void get_data();
		void pjd.events.addListener(_prev_btn,'click',null,change_month,{direction:-1});
		void pjd.events.addListener(_next_btn,'click',null,change_month,{direction:1});
	};
	function populate_days(){
		for(var i=0;i<7;i++){
			var li=pjd.node.inject('li',_days);
			void pjd.setHtml(li,_labels.days[_lang].split('')[i]);
		}
	};
	function populate_grid(){
		var startingIndex=get_starting_index();
		var maxDays=get_number_of_days();
		void pjd.setHtml(_grid,'');
		void pjd.setHtml(_month_display,_labels.months[_lang][_month]+' '+_year);
		for(var i=0;i<42;i++){
			var li=pjd.node.inject('li',_grid);
			void pjd.setStyle(li,{zIndex:42-i});
			var label=i-startingIndex+1;
			var isEmpty=i>=startingIndex&&label<=maxDays?false:true;
			var content=isEmpty?'':'<span>'+label+'</span>';
			if(!isEmpty){
				var event_list=get_event_for_specific_day(label);
				if(event_list.length>0){
					void pjd.setClassName(li,'active');
					content+="<div>";
					for(var j=0;j<event_list.length;j++){
						var signature=event_list[j].split('*');
						var data=_cache[_year][_month][signature[0]][signature[1]];
						content+="<a href='"+data.link+"'>"+data.title+"</a>";
					}				
					content+="</div>";
				}
			}else{void pjd.setClassName(li,'empty');}
			void pjd.setHtml(li,content);
		}
	};
	function change_month(event){
		var step=event.args.direction;
		if(_month+step<0){
			_month=11;
			_year--;
		}else if(_month+step>11){
			_month=0;
			_year++;
		}else{_month+=step;}
		void get_data();
	};
	function get_event_for_specific_day(day){
		var data=_cache[_year][_month],list=[];
		for(var i in data){
			var events=data[i];
			for(var j=0;j<events.length;j++){
				if(events[j].activeDay['a_'+day])list.push(i+'*'+j);
			}
		}
		return list;
	};
	function get_data(){
		if(!_cache[_year])_cache[_year]={};
		if(!_cache[_year][_month]){
			try{_connection.abort();}catch(e){}
			_connection = $.ajax({
				type:"GET",
				url:"ajax-requests/calendar.cfm",
				dataType:"xml",
				data:"month="+(_month+1)+"&year="+_year,
				success:function(xml){
					var data = {} ;
					$(xml).find('event').each( function(){
						var eventData={
							title:$(this).find('title').text(),
							id:$(this).find('id').text(),
							startDate:$(this).find('startDate').text(),
							endDate:$(this).find('endDate').text(),
							activeDay:{},
							link:$(this).find('link').text()
						};
						if(pjd.isEmpty(eventData.endDate))eventData.endDate=eventData.startDate;
						var startDate=eventData.startDate.split('/');
						var endDate=eventData.endDate.split('/');
						var startIndex=1;
						var duration=0;
						startDate[1]-=1;
						endDate[1]-=1;
						if(startDate[1]==endDate[1]){
							startIndex=startDate[0];
							duration=endDate[0];
						}else{
							startIndex=_month>startDate[1]?1:startDate[0];
							duration=endDate[1]>_month?get_number_of_days():endDate[0];
						}
						for(var i=startIndex;i<=duration;i++)eventData.activeDay['a_'+i]=true;
						if(!data['event'+eventData.id])data['event'+eventData.id]=[];
						data['event'+eventData.id].push(eventData);
					} ) ;
					_cache[_year][_month]=data;
					void populate_grid();
				}
			});
		}else{
			void populate_grid();
		}
	}
	function get_starting_index(){return new Date(_year,_month,1).getDay();};
	function get_number_of_days(){return 32-new Date(_year,_month,32).getDate();};
};

function TabMenu(menu_id,pointer_id,realtime){
	if(!pjd.isString(menu_id)||pjd.isEmpty(menu_id))return;
	if(!pjd.isString(pointer_id)||pjd.isEmpty(pointer_id))return;
	var _menu_id=menu_id;
	var _pointer_id=pointer_id;
	var _realtime=pjd.isBoolean(realtime)?realtime:false;		
	var _menu,_more,_pointer,_display,_control,_view,_url_params={};
	this.initialize=function(){
		_menu=pjd.getById(_menu_id);
		_pointer=pjd.getById(_pointer_id);
		if(_menu==null||_pointer==null)return;
		var more=pjd.getByClassName('more_button',_menu,'li');
		if(more)_more=more;			
		var display=pjd.getByClassName('display',_menu,'li');
		if(display)_display=display;
		void get_pre_selected();
		void getUrlParameter();
		void parse();
	};
	function parse(){
		var links=pjd.getByName('a',_menu);
		var view_opened=false;
		for(var i=0;i<links.length;i++){
			var link=links[i];
			var li=link.parentNode;
			if(li==_more||li==_display){
				link.href="javascript:void(0);";
				if(li==_more)void pjd.setStyle(_more,{zIndex:999999});
				if(li==_display)void pjd.setStyle(_display,{zIndex:200});
				continue;
			}
			var view_id=get_view_id(link);
			if(view_id!=null){
				if(_url_params[_menu_id]&&_url_params[_menu_id]==view_id){
					void on_click({args:{control:link.parentNode,view_id:view_id}});
					view_opened=true;
				}
				if(_realtime){
					link.href="javascript:void(0);";
					void pjd.events.addListener(link,'click',null,on_click,{control:li,view_id:view_id});
				}
			}
		}
		if(!view_opened){
			void select_control(_control);
			void display_view(_view);
		}
	};
	function get_view_id(link){
		var id=link.href.match(/#[a-zA-Z0-9_]*$/gi);
		if(id!=null)return id[0].replace('#','');
		return null;
	};
	function get_pre_selected(){
		var selected=pjd.getByClassName('selected',_menu,'li');
		if(selected){
			_control=selected;
			try{
				_view=pjd.getById(get_view_id(pjd.getByName('a',_control)[0]));
			}catch(error){}
		}
	};
	
	/* ex: #MenuID=ViewID; */
	function getUrlParameter(){
		var params=window.location.hash.replace('#','').split(';');
		for(var i=0;i<params.length;i++){
			var param=params[i].split('=');
			_url_params[param[0]]=param.length>1?param[1]:null;
		};
	};
	function display_view(view){
		if(_view)void pjd.hide(_view);
		_view=view;
		void pjd.show(_view);
	};
	function select_control(control){
		if(_control)void pjd.removeClassName(_control,'selected');
		_control=control;
		void pjd.addClassName(_control,'selected');
		if(_more&&pjd.node.isChildOf(_more,_control)){
			void pjd.setHtml(_display,pjd.getHtml(_control));
			void pjd.show(_display);
			var base=_display;
		}else{
			if(_display)void pjd.hide(_display);
			var base=_control;
		}
		var offset=pjd.getOffset(base);
		var menu_offset=pjd.getOffset(_menu);
		void pjd.setStyle(_pointer,{backgroundPosition:((offset.x-menu_offset.x)+base.offsetWidth-20)+'px 0px'});
	};		
	function on_click(event){
		void display_view(pjd.getById(event.args.view_id));
		void select_control(event.args.control);
	};
};

/* PJD Image Slideshow {09:41 2012-01-27} */
function pjd_image_slideshow(id,delay){
	var _id=id;
	var _delay=(pjd.isNumber(delay)?delay:5)*1000;
	var _container,_images;
	var _index=0;
	this.initialize=function(){
		_container=pjd.getById(_id);
		if(!_container)return;
		_images=pjd.getByName('a',_container);
		void pause();		
	};
	function pause(){void setTimeout(fadeout,_delay);};
	function change_image(){
		void pjd.hide(_images[_index]);
		_index=_index+1>_images.length-1?0:_index+1;
		void pjd.show(_images[_index]);
		void fadein();
	};
	function fadein(){void pjd.motions.animate('imageSlide'+_index,_images[_index],'alpha',0,100,30,null,pause,'');};
	function fadeout(){void pjd.motions.animate('imageSlide'+_index,_images[_index],'alpha',100,0,30,null,change_image,'');};
};

/* PJD Scroller {11:15 2012-01-27} */
function pjd_scroller(id,scroll_up_btn_id,scroll_down_btn_id,vertical_axis,speed){
	var _id=id;
	var _list,_intl,_btn;
	var _btn_id={up:scroll_up_btn_id,down:scroll_down_btn_id};
	var _speed=typeof speed=='number'&&speed>0?speed:12;
	var _vertical_axis=typeof vertical_axis=='boolean'?vertical_axis:true;
	this.initialize=function(){
		_list=pjd.getById(_id);
		_btn={
			up:pjd.getById(_btn_id.up),
			down:pjd.getById(_btn_id.down)
		};
		if(!_btn.up||!_btn.down)return;
		void pjd.events.addListener(_btn.up,'mousedown',null,start,{direction:1});
		void pjd.events.addListener(_btn.down,'mousedown',null,start,{direction:-1});
		void pjd.events.addListener(document,'dragstart',null,stop);
		void pjd.events.addListener(document,'mouseup',null,stop);
	};
	function stop(){void clearInterval(_intl);};
	function start(event){
		void stop();
		_intl=setInterval(function(){_list[_vertical_axis?'scrollTop':'scrollLeft']-=(event.args.direction*_speed);},50);
	};
};
