
function navigation_calendar(parent,id)
{
	this.id = id;
	this.parent = parent;
	//events
	if (typeof(cmn_EventContainer) == "function")
		this.events = new cmn_EventContainer();
	//Type Selection
	this.TypeSelection = 0;
	//dates
	this.TodayYear = null;
	this.TodayMonth = null;
	this.TodayDate = null
	this.CurrentMonth = null;
	this.CurrentDate = null;
	this.CurrentYear = null;
	this.CurrentViewMonth = null;
	this.CurrentViewYear = null;
	//enums
	this.Monthes = null;
	this.DaysOfWeek = null;
	//tables
	this.maintable = null;
	this.monthtable = null;
	this.yeartable = null;
	this.daysofweektable = null;
	this.daystable = null;
	//init
	this.InitDate();
	this.InitMonthes();
	this.InitDaysOfWeek();
	//css
	this.DateCellCssClass = "";
	this.WeekCellCssClass = "";
	this.MonthCellCssClass = "";
	this.YearCellCssClass = "";
	this.SelectedMonthCellCssClass = "";
	this.RightYearCellCssClass = "";
	this.LeftYearCellCssClass = "";
	this.SelectedDateCellCssClass = "";
	//fields
	this.CountRows = 6;
	this.CountCells = 8;
	//Array of Events
	this.Events = null;
	//Script handler for getting array of events
	this.GetEvents = null;
	this.enableSelecting = true;
}
navigation_calendar.prototype.constructor = navigation_calendar;
navigation_calendar.prototype.attachEvent=function(evt, func)
{
	this.events.attachEvent(evt, func);
}
navigation_calendar.prototype.InitDate = function()
{
	var today = new Date();
	this.TodayMonth = today.getMonth() + 1;
	this.TodayDate = today.getDate();
	this.TodayYear = today.getFullYear();
	this.SetCurrentDate(this.TodayYear, this.TodayMonth, this.TodayDate);
}
navigation_calendar.prototype.GetCurrentDate = function()
{
	return new Date(this.CurrentYear, this.CurrentMonth - 1, this.CurrentDate);
}
navigation_calendar.prototype.SetDateFrom = function(date,type)
{
	if (date == null) date = new Date();
	if (type == null) type = 0;
	this.SetCurrentDate(date.getFullYear(),date.getMonth()+1,date.getDate(),type,true)
}
navigation_calendar.prototype.SetCurrentDate = function(CurrentYear, CurrentMonth, CurrentDate, TypeSelection, dontFireEvent, mandatoryrepainting)
{
	var yearchange = false, monthchange = false, datechange = false, typechange = false, 
		oldviewyear = null, oldviewmonth = null;
		
	var changeview = !this.IsDateInCurrentView(new Date(CurrentYear,CurrentMonth-1,CurrentDate)) || 
		!this.CurrentViewYear || !this.CurrentViewMonth;

	if (CurrentYear != null)
	{
		if (this.CurrentViewYear != CurrentYear) yearchange = true;
		this.CurrentYear = CurrentYear;
		oldviewyear = this.CurrentViewYear;
		if (changeview != false) this.CurrentViewYear = this.CurrentYear;
		if (this.yeartable != null) this.DrawYearTable();
	}
	if (CurrentMonth != null)
	{
		if (this.CurrentMonth != CurrentMonth) monthchange = true;
		this.CurrentMonth = CurrentMonth;
		oldviewmonth = this.CurrentViewMonth;
		if (changeview != false) this.CurrentViewMonth = this.CurrentMonth;
	}
	if (CurrentDate != null && this.CurrentDate != CurrentDate)
	{
		this.CurrentDate = CurrentDate;
		datechange = true;
	}
	if (this.TypeSelection != TypeSelection && TypeSelection != null)
	{
		typechange = true;
		this.TypeSelection = TypeSelection;
	}
	if (CurrentYear == null) this.CurrentYear = this.CurrentViewYear;
	if (CurrentMonth == null) this.CurrentMonth = this.CurrentViewMonth;
	if (CurrentYear != null && CurrentMonth != null && CurrentDate != null && ( monthchange || yearchange) )
		datechange = true;
	if (this.TypeSelection == 1)
	{
		var newdate = new Date(this.CurrentYear,this.CurrentMonth-1,this.CurrentDate);
		var offset = 1 - newdate.getDay();
		if (offset != 0)
		{
			newdate = this.AddDays(newdate, offset);
			this.CurrentYear = newdate.getFullYear();
			this.CurrentMonth = newdate.getMonth() + 1;
			this.CurrentDate = newdate.getDate();
			datechange = true;
		}
	}
	var newdate = new Date(this.CurrentYear,this.CurrentMonth-1,this.CurrentDate);
	if (yearchange || monthchange || changeview || datechange || typechange || mandatoryrepainting)
	{
		if (this.maintable != null)
		{
			if (yearchange || monthchange || changeview || mandatoryrepainting) this.DrawMonthTable();
			this.DrawDaysTable();
			if (typechange || datechange || monthchange || yearchange)
			{
				var newMonth = newdate.getMonth();
				if (yearchange) this.CallGetEvents();
				if (newMonth != this.CurrentMonth-1)
				{
					this.SetCurrentDate(newdate.getFullYear(),this.CurrentMonth,newdate.getDate(),this.TypeSelection);
					return;
				}
			}
		}
	}
	else
	{
		this.CurrentViewYear = oldviewyear;
		this.CurrentViewMonth = oldviewmonth;
	}
	if (this.events != null && dontFireEvent != true) this.events.fireEvent("ondatechange",[newdate,this.TypeSelection]);
}
navigation_calendar.prototype.floorDate = function(date)
{
    if (date != null)
    {
        date.setHours(0);
        date.setMinutes(0);
        date.setSeconds(0); 
    }
    return date; 
}
navigation_calendar.prototype.AddDay = function(date)
{
	return this.AddDays(date,1);
}
navigation_calendar.prototype.RemoveDay = function(date)
{
	return this.AddDays(date,-1);
}
navigation_calendar.prototype.AddDays = function(date,inc)
{
	var dt = new Date(date.getFullYear(),date.getMonth(),date.getDate(), 12);
	dt = this.floorDate(new Date(dt.getTime() + inc*24*3600000));
	return dt;
}
navigation_calendar.prototype.AddYears = function(inc)
{
	if (this.CurrentYear + inc >= 0) 
		this.SetCurrentDate(this.CurrentViewYear + inc,null,null,this.TypeSelection,false,true);
}
navigation_calendar.prototype.InitMonthes = function()
{
	if (this.Monthes == null) this.Monthes = Date.MonthesAbbreviations;
	return this.Monthes;
}
navigation_calendar.prototype.InitDaysOfWeek = function()
{
	if (this.DaysOfWeek == null) this.DaysOfWeek = ["S","M","T","W","T","F","S"];
	return this.DaysOfWeek;
}
navigation_calendar.prototype.GetMonthClickHandler = function(month)
{
	return function(e){this.calendar.SetCurrentDate(null,month,null,this.calendar.TypeSelection,false,true); e.returnValue = false; }
}
navigation_calendar.prototype.GetDateClickHandler = function(date,TypeSelection)
{
	return function(e){this.calendar.SetCurrentDate(date.getFullYear(),date.getMonth() + 1,date.getDate(),TypeSelection); e.returnValue = false; }
}
navigation_calendar.prototype.Draw = function()
{
	var table, row, td;
	if (this.maintable == null)
	{
		this.maintable = DOMObjectFactory.CreateElement(UI.HtmlTag.Table);
		this.maintable.id = this.id;
		// TO DO: Viacheslav Kopichev (Memory leak problem)	
		dom_setProperty(this.maintable, "calendar", this);
		this.maintable.width = "100%";
		this.maintable.className="table-default calendar-inner";
		this.maintable.cellPadding = this.maintable.cellSpacing = this.maintable.border = 0;
		this.parent.appendChild(this.maintable);
		row = this.maintable.insertRow();
		td = row.insertCell();
		this.yeartable = DOMObjectFactory.CreateElement(UI.HtmlTag.Table);
		td.appendChild(this.yeartable);
		row = this.maintable.insertRow();
		td = row.insertCell();
		this.monthtable = DOMObjectFactory.CreateElement(UI.HtmlTag.Table);
		td.appendChild(this.monthtable);
		row = this.maintable.insertRow();
		td = row.insertCell();
		this.daysofweektable = DOMObjectFactory.CreateElement(UI.HtmlTag.Table);
		td.appendChild(this.daysofweektable);
		row = this.maintable.insertRow();
		td = row.insertCell();
		this.daystable = DOMObjectFactory.CreateElement(UI.HtmlTag.Table);
		td.appendChild(this.daystable);
		row.style.height = "100%";
	}
	this.DrawYearTable();
	this.DrawMonthTable();
	this.DrawDaysOfWeekTable();
	this.DrawDaysTable();
}
navigation_calendar.prototype.DrawYearTable = function()
{
	if (this.yeartable == null || this.yeartable.rows.length == 0)
	{
		this.yeartable.className = "calendar-year";
		this.yeartable.width = "100%";
		var row = this.yeartable.insertRow();
		var td;
		td = row.insertCell();
		dom_setProperty(td, "calendar", this);
		td.className = this.YearCellCssClass;
		td.nowrap = true;
		var span = DOMObjectFactory.CreateElement(UI.HtmlTag.Span);
		td.appendChild(span);
		var img = DOMObjectFactory.CreateElement(UI.HtmlTag.Image);
		img.width = img.height = "16";
		img.src = cmn_GetImageUrl("year-prev.png");
		img.title = "Prev";
		dom_attachEventForObject(img,"click",function(){img.parentElement.parentElement.calendar.AddYears(-1);});
		span.appendChild(img);
		span = DOMObjectFactory.CreateElement(UI.HtmlTag.Span);
		td.appendChild(span);
		span = DOMObjectFactory.CreateElement(UI.HtmlTag.Span);
		td.appendChild(span);
		img = DOMObjectFactory.CreateElement(UI.HtmlTag.Image);
		img.width = img.height = "16";
		img.src = cmn_GetImageUrl("year-next.png");
		img.title = "Next";
		dom_attachEventForObject(img,"click",function(){img.parentElement.parentElement.calendar.AddYears(1);});
		span.appendChild(img);
	}
	/*if ( this.CurrentViewYear == this.TodayYear)
		this.yeartable.rows[0].cells[3].disabled = true;
	else
		this.yeartable.rows[0].cells[3].disabled = false;*/
	this.yeartable.rows[0].cells[0].childNodes[1].innerText = this.CurrentViewYear;
}
navigation_calendar.prototype.DrawMonthTable = function()
{
	this.monthtable.style.width = "100%";
	this.monthtable.className = "table-default";
	var row;
	var len = this.Monthes.length;
	var havedrew = this.monthtable.rows == null || this.monthtable.rows.length == 0;
	for(var i=0; i<len; ++i)
	{
		var halflen = parseInt(len/2);
		var ind = i >= halflen ? 1 : 0;
		var ind2 = i >= halflen ? i - ind*halflen : i;
		if (havedrew)
		{
			if (i == 0 || i == halflen)
				row = this.monthtable.insertRow();
			td = row.insertCell();
			td.noWrap = true;
			td.width = 100/len + "%";
			td.calendar = this;
			dom_attachEventForObject(td,"click",this.GetMonthClickHandler(i+1));
			var a = DOMObjectFactory.CreateElement(UI.HtmlTag.A);
			a.href = "#";
			dom_attachEventForObject(a,"click",function() {return false;});
			a.innerText = this.Monthes[i];
			td.appendChild(a);
		}
		
		this.monthtable.rows[ind].cells[ind2].className = this.MonthCellCssClass;
		if (i+1 == this.CurrentViewMonth) 
			this.monthtable.rows[ind].cells[ind2].className = this.SelectedMonthCellCssClass;
		if ( this.CurrentViewYear < this.TodayYear || 
			 this.CurrentViewYear == this.TodayYear && i + 1 < this.TodayMonth)
				 this.monthtable.rows[ind].cells[ind2].className += " " + this.TextInactiveClass;
		else
			this.monthtable.rows[ind].cells[ind2].className += " " + this.TextActiveClass;
	}
}
navigation_calendar.prototype.DrawDaysOfWeekTable = function()
{
	var row,td;
	var len = this.DaysOfWeek.length;
	if (this.daysofweektable.rows == null || this.daysofweektable.rows.length == 0)
	{
		this.daysofweektable.style.width = "100%";
		this.daysofweektable.className = "table-default";
		row = this.daysofweektable.insertRow();
		var wd = 100/(len+1) + "%";
		for(var i=0, iLen=len+1;i<iLen;++i)
		{
			td = row.insertCell();
			td.noWrap = true;
			td.innerText = " ";
			td.width = wd;
			if (!str_IsStringEmpty(this.WeekCellCssClass))
				td.className = this.WeekCellCssClass;
		}
	}
	for(var i=0;i<len;++i) this.daysofweektable.rows[0].cells[i+1].innerText = this.DaysOfWeek[i];
}
navigation_calendar.prototype.IsDateInCurrentView = function(date)
{
	var startDt = this.floorDate(new Date(this.CurrentViewYear,this.CurrentViewMonth-1,1)), 
		day = startDt.getDay(), bgDt = this.AddDays(startDt,-(day==0?7:day)), enDt = this.AddDays(bgDt, 41);
	return (date >= bgDt && date <= enDt) ? true : false;	
}
navigation_calendar.prototype.DrawDaysTable = function()
{
	var row = null;
	var td = null;
	if (this.daystable.rows == null || this.daystable.rows.length == 0)
	{
		this.daystable.width = "100%";
		this.daystable.className = "table-default";
		for (var i=0,iLen=this.CountRows;i<iLen;++i)
		{
			row = this.daystable.insertRow();
			row.className = "calendar-row-days";
			var jLen=this.CountCells, wd=100/jLen+"%", ht=100/iLen+"%";
			for (var j=0;j<jLen;++j)
			{
				td = row.insertCell();
				var a = DOMObjectFactory.CreateElement(UI.HtmlTag.A);
				a.href = "#";
				dom_attachEventForObject(a,"click",function() {return false;});
				td.appendChild(a);
				// TO DO: Viacheslav Kopichev (Memory leak problem)	
				dom_setProperty(td, "calendar", this);
				td.width = wd;
				/*td.style.height = ht;
				td.nowrap = true;*/
				if (!str_IsStringEmpty(this.DateCellCssClass))
					td.className = this.DateCellCssClass;
				if (j==0) td.childNodes[0].innerHTML = "&#8594;";
			}
		}
		//this.daystable.rows[this.CountRows-1].style.visibility = "hidden";
	}
	var firstDate = new Date(this.CurrentViewYear,this.CurrentViewMonth - 1,1);
	var startrow = 0;
	var startcell = 0;
	var day = firstDate.getDay();
	
	if (day == 0) { startrow = 1; startcell=7; } else startcell=day;
		
	var date = this.floorDate(firstDate);
	//fill first row
	if (startrow == 0)
	{
		for (var j=startcell+1,jLen=this.CountCells;j<jLen;++j)
		{
			td = this.daystable.rows[startrow].cells[j];
			this.FillDateCell(td,date,startrow,j);
			date = this.AddDay(date); 
		}
		++startrow;
	}
	//to right bottom
	var savedate, iLen=this.CountRows, iLen2=iLen-2, jLen=this.CountCells, jLen1=jLen-1;
	for (var i=startrow;i<iLen;++i)
		for (var j=1;j<jLen;++j)
		{
			if (i == iLen2 && j == jLen1) savedate = date; 
			td = this.daystable.rows[i].cells[j];
			this.FillDateCell(td,date,i,j);
			date = this.AddDay(date);
		}
	/*if (savedate.getFullYear() == this.CurrentViewYear && savedate.getMonth() == this.CurrentViewMonth-1)
		this.daystable.rows[this.CountRows-1].style.visibility = "visible";
	else
		this.daystable.rows[this.CountRows-1].style.visibility = "hidden";*/
	//to left top
	var date = this.floorDate(firstDate);
	for (var j=startcell; j>0; --j)
	{
		date = this.RemoveDay(date);
		td = this.daystable.rows[0].cells[j];
		this.FillDateCell(td,date,0,j);
	}
	this.PlacementEvents();
}

navigation_calendar.prototype.FillDateCell = function(td,date,i,j)
{
	td.childNodes[0].innerText = date.getDate();
	td.date = date.getFullYear()+"-"+(date.getMonth()+1)+"-"+date.getDate();
	td.style.fontWeight = "normal";
	if (td.clickHandler)
		dom_detachEventForObject(td,"click",td.clickHandler);
	td.clickHandler = this.GetDateClickHandler(date,0);	
	dom_attachEventForObject(td,"click",td.clickHandler)
	if (j == 2)
	{
		var weekCell = this.daystable.rows[i].cells[0];
		if (weekCell.clickHandler)
			dom_detachEventForObject(weekCell,"click",weekCell.clickHandler);
		weekCell.clickHandler = this.GetDateClickHandler(date,1);
		dom_attachEventForObject(weekCell,"click",weekCell.clickHandler)
	}
	var sel = false;
	var currentdate = this.GetCurrentDate();
	
	var year = this.CurrentYear;
	var month = this.CurrentMonth - 1;
	var dt = this.CurrentDate;
	var day = currentdate.getDay();
	
	var startweekday = this.AddDays(currentdate,-day);
	var endweekday = this.AddDays(currentdate,6-day);
	
	var year1 = date.getFullYear();
	var month1 = date.getMonth();
	var dt1 = date.getDate();

	switch (this.TypeSelection)
	{
		case 0:
			if (year == year1 && month == month1 && dt == dt1) sel = true;
		        break;
		case 1:
			if (startweekday < date && date < endweekday) sel = true;
		break;
	}	
	td.style.fontWeight = "normal";
	td.className = this.DateCellCssClass;
	if (sel && this.enableSelecting)
		td.className = this.SelectedDateCellCssClass;
	else
	{
		if (month1 != this.CurrentViewMonth - 1)
			td.className += " " + this.TextInactiveClass;
	}
}

navigation_calendar.prototype.SetEvents = function(events)
{
	this.Events = events;
	this.PlacementEvents();
}

navigation_calendar.prototype.PlacementEvents = function()
{
	if (this.Events == null) return;
	if (this.daystable.rows != null)
		for (var i=0,iLen=this.CountRows,jLen=this.CountCells;i<iLen;++i)
			for (var j=1;j<jLen;++j)
				this.daystable.rows[i].cells[j].style.fontWeight = (this.Events[this.daystable.rows[i].cells[j].date] == 1)?"bold":"normal";
}

navigation_calendar.prototype.CallGetEvents = function()
{
	if (typeof(this.GetEvents) == "function") this.GetEvents(this,this.CurrentViewYear);
}

navigation_calendar.prototype.EnableSelecting = function(enable)
{
	if (this.enableSelecting != enable)
	{
		this.enableSelecting = enable;
		this.DrawDaysTable();
	}
}

function navigation_UpdateCalendar(calendar)
{
	if (calendar == null) return;
	var sdate = nav_currentNavInfo.GetParameter(P_NAVCALENDAR_DATE);
	var date = null;
	if (sdate != null) date = new Date().FromPostParam(sdate);
	var type = nav_currentNavInfo.GetParameter(P_NAVCALENDAR_TYPE);
	if (type == null) type = 0;
	type = parseInt(type);
	calendar.SetDateFrom(date,type);
}

function navigation_EnableSelecting(calendar, state)
{
	if (state == SRCH_SES_FILTER && nav_currentNavInfo.GetParameter(P_CALENDAR_FILTER_TYPE) == "1")
		calendar.EnableSelecting(false);
	else 
		calendar.EnableSelecting(true);
}

function fltr_OnNavigationCalendarChange(params)
{
	fltr_DoNavigationCalendarFilter(params[0], params[1]);
}

function fltr_DoNavigationCalendarFilter(date, type)
{
	var sdate = date;
	if (date.ToPostParam)
		sdate = date.ToPostParam();
	var query = new dm_QueryString();
	query.Add(P_NAVCALENDAR_TYPE, type == 0 ? '' : type);
	query.Add(P_NAVCALENDAR_DATE, sdate);
	var objdate = new Date();
	objdate = objdate.FromPostParam(sdate);
	query.Add(P_NAVCALENDAR_PERIOD, objdate.getFullYear() + "-" + (objdate.getMonth()+1));
	query.Add(P_CALENDAR_FILTER_TYPE);
	srch_inpDeleteFilters(SRCH_TN_PERIOD);
	srch_inpDoSearch(false);
	nav_ChangePagePersistantParams(query.getStringValue());
}