/*

Версия 1.10 (12.02.2009)

Внедрение

var calendar=new tСalendar('datetime',true,1211468200);
Где:
	datetime - идентификатор элемента ввода
	true - Отображение времени
	1211468200 - DateStamp в формате UNIX
*/

Function.prototype.bind=function(object){
  var method=this;
  var arg=arguments;
  return function(arg){return method.apply(object,arguments);}
}

function tСalendar(id,show_time,time_stamp){
	//Проверка параметров
	this.show_time=show_time;
	this.time_stamp=time_stamp;

	this.obj=document.getElementById(id);

	this.id=this.obj.id;
	if (!this.obj) return false;
	
	//Проверка на Браузры
	this.IE = (navigator.userAgent && (navigator.userAgent.indexOf("MSIE") != -1));
	this.FF = (navigator.userAgent && (navigator.userAgent.indexOf("Firefox") != -1));
	this.OP = (navigator.userAgent && (navigator.userAgent.indexOf("Opera") != -1));

	this.chtml = "<DIV id=cal_body"+this.id+" style='position:absolute; top:0; left:0; width:177; height:171; overflow:hidden'>";
	this.chtml += "<DIV id=cal_conteiner"+this.id+" style='position:absolute; top:-172; left:0; width:175; height:169;'>";
	this.chtml +="<DIV style='font-family:Arial; position:absolute; top:0; left:0; width:100%; height:100%; background:#fff; border:1px solid #A5ACB2;'>";
	this.chtml +="<DIV style='text-align:center; white-space:nowrap; background:#E0E0EB; position:relative; left:0px; margin:4px; width:162px; height:23px; padding:2px;'><SELECT style='font-size:11px' ID="+this.id+"month>";
	this.chtml+="<OPTION>Январь<OPTION>Февраль<OPTION>Март<OPTION>Апрель<OPTION>Май<OPTION>Июнь<OPTION>Июль<OPTION>Август<OPTION>Сентябрь<OPTION>Октябрь<OPTION>Ноябрь<OPTION>Декабрь</SELECT>&nbsp;";
	this.chtml +="<SELECT style='font-size:10px' ID="+this.id+"year class=control>";
	
	dt = new Date();
	this.start_year=dt.getFullYear()-90; 
	this.end_year=dt.getFullYear()+5; 
	for (var i=this.start_year; i<this.end_year+1; i++) 
		this.chtml += "<OPTION>"+i;
	this.chtml +="</SELECT>";
	this.chtml +="<span class=hand style='font-family: sans-serif; margin-left:6px; font-size:11px; cursor:hand' id="+this.id+"close>x</span>";
	this.chtml +="<span class=hand style='font-family: sans-serif; margin-left:2px; font-size:9px; cursor:hand' id="+this.id+"ok>OK</span>";

	this.chtml +="</DIV>";
	this.chtml +="<style>";
	this.chtml +=".control {  font-size: 9px; height: 18px}";
	this.chtml +=".control1 {  font-size: 9px; height: 18px; width: 35px;}";
	this.chtml +=".oShield {position:absolute; top:0; left:0; width:0; height:0;}";
	this.chtml +=".day_off_header {padding-bottom:3px; border-bottom:1px solid #A5ACB2; height: 14px; width: 20px; font-size: 11px; color: #636C76; text-align: center;}";
	this.chtml +=".day_header {padding-bottom:3px; border-bottom:1px solid #A5ACB2; height: 14px; width: 20px; font-size: 11px;  color: #000; text-align: center; cursor: default; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px}";
	this.chtml +=".day_disabled {  font-size: 11px; color:#ddd; height: 14px; width: 20px; text-align: center; cursor: default; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px}";
	this.chtml +=".day {  font-size: 11px; background-color: #FFFFFF; height: 14px; width: 20px; text-align: center; cursor: default;  padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px}";
	this.chtml +=".day_selected { font-size: 11px;  background-color: #FBC84F; height: 12px; width: 18px; text-align: center; cursor: default; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px}";
	this.chtml +=".day_off { font-size: 11px;  height: 14px; width: 20px; text-align: center ; color: #636C76 ; cursor: default; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px}";
	this.chtml +=".day_mouseover { font-size: 11px;  color: #000000; background-color: #DEDEDE; height: 14px; width: 20px; text-align: center; cursor: default; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px}";
	this.chtml +=".hand {cursor:hand; cursor:pointer}";
	this.chtml +=".calendar_button { font-size:11px; cursor:hand; cursor:pointer; border-bottom:1px dashed #A5ACB2; text-decoration: none; color:#A5ACB2}";
	this.chtml +="-->";
	this.chtml +="</style>";
	this.chtml +="<table width=140 style='border-bottom:1px solid #A5ACB2; margin-left:16px' ID="+this.id+"CalTable border=0 cellpadding=2 cellspacing=0>";
	this.chtml +="<tr> ";
	this.chtml +="<td class=day_header>Пн</td><td class=day_header>Вт</td><td class=day_header>Ср</td><td class=day_header>Чт</td><td class=day_header>Пт</td><td class=day_off_header>Сб</td><td class=day_off_header>Вс</td>";
	this.chtml +="</tr>";
	for (var i=0; i<7; i++) 
		this.chtml +="<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>";
	this.chtml +="</table>";
	this.chtml +="<DIV style='width:166px; margin-left:4px; text-align:center'>";
	if (this.show_time) this.chtml +="<span class=calendar_button ID="+this.id+"time>Время</span>&nbsp;&nbsp;";
	this.chtml +="<span class=calendar_button ID="+this.id+"today>Cегодня</span>";
	this.chtml +="&nbsp;&nbsp;<span class=calendar_button ID="+this.id+"clear value=''>Очистить</span>";
	this.chtml +="</DIV>";
	this.chtml +="</CENTER></DIV></DIV></DIV>";
	
	this.showDate=function(){ //Отображает дату в value объекта
		month=this.date.getMonth()+1;
		d=this.date.getDate();
		d=((d<10)?'0':'')+d;
		this.obj.value=d+'.'+((month<10)?"0":"")+month+'.'+(this.date.getFullYear());
		if (this.show_time){
			this.obj.value+=' ';
			h=this.date.getHours();
			m=this.date.getMinutes();
			s=this.date.getSeconds();
			h=((h<10)?'0':'')+h;
			m=((m<10)?'0':'')+m;
			s=((s<10)?'0':'')+s;
			this.obj.value+=h+':'+m+':'+s;
		}
	}
	
	this.showTime=function(obj){ //Отображает время на календаре
		h=this.date.getHours();
		m=this.date.getMinutes();
		s=this.date.getSeconds();
		h=((h<10)?'0':'')+h;
		m=((m<10)?'0':'')+m;
		s=((s<10)?'0':'')+s;
//		this.time_object.value+=h+':'+m+':'+s;
		this.time_object.innerHTML=h+':'+m+':'+s;
	}
	
	this.get_time=function(){ //Парсит время в дату из календаря
		time_string=this.time_object.innerHTML;
	
		h=time_string.substr(0,2);
		mi=time_string.substr(3,2);
		s=time_string.substr(6,2);
		if(h>=0 && h<24 && mi>=0 && mi<60 && s>=0 && s<60){
			this.date.setHours(h);
			this.date.setMinutes(mi);
			this.date.setSeconds(s);
		}
	}
	
	this.parseDate=function(date){ //Добавляет в дату удобные поля для работы
		if (!date) return false;
		ret=date;
		month=date.getMonth()+1;
		ret.d=date.getDate();
		ret.m=((month<10)?"0":"")+month;
		ret.y=date.getFullYear();
		ret.h=date.getHours();
		ret.mi=date.getMinutes();
		ret.s=date.getSeconds();
		return ret;
	}
	
	this.eventHandlerClick=function (month) { //Клик на день (c относительным месяцем
		if (this.IE){
			var sobj=window.document.selection;
			var Range = sobj.createRange();
			var parent = Range.parentElement();
		}else{
			var selection = getSelection();
			range = selection.getRangeAt(0);
			parent = range.commonAncestorContainer;
		}
		while (parent && parent.tagName!="TD")
			parent=parent.parentNode;
		
		if (parent.tagName=="TD"){
			anEvObj=parent;
			this.day=parent.innerHTML;
			this.date.setDate(this.day);
			if (month) this.date.setMonth(this.date.getMonth()+month);
			this.submit_calendar();			
		}
	}
	
	this.getDaysInMonth=function(x_month,x_year)  {
		if (x_month==1 || x_month==3 || x_month==5 || x_month==7 || x_month==8 || x_month==10 || x_month==12)  days=31;
		else if (x_month==4 || x_month==6 || x_month==9 || x_month==11) days=30;
		else if (x_month==2)  {
			if (this.isLeapYear(x_year)) { days=29; }
			else { days=28; }
		}
		return (days);
	}
	
	this.isLeapYear=function(){
		if (((this.x_year % 4)==0) && ((this.x_year % 100)!=0) || ((this.x_year % 400)==0)) {
			return (true);
		}else{ 
			return (false); }
	}

	this.displayCalendar=function(x_month, x_year, x_day) {
		month = 1*x_month;
		year = 1*x_year;
		day = 1*x_day;
		fDayOfMonth=new Date (year, month-1, 1); //Первый день этого месяца
		fDayOfMonth=fDayOfMonth.getDay()==0?7:fDayOfMonth.getDay();
		daysInMonth=this.getDaysInMonth(month,year);
		daysInMonthBefore=month==1?this.getDaysInMonth(12,year-1):this.getDaysInMonth(month-1,year);
		
		for (i=0; i<42; i++){
			curr_cell_obj=this.table_object.rows[Math.floor(i/7)+1].cells[i%7];
			(curr_cell_obj.cellIndex<5) ? curr_cell_obj.className="day":curr_cell_obj.className="day_off";
			
			if (i < fDayOfMonth-1 ) {
				curr_cell_obj.innerHTML=daysInMonthBefore - fDayOfMonth + i;
				curr_cell_obj.className="day_disabled";
				curr_cell_obj.onmouseover="";
				curr_cell_obj.onmouseout="";			
				curr_cell_obj.onclick=function(){this.eventHandlerClick(-1)}.bind(this);
			}else
			if(i<(daysInMonth+fDayOfMonth-1)){
				curr_cell_obj.innerHTML=i-fDayOfMonth+2;
				if (i-fDayOfMonth+2==day) curr_cell_obj.className="day_selected";
				curr_cell_obj.onmouseover=function(){if (this.className!="day_selected") this.className="day_mouseover";};
				curr_cell_obj.onmouseout=function(){if (this.className!="day_selected") (this.cellIndex<5) ? this.className="day":this.className="day_off";};
				curr_cell_obj.onclick=function(){this.eventHandlerClick()}.bind(this);
			}else{
				curr_cell_obj.innerHTML=i-(daysInMonth+fDayOfMonth)+2;
				curr_cell_obj.className="day_disabled";
				curr_cell_obj.onmouseover="";
				curr_cell_obj.onmouseout="";		
				curr_cell_obj.onclick=function(){this.eventHandlerClick(1)}.bind(this);
			}
		}
	}
	
	this.setToday=function() {
		this.date=new Date();
		this.submit_calendar();	
	}
 
	this.calcTop=function(zzz){
		t=0;
		while ((zzz)&&(zzz.tagName!='BODY')){
               t+=zzz.offsetTop;
			zzz=zzz.offsetParent;
		}
		return (t+25);
	}

	this.calcLeft=function(zzz){
		l=0;		
		while ((zzz)&&(zzz.tagName!='BODY')){
               l+=zzz.offsetLeft;
			zzz=zzz.offsetParent;
		}
		return (l+1);
	}

	this.onChangeMonth=function(){ //При смене месяца
		this.block_close=true; 
		daysInMonth=this.getDaysInMonth(this.month_input_object.selectedIndex+1,this.date.getYear);
		if (this.date.getDate()>daysInMonth) this.date.setDate(daysInMonth); 
		this.date.setMonth(this.month_input_object.selectedIndex); 
		
		this.displayCalendar(this.month_input_object.selectedIndex+1,this.date.getYear(),this.date.getDate());  
		setTimeout(function(){
			this.block_close=false;
		}.bind(this),100);
		
	}
	
	this.onChangeYear=function(){ //При смене года
		this.block_close=true; 
		this.date.setFullYear(this.year_input_object.selectedIndex+this.start_year); 
		
		daysInMonth=this.getDaysInMonth(this.month_input_object.selectedIndex+1,this.date.getYear);
		if (this.date.getDate()>daysInMonth) this.date.setDate(daysInMonth);		
		
		this.displayCalendar(this.month_input_object.selectedIndex+1,this.date.getYear(),this.date.getDate());  
		setTimeout(function(){
			this.block_close=false;
		}.bind(this),100); 
	}
	
	this.open=function(){  //Открыть календарь
		if (this.show) return;
		this.show=true;
		this.undo_date = new Date(this.date);//Дата перед началом модификаций
		this.init   = new Date();
		this.day   = this.init.getDate();
		this.oDiv = document.createElement("DIV");

		this.oDiv.innerHTML=this.chtml;
		this.oDiv.style.position="absolute";
		this.oDiv.style.zIndex=301;
		document.body.appendChild(this.oDiv);

		this.oDiv.style.left=this.calcLeft(this.obj);
		this.oDiv.style.top=this.calcTop(this.obj);
		
		this.month_input_object=document.getElementById(this.id+"month");
		this.year_input_object=document.getElementById(this.id+"year");
		this.close_object=document.getElementById(this.id+"close");
		this.table_object=document.getElementById(this.id+"CalTable");
		this.today_object=document.getElementById(this.id+"today");
		this.clear_object=document.getElementById(this.id+"clear");
		this.time_object=document.getElementById(this.id+"time");
		this.ok_object=document.getElementById(this.id+"ok");

		this.date=this.parseDate(this.date);
		
		this.month_input_object.onchange=function(){this.onChangeMonth();}.bind(this);
		this.year_input_object.onchange=function(){this.onChangeYear();}.bind(this);
		
		if (this.time_object) this.time_object.onclick=function(){this.block_close=true; if (time_str=prompt("Введите время в формате (чч:мм:сс)",this.time_object.innerHTML)) { this.time_object.innerHTML=time_str	; this.get_time();} setTimeout(function(){this.block_close=false;}.bind(this),100); }.bind(this);
		
		this.close_object.onclick=function(){this.date=this.undo_date; this.close()}.bind(this);//Отмена и закрытие
		this.ok_object.onclick=function(){this.submit_calendar()}.bind(this);//Отмена и закрытие
		this.today_object.onclick=function(){this.setToday()}.bind(this);
		this.clear_object.onclick=function(){this.obj.value=''; this.close()}.bind(this);
		
		this.month_input_object.selectedIndex=this.date.m-1;
		this.year_input_object.selectedIndex=this.date.y-this.start_year;
		
		if (this.show_time)
			this.showTime(); 
		
		this.displayCalendar(this.date.m,this.date.y,this.date.d);

		this.oDiv.onmouseover=function(){this.global_mouseon=1;}.bind(this);
		this.oDiv.onmouseout=function(){this.global_mouseon=2;}.bind(this);
		
		this.global_mouseon=0;
		this.block_close=false;
		
		document.onclick=function(){
			if (this.global_mouseon==2 && !this.block_close) this.close();
		}.bind(this);	
		
		setTimeout(function(){
			if (this.global_mouseon==0) this.global_mouseon=2;
		}.bind(this),100);		

		this.slider=new tSlider({id:'cal_conteiner'+this.id});
		this.slider.slide({
			from:-172,
			to:0,
			ms:10,
			step:20,
			param:'style.top'
		});		
	}	
	
	this.submit_calendar=function(){ //Подтверждение правильности задания даты и времени
		this.showDate();
		this.obj_value.value=Math.floor(this.date.valueOf()/1000);
		this.close();
	}
	
	this.close=function(){ //Закрыть календарь
		this.slider.slide({
			id:'cal_conteiner'+this.id,
			from:0,
			to:-172,
			ms:10,
			step:20,
			param:'style.top',
			func:this.kill,
			farg:this.oDiv
		});		
		this.show=false;
		this.global_mouseon=0;
	}
	
	this.kill=function(obj){ //Закрыть календарь
		document.body.removeChild(obj);
	}	

	this.submit=function(){ //Событие при субмите формы
		this.obj_value.value=Math.floor(this.date.valueOf()/1000);
//		this.close();
	}

	this.init=function(){ //Инициализация объекта
		if (this.time_stamp){ //Вычисляем дату из таймстампа если он передан
			js_time_stamp = this.time_stamp * 1000;
			this.date = new Date(js_time_stamp);
			this.date.d=this.date.getDate();
			this.showDate();
		}else{
			this.date = new Date();
			if (this.obj.value!=''){
				d=this.obj.value.substr(0,2);
				m=this.obj.value.substr(3,2);
				y=this.obj.value.substr(6,4);

				if (d > 0 && d <= this.getDaysInMonth(m,y) && m  > 0 && m < 13 && y > 1899 && y < 2100){
					this.date.setDate(d);
					this.date.setMonth(m-1);
					this.date.setFullYear(y);
					
					if (this.show_time){
						h=this.obj.value.substr(11,2);
						mi=this.obj.value.substr(14,2);
						s=this.obj.value.substr(17,2);
						if(h>=0 && h<24 && mi>=0 && mi<60 && s>=0 && s<60){
							this.date.setHours(h);
							this.date.setMinutes(mi);
							this.date.setSeconds(s);
						}
					}
				}
			}
		}
		
		//Поиск формы
		var tmp_frm=this.obj.parentNode;
		while((tmp_frm) && (tmp_frm.nodeName!='FORM'))
			tmp_frm=tmp_frm.parentNode;
		if (tmp_frm){
			this.form=tmp_frm;
			old_name=this.obj.name; //Создаем дополнительный объект, заменяем имя
			this.obj.name=old_name+'_text';
			this.obj_value= document.createElement("input");
			this.obj_value.type='Hidden';
			this.obj_value.name=old_name;
			this.form.appendChild(this.obj_value);
			this.obj_value.value=Math.floor(this.date.valueOf()/1000);
		}else{
			alert("JavaScript tСalendar error: Не найдена форма.");
		}


		//Настройка событий

		this.obj.onclick=function(){this.open()}.bind(this);
		this.form.onsubmit=function(){this.submit()}.bind(this);
	
	}

	
	if (this.IE)
		    window.attachEvent("onload",function(){this.init()}.bind(this));
	else
		    window.addEventListener("load",function(){this.init()}.bind(this),true);
	
		
}//Конец объекта


// onmouseup="slider.slide('bicont','style.left','',(-1*(400*{images.IMGID})),10,50)"

/*
Аргументы конструктора:
obj - перемещаемый объект или
id - идентификатор перемещаемого обьекта

SLIDE - перемещение
param - изменяемый параметр например style.top
from - Начальное значение
to - конечное значение
ms - продолжительность шага или 10
step - величина шага или 10
func - функция которая выполнитса после завершения движения
farg - Аргументы функции func
*/

Function.prototype.slBind=function(object){ //Прототипирование функций слайдера с целью передачи this
  var method=this;
  var arg=arguments;
  return function(arg){return method.apply(object,arguments);}
}

function tSlider(arg){
	this.error=function(msg){
		alert(msg);
		return false;
	}	
	
	this.block=false; //Блокируем слайдер
	this.obj=(arg.obj)?arg.obj:document.getElementById(arg.id); //Пытаемся найти объект
	if (!this.obj) return this.error('tSlider Не удалось найти объект '+arg.id);	
	
	this.slide=function(arg){ //Начало слайда
		this.func=arg.func;
		this.farg=arg.farg;
		this.param=arg.param; //Параметр который двигаем
		if (this.block) return;
		this.step=(arg.step)?arg.step:10;//Указываем шаг
		this.ms=(arg.ms)?arg.ms:10;//Указываем скорость
		this.to=1*(arg.to);
		if (this.to===false) return this.error('tSlider Не удалось найти финальное значение to '+arg.to);
		
		if (arg.from=='' || arg.from==false) arg.from=0;
		this.now=(this.now!=null)?this.now:arg.from; 
		this.from=this.now;	//Вычисляем от чего собственно планируем двигатся	

		this.ff=(this.to<this.from)?false:true;//направление прибавления

		this.block=true;
		this.interval=setInterval(function(){this.process();}.slBind(this),this.ms);  	
	}
	
	this.process = function (){//Интервальный запуск
		d=Math.abs((this.ff)?(this.from-this.to):(this.to-this.from));
		p=(d==0)?100:Math.abs(this.now-this.from)/d*100;
		this.slidestep=this.step; 
		if (p>80) this.slidestep=this.step*((100-p)/20)+0.6; 
		if (this.ff)
			this.now=Math.round(this.now+this.slidestep);
		else
			this.now=Math.round(this.now-this.slidestep);
		if ( (this.now>=this.to && this.ff) || (this.now<=this.to && !this.ff) ){
			eval("this.obj."+this.param+'=this.to;');
			this.now=this.to;
			this.stop();
		}
		eval("this.obj."+this.param+'=this.now;');
	}
	
	this.stop = function(){ //ОСтановка
		clearInterval(this.interval);
		this.block=false;
		if (this.func) this.func(this.farg);
	}
}

