function parseUri (str) {
	var	o   = parseUri.options,
		m   = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
		uri = {},
		i   = 14;

	while (i--) uri[o.key[i]] = m[i] || "";

	uri[o.q.name] = {};
	uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
		if ($1) uri[o.q.name][$1] = $2;
	});

	return uri;
};
parseUri.options = {
	strictMode: false,
	key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
	q:   {
		name:   "queryKey",
		parser: /(?:^|&)([^&=]*)=?([^&]*)/g
	},
	parser: {
		strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
		loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
	}
};

(function($){
    $.fn.jqueryCal = function(options){
        var defaults = {
            xmlPath: 'calendar_events.php?',
            noEvents: 'no events.',
            noEventsToday: 'no events today',
            monthText: '',
            getXMLmonthly: false,
            toolTipBigPrev: "Предыдущий год",
            toolTipSmallPrev: "Предыдущий месяц",
            toolTipSmallNext: "Следующий год",
            toolTipBigNext: "Следующий год",
            isShowEventDesc: false
        };
        var options = $.extend(defaults, options);
        return this.each(function(){
            // global vars
            datesLoaded = new Array();
            var divID = $(this).attr("id");
            var dateList = new Array();
            var weekClasses = new Array("Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс");
            var weekday = new Array("Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag");
            var currentDate = new Date();
            currentDate.setHours(0);
            currentDate.setMinutes(0);
            currentDate.setSeconds(0);
            currentDate.setMilliseconds(0);
            var selectedDate = new Date();
            selectedDate.setDate(1);
            selectedDate.setHours(0);
            selectedDate.setMinutes(0);
            selectedDate.setSeconds(0);
            selectedDate.setMilliseconds(0);
            var selectedWeek = new Date();
            selectedWeek.setHours(0);
            selectedWeek.setMinutes(0);
            selectedWeek.setSeconds(0);
            selectedWeek.setMilliseconds(0);
            var tempDate = new Date();
            tempDate.setHours(0);
            tempDate.setMinutes(0);
            tempDate.setSeconds(0);
            tempDate.setMilliseconds(0);
            var clickedEventText = "";
            var todayText = "";
            var xmlPath = xmlPath;
            var tmpString = "";
            var tmpStringParts = new Array();
            var datesInWeek = new Array();
            var htmlString = "";

            writeHTML();

            // parse XML
            function parseXML(){
                try {
			if (datesLoaded[ selectedDate.getFullYear() ] != undefined && datesLoaded[ selectedDate.getFullYear() ][ selectedDate.getMonth() + 1 ] != undefined ) {
				fillHTML();
			} else {
				if (options.getXMLmonthly) {
					xmlPath = options.xmlPath + "year=" + selectedDate.getFullYear() + "&month=" + (selectedDate.getMonth() + 1);
					if ( datesLoaded[ selectedDate.getFullYear() ] == undefined ) {
						datesLoaded[ selectedDate.getFullYear() ] = new Array();
					}
					if ( datesLoaded[ selectedDate.getFullYear() ][ selectedDate.getMonth() + 1 ] == undefined ) {
						datesLoaded[ selectedDate.getFullYear() ][ selectedDate.getMonth() + 1 ] = new Array();
					}				
				} else  {
					xmlPath = options.xmlPath + "year=" + selectedDate.getFullYear();
					datesLoaded[ selectedDate.getFullYear() ] = new Array();
					for (var i = 0; i < 12; i++) {
						datesLoaded[ selectedDate.getFullYear() ][ i + 1 ] = new Array();
					}
				}

				// parse XML
				$.ajax({
					type: "GET",
					url: xmlPath,
					dataType: "xml",
					success: function(xml){
					$(xml).find('calendardoc').each(function(i){
						var event = new Object();
						event["id"]		= $(this).find('id').text();
						event["dateStart"]	= new Date($(this).children("dateStart").text());
						event["dateEnd"]	= new Date($(this).children("dateEnd").text());
						event["title"]		= $(this).find('title').text();
						event["text"]		= $(this).find('text').text();
						event["link"]		= $(this).find('url').text();
						event["isCurrentRegion"]= $(this).find('isCurrentRegion').text();
						if ( event["isCurrentRegion"] == 2 && options.isShowEventDesc ) {
							$('.content').html( '<div style="float: left;">' + event["dateStart"].toLocaleDateString() + '</div><div style="float: right;">' + $(this).find('regionName').text() + '</div><p style="clear: both;"><a class="link_2" href="http://seminars.softline.ru/it_page.php?id=' + event["id"] + '">' + event["title"] + '</a></p>' );
						}
						dateList.push(event);
					});
					fillHTML();
					}
				})
			}
                } 
                catch (err) {
                    fillHTML();
                }
            }

            // write HTML
            function writeHTML(){

		parsedUri = parseUri(document.location);
		if (parsedUri.queryKey.m != undefined) {
			selectedDate.setMonth(parsedUri.queryKey.m - 1);
		}


                if ((divID).match("Month")) {
                    htmlString += "<div class='head'><a class='bigPrev' title='" + options.toolTipBigPrev + "' href='#'>&laquo;</a><a class='smallPrev'  title='" + options.toolTipSmallPrev + "' href='#'>&lt;</a><span class='text'></span><a class='smallNext' title='" + options.toolTipSmallNext + "' href='#'>&gt;</a><a class='bigNext' title='" + options.toolTipBigNext + "' href='#'>&raquo;</a></div><div class='body'><div class='calendarWeekContainer'>";
                    //htmlString += "<span class='kw'>&nbsp;</span>";
                    for (var i = 0; i <= 5; i++) {
                        htmlString += "<span class='calendarWeek'></span>";
                    }
                    htmlString += "</div><div class='weekDaysContainer'>";
                    for (var i = 0; i <= 6; i++) {
                        htmlString += "<span class='weekDays " + weekClasses[i] + "'></span>";
                    }
                    htmlString += "</div><div class='weekDatesContainer'>";
                    for (var i = 0; i <= 41; i++) {
                        var j = 0;
                        j++;
                        htmlString += "<span class='weekDates " + weekClasses[j] + "'></span>";
                        if (j = 6) 
                            j = 0;
                    }
                    //htmlString += "</div><div class='content'>" + options.defaultEvent + "</div></div>";
			htmlString += "</div><div class='content'></div></div>";
                    $("#" + divID).html(htmlString);
                    // month
			$("#" + divID + " .head .bigPrev").click(function(){
				selectedDate.setYear(selectedDate.getFullYear() - 1);

				parseXML();
				return false;
			});
			$("#" + divID + " .head .smallPrev").click(function(){
				if (selectedDate.getMonth()) {
					selectedDate.setMonth(selectedDate.getMonth() - 1);
				} else {
					selectedDate.setYear(selectedDate.getFullYear() - 1);
					selectedDate.setMonth(11);
				}
				

				parseXML();
				return false;
			});
			$("#" + divID + " .head .smallNext").click(function(){

			if (selectedDate.getMonth() < 11) {
					selectedDate.setMonth(selectedDate.getMonth() + 1);
				} else {
					selectedDate.setYear(selectedDate.getFullYear() + 1);
					selectedDate.setMonth(0);
				}

				parseXML();
				return false;
			});
			$("#" + divID + " .head .bigNext").click(function(){
				selectedDate.setYear(selectedDate.getFullYear() + 1);

				parseXML();
				return false;
			});
                }

                fillHTML();
                parseXML();
            }

            // fill HTML
            function fillHTML(){
                if ((divID).match("Month")) {
                    // clean HTML
                    cleanHTMLMonth();
                    var firstOfSelectedMonth = selectedDate;
                    firstOfSelectedMonth.setDate(1);
                    currentDate = new Date();
                    parsedUri = parseUri(document.location);
                    if (parsedUri.queryKey.y != undefined) {
                        currentDate.setFullYear(parsedUri.queryKey.y);
                    }
                    if (parsedUri.queryKey.m != undefined) {
                        currentDate.setMonth(parsedUri.queryKey.m - 1);
                    }
                    if (parsedUri.queryKey.y != undefined) {
                        currentDate.setDate(parsedUri.queryKey.d);
                    }
                    $("#" + divID + " .head .text").html('<a class="link_2" href="http://seminars.softline.ru/calendar.php?m=' + (selectedDate.getMonth() + 1) + '&year=' + selectedDate.getFullYear() + '">' + options.monthText + " " + selectedDate.getMonthName() + " " + selectedDate.getFullYear() + '</a>');
                    for (i = 0; i <= weekClasses.length; i++) {
                        $("#" + divID + " .body .weekDaysContainer .weekDays." + weekClasses[i]).text(weekClasses[i]);
                    }
                    var startWrite = 0;
                    var j = 1;
                    if (selectedDate.getDay() == 0) {
                        startWrite = 6;
                    }
                    else {
                        startWrite = selectedDate.getDay() - 1;
                    }

                    $("#" + divID + " .body .weekDatesContainer .weekDates").each(function(i){
                        if (startWrite <= i && j <= (daysInMonth(firstOfSelectedMonth.getMonth() + 1, firstOfSelectedMonth.getFullYear() + 1))) {
                            $(this).html('<a class="link_2" href="http://seminars.softline.ru/calendar.php?d=' + j + '&m=' + (selectedDate.getMonth() + 1) + '&y=' + selectedDate.getFullYear()  + '">' + j + '</a>');
                            $(this).addClass("pointer").attr('date',j);//.addClass('date'+j);
                            $(this).hover(function(){
                                $(this).addClass("hover");
                            }, function(){
                                $(this).removeClass("hover");
                            });
                            j++;
                            // mark current day
                            if ((selectedDate.getMonth() == currentDate.getMonth()) && (selectedDate.getFullYear() == currentDate.getFullYear()) && ($(this).text() == currentDate.getDate())) 
                                $(this).addClass("currentDate");
                        }
                    });
                    // mark events
                    for (var i = 0; i < dateList.length; i++) {
			if ((dateList[i]["dateStart"].getMonth() != selectedDate.getMonth()) || (dateList[i]["dateStart"].getYear() != selectedDate.getYear())) {
				continue;
			}
		
			$("#" + divID + " .body .weekDatesContainer span.weekDates[date=" + dateList[i]["dateStart"].getDate()+']').addClass('event');
                    }
                    // add events
                    addEventInfo();
                }
            }
            
            
            // clean HTML month
            function cleanHTMLMonth(){
                $("#" + divID + " .body .weekDatesContainer .weekDates").each(function(){
                    $(this).text("");
                    $(this).removeClass("event").removeClass("currentDate").removeClass("pointer").removeAttr("date").unbind();
                    $(this).click(function(){
                    });
                });
                $("#" + divID + " .head .text").text = "";
            }
            
            
            // clean HTML week
            function cleanHTMLWeek(){
                $("#" + divID + " .body .date").each(function(j){
                    $(this).removeClass("event");
                    $(this).removeClass("currentDate");
                    $(this).removeClass("pointer");
                    $(this).unbind();
                    $(this).click(function(){
                    });
                });
                $("#" + divID + " .head .text").text = "";
            }
            
            
            // get days of month
            function daysInMonth(month, year){
                var m = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
                if (month != 2) 
                    return m[month - 1];
                if (year % 4 != 0) 
                    return m[1];
                if (year % 100 == 0 && year % 400 != 0) 
                    return m[1];
                return m[1] + 1;
            }


            // week of year & week of month
            function getWeekOfMonth(date){
                var todayDayOfMonth = date.getDate() - 1;
                var first = new Date(date.getFullYear() + '/' + (date.getMonth() + 1) + '/01');
                var monthFirstDateDay = first.getDay();
                return Math.ceil((todayDayOfMonth + monthFirstDateDay) / 7);
            }


            // calculate CalendarWeek
            function getCalendarWeek(jahr, monat, tag){
                var datum = new Date(jahr, monat - 1, tag);
                var jh = jahr + 1;
                var kalwo = getkaldiff(datum, jh);
                while (kalwo < 1) {
                    jh--;
                    kalwo = getkaldiff(datum, jh);
                }
                return kalwo;
            }
            function getkaldiff(datum, jahr){
                var d4j = new Date(jahr, 0, 4);
                var wt4j = (d4j.getDay() + 6) % 7;
                var m1wjT = Math.floor(0.01 + d4j.getTime() / 864e5 - wt4j);
                var datumT = Math.floor(0.01 + datum.getTime() / 864e5);
                return Math.floor(1 + (datumT - m1wjT) / 7);
            }

            // add event info  
	function addEventInfo(){
		if ((divID).match("Month")) {
			// add day events
			$("#" + divID + " .body .weekDatesContainer .pointer").each(function(){
				$(this).hover(function(){
					$(this).addClass("mouseOver");
				}, function(){
					$(this).removeClass("mouseOver");
				});

				if ( options.isShowEventDesc ) {
					// показывать события на выбранный день
					$(this).mouseover(function(){
						$("#" + divID + " .body .weekDatesContainer .pointer").each(function(){
							$(this).removeClass("currentDate");
						});
						$(this).addClass("currentDate");
						clickedEventText = "";
						selectedDate.setDate($(this).text());
						for (var i = 0; i <= dateList.length - 1; i++) {
							if (selectedDate.toLocaleDateString() >= dateList[i]["dateStart"].toLocaleDateString() && selectedDate.toLocaleDateString() <= dateList[i]["dateEnd"].toLocaleDateString() ) {
							//clickedEventText = clickedEventText.concat("<b>" + dateList[i]["title"] + "</b><br />" + c.toLocaleDateString() + "<br />" + dateList[i]["text"] + "<br />"); // <a href class='url'>" + dateList[i]["url"] + "</a>
								if ( dateList[i]["isCurrentRegion"] == 1 ) {
									clickedEventText = clickedEventText.concat('<p class="calendar-event"><a class="link_2" href="http://seminars.softline.ru/it_page.php?id=' + dateList[i]["id"] + '">' + dateList[i]["title"] + '</a></p>');
								}
							}
						}
						if (clickedEventText == "") {
							clickedEventText = '';//"<b>" + clickedEventText.concat(options.noEvents) + "</b>";
						} else {
							//clickedEventText = '<a href="http://seminars.softline.ru/calendar.php?d=' + selectedDate.getDate() + '&m=' + (selectedDate.getMonth() + 1) + '&y=' + selectedDate.getFullYear()  + '">' + selectedDate.toLocaleDateString() + '</a>' + "\r\n" + '<ul>' + clickedEventText + '</ul>';
							clickedEventText = clickedEventText;
						}
						$("#" + divID + " .content").html(clickedEventText);
						return false;
					})
				}
			});

			if ((currentDate.getMonth() == selectedDate.getMonth()) && (currentDate.getFullYear() == selectedDate.getFullYear())) {
				//$('.weekDates.currentDate').click();
                    	}
		}
	}
	});
    };
})(jQuery);

