Calendar=new Class({initialize:function(input,props){this.props=Object.extend({classes:['c-icon','c-icon-active','c-div','c-a-prev','c-a-next','c-td-heading','c-td-invalid','c-td-valid','c-td-hover','c-td-active'],drag:true,emptycells:true,format:'m/d/y',future:true,offset:1,pad:0,past:false,debug:false},props||{});this.props.emptycells=(this.props.emptycells)?6:5;this.weekdays=['S','S','M','T','W','T','F'];this.months=['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];this.mDays=[31,28,31,30,31,30,31,31,30,31,30,31];this.calendars=[];var d=new Date();d.setDate(d.getDate()+this.props.pad);this.year=d.getFullYear();if(this.year<1900){this.year+=1900;}
this.month=d.getMonth()+1;this.today=d.getDate();this.inputs=input.replace(/ /g,'').split(',');for(var i=0;i<this.inputs.length;i++){var input=$(this.inputs[i]);if(!input){continue};if(input.getTag()=='select'){selects=$ES('select',input.parentNode);selects.each(function(select){if(!select.format){select.format=this.props.format;}
select.addEvent('change',function(i){this.change(i);}.pass(i,this));},this);}else{var selects=null;input.readOnly=true;input.addEvent('focus',function(i){this.toggle(i);}.pass(i,this));}
var a=new Element('a');a.addClass(this.props.classes[0]).addEvent('click',function(i){this.toggle(i);}.pass(i,this)).injectAfter(input);input.addClass(this.props.classes[0]);var calendar=[];calendar['debug']=i;calendar['a']=a;calendar['input']=input;calendar['selects']=selects;if(selects){calendar['value']=this.getValue(selects);}
else calendar['value']=this.unformat(input.value);if(calendar['value'].length){var v=calendar['value'].split(',');calendar['year']=v[2].toInt();calendar['month']=v[1].toInt();}
else{calendar['year']=this.year;calendar['month']=this.month;}
calendar['display']='none';this.calendars.push(calendar);if(selects){this.click(calendar,calendar['value']);}}
this.div=new Element('div');this.div.addClass(this.props.classes[2]).setStyle('opacity',0).injectInside(document.body);this.fx=new Fx.Style(this.div,'opacity');if(this.props.drag){var drag=new Drag.Move(this.div);}},reset:function(){for(var i=0;i<this.inputs.length;i++){var calendar=this.calendars[i];var input=calendar['input'];var selects=calendar['selects'];if(selects){calendar['value']=this.getValue(selects);}
else{calendar['value']=this.unformat(input.value);}
if(calendar['value'].length){var v=calendar['value'].split(',');calendar['year']=v[2].toInt();calendar['month']=v[1].toInt();}
else{calendar['year']=this.year;calendar['month']=this.month;}}},toggle:function(n){calendar=this.calendars[n];if(calendar['display']=='none'){document.onmousedown=(function(z){return function(e){var e=new Event(e);var el=e.target;while(el!=document.body){if(el==this.div)return;for(i=0;i<this.calendars.length;i++){if(el==this.calendars[i]['a']||el==this.calendars[i]['input'])return;}
el=el.parentNode;}
this.toggle(z);}})(n).bind(this);for(var i=0;i<this.calendars.length;i++){if(this.calendars[i]==calendar){calendar['display']='block';calendar['a'].addClass(this.props.classes[1]);}
else{this.calendars[i]['display']='none';this.calendars[i]['a'].removeClass(this.props.classes[1]);}}
var c=calendar['a'].getCoordinates();this.div.setStyles({left:(c['left']+c['width'])+'px',top:c['top']+'px'});for(var i=0;i<this.calendars.length;i++){if(i!=n&&this.calendars[i]['value'].length&&!calendar['value'].length){var v=this.calendars[i]['value'].split(',');calendar['month']=v[1].toInt();calendar['year']=v[2].toInt();}}
this.create(calendar);}
else{document.onmousedown=null;calendar['display']='none';calendar['a'].removeClass(this.props.classes[1]);}
if(calendar['display']=='none'&&this.div.getStyle('opacity')>0)this.fx.custom(1,0);else if(this.div.getStyle('opacity')==0)this.fx.custom(0,1);},change:function(cal,v){if($type(cal)=='number')cal=this.calendars[cal];if(!v){if(cal['selects'])v=this.getValue(cal['selects']);else v=this.unformat(cal['input'].value);}
this.click(cal,v);v=cal['value'].split(',');var d=v[0].toInt();var m=v[1].toInt();var y=v[2].toInt();for(var c=0;c<this.calendars.length;c++){if(c!=cal['debug']&&this.calendars[c]['value'].length){v=this.calendars[c]['value'].split(',');v[0]=v[0].toInt();v[1]=v[1].toInt();v[2]=v[2].toInt();var changed=false;if(c<cal['debug']){if(y<v[2]){changed=true;v[2]=y;v[1]=m;v[0]=d-1;}
if(y==v[2]&&m<v[1]){changed=true;v[1]=m;v[0]=d-1;}
if(y==v[2]&&m==v[1]&&d<=v[0]){changed=true;v[0]=d-1;}
if(v[0]<1){v[1]=v[1]-1;if(v[1]<1){v[2]=v[2]-1;v[1]=12;}
v[0]=(this.isLeapYear(v[2])&&v[1]==2)?29:this.mDays[v[1]-1];}
if(changed)this.click(this.calendars[c],v.join(','));}
if(c>cal['debug']){if(y>v[2]){changed=true;v[2]=y;v[1]=m;v[0]=d+1;}
if(y==v[2]&&m>v[1]){changed=true;v[1]=m;v[0]=d+1;}
if(y==v[2]&&m==v[1]&&d>=v[0]){changed=true;v[0]=d+1;}
if(v[0]>((this.isLeapYear(v[2])&&v[1]==2)?29:this.mDays[v[1]-1])){v[1]=v[1]+1;if(v[1]>12){v[2]=v[2]+1;v[1]=1;}
v[0]=1;}
if(changed)this.click(this.calendars[c],v.join(','));}}}},click:function(cal,v){v=v.split(',');if(cal['selects']){v[0]=v[0].toInt();v[1]=v[1].toInt();v[2]=v[2].toInt();var start=1;if(v[1]==this.month&&!this.props.past)start=this.today;var stop=(this.isLeapYear(v[2])&&v[1]==2)?29:this.mDays[v[1]-1];if(v[1]==this.month&&!this.props.future)stop=this.today;if(v[0]<start)v[0]=start;if(v[0]>stop)v[0]=stop;for(var s=0;s<cal['selects'].length;s++){var select=cal['selects'][s];select.value=this.format(v[0],v[1],v[2],select.format);if(select.format=='d'){select.setHTML('');for(var day=start;day<=stop;day++){var option=new Element('option');if(day==(v[0]))option.selected=true;option.setProperty('value',String(day)).appendText(String(day)).injectInside(select);}}}}
else cal['input'].value=this.format(v[0],v[1],v[2]);cal['value']=v[0]+','+v[1]+','+v[2];cal['year']=v[2];cal['month']=v[1];},prev:function(cal,d){if(d=='m'){cal['month']--;if(cal['month']<1){cal['month']=12;cal['year']--;}}
else{cal['year']--;}
this.create(cal);},next:function(cal,d){if(d=='m'){cal['month']++;if(cal['month']>12){cal['month']=1;cal['year']++;}}
else{cal['year']++;}
this.create(cal);},unformat:function(v,f){if(!v||!v.length||v==this.props.format)return'';f=(f)?f:this.props.format;var u='';var x=new Array();var y=new Array();while(f.length){var c=f.substr(0,1);f=f.substr(1);if(/d|m|y/.test(c)){var n=0;while(f.substr(0,1)==c){n++;f=f.substr(1);}
if(n>0){var d=v.substr(u.length,(n+1));}
else if(f.length==0){var d=v.substring(u.length,v.length);}
else if(!/d|m|y/.test(f.substr(0,1))){var d=v.substring(u.length,v.indexOf(f.substr(0,1),u.length));}
else{return false;}
u=u+d;x.push(d);y.push(c);}
else u=u+c;}
f="d,m,y";for(var k=0;k<x.length;k++){f=f.replace(y[k],x[k]);}
f=f.replace(/d|m|y/g,'');return f},format:function(d,m,y,f){f=(f)?f:this.props.format;var x=new Array(d,m,y);var y=new Array('d','m','y');for(var k=0;k<3;k++){var num=0;var p=f.indexOf(y[k]);while(p!=-1){num++;p=f.indexOf(y[k],p+1);}
if(num>1){x[k]=String(x[k]);while(x[k].length<num)x[k]='0'+x[k];re=new RegExp(y[k]+'+');f=f.replace(re,x[k].substring(x[k].length-num,x[k].length));}
else f=f.replace(y[k],x[k]);}
return f;},isLeapYear:function(year){return(!(year%4)&&(year<1582||year%100||!(year%400)))?true:false;},getWeekday:function(year,days){var d=days;if(year)d+=(year-1)*365;for(var i=1;i<year;i++)if(this.isLeapYear(i))d++;if(year>1582||(year==1582&&days>=277))d-=10;if(d)d=(d-this.props.offset)%7;else if(this.props.offset)d+=7-this.props.offset;return d;},getValue:function(selects){var b=new Array(3);selects.each(function(select){var f=select.format;var a=this.unformat(select.value,f).split(',');for(var i=0;i<3;i++)if(a[i].length)b[i]=a[i];},this);return b.join(',');},create:function(cal){var n=cal['debug'];var inThisYear=(cal['year']==this.year)?true:false;var inThisMonth=(inThisYear&&cal['month']==this.month)?true:false;var thisDay=false;var inLessMonth=false;var lessDay=false;var inGreaterMonth=false;var greaterDay=false;for(var i=0;i<this.calendars.length;i++){if(this.calendars[i]['value'].length){var v=this.calendars[i]['value'].split(',');v[0]=v[0].toInt();v[1]=v[1].toInt();v[2]=v[2].toInt();if(i!=n){if(i<n&&cal['year']==v[2]&&cal['month']==v[1]){inLessMonth=true;lessDay=v[0];}
if(i>n&&cal['year']==v[2]&&cal['month']==v[1]){inGreaterMonth=true;greaterDay=v[0];}}
else{if(cal['year']==v[2]&&cal['month']==v[1])thisDay=v[0];}}}
this.mDays[1]=(this.isLeapYear(cal['year']))?29:28;var days=0;for(var i=0;i<cal['month']-1;i++)days+=this.mDays[i];var start=days;if(cal['year'])start+=(cal['year']-1)*365;for(var i=1;i<cal['year'];i++)if(this.isLeapYear(i))start++;if(cal['year']>1582||(cal['year']==1582&&days>=277))start-=10;if(start)start=(start-this.props.offset)%7;else if(this.props.offset)start+=7-this.props.offset;var stop=this.mDays[cal['month']-1];var table=new Element('table');var tbody=new Element('tbody');tbody.injectInside(table);var tr=new Element('tr');tr.injectInside(tbody);var th=new Element('th').injectInside(tr);if(!inThisMonth||this.props.past){var a=new Element('a');a.onclick=(function(kal){return function(){this.prev(kal,'m');}})(cal).bind(this);a.addClass(this.props.classes[3]).appendText(unescape('%3C')).injectInside(th);}
var th=new Element('th').setProperty('colSpan','5').appendText(this.months[cal['month']-1]+' '+cal['year']).injectInside(tr);var th=new Element('th').injectInside(tr);if(!inThisMonth||this.props.future){var a=new Element('a');a.onclick=(function(kal){return function(){this.next(kal,'m');}})(cal).bind(this);a.addClass(this.props.classes[4]).appendText(unescape('%3E')).injectInside(th);}
var tr=new Element('tr');tr.injectInside(tbody);for(var i=0;i<=6;i++){var d=(i+this.props.offset)%7;this.td(this.weekdays[d],this.props.classes[5],cal,tr);}
var daycount=1;var rowcount=0;while(daycount<=stop||rowcount<this.props.emptycells){var tr=new Element('tr');tr.injectInside(tbody);rowcount++;var wdays=0;for(var i=0;i<=6;i++){if((inThisMonth&&daycount<this.today&&!this.props.past)||(inThisMonth&&daycount>this.today&&!this.props.future))cls=this.props.classes[6];else if((inLessMonth&&daycount==lessDay)||(inGreaterMonth&&daycount==greaterDay))cls=this.props.classes[9];else if(daycount==thisDay)cls=this.props.classes[8];else cls=this.props.classes[7];if((daycount==1&&i<start)||daycount>stop)txt=null;else{txt=daycount;daycount++;wdays++;}
this.td(txt,cls,cal,tr);}}
this.div.setHTML('');table.injectInside(this.div);if(this.props.debug)alert('<div class="'+this.div.className+'">'+this.div.innerHTML+'</div>');},td:function(txt,cls,cal,tr){var td=new Element('td');td.appendText(((txt)?txt:unescape('%20'))).injectInside(tr);if(txt)td.addClass(cls);if(txt&&cls==this.props.classes[7]){td.addEvent('mouseover',function(td,cls){td.addClass(cls);}.pass([td,this.props.classes[8]]));td.addEvent('mouseout',function(td,cls){td.removeClass(cls);}.pass([td,this.props.classes[8]]));fn=function(txt,cal){this.change(cal,txt+','+cal['month']+','+cal['year']);this.toggle(cal['debug']);}.pass([txt,cal],this);td.addEvent('click',fn);}}});