﻿if(!window.c1_webcalendar_loaded)
{

    //===Constants==============================
    var c1_dayofweek_sunday = 0;
    var c1_dayofweek_monday = 1;
    var c1_dayofweek_tuesday = 2;
    var c1_dayofweek_wednesday = 3;
    var c1_dayofweek_thursday = 4;
    var c1_dayofweek_friday = 5;
    var c1_dayofweek_saturday = 6;
    
    var c1_daytype_default = 0;
    var c1_daytype_weekend = 1;
    var c1_daytype_othermonth = 2;
    var c1_daytype_outofrange = 4;
    var c1_daytype_today = 8;
    var c1_daytype_custom = 16;
    var c1_daytype_disabled = 32;
    var c1_daytype_selected = 64;
    var c1_daytype_gap = 128;
    
    var c1_weekdayformat_firstletter = 0;
    var c1_weekdayformat_firsttwoletters = 1;
    var c1_weekdayformat_abbreviated = 2;
    var c1_weekdayformat_full = 3;
    
    var c1_monthdayformat_default = 0;
    var c1_monthdayformat_zeropadding = 1;
    
    var c1_selectionmode_none = 0;
    var c1_selectionmode_day = 1;
    var c1_selectionmode_days = 2;
    var c1_selectionmode_weekday = 4;
    var c1_selectionmode_weeknumber = 8;
    var c1_selectionmode_month = 16;
    
    var c1_navbtn_unknown = -1;
    var c1_navbtn_qprev = 0;
    var c1_navbtn_prev = 1;
    var c1_navbtn_next = 2;
    var c1_navbtn_qnext = 3;
    
    var c1_previewbtn_unknown = -1;
    var c1_previewbtn_prev = 0;
    var c1_previewbtn_next = 1;
    
    
    //===Global functions=======================
    function Calendar_CreateDate(year, month, day)
    {
	    month-=1;
	
	    while(true)
	    {
		    var date=new Date(year,month,day);
		    if(date.getDate()==day)	{return date;};
		    day-=1;
	    };
    };
    
    function Calendar_GetDateString(date)
    {
        return date.getFullYear() + "_" + (date.getMonth() + 1) + "_" + date.getDate();
    }
    
    function Calendar_GetMonthString(date)
    {
        return date.getFullYear() + "_" + (date.getMonth() + 1);
    }
    
    function Calendar_FormatDateString(format, date)
    {
        if (C1_IsStringNullOrEmpty(format))
            format = "MMM d, y, EE";
            
        return date.c1_LocalFormat(format);
    }
    
    function Calendar_Mod(val,n)
    {
	    var val=val%n;
	    while(val<0)val+=n;
    	
	    return val;
    };

    function Calendar_ModNonZero(val,n)
    {
	    var val=val%n;
	    while(val<=0)val+=n;
    	
	    return val;
    };
    
    function Calendar_GetPrevMonth(date)
    {
        var year = date.getFullYear();
        var month = date.getMonth();
        
	    if(month==1)
	    {
	        year--;
	        month = 12;
	    }else
	    {
	        month--;
	    };
	    
	    return new Date(year, month, 1);
    };

    function Calendar_GetNextMonth(date)
    {
        var year = date.getFullYear();
        var month = date.getMonth();
        
	    if(month==12)
	    {
	        year++;
	        month = 1;
	    }else
	    {
	        month++;
	    };
	    
	    return new Date(year, month, 1);
    };
    
    
    //===CalendarCellStyle====================
    
    function CalendarCellStyle(css, style, hoverCss, hoverStyle)
    {
        this.CssClass = css;
        this.Style = style;
        this.HoverCssClass = hoverCss;
        this.HoverStyle = hoverStyle;
    }
    
    CalendarCellStyle.prototype.GetProperty=function(propName) { return this[propName]; };
    CalendarCellStyle.prototype.SetProperty=function(propName,propValue) { this[propName]=propValue; };
    
    CalendarCellStyle.prototype.Clone=function()
    {
        return new CalendarCellStyle(this.CssClass, this.Style, this.HoverCssClass, this.HoverStyle);
    }
    
    CalendarCellStyle.prototype.MergeWith=function(style)
    {   
        if (style == null) return;
    
        if (!C1_IsStringNullOrEmpty(style.CssClass))
            this.CssClass = style.CssClass;
            
        if (!C1_IsStringNullOrEmpty(style.HoverCssClass))
            this.CssClass = style.HoverCssClass;
        
        this.Style = this.Style + ";" + style.Style;
        this.HoverStyle = this.HoverStyle + ";" + style.HoverStyle;
        
        if (!C1_IsStringNullOrEmpty(this.Style))
        {
            this.Style = this.Style.replace(";;", ";");
        }
        
        if (!C1_IsStringNullOrEmpty(this.HoverStyle))
        {
            this.HoverStyle = this.HoverStyle.replace(";;", ";");
        }
    }
    
    //===CalendarDay==========================
    function CalendarDay(date, style, template)
    {
        this.Date = date.c1_GetDateOnly();
        this.Style = style;
        this.Template = template;
    };

    CalendarDay.prototype.GetProperty=function(propName){return this[propName];};
    CalendarDay.prototype.SetProperty=function(propName,propValue){this[propName]=propValue;};


    //===CalendarDayCollection================
    function CalendarDayCollection()
    {
	    this.coll = new Array();
    };

    CalendarDayCollection.prototype.GetProperty = function(propName){return this[propName];};
    CalendarDayCollection.prototype.SetProperty = function(propName,propValue){this[propName]=propValue;};

    CalendarDayCollection.prototype.Add = function(calendarDay)
    {
        this.coll[calendarDay.Date.c1_GetDateOnly()] = calendarDay;
    }
    
    CalendarDayCollection.prototype.Remove = function(date)
    {
        this.coll[date.c1_GetDateOnly()] = undefined;
    }
    
    CalendarDayCollection.prototype.Clear = function()
    {
        this.coll = new Array();
    }
    
    CalendarDayCollection.prototype.Count = function()
    {
        var size = 0;

        for (var i in this.coll)
        {
            if (this.coll[i] != undefined)
                size ++;
        }

        return size;
    }
    
    CalendarDayCollection.prototype.Get = function(date)
    {
        return this.coll[date.c1_GetDateOnly()];
    }

    CalendarDayCollection.prototype.Contains = function(date)
    {
         var exists = false;
         var d = date.c1_GetDateOnly().toString();

        for (var i in this.coll)
        {
            if (i == d && this.coll[i] != undefined)
            {
                exists = true;
                break;
            }
        }
        return exists;
    }
    
    
    //===DateCollection========================
    function DateCollection(dateArray)
    {
        this.Clear();
        for(var i = 0; i < dateArray.length; i++)
            this.Add(new Date(dateArray[i]));
    };

    DateCollection.prototype.GetProperty=function(propName) { return this[propName]; };
    DateCollection.prototype.SetProperty=function(propName,propValue) { this[propName]=propValue; };

    DateCollection.prototype.Count=function()
    {
        return this.DateArray.length;
    };

    DateCollection.prototype.Clear=function()
    {
	    this.DateArray = new Array();
    };
    
    DateCollection.prototype.IndexOf=function(date)
    {
        return this.FindRangeBound(date, true, false);
    };

    DateCollection.prototype.Contains=function(date)
    {
	    return this.IndexOf(date) != -1;
    };

    DateCollection.prototype.Remove=function(date)
    {
	    this.RemoveRange(date,date);
    };

    DateCollection.prototype.Add=function(date)
    {
	    this.AddRange(date,date);
    };

    DateCollection.prototype.FindRangeBound=function(date, exact, isStart)
    {
        date = date.c1_GetDateOnly();
	    var low = 0;
	    var hi = this.DateArray.length;
	            
	    var index;
	    while(low<hi)
	    {
		    index = (low+hi)>>1;
		    if(date.valueOf() == this.DateArray[index].valueOf())  return index;
    		
		    if(date < this.DateArray[index])
		    {
			    hi=index;
		    }else
		    {
			    low=index+1;
		    };
	    };
	    
	    if (exact) return -1;
	    return isStart ? low : hi;
    };

    DateCollection.prototype.RemoveRange=function(startDate,endDate)
    {
	    var startIndex=this.FindRangeBound(startDate, false, true);
	    var endIndex=this.FindRangeBound(endDate, false, false);
	    
	    if (startIndex < 0 || endIndex < 0) {return;};
	    if(startIndex>endIndex){return;};
    	
	    var startSlice=startIndex==0?[]:this.DateArray.slice(0,startIndex);
	    var endSlice=this.DateArray.slice(endIndex);
	    this.DateArray=startSlice.concat(endSlice);
    };

    DateCollection.prototype.AddRange=function(startDate,endDate)
    {
	    this.RemoveRange(startDate,endDate);
	    var insertIndex=this.FindRangeBound(startDate, false, true);
	    var startSlice=insertIndex==0?[]:this.DateArray.slice(0,insertIndex);
	    var endSlice=this.DateArray.slice(insertIndex);
	    var midSlice=[];
	    var startDate=startDate.c1_GetDateOnly();
	    var endDate=endDate.c1_GetDateOnly();
    	
	    for(var curDate=startDate;curDate<=endDate;curDate=curDate.c1_AddDays(1))
	    {
	        midSlice[midSlice.length]=curDate;
	    };

	    this.DateArray=startSlice.concat(midSlice.concat(endSlice));
    };
    
    DateCollection.prototype.ToDateArray=function()
    {
        var dateArray = new Array();
        if (!this.DateArray) return dateArray;
        
        for(var i = 0; i < this.DateArray.length; i++)
            dateArray[i] = this.DateArray[i];
            
        return dateArray;
    };
    
    DateCollection.prototype.ToString=function()
    {
        if (this.DateArray != null)
            return this.DateArray.toString();
            
        return "";
    }
    

    //===MonthView========================
    function MonthView(calendar, id, displayDate)
    {
        this._owner = calendar;
        this._id = id;
        
        var blankDate = new Date(1900, 0, 1);
        if (!displayDate) displayDate = new Date();
        if (displayDate.valueOf() == blankDate.valueOf()) displayDate = new Date();
        
        this.DisplayDate = displayDate;
        this.Visible = true;
        this.ShowTitle = true;
        
        this.CalcDates(this.DisplayDate);
    }
    
    MonthView.prototype.GetProperty=function(propName){ return this[propName]; };
    MonthView.prototype.SetProperty=function(propName,propValue) { this[propName]=propValue; };
    
    MonthView.prototype.CalcDates = function(date)
    {
        var daysInMonth = date.c1_GetDaysInMonth();
        
        this._startDateInMonth = new Date(date.getFullYear(), date.getMonth(), 1);
        this._endDateInMonth = this._startDateInMonth.c1_AddDays(daysInMonth - 1);
        
        this._startDate = this._startDateInMonth.c1_GetWeekStartDate(this._owner.FirstDayOfWeek);
        this._endDate = this._startDate.c1_AddDays(this._owner.DayRows * this._owner.DayColumns - 1);
    }
    
    MonthView.prototype.IsGroupBeginMonth = function()
    {
        var date = this._owner.GetDisplayDate();
        return (this._startDateInMonth.getFullYear() == date.getFullYear() && this._startDateInMonth.getMonth() == date.getMonth());
    }
    
    MonthView.prototype.IsGroupEndMonth = function()
    {
        var date = this._owner.GetDisplayDate();
        date = new Date(date.getFullYear(), date.getMonth(), 1);
        date = date.c1_AddMonths(this._owner.MonthCols * this._owner.MonthRows - 1);
        return (this._startDateInMonth.getFullYear() == date.getFullYear() && this._startDateInMonth.getMonth() == date.getMonth());
    }
    
    MonthView.prototype.GetMonthDate = function()
    {
        if (!this._startDateInMonth)
            tihs.CalcDates(this.DisplayDate);
            
        return this._startDateInMonth;
    }
    
    MonthView.prototype.SetMonthDate = function(date)
    {
        this.CalcDates(date);
    }
    
    MonthView.prototype.GetTitle = function()
    {
        return this._owner.GetTitleText(false, this._startDateInMonth);
    }
    
    MonthView.prototype.GetWeekDayText = function(day, format)
    {
        if (!format && format == null)
            format = c1_weekdayformat_full;
    
        switch(format)
        {
            case c1_weekdayformat_full:
                return c1_daynames[day];
                break;

            case c1_weekdayformat_firstletter:
                return c1_daynames[day].substring(0, 1);
                break;
                
            case c1_weekdayformat_firsttwoletters:
                return c1_daynames[day].substring(0, 2);
                break;
                
            case c1_weekdayformat_abbreviated:
                return c1_abbdaynames[day];
                break;
        }
        
        return "";
    }
    
    MonthView.prototype.GetRowColCount = function()
    {
        var rows = this._owner.DayRows;
        var cols = this._owner.DayColumns;

        if (this._owner.ShowWeekDays) rows++;
        if (this._owner.ShowWeekNumbers) cols++;
    
        return [rows, cols];
    }
    
    MonthView.prototype.GetHtml = function()
    {
        // number of rows and columns
        var rows = this._owner.DayRows;
        var cols = this._owner.DayColumns;

        if (this._owner.ShowWeekDays) rows++;
        if (this._owner.ShowWeekNumbers) cols++;
        if (!this._owner.IsSingleMonth()) rows++;
        
        rows++;
        
        var width = Math.floor(100 / cols) + "%";
        var height = Math.floor(100 / rows) + "%";
        
        var htmlMonth = new HtmlTextWriter();
        htmlMonth.WriteBeginTag("table");
        htmlMonth.WriteAttribute("id", this._id);
        htmlMonth.WriteAttribute("width", "100%");
        htmlMonth.WriteAttribute("height", "100%");
        htmlMonth.WriteAttribute("cellspacing", this._owner.CellSpacing);
        htmlMonth.WriteAttribute("cellpadding", this._owner.CellPadding);
        htmlMonth.WriteAttribute("summary", this.GetTitle());
    	
	    if(this._owner.ShowGridLines)
	    {
	        var gl;
	        switch(this._owner.ShowGridLines)
	        {
	            case 1:
	            gl = "rows";
	            break;
	            
	            case 2:
	            gl = "cols"
	            break;
	            
	            case 3:
	            gl = "all";
	            break;
	        }
	        
	        htmlMonth.WriteAttribute("rules", gl);
	    }
	    else
	    {
		    htmlMonth.WriteAttribute("border", 0);
	    };
	    
	    var style = this._owner.MonthViewStyle.Style + ";cursor:hand;"
	    if (c1_browser_ie)
	        style += "table-layout:fixed;";
	    
	    htmlMonth.WriteAttribute("style", style);
	    htmlMonth.WriteAttribute("class", this._owner.MonthViewStyle.CssClass);
	    htmlMonth.WriteTagRightChar();
    
	    if (!this._owner.IsSingleMonth())
	    {
	        //htmlMonth.WriteFullBeginTag("tr");
	        htmlMonth.WriteBeginTag("tr");
	        htmlMonth.WriteAttribute("height", height);
	        htmlMonth.WriteTagRightChar();
	        
	        htmlMonth.WriteBeginTag("td");
	        
	        if (!this._owner.ShowCalendarTitle && this.IsGroupBeginMonth())
	        {
   	            htmlMonth.WriteAttribute("id", this._id + "_monthtitle");
	            htmlMonth.WriteAttribute("colspan", cols);
	            htmlMonth.WriteAttribute("valign", "top");
	            htmlMonth.WriteAttribute("cell-spacing", "0px");

	            var css = this._owner.MonthTitleStyle.CssClass;
	            if (!css)
	                css = this._owner.TitleStyle.CssClass;
    	        
                style = this._owner.TitleStyle.Style + this._owner.MonthTitleStyle.Style;
                style = style + ";white-space:nowrap; cursor:pointer;text-align:" + this._owner.TitleAlign + ";";
                
                htmlMonth.WriteAttribute("style", style);
	            htmlMonth.WriteAttribute("class", css);
	            htmlMonth.WriteTagRightChar();

	            htmlMonth.Write(this._owner.GetTitleHtml(false, this._startDateInMonth));
	        }else
	        {
	            htmlMonth.WriteAttribute("id", this._id + "_monthtitle");
	            htmlMonth.WriteAttribute("colspan", cols);
	            htmlMonth.WriteAttribute("valign", "top");

	            var css = this._owner.MonthTitleStyle.CssClass;
	            if (!css)
	                css = this._owner.TitleStyle.CssClass;
    	        
                style = this._owner.TitleStyle.Style + this._owner.MonthTitleStyle.Style;
                style = style + ";white-space:nowrap; cursor:pointer;text-align:" + this._owner.TitleAlign + ";";
                
                htmlMonth.WriteAttribute("style", style);
	            htmlMonth.WriteAttribute("class", css);
	            htmlMonth.WriteTagRightChar();
    	        
	            htmlMonth.Write(this.GetTitle());
	        }
	        
	        htmlMonth.WriteEndTag("td");
	        htmlMonth.WriteEndTag("tr");
	    }

        if (this._owner.ShowWeekDays)
        {
            //htmlMonth.WriteFullBeginTag("tr");
            htmlMonth.WriteBeginTag("tr");
	        htmlMonth.WriteAttribute("height", height);
	        htmlMonth.WriteTagRightChar();
            if (this._owner.ShowWeekNumbers)
            {
                if (this._owner.SelectionMode != 0 && (this._owner.SelectionMode & c1_selectionmode_month) != 0)
                {
                    htmlMonth.WriteBeginTag("td");
                    htmlMonth.WriteAttribute("id", this._id + "_ms");
                    htmlMonth.WriteAttribute("style", this._owner.WeekDayStyle.Style + ";cursor:pointer;");
                    htmlMonth.WriteAttribute("class", this._owner.WeekDayStyle.CssClass);
                    htmlMonth.WriteAttribute("width", width);

                    if (!this._owner.PreviewMode && this._owner.IsEnabled)
                    {
                        htmlMonth.WriteAttribute("onclick", this._owner.InstName + ".MonthSelectorOnClick(this, event)");
                        htmlMonth.WriteAttribute("onmouseover", this._owner.InstName + ".MonthSelectorOnMouseOver(this, event)");
                        htmlMonth.WriteAttribute("onmouseout", this._owner.InstName + ".MonthSelectorOnMouseOut(this, event)");
                        htmlMonth.WriteAttribute("onmousedown", this._owner.InstName + ".MonthSelectorOnMouseDown(this, event)");
                        htmlMonth.WriteAttribute("onmouseup", this._owner.InstName + ".MonthSelectorOnMouseUp(this, event)");
                    }
                    htmlMonth.WriteTagRightChar();

                    if (!C1_IsStringNullOrEmpty(this._owner.MonthSelectorImage))
                    {
                        htmlMonth.WriteBeginTag("img");
                        htmlMonth.WriteAttribute("alt", this._owner.MonthSelectorToolTip);
                        htmlMonth.WriteAttribute("style", "border-width:0px;border:0px;");
                        htmlMonth.WriteAttribute("src", this._owner.MonthSelectorImage);
                        htmlMonth.WriteSelfClosingTagEnd();
                    }else
                    {
                        htmlMonth.Write(this._owner.MonthSelectorText);
                    }
                    
                    htmlMonth.WriteEndTag("td");
                }else
                {
                    htmlMonth.WriteBeginTag("td");
                    htmlMonth.WriteAttribute("style", this._owner.WeekDayStyle.Style + ";cursor:pointer;");
                    htmlMonth.WriteAttribute("class", this._owner.WeekDayStyle.CssClass);
                    htmlMonth.WriteAttribute("width", width);
                    htmlMonth.WriteTagRightChar();
                    htmlMonth.WriteEndTag("td");
                }
            }
            
            var dayOfWeek = this._startDate.getDay();
            var weekStartDate = this._startDate;
            for (var i = 0; i < this._owner.DayColumns; i++)
            {
                var colIndex = i + (this._owner.ShowWeekNumbers ? 1 : 0);
               
                htmlMonth.WriteBeginTag("td");
                htmlMonth.WriteAttribute("id", this._id + "_cs_" + colIndex);
                htmlMonth.WriteAttribute("style", this._owner.WeekDayStyle.Style + ";cursor:pointer;");
                htmlMonth.WriteAttribute("class", this._owner.WeekDayStyle.CssClass);
                htmlMonth.WriteAttribute("title", this.GetWeekDayText(dayOfWeek, c1_weekdayformat_full));
                htmlMonth.WriteAttribute("abbr", "abbrText");
                htmlMonth.WriteAttribute("scope", "col");
                htmlMonth.WriteAttribute("width", width);
                    
                if (!this._owner.PreviewMode && this._owner.IsEnabled)
                {
                    if (this._owner.SelectionMode != 0 && (this._owner.SelectionMode & c1_selectionmode_weekday) != 0)
                    {
                        htmlMonth.WriteAttribute("onclick", this._owner.InstName + ".ColSelectorOnClick(this, event)");
                        htmlMonth.WriteAttribute("onmouseover", this._owner.InstName + ".ColSelectorOnMouseOver(this, event)");
                        htmlMonth.WriteAttribute("onmouseout", this._owner.InstName + ".ColSelectorOnMouseOut(this, event)");
                        htmlMonth.WriteAttribute("onmousedown", this._owner.InstName + ".ColSelectorOnMouseDown(this, event)");
                        htmlMonth.WriteAttribute("onmouseup", this._owner.InstName + ".ColSelectorOnMouseUp(this, event)");
                    }
                }
                    
                htmlMonth.WriteTagRightChar();

                htmlMonth.Write(this.GetWeekDayText(dayOfWeek, this._owner.WeekDayFormat))
                htmlMonth.WriteEndTag("td");
                
                dayOfWeek = ((dayOfWeek + 1) % 7);
                    weekStartDate = weekStartDate.c1_AddDays(1);
            }
            
            htmlMonth.WriteEndTag("tr");
        }
        
        var date = this._startDate;
        var wnDate = this._startDateInMonth;
        for (var i = 0; i < this._owner.DayRows; i++)
        {
            htmlMonth.WriteBeginTag("tr");
	        htmlMonth.WriteAttribute("height", height);
	        htmlMonth.WriteTagRightChar();
            
            if (this._owner.ShowWeekNumbers)
            {
                var rowIndex = i + (this._owner.ShowWeekDays ? 1 : 0);
                if (!this._owner.IsSingleMonth()) rowIndex++;
            
                htmlMonth.WriteBeginTag("td");
                htmlMonth.WriteAttribute("id", this._id + "_rs_" + rowIndex);
                htmlMonth.WriteAttribute("style", this._owner.WeekNumberStyle.Style + ";cursor:pointer;");
                htmlMonth.WriteAttribute("class", this._owner.WeekNumberStyle.CssClass);
                htmlMonth.WriteAttribute("width", width);

                if (!this._owner.PreviewMode && this._owner.IsEnabled)
                {
                    if (this._owner.SelectionMode != 0 && (this._owner.SelectionMode & c1_selectionmode_weeknumber) != 0)
                    {
                        htmlMonth.WriteAttribute("onclick", this._owner.InstName + ".RowSelectorOnClick(this, event)");
                        htmlMonth.WriteAttribute("onmouseover", this._owner.InstName + ".RowSelectorOnMouseOver(this, event)");
                        htmlMonth.WriteAttribute("onmouseout", this._owner.InstName + ".RowSelectorOnMouseOut(this, event)");
                        htmlMonth.WriteAttribute("onmousedown", this._owner.InstName + ".RowSelectorOnMouseDown(this, event)");
                        htmlMonth.WriteAttribute("onmouseup", this._owner.InstName + ".RowSelectorOnMouseUp(this, event)");
                    }
                }
                htmlMonth.WriteTagRightChar();
                
                var weekNumber = wnDate.c1_GetWeekOfYear(this._owner.FirstDayOfWeek);
                htmlMonth.Write(weekNumber);
                htmlMonth.WriteEndTag("td");
                
                wnDate = wnDate.c1_AddDays(this._owner.DayColumns);
            }
            
            for (var j = 0; j < this._owner.DayColumns; j++)
            {
                this.FillDayCell(htmlMonth, date);
                date = date.c1_AddDays(1);
            }

            htmlMonth.WriteEndTag("tr");
        }
        
        htmlMonth.WriteEndTag("table");

        return htmlMonth.ToString();
    }
    
    MonthView.prototype.GetDayType = function(date)
    {
        var dayType = c1_daytype_default;
        var dow = date.getDay();
        var weekEnd = (dow == c1_dayofweek_saturday || dow == c1_dayofweek_sunday);
        var outOfRange = (date < this._owner.MinDate || date > this._owner.MaxDate);
        var otherMonth = (date < this._startDateInMonth || date > this._endDateInMonth);
        var isDisabled = false;
        if (this._owner.DisableDates)
            isDisabled = this._owner.DisableDates.Contains(date);
        var isSelected = false;
        if (this._owner.SelectedDates)
            isSelected = this._owner.SelectedDates.Contains(date);
        var today = new Date();
        var isToday = (date.getFullYear() == today.getFullYear() && date.getMonth() == today.getMonth() && date.getDate() == today.getDate());
        var isCustom = false;
        if (this._owner.CustomDays)
            isCustom = this._owner.CustomDays.Contains(date);
   
        if (weekEnd)
            dayType |= c1_daytype_weekend;
            
        if (isToday)
            dayType |= c1_daytype_today;

        if (isDisabled)
            dayType |= c1_daytype_disabled;

        if (otherMonth)
            dayType |= c1_daytype_othermonth;
            
        if (outOfRange)
            dayType |= c1_daytype_outofrange;
           
        if (isSelected)
            dayType |= c1_daytype_selected;

        if (isCustom)
            dayType |= c1_daytype_custom;
       
       var showOtherMonthDays = true;
       if (this._owner.MonthRows * this._owner.MonthCols > 1)
       {
            if (dayType & c1_daytype_othermonth)
            {
                 if (date < this._startDateInMonth)
                 {
                     showOtherMonthDays = this.IsGroupBeginMonth();
                 }
                 else
                 {
                     if (date > this._endDateInMonth)
                     {
                         showOtherMonthDays = this.IsGroupEndMonth();
                     }
                 }
            }
        }
        
        if (otherMonth && (!this._owner.ShowOtherMonthDays || !showOtherMonthDays))
            dayType |= c1_daytype_gap;
            
        return dayType;
    }
    
    MonthView.prototype.RefreshDate = function(date)
    {
        if (date < this._startDate || date > this._endDate) return;
        
        var offset = Math.round(Math.abs(date.valueOf() - this._startDate.valueOf())/(24*60*60*1000));
        var row = Math.floor(offset / this._owner.DayColumns);
        var col = Math.floor(offset % this._owner.DayColumns);
        
        if (this._owner.ShowWeekNumbers) col++;
        if (this._owner.ShowWeekDays) row++;
        if (!this._owner.IsSingleMonth()) row++;
        
        var tbl = document.getElementById(this._id);
        if (tbl)
        {
            if (row < tbl.rows.length)
            {
                var r = tbl.rows[row];
                if (col < r.cells.length)
                {
                    var dayCell = r.cells[col];
                    var dayType = this.GetDayType(date);
                    dayCell.attributes["daytype"].value = dayType;
                    this._owner.RefreshDayCell(dayCell);
                }
            }
        }
    }
    
    MonthView.prototype.FillDayCell = function(htmlMonth, date)
    {
        var text = date.getDate().toString();
        
        if (this._owner.MonthDayFormat == c1_monthdayformat_zeropadding)
        {
            if (text.length == 1)
                text = "0" + text;
        }
        
        var tooltip = Calendar_FormatDateString(this._owner.ToolTipDateFormat, date);
        var dayType = this.GetDayType(date);
        if (dayType & c1_daytype_custom)
        {
            var calendarDay = this._owner.CustomDays.Get(date);
            if (calendarDay != null)
            {
                if (!C1_IsStringNullOrEmpty(calendarDay.Template))
                    text = calendarDay.Template;
             }
        }
        
        text = '<span style="cursor:pointer;">' + text + '</span>';
        if (dayType & c1_daytype_gap) text = "&#160;";
        
        var cellStyle = this._owner.GetCellStyle(dayType, date);
        
        htmlMonth.WriteBeginTag("td");
        htmlMonth.WriteAttribute("daytype", dayType);
        htmlMonth.WriteAttribute("title", tooltip);
        htmlMonth.WriteAttribute("date", date.toString());
        htmlMonth.WriteAttribute("style", cellStyle.Style + "; cursor:pointer;");
        htmlMonth.WriteAttribute("class", cellStyle.CssClass);

        if (!this._owner.PreviewMode && this._owner.IsEnabled)
        {
            if (this._owner.SelectionMode != 0 && (this._owner.SelectionMode & (c1_selectionmode_day | c1_selectionmode_days)) != 0)
            {
                if (this._owner.IsSelectable(dayType))
                {
                    htmlMonth.WriteAttribute("onclick", this._owner.InstName + ".CalendarDayOnClick(this, event)");
                    htmlMonth.WriteAttribute("onmouseover", this._owner.InstName + ".CalendarDayOnMouseOver(this, event)");
                    htmlMonth.WriteAttribute("onmouseout", this._owner.InstName + ".CalendarDayOnMouseOut(this, event)");
                    htmlMonth.WriteAttribute("onmousedown", this._owner.InstName + ".CalendarDayOnMouseDown(this, event)");
                    htmlMonth.WriteAttribute("onmouseup", this._owner.InstName + ".CalendarDayOnMouseUp(this, event)");
                }
            }
        }
        
        htmlMonth.WriteTagRightChar();

        htmlMonth.Write(text);
        htmlMonth.WriteEndTag("td");
    }   

    //===C1WebCalendar========================
    function C1WebCalendar(id, uniqueID, instname)
    {
        this.ID = id;
        this.UniqueID = uniqueID;
        this.InstName = instname;
        this.DisplayDate = new Date();
        this.LastSelDate = null;
        this.SwapDuration = 300;
        this.NavigationSlideType = c1_slidetype_constant;
        
        this.DisplayDate = this.GetDisplayDate();
    }
    
    C1WebCalendar.prototype.GetProperty=function(propName){ return this[propName]; };
    C1WebCalendar.prototype.SetProperty=function(propName,propValue) { this[propName]=propValue; };

    C1WebCalendar.prototype.Initialize=function()
    {
        this.Initializing = true;
        
        this.Container = document.getElementById(this.ID+'_Container');
        if (c1_browser_ie7)
            this.Container.style.cssText = "overflow:visible;min-width:1px;min-height:1px;";
        else
            this.Container.style.cssText = "overflow:visible;";
            
        this.Container.innerHTML = this.Render();
        
        this.CalendarTable = document.getElementById(this.ID);
        
        this.PopupSetting.OnBeforeClose = this.HandleBeforeClose;
        this.PopupSetting.OnAfterClose = this.HandleAfterClose;
        this.PopupSetting.OnBeforePopup = this.HandleBeforePopup;
        this.PopupSetting.OnAfterPopup = this.HandleAfterPopup;
        
        var width = parseInt(this.CalendarTable.style.pixelWidth);
        if (isNaN(width) || width==0)
            width = parseInt(this.CalendarTable.offsetWidth);
        width = (isNaN(width) || width== 0)?120:width;
        if (width > 0)
            this.PopupSetting.Width = width;
            
        var height = parseInt(this.CalendarTable.style.pixelHeight);
        if (isNaN(height) || height==0)
            height = parseInt(this.CalendarTable.offsetHeight);
        height = (isNaN(height) || height == 0)?120:height;
        if (height > 0)
            this.PopupSetting.Height = height;

        this.SaveSelectedDates();
        this.SaveDisplayDate();
        
        if (this.PopupMode)
            this.Container.style.display = "none";
        
        this.Initializing = false;
    }
    
    C1WebCalendar.prototype.HandleBeforePopup=function(obj)
    {
        return this.Owner.FireBeforePopupEvent();
    }
    
    C1WebCalendar.prototype.HandleAfterPopup=function(obj)
    {
        return this.Owner.FireAfterPopupEvent();
    }
    
    C1WebCalendar.prototype.HandleBeforeClose=function(obj)
    {
        if (this.Owner.MonthPicker && this.Owner.MonthPicker.IsPopupShowing()) return false;        
        
        return this.Owner.FireBeforeCloseEvent();
    }
    
    C1WebCalendar.prototype.HandleAfterClose=function(obj)
    {
        return this.Owner.FireAfterCloseEvent();
    }
    
    C1WebCalendar.prototype.Refresh=function()
    {
        this.CalendarTable = document.getElementById(this.ID);
        if (this.CalendarTable)
        {
            this.Container = this.CalendarTable.parentNode;
            
            if (this.Container)
            {
                this.Container.innerHTML = this.Render();
            }
        }
    }
    
    C1WebCalendar.prototype.IsSingleMonth = function()
    {
        return this.MonthCols * this.MonthRows == 1;
    }
    
    C1WebCalendar.prototype.GetDisplayDate = function()
    {
        var date = this.DisplayDate;
        if (!date)
            date = new Date();
            
        if (date.getFullYear() == 1900 && date.getMonth() == 1 && date.getDay() == 1)
            date = new Date();
            
        return date;
    }
    
    C1WebCalendar.prototype.GetNavigatorHtml = function(imgName, text, tooltip, id)
    {
        var htmlLink = new HtmlTextWriter();
        
        if (C1_IsStringNullOrEmpty(tooltip))
            tooltip = text;
        
        htmlLink.WriteBeginTag("a");
        htmlLink.WriteAttribute("id", this.ID + id);
        htmlLink.WriteAttribute("title", tooltip);
        htmlLink.WriteAttribute("href", "javascript:void(0)");
        
        var btnName = id;
        btnName  = btnName.substr(1);
        
        var btnId = this.GetBtnID(btnName);
        var style = this.GetNavBtnStyle(btnId); 
        if (!C1_IsStringNullOrEmpty(style.Style))
            htmlLink.WriteAttribute("style", style.Style);

        if (!C1_IsStringNullOrEmpty(style.CssClass))
            htmlLink.WriteAttribute("class", style.CssClass);
        
        if (!this.PreviewMode && this.IsEnabled)
        {
            htmlLink.WriteAttribute("onclick", this.InstName + ".NavOnClick(this, event)");
            htmlLink.WriteAttribute("onmouseover", this.InstName + ".NavOnMouseOver(this, event)");
            htmlLink.WriteAttribute("onmouseout", this.InstName + ".NavOnMouseOut(this, event)");
        }
        htmlLink.WriteTagRightChar();
        
        if (!C1_IsStringNullOrEmpty(imgName))
        {
            htmlLink.WriteBeginTag("img")
            htmlLink.WriteAttribute("alt", tooltip);
            htmlLink.WriteAttribute("src", imgName);
            htmlLink.WriteAttribute("style", "border:0px;");
            htmlLink.WriteSelfClosingTagEnd();
        }else
        {
            htmlLink.Write(text);
        }
        
        htmlLink.WriteEndTag("a");
        
        return htmlLink.ToString();
    }
    
    C1WebCalendar.prototype.GetTitleText = function(group, monthDate)
    {
        var count = this.MonthRows * this.MonthCols;
        var startMonth = this.GetDisplayDate();
        var endMonth = startMonth.c1_AddMonths(count - 1);
        
        if (!this.CalendarTitle) this.CalendarTitle = "MMMM yyyy";
        if (!this.MonthViewTitle) this.MonthViewTitle = "MMMM yyyy";
        
        return String.c1format(group ? this.CalendarTitle : this.MonthViewTitle, monthDate, startMonth, endMonth, count);
    }
    
    C1WebCalendar.prototype.GetTitleHtml = function(group, monthDate)
    {
        var htmlTitle = new HtmlTextWriter();
        
        htmlTitle.WriteBeginTag("table")
        htmlTitle.WriteAttribute("id", this.ID + "_titlebar");
        
        if (group)
        {
            htmlTitle.WriteAttribute("cellspacing", this.NavigationCellSpacing);
            htmlTitle.WriteAttribute("cellpadding", this.NavigationCellPadding);
        }else
        {
            htmlTitle.WriteAttribute("cellspacing", 0);
            htmlTitle.WriteAttribute("cellpadding", 0);
        }
        htmlTitle.WriteAttribute("border", 0);
        
        if (group)
        {
            htmlTitle.WriteAttribute("style", this.TitleStyle.Style);
            htmlTitle.WriteAttribute("class", this.TitleStyle.CssClass);
        }else
        {
            var css = this.MonthTitleStyle.CssClass;
	        if (!css)
	            css = this.TitleStyle.CssClass;
	        
            var style = this.TitleStyle.Style + this.MonthTitleStyle.Style;
            var paddingStyle = "padding-left:" + this.NavigationCellPadding +"px;padding-right:" + this.NavigationCellPadding + "px;padding-top:0px;padding-bottom:0px;";
            style = style + ";white-space:nowrap;cursor:pointer;text-align:" + this.TitleAlign + ";" + paddingStyle;
            
            htmlTitle.WriteAttribute("style", style);
            htmlTitle.WriteAttribute("class", css);

        }
        htmlTitle.WriteTagRightChar();
        
        htmlTitle.WriteFullBeginTag("tr");

        if (group)        
            htmlTitle.WriteFullBeginTag("td");
        else
        {
            htmlTitle.WriteBeginTag("td");
            htmlTitle.WriteAttribute("style", paddingStyle);
            htmlTitle.WriteTagRightChar();
        }
        if (!this.PreviewMode && this.ShowMonthNavigator)
        {
            htmlTitle.Write(this.GetNavigatorHtml(this.QuickPrevImage, this.QuickPrevText, this.QuickPrevToolTip, "_QPREV"));
        }
        htmlTitle.WriteEndTag("td");
        
        if (group)        
            htmlTitle.WriteFullBeginTag("td");
        else
        {
            htmlTitle.WriteBeginTag("td");
            htmlTitle.WriteAttribute("style", paddingStyle);
            htmlTitle.WriteTagRightChar();
        }
        if (!this.PreviewMode && this.ShowMonthNavigator)
        {
            htmlTitle.Write(this.GetNavigatorHtml(this.PrevImage, this.PrevText, this.PrevToolTip, "_PREV"));
        }
        htmlTitle.WriteEndTag("td");
        
        
        htmlTitle.WriteBeginTag("td");
        htmlTitle.WriteAttribute("id", this.ID + "_title");
        
        var titleStyle = "width:100%;white-space:nowrap;cursor:pointer;text-align:" + this.TitleAlign + ";";
        htmlTitle.WriteAttribute("style", titleStyle);
        if (this.AllowQuickSelector && this.IsEnabled)
        {
            htmlTitle.WriteAttribute("onclick", this.InstName + ".TitleOnClick(this, event)");
        }
        htmlTitle.WriteTagRightChar();
        
        if (group)
        {
            htmlTitle.Write(this.GetTitleText(true, this.GetDisplayDate()));
        }else
        {
            htmlTitle.Write(this.GetTitleText(false, monthDate));
        }
        
        htmlTitle.WriteEndTag("td");
        
        if (group)        
            htmlTitle.WriteFullBeginTag("td");
        else
        {
            htmlTitle.WriteBeginTag("td");
            htmlTitle.WriteAttribute("style", paddingStyle);
            htmlTitle.WriteTagRightChar();
        }
        if (!this.PreviewMode && this.ShowMonthNavigator)
        {
            htmlTitle.Write(this.GetNavigatorHtml(this.NextImage, this.NextText, this.NextToolTip, "_NEXT"));
        }
        htmlTitle.WriteEndTag("td");
        
        if (group)        
            htmlTitle.WriteFullBeginTag("td");
        else
        {
            htmlTitle.WriteBeginTag("td");
            htmlTitle.WriteAttribute("style", paddingStyle);
            htmlTitle.WriteTagRightChar();
        }
        if (!this.PreviewMode && this.ShowMonthNavigator)
        {
            htmlTitle.Write(this.GetNavigatorHtml(this.QuickNextImage, this.QuickNextText, this.QuickNextToolTip, "_QNEXT"));
        }
        htmlTitle.WriteEndTag("td");
        
        htmlTitle.WriteEndTag("tr");
        htmlTitle.WriteEndTag("table")
        
        return htmlTitle.ToString();
    }
    
    C1WebCalendar.prototype.CreateMonthViews = function()
    {
        this.MonthViews = {};
    
        var date = this.GetDisplayDate();
        for (var row = 0; row < this.MonthRows; row++)
        {
            for (var col = 0; col < this.MonthCols; col++)   
            {
                var monthID = Calendar_GetMonthString(date);
                this.MonthViews[monthID] = new MonthView(this, this.ID + "_" + Calendar_GetMonthString(date), date);
                date = date.c1_AddMonths(1);
            }
        }
        
        date = this.GetDisplayDate();
        var monthID = Calendar_GetMonthString(date);
        var mv = this.MonthViews[monthID];
        if (mv)
            this.VisibleDateStart = mv._startDate;
            
        var count = this.MonthRows * this.MonthCols;
        if (count > 1)
        {
            date = date.c1_AddMonths(count - 1);
            monthID = Calendar_GetMonthString(date);
            mv = this.MonthViews[monthID];
        }
        
        if (mv)
            this.VisibleDateEnd = mv._endDate;
    }
    
    C1WebCalendar.prototype.GetMonthView = function(date)
    {
        var monthID = Calendar_GetMonthString(date);
        return  this.MonthViews[monthID];
    }
    
    C1WebCalendar.prototype.RefreshDate = function(date)
    {
        if (this.MonthViews == null) return;
        
        if (date < this.VisibleDateStart || date > this.VisibleDateEnd) return;
        
        for(var i in this.MonthViews)
        {
            var mv = this.MonthViews[i];
            if (mv) mv.RefreshDate(date);
        }
    }
    
    C1WebCalendar.prototype.GetMonthsHtml = function()
    {
        var htmlMonths = new HtmlTextWriter();

        htmlMonths.WriteBeginTag("table");
        htmlMonths.WriteAttribute("id", this.ID + "_Months");
        htmlMonths.WriteAttribute("cellspacing", this.MonthViewSpacing);
        htmlMonths.WriteAttribute("cellpadding", 0);
        htmlMonths.WriteAttribute("width", "100%");
        htmlMonths.WriteAttribute("height", "100%");
        htmlMonths.WriteAttribute("border", 0);
        htmlMonths.WriteTagRightChar();

        var width = 100 / this.MonthCols + "%";
        var height = 100 / this.MonthRows + "%";

        var date = this.GetDisplayDate();
        for (var r = 0; r < this.MonthRows; r++)
        {
            htmlMonths.WriteBeginTag("tr");
            if (!this.IsSingleMonth())
                htmlMonths.WriteAttribute("style", "vertical-align:top;");
            htmlMonths.WriteTagRightChar();
            
            for (var c = 0; c < this.MonthCols; c++)
            {
                htmlMonths.WriteBeginTag("td");
                htmlMonths.WriteAttribute("style", "height:" + height + "; width:" + width);
                htmlMonths.WriteTagRightChar();
                
                var mv = this.GetMonthView(date);
                htmlMonths.Write(mv.GetHtml());
                
                htmlMonths.WriteEndTag("td");
                
                date = date.c1_AddMonths(1);
            }
               
            htmlMonths.WriteEndTag("tr");
        }
        
        htmlMonths.WriteEndTag("table");
        
        return htmlMonths.ToString();
    }
    
  
    C1WebCalendar.prototype.GetHtml = function()
    {
        this.CreateMonthViews();
        
        var htmlCalendar = new HtmlTextWriter();
        
        htmlCalendar.WriteBeginTag("table")
        htmlCalendar.WriteAttribute("id", this.ID);
        htmlCalendar.WriteAttribute("cellspacing", 0);
        htmlCalendar.WriteAttribute("cellpadding", 0);
        htmlCalendar.WriteAttribute("width", "100%");
        htmlCalendar.WriteAttribute("height", "100%");
        htmlCalendar.WriteAttribute("border", 0);
        
        if (this.Container.accessKey)
            htmlCalendar.WriteAttribute("accesskey", this.Container.accessKey);
            
        if (!this.IsEnabled)
            htmlCalendar.WriteAttribute("disabled", "disabled");
            
        htmlCalendar.WriteAttribute("style", this.ControlStyle);
        htmlCalendar.WriteAttribute("class", this.CssClass);
            
        htmlCalendar.WriteTagRightChar();
        
        if (this.ShowCalendarTitle)
        {
            htmlCalendar.WriteFullBeginTag("tr");
            
            htmlCalendar.WriteBeginTag("td")
            htmlCalendar.WriteAttribute("colspan", 3);
            htmlCalendar.WriteAttribute("style", "vertical-align:top;white-space:nowrap");
            htmlCalendar.WriteTagRightChar();
            htmlCalendar.Write(this.GetTitleHtml(true, null));
            htmlCalendar.WriteEndTag("td")
            
            htmlCalendar.WriteEndTag("tr");
        }
        
        if (!this.PreviewMode && !C1_IsStringNullOrEmpty(this.HeaderTemplate))
        {
            htmlCalendar.WriteFullBeginTag("tr");
            
            htmlCalendar.WriteBeginTag("td")
            htmlCalendar.WriteAttribute("colspan", 3);
            htmlCalendar.WriteAttribute("style", "vertical-align:top;white-space:nowrap");
            htmlCalendar.WriteTagRightChar();
            htmlCalendar.Write(this.HeaderTemplate);
            htmlCalendar.WriteEndTag("td")

            htmlCalendar.WriteEndTag("tr");
        }

        
        htmlCalendar.WriteFullBeginTag("tr");
        
        if (!this.PreviewMode && this.AllowPreview && this.IsEnabled)
        {
            htmlCalendar.WriteBeginTag("td");
            htmlCalendar.WriteAttribute("id", this.ID + "_PEVPREVIEW");
            htmlCalendar.WriteAttribute("width", "16px");
            htmlCalendar.WriteAttribute("align", "center");
            htmlCalendar.WriteAttribute("style", this.PrevPreviewStyle.Style);
            htmlCalendar.WriteAttribute("class", this.PrevPreviewStyle.CssClass);
            htmlCalendar.WriteAttribute("onclick", this.InstName + ".PreviewOnClick(this, event);");
            htmlCalendar.WriteAttribute("onmouseover", this.InstName + ".PreviewOnMouseOver(this, event);");
            htmlCalendar.WriteAttribute("onmouseout", this.InstName + ".PreviewOnMouseOut(this, event);");
            htmlCalendar.WriteAttribute("onmousedown", this.InstName + ".PreviewOnMouseDown(this, event);");
            htmlCalendar.WriteAttribute("onmouseup", this.InstName + ".PreviewOnMouseUp(this, event);");
            htmlCalendar.WriteTagRightChar();
            
            if (!C1_IsStringNullOrEmpty(this.PrevPreviewImage))
            {
                htmlCalendar.WriteBeginTag("img");
                htmlCalendar.WriteAttribute("src", this.PrevPreviewImage);
                htmlCalendar.WriteAttribute("alt", this.PrevPreviewToolTip);
                htmlCalendar.WriteAttribute("style", "border:0px;");
                htmlCalendar.WriteSelfClosingTagEnd();
            }
            
            htmlCalendar.WriteEndTag("td");
        }
        htmlCalendar.WriteBeginTag("td");
        htmlCalendar.WriteAttribute("style", "min-height:1px;width:100%;height:100%;");
        htmlCalendar.WriteTagRightChar();
        htmlCalendar.WriteBeginTag("div");
        htmlCalendar.WriteAttribute("id", this.ID + "_SwapContainer");
        
        if (c1_browser_ie7)
            htmlCalendar.WriteAttribute("style", "width:100%;height:100%;min-height:1px;margin:0px;padding:0px;border:none;");
        else
            htmlCalendar.WriteAttribute("style", "width:100%;height:100%;margin:0px;padding:0px;border:none;");
            
        htmlCalendar.WriteTagRightChar();
        htmlCalendar.WriteBeginTag("table");
        htmlCalendar.WriteAttribute("id", this.ID + "_SwapTable");
        htmlCalendar.WriteAttribute("cellspacing", 0);
        htmlCalendar.WriteAttribute("cellpadding", 0);
        htmlCalendar.WriteAttribute("border", 0);
        htmlCalendar.WriteAttribute("style", "width:100%;height:100%;");
        htmlCalendar.WriteTagRightChar();
        htmlCalendar.WriteBeginTag("tr");
        htmlCalendar.WriteAttribute("id", this.ID + "_SwapTr");
        htmlCalendar.WriteTagRightChar();
        htmlCalendar.WriteBeginTag("td");
        htmlCalendar.WriteAttribute("id", this.ID + "_SwapTd");
        htmlCalendar.WriteAttribute("width", "100%");
        htmlCalendar.WriteAttribute("height", "100%");
        htmlCalendar.WriteTagRightChar();
        htmlCalendar.Write(this.GetMonthsHtml());
        htmlCalendar.WriteEndTag("td");
        htmlCalendar.WriteEndTag("tr");
        htmlCalendar.WriteEndTag("table");
        htmlCalendar.WriteEndTag("div");
        htmlCalendar.WriteEndTag("td");
        
       if (!this.PreviewMode && this.AllowPreview && this.IsEnabled)
        {
            htmlCalendar.WriteBeginTag("td");
            htmlCalendar.WriteAttribute("id", this.ID + "_NEXTPREVIEW");
            htmlCalendar.WriteAttribute("width", "16px");
            htmlCalendar.WriteAttribute("align", "center");
            htmlCalendar.WriteAttribute("style", this.NextPreviewStyle.Style);
            htmlCalendar.WriteAttribute("class", this.NextPreviewStyle.CssClass);
            htmlCalendar.WriteAttribute("onclick", this.InstName + ".PreviewOnClick(this, event);");
            htmlCalendar.WriteAttribute("onmouseover", this.InstName + ".PreviewOnMouseOver(this, event);");
            htmlCalendar.WriteAttribute("onmouseout", this.InstName + ".PreviewOnMouseOut(this, event);");
            htmlCalendar.WriteAttribute("onmousedown", this.InstName + ".PreviewOnMouseDown(this, event);");
            htmlCalendar.WriteAttribute("onmouseup", this.InstName + ".PreviewOnMouseUp(this, event);");
            htmlCalendar.WriteTagRightChar();
            
            if (!C1_IsStringNullOrEmpty(this.NextPreviewImage))
            {
                htmlCalendar.WriteBeginTag("img");
                htmlCalendar.WriteAttribute("src", this.NextPreviewImage);
                htmlCalendar.WriteAttribute("alt", this.NextPreviewToolTip);
                htmlCalendar.WriteAttribute("style", "border:0px;");
                htmlCalendar.WriteSelfClosingTagEnd();
            }
            
            htmlCalendar.WriteEndTag("td");
        }
        
        htmlCalendar.WriteEndTag("tr");
        
        if (!this.PreviewMode && !C1_IsStringNullOrEmpty(this.FooterTemplate))
        {
            htmlCalendar.WriteFullBeginTag("tr");
            
            htmlCalendar.WriteBeginTag("td")
            htmlCalendar.WriteAttribute("colspan", 3);
            htmlCalendar.WriteAttribute("style", "vertical-align:top;white-space:nowrap");
            htmlCalendar.WriteTagRightChar();
            htmlCalendar.Write(this.FooterTemplate);
            htmlCalendar.WriteEndTag("td")

            htmlCalendar.WriteEndTag("tr");
        }

        
        htmlCalendar.WriteEndTag("table")
        
        return htmlCalendar.ToString();
    }
    
    C1WebCalendar.prototype.GetCellStyle = function(dayType, date)
    {
        var cellStyle = this.DayStyle.Clone();
        
        if (!(dayType & c1_daytype_gap))
        {
            if (dayType & c1_daytype_weekend)
                cellStyle.MergeWith(this.WeekendDayStyle);
                
            if (dayType & c1_daytype_outofrange)
                cellStyle.MergeWith(this.OutOfRangeDayStyle);
            else
            {
                if (dayType & c1_daytype_othermonth)
                    cellStyle.MergeWith(this.OtherMonthDayStyle);
                    
                if (dayType & c1_daytype_disabled)
                    cellStyle.MergeWith(this.DisabledDayStyle);
                    
                if (dayType & c1_daytype_today)
                    cellStyle.MergeWith(this.TodayDayStyle);
                    
                if (dayType & c1_daytype_selected)
                    cellStyle.MergeWith(this.SelectedDayStyle);
                    
                if (dayType & c1_daytype_custom)
                {
                    var calendarDay = this.CustomDays.Get(date);
                    if (calendarDay != null)
                        cellStyle.MergeWith(calendarDay.Style);
                }
            }
        }
        
        return cellStyle;
    }
    
    C1WebCalendar.prototype.RefreshDayCell = function(dayCell)
    {
	    if(!dayCell.State)
		    dayCell.State = 'normal';
		    
		if (dayCell.attributes["daytype"] == null) return;
		if (dayCell.attributes["date"] == null) return;
                        
        var dayType = parseInt(dayCell.attributes["daytype"].value);
        var date = new Date(dayCell.attributes["date"].value);
        var cellStyle = this.GetCellStyle(dayType, date);
        
        var style = cellStyle.Style;
        var css = cellStyle.CssClass;
        
        if (dayCell.State == 'hover')
        {
            if (!C1_IsStringNullOrEmpty(cellStyle.HoverStyle))
                style = style + ";" + cellStyle.HoverStyle;
                
            if (!C1_IsStringNullOrEmpty(cellStyle.HoverCssClass))
                css = cellStyle.HoverCssClass;
        }
        
        dayCell.style.cssText = style;
        dayCell.className = css;
    }
    
    C1WebCalendar.prototype.IsSelectable = function(dayType)
    {
        if (dayType & c1_daytype_othermonth) return false;
        if (dayType & c1_daytype_outofrange) return false;
        if (dayType & c1_daytype_disabled) return false;
        return true;;
    }
       
    C1WebCalendar.prototype.InitMonthSelector = function(cornerCell)
    {
        if (cornerCell.DayCells) return;
        
        var tokens = cornerCell.id.split('_');
        if (tokens[tokens.length - 1] != 'ms') throw "not a monthview";
        
        var monthID = tokens.slice(0,tokens.length-1).join('_');
        
        var monthTable = window.C1_GetParentTableElement(cornerCell);
        if (!monthTable) throw "not a monthview";
        if (monthTable.id != monthID) throw "not a monthview";
        
        var cells = new Array();
        for (var i = 0; i < monthTable.rows.length; i++)
        {
            var row = monthTable.rows[i];
            for (var j = 0; j < row.cells.length; j++)
            {
                var td = row.cells[j];
                if (td)
                {
                    if (td.attributes["daytype"] == null) continue;
                            
                    var dayType = parseInt(td.attributes["daytype"].value);
                    if (this.IsSelectable(dayType))
                        cells[cells.length] = td;
                }
            }
        }
        
        cornerCell.DayCells = cells;
    }
    
    C1WebCalendar.prototype.InitColSelector = function(colCell)
    {
        if (colCell.DayCells) return;
        
        var tokens = colCell.id.split('_');
        if (tokens[tokens.length - 2] != 'cs') throw "not a column";

        var colIndex = tokens[tokens.length - 1];
        var monthID = tokens.slice(0,tokens.length-2).join('_');
        
        var monthTable = C1_GetParentTableElement(colCell);
        if (!monthTable) throw "not a column";
        if (monthTable.id != monthID) throw "not a column";
        
        var cells = new Array();
        if (monthTable)
        {
            var i = 0;
            if (!this.IsSingleMonth())
                i++;
                
            if (this.ShowWeekDays)
                i++;
                
            for (; i < monthTable.rows.length; i++)
            {
                var tr = monthTable.rows[i];
                if (colIndex < tr.cells.length)
                {
                    var td = tr.cells[colIndex];
                    if (td)
                    {
                        if (td.attributes["daytype"] == null) continue;
                        
                        var dayType = parseInt(td.attributes["daytype"].value);
                        if (this.IsSelectable(dayType))
                            cells[cells.length] = td;
                    }
                }
            }
        }
        
        colCell.DayCells = cells;
    }
    
    C1WebCalendar.prototype.InitRowSelector = function(rowCell)
    {
        if (rowCell.DayCells) return;
        
        var tokens = rowCell.id.split('_');
        if (tokens[tokens.length - 2] != 'rs') throw "not a row";
        
        var rowIndex = tokens[tokens.length - 1];
        var monthID = tokens.slice(0,tokens.length-2).join('_');
        
        var monthTable = C1_GetParentTableElement(rowCell);
        if (!monthTable) throw "not a row";
        if (monthTable.id != monthID) throw "not a row";
        
        var tr = monthTable.rows[rowIndex];
        var cells = new Array();
        if (tr)
        {
            var i = 0;
            if (this.ShowWeekDays)
                i++;
               
            for (; i < tr.cells.length; i++)
            {
                var td = tr.cells[i];
                if (td)
                {
                    if (td.attributes["daytype"] == null) continue;
                        
                    var dayType = parseInt(td.attributes["daytype"].value);
                    if (this.IsSelectable(dayType))
                        cells[cells.length] = td;
                }
            }
        }
        
        rowCell.DayCells = cells;
    }
    
    C1WebCalendar.prototype.MonthSelectorOnClick = function(cornerCell, e)
    {
        if (!cornerCell.DayCells)
            this.InitMonthSelector(cornerCell);
            
        this.LastSelDate = null;
        this.UnSelectAll();
            
        var selDates = [];
        for(var i=0; i < cornerCell.DayCells.length; i++)
        {
            var dayCell = cornerCell.DayCells[i];
            
            if (!dayCell.attributes["date"]) continue;
            var date = new Date(dayCell.attributes["date"].value);
            this.SelectDate(date);
            
            selDates[selDates.length] = date;
		}
		
		this.SaveSelectedDates();
		
        if (this.AutoPostBackOnSelect)
        {
            this.DoPostBack("Select");
            return;
        }
		
		this.FireSelChangeEvent("M", selDates);
		
		if (this.IsPopupShowing())
		    this.Close();
    }
    
    C1WebCalendar.prototype.MonthSelectorOnMouseOver = function(cornerCell, e)
    {
        if (!cornerCell.DayCells)
            this.InitMonthSelector(cornerCell);
            
        for(var i=0; i < cornerCell.DayCells.length; i++)
		    this.CalendarDayOnMouseOver(cornerCell.DayCells[i]);
    }
    
    C1WebCalendar.prototype.MonthSelectorOnMouseOut = function(cornerCell, e)
    {
        if (!cornerCell.DayCells)
            this.InitMonthSelector(cornerCell);
            
        for(var i=0; i < cornerCell.DayCells.length; i++)
		    this.CalendarDayOnMouseOut(cornerCell.DayCells[i]);
    }
    
    C1WebCalendar.prototype.MonthSelectorOnMouseDown = function(cornerCell, e)
    {
    }
    
    C1WebCalendar.prototype.MonthSelectorOnMouseUp = function(cornerCell, e)
    {
    }
    
    C1WebCalendar.prototype.ColSelectorOnClick = function(colCell, e)
    {
        if (!colCell.DayCells)
            this.InitColSelector(colCell);
        
        this.UnSelectAll();

        var selDates = [];
        for(var i=0; i < colCell.DayCells.length; i++)
        {
            var dayCell = colCell.DayCells[i];
            
            if (!dayCell.attributes["date"]) continue;
            var date = new Date(dayCell.attributes["date"].value);
            this.SelectDate(date);
            
            selDates[selDates.length] = date;
		}
		
		this.SaveSelectedDates();
		
        if (this.AutoPostBackOnSelect)
        {
            this.DoPostBack("Select");
            return;
        }
		
		this.FireSelChangeEvent("WD", selDates);
		
		if (this.IsPopupShowing())
		    this.Close();
    }
    
    C1WebCalendar.prototype.ColSelectorOnMouseOver = function(colCell, e)
    {
        if (!colCell.DayCells)
            this.InitColSelector(colCell);
            
        for(var i=0; i < colCell.DayCells.length; i++)
		    this.CalendarDayOnMouseOver(colCell.DayCells[i]);
		
		if (!C1_IsStringNullOrEmpty(this.WeekDayStyle.HoverStyle))
		    colCell.style.cssText = this.WeekDayStyle.Style + ";" + this.WeekDayStyle.HoverStyle;
		    
		if (!C1_IsStringNullOrEmpty(this.WeekDayStyle.HoverCssClass))
		    colCell.className = this.WeekDayStyle.HoverCssClass;
    }
    
    C1WebCalendar.prototype.ColSelectorOnMouseOut = function(colCell, e)
    {
        if (!colCell.DayCells)
            this.InitColSelector(colCell);
            
        for(var i=0; i < colCell.DayCells.length; i++)
		    this.CalendarDayOnMouseOut(colCell.DayCells[i]);
		    
		colCell.style.cssText = this.WeekDayStyle.Style;
		colCell.className = this.WeekDayStyle.CssClass;
    }
    
    C1WebCalendar.prototype.ColSelectorOnMouseDown = function(colCell, e)
    {
    }
    
    C1WebCalendar.prototype.ColSelectorOnMouseUp = function(colCell, e)
    {
    }
    
    C1WebCalendar.prototype.RowSelectorOnClick = function(rowCell, e)
    {
        if (!rowCell.DayCells)
            this.InitRowSelector(rowCell);
            
        this.UnSelectAll();

        var selDates = [];
        for(var i=0; i < rowCell.DayCells.length; i++)
        {
            var dayCell = rowCell.DayCells[i];
            
            if (!dayCell.attributes["date"]) continue;
            var date = new Date(dayCell.attributes["date"].value);
            this.SelectDate(date);
            
            selDates[selDates.length] = date;
		}
		
		this.SaveSelectedDates();
		
        if (this.AutoPostBackOnSelect)
        {
            this.DoPostBack("Select");
            return;
        }
		
		this.FireSelChangeEvent("WN", selDates);
		
		if (this.IsPopupShowing())
		    this.Close();
    }
    
    C1WebCalendar.prototype.RowSelectorOnMouseOver = function(rowCell, e)
    {
        if (!rowCell.DayCells)
            this.InitRowSelector(rowCell);
            
        for(var i=0; i < rowCell.DayCells.length; i++)
		    this.CalendarDayOnMouseOver(rowCell.DayCells[i]);
		    
		if (!C1_IsStringNullOrEmpty(this.WeekNumberStyle.HoverStyle))
		    rowCell.style.cssText = this.WeekNumberStyle.Style + ";" + this.WeekNumberStyle.HoverStyle;
		    
		if (!C1_IsStringNullOrEmpty(this.WeekNumberStyle.HoverCssClass))
		    rowCell.className = this.WeekNumberStyle.HoverCssClass;
    }
    
    C1WebCalendar.prototype.RowSelectorOnMouseOut = function(rowCell, e)
    {
        if (!rowCell.DayCells)
            this.InitRowSelector(rowCell);
            
        for(var i=0; i < rowCell.DayCells.length; i++)
		    this.CalendarDayOnMouseOut(rowCell.DayCells[i]);
		    
		rowCell.style.cssText = this.WeekNumberStyle.Style;
		rowCell.className = this.WeekNumberStyle.CssClass;
    }
    
    C1WebCalendar.prototype.RowSelectorOnMouseDown = function(rowCell, e)
    {
    }
    
    C1WebCalendar.prototype.RowSelectorOnMouseUp = function(rowCell, e)
    {
    }

    C1WebCalendar.prototype.UnSelectAll = function()
    {
		var origSel = this.SelectedDates.DateArray;
		if(origSel != null && origSel.length > 0)
		{
			this.SelectedDates.Clear();

			for(var i=0; i < origSel.length; i++)
			{
				var d = origSel[i];
				this.RefreshDate(d);
			}
		}
    }

    C1WebCalendar.prototype.SelectDate = function(date)
    {
        if(this.DisableDates.Contains(date)){return;};
	    if(date<this.MinDate||date>this.MaxDate){return;};
	    
	    this.SelectedDate = date;
	    this.SelectedDates.Add(date);
	    this.RefreshDate(date);
    }
    
    C1WebCalendar.prototype.CalendarDayOnClick = function(dayCell, e)
    {
        if (dayCell.attributes["date"] == null) return;
        
        if (((this.SelectionMode & c1_selectionmode_days) == 0) || (!e.ctrlKey && !e.shiftKey))
            this.UnSelectAll();
        
        var date = new Date(dayCell.attributes["date"].value);
        
        if (!e.shiftKey || ((this.SelectionMode & (c1_selectionmode_day | c1_selectionmode_days)) == c1_selectionmode_day))
        {
            this.LastSelDate = date;
            this.SelectDate(date);
        }else
        {
            if (this.LastSelDate != null)
            {
                var minDate = this.LastSelDate;
                var maxDate = date;
                if (this.LastSelDate > date)
                {
                    maxDate = this.LastSelDate;
                    minDate = date;
                }
                
                while(true)
                {
                    if (minDate > maxDate) break;
                    
                    this.SelectDate(minDate);
                    minDate = minDate.c1_AddDays(1);
                }
                
                this.LasSelDate = null;
            }else
            {
                this.SelectDate(date);
            }
        }
        
        var selDates = [];
        selDates[selDates.length] = date;
        
        this.SaveLastSelDate();
        this.SaveSelectedDates();
        
        if (this.AutoPostBackOnSelect)
        {
            this.DoPostBack("Select");
            return;
        }
        
        this.FireSelChangeEvent("D", selDates);
        
		if (this.IsPopupShowing())
		    this.Close();
    }
    
    C1WebCalendar.prototype.CalendarDayOnMouseOver = function(dayCell, e)
    {
    	dayCell.State = 'hover';
	    this.RefreshDayCell(dayCell);
    }
    
    C1WebCalendar.prototype.CalendarDayOnMouseOut = function(dayCell, e)
    {
        dayCell.State = 'normal';
	    this.RefreshDayCell(dayCell);
    }
    
    C1WebCalendar.prototype.CalendarDayOnMouseDown = function(dayCell, e)
    {
        dayCell.State = 'pushed';
	    this.RefreshDayCell(dayCell);
    }
    
    C1WebCalendar.prototype.CalendarDayOnMouseUp = function(dayCell, e)
    {
        dayCell.State = 'hover';
	    this.RefreshDayCell(dayCell);
    }

    C1WebCalendar.prototype.PreviewOnClick = function(prvCell, e)
    {
    }
   
    C1WebCalendar.prototype.PreviewOnMouseOver = function(prvCell, e)
    {
        var style;
        var btnId = this.GetPreviewBtnID(prvCell);
        if (btnId < 0) return;
        
        if (this.Swapping) return;
        if (c1_browser_ie)
        {
            if (this.PreviewPopup)
            {
                if (this.PreviewPopup.IsShowing())
                    return;
            }
        }
        
        switch(btnId)
        {
            case c1_previewbtn_prev:
                style = this.PrevPreviewStyle;
                break;
                
            case c1_previewbtn_next:
                style = this.NextPreviewStyle;
                break;
        }
        
        if (!C1_IsStringNullOrEmpty(style.HoverStyle))
            prvCell.style.cssText = style.HoverStyle;

        if (!C1_IsStringNullOrEmpty(style.HoverCssClass))
            prvCell.className = style.HoverCssClass;
            
        var mainId = this.ID;
        var mainInstName = this.InstName;
        var mainDate = this.DisplayDate;
        var mainDateStart = this.VisibleDateStart;
        var mainDateEnd = this.VisibleDateEnd;
        
        var months = this.MonthCols * this.MonthRows;
        if (btnId == c1_previewbtn_prev)
            months = -months;
        
        this.ID = this.ID + "_PreviewTemp";
        this.DisplayDate = this.DisplayDate.c1_AddMonths(months);
        this.PreviewMode = true;
        
        var content = this.Render();
                
        if (this.PreviewPopup == null)
        {
            this.PreviewPopup = new PopupSetting(this);
            this.PreviewPopup.Id = this.InstName + '.PreviewPopup';
            this.PreviewPopup.Width = this.PopupSetting.Width;
            this.PreviewPopup.Height = this.PopupSetting.Height;
        }

        if (btnId == c1_previewbtn_prev)
        {
            this.PreviewPopup.Dock = c1_dock_lefttop;
            this.PreviewPopup.ExpandDirection = c1_slidedirection_left;
            this.PreviewPopup.CollapseDirection = c1_slidedirection_right;
        }else
        {
            this.PreviewPopup.Dock = c1_dock_righttop;
            this.PreviewPopup.ExpandDirection = c1_slidedirection_right;
            this.PreviewPopup.CollapseDirection = c1_slidedirection_left;
        }
        
        this.PreviewPopup.SetContent(content);
        
        this.ID = mainId;
        this.DisplayDate = mainDate;
        this.PreviewMode = false;
        this.CreateMonthViews();
        
        this.PreviewPopup.ShowBeside(prvCell);
    }
    
    C1WebCalendar.prototype.PreviewOnMouseOut = function(prvCell, e)
    {
        var style;
        var btnId = this.GetPreviewBtnID(prvCell);
        if (btnId < 0) return;
        
        if (e.toElement != null)
        {
            if (e.toElement == prvCell || e.toElement.parentElement == prvCell) return;
        }
        
        switch(btnId)
        {
            case c1_previewbtn_prev:
                style = this.PrevPreviewStyle;
                break;
                
            case c1_previewbtn_next:
                style = this.NextPreviewStyle;
                break;
        }
        
        prvCell.className = style.CssClass;
        prvCell.style.cssText = style.Style;
            
        if (this.PreviewPopup)
        {
            if (this.PreviewPopup.IsShowing())
            {
                this.PreviewPopup.Hide();
                
                if (c1_browser_ie)
                    this.Refresh();
            }
        }
    }
    
    C1WebCalendar.prototype.PreviewOnMouseDown = function(prvCell, e)
    {
    }
    
    C1WebCalendar.prototype.PreviewOnMouseUp = function(prvCell, e)
    {
    }

    C1WebCalendar.prototype.SwapToDate = function(date) {
        if (this.Swapping) this.SwapEnd();

        this.SwapContainer = document.getElementById(this.ID + '_SwapContainer');
        if (!this.SwapContainer) return;

        this.SwapTable = document.getElementById(this.ID + '_SwapTable');
        if (!this.SwapTable) return;

        this.SwapTr = document.getElementById(this.ID + '_SwapTr');
        if (!this.SwapTr) return;

        this.SwapTd = document.getElementById(this.ID + '_SwapTd');
        if (!this.SwapTd) return;

        this.DisplayDate = date;
        this.CreateMonthViews();

        this.Swapping = true;
        var navSlideType = (this.SwapDuration > 0) ? this.NavigationSlideType : c1_slidetype_none;

        if (navSlideType != c1_slidetype_none) {
            var w = this.SwapContainer.offsetWidth;
            var h = this.SwapContainer.offsetHeight;

            if (c1_browser_ie7) {
                this.SwapContainer.style.width = w + 'px';
                this.SwapContainer.style.minHeight = h + 'px';
            } else {
                this.SwapContainer.style.width = w + 'px';
                this.SwapContainer.style.height = h + 'px';
            }
            this.SwapContainer.style.overflow = 'hidden';
            this.SwapWidth = this.SwapTable.offsetWidth;
            this.SwapTd.style.width = this.SwapWidth + 'px';

            var td = document.createElement('TD');
            td.innerHTML = this.GetMonthsHtml();
            td.id = this.ID + '_SwapTd';
            td.height = '100%';

            if (this.SwapLeft) {
                this.SwapTr.insertBefore(td, this.SwapTr.firstChild);
                this.SwapTable.style.width = (2 * this.SwapWidth) + 'px';
            } else {
                this.SwapTr.appendChild(td);
                this.SwapTable.style.width = (2 * this.SwapWidth) + 'px';
            }

            this.SwapStartTime = (new Date()).getTime();
            this.SwapTimerId = setInterval(this.InstName + '.SwapStep()', 50);
        }
        else {
            this.SwapTd.innerHTML = this.GetMonthsHtml();
            this.Swapping = false;
            this.RefreshCalendarTitle();
        };
    }
    
    C1WebCalendar.prototype.SwapStep = function()
    {
	    var duration=(new Date()).getTime()-this.SwapStartTime;
	    if(duration>this.SwapDuration)
	    {
		    this.SwapEnd();
	    }else
	    {
		    var ratio = window.C1_CalcVisibleRatio(duration,this.SwapDuration,this.NavigationSlideType);
		    var size = this.SwapWidth * ratio;
		    if (this.SwapLeft)
		    {
		        this.SwapContainer.scrollLeft=this.SwapWidth-size;
		    }else
		    {
		        this.SwapContainer.scrollLeft=size;
		    }
	    };
    };

    C1WebCalendar.prototype.SwapEnd = function()
    {
	    clearInterval(this.SwapTimerId);
    	if (this.SwapLeft)
    	{
		    this.SwapTr.removeChild(this.SwapTr.lastChild);
		    this.SwapTable.style.width='100%';
		    this.SwapTable.style.height='100%';
    	}else
    	{
		    this.SwapTr.removeChild(this.SwapTr.firstChild);
		    this.SwapTable.style.width='100%';
		    this.SwapTable.style.height='100%';
    	}
    	
	    this.SwapTd.style.position='static';
	    this.SwapContainer.style.width='100%';
	    this.SwapContainer.style.height='100%';
	    this.SwapContainer.style.overflow='visible';
	    this.Swapping = false;
	    
	    if (this.ShowCalendarTitle)
	        this.RefreshCalendarTitle();
    };
    
    C1WebCalendar.prototype.RefreshCalendarTitle = function()
    {
  	    var td =document.getElementById(this.ID+'_title');
	    if(td)
	    {
		    td.innerHTML = this.GetTitleText(true, this.GetDisplayDate());
	    };
    }
    
    C1WebCalendar.prototype.GetBtnID = function(btn)
    {
        switch(btn)
        {
            case "QPREV":
                return c1_navbtn_qprev;
                break;
                
            case "PREV":
                return c1_navbtn_prev;
                break;
                
            case "NEXT":
                return c1_navbtn_next;
                break;
                
            case "QNEXT":
                return c1_navbtn_qnext;
                break;
        }
        
        return c1_navbtn_unknown;
    }
    
    C1WebCalendar.prototype.GetNavBtnID = function(btn)
    {
        var tokens = btn.id.split('_');
        if (tokens.length < 2) return c1_navbtn_unknown;
        
        var name = tokens[tokens.length - 1].toUpperCase();
        var newTokens = tokens.slice(0, -1);
        var id = newTokens.join('_'); 
        
        if (id != this.ID) return c1_navbtn_unknown;

        return this.GetBtnID(name);
    }
    
    C1WebCalendar.prototype.GetPreviewBtnID = function(btn)
    {
        var tokens = btn.id.split('_');
        if (tokens.length < 2) return c1_previewbtn_unknown;
        
        var name = tokens[tokens.length - 1].toUpperCase();
        var newTokens = tokens.slice(0, -1);
        var id = newTokens.join('_'); 
        
        if (id != this.ID) return c1_previewbtn_unknown;

        switch(name)
        {
            case "PEVPREVIEW":
                return c1_previewbtn_prev;
                break;
                
            case "NEXTPREVIEW":
                return c1_previewbtn_next;
                break; 
        }
        
        return c1_previewbtn_unknown;
    }
    
    C1WebCalendar.prototype.TitleOnClick = function(title, e)
    {
        if (!this.AllowQuickSelector) return;
        
        if (this.MonthPicker == null)
        {
            this.MonthPicker = new MonthPicker(this)
        }
        
        this.MonthPicker.Month = this.DisplayDate.getMonth();
        this.MonthPicker.Year = this.DisplayDate.getFullYear();
        
        var posx = 0;
	    var posy = 0;
	    if (!e) var e = window.event;
	    if (e.pageX || e.pageY) 	
	    {
		    posx = e.pageX;
		    posy = e.pageY;
	    }
	    else if (e.clientX || e.clientY) 	
	    {
		    posx = e.clientX + document.body.scrollLeft
			    + document.documentElement.scrollLeft;
		    posy = e.clientY + document.body.scrollTop
			    + document.documentElement.scrollTop;
	    }

        this.MonthPicker.PopupAt(posx, posy);
    }

    C1WebCalendar.prototype.NavOnClick = function(navbtn, e) {

        if (this.Swapping) return;

        var months = this.NavigationStep;
        var btnId = this.GetNavBtnID(navbtn);
        switch (btnId) {
            case c1_navbtn_next:
                months = this.NavigationStep;
                break;

            case c1_navbtn_qnext:
                months = this.QuickNavigationStep;
                break;

            case c1_navbtn_prev:
                months = -this.NavigationStep;
                break;

            case c1_navbtn_qprev:
                months = -this.QuickNavigationStep;
                break;
        }

        var date = this.GetDisplayDate();
        this.DisplayDate = date.c1_AddMonths(months)
        this.SaveDisplayDate();

        if (this.AutoPostBackOnNavigate) {
            this.DoPostBack("Navigate");
            return;
        }

        this.SwapLeft = date > this.GetDisplayDate();
        this.SwapToDate(this.DisplayDate);
    }
    
    C1WebCalendar.prototype.GetNavBtnStyle = function(btnId)
    {
        var style;
        switch(btnId)
        {
            case c1_navbtn_next:
                style = this.NextStyle;
                break;
                
            case c1_navbtn_qnext:
                style = this.QuickNextStyle;
                break;
                
            case c1_navbtn_prev:
                style = this.PrevStyle;
                break;
                
            case c1_navbtn_qprev:
                style = this.QuickPrevStyle;
                break;
        }
        
        return style;
    }
    
    C1WebCalendar.prototype.NavOnMouseOver = function(navbtn, e)
    {
        var btnId = this.GetNavBtnID(navbtn);
        var style = this.GetNavBtnStyle(btnId); 
        
        if (!C1_IsStringNullOrEmpty(style.HoverStyle))
            navbtn.style.cssText = style.HoverStyle;

        if (!C1_IsStringNullOrEmpty(style.HoverCssClass))
            navbtn.className = style.HoverCssClass;
    }
    
    C1WebCalendar.prototype.NavOnMouseOut = function(navbtn, e)
    {
        var btnId = this.GetNavBtnID(navbtn);
        var style = this.GetNavBtnStyle(btnId); 
        
        navbtn.className = style.CssClass;
        navbtn.style.cssText = style.Style;
    }
    
    C1WebCalendar.prototype.Render = function()
    {
        if (!this.DisplayDate) this.DisplayDate = new Date();
        
        var html = this.GetHtml();
        return html;
    }
    
    C1WebCalendar.prototype.IsPopupShowing = function()
    {
        if (!this.PopupSetting) return false;
        
        return (this.PopupSetting.IsShowing());
    }

    C1WebCalendar.prototype.PopupBeside = function(element, dock)
    {
        if (this.IsPopupShowing()) return;
    
    
        this.Container.innerHTML = '';
        this.PopupSetting.SetContent(this.Render());
        this.PopupSetting.ShowBeside(element, dock);
    }
    
    C1WebCalendar.prototype.PopupAt = function(x, y)
    {
        if (this.IsPopupShowing()) return;
    
        this.Container.innerHTML = '';
        this.PopupSetting.SetContent(this.Render());
        this.PopupSetting.ShowAt(x, y);
    }
     
    C1WebCalendar.prototype.Close = function()
    {
        if (!this.IsPopupShowing()) return;
        
        this.PopupSetting.Hide();
    }
    
    C1WebCalendar.prototype.SaveSelectedDates = function()
    {
        var tb = document.getElementById(this.ID + "_selecteddates");
        if (tb != null)
        {
            tb.value = this.SelectedDates.ToString();
        }
    }
    
    C1WebCalendar.prototype.SaveDisplayDate = function()
    {
        var tb = document.getElementById(this.ID + "_displaydate");
        if (tb != null)
        {
            tb.value = this.DisplayDate.toString();
        }
    }
    
    C1WebCalendar.prototype.SaveLastSelDate = function()
    {
        var tb = document.getElementById(this.ID + "_lastseldate");
        if (tb != null)
        {
            if (this.LastSelDate == null)
                tb.value = "";
            else
                tb.value = this.LastSelDate.toString();
        }
    }
    
    C1WebCalendar.prototype.DoPostBack = function(eventArgs)
    {
        if (!eventArgs) eventArgs = "";
 
        var command = "__doPostBack('" + this.UniqueID + "', '" + eventArgs + "');";
        eval(command);
    }
    
    C1WebCalendar.prototype.BindToSchedule = function(schedule)
    {
        if (schedule)
            schedule.set_calendar(this);
    }
    
    C1WebCalendar.prototype.FireBeforePopupEvent = function()
    {
        var ret = true;
        if (this.OnBeforePopup != null)
            ret = this.OnBeforePopup(this);
            
        return ret == undefined ? true : ret;
    }
    
    C1WebCalendar.prototype.FireAfterPopupEvent = function()
    {
        var ret = true;
        if (this.OnAfterPopup != null)
            ret = this.OnAfterPopup(this);
            
        return ret == undefined ? true : ret;       
    }
    
    C1WebCalendar.prototype.FireBeforeCloseEvent = function()
    {
        var ret = true;
        if (this.OnBeforeClose != null)
            ret = this.OnBeforeClose(this);
            
        return ret == undefined ? true : ret;
    }
    
    C1WebCalendar.prototype.FireAfterCloseEvent = function()
    {
        var ret = true;
        if (this.OnAfterClose != null)
            ret = this.OnAfterClose(this);
            
        return ret == undefined ? true : ret;
    }
    
    C1WebCalendar.prototype.FireSelChangeEvent = function(type, selDates)
    {
        if (this.OnSelChange != null)
            this.OnSelChange(this, type, selDates);
    }
    
    function MonthPicker(owner)
    {
        this.Owner = owner;
        this.Width = 140;
        this.Height = 140;
        this.OKText = "OK";
        this.CancelText = owner.CancelText;
        this.TodayText = owner.TodayText;
        
        var today = new Date();
        this.Month = today.getMonth();
        this.Year = today.getFullYear();
        
        this.PopupSetting = new PopupSetting(this);
        this.PopupSetting.Id = this.Owner.InstName + '.MonthPicker.PopupSetting';

        if (this.Owner.PopupSetting != null)
            this.PopupSetting.LayerIndex = this.Owner.PopupSetting.LayerIndex + 1;
                
        this.PopupSetting.Width = this.Width;
        this.PopupSetting.Height = this.Height;
    }

    MonthPicker.prototype.GetMonthText=function(month)
    {
        var text = c1_monthnames[month];
        if (text.length > 3)
            text = text.substring(0, 3);

        return text;
    }
    
    MonthPicker.prototype.GetButtons=function()
    {
        var cellStyle = 'border-width:1px; border-style:solid; border-color:black;background-color:LightBlue;';

        var htmlBtns = new HtmlTextWriter();
        htmlBtns.WriteBeginTag("table");
        var style = "white-space:nowrap; cursor:pointer; font: bold 11px Arial, Verdana, Sans-Serif;";
        htmlBtns.WriteAttribute("style", style);
        htmlBtns.WriteTagRightChar();
        htmlBtns.WriteFullBeginTag("tr");
        
        htmlBtns.WriteBeginTag("td");
        htmlBtns.WriteAttribute("style", cellStyle);
        htmlBtns.WriteAttribute("onclick", this.Owner.InstName + ".MonthPicker.OnTodayClick(this);");
        htmlBtns.WriteTagRightChar();
        htmlBtns.Write(this.TodayText);
        htmlBtns.WriteEndTag("td");
        
        htmlBtns.WriteFullBeginTag("td");
        htmlBtns.Write("&nbsp;");
        htmlBtns.WriteEndTag("td");
        
        htmlBtns.WriteBeginTag("td");
        htmlBtns.WriteAttribute("style", cellStyle);
        htmlBtns.WriteAttribute("onclick", this.Owner.InstName + ".MonthPicker.OnOKClick(this);");
        htmlBtns.WriteTagRightChar();
        htmlBtns.Write(this.OKText);
        htmlBtns.WriteEndTag("td");
        
        htmlBtns.WriteBeginTag("td");
        htmlBtns.WriteAttribute("style", cellStyle);
        htmlBtns.WriteAttribute("onclick", this.Owner.InstName + ".MonthPicker.OnCancelClick(this);");
        htmlBtns.WriteTagRightChar();
        htmlBtns.Write(this.CancelText);
        htmlBtns.WriteEndTag("td");
        
        htmlBtns.WriteEndTag("tr");
        htmlBtns.WriteEndTag("table");
        
        return htmlBtns.ToString();
    }
    
    MonthPicker.prototype.OnTodayClick=function(cell)
    {
        if (this.Owner)
        {
            var date = new Date();
            this.Owner.DisplayDate = date;
            this.Owner.SaveDisplayDate();
            
            if (this.IsPopupShowing())
                this.PopupSetting.Hide();
                
            if (this.Owner.AutoPostBackOnNavigate)
            {
                this.Owner.DoPostBack("Navigate");
                return;
            }

            this.Owner.Refresh();
        }
    }
    
    MonthPicker.prototype.OnOKClick=function(cell)
    {
        if (this.Owner)
        {
            var date = new Date(this.Year, this.Month, 1);
            this.Owner.DisplayDate = date;
            this.Owner.SaveDisplayDate();
            
            if (this.IsPopupShowing())
                this.PopupSetting.Hide();
                
            if (this.Owner.AutoPostBackOnNavigate)
            {
                this.Owner.DoPostBack("Navigate");
                return;
            }
                
            this.Owner.Refresh();
        }
    }
    
    MonthPicker.prototype.OnCancelClick=function(cell)
    {
        if (this.IsPopupShowing())
            this.PopupSetting.Hide();
    }
    
    MonthPicker.prototype.Sel_Month=function(cell)
    {
        if (cell)
        {
            var table = window.C1_GetParentTableElement(cell);
            if (table)
            {
                for (var r = 0; r < table.rows.length; r++)
                {
                    for (var col = 0; col < table.rows[r].cells.length; col++)
                    {
                        var c = table.rows[r].cells[col];
                        if (c.attributes["celltype"] != null)
                        {
                            if (c.attributes["celltype"].value == "month")
                                c.style.backgroundColor="";
                        }
                    }
                }
            }

            cell.style.backgroundColor = "Gray";
            
            if (cell.attributes["cellvalue"] != null)
                this.Month = parseInt(cell.attributes["cellvalue"].value);
        }
    }
    
    MonthPicker.prototype.Sel_Year=function(cell)
    {
        if (cell)
        {
            var table = window.C1_GetParentTableElement(cell);
            if (table)
            {
                for (var r = 0; r < table.rows.length; r++)
                {
                    for (var col = 0; col < table.rows[r].cells.length; col++)
                    {
                        var c = table.rows[r].cells[col];
                        if (c.attributes["celltype"] != null)
                        {
                            if (c.attributes["celltype"].value == "year")
                                c.style.backgroundColor="";
                        }
                    }
                }
            }

            cell.style.backgroundColor = "Gray";
            
            if (cell.attributes["cellvalue"] != null)
                this.Year = parseInt(cell.attributes["cellvalue"].value);
        }
    }
    
    MonthPicker.prototype.RefreshYears=function(cell, count)
    {
        if (cell && this.FirstYear != null)
        {
            this.FirstYear += count;
            var year = this.FirstYear;
            
            var table = window.C1_GetParentTableElement(cell);
            if (table)
            {
                for (var r = 0; r < table.rows.length; r++)
                {
                    var tr = table.rows[r];
                    for (var col=0; col < tr.cells.length;col++)
                    {
                        var c = tr.cells[col];
                        if (c.attributes["celltype"] != null)
                        {
                            if (c.attributes["celltype"].value == "year")
                            {
                                c.innerHTML = year;
                                c.attributes["cellvalue"].value = year;
                                
                                if (c.attributes["cellvalue"].value == this.Year)
                                    c.style.backgroundColor="Gray";
                                else
                                    c.style.backgroundColor="";
                                
                                year++
                            }
                        }
                    }
                }
            }
        }
    }
    
    MonthPicker.prototype.GetHtml=function()
    {
        var year = this.Year - 4;
        this.FirstYear = year;
    
        var html = new HtmlTextWriter();
        html.WriteBeginTag("table");
        html.WriteAttribute("width", "100%");
        html.WriteAttribute("height", "100%");
        html.WriteAttribute("cellspacing", 0);
        html.WriteAttribute("cellpadding", 0);
        html.WriteAttribute("border", 0);

        var style = "text-align:center; white-space:nowrap; cursor:pointer; font: normal 11px Arial, Verdana, Sans-Serif;";
        html.WriteAttribute("style", style);
        html.WriteTagRightChar();
        
        var month = 0;
        for(var i = 0; i < 5; i++)
        {
            html.WriteFullBeginTag("tr")
            
            html.WriteBeginTag("td");
            if (month == this.Month)
                html.WriteAttribute("style", "background-color:Gray");
                
            html.WriteAttribute("celltype", "month");
            html.WriteAttribute("cellvalue", month);
            html.WriteAttribute("onclick", this.Owner.InstName + ".MonthPicker.Sel_Month(this);");
            html.WriteTagRightChar();
            html.Write(this.GetMonthText(month));
            html.WriteEndTag("td");
            month++;
            
            html.WriteBeginTag("td");
            if (month == this.Month)
                html.WriteAttribute("style", "background-color:Gray");
            html.WriteAttribute("celltype", "month");
            html.WriteAttribute("cellvalue", month);
            html.WriteAttribute("onclick", this.Owner.InstName + ".MonthPicker.Sel_Month(this);");
            html.WriteTagRightChar();
            html.Write(this.GetMonthText(month));
            html.WriteEndTag("td")
            month++;
            
            html.WriteBeginTag("td");
            if (year == this.Year)
                html.WriteAttribute("style", "background-color:Gray");
            html.WriteAttribute("celltype", "year");
            html.WriteAttribute("cellvalue", year);
            html.WriteAttribute("onclick", this.Owner.InstName + ".MonthPicker.Sel_Year(this);");
            html.WriteTagRightChar();
            html.Write(year);
            html.WriteEndTag("td");
            year++
            
            html.WriteBeginTag("td");
            if (year == this.Year)
                html.WriteAttribute("style", "background-color:Gray");
            html.WriteAttribute("celltype", "year");
            html.WriteAttribute("cellvalue", year);
            html.WriteAttribute("onclick", this.Owner.InstName + ".MonthPicker.Sel_Year(this);");
            html.WriteTagRightChar();
            html.Write(year);
            html.WriteEndTag("td");
            year++
            
            html.WriteEndTag("tr");
        }
        
        html.WriteFullBeginTag("tr");
            
        html.WriteBeginTag("td");
        if (month == this.Month)
            html.WriteAttribute("style", "background-color:Gray");
        html.WriteAttribute("celltype", "month");
        html.WriteAttribute("cellvalue", month);
        html.WriteAttribute("onclick", this.Owner.InstName + ".MonthPicker.Sel_Month(this);");
        html.WriteTagRightChar();
        html.Write(this.GetMonthText(month));
        html.WriteEndTag("td");
        month++;
        
        html.WriteBeginTag("td");
        if (month == this.Month)
            html.WriteAttribute("style", "background-color:Gray");
        html.WriteAttribute("celltype", "month");
        html.WriteAttribute("cellvalue", month);
        html.WriteAttribute("onclick", this.Owner.InstName + ".MonthPicker.Sel_Month(this);");
        html.WriteTagRightChar();
        html.Write(this.GetMonthText(month));
        html.WriteEndTag("td");
        
        html.WriteBeginTag("td");
        html.WriteAttribute("onclick", this.Owner.InstName + ".MonthPicker.RefreshYears(this, -10);");
        html.WriteTagRightChar();
        html.Write("<<");
        html.WriteEndTag("td");
        
        html.WriteBeginTag("td");
        html.WriteAttribute("onclick", this.Owner.InstName + ".MonthPicker.RefreshYears(this, 10);");
        html.WriteTagRightChar();
        html.Write(">>");
        html.WriteEndTag("td");
        
        html.WriteEndTag("tr");
        
        html.WriteFullBeginTag("tr");
        html.WriteBeginTag("td");
        html.WriteAttribute("colspan", 4);
        html.WriteTagRightChar();
        html.Write(this.GetButtons());
        html.WriteEndTag("td");

        html.WriteEndTag("tr");
        
        html.WriteEndTag("table");
        
        return html.ToString();
    }
    
    MonthPicker.prototype.Render=function()
    {
        var html = new HtmlTextWriter();
        
        html.WriteBeginTag("div");
        html.WriteAttribute("id", this.Owner.ID + "_MonthPicker");
        html.WriteAttribute("width", this.Width);
        html.WriteAttribute("height", this.Height);
        html.WriteAttribute("style", "border:solid 1px Gray;");
        html.WriteTagRightChar();
        
        html.Write(this.GetHtml());
        
        html.WriteEndTag("div");
        
        return html.ToString();
    }
    
    MonthPicker.prototype.IsPopupShowing = function()
    {
        if (!this.PopupSetting) return false;
        
        return (this.PopupSetting.IsShowing());
    }
    
    MonthPicker.prototype.PopupAt=function(x, y)
    {
        var html = this.Render();
        this.PopupSetting.SetContent(html);
        this.PopupSetting.ShowAt(x, y);
    }
};

window.c1_webcalendar_loaded=true;


if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();