function luachCell (timestamp, indexInSet, moadim, city, env) {
	this.indexInSet = indexInSet;
	this.timestamp = timestamp;
	
	this.moed_str = "";
	this.moed_type = 0;
		
	this.isCurrent = false;
	this.isShabat = false;
	this.isLastInSet = false;
	this.isLuachCurrent = false;
	
	var cDate = new Date (timestamp);
	this.cdate = cDate.getDate();
	this.cmonth = cDate.getMonth() + 1;
	this.cyear = cDate.getFullYear();
	this.dow = cDate.getDay();
	
	var	hDate = getHebFromCiv(this.cdate, this.cmonth, this.cyear);
	this.hdate = hDate.date;
	this.hmonth = hDate.month;
	this.hyear = hDate.year;
	var hmonth_length = hDate.hmonthlength;
	
	var nextCDate = new Date (timestamp + 24*60*60*1000);
	
	var	nexthDate = getHebFromCiv(nextCDate.getDate(), nextCDate.getMonth() + 1, nextCDate.getFullYear());
	this.nexthdate = nexthDate.date;
	this.nexthmonth = nexthDate.month;
	this.nexthyear = nexthDate.year;
	var nexthmonth_length = nexthDate.hmonthlength;
	
	this.moadim = moadim.get_current_moadim (this.cdate, this.cmonth, this.cyear, city.galut);
	
	if (this.moadim.length > 0) {
		this.moed_type = this.moadim[0].get_type_by_date (this.cdate, this.cmonth, this.cyear);
		this.moed_str = strip_tags(moadim.get_term_moadim_str(this.moadim, this.cdate, this.cmonth, this.cyear));
	}
		
	if (this.dow == 6)
		this.isShabat = true;
			
	this.cellTitle = this.cdate + " " + env.CivMonthNamesRp[this.cmonth - 1] + " " + this.cyear + " / ";
	if (this.hmonth == this.nexthmonth) {
		this.cellTitle += this.hdate + " - " + this.nexthdate + " " + env.HebMonthNamesRp[this.hmonth] + " " + this.hyear;
	} else if (this.hyear == this.nexthyear) {
		this.cellTitle +=  this.hdate + " " + env.HebMonthNamesRp[this.hmonth] + " - " + this.nexthdate + " " + env.HebMonthNamesRp[this.nexthmonth] + " " + this.hyear;
	} else {
		this.cellTitle +=  this.hdate + " " + env.HebMonthNamesRp[this.hmonth] + " " + this.hyear + " - " + this.nexthdate + " " + env.HebMonthNamesRp[this.nexthmonth] + " " + this.nexthyear;
	}
		
	if (this.moed_type > 0) {
		this.cellTitle += "; " + this.moed_str;
	}
}

var prev_day_cellId;
var prev_day_cellUrl;
var prev_day_cellTitle; 
var prev_day_cellClass;
var prev_day_cdate;
var prev_day_cmonth;
var prev_day_cyear;
function luachCell_get_set (env, luach_month) {
	var output = "<td class='" + env.calendarClasses.cell + "'>\n\t<table cellpadding='0' cellspacing='0' border='0'>\n\t\t";
		
		if (this.indexInSet < 6)
			output += "<tr>\n\t\t\t<td class='" + env.calendarClasses.day_names + "left' " + (this.indexInSet != 0 ? "" : "style='border-top: none; border-bottom: none;'") + ">&nbsp;</td>\n\t\t\t	<td class='" + env.calendarClasses.day_names + "'>" + env.DaysNamesShort[this.indexInSet] + "</td>\n\t\t</tr>\n\t\t";
		else if (this.indexInSet == 6) 
			output += "<tr>\n\t\t\t<td class='" + env.calendarClasses.day_names + "left'>&nbsp;</td>\n\t\t\t<td class='" + env.calendarClasses.shab_name + "'>" + env.DaysNamesShort[this.indexInSet] + "</td>\n\t\t</tr>\n\t\t";		
		
		var cur_day_cellId = this.cdate +""+ this.cmonth +""+ this.cyear;
		var cur_day_cellClass = "";
		
		if (this.cmonth != luach_month)
			cur_day_cellClass = "Blank";
		else
			cur_day_cellClass = "Pure";
		
		switch (this.moed_type) {
			case IOM_TOV:
				cur_day_cellClass += "Event1";
				break;
			case HOL_A_MOED:
				cur_day_cellClass += "Event2";
				break;
			case HAG:
				cur_day_cellClass += "Event3";
				break;
			case ZOM:
				cur_day_cellClass += "Event4";
				break;
			case ROSH_HODESH:
				cur_day_cellClass += "Event5";
				break;
			case UNKNOWN_MOED_TYPE:
			default:
				if (this.isShabat)
					cur_day_cellClass += "Shabat";
				else
					cur_day_cellClass += "Simple";
				break;
		}
		
		var today = "";
		if (this.isCurrent) {
			today = "<div class='triplediv'></div>";
		} else if (this.isLuachCurrent && typeof(MedTerm) != 'undefined') {
			if (MedTerm.term_date == this.cdate && MedTerm.term_month == this.cmonth && MedTerm.term_year == this.cyear)
				today = "<div class='tripledivTerm'></div>";
		} else if (this.isLuachCurrent) {
				today = "<div class='tripledivTerm'></div>";
		}
		
		var cur_day_cellUrl = env.calendar_url + "?date=" + this.cdate + "&month=" + this.cmonth + "&year=" + this.cyear;
		var celladds1 = "";
		if (this.indexInSet%7 != 0)
			celladds1 += "onmouseover='cellhover(" + prev_day_cellId + ", true);return false;' onmouseout='cellhover(" + prev_day_cellId + ", false);return false;' onclick='change_term_date_by_date(" + prev_day_cdate + ", " + prev_day_cmonth + ", " + prev_day_cyear + ");' title='" + prev_day_cellTitle + "' cellid='" + prev_day_cellId + "'";
		else
			prev_day_cellClass = "";
			
		var celladds2 = "onmouseover='cellhover(" + cur_day_cellId + ", true);return false;' onmouseout='cellhover(" + cur_day_cellId + ", false);return false;' onclick='change_term_date_by_date(" + this.cdate + ", " + this.cmonth + ", " + this.cyear + ");' title='" + this.cellTitle + "' cellid='" + cur_day_cellId + "'";
		
		output += "<tr>\n\t\t\t<td " + celladds1 + " class='cellsetTopLeft " + prev_day_cellClass + "'>&nbsp;</td>\n\t\t\t<td class='cellsetTopRight" + (this.cdate > 9 ? "2" : "1") + " " + cur_day_cellClass + "' " + celladds2 + ">\n\t\t\t\t<a href='#'>" + this.cdate + "</a>\n\t\t\t</td>\n\t\t</tr>\n\t\t<tr>\n\t\t\t<td colspan='2' class='cellsetBottom " + cur_day_cellClass + "' " + celladds2 + ">" + today + "" + this.hdate + "</td>\n\t\t</tr>\n\t";
		
		output += "</table>\n</td>";
		
		if (this.indexInSet%7 == 6) {
			output += "<td class='rightEdge'" + (this.isLastInSet ? " style='border: none;'" : "") + ">\n\t<table width='8px' cellpadding='0' cellspacing='0' border='0'>\n\t\t";
			if (this.indexInSet == 6) {
				output += "<tr>\n\t\t\t<td class='" + env.calendarClasses.shab_name + "left'>&nbsp;</td>\n\t\t</tr>\n\t\t";
			}
										
			output += "<tr>\n\t\t\t<td title='" + this.cellTitle + "' class='cellsetTopLeft " + cur_day_cellClass + "' " + celladds2 + ">&nbsp;</td>\n\t\t</tr>\n\t\t<tr>\n\t\t\t<td class='edgeBottom'>&nbsp;</td>\n\t\t</tr>\n\t</table>\n</td>";
		}
		
		prev_day_cdate = this.cdate;
		prev_day_cmonth = this.cmonth;
		prev_day_cyear = this.cyear;
		prev_day_cellId = cur_day_cellId;
		prev_day_cellUrl = cur_day_cellUrl;
		prev_day_cellTitle = this.cellTitle;
		prev_day_cellClass = cur_day_cellClass;
		
		return output;		
}
luachCell.prototype.get_set = luachCell_get_set;

function Luach (luach_cdate, luach_cmonth, luach_cyear, current_cdate, current_cmonth, current_cyear, city, env, moadim) {
	this.cells = new Array();
	this.firstInMonthIndex = 0;
	this.lastInMonthIndex = 0;
	
	this.luach_cdate = luach_cdate;
	this.luach_cmonth = luach_cmonth;
	this.luach_cyear = luach_cyear;
	this.current_cdate = current_cdate;
	this.current_cmonth = current_cmonth;
	this.current_cyear = current_cyear;
	
	var firstDayOfWeekDate = new Date (luach_cyear, luach_cmonth - 1, 1, 1, 1, 1);
	var firstDayOfWeek = firstDayOfWeekDate.getDay();
	var lastDayOfWeekDate = new Date (luach_cyear, luach_cmonth - 1, civMonthLength(luach_cyear, luach_cmonth), 1, 1, 1);
	var lastDayOfWeek = lastDayOfWeekDate.getDay();
	
	var TodayDate = new Date (current_cyear, current_cmonth - 1, current_cdate, 1, 1, 1);
	var TodayStamp = TodayDate.getTime();
	var TodayLuach = new Date (luach_cyear, luach_cmonth - 1, luach_cdate, 1, 1, 1);
	var TodayLuachStamp = TodayLuach.getTime();
	var FirstMonthStamp = firstDayOfWeekDate.getTime();
	var LastMonthStamp = lastDayOfWeekDate.getTime();
	var SetBeginStamp = FirstMonthStamp - 1000*24*60*60*firstDayOfWeek; 
	var SetEndStamp = LastMonthStamp + 1000*24*60*60*(6 - lastDayOfWeek);
	var curStampDate = new Date (SetBeginStamp);
	var curStamp = curStampDate.getTime();
		
	var i = 0;
	this.moadim = moadim;
	
	while (Math.round((curStamp - SetEndStamp)/(3600*1000*24)) <= 0) {
		this.cells[i] = new luachCell (curStamp, i, this.moadim, city, env);
		if (Math.round((curStamp - FirstMonthStamp)/(3600*1000*24)) == 0)
			this.firstInMonthIndex = i;			
		if (Math.round((curStamp - LastMonthStamp)/(3600*1000*24)) == 0)
			this.lastInMonthIndex = i;
		if (Math.round((curStamp - TodayStamp)/(3600*1000*24)) == 0)
			this.cells[i].isCurrent = true;
		if (Math.round((curStamp - TodayLuachStamp)/(3600*1000*24)) == 0)
			this.cells[i].isLuachCurrent = true;
		curStamp += 1000*24*60*60; 
		i++;
	}
	this.cells[i - 1].isLastInSet = true;
}

function Luach_change_set (env) {
		this.change_set_header (env);
		var output = "<table align='center' class='" + env.calendarClasses.table + "' border='0' cellpadding='0' cellspacing='0'>\n\t\t\t<tr>\n\t\t\t\t";
		
		for (i in this.cells) {
			if (i > 0 && i%7 == 0)
				output += "</tr>\n\t\t\t<tr>\n\t\t\t\t";
			output += this.cells[i].get_set (env, this.luach_cmonth);
		}
		
		output += "</tr>\n\t\t</table>\n";
		
		$('#monthset').html(output);
}
Luach.prototype.change_set = Luach_change_set;

function Luach_change_set_header (env) {
		var output = "<b>" + env.CivMonthNames[this.luach_cmonth - 1] + "  " + this.luach_cyear + "</b><br>";
		
		var firstHebMonthNum = this.cells[this.firstInMonthIndex].hmonth;
		var lastHebMonthNum = this.cells[this.lastInMonthIndex].hmonth;
		var firstHebYear = this.cells[this.firstInMonthIndex].hyear;
		var lastHebYear = this.cells[this.lastInMonthIndex].hyear;
				
		if (firstHebMonthNum == lastHebMonthNum) {
			output += env.HebMonthNames[firstHebMonthNum] + "  " + firstHebYear;
		} else {
			if (firstHebYear == lastHebYear) {
				output += env.HebMonthNames[firstHebMonthNum] + " / " + env.HebMonthNames[lastHebMonthNum] + "  " + firstHebYear;
			} else {
				output += env.HebMonthNames[firstHebMonthNum] + " " + firstHebYear + " / " + env.HebMonthNames[lastHebMonthNum] + " " + lastHebYear;
			}
		}
		
		$('#monthnames').html(output);
}
Luach.prototype.change_set_header = Luach_change_set_header;

function Luach_change_moadim (city) {
	var recent_moadim = moadim.get_recent_moadim (this.luach_cdate, this.luach_cmonth, this.luach_cyear, city.galut);
	if (recent_moadim.length > 0) {
		$('div.recent_moadim').html("<b>Недавно был" + (recent_moadim.length > 1 ? "и" : "") + ":</b><br>" + moadim.get_set_moadim_str (recent_moadim, this.luach_cdate, this.luach_cmonth, this.luach_cyear));
	} else {
		$('div.recent_moadim').html("");
	}
	var	current_moadim = moadim.get_current_moadim (this.luach_cdate, this.luach_cmonth, this.luach_cyear, city.galut);
	if (current_moadim.length > 0) {
		$('div.current_moadim').html("<b>Сейчас:</b><br>" + moadim.get_set_moadim_str (current_moadim, this.luach_cdate, this.luach_cmonth, this.luach_cyear));
	} else {
		$('div.current_moadim').html("");
	}
	var	coming_moadim = moadim.get_coming_moadim (this.luach_cdate, this.luach_cmonth, this.luach_cyear, city.galut);
	if (coming_moadim.length > 0) {
		$('div.coming_moadim').html("<b>Скоро:</b><br>" + moadim.get_set_moadim_str (coming_moadim, this.luach_cdate, this.luach_cmonth, this.luach_cyear));
	} else {
		$('div.coming_moadim').html("");
	}
}
Luach.prototype.change_moadim = Luach_change_moadim;

function Luach_change_nextshabat (city, env) {
		if (nextShabatNewDate == false && nextShabatNewCity == false)
			return;
			
		if (nextShabatNewCity == true) {
				nextShabatZmanim.latitude = city.latitude;
				nextShabatZmanim.longitude = city.longitude;
				nextShabatZmanim.timezone = city.gmt + city.swtime;
				nextShabatZmanim.set_knissat(city.shabatAdj);
		}
			
		var luach_CDate = new Date (this.luach_cyear, this.luach_cmonth - 1, this.luach_cdate, 1, 1, 1);
		var luach_dow = luach_CDate.getDay();
		if (luach_dow == 6) {
			var luach_PrevCDate = new Date (luach_CDate.getTime() - 24*3600*1000);
			var doys = getDoys (this.luach_cdate, this.luach_cmonth, this.luach_cyear);
			nextShabatZmanim.day_of_year = doys[0];
			nextShabatZmanim.day_of_year_prev = doys[1];
			nextShabatZmanim.day_of_year_next = doys[2];
			nextShabatZmanim.set_zmanim();
			
			
			var tzeit = nextShabatZmanim.zmanim[nextShabatZmanim.get_zman_key_by_keyword ("tzeit")];
			if(tzeit.time < clockHour + clockMin/60) {
				var nextShabatOffset = 7;				
			} else {
				nextShabatMotzeiTime = {'time': tzeit.time, 'date': this.luach_cdate, 'month': this.luach_cmonth, 'year': this.luach_cyear};
				
				var doys = getDoys (luach_PrevCDate.getDate(), luach_PrevCDate.getMonth() + 1, luach_PrevCDate.getFullYear());
				nextShabatZmanim.day_of_year = doys[0];
				nextShabatZmanim.day_of_year_prev = doys[1];
				nextShabatZmanim.day_of_year_next = doys[2];
				nextShabatZmanim.set_zmanim();
				
				var knissat = nextShabatZmanim.zmanim[nextShabatZmanim.get_zman_key_by_keyword ("knissat")];
				nextShabatKnissatTime = {'time': knissat.time, 'date': luach_PrevCDate.getDate(), 'month': luach_PrevCDate.getMonth() + 1, 'year': luach_PrevCDate.getFullYear()};
				
				$('#nextShabatKnissatDate').text(format_2digits(nextShabatKnissatTime.date) + '.' + format_2digits(nextShabatKnissatTime.month) + '.' + nextShabatKnissatTime.year.toString().substr(2,2));
				$('#nextShabatKnissatTime').text(timeadj(nextShabatKnissatTime.time, city.ampm, knissat.roundup));
		
				$('#nextShabatMotzeiDate').text(format_2digits(nextShabatMotzeiTime.date) + '.' + format_2digits(nextShabatMotzeiTime.month) + '.' + nextShabatMotzeiTime.year.toString().substr(2,2));
				$('#nextShabatMotzeiTime').text(timeadj(nextShabatMotzeiTime.time, city.ampm, tzeit.roundup));
				
				return;
			}
		} else {
			nextShabatOffset = 6 - luach_dow;
		}
		
		var PrevCDate  = new Date (luach_CDate.getTime() + 24*3600*1000*(nextShabatOffset-1));
		var ShabCDate  = new Date (luach_CDate.getTime() + 24*3600*1000*(nextShabatOffset));

		var doys = getDoys (PrevCDate.getDate(), PrevCDate.getMonth() + 1, PrevCDate.getFullYear());
		nextShabatZmanim.day_of_year = doys[0];
		nextShabatZmanim.day_of_year_prev = doys[1];
		nextShabatZmanim.day_of_year_next = doys[2];
		nextShabatZmanim.set_zmanim();
				
		var knissat = nextShabatZmanim.zmanim[nextShabatZmanim.get_zman_key_by_keyword ("knissat")];
		nextShabatKnissatTime = {'time': knissat.time, 'date': PrevCDate.getDate(), 'month': PrevCDate.getMonth() + 1, 'year': PrevCDate.getFullYear()};
		
		var doys = getDoys (ShabCDate.getDate(), ShabCDate.getMonth() + 1, ShabCDate.getFullYear());
		nextShabatZmanim.day_of_year = doys[0];
		nextShabatZmanim.day_of_year_prev = doys[1];
		nextShabatZmanim.day_of_year_next = doys[2];
		nextShabatZmanim.set_zmanim();
		
		var tzeit = nextShabatZmanim.zmanim[nextShabatZmanim.get_zman_key_by_keyword ("tzeit")];
		nextShabatMotzeiTime = {'time': tzeit.time, 'date': ShabCDate.getDate(), 'month': ShabCDate.getMonth() + 1, 'year': ShabCDate.getFullYear()};
		
		$('#nextShabatKnissatDate').text(format_2digits(nextShabatKnissatTime.date) + '.' + format_2digits(nextShabatKnissatTime.month) + '.' + nextShabatKnissatTime.year.toString().substr(2,2));
		$('#nextShabatKnissatTime').text(timeadj(nextShabatKnissatTime.time, city.ampm, knissat.roundup));
		$('#nextShabatMotzeiDate').text(format_2digits(nextShabatMotzeiTime.date) + '.' + format_2digits(nextShabatMotzeiTime.month) + '.' + nextShabatMotzeiTime.year.toString().substr(2,2));
		$('#nextShabatMotzeiTime').text(timeadj(nextShabatMotzeiTime.time, city.ampm, tzeit.roundup));
		return;
	}
Luach.prototype.change_nextshabat = Luach_change_nextshabat;

