﻿DateFormat = 'yyyy-MM-dd';
SelectDateEvents = new Array();

function SetDate(calendar, date) {

    $(calendar).data('SelectedDate', date);
    $(calendar).val(formatDate(date, DateFormat));

    var CoupledCalendarData = $(calendar).data('CoupledCalendar');

    if (CoupledCalendarData != undefined && CoupledCalendarData != null) {
        CoupledCalendar = $('#' + CoupledCalendarData.Id)[0];
        CoupledCalendarDate = GetDate(CoupledCalendar);

        var CoupledCalendarTime = CoupledCalendarDate.getTime();
        var IncreasedTime = new Date(date.getFullYear(), date.getMonth(), date.getDate() + CoupledCalendarData.Days, 0, 0, 0, 0).getTime();

        if (CoupledCalendarData.Relation == '>' && CoupledCalendarTime <= IncreasedTime) {
            SetDate(CoupledCalendar, new Date(date.getFullYear(), date.getMonth(), date.getDate() + CoupledCalendarData.Days + 1, 0, 0, 0, 0));
        }
        if (CoupledCalendarData.Relation == '>=' && CoupledCalendarTime < IncreasedTime) {
            SetDate(CoupledCalendar, new Date(date.getFullYear(), date.getMonth(), date.getDate() + CoupledCalendarData.Days, 0, 0, 0, 0));
        }
        if (CoupledCalendarData.Relation == '==' && CoupledCalendarTime != IncreasedTime) {
            SetDate(CoupledCalendar, new Date(date.getFullYear(), date.getMonth(), date.getDate() + CoupledCalendarData.Days, 0, 0, 0, 0));
        }
        if (CoupledCalendarData.Relation == '<=' && CoupledCalendarTime > IncreasedTime) {
            SetDate(CoupledCalendar, new Date(date.getFullYear(), date.getMonth(), date.getDate() + CoupledCalendarData.Days, 0, 0, 0, 0));
        }
        if (CoupledCalendarData.Relation == '<' && CoupledCalendarTime >= IncreasedTime) {
            SetDate(CoupledCalendar, new Date(date.getFullYear(), date.getMonth(), date.getDate() + CoupledCalendarData.Days - 1, 0, 0, 0, 0));
        }
    }

    $('#' + calendar.id + '-Div').hide();
    $(document).unbind('click', HideCalendar);

    if (SelectDateEvents[calendar.id + '-Div'] != undefined) {
        SelectDateEvents[calendar.id + '-Div']();
    }
}

function GetDate(calendar) {
    var Time = getDateFromFormat($(calendar).val(), DateFormat);

    var Value = Time == 0 ? new Date() : new Date(Time);
    Value.setHours(0);
    Value.setMinutes(0);
    Value.setSeconds(0);
    Value.setMilliseconds(0);

    return Value;
}

function GetDayCell(calendar, date, month) {

    var SelectedDate = $(calendar).data('SelectedDate');
    var MinDate = $(calendar).data('MinDate');
    var MaxDate = $(calendar).data('MaxDate');

    var InRange = (MinDate == undefined || date >= MinDate) && (MaxDate == undefined || date <= MaxDate);
    var IsSelected = date.getTime() == SelectedDate.getTime();

    var DayLink = document.createElement('a');
    DayLink.innerHTML = date.getDate();
    DayLink.href = '#';

    if (InRange) {
        if (IsSelected) {
            DayLink.className = 'CalendarSelectedDay';
        }
        else {
            DayLink.className = date.getMonth() == month ? 'CalendarDay' : 'CalendarOtherMonthDay';
        }

        DayLink.title = formatDate(date, 'd MMM yyyy');

        DayLink.onclick = function () {
            SetDate(calendar, date);
            return false;
        }
    }
    else {
        DayLink.className = 'CalendarOutOfRangeDay';
        DayLink.onclick = function () {
            return false;
        }
    }

    return DayLink;
}

function GenerateCalendar(calendar) {

    var CalendarDivId = calendar.id + '-Div';

    var CurrentDate = $(calendar).data('CurrentDate');
    var SelectedDate = $(calendar).data('SelectedDate');

    var DaysInMonth = 32 - new Date(CurrentDate.getFullYear(), CurrentDate.getMonth(), 32).getDate();

    $('#CurrentMonthDisplay', $('#' + CalendarDivId)).html(formatDate(CurrentDate, 'MMM yyyy'));

    
    var InsertedDays = 0;

    var CurrentDay;
    var CurrentYear = CurrentDate.getFullYear();
    var CurrentMonth = CurrentDate.getMonth();
    var FirstDay = new Date(CurrentYear, CurrentMonth, 1).getDay();

    var DaysDiv = $('#Days', $('#' + calendar.id + '-Div'));
    DaysDiv.html('');

    if (FirstDay == 0) {
        FirstDay = 7;
    }
    
    for (var PastDays = -FirstDay + 2; PastDays <= 0; PastDays++) {
        DaysDiv.append(GetDayCell(calendar, new Date(CurrentYear, CurrentMonth, PastDays, 0, 0, 0, 0), CurrentMonth))
        InsertedDays++;
    }

    for (var Day = 1; Day <= DaysInMonth; Day++) {
        DaysDiv.append(GetDayCell(calendar, new Date(CurrentYear, CurrentMonth, Day, 0, 0, 0, 0), CurrentMonth));
        InsertedDays++;
    }

    var DaysToInsert = 7 - InsertedDays % 7;

    if (DaysToInsert == 7) {
        DaysToInsert = 0;
    }

    for (Day = 1; Day <= DaysToInsert; Day++) {
        CurrentDay = new Date(CurrentYear, CurrentMonth, DaysInMonth + Day, 0, 0, 0, 0);
        DaysDiv.append(GetDayCell(calendar, CurrentDay, CurrentMonth));
        InsertedDays++;
    }
}

function HideCalendar(event) {
    event.data.CalendarDiv.hide();
    $(document).unbind('click', HideCalendar);
}


function ShowCalendar(calendar) {
    if (calendar.disabled) {
        return;
    }

    var CalendarDiv = $('#' + calendar.id + '-Div');

    var SelectedDate = GetDate(calendar);

    $(calendar).data('CurrentDate', SelectedDate);
    $(calendar).data('SelectedDate', SelectedDate);

    var CalendarPosition = $(calendar).position();

    CalendarDiv.css('left', CalendarPosition.left + 'px');
    CalendarDiv.css('top', (CalendarPosition.top + $(calendar).outerHeight()) + 'px');

    GenerateCalendar(calendar);

    CalendarDiv.show(2, function () {
        $(document).bind('click', { CalendarDiv: CalendarDiv }, HideCalendar);
    });

    CalendarDiv.bind('click', function (event) {
        event.stopPropagation();
    });
}

function setCalendarOptions(dayAbbreviations, months, dateFormat) {

    DateFormat = dateFormat;

    if (dayAbbreviations != undefined) {
        DAY_NAMES[7] = dayAbbreviations['Mon'];
        DAY_NAMES[8] = dayAbbreviations['Tue'];
        DAY_NAMES[9] = dayAbbreviations['Wed'];
        DAY_NAMES[10] = dayAbbreviations['Thu'];
        DAY_NAMES[11] = dayAbbreviations['Fri'];
        DAY_NAMES[12] = dayAbbreviations['Sat'];
        DAY_NAMES[13] = dayAbbreviations['Sun'];
    }

    if (months != undefined) {
        MONTH_NAMES[0] = months['January'];
        MONTH_NAMES[1] = months['February'];
        MONTH_NAMES[2] = months['March'];
        MONTH_NAMES[3] = months['April'];
        MONTH_NAMES[4] = months['May'];
        MONTH_NAMES[5] = months['June'];
        MONTH_NAMES[6] = months['July'];
        MONTH_NAMES[7] = months['August'];
        MONTH_NAMES[8] = months['September'];
        MONTH_NAMES[9] = months['October'];
        MONTH_NAMES[10] = months['November'];
        MONTH_NAMES[11] = months['December'];
    }
}

function setCalendarsDistance(sourceCalendar, destCalendar, desiredDaysBetween) {
    
    var SourceTime = getDateFromFormat($(sourceCalendar).val(), DateFormat);
    var SourceDate = new Date(SourceTime);
    var DestDate = new Date(SourceDate.getFullYear(), SourceDate.getMonth(), SourceDate.getDate() + parseInt(desiredDaysBetween), 0, 0, 0, 0);
    $(destCalendar).val(formatDate(DestDate, DateFormat));
}

function makeThingsChronological(calendarWithEarlierDate, calendarWithLaterDate, defaultDaysOffset, triggeringCalendar) {

    if (calendarWithEarlierDate == undefined) {
        return;
    }

    if (calendarWithLaterDate == undefined) {
        return;
    }

    if (triggeringCalendar == undefined) {
        return;
    }

    var EarlierTime = getDateFromFormat($(calendarWithEarlierDate).val(), DateFormat);
    var LaterTime = getDateFromFormat($(calendarWithLaterDate).val(), DateFormat);

    if (LaterTime < EarlierTime) {

        var EarlierDate;
        var LaterDate;

        if (triggeringCalendar == calendarWithEarlierDate) {
            EarlierDate = new Date(EarlierTime);
            LaterDate = new Date(EarlierDate.getFullYear(), EarlierDate.getMonth(), EarlierDate.getDate() + defaultDaysOffset);
            $(calendarWithLaterDate).val(formatDate(LaterDate, DateFormat));
        }

        if (triggeringCalendar == calendarWithLaterDate) {
            LaterDate = new Date(LaterTime);
            EarlierDate = new Date(LaterDate.getFullYear(), LaterDate.getMonth(), LaterDate.getDate() - defaultDaysOffset);
            $(calendarWithEarlierDate).val(formatDate(EarlierDate, DateFormat));
        }
    }

}

function getDaysBetweenCalendars(calendar1, calendar2) {

    // The number of milliseconds in one day
    var OneDay = 1000 * 60 * 60 * 24;

    // Convert both dates to milliseconds
    var Time1 = getDateFromFormat($(calendar1).val(), DateFormat);
    var Time2 = getDateFromFormat($(calendar2).val(), DateFormat);

    // Calculate the difference in milliseconds
    var Difference = Math.abs(Time1 - Time2);

    // Convert back to days and return
    return Math.round(Difference / OneDay);

}

function CreateNavigationBar(calendar) {

    var NavigationBar = document.createElement('div');

    var DecreaseYearLink = document.createElement('a');
    DecreaseYearLink.innerHTML = '&lt;&lt;';
    DecreaseYearLink.className = 'CalendarDecYear';
    DecreaseYearLink.href = '#';
    DecreaseYearLink.onclick = function () {
        var CurrentDate = $(calendar).data('CurrentDate');
        $(calendar).data('CurrentDate', new Date(CurrentDate.getFullYear() - 1, CurrentDate.getMonth(), 1, 0, 0, 0, 0));
        GenerateCalendar(calendar);
        return false;
    }
    $(NavigationBar).append(DecreaseYearLink);

    var DecreaseMonthLink = document.createElement('a');
    DecreaseMonthLink.innerHTML = '&lt;';
    DecreaseMonthLink.className = 'CalendarDecMonth';
    DecreaseMonthLink.href = '#';
    DecreaseMonthLink.onclick = function () {
        var CurrentDate = $(calendar).data('CurrentDate');
        $(calendar).data('CurrentDate', new Date(CurrentDate.getFullYear(), CurrentDate.getMonth() - 1, 1, 0, 0, 0, 0));
        GenerateCalendar(calendar);
        return false;
    }
    $(NavigationBar).append(DecreaseMonthLink);

    var CurrentMonthDisplay = document.createElement('div');
    CurrentMonthDisplay.className = 'CalendarCurrent';
    CurrentMonthDisplay.id = 'CurrentMonthDisplay';
    $(NavigationBar).append(CurrentMonthDisplay);

    var IncreaseMonthLink = document.createElement('a');
    IncreaseMonthLink.innerHTML = '&gt;';
    IncreaseMonthLink.className = 'CalendarIncMonth';
    IncreaseMonthLink.href = '#';
    IncreaseMonthLink.onclick = function () {
        var CurrentDate = $(calendar).data('CurrentDate');
        $(calendar).data('CurrentDate', new Date(CurrentDate.getFullYear(), CurrentDate.getMonth() + 1, 1, 0, 0, 0, 0));
        GenerateCalendar(calendar);
        return false;
    }
    $(NavigationBar).append(IncreaseMonthLink);

    var IncreaseYearLink = document.createElement('a');
    IncreaseYearLink.innerHTML = '&gt;&gt;';
    IncreaseYearLink.className = 'CalendarIncYear';
    IncreaseYearLink.href = '#';
    IncreaseYearLink.onclick = function () {
        var CurrentDate = $(calendar).data('CurrentDate');
        $(calendar).data('CurrentDate', new Date(CurrentDate.getFullYear() + 1, CurrentDate.getMonth(), 1, 0, 0, 0, 0));
        GenerateCalendar(calendar);
        return false;
    }
    $(NavigationBar).append(IncreaseYearLink);

    return NavigationBar;
}

function CreateDayHeaders() {
    var DayHeadersBar = document.createElement('div');

    for (var DayOfTheWeek = 0; DayOfTheWeek < 7; DayOfTheWeek++) {
        var DayHeader = document.createElement('div');
        DayHeader.innerHTML = DAY_NAMES[DayOfTheWeek + 7];
        DayHeader.className = DayOfTheWeek == 6 ? 'CalendarSunday' : 'CalendarDayOfTheWeek';
        $(DayHeadersBar).append(DayHeader);
    }

    return DayHeadersBar;
}

$.fn.initializeCalendar = function () {
    this.each(function () {

        if (this.tagName == 'INPUT') {

            var CalendarDiv = document.createElement('div');
            CalendarDiv.id = this.id + '-Div';
            CalendarDiv.className = 'Calendar';
            CalendarDiv.style.display = 'none';
            $(this).after(CalendarDiv);

            var DaysDiv = document.createElement('div');
            DaysDiv.id = 'Days';

            $(CalendarDiv).append(CreateNavigationBar(this));
            $(CalendarDiv).append(CreateDayHeaders());
            $(CalendarDiv).append(DaysDiv);


            if ($('#' + this.id + '-Min').val() != undefined) {
                var MinDate = new Date(getDateFromFormat($('#' + this.id + '-Min').val(), DateFormat));
                MinDate.setHours(0);
                MinDate.setMinutes(0);
                MinDate.setSeconds(0);
                MinDate.setMilliseconds(0);
                $(this).data('MinDate', MinDate);

                $('#' + this.id + '-Min').remove();
            }
            if ($('#' + this.id + '-Max').val() != undefined) {
                var MaxDate = new Date(getDateFromFormat($('#' + this.id + '-Max').val(), DateFormat));
                MaxDate.setHours(0);
                MaxDate.setMinutes(0);
                MaxDate.setSeconds(0);
                MaxDate.setMilliseconds(0);
                $(this).data('MaxDate', MaxDate);

                $('#' + this.id + '-Max').remove();
            }

            var CoupledCalendar = $('#' + this.id + '-Coupled');
            if (CoupledCalendar.val() != undefined) {

                $(this).data('CoupledCalendar', $.parseJSON(CoupledCalendar.val()));

                CoupledCalendar.remove();
            }

            $(this).click(function (e) {
                ShowCalendar(this);
            });

            $(this).change(function (e) {
                var Time = getDateFromFormat($(this).val(), DateFormat);
                if (Time > 0) {
                    SetDate(this, new Date(Time));
                }
            });
        }

    });
}
